ZGlmZiAtLWdpdCBhL0NIQU5HRVMudHh0IGIvQ0hBTkdFUy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzU3ZWRkOQotLS0gL2Rldi9udWxsCisrKyBiL0NIQU5HRVMudHh0CkBAIC0wLDAgKzEsMTU2MSBAQAorSEJhc2UgQ2hhbmdlIExvZworUmVsZWFzZSAwLjIwLjAgLSBVbnJlbGVhc2VkCisgIElOQ09NUEFUSUJMRSBDSEFOR0VTCisgICBIQkFTRS0xMTQ3ICBNb2RpZnkgdGhlIHNjcmlwdHMgdG8gdXNlIFpvb2tlZXBlcgorICAgSEJBU0UtMTE0NCAgU3RvcmUgdGhlIFJPT1QgcmVnaW9uIGxvY2F0aW9uIGluIFpvb2tlZXBlcgorICAgICAgICAgICAgICAgKE5pdGF5IEpvZmZlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTExNDYgIFJlcGxhY2UgdGhlIEhSUyBsZWFzZXMgd2l0aCBab29rZWVwZXIKKyAgIEhCQVNFLTYxICAgIENyZWF0ZSBhbiBIQmFzZS1zcGVjaWZpYyBNYXBGaWxlIGltcGxlbWVudGF0aW9uCisgICAgICAgICAgICAgICAoUnlhbiBSYXdzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtMTE0NSAgRW5zdXJlIHRoYXQgdGhlcmUgaXMgb25seSAxIE1hc3RlciB3aXRoIFpvb2tlZXBlciAoUmVtb3ZlcworICAgICAgICAgICAgICAgaGJhc2UubWFzdGVyKSAoTml0YXkgSm9mZmUgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI4OSAgUmVtb3ZlICJoYmFzZS5mdWxseS5kaXN0cmlidXRlZCIgb3B0aW9uIGFuZCB1cGRhdGUgZG9jcworICAgICAgICAgICAgICAgKE5pdGF5IEpvZmZlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyMzQgIENoYW5nZSBIQmFzZSBTdG9yZUtleSBmb3JtYXQKKyAgIEhCQVNFLTEzNDggIE1vdmUgMC4yMC4wIHRhcmdldGVkIFRSVU5LIHRvIDAuMjAuMCBoYWRvb3AKKyAgICAgICAgICAgICAgIChSeWFuIFJhd3NvbiBhbmQgU3RhY2spCisgICBIQkFTRS0xMzQyICBBZGQgdG8gZmlsZXN5c3RlbSBpbmZvIG5lZWRlZCB0byByZWJ1aWxkIC5NRVRBLgorICAgSEJBU0UtMTM2MSAgRGlzYWJsZSBibG9vbSBmaWx0ZXJzCisgICBIQkFTRS0xMzY3ICBHZXQgcmlkIG9mIFRocmlmdCBleGNlcHRpb24gJ05vdEZvdW5kJworICAgSEJBU0UtMTM4MSAgUmVtb3ZlIG9uZWxhYiBhbmQgYmxvb20gZmlsdGVycyBmaWxlcyBmcm9tIGhiYXNlCisgICBIQkFTRS0xNDExICBSZW1vdmUgSExvZ0VkaXQuCisKKyAgQlVHIEZJWEVTCisgICBIQkFTRS0xMTQwICAiYW50IGNsZWFuIHRlc3QiIGZhaWxzIChOaXRheSBKb2ZmZSB2aWEgU3RhY2spCisgICBIQkFTRS0xMTI5ICBNYXN0ZXIgd29uJ3QgZ28gZG93bjsgc3R1Y2sgam9pbmVkIG9uIHJvb3RTY2FubmVyCisgICBIQkFTRS0xMTM2ICBIYXNoRnVuY3Rpb24gaW5hZHZlcnRlbnRseSBkZXN0cm95cyBzb21lIHJhbmRvbW5lc3MKKyAgICAgICAgICAgICAgIChKb25hdGhhbiBFbGxpcyB2aWEgU3RhY2spCisgICBIQkFTRS0xMTM4ICBUZXN0IHRoYXQgcmVhZGVycyBvcGVuZWQgYWZ0ZXIgYSBzeW5jIGNhbiBzZWUgYWxsIGRhdGEgdXAgdG8gdGhlCisgICAgICAgICAgICAgICBzeW5jICh0ZW1wb3JhcnkgdW50aWwgSEFET09QLTQzNzkgaXMgcmVzb2x2ZWQpCisgICBIQkFTRS0xMTIxICBDbHVzdGVyIGNvbmZ1c2VkIGFib3V0IHdoZXJlIC1ST09ULSBpcworICAgSEJBU0UtMTE0OCAgQWx3YXlzIGZsdXNoIEhMb2cgb24gcm9vdCBvciBtZXRhIHJlZ2lvbiB1cGRhdGVzCisgICBIQkFTRS0xMTgxICBzcmMvc2F2ZVZlcnNpb24uc2ggYmFpbHMgb24gbm9uLXN0YW5kYXJkIEJvdXJuZSBzaGVsbHMKKyAgICAgICAgICAgICAgIChlLmcuIGRhc2gpIChLIE0gdmlhIEplYW4tRGFuaWVsIENyeWFucykKKyAgIEhCQVNFLTExNzUgIEhCQSBhZG1pbmlzdHJhdGl2ZSB0b29scyBkbyBub3Qgd29yayB3aGVuIHNwZWNpZnlpbmcgcmVnaW9uCisgICAgICAgICAgICAgICBuYW1lIChKb25hdGhhbiBHcmF5IHZpYSBBbmRyZXcgUHVydGVsbCkKKyAgIEhCQVNFLTExOTAgIFRhYmxlSW5wdXRGb3JtYXRCYXNlIHdpdGggcm93IGZpbHRlcnMgc2NhbiB0b28gZmFyIChEYXZlCisgICAgICAgICAgICAgICBMYXRoYW0gdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTE5OCAgT09NRSBpbiBJUEMgc2VydmVyIGRvZXMgbm90IHRyaWdnZXIgYWJvcnQgYmVoYXZpb3IKKyAgIEhCQVNFLTEyMDkgIE1ha2UgcG9ydCBkaXNwbGF5ZWQgdGhlIHNhbWUgYXMgaXMgdXNlZCBpbiBVUkwgZm9yIFJlZ2lvblNlcnZlcgorICAgICAgICAgICAgICAgdGFibGUgaW4gVUkgKExhcnMgR2VvcmdlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyMTcgIGFkZCBuZXcgY29tcHJlc3Npb24gYW5kIGhmaWxlIGJsb2Nrc2l6ZSB0byBIQ29sdW1uRGVzY3JpcHRvcgorICAgSEJBU0UtODU5ICAgSFN0b3JlS2V5IG5lZWRzIGEgcmV3b3JraW5nCisgICBIQkFTRS0xMjExICBOUEUgaW4gcmV0cmllcyBleGhhdXN0ZWQgZXhjZXB0aW9uCisgICBIQkFTRS0xMjMzICBUcmFuc2FjdGlvbmFsIGZpeGVzOiBPdmVybHkgY29uc2VydmF0aXZlIHNjYW4gcmVhZC1zZXQsCisgICAgICAgICAgICAgICBwb3RlbnRpYWwgQ01FIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtMTIzOSAgaW4gdGhlIFJFU1QgaW50ZXJmYWNlIGRvZXMgbm90IGNvcnJlY3RseSBjbGVhciB0aGUgY2hhcmFjdGVyCisgICAgICAgICAgICAgICBidWZmZXIgZWFjaCBpdGVyYXRpb24tMTE4NSAgd3JvbmcgcmVxdWVzdC9zZWMgaW4gdGhlIGd1aQorICAgICAgICAgICAgICAgcmVwb3J0aW5nIHdyb25nIChCcmlhbiBCZWdncyB2aWEgU3RhY2spCisgICBIQkFTRS0xMjQ1ICBoZmlsZSBtZXRhIGJsb2NrIGhhbmRsaW5nIGJ1Z3MgKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyMzggIFVuZGVyIHVwbG9hZCwgcmVnaW9uIHNlcnZlcnMgYXJlIHVuYWJsZQorICAgICAgICAgICAgICAgdG8gY29tcGFjdCB3aGVuIGxvYWRlZCB3aXRoIGh1bmRyZWRzIG9mIHJlZ2lvbnMKKyAgIEhCQVNFLTEyNDcgIGNoZWNrQW5kU2F2ZSBkb2Vzbid0IFdyaXRlIEFoZWFkIExvZworICAgSEJBU0UtMTI0MyAgb2xkbG9nZmlsZS5kYXQgaXMgc2NyZXdlZCwgc28gaXMgaXQncyByZWdpb24KKyAgIEhCQVNFLTExNjkgIFdoZW4gYSBzaHV0ZG93biBpcyByZXF1ZXN0ZWQsIHN0b3Agc2Nhbm5pbmcgTUVUQSByZWdpb25zCisgICAgICAgICAgICAgICBpbW1lZGlhdGVseQorICAgSEJBU0UtMTI1MSAgSENvbm5lY3Rpb25NYW5hZ2VyLmdldENvbm5lY3Rpb24oSEJhc2VDb25maWd1cmF0aW9uKSByZXR1cm5zIAorICAgICAgICAgICAgICAgc2FtZSBIQ29ubmVjdGlvbiBmb3IgZGlmZmVyZW50IEhCYXNlQ29uZmlndXJhdGlvbnMgCisgICBIQkFTRS0xMTU3LCBIQkFTRS0xMTU2IElmIHdlIGRvIG5vdCB0YWtlIHN0YXJ0IGNvZGUgYXMgYSBwYXJ0IG9mIHJlZ2lvbgorICAgICAgICAgICAgICAgc2VydmVyIHJlY292ZXJ5LCB3ZSBjb3VsZCBpbmFkdmVydGFudGx5IHRyeSB0byByZWFzc2lnbiByZWdpb25zCisgICAgICAgICAgICAgICBhc3NpZ25lZCB0byBhIHJlc3RhcnRlZCBzZXJ2ZXIgd2l0aCBhIGRpZmZlcmVudCBzdGFydCBjb2RlOworICAgICAgICAgICAgICAgSW1wcm92ZSBsZWFzZSBoYW5kbGluZworICAgSEJBU0UtMTI2NyAgYmluYXJ5IGtleXMgYnJva2VuIGluIHRydW5rIChhZ2FpbikgLS0gcGFydCAyIGFuZCAzCisgICAgICAgICAgICAgICAoUnlhbiBSYXdzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtMTI2OCAgWm9vS2VlcGVyIGNvbmZpZyBwYXJzaW5nIGNhbiBicmVhayBIQmFzZSBzdGFydHVwCisgICAgICAgICAgICAgICAoTml0YXkgSm9mZmUgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI3MCAgRml4IFRlc3RJbmZvU2VydmVycyAoTml0YXkgSm9mZmUgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI3NyAgSFN0b3JlS2V5OiBXcm9uZyBjb21wYXJhdG9yIGxvZ2ljIChFdmdlbnkgUnlhYml0c2tpeSkKKyAgIEhCQVNFLTEyNzUgIFRlc3RUYWJsZS50ZXN0Q3JlYXRlVGFibGUgYnJva2VuIChSeWFuIFJhd3NvbiB2aWEgU3RhY2spCisgICBIQkFTRS0xMjc0ICBUZXN0TWVyZ2VUYWJsZSBpcyBicm9rZW4gaW4gSHVkc29uIChOaXRheSBKb2ZmZSB2aWEgU3RhY2spCisgICBIQkFTRS0xMjgzICB0aHJpZnQncyBwYWNrYWdlIGRlc2NycGl0aW9uIG5lZWRzIHRvIHVwZGF0ZSBmb3Igc3RhcnQvc3RvcAorICAgICAgICAgICAgICAgcHJvY2VkdXJlIChSb25nLWVuIEZhbiB2aWEgU3RhY2spCisgICBIQkFTRS0xMjg0ICBkcm9wIHRhYmxlIGRyb3BzIGFsbCBkaXNhYmxlZCB0YWJsZXMKKyAgIEhCQVNFLTEyOTAgIHRhYmxlLmpzcCBlaXRoZXIgNTAwcyBvdXQgb3IgZG9lc250IGxpc3QgdGhlIHJlZ2lvbnMgKFJ5YW4KKyAgICAgICAgICAgICAgIFJhd3NvbiB2aWEgQW5kcmV3IFB1cnRlbGwpCisgICBIQkFTRS0xMjkzICBoZmlsZSBkb2Vzbid0IHJlY3ljbGUgZGVjb21wcmVzc29ycyAoUnlhbiBSYXdzb24gdmlhIEFuZHJldworICAgICAgICAgICAgICAgUHVydGVsbCkKKyAgIEhCQVNFLTExNTAgIEhNc2cgY2FycmllcyBzYWZlbW9kZSBmbGFnOyByZW1vdmUgKE5pdGF5IEpvZmZlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyMzIgIHpvb2tlZXBlciBjbGllbnQgd29udCByZWNvbm5lY3QgaWYgdGhlcmUgaXMgYSBwcm9ibGVtIChOaXRheQorICAgICAgICAgICAgICAgSm9mZmUgdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTMwMyAgU2Vjb25kYXJ5IGluZGV4IGNvbmZpZ3VyYXRpb24gcHJldmVudHMgSEJhc2UgZnJvbSBzdGFydGluZworICAgICAgICAgICAgICAgKEtlbiBXZWluZXIgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI5OCAgbWFzdGVyLmpzcCAmIHRhYmxlLmpzcCBkbyBub3QgVVJJIEVuY29kZSB0YWJsZSBvciByZWdpb24KKyAgICAgICAgICAgICAgIG5hbWVzIGluIGxpbmtzIChMYXJzIEdlb3JnZSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzEwICBPZmYgYnkgb25lIGVycm9yIGluIEJ5dGVzLnZpbnRUb0J5dGVzCisgICBIQkFTRS0xMjAyICBnZXRSb3cgZG9lcyBub3QgYWx3YXlzIHdvcmsgd2hlbiBzcGVjaWZ5aW5nIG51bWJlciBvZiB2ZXJzaW9ucworICAgSEJBU0UtMTMyNCAgaGJhc2UtMTIzNCBicm9rZSB0ZXN0Z2V0MiB1bml0IHRlc3QgKGFuZCBicm9rZSB0aGUgYnVpbGQpCisgICBIQkFTRS0xMzIxICBoYmFzZS0xMjM0IGJyb2tlIFRlc3RDb21wYWN0aW9uOyBmaXggYW5kIHJlZW5hYmxlCisgICBIQkFTRS0xMzMwICBiaW5hcnkga2V5cyBicm9rZW4gb24gdHJ1bmsgKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEzMzIgIHJlZ2lvbnNlcnZlciBjYXJyeWluZyAuTUVUQS4gc3RhcnRzIHN1Y2tpbmcgYWxsIGNwdSwgZHJpdmVzIGxvYWQKKyAgICAgICAgICAgICAgIHVwIC0gaW5maW5pdGUgbG9vcD8gKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEzMzQgIC5NRVRBLiByZWdpb24gcnVubmluZyBpbnRvIGhmaWxlIGVycm9ycyAoUnlhbiBSYXdzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtMTMzOCAgbG9zdCB1c2Ugb2YgY29tcGFjdGlvbi5kaXI7IHdlIHdlcmUgY29tcGFjdGluZyBpbnRvIGxpdmUgc3RvcmUKKyAgICAgICAgICAgICAgIHN1YmRpcmVjdG9yeQorICAgSEJBU0UtMTA1OCAgUHJldmVudCBydW5hd2F5IGNvbXBhY3Rpb25zCisgICBIQkFTRS0xMjkyICBwaHAgdGhyaWZ0J3MgZ2V0Um93KCkgd291bGQgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSByb3cgZG9lcworICAgICAgICAgICAgICAgbm90IGV4aXN0IChSb25nLWVuIEZhbiB2aWEgU3RhY2spCisgICBIQkFTRS0xMzQwICBGaXggbmV3IGphdmFkb2Mgd2FybmluZ3MgKEV2Z2VueSBSeWFiaXRza2l5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyODcgIFBhcnRpdGlvbmVyIGNsYXNzIG5vdCB1c2VkIGluIFRhYmxlTWFwUmVkdWNlVXRpbC5pbml0VGFibGVSZWR1Y2VKb2IoKQorICAgICAgICAgICAgICAgKExhcnMgR2VvcmdlIGFuZCBCaWxseSBQZWFyc29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEzMjAgIGhiYXNlLTEyMzQgYnJva2UgZmlsdGVyIHRlc3RzCisgICBIQkFTRS0xMzU1ICBbcGVyZm9ybWFuY2VdIENhY2hlIGZhbWlseSBtYXh2ZXJzaW9uczsgd2Ugd2VyZSBjYWxjdWxhdGluZyBvbgorICAgICAgICAgICAgICAgZWFjaCBhY2Nlc3MKKyAgIEhCQVNFLTEzNTggIEJ1ZyBpbiByZWFkaW5nIGZyb20gTWVtY2FjaGUgbWV0aG9kIChyZWFkIG9ubHkgZnJvbSBzbmFwc2hvdCkKKyAgICAgICAgICAgICAgIChFdmdlbnkgUnlhYml0c2tpeSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzIyICBoYmFzZS0xMjM0IGJyb2tlIFRlc3RBdG9taWNJbmNyZW1lbnQ7IGZpeCBhbmQgcmVlbmFibGUKKyAgICAgICAgICAgICAgIChFdmdlbnkgUnlhYml0c2tpeSBhbmQgUnlhbiBSYXdzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtMTM0NyAgSFRhYmxlLmluY3JlbWVudENvbHVtblZhbHVlIGRvZXMgbm90IHRha2UgbmVnYXRpdmUgJ2Ftb3VudCcKKyAgICAgICAgICAgICAgIChFdmdlbnkgUnlhYml0c2tpeSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzY1ICBUeXBvIGluIFRhYmxlSW5wdXRGb3JtYXRCYXNlLnNldElucHV0Q29sdW1zIChKb24gR3JheSB2aWEgU3RhY2spCisgICBIQkFTRS0xMjc5ICBGaXggdGhlIHdheSBob3N0bmFtZXMgYW5kIElQcyBhcmUgaGFuZGxlZAorICAgSEJBU0UtMTM2OCAgSEJBU0UtMTI3OSBicm9rZSB0aGUgYnVpbGQKKyAgIEhCQVNFLTEyNjQgIFdyb25nIHJldHVybiB2YWx1ZXMgb2YgY29tcGFyYXRvcnMgZm9yIENvbHVtblZhbHVlRmlsdGVyCisgICAgICAgICAgICAgICAoVGhvbWFzIFNjaG5laWRlciB2aWEgQW5kcmV3IFB1cnRlbGwpCisgICBIQkFTRS0xMzc0ICBOUEUgb3V0IG9mIFpvb0tlZXBlcldyYXBwZXIubG9hZFpvb0tlZXBlckNvbmZpZworICAgSEJBU0UtMTMzNiAgU3BsaXR0aW5nIHVwIHRoZSBjb21wYXJlIG9mIGZhbWlseStjb2x1bW4gaW50byAyIGRpZmZlcmVudAorICAgICAgICAgICAgICAgY29tcGFyZSAKKyAgIEhCQVNFLTEzNzcgIFJTIGFkZHJlc3MgaXMgbnVsbCBpbiBtYXN0ZXIgd2ViIFVJCisgICBIQkFTRS0xMzQ0ICBXQVJOIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjogQ2Fubm90IHNldCBhIHJlZ2lvbiBhcyBvcGVuIGlmIGl0CisgICAgICAgICAgICAgICBoYXMgbm90IGJlZW4gcGVuZGluZworICAgSEJBU0UtMTM4NiAgTlBFIGluIGhvdXNla2VlcGluZworICAgSEJBU0UtMTM5NiAgUmVtb3ZlIHVudXNlZCBzZXF1ZW5jZWZpbGUgYW5kIG1hcGZpbGUgY29uZmlnLiBmcm9tCisgICAgICAgICAgICAgICBoYmFzZS1kZWZhdWx0LnhtbAorICAgSEJBU0UtMTM5OCAgVGFibGVPcGVyYXRpb24gZG9lc250IGZvcm1hdCBrZXlzIGZvciBtZXRhIHNjYW4gcHJvcGVybHkKKyAgICAgICAgICAgICAgIChSeWFuIFJhd3NvbiB2aWEgU3RhY2spCisgICBIQkFTRS0xMzk5ICBDYW4ndCBkcm9wIHRhYmxlcyBzaW5jZSBIQkFTRS0xMzk4IChSeWFuIFJhd3NvbiB2aWEgQW5kcmV3CisgICAgICAgICAgICAgICBQdXJ0ZWxsKQorICAgSEJBU0UtMTMxMSAgWm9vS2VlcGVyV3JhcHBlcjogRmFpbGVkIHRvIHNldCB3YXRjaGVyIG9uIFpOb2RlIC9oYmFzZS9tYXN0ZXIKKyAgICAgICAgICAgICAgIChOaXRheSBKb2ZmZSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzkxICBOUEUgaW4gVGFibGVJbnB1dEZvcm1hdEJhc2UkVGFibGVSZWNvcmRSZWFkZXIucmVzdGFydCBpZiB6b28uY2ZnCisgICAgICAgICAgICAgICBpcyB3cm9uZyBvciBtaXNzaW5nIG9uIHRhc2sgdHJhY2tlcnMKKyAgIEhCQVNFLTEzMjMgIGhiYXNlLTEyMzQgYnJva2UgVGVzdFRocmlmdFNlcnZlcjsgZml4IGFuZCByZWVuYWJsZQorCisgIElNUFJPVkVNRU5UUworICAgSEJBU0UtMTA4OSAgQWRkIGNvdW50IG9mIHJlZ2lvbnMgb24gZmlsZXN5c3RlbSB0byBtYXN0ZXIgVUk7IGFkZCBwZXJjZW50YWdlCisgICAgICAgICAgICAgICBvbmxpbmUgYXMgZGlmZmVyZW5jZSBiZXR3ZWVuIHdoYXRzIG9wZW4gYW5kIHdoYXRzIG9uIGZpbGVzeXN0ZW0KKyAgICAgICAgICAgICAgIChTYW11ZWwgR3VvIHZpYSBTdGFjaykKKyAgIEhCQVNFLTExMzAgIFByZWZpeFJvd0ZpbHRlciAoTWljaGFlbCBHb3R0ZXNtYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtMTEzOSAgVXBkYXRlIENsb3ZlciBpbiBidWlsZC54bWwKKyAgIEhCQVNFLTg3NiAgIFRoZXJlIGFyZSBhIGxhcmdlIG51bWJlciBvZiBKYXZhIHdhcm5pbmdzIGluIEhCYXNlOyBwYXJ0IDEsCisgICAgICAgICAgICAgICBwYXJ0IDIsIHBhcnQgMywgcGFydCA0LCBwYXJ0IDUsIHBhcnQgNiwgcGFydCA3IGFuZCBwYXJ0IDgKKyAgICAgICAgICAgICAgIChFdmdlbnkgUnlhYml0c2tpeSB2aWEgU3RhY2spCisgICBIQkFTRS04OTYgICBVcGRhdGUganJ1YnkgZnJvbSAxLjEuMiB0byAxLjEuNgorICAgSEJBU0UtMTAzMSAgQWRkIHRoZSBab29rZWVwZXIgamFyCisgICBIQkFTRS0xMTQyICBDbGVhbnVwIHRocmlmdCBzZXJ2ZXI7IHJlbW92ZSBUZXh0IGFuZCBwcm9mdXNlIERFQlVHIG1lc3NhZ2luZworICAgICAgICAgICAgICAgKFRpbSBTZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEwNjQgIEhCYXNlIFJFU1QgeG1sL2pzb24gaW1wcm92ZW1lbnRzIChCcmlhbiBCZWdncyB3b3JraW5nIG9mCisgICAgICAgICAgICAgICBpbml0aWFsIE1pY2hhZWwgR290dGVzbWFuIHdvcmsgdmlhIFN0YWNrKQorICAgSEJBU0UtNTEyMSAgRml4IHNoZWxsIHVzYWdlIGZvciBmb3JtYXQud2lkdGgKKyAgIEhCQVNFLTg0NSAgIEhDTS5pc1RhYmxlRW5hYmxlZCBkb2Vzbid0IHJlYWxseSB0ZWxsIGlmIGl0IGlzLCBvciBub3QKKyAgIEhCQVNFLTkwMyAgIFtzaGVsbF0gQ2FuJ3Qgc2V0IHRhYmxlIGRlc2NyaXB0b3IgYXR0cmlidXRlcyB3aGVuIEkgYWx0ZXIgYQorICAgICAgICAgICAgICAgdGFibGUKKyAgIEhCQVNFLTExNjYgIHNhdmVWZXJzaW9uLnNoIGRvZXNuJ3Qgd29yayB3aXRoIGdpdCAoTml0YXkgSm9mZmUgdmlhIFN0YWNrKQorICAgSEJBU0UtMTE2NyAgSlNQIGRvZXNuJ3Qgd29yayBpbiBhIGdpdCBjaGVja291dCAoTml0YXkgSm9mZmUgdmlhIEFuZHJldworICAgICAgICAgICAgICAgUHVydGVsbCkKKyAgIEhCQVNFLTExNzggIEFkZCBzaHV0ZG93biBjb21tYW5kIHRvIHNoZWxsCisgICBIQkFTRS0xMTg0ICBIQ29sdW1uRGVzY3JpcHRvciBpcyB0b28gcmVzdHJpY3RpdmUgd2l0aCBmYW1pbHkgbmFtZXMKKyAgICAgICAgICAgICAgIChUb2J5IFdoaXRlIHZpYSBBbmRyZXcgUHVydGVsbCkKKyAgIEhCQVNFLTExODAgIEFkZCBtaXNzaW5nIGltcG9ydCBzdGF0ZW1lbnRzIHRvIFNhbXBsZVVwbG9hZGVyIGFuZCByZW1vdmUKKyAgICAgICAgICAgICAgIHVubmVjZXNzYXJ5IEBPdmVycmlkZXMgKFJ5YW4gU21pdGggdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTE5MSAgWm9vS2VlcGVyIGVuc3VyZVBhcmVudEV4aXN0cyBjYWxscyBmYWlsIAorICAgICAgICAgICAgICAgb24gYWJzb2x1dGUgcGF0aCAoTml0YXkgSm9mZmUgdmlhIEplYW4tRGFuaWVsIENyeWFucykKKyAgIEhCQVNFLTExODcgIEFmdGVyIGRpc2FibGluZy9lbmFibGluZyBhIHRhYmxlLCB0aGUgcmVnaW9ucyBzZWVtcyB0byAKKyAgICAgICAgICAgICAgIGJlIGFzc2lnbmVkIHRvIG9ubHkgMS0yIHJlZ2lvbiBzZXJ2ZXJzCisgICBIQkFTRS0xMjEwICBBbGxvdyB0cnVuY2F0aW9uIG9mIG91dHB1dCBmb3Igc2NhbiBhbmQgZ2V0IGNvbW1hbmRzIGluIHNoZWxsCisgICAgICAgICAgICAgICAoTGFycyBHZW9yZ2UgdmlhIFN0YWNrKQorICAgSEJBU0UtMTIyMSAgV2hlbiB1c2luZyBhbnQgLXByb2plY3RoZWxwIHRvIGJ1aWxkIEhCYXNlIG5vdCBhbGwgdGhlIGltcG9ydGFudAorICAgICAgICAgICAgICAgb3B0aW9ucyBzaG93IHVwIChFcmlrIEhvbHN0YWQgdmlhIFN0YWNrKQorICAgSEJBU0UtMTE4OSAgQ2hhbmdpbmcgdGhlIG1hcCB0eXBlIHVzZWQgaW50ZXJuYWxseSBmb3IgSGJhc2VNYXBXcml0YWJsZQorICAgICAgICAgICAgICAgKEVyaWsgSG9sc3RhZCB2aWEgU3RhY2spCisgICBIQkFTRS0xMTg4ICBNZW1vcnkgc2l6ZSBvZiBKYXZhIE9iamVjdHMgLSBNYWtlIGNhY2hlYWJsZSBvYmplY3RzIGltcGxlbWVudAorICAgICAgICAgICAgICAgSGVhcFNpemUgKEVyaWsgSG9sc3RhZCB2aWEgU3RhY2spCisgICBIQkFTRS0xMjMwICBEb2N1bWVudCBpbnN0YWxsYXRpb24gb2YgSEJhc2Ugb24gV2luZG93cworICAgSEJBU0UtMTI0MSAgSEJhc2UgYWRkaXRpb25zIHRvIFpvb0tlZXBlciBwYXJ0IDEgKE5pdGF5IEpvZmZlIHZpYSBKRCkKKyAgIEhCQVNFLTEyMzEgIFRvZGF5LCBnb2luZyBmcm9tIGEgUm93UmVzdWx0IHRvIGEgQmF0Y2hVcGRhdGUgcmVxaXVyZXMgc29tZQorICAgICAgICAgICAgICAgZGF0YSBwcm9jZXNzaW5nIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHByZXR0eSBtdWNoIHRoZSBzYW1lIHRoaW5nCisgICAgICAgICAgICAgICAoRXJpayBIb2xzdGFkIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyNDAgIFdvdWxkIGJlIG5pY2UgaWYgUm93UmVzdWx0IGNvdWxkIGJlIGNvbXBhcmFibGUKKyAgICAgICAgICAgICAgIChFcmlrIEhvbHN0YWQgdmlhIFN0YWNrKQorICAgSEJBU0UtODAzICAgQXRvbWljIGluY3JlbWVudCBvcGVyYXRpb25zIChSeWFuIFJhd3NvbiBhbmQgSm9uIEdyYXkgdmlhIFN0YWNrKQorICAgICAgICAgICAgICAgUGFydCAxIGFuZCBwYXJ0IDIgLS0gZml4IGZvciBhIGNyYXNoLgorICAgSEJBU0UtMTI1MiAgTWFrZSBhdG9taWMgaW5jcmVtZW50IHBlcmZvcm0gYSBiaW5hcnkgaW5jcmVtZW50CisgICAgICAgICAgICAgICAoSm9uYXRoYW4gR3JheSB2aWEgU3RhY2spCisgICBIQkFTRS0xMjU4LDEyNTkgZ2FuZ2xpYSBtZXRyaWNzIGZvciAncmVxdWVzdHMnIGlzIGNvbmZ1c2luZworICAgICAgICAgICAgICAgKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyNjUgIEhMb2dFZGl0IHN0YXRpYyBjb25zdGFudHMgc2hvdWxkIGJlIGZpbmFsIChOaXRheSBKb2ZmZSB2aWEKKyAgICAgICAgICAgICAgIFN0YWNrKQorICAgSEJBU0UtMTI0NCAgWm9vS2VlcGVyV3JhcHBlciBjb25zdGFudHMgY2xlYW51cCAoTml0YXkgSm9mZmUgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI2MiAgRWNsaXBzZSB3YXJuaW5ncywgaW5jbHVkaW5nIHBlcmZvcm1hbmNlIHJlbGF0ZWQgdGhpbmdzIGxpa2UKKyAgICAgICAgICAgICAgIHN5bnRoZXRpYyBhY2Nlc3NvcnMgKE5pdGF5IEpvZmZlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEyNzMgIFpvb0tlZXBlciBXQVJOIHNwaXRzIG91dCBsb3RzIG9mIHVzZWxlc3MgbWVzc2FnZXMKKyAgICAgICAgICAgICAgIChOaXRheSBKb2ZmZSB2aWEgU3RhY2spCisgICBIQkFTRS0xMjg1ICBGb3JjaW5nIGNvbXBhY3Rpb25zIHNob3VsZCBiZSBhdmFpbGFibGUgdmlhIHRocmlmdAorICAgICAgICAgICAgICAgKFRpbSBTZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTExODYgIE1lbW9yeS1hd2FyZSBNYXBzIHdpdGggTFJVIGV2aWN0aW9uIGZvciBjZWxsIGNhY2hlIAorICAgICAgICAgICAgICAgKEpvbmF0aGFuIEdyYXkgdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTIwNSAgUmVnaW9uU2VydmVycyBzaG91bGQgZmluZCBuZXcgbWFzdGVyIHdoZW4gYSBuZXcgbWFzdGVyIGNvbWVzIHVwCisgICAgICAgICAgICAgICAoTml0YXkgSm9mZmUgdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTMwOSAgSEZpbGUgcmVqZWN0cyBrZXkgaW4gTWVtY2FjaGUgd2l0aCBlbXB0eSB2YWx1ZQorICAgSEJBU0UtMTMzMSAgTG93ZXIgdGhlIGRlZmF1bHQgc2Nhbm5lciBjYWNoaW5nIHZhbHVlCisgICBIQkFTRS0xMjM1ICBBZGQgdGFibGUgZW5hYmxlZCBzdGF0dXMgdG8gc2hlbGwgYW5kIFVJCisgICAgICAgICAgICAgICAoTGFycyBHZW9yZ2UgdmlhIFN0YWNrKQorICAgSEJBU0UtMTMzMyAgUm93Q291bnRlciB1cGRhdGVzCisgICBIQkFTRS0xMTk1ICBJZiBIQmFzZSBkaXJlY3RvcnkgZXhpc3RzIGJ1dCB2ZXJzaW9uIGZpbGUgaXMgaW5leGlzdGVudCwgc3RpbGwKKyAgICAgICAgICAgICAgIHByb2NlZWQgd2l0aCBib290c3RyYXBwaW5nIChFdmdlbnkgUnlhYml0c2tpeSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzAxICBIVGFibGUuZ2V0Um93KCkgcmV0dXJucyBudWxsIGlmIHRoZSByb3cgZG9lcyBubyBleGlzdAorICAgICAgICAgICAgICAgKFJvbmctZW4gRmFuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTExNzYgIEphdmFkb2NzIGluIEhCQSBzaG91bGQgYmUgY2xlYXIgYWJvdXQgd2hpY2ggZnVuY3Rpb25zIGFyZQorICAgICAgICAgICAgICAgYXN5bmNocm9ub3VzIGFuZCB3aGljaCBhcmUgc3luY2hyb25vdXMKKyAgICAgICAgICAgICAgIChFdmdlbnkgUnlhYml0c2tpeSB2aWEgU3RhY2spCisgICBIQkFTRS0xMjYwICBCeXRlcyB1dGlsaXR5IGNsYXNzIGNoYW5nZXM6IHJlbW92ZSB1c2FnZSBvZiBCeXRlQnVmZmVyIGFuZAorICAgICAgICAgICAgICAgcHJvdmlkZSBhZGRpdGlvbmFsIEJ5dGVCdWZmZXIgcHJpbWl0aXZlcyAoSm9uIEdyYXkgdmlhIFN0YWNrKQorICAgSEJBU0UtMTE4MyAgTmV3IE1SIHNwbGl0dGluZyBhbGdvcml0aG0gYW5kIG90aGVyIG5ldyBmZWF0dXJlcyBuZWVkIGEgd2F5IHRvCisgICAgICAgICAgICAgICBzcGxpdCBhIGtleSByYW5nZSBpbiBOIGNodW5rcyAoSm9uIEdyYXkgdmlhIFN0YWNrKQorICAgSEJBU0UtMTM1MCAgTmV3IG1ldGhvZCBpbiBIVGFibGUuamF2YSB0byByZXR1cm4gc3RhcnQgYW5kIGVuZCBrZXlzIGZvcgorICAgICAgICAgICAgICAgcmVnaW9ucyBpbiBhIHRhYmxlIChWaW1hbCBNYXRoZXcgdmlhIFN0YWNrKQorICAgSEJBU0UtMTI3MSAgQWxsb3cgbXVsdGlwbGUgdGVzdHMgdG8gcnVuIG9uIG9uZSBtYWNoaW5lCisgICAgICAgICAgICAgICAoRXZnZW55IFJ5YWJpdHNraXkgdmlhIFN0YWNrKQorICAgSEJBU0UtMTExMiAgd2Ugd2lsbCBsb3NlIGRhdGEgaWYgdGhlIHRhYmxlIG5hbWUgaGFwcGVucyB0byBiZSB0aGUgbG9ncycgZGlyCisgICAgICAgICAgICAgICBuYW1lIChTYW11ZWwgR3VvIHZpYSBTdGFjaykKKyAgIEhCQVNFLTg4OSAgIFRoZSBjdXJyZW50IFRocmlmdCBBUEkgZG9lcyBub3QgYWxsb3cgYSBuZXcgc2Nhbm5lciB0byBiZQorICAgICAgICAgICAgICAgY3JlYXRlZCB3aXRob3V0IHN1cHBseWluZyBhIGNvbHVtbiBsaXN0IHVubGlrZSB0aGUgb3RoZXIgQVBJcy4KKyAgICAgICAgICAgICAgIChUaW0gU2VsbCB2aWEgU3RhY2spCisgICBIQkFTRS0xMzQxICBIVGFibGUgcG9vbGVyCisgICBIQkFTRS0xMzc5ICByZS1lbmFibGUgTFpPIHVzaW5nIGhhZG9vcC1ncGwtY29tcHJlc3Npb24gbGlicmFyeQorICAgICAgICAgICAgICAgKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEzODMgIGhiYXNlIHNoZWxsIG5lZWRzIHRvIHdhcm4gb24gZGVsZXRpbmcgbXVsdGktcmVnaW9uIHRhYmxlCisgICBIQkFTRS0xMjg2ICBUaHJpZnQgc2hvdWxkIHN1cHBvcnQgbmV4dChuYlJvdykgbGlrZSBmdW5jdGlvbmFsaXR5CisgICAgICAgICAgICAgICAoQWxleCBOZXdtYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtMTM5MiAgY2hhbmdlIGhvdyB3ZSBidWlsZC9jb25maWd1cmUgbHpvY29kZWMgKFJ5YW4gUmF3c29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEzOTcgIEJldHRlciBkaXN0cmlidXRpb24gaW4gdGhlIFBlcmZvcm1hbmNlRXZhbHVhdGlvbiBNYXBSZWR1Y2UKKyAgICAgICAgICAgICAgIHdoZW4gcm93cyBydW4gdG8gdGhlIEJpbGxpb25zCisgICBIQkFTRS0xMzkzICBOYXJyb3cgc3luY2hyb25pemF0aW9uIGluIEhMb2cKKyAgIEhCQVNFLTE0MDQgIG1pbm9yIGVkaXQgb2YgcmVnaW9uc2VydmVyIGxvZ2dpbmcgbWVzc2FnZXMKKyAgIEhCQVNFLTE0MDUgIFRocmVhZHMuc2h1dGRvd24gaGFzIHVubmVjZXNzYXJ5IGJyYW5jaAorICAgSEJBU0UtMTQwNyAgQ2hhbmdpbmcgaW50ZXJuYWwgc3RydWN0dXJlIG9mIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUKKyAgICAgICAgICAgICAgIGNvbnRydWN0b3IgKEVyaWsgSG9sc3RhZCB2aWEgU3RhY2spCisgICBIQkFTRS0xMzQ1ICBSZW1vdmUgZGlzdHJpYnV0ZWQgbW9kZSBmcm9tIE1pbmlab29LZWVwZXIgKE5pdGF5IEpvZmZlIHZpYQorICAgICAgICAgICAgICAgU3RhY2spCisgICBIQkFTRS0xNDE0ICBBZGQgc2VydmVyIHN0YXR1cyBsb2dnaW5nIGNob3JlIHRvIFNlcnZlck1hbmFnZXIKKyAgIEhCQVNFLTEzNzkgIE1ha2UgS2V5VmFsdWUgaW1wbGVtZW50IFdyaXRhYmxlCisgICAgICAgICAgICAgICAoRXJpayBIb2xzdGFkIGFuZCBKb24gR3JheSB2aWEgU3RhY2spCisgICBIQkFTRS0xMzgwICBNYWtlIEtleVZhbHVlIGltcGxlbWVudCBIZWFwU2l6ZQorICAgICAgICAgICAgICAgKEVyaWsgSG9sc3RhZCBhbmQgSm9uIEdyYXkgdmlhIFN0YWNrKQorICAgSEJBU0UtMTQxMyAgRmFsbCBiYWNrIHRvIGZpbGVzeXN0ZW0gYmxvY2sgc2l6ZSBkZWZhdWx0IGlmIEhMb2cgYmxvY2tzaXplIGlzCisgICAgICAgICAgICAgICBub3Qgc3BlY2lmaWVkCisgICBIQkFTRS0xNDE3ICBDbGVhbnVwIGRpc29yaWVudGF0aW5nIFJQQyBtZXNzYWdlCisKKyAgT1BUSU1JWkFUSU9OUworICAgSEJBU0UtMTQxMiAgQ2hhbmdlIHZhbHVlcyBmb3IgZGVsZXRlIGNvbHVtbiBhbmQgY29sdW1uIGZhbWlseSBpbiBLZXlWYWx1ZQorCitSZWxlYXNlIDAuMTkuMCAtIDAxLzIxLzIwMDkKKyAgSU5DT01QQVRJQkxFIENIQU5HRVMKKyAgIEhCQVNFLTg4NSAgIFRhYmxlTWFwIGFuZCBUYWJsZVJlZHVjZSBzaG91bGQgYmUgaW50ZXJmYWNlcworICAgICAgICAgICAgICAgKERvxJ9hY2FuIEfDvG5leSB2aWEgU3RhY2spCisgICBIQkFTRS05MDUgICBSZW1vdmUgVjUgbWlncmF0aW9uIGNsYXNzZXMgZnJvbSAwLjE5LjAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEKKyAgICAgICAgICAgICAgIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS04NTIgICBDYW5ub3Qgc2NhbiBhbGwgZmFtaWxpZXMgaW4gYSByb3cgd2l0aCBhIExJTUlULCBTVEFSVFJPVywgZXRjLgorICAgICAgICAgICAgICAgKEl6YWFrIFJ1YmluIHZpYSBTdGFjaykKKyAgIEhCQVNFLTk1MyAgIEVuYWJsZSBCTE9DS0NBQ0hFIGJ5IGRlZmF1bHQgW1dBUyAtPiBSZWV2YWx1YXRlIEhCQVNFLTI4OCBibG9jaworICAgICAgICAgICAgICAgY2FjaGluZyB3b3JrLi4uLj9dIC0tIFVwZGF0ZSB5b3VyIGhiYXNlLWRlZmF1bHQueG1sIGZpbGUhCisgICBIQkFTRS02MzYgICBqYXZhNiBhcyBhIHJlcXVpcmVtZW50CisgICBIQkFTRS05OTQgICBJUEMgaW50ZXJmYWNlcyB3aXRoIGRpZmZlcmVudCB2ZXJzaW9ucyBjYW4gY2F1c2UgcHJvYmxlbXMKKyAgIEhCQVNFLTEwMjggIElmIGtleSBkb2VzIG5vdCBleGlzdCwgcmV0dXJuIG51bGwgaW4gZ2V0Um93IHJhdGhlciB0aGFuIGFuCisgICAgICAgICAgICAgICBlbXB0eSBSb3dSZXN1bHQKKyAgIEhCQVNFLTExMzQgIE9PTUUgaW4gSE1hc3RlciB3aGVuIEhCYXNlUlBDIGlzIG9sZGVyIHRoYW4gMC4xOQorCisgIEJVRyBGSVhFUworICAgSEJBU0UtODkxICAgSFJTLnZhbGlkYXRlVmFsdWVzTGVuZ3RoIHRocm93cyBJT0UsIGdldHMgY2F1Z2h0IGluIHRoZSByZXRyaWVzCisgICBIQkFTRS04OTIgICBDZWxsIGl0ZXJhdGlvbiBpcyBicm9rZW4gKERvxJ9hY2FuIEfDvG5leSB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTg5OCAgIFJvd1Jlc3VsdC5jb250YWluc0tleShTdHJpbmcpIGRvZXNuJ3Qgd29yaworICAgICAgICAgICAgICAgKERvxJ9hY2FuIEfDvG5leSB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTkwNiAgIFtzaGVsbF0gVHJ1bmNhdGVzIG91dHB1dAorICAgSEJBU0UtOTEyICAgUEUgaXMgYnJva2VuIHdoZW4gb3RoZXIgdGFibGVzIGV4aXN0CisgICBIQkFTRS04NTMgICBbc2hlbGxdIENhbm5vdCBkZXNjcmliZSBtZXRhIHRhYmxlcyAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtODQ0ICAgQ2FuJ3QgcGFzcyBzY3JpcHQgdG8gaGJhc2Ugc2hlbGwgCisgICBIQkFTRS04MzcgICBBZGQgdW5pdCB0ZXN0cyBmb3IgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlciAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtOTEzICAgQ2xhc3NlcyB1c2luZyBsb2c0aiBkaXJlY3RseQorICAgSEJBU0UtOTE0ICAgTVNHX1JFUE9SVF9DTE9TRSBoYXMgYSBieXRlIGFycmF5IGZvciBhIG1lc3NhZ2UKKyAgIEhCQVNFLTkxOCAgIFJlZ2lvbiBiYWxhbmNpbmcgZHVyaW5nIHN0YXJ0dXAgbWFrZXMgY2x1c3RlciB1bnN0YWJsZQorICAgSEJBU0UtOTIxICAgcmVnaW9uIGNsb3NlIGFuZCBvcGVuIHByb2Nlc3NlZCBvdXQgb2Ygb3JkZXI7IG1ha2VzIGZvciAKKyAgICAgICAgICAgICAgIGRpc2FncmVlbWVudCBiZXR3ZWVuIG1hc3RlciBhbmQgcmVnaW9uc2VydmVyIG9uIHJlZ2lvbiBzdGF0ZQorICAgSEJBU0UtOTI1ICAgSFJTIE5QRSBvbiB3YXkgb3V0IGlmIG5vIG1hc3RlciB0byBjb25uZWN0IHRvCisgICBIQkFTRS05MjggICBOUEUgdGhyb3dpbmcgUmV0cmllc0V4aGF1c3RlZEV4Y2VwdGlvbgorICAgSEJBU0UtOTI0ICAgVXBkYXRlIGhhZG9vcCBpbiBsaWIgb24gMC4xOCBoYmFzZSBicmFuY2ggdG8gMC4xOC4xCisgICBIQkFTRS05MjkgICBDbGFyaWZ5IHRoYXQgdHRsIGluIEhDb2x1bW5EZXNjcmlwdG9yIGlzIHNlY29uZHMKKyAgIEhCQVNFLTkzMCAgIFJlZ2lvblNlcnZlciBzdHVjazogSExvZzogQ291bGQgbm90IGFwcGVuZC4gUmVxdWVzdGluZyBjbG9zZSBvZgorICAgICAgICAgICAgICAgbG9nIGphdmEuaW8uSU9FeGNlcHRpb246IENvdWxkIG5vdCBnZXQgYmxvY2sgbG9jYXRpb25zLiBBYm9ydGluZy4uLgorICAgSEJBU0UtOTI2ICAgSWYgbm8gbWFzdGVyLCByZWdpb25zZXJ2ZXJzIHNob3VsZCBoYW5nIG91dCByYXRoZXIgdGhhbiBmYWlsIG9uCisgICAgICAgICAgICAgICBjb25uZWN0aW9uIGFuZCBzaHV0IHRoZW1zZWx2ZXMgZG93bgorICAgSEJBU0UtOTE5ICAgTWFzdGVyIGFuZCBSZWdpb24gU2VydmVyIG5lZWQgdG8gcHJvdmlkZSByb290IHJlZ2lvbiBsb2NhdGlvbiBpZgorICAgICAgICAgICAgICAgdGhleSBhcmUgdXNpbmcgSFRhYmxlCisgICAgICAgICAgICAgICBXaXRoIEotRCdzIG9uZSBsaW5lIHBhdGNoLCB0ZXN0IGNhc2VzIG5vdyBhcHBlYXIgdG8gd29yayBhbmQKKyAgICAgICAgICAgICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbiB3b3JrcyBhcyBiZWZvcmUuCisgICBIQkFTRS05MzkgICBOUEUgaW4gSFN0b3JlS2V5CisgICBIQkFTRS05NDUgICBCZSBjb25zaXN0ZW50IGluIHVzZSBvZiBxdWFsaWZpZWQvdW5xdWFsaWZpZWQgbWFwZmlsZSBwYXRocworICAgSEJBU0UtOTQ2ICAgUm93IHdpdGggNTVrIGRlbGV0ZXMgdGltZXNvdXQgc2Nhbm5lciBsZWFzZQorICAgSEJBU0UtOTUwICAgSFRhYmxlLmNvbW1pdCBubyBsb25nZXIgd29ya3Mgd2l0aCBleGlzdGluZyBSb3dMb2NrcyB0aG91Z2ggaXQncyBzdGlsbCBpbiBBUEkKKyAgIEhCQVNFLTk1MiAgIERlYWRsb2NrIGluIEhSZWdpb24uYmF0Y2hVcGRhdGUKKyAgIEhCQVNFLTk1NCAgIERvbid0IHJlYXNzaWduIHJvb3QgcmVnaW9uIHVudGlsIFByb2Nlc3NTZXJ2ZXJTaHV0ZG93biBoYXMgc3BsaXQKKyAgICAgICAgICAgICAgIHRoZSBmb3JtZXIgcmVnaW9uIHNlcnZlcidzIGxvZworICAgSEJBU0UtOTU3ICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uIHRlc3RzIGlmIHRhYmxlIGV4aXN0cyBieSBjb21wYXJpbmcgZGVzY3JpcHRvcnMKKyAgIEhCQVNFLTcyOCwgIEhCQVNFLTk1NiwgSEJBU0UtOTU1IEFkZHJlc3MgdGhyZWFkIG5hbWluZywgd2hpY2ggdGhyZWFkcyBhcmUKKyAgICAgICAgICAgICAgIENob3JlcywgdnMgVGhyZWFkcywgbWFrZSBITG9nIG1hbmFnZXIgdGhlIHdyaXRlIGFoZWFkIGxvZyBhbmQKKyAgICAgICAgICAgICAgIG5vdCBleHRlbmQgaXQgdG8gcHJvdmlkZWQgb3B0aW9uYWwgSExvZyBzeW5jIG9wZXJhdGlvbnMuCisgICBIQkFTRS05NzAgICBVcGRhdGUgdGhlIGNvcHkvcmVuYW1lIHNjcmlwdHMgdG8gZ28gYWdhaW5zdCBjaGFuZ2UgQVBJCisgICBIQkFTRS05NjYgICBIQkFTRS03NDggbWlzc2VzIHNvbWUgd3JpdGVzCisgICBIQkFTRS05NzEgICBGaXggdGhlIGZhaWxpbmcgdGVzdHMgb24gSHVkc29uCisgICBIQkFTRS05NzMgICBbZG9jXSBJbiBnZXR0aW5nIHN0YXJ0ZWQsIG1ha2UgaXQgY2xlYXIgdGhhdCBoYmFzZSBuZWVkcyB0bworICAgICAgICAgICAgICAgY3JlYXRlIGl0cyBkaXJlY3RvcnkgaW4gaGRmcworICAgSEJBU0UtOTYzICAgRml4IHRoZSByZXRyaWVzIGluIEhUYWJsZS5mbHVzaENvbW1pdAorICAgSEJBU0UtOTY5ICAgV29uJ3Qgd2hlbiBzdG9yZWZpbGUgPiAyRy4KKyAgIEhCQVNFLTk3NiAgIEhBRE9PUCAwLjE5LjAgUkMwIGlzIGJyb2tlOyByZXBsYWNlIHdpdGggSEVBRCBvZiBicmFuY2gtMC4xOQorICAgSEJBU0UtOTc3ICAgQXJjYW5lIEhTdG9yZUtleSBjb21wYXJhdG9yIGJ1ZworICAgSEJBU0UtOTc5ICAgUkVTVCB3ZWIgYXBwIGlzIG5vdCBzdGFydGVkIGF1dG9tYXRpY2FsbHkKKyAgIEhCQVNFLTk4MCAgIFVuZG8gY29yZSBvZiBIQkFTRS05NzUsIGNhY2hpbmcgb2Ygc3RhcnQgYW5kIGVuZCByb3cKKyAgIEhCQVNFLTk4MiAgIERlbGV0aW5nIGEgY29sdW1uIGluIE1hcFJlZHVjZSBmYWlscyAoRG/En2FjYW4gR8O8bmV5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTk4NCAgIEZpeCBqYXZhZG9jIHdhcm5pbmdzCisgICBIQkFTRS05ODUgICBGaXggamF2YWRvYyB3YXJuaW5ncworICAgSEJBU0UtOTUxICAgRWl0aGVyIHNodXQgZG93biBtYXN0ZXIgb3IgbGV0IGl0IGZpbmlzaCBjbGVhbnVwCisgICBIQkFTRS05NjQgICBTdGFydHVwIHN0dWNrICJ3YWl0aW5nIGZvciByb290IHJlZ2lvbiIKKyAgIEhCQVNFLTk2NCwgSEJBU0UtNjc4IHByb3ZpZGUgZm9yIHNhZmUtbW9kZSB3aXRob3V0IGxvY2tpbmcgdXAgSEJhc2UgIndhaXRpbmcKKyAgICAgICAgICAgICAgIGZvciByb290IHJlZ2lvbiIKKyAgIEhCQVNFLTk5MCAgIE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaW4gZmx1c2hTb21lUmVnaW9uczsgdG9vayB0d28gYXR0ZW1wdHMuCisgICBIQkFTRS02MDIgICBIQmFzZSBDcmFzaCB3aGVuIG5ldHdvcmsgY2FyZCBoYXMgYSBJUHY2IGFkZHJlc3MKKyAgIEhCQVNFLTk5NiAgIE1pZ3JhdGlvbiBzY3JpcHQgdG8gdXAgdGhlIHZlcnNpb25zIGluIGNhdGFsb2cgdGFibGVzCisgICBIQkFTRS05OTEgICBVcGRhdGUgdGhlIG1hcHJlZCBwYWNrYWdlIGRvY3VtZW50IGV4YW1wbGVzIHNvIHRoZXkgd29yayB3aXRoCisgICAgICAgICAgICAgICBUUlVOSy8wLjE5LjAuCisgICBIQkFTRS0xMDAzICBJZiBjZWxsIGV4Y2VlZHMgVFRMIGJ1dCBub3QgVkVSU0lPTnMsIHdpbGwgbm90IGJlIHJlbW92ZWQgZHVyaW5nCisgICAgICAgICAgICAgICBtYWpvciBjb21wYWN0aW9uCisgICBIQkFTRS0xMDA1ICBSZWdleCBhbmQgc3RyaW5nIGNvbXBhcmlzb24gb3BlcmF0b3JzIGZvciBDb2x1bW5WYWx1ZUZpbHRlcgorICAgSEJBU0UtOTEwICAgU2Nhbm5lciBtaXNzZXMgY29sdW1ucyAvIHJvd3Mgd2hlbiB0aGUgc2Nhbm5lciBpcyBvYnRhaW5lZAorICAgICAgICAgICAgICAgZHVyaW5nIGEgbWVtY2FjaGUgZmx1c2gKKyAgIEhCQVNFLTEwMDkgIE1hc3RlciBzdHVjayBpbiBsb29wIHdhbnRpbmcgdG8gYXNzaWduIGJ1dCByZWdpb25zIGFyZSBjbG9zaW5nCisgICBIQkFTRS0xMDE2ICBGaXggZXhhbXBsZSBpbiBqYXZhZG9jIG92ZXJ2aWUKKyAgIEhCQVNFLTEwMjEgIGhiYXNlIG1ldHJpY3MgRmlsZUNvbnRleHQgbm90IHdvcmtpbmcKKyAgIEhCQVNFLTEwMjMgIENoZWNrIGdsb2JhbCBmbHVzaGVyCisgICBIQkFTRS0xMDM2ICBIQkFTRS0xMDI4IGJyb2tlIFRocmlmdAorICAgSEJBU0UtMTAzNyAgU29tZSB0ZXN0IGNhc2VzIGZhaWxpbmcgb24gV2luZG93cy9DeWd3aW4gYnV0IG5vdCBVTklYL0xpbnV4CisgICBIQkFTRS0xMDQxICBNaWdyYXRpb24gdGhyb3dpbmcgTlBFCisgICBIQkFTRS0xMDQyICBPT01FIGJ1dCB3ZSBkb24ndCBhYm9ydDsgdHdvIHBhcnQgY29tbWl0LgorICAgSEJBU0UtOTI3ICAgV2UgZG9uJ3QgcmVjb3ZlciBpZiBIUlMgaG9zdGluZyAtUk9PVC0vLk1FVEEuIGdvZXMgZG93bgorICAgSEJBU0UtMTAyOSAgUkVTVCB3aWtpIGRvY3VtZW50YXRpb24gaW5jb3JyZWN0CisgICAgICAgICAgICAgICAoU2lzaGVuIEZyZWVjaXR5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTEwNDMgIFJlbW92aW5nIEBPdmVycmlkZSBhdHRyaWJ1dGVzIHdoZXJlIHRoZXkgYXJlIG5vIGxvbmdlciBuZWVkZWQuCisgICAgICAgICAgICAgICAoUnlhbiBTbWl0aCB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTkyNyAgIFdlIGRvbid0IHJlY292ZXIgaWYgSFJTIGhvc3RpbmcgLVJPT1QtLy5NRVRBLiBnb2VzIGRvd24gLQorICAgICAgICAgICAgICAgKGZpeCBidWcgaW4gY3JlYXRlVGFibGUgd2hpY2ggY2F1c2VkIHRlc3RzIHRvIGZhaWwpCisgICBIQkFTRS0xMDM5ICBDb21wYWN0aW9uIGZhaWxzIGlmIGJsb29tZmlsdGVycyBhcmUgZW5hYmxlZAorICAgSEJBU0UtMTAyNyAgTWFrZSBnbG9iYWwgZmx1c2hlciBjaGVjayB3b3JrIHdpdGggcGVyY2VudGFnZXMgcmF0aGVyIHRoYW4KKyAgICAgICAgICAgICAgIGhhcmQgY29kZSBtZW1vcnkgc2l6ZXMKKyAgIEhCQVNFLTEwMDAgIFNsZWVwZXIuc2xlZXAgZG9lcyBub3QgZ28gYmFjayB0byBzbGVlcCB3aGVuIGludGVycnVwdGVkCisgICAgICAgICAgICAgICBhbmQgbm8gc3RvcCBmbGFnIGdpdmVuLgorICAgSEJBU0UtOTAwICAgUmVnaW9uc2VydmVyIG1lbW9yeSBsZWFrIGNhdXNpbmcgT09NRSBkdXJpbmcgcmVsYXRpdmVseQorICAgICAgICAgICAgICAgbW9kZXN0IGJ1bGsgaW1wb3J0aW5nOyBwYXJ0IDEgYW5kIHBhcnQgMgorICAgSEJBU0UtMTA1NCAgSW5kZXggTlBFIG9uIHNjYW5uaW5nIChDbGludCBNb3JnYW4gdmlhIEFuZHJldyBQdXJ0ZWxsKQorICAgSEJBU0UtMTA1MiAgU3RvcHBpbmcgYSBIUmVnaW9uU2VydmVyIHdpdGggdW5mbHVzaGVkIGNhY2hlIGNhdXNlcyBkYXRhIGxvc3MKKyAgICAgICAgICAgICAgIGZyb20gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uCisgICBIQkFTRS0xMDU5ICBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGluIG5vdGlmeUNoYW5nZWRSZWFkZXJzT2JzZXJ2ZXJzCisgICBIQkFTRS0xMDYzICAiRmlsZSBzZXBhcmF0b3IgcHJvYmxlbSBvbiBXaW5kb3dzIiAoTWF4IExlaG4gdmlhIFN0YWNrKQorICAgSEJBU0UtMTA2OCAgVGVzdENvbXBhY3Rpb24gYnJva2VuIG9uIGh1ZHNvbgorICAgSEJBU0UtMTA2NyAgVGVzdFJlZ2lvblJlYmFsYW5jaW5nIGJyb2tlbiBieSBydW5uaW5nIG9mIGhkZnMgc2h1dGRvd24gdGhyZWFkCisgICBIQkFTRS0xMDcwICBVcCBkZWZhdWx0IGluZGV4IGludGVydmFsIGluIFRSVU5LIGFuZCBicmFuY2gKKyAgIEhCQVNFLTEwNDUgIEhhbmd1cCBieSByZWdpb25zZXJ2ZXIgY2F1c2VzIHdyaXRlIHRvIGZhaWwKKyAgIEhCQVNFLTEwNzkgIER1bWIgTlBFIGluIFNlcnZlckNhbGxhYmxlIGhpZGVzIHRoZSBSZXRyaWVzRXhoYXVzdGVkIGV4Y2VwdGlvbgorICAgSEJBU0UtNzgyICAgVGhlIERFTEVURSBrZXkgaW4gdGhlIGhiYXNlIHNoZWxsIGRlbGV0ZXMgdGhlIHdyb25nIGNoYXJhY3RlcgorICAgICAgICAgICAgICAgKFRpbSBTZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTU0MywgIEhCQVNFLTEwNDYsIEhCYXNlLTEwNTEgQSByZWdpb24ncyBzdGF0ZSBpcyBrZXB0IGluIHNldmVyYWwgcGxhY2VzCisgICAgICAgICAgICAgICBpbiB0aGUgbWFzdGVyIG9wZW5pbmcgdGhlIHBvc3NpYmlsaXR5IGZvciByYWNlIGNvbmRpdGlvbnMKKyAgIEhCQVNFLTEwODcgIERGUyBmYWlsdXJlcyBkaWQgbm90IHNodXRkb3duIHJlZ2lvbnNlcnZlcgorICAgSEJBU0UtMTA3MiAgQ2hhbmdlIFRocmVhZC5qb2luIG9uIGV4aXQgdG8gYSB0aW1lZCBUaHJlYWQuam9pbgorICAgSEJBU0UtMTA5OCAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOiBDYW5ub3Qgc2V0IGEgcmVnaW9uIHRvIGJlIGNsb3NlZCBpdCBpdAorICAgICAgICAgICAgICAgd2FzIG5vdCBhbHJlYWR5IG1hcmtlZCBhcyBjbG9zaW5nCisgICBIQkFTRS0xMTAwICBIQkFTRS0xMDYyIGJyb2tlIFRlc3RGb3JjZVNwbGl0CisgICBIQkFTRS0xMTkxICBzaGVsbCB0b29scyAtPiBjbG9zZV9yZWdpb24gZG9lcyBub3Qgd29yayBmb3IgcmVnaW9ucyB0aGF0IGRpZAorICAgICAgICAgICAgICAgbm90IGRlcGxveSBwcm9wZXJseSBvbiBzdGFydHVwCisgICBIQkFTRS0xMDkzICBOUEUgaW4gSFN0b3JlI2NvbXBhY3QKKyAgIEhCQVNFLTEwOTcgIFNlcXVlbmNlRmlsZS5SZWFkZXIga2VlcHMgYXJvdW5kIGJ1ZmZlciB3aG9zZSBzaXplIGlzIHRoYXQgb2YKKyAgICAgICAgICAgICAgIGxhcmdlc3QgaXRlbSByZWFkIC0+IHJlc3VsdHMgaW4gbG90cyBvZiBkZWFkIGhlYXAKKyAgIEhCQVNFLTExMDcgIE5QRSBpbiBIU3RvcmVTY2FubmVyLnVwZGF0ZVJlYWRlcnMKKyAgIEhCQVNFLTEwODMgIFdpbGwga2VlcCBzY2hlZHVsaW5nIG1ham9yIGNvbXBhY3Rpb25zIGlmIGxhc3QgdGltZSBvbmUgcmFuLCB3ZQorICAgICAgICAgICAgICAgZGlkbid0LgorICAgSEJBU0UtMTEwMSAgTlBFIGluIEhDb25uZWN0aW9uTWFuYWdlciRUYWJsZVNlcnZlcnMucHJvY2Vzc0JhdGNoT2ZSb3dzCisgICBIQkFTRS0xMDk5ICBSZWdpb25zIGFzc2lnbmVkIHdoaWxlIG1hc3RlciBpcyBzcGxpdHRpbmcgbG9ncyBvZiByZWNlbnRseQorICAgICAgICAgICAgICAgY3Jhc2hlZCBzZXJ2ZXI7IHJlZ2lvbnNlcnZlciB0cmllcyB0byBleGVjdXRlIGluY29tcGxldGUgbG9nCisgICBIQkFTRS0xMTA0LCBIQkFTRS0xMDk4LCBIQkFTRS0xMDk2OiBEb3VibHktYXNzaWduZWQgcmVnaW9ucyByZWR1eCwKKyAgICAgICAgICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjogQ2Fubm90IHNldCBhIHJlZ2lvbiB0byBiZSBjbG9zZWQgaXQgaXQgd2FzCisgICAgICAgICAgICAgICBub3QgYWxyZWFkeSBtYXJrZWQgYXMgY2xvc2luZywgRG9lcyBub3QgcmVjb3ZlciBpZiBIUlMgY2FycnlpbmcgCisgICAgICAgICAgICAgICAtUk9PVC0gZ29lcyBkb3duCisgICBIQkFTRS0xMTE0ICBXZWlyZCBOUEVzIGNvbXBhY3RpbmcKKyAgIEhCQVNFLTExMTYgIGdlbmVyYXRlZCB3ZWIueG1sIGFuZCBzdm4gZG9uJ3QgcGxheSBuaWNlIHRvZ2V0aGVyCisgICBIQkFTRS0xMTE5ICBBcnJheU91dE9mQm91bmRzRXhjZXB0aW9uIGluIEhTdG9yZS5jb21wYWN0CisgICBIQkFTRS0xMTIxICBDbHVzdGVyIGNvbmZ1c2VkIGFib3V0IHdoZXJlIC1ST09ULSBpcworICAgSEJBU0UtMTEyNSAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uOiBDYW5ub3Qgc2V0IGEgcmVnaW9uIHRvIGJlIGNsb3NlZCBpZiBpdCB3YXMKKyAgICAgICAgICAgICAgIG5vdCBhbHJlYWR5IG1hcmtlZCBhcyBwZW5kaW5nIGNsb3NlCisgICBIQkFTRS0xMTI0ICBCYWxhbmNlciBraWNrcyBpbiB3YXkgdG9vIGVhcmx5CisgICBIQkFTRS0xMTI3ICBPT01FIHJ1bm5pbmcgcmFuZG9tUmVhZCBQRQorICAgSEJBU0UtMTEzMiAgQ2FuJ3QgYXBwZW5kIHRvIEhMb2csIGNhbid0IHJvbGwgbG9nLCBpbmZpbml0ZSBjeWNsZSAoYW5vdGhlcgorICAgICAgICAgICAgICAgc3BpbiBvbiBIQkFTRS05MzApCisKKyAgSU1QUk9WRU1FTlRTCisgICBIQkFTRS05MDEgICBBZGQgYSBsaW1pdCB0byBrZXkgbGVuZ3RoLCBjaGVjayBrZXkgYW5kIHZhbHVlIGxlbmd0aCBvbiBjbGllbnQgc2lkZQorICAgSEJBU0UtODkwICAgQWx0ZXIgdGFibGUgb3BlcmF0aW9uIGFuZCBhbHNvIHJlbGF0ZWQgY2hhbmdlcyBpbiBSRVNUIGludGVyZmFjZQorICAgICAgICAgICAgICAgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS04OTQgICBbc2hlbGxdIFNob3VsZCBiZSBhYmxlIHRvIGNvcHktcGFzdGUgdGFibGUgZGVzY3JpcHRpb24gdG8gY3JlYXRlCisgICAgICAgICAgICAgICBuZXcgdGFibGUgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS04ODYsIEhCQVNFLTg5NSBTb3J0IHRoZSB0YWJsZXMgaW4gdGhlIHdlYiBVSSwgW3NoZWxsXSAnbGlzdCcgY29tbWFuZAorICAgICAgICAgICAgICAgc2hvdWxkIGVtaXQgYSBzb3J0ZWQgbGlzdCBvZiB0YWJsZXMgKEtyenlzenRvZiBTemxhcGluc2tpIHZpYSBTdGFjaykKKyAgIEhCQVNFLTg4NCAgIERvdWJsZSBhbmQgZmxvYXQgY29udmVydGVycyBmb3IgQnl0ZXMgY2xhc3MKKyAgICAgICAgICAgICAgIChEb8SfYWNhbiBHw7xuZXkgdmlhIFN0YWNrKQorICAgSEJBU0UtOTA4ICAgQWRkIGFwcHJveGltYXRlIGNvdW50aW5nIHRvIENvdW50aW5nQmxvb21GaWx0ZXIKKyAgICAgICAgICAgICAgIChBbmRyemVqIEJpYWxlY2tpIHZpYSBTdGFjaykKKyAgIEhCQVNFLTkyMCAgIE1ha2UgcmVnaW9uIGJhbGFuY2luZyBzbG9wcGllcgorICAgSEJBU0UtOTAyICAgQWRkIGZvcmNlIGNvbXBhY3Rpb24gYW5kIGZvcmNlIHNwbGl0IG9wZXJhdGlvbnMgdG8gVUkgYW5kIEFkbWluCisgICBIQkFTRS05NDIgICBBZGQgY29udmVuaWVuY2UgbWV0aG9kcyB0byBSb3dGaWx0ZXJTZXQKKyAgICAgICAgICAgICAgIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtOTQzICAgdG8gQ29sdW1uVmFsdWVGaWx0ZXI6IGFkZCBmaWx0ZXJJZkNvbHVtbk1pc3NpbmcgcHJvcGVydHksIGFkZAorICAgICAgICAgICAgICAgU3ViU3RyaW5nIG9wZXJhdG9yIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtOTM3ICAgVGhyaWZ0IGdldFJvdyBkb2VzIG5vdCBzdXBwb3J0IHNwZWNpZnlpbmcgY29sdW1ucworICAgICAgICAgICAgICAgKERvxJ9hY2FuIEfDvG5leSB2aWEgU3RhY2spCisgICBIQkFTRS05NTkgICBCZSBhYmxlIHRvIGdldCBtdWx0aXBsZSBSb3dSZXN1bHQgYXQgb25lIHRpbWUgZnJvbSBjbGllbnQgc2lkZQorICAgICAgICAgICAgICAgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS05MzYgICBSRVNUIEludGVyZmFjZTogZW5hYmxlIGdldCBudW1iZXIgb2Ygcm93cyBmcm9tIHNjYW5uZXIgaW50ZXJmYWNlCisgICAgICAgICAgICAgICAoU2lzaGVuIEZyZWVjaXR5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTk2MCAgIFJFU1QgaW50ZXJmYWNlOiBtb3JlIGdlbmVyaWMgY29sdW1uIGZhbWlseSBjb25maWd1cmUgYW5kIGFsc28KKyAgICAgICAgICAgICAgIGdldCBSb3dzIHVzaW5nIG9mZnNldCBhbmQgbGltaXQgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS04MTcgICBIYmFzZS9TaGVsbCBUcnVuY2F0ZQorICAgSEJBU0UtOTQ5ICAgQWRkIGFuIEhCYXNlIE1hbnVhbAorICAgSEJBU0UtODM5ICAgVXBkYXRlIGhhZG9vcCBsaWJzIGluIGhiYXNlOyBtb3ZlIGhiYXNlIFRSVU5LIG9uIHRvIGFuIGhhZG9vcAorICAgICAgICAgICAgICAgMC4xOS4wIFJDCisgICBIQkFTRS03ODUgICBSZW1vdmUgSW5mb1NlcnZlciwgdXNlIEhBRE9PUC0zODI0IFN0YXR1c0h0dHBTZXJ2ZXIgCisgICAgICAgICAgICAgICBpbnN0ZWFkIChyZXF1aXJlcyBoYWRvb3AgMC4xOSkKKyAgIEhCQVNFLTgxICAgIFdoZW4gYSBzY2FubmVyIGxlYXNlIHRpbWVzIG91dCwgdGhyb3cgYSBtb3JlICJ1c2VyIGZyaWVuZGx5IiBleGNlcHRpb24KKyAgIEhCQVNFLTk3OCAgIFJlbW92ZSBCbG9vbUZpbHRlckRlc2NyaXB0b3IuIEl0IGlzIG5vIGxvbmdlciB1c2VkLgorICAgSEJBU0UtOTc1ICAgSW1wcm92ZSBNYXBGaWxlIHBlcmZvcm1hbmNlIGZvciBzdGFydCBhbmQgZW5kIGtleQorICAgSEJBU0UtOTYxICAgRGVsZXRlIG11bHRpcGxlIGNvbHVtbnMgYnkgcmVndWxhciBleHByZXNzaW9uCisgICAgICAgICAgICAgICAoU2FtdWVsIEd1byB2aWEgU3RhY2spCisgICBIQkFTRS03MjIgICBTaHV0ZG93biBhbmQgQ29tcGFjdGlvbnMKKyAgIEhCQVNFLTk4MyAgIERlY2xhcmUgUGVybCBuYW1lc3BhY2UgaW4gSGJhc2UudGhyaWZ0CisgICBIQkFTRS05ODcgICBXZSBuZWVkIGEgSGJhc2UgUGFydGl0aW9uZXIgZm9yIFRhYmxlTWFwUmVkdWNlVXRpbC5pbml0VGFibGVSZWR1Y2VKb2IKKyAgICAgICAgICAgICAgIE1SIEpvYnMgKEJpbGx5IFBlYXJzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtOTkzICAgVHVybiBvZmYgbG9nZ2luZyBvZiBldmVyeSBjYXRhbG9nIHRhYmxlIHJvdyBlbnRyeSBvbiBldmVyeSBzY2FuCisgICBIQkFTRS05OTIgICBVcCB0aGUgdmVyc2lvbnMga2VwdCBieSBjYXRhbG9nIHRhYmxlczsgY3VycmVudGx5IDEuIE1ha2UgaXQgMTA/CisgICBIQkFTRS05OTggICBOYXJyb3cgZ2V0Q2xvc2VzdFJvd0JlZm9yZSBieSBwYXNzaW5nIGNvbHVtbiBmYW1pbHkKKyAgIEhCQVNFLTk5OSAgIFVwIHZlcnNpb25zIG9uIGhpc3RvcmlhbiBhbmQga2VlcCBoaXN0b3J5IG9mIGRlbGV0ZWQgcmVnaW9ucyBmb3IgYQorICAgICAgICAgICAgICAgd2hpbGUgcmF0aGVyIHRoYW4gZGVsZXRlIGltbWVkaWF0ZWx5CisgICBIQkFTRS05MzggICBNYWpvciBjb21wYWN0aW9uIHBlcmlvZCBpcyBub3QgY2hlY2tlZCBwZXJpb2RpY2FsbHkKKyAgIEhCQVNFLTk0NyAgIFtPcHRpbWl6YXRpb25dIE1ham9yIGNvbXBhY3Rpb24gc2hvdWxkIHJlbW92ZSBkZWxldGVzIGFzIHdlbGwgYXMKKyAgICAgICAgICAgICAgIHRoZSBkZWxldGVkIGNlbGwKKyAgIEhCQVNFLTY3NSAgIFJlcG9ydCBjb3JyZWN0IHNlcnZlciBob3N0aW5nIGEgdGFibGUgc3BsaXQgZm9yIGFzc2lnbm1lbnQgdG8KKyAgICAgICAgICAgICAgIGZvciBNUiBKb2JzCisgICBIQkFTRS05MjcgICBXZSBkb24ndCByZWNvdmVyIGlmIEhSUyBob3N0aW5nIC1ST09ULS8uTUVUQS4gZ29lcyBkb3duCisgICBIQkFTRS0xMDEzICBBZGQgZGVidWdnaW5nIGFyb3VuZCBjb21taXQgbG9nIGNsZWFudXAKKyAgIEhCQVNFLTk3MiAgIFVwZGF0ZSBoYmFzZSB0cnVuayB0byB1c2UgcmVsZWFzZWQgaGFkb29wIDAuMTkuMAorICAgSEJBU0UtMTAyMiAgQWRkIHN0b3JlZmlsZSBpbmRleCBzaXplIHRvIGhiYXNlIG1ldHJpY3MKKyAgIEhCQVNFLTEwMjYgIFRlc3RzIGluIG1hcHJlZCBhcmUgZmFpbGluZworICAgSEJBU0UtMTAyMCAgUmVnaW9uc2VydmVyIE9PTUUgaGFuZGxlciBzaG91bGQgZHVtcCB2aXRhbCBzdGF0cworICAgSEJBU0UtMTAxOCAgUmVnaW9uc2VydmVycyBzaG91bGQgcmVwb3J0IGRldGFpbGVkIGhlYWx0aCB0byBtYXN0ZXIKKyAgIEhCQVNFLTEwMzQgIFJlbW92ZSB1c2VsZXNzIFRlc3RUb1N0cmluZyB1bml0IHRlc3QKKyAgIEhCQVNFLTEwMzAgIEJpdCBvZiBwb2xpc2ggb24gSEJBU0UtMTAxOAorICAgSEJBU0UtODQ3ICAgbmV3IEFQSTogSFRhYmxlLmdldFJvdyB3aXRoIG51bVZlcnNpb24gc3BlY2lmaWVkCisgICAgICAgICAgICAgICAoRG/En2FjYW4gR8O8bmV5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTEwNDggIEhMb2c6IEZvdW5kIDAgbG9ncyB0byByZW1vdmUgb3V0IG9mIHRvdGFsIDE0NTA7IG9sZGVzdAorICAgICAgICAgICAgICAgb3V0c3RhbmRpbmcgc2VxbnVtIGlzIDE2MjI5NzA1MyBmciBvbSByZWdpb24gLVJPT1QtLCwwCisgICBIQkFTRS0xMDU1ICBCZXR0ZXIgdm0gc3RhdHMgb24gc3RhcnR1cAorICAgSEJBU0UtMTA2NSAgTWlub3IgbG9nZ2luZyBpbXByb3ZlbWVudHMgaW4gdGhlIG1hc3RlcgorICAgSEJBU0UtMTA1MyAgYnJpbmcgcmVjZW50IHJwYyBjaGFuZ2VzIGRvd24gZnJvbSBoYWRvb3AKKyAgIEhCQVNFLTEwNTYgIFttaWdyYXRpb25dIGVuYWJsZSBibG9ja2NhY2hpbmcgb24gLk1FVEEuIHRhYmxlCisgICBIQkFTRS0xMDY5ICBTaG93IHdoZXRoZXIgSFJlZ2lvbiBtYWpvciBjb21wYWN0cyBvciBub3QgaW4gSU5GTyBsZXZlbAorICAgSEJBU0UtMTA2NiAgTWFzdGVyIHNob3VsZCBzdXBwb3J0IGNsb3NlL29wZW4vcmVhc3NpZ25tZW50L2VuYWJsZS9kaXNhYmxlCisgICAgICAgICAgICAgICBvcGVyYXRpb25zIG9uIGluZGl2aWR1YWwgcmVnaW9ucworICAgSEJBU0UtMTA2MiAgQ29tcGFjdGlvbnMgYXQgKHJlKXN0YXJ0IG9uIGEgbGFyZ2UgdGFibGUgY2FuIG92ZXJ3aGVsbSBERlMKKyAgIEhCQVNFLTExMDIgIGJvb2xlYW4gSFRhYmxlLmV4aXN0cygpCisgICBIQkFTRS0xMTA1ICBSZW1vdmUgZHVwbGljYXRlZCBjb2RlIGluIEhDTSwgYWRkIGphdmFkb2MgdG8gUmVnaW9uU3RhdGUsIGV0Yy4KKyAgIEhCQVNFLTExMDYgIEV4cG9zZSBnZXRDbG9zZXN0Um93QmVmb3JlIGluIEhUYWJsZQorICAgICAgICAgICAgICAgKE1pY2hhZWwgR290dGVzbWFuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTEwODIgIEFkbWluaXN0cmF0aXZlIGZ1bmN0aW9ucyBmb3IgdGFibGUvcmVnaW9uIG1haW50ZW5hbmNlCisgICBIQkFTRS0xMDkwICBBdG9taWMgQ2hlY2sgQW5kIFNhdmUgaW4gSFRhYmxlIChNaWNoYWVsIEdvdHRlc21hbiB2aWEgU3RhY2spCisgICBIQkFTRS0xMTM3ICBBZGQgbm90IG9uIHhjZWl2ZXJzIGNvdW50IHRvIG92ZXJ2aWV3IGRvY3VtZW50YXRpb24KKworICBORVcgRkVBVFVSRVMKKyAgIEhCQVNFLTg3NSAgIFVzZSBNdXJtdXJIYXNoIGluc3RlYWQgb2YgSmVua2luc0hhc2ggW2luIGJsb29tZmlsdGVyc10KKyAgICAgICAgICAgICAgIChBbmRyemVqIEJpYWxlY2tpIHZpYSBTdGFjaykKKyAgIEhCQVNFLTYyNSAgIE1ldHJpY3Mgc3VwcG9ydCBmb3IgY2x1c3RlciBsb2FkIGhpc3Rvcnk6IGVtaXNzaW9ucyBhbmQgZ3JhcGhzCisgICBIQkFTRS04ODMgICBTZWNvbmRhcnkgaW5kZXhlcyAoQ2xpbnQgTW9yZ2FuIHZpYSBBbmRyZXcgUHVydGVsbCkKKyAgIEhCQVNFLTcyOCAgIFN1cHBvcnQgZm9yIEhMb2cgYXBwZW5kcworCisgIE9QVElNSVpBVElPTlMKKyAgIEhCQVNFLTc0OCAgIEFkZCBhbiBlZmZpY2llbnQgd2F5IHRvIGJhdGNoIHVwZGF0ZSBtYW55IHJvd3MKKyAgIEhCQVNFLTg4NyAgIEZpeCBhIGhvdHNwb3QgaW4gc2Nhbm5lcnMKKyAgIEhCQVNFLTk2NyAgIFtPcHRpbWl6YXRpb25dIENhY2hlIGNlbGwgbWF4aW11bSBsZW5ndGggKEhDRC5nZXRNYXhWYWx1ZUxlbmd0aCk7CisgICAgICAgICAgICAgICBpdHMgdXNlZCBjaGVja2luZyBiYXRjaCBzaXplCisgICBIQkFTRS05NDAgICBNYWtlIHRoZSBUYWJsZU91dHB1dEZvcm1hdCBiYXRjaGluZy1hd2FyZQorICAgSEJBU0UtNTc2ICAgSW52ZXN0aWdhdGUgSVBDIHBlcmZvcm1hbmNlCisKK1JlbGVhc2UgMC4xOC4wIC0gU2VwdGVtYmVyIDIxc3QsIDIwMDgKKworICBJTkNPTVBBVElCTEUgQ0hBTkdFUworICAgSEJBU0UtNjk3ICAgVGhyaWZ0IGlkbCBuZWVkcyB1cGRhdGUvZWRpdCB0byBtYXRjaCBuZXcgMC4yIEFQSSAoYW5kIHRvIGZpeCBidWdzKQorICAgICAgICAgICAgICAgKFRpbSBTZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTgyMiAgIFVwZGF0ZSB0aHJpZnQgUkVBRE1FIGFuZCBIQmFzZS50aHJpZnQgdG8gdXNlIHRocmlmdCAyMDA4MDQxMQorICAgICAgICAgICAgICAgVXBkYXRlZCBhbGwgb3RoZXIgbGFuZ3VhZ2VzIGV4YW1wbGVzIChvbmx5IHB5dGhvbiB3ZW50IGluKQorCisgIEJVRyBGSVhFUworICAgSEJBU0UtODgxICAgRml4ZWQgYnVnIHdoZW4gTWFzdGVyIHRyaWVzIHRvIHJlYXNzaWduIHNwbGl0IG9yIG9mZmxpbmUgcmVnaW9ucworICAgICAgICAgICAgICAgZnJvbSBhIGRlYWQgc2VydmVyCisgICBIQkFTRS04NjAgICBGaXhlZCBCdWcgaW4gSW5kZXhUYWJsZVJlZHVjZSB3aGVyZSBpdCBjb25jZXJucyB3cml0aW5nIGx1Y2VuZSAKKyAgICAgICAgICAgICAgIGluZGV4IGZpZWxkcy4KKyAgIEhCQVNFLTgwNSAgIFJlbW92ZSB1bm5lY2Vzc2FyeSBnZXRSb3cgb3ZlcmxvYWRzIGluIEhSUyAoSm9uYXRoYW4gR3JheSB2aWEKKyAgICAgICAgICAgICAgIEppbSBLZWxsZXJtYW4pIChGaXggd2hpdGVzcGFjZSBkaWZmcyBpbiBIUmVnaW9uU2VydmVyKQorICAgSEJBU0UtODExICAgSFREIGlzIG5vdCBmdWxseSBjb3B5YWJsZSAoQW5kcmV3IFB1cnRlbGwgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS03MjkgICBDbGllbnQgcmVnaW9uL21ldGFkYXRhIGNhY2hlIHNob3VsZCBoYXZlIGEgcHVibGljIG1ldGhvZCBmb3IKKyAgICAgICAgICAgICAgIGludmFsaWRhdGluZyBlbnRyaWVzIChBbmRyZXcgUHVydGVsbCB2aWEgU3RhY2spCisgICBIQkFTRS04MTkgICBSZW1vdmUgRE9TLXN0eWxlIF5NIGNhcnJpYWdlIHJldHVybnMgZnJvbSBhbGwgY29kZSB3aGVyZSBmb3VuZAorICAgICAgICAgICAgICAgKEpvbmF0aGFuIEdyYXkgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS04MTggICBEZWFkbG9jayBydW5uaW5nICdmbHVzaFNvbWVSZWdpb25zJyAoQW5kcmV3IFB1cnRlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtODIwICAgTmVlZCBtYWlubGluZSB0byBmbHVzaCB3aGVuICdCbG9ja2luZyB1cGRhdGVzJyBnb2VzIHVwLgorICAgICAgICAgICAgICAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS04MjEgICBVbmtub3duU2Nhbm5lciBoYXBwZW5zIHRvbyBvZnRlbiAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTgxMyAgIEFkZCBhIHJvdyBjb3VudGVyIGluIHRoZSBuZXcgc2hlbGwgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS04MjQgICBCdWcgaW4gSGxvZyB3ZSBwcmludCBhcnJheSBvZiBieWVzIGZvciByZWdpb24gbmFtZQorICAgICAgICAgICAgICAgKEJpbGx5IFBlYXJzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtODI1ICAgTWFzdGVyIGxvZ3Mgc2hvd2luZyBieXRlIFtdIGluIHBsYWNlIG9mIHN0cmluZyBpbiBsb2dnaW5nCisgICAgICAgICAgICAgICAoQmlsbHkgUGVhcnNvbiB2aWEgU3RhY2spCisgICBIQkFTRS04MDgsODA5IE1BWF9WRVJTSU9OUyBub3QgcmVzcGVjdGVkLCBhbmQgRGVsZXRhbGwgZG9lc24ndCBhbmQgaW5zZXJ0cworICAgICAgICAgICAgICAgYWZ0ZXIgZGVsZXRlIGRvbid0IHdvcmsgYXMgZXhwZWN0ZWQKKyAgICAgICAgICAgICAgIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIFN0YWNrKQorICAgSEJBU0UtODMxICAgY29tbWl0dGluZyBCYXRjaFVwZGF0ZSB3aXRoIG5vIHJvdyBzaG91bGQgY29tcGxhaW4KKyAgICAgICAgICAgICAgIChBbmRyZXcgUHVydGVsbCB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTgzMyAgIERvaW5nIGFuIGluc2VydCB3aXRoIGFuIHVua25vd24gZmFtaWx5IHRocm93cyBhIE5QRSBpbiBIUlMKKyAgIEhCQVNFLTgxMCAgIFByZXZlbnQgdGVtcG9yYXJ5IGRlYWRsb2NrcyB3aGVuLCBkdXJpbmcgYSBzY2FuIHdpdGggd3JpdGUKKyAgICAgICAgICAgICAgIG9wZXJhdGlvbnMsIHRoZSByZWdpb24gc3BsaXRzIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIEppbQorICAgICAgICAgICAgICAgS2VsbGVybWFuKQorICAgSEJBU0UtODQzICAgRGVsZXRpbmcgYW5kIHJlY3JlYXRpbmcgYSB0YWJsZSBpbiBhIHNpbmdsZSBwcm9jZXNzIGRvZXMgbm90IHdvcmsKKyAgICAgICAgICAgICAgIChKb25hdGhhbiBHcmF5IHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtODQ5ICAgU3BlZWQgaW1wcm92ZW1lbnQgaW4gSmVua2luc0hhc2ggKEFuZHJ6ZWogQmlhbGVja2kgdmlhIFN0YWNrKQorICAgSEJBU0UtNTUyICAgQmxvb20gZmlsdGVyIGJ1Z3MgKEFuZHJ6ZWogQmlhbGVja2kgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS03NjIgICBkZWxldGVGYW1pbHkgdGFrZXMgdGltZXN0YW1wLCBzaG91bGQgb25seSB0YWtlIHJvdyBhbmQgZmFtaWx5LgorICAgICAgICAgICAgICAgSmF2YWRvYyBkZXNjcmliZXMgYm90aCBjYXNlcyBidXQgb25seSBpbXBsZW1lbnRzIHRoZSB0aW1lc3RhbXAKKyAgICAgICAgICAgICAgIGNhc2UuIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS03NjggICBUaGlzIG1lc3NhZ2UgJ2phdmEuaW8uSU9FeGNlcHRpb246IEluc3RhbGwgMC4xLnggb2YgaGJhc2UgYW5kIHJ1bgorICAgICAgICAgICAgICAgaXRzIG1pZ3JhdGlvbiBmaXJzdCcgaXMgdXNlbGVzcyAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBKaW0KKyAgICAgICAgICAgICAgIEtlbGxlcm1hbikKKyAgIEhCQVNFLTgyNiAgIERlbGV0ZSB0YWJsZSBmb2xsb3dlZCBieSByZWNyZWF0aW9uIHJlc3VsdHMgaW4gaG9ua2VkIHRhYmxlCisgICBIQkFTRS04MzQgICAnTWFqb3InIGNvbXBhY3Rpb25zIGFuZCB1cHBlciBib3VuZCBvbiBmaWxlcyB3ZSBjb21wYWN0IGF0IGFueQorICAgICAgICAgICAgICAgb25lIHRpbWUgKEJpbGx5IFBlYXJzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtODM2ICAgVXBkYXRlIHRocmlmdCBleGFtcGxlcyB0byB3b3JrIHdpdGggY2hhbmdlZCBJREwgKEhCQVNFLTY5NykKKyAgICAgICAgICAgICAgIChUb2J5IFdoaXRlIHZpYSBTdGFjaykKKyAgIEhCQVNFLTg1NCAgIGhiYXNlLTg0MSBicm9rZSBidWlsZCBvbiBodWRzb24/IC0gbWFrZXMgc3VyZSB0aGF0IHByb3hpZXMgYXJlCisgICAgICAgICAgICAgICBjbG9zZWQuIChBbmRyZXcgUHVydGVsbCB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTg1NSAgIGNvbXBhY3Rpb24gY2FuIHJldHVybiBsZXNzIHZlcnNpb25zIHRoZW4gd2Ugc2hvdWxkIGluIHNvbWUgY2FzZXMKKyAgICAgICAgICAgICAgIChCaWxseSBQZWFyc29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTgzMiAgIFByb2JsZW0gd2l0aCByb3cga2V5cyBiZWdpbm5pZyB3aXRoIGNoYXJhY3RlcnMgPCB0aGFuICcsJyBhbmQKKyAgICAgICAgICAgICAgIHRoZSByZWdpb24gbG9jYXRpb24gY2FjaGUKKyAgIEhCQVNFLTg2NCAgIERlYWRsb2NrIGluIHJlZ2lvbnNlcnZlcgorICAgSEJBU0UtODY1ICAgRml4IGphdmFkb2Mgd2FybmluZ3MgKFJvbmctRW4gRmFuIHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtODcyICAgR2V0dGluZyBleGNlcHRpb25zIGluIHNoZWxsIHdoZW4gY3JlYXRpbmcvZGlzYWJsaW5nIHRhYmxlcworICAgSEJBU0UtODY4ICAgSW5jcmVtZW50aW5nIGJpbmFyeSByb3dzIGNhdXNlIHN0cmFuZ2UgYmVoYXZpb3Igb25jZSB0YWJsZQorICAgICAgICAgICAgICAgc3BsaXRzIChKb25hdGhhbiBHcmF5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTg3NyAgIEhDTSBpcyB1bmFibGUgdG8gZmluZCB0YWJsZSB3aXRoIG11bHRpcGxlIHJlZ2lvbnMgd2hpY2ggY29udGFpbnMKKyAgICAgICAgICAgICAgIGJpbmFyeSAoSm9uYXRoYW4gR3JheSB2aWEgU3RhY2spCisKKyAgSU1QUk9WRU1FTlRTCisgICBIQkFTRS04MDEgIFdoZW4gYSB0YWJsZSBoYXZlbid0IGRpc2FibGUsIHNoZWxsIGNvdWxkIHJlc3BvbnNlIGluIGEgInVzZXIKKyAgICAgICAgICAgICAgZnJpZW5kbHkiIHdheS4KKyAgIEhCQVNFLTgxNiAgVGFibGVNYXAgc2hvdWxkIHN1cnZpdmUgVVNFIChBbmRyZXcgUHVydGVsbCB2aWEgU3RhY2spCisgICBIQkFTRS04MTIgIENvbXBhY3Rpb24gbmVlZHMgbGl0dGxlIGJldHRlciBza2lwIGFsZ28gKERhbmllbCBMZWZmZWwgdmlhIFN0YWNrKQorICAgSEJBU0UtODA2ICBDaGFuZ2UgSGJhc2VNYXBXcml0YWJsZSBhbmQgUm93UmVzdWx0IHRvIGltcGxlbWVudCBTb3J0ZWRNYXAKKyAgICAgICAgICAgICAgaW5zdGVhZCBvZiBNYXAgKEpvbmF0aGFuIEdyYXkgdmlhIFN0YWNrKQorICAgSEJBU0UtNzk1ICBNb3JlIFRhYmxlIG9wZXJhdGlvbiBpbiBUYWJsZUhhbmRsZXIgZm9yIFJFU1QgaW50ZXJmYWNlOiBwYXJ0IDEKKyAgICAgICAgICAgICAgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS03OTUgIE1vcmUgVGFibGUgb3BlcmF0aW9uIGluIFRhYmxlSGFuZGxlciBmb3IgUkVTVCBpbnRlcmZhY2U6IHBhcnQgMgorICAgICAgICAgICAgICAoU2lzaGVuIEZyZWVjaXR5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTgzMCAgRGVidWdnaW5nIEhDTS5sb2NhdGVSZWdpb25Jbk1ldGEgaXMgcGFpbmZ1bAorICAgSEJBU0UtNzg0ICBCYXNlIGhiYXNlLTAuMy4wIG9uIGhhZG9vcC0wLjE4CisgICBIQkFTRS04NDEgIENvbnNvbGlkYXRlIG11bHRpcGxlIG92ZXJsb2FkZWQgbWV0aG9kcyBpbiBIUmVnaW9uSW50ZXJmYWNlLAorICAgICAgICAgICAgICBIUmVnaW9uU2VydmVyIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS04NDAgIE1vcmUgb3B0aW9ucyBvbiB0aGUgcm93IHF1ZXJ5IGluIFJFU1QgaW50ZXJmYWNlCisgICAgICAgICAgICAgIChTaXNoZW4gRnJlZWNpdHkgdmlhIFN0YWNrKQorICAgSEJBU0UtODc0ICBkZWxldGluZyBhIHRhYmxlIGtpbGxzIGNsaWVudCBycGM7IG5vIHN1YnNlcXVlbnQgY29tbXVuaWNhdGlvbiBpZgorICAgICAgICAgICAgICBzaGVsbCBvciB0aHJpZnQgc2VydmVyLCBldGMuIChKb25hdGhhbiBHcmF5IHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtODcxICBNYWpvciBjb21wYWN0aW9uIHBlcmlvZGljaXR5IHNob3VsZCBiZSBzcGVjaWZ5YWJsZSBhdCB0aGUgY29sdW1uCisgICAgICAgICAgICAgIGZhbWlseSBsZXZlbCwgbm90IGNsdXN0ZXIgd2lkZSAoSm9uYXRoYW4gR3JheSB2aWEgU3RhY2spCisgICBIQkFTRS00NjUgIEZpeCBqYXZhZG9jIGZvciBhbGwgcHVibGljIGRlY2xhcmF0aW9ucworICAgSEJBU0UtODgyICBUaGUgQmF0Y2hVcGRhdGUgY2xhc3MgcHJvdmlkZXMsIHB1dChjb2wsIGNlbGwpIGFuZCBkZWxldGUoY29sKQorICAgICAgICAgICAgICBidXQgbm8gZ2V0KCkgKFJ5YW4gU21pdGggdmlhIFN0YWNrIGFuZCBKaW0gS2VsbGVybWFuKQorCisgIE5FVyBGRUFUVVJFUworICAgSEJBU0UtNzg3ICBQb3N0Z3Jlc3FsIHRvIEhCYXNlIHRhYmxlIHJlcGxpY2F0aW9uIGV4YW1wbGUgKFRpbSBTZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTc5OCAgUHJvdmlkZSBDbGllbnQgQVBJIHRvIGV4cGxpY2l0bHkgbG9jayBhbmQgdW5sb2NrIHJvd3MgKEpvbmF0aGFuCisgICAgICAgICAgICAgIEdyYXkgdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS03OTggIEFkZCBtaXNzaW5nIGNsYXNzZXM6IFVua25vd25Sb3dMb2NrRXhjZXB0aW9uIGFuZCBSb3dMb2NrIHdoaWNoCisgICAgICAgICAgICAgIHdlcmUgcHJlc2VudCBpbiBwcmV2aW91cyB2ZXJzaW9ucyBvZiB0aGUgcGF0Y2hlcyBmb3IgdGhpcyBpc3N1ZSwKKyAgICAgICAgICAgICAgYnV0IG5vdCBpbiB0aGUgdmVyc2lvbiB0aGF0IHdhcyBjb21taXR0ZWQuIEFsc28gZml4IGEgbnVtYmVyIG9mCisgICAgICAgICAgICAgIGNvbXBpbGF0aW9uIHByb2JsZW1zIHRoYXQgd2VyZSBpbnRyb2R1Y2VkIGJ5IHBhdGNoLgorICAgSEJBU0UtNjY5ICBNdWx0aVJlZ2lvbiB0cmFuc2FjdGlvbnMgd2l0aCBPcHRpbWlzdGljIENvbmN1cnJlbmN5IENvbnRyb2wKKyAgICAgICAgICAgICAgKENsaW50IE1vcmdhbiB2aWEgU3RhY2spCisgICBIQkFTRS04NDIgIFJlbW92ZSBtZXRob2RzIHRoYXQgaGF2ZSBUZXh0IGFzIGEgcGFyYW1ldGVyIGFuZCB3ZXJlIGRlcHJlY2F0ZWQKKyAgICAgICAgICAgICAgaW4gMC4yLjEgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgSmltIEtlbGxlcm1hbikKKworICBPUFRJTUlaQVRJT05TCisKK1JlbGVhc2UgMC4yLjAgLSBBdWd1c3QgOCwgMjAwOC4KKworICBJTkNPTVBBVElCTEUgQ0hBTkdFUworICAgSEJBU0UtNTg0ICAgTmFtZXMgaW4gdGhlIGZpbHRlciBpbnRlcmZhY2UgYXJlIGNvbmZ1c2luZyAoQ2xpbnQgTW9yZ2FuIHZpYQorICAgICAgICAgICAgICAgSmltIEtlbGxlcm1hbikgKEFQSSBjaGFuZ2UgZm9yIGZpbHRlcnMpCisgICBIQkFTRS02MDEgICBKdXN0IHJlbW92ZSBkZXByZWNhdGVkIG1ldGhvZHMgaW4gSFRhYmxlOyAwLjIgaXMgbm90IGJhY2t3YXJkCisgICAgICAgICAgICAgICBjb21wYXRpYmxlIGFueXdheXMKKyAgIEhCQVNFLTgyICAgIFJvdyBrZXlzIHNob3VsZCBiZSBhcnJheSBvZiBieXRlcworICAgSEJBU0UtNzYgICAgUHVyZ2Ugc2VydmVycyBvZiBUZXh0IChEb25lIGFzIHBhcnQgb2YgSEJBU0UtODIgY29tbWl0KS4KKyAgIEhCQVNFLTQ4NyAgIFJlcGxhY2UgaHFsIHcvIGEgaGJhc2UtZnJpZW5kbHkgamlyYiBvciBqeXRob24gc2hlbGwKKyAgICAgICAgICAgICAgIFBhcnQgMTogcHVyZ2Ugb2YgaHFsIGFuZCBhZGRlZCByYXcgamlyYiBpbiBpdHMgcGxhY2UuCisgICBIQkFTRS01MjEgICBJbXByb3ZlIGNsaWVudCBzY2FubmVyIGludGVyZmFjZQorICAgSEJBU0UtMjg4ICAgQWRkIGluLW1lbW9yeSBjYWNoaW5nIG9mIGRhdGEuIFJlcXVpcmVkIHVwZGF0ZSBvZiBoYWRvb3AgdG8gCisgICAgICAgICAgICAgICAwLjE3LjAtZGV2LjIwMDgtMDItMDdfMTItMDEtNTguIChUb20gV2hpdGUgdmlhIFN0YWNrKSAKKyAgIEhCQVNFLTY5NiAgIE1ha2UgYmxvb21maWx0ZXIgdHJ1ZS9mYWxzZSBhbmQgc2VsZi1zaXppbmcKKyAgIEhCQVNFLTcyMCAgIGNsZWFuIHVwIGluY29uc2lzdGVuY2llcyBhcm91bmQgZGVsZXRlcyAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNzk2ICAgRGVwcmVjYXRlcyBUZXh0IG1ldGhvZHMgZnJvbSBIVGFibGUKKyAgICAgICAgICAgICAgIChNaWNoYWVsIEdvdHRlc21hbiB2aWEgU3RhY2spCisKKyAgQlVHIEZJWEVTCisgICBIQkFTRS01NzQgICBIQmFzZSBkb2VzIG5vdCBsb2FkIGhhZG9vcCBuYXRpdmUgbGlicyAoUm9uZy1FbiBGYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNTk4ICAgTG9nZ2dpbmcsIG5vIC5sb2cgZmlsZTsgYWxsIGdvZXMgaW50byAub3V0CisgICBIQkFTRS02MjIgICBSZW1vdmUgU3RhdGljVGVzdEVudmlyb25tZW50IGFuZCBwdXQgYSBsb2c0ai5wcm9wZXJ0aWVzIGluIHNyYy90ZXN0CisgICBIQkFTRS02MjQgICBNYXN0ZXIgd2lsbCBzaHV0IGRvd24gaWYgbnVtYmVyIG9mIGFjdGl2ZSByZWdpb24gc2VydmVycyBpcyB6ZXJvCisgICAgICAgICAgICAgICBldmVuIGlmIHNodXRkb3duIHdhcyBub3QgcmVxdWVzdGVkCisgICBIQkFTRS02MjkgICBTcGxpdCByZXBvcnRzIGluY29ycmVjdCBlbGFwc2VkIHRpbWUKKyAgIEhCQVNFLTYyMyAgIE1pZ3JhdGlvbiBzY3JpcHQgZm9yIGhiYXNlLTgyCisgICBIQkFTRS02MzAgICBEZWZhdWx0IGhiYXNlLnJvb3RkaXIgaXMgZ2FyYmFnZQorICAgSEJBU0UtNTg5ICAgUmVtb3ZlIHJlZmVyZW5jZXMgdG8gZGVwcmVjYXRlZCBtZXRob2RzIGluIEhhZG9vcCBvbmNlCisgICAgICAgICAgICAgICBoYWRvb3AtMC4xNy4wIGlzIHJlbGVhc2VkCisgICBIQkFTRS02MzggICBQdXJnZSBcciBmcm9tIHNyYworICAgSEJBU0UtNjQ0ICAgRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uIGJ1dCBSZWdpb25TZXJ2ZXIgZG9lc24ndCByZXN0YXJ0CisgICBIQkFTRS02NDEgICBJbXByb3ZlIG1hc3RlciBzcGxpdCBsb2dnaW5nCisgICBIQkFTRS02NDIgICBTcGxpdHRpbmcgbG9nIGluIGEgaG9zdGlsZSBlbnZpcm9ubWVudCAtLSBiYWQgaGRmcyAtLSB3ZSBkcm9wCisgICAgICAgICAgICAgICB3cml0ZS1haGVhZC1sb2cgZWRpdHMKKyAgIEhCQVNFLTY0NiAgIEVPRkV4Y2VwdGlvbiBvcGVuaW5nIEhTdG9yZUZpbGUgaW5mbyBmaWxlIChzcGluIG9uIEhCQVNFLTY0NWFuZCA1NTApCisgICBIQkFTRS02NDggICBJZiBtYXBmaWxlIGluZGV4IGlzIGVtcHR5LCBydW4gcmVwYWlyCisgICBIQkFTRS02NDAgICBUZXN0TWlncmF0ZSBmYWlsaW5nIG9uIGh1ZHNvbgorICAgSEJBU0UtNjUxICAgVGFibGUuY29tbWl0IHNob3VsZCB0aHJvdyBOb1N1Y2hDb2x1bW5GYW1pbHlFeGNlcHRpb24gaWYgY29sdW1uCisgICAgICAgICAgICAgICBmYW1pbHkgZG9lc24ndCBleGlzdAorICAgSEJBU0UtNjQ5ICAgQVBJIHBvbGx1dGVkIHdpdGggZGVmYXVsdCBhbmQgcHJvdGVjdGVkIGFjY2VzcyBkYXRhIG1lbWJlcnMgYW5kIG1ldGhvZHMKKyAgIEhCQVNFLTY1MCAgIEFkZCBTdHJpbmcgdmVyc2lvbnMgb2YgZ2V0LCBzY2FubmVyLCBwdXQgaW4gSFRhYmxlCisgICBIQkFTRS02NTYgICBEbyBub3QgcmV0cnkgZXhjZXB0aW9ucyBzdWNoIGFzIHVua25vd24gc2Nhbm5lciBvciBpbGxlZ2FsIGFyZ3VtZW50CisgICBIQkFTRS02NTkgICBITG9nI2NhY2hlRmx1c2hMb2NrIG5vdCBjbGVhcmVkOyBoYW5ncyBhIHJlZ2lvbgorICAgSEJBU0UtNjYzICAgSW5jb3JyZWN0IHNlcXVlbmNlIG51bWJlciBmb3IgY2FjaGUgZmx1c2gKKyAgIEhCQVNFLTY1NSAgIE5lZWQgcHJvZ3JhbW1hdGljIHdheSB0byBhZGQgY29sdW1uIGZhbWlseTogbmVlZCBwcm9ncmFtbWF0aWMgd2F5CisgICAgICAgICAgICAgICB0byBlbmFibGUvZGlzYWJsZSB0YWJsZQorICAgSEJBU0UtNjU0ICAgQVBJIEhUYWJsZS5nZXRNZXRhZGF0YSgpLmFkZEZhbWlseSBzaG91bGRuJ3QgYmUgZXhwb3NlZCB0byB1c2VyCisgICBIQkFTRS02NjYgICBVbm1vZGlmeWFibGVIUmVnaW9uSW5mbyBnaXZlcyB0aGUgd3JvbmcgZW5jb2RlZCBuYW1lCisgICBIQkFTRS02NjggICBIQkFTRS01MzMgYnJva2UgYnVpbGQKKyAgIEhCQVNFLTY3MCAgIEhpc3RvcmlhbiBkZWFkbG9ja3MgaWYgcmVnaW9uc2VydmVyIGlzIGF0IGdsb2JhbCBtZW1vcnkgYm91bmRhcnkKKyAgICAgICAgICAgICAgIGFuZCBpcyBob3N0aW5nIC5NRVRBLgorICAgSEJBU0UtNjY1ICAgU2VydmVyIHNpZGUgc2Nhbm5lciBkb2Vzbid0IGhvbm9yIHN0b3Agcm93CisgICBIQkFTRS02NjIgICBVSSBpbiB0YWJsZS5qc3AgZ2l2ZXMgTUVUQSBsb2NhdGlvbnMsIG5vdCB0aGUgdGFibGUncyByZWdpb25zCisgICAgICAgICAgICAgICBsb2NhdGlvbiAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTY3NiAgIEJ5dGVzLmdldEludCByZXR1cm5zIGEgbG9uZyAoQ2xpbnQgTW9yZ2FuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTY4MCAgIENvbmZpZyBwYXJhbWV0ZXIgaGJhc2UuaW8uaW5kZXguaW50ZXJ2YWwgIHNob3VsZCBiZQorICAgICAgICAgICAgICAgaGJhc2UuaW5kZXguaW50ZXJ2YWwsIGFjY29yZGluZyB0byBIQmFzZU1hcEZpbGUuSGJhc2VXcml0ZXIKKyAgICAgICAgICAgICAgIChMTiB2aWEgU3RhY2spCisgICBIQkFTRS02ODIgICBVbm5lY2Vzc2FyeSBpdGVyYXRpb24gaW4gSE1lbWNhY2hlLmludGVybmFsR2V0PyBnb3QgbXVjaCBiZXR0ZXIKKyAgICAgICAgICAgICAgIHJlYWRpbmcgcGVyZm9ybWFuY2UgYWZ0ZXIgYnJlYWsgaXQgKExOIHZpYSBTdGFjaykKKyAgIEhCQVNFLTY4NiAgIE1lbWNhY2hlU2Nhbm5lciBkaWRuJ3QgcmV0dXJuIHRoZSBmaXJzdCByb3coaWYgaXQgZXhpc3RzKSwKKyAgICAgICAgICAgICAgIGJlY2F1c2UgSFNjYW5uZXJJbnRlcmZhY2UncyBvdXRwdXQgaW5jb3JyZWN0IChMTiB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTY5MSAgIGdldCogYW5kIGdldFNjYW5uZXIgYXJlIGRpZmZlcmVudCBpbiBob3cgdGhleSB0cmVhdCBjb2x1bW4gcGFyYW1ldGVyCisgICBIQkFTRS02OTQgICBIU3RvcmUucm93QXRPckJlZm9yZUZyb21NYXBGaWxlKCkgZmFpbHMgdG8gbG9jYXRlIHRoZSByb3cgaWYgIyBvZiBtYXBmaWxlcyA+PSAyCisgICAgICAgICAgICAgICAoUm9uZy1FbiBGYW4gdmlhIEJyeWFuKQorICAgSEJBU0UtNjUyICAgZHJvcHBpbmcgdGFibGUgZmFpbHMgc2lsZW50bHkgaWYgdGFibGUgaXNuJ3QgZGlzYWJsZWQKKyAgIEhCQVNFLTY4MyAgIGNhbiBub3QgZ2V0IHN2biByZXZpc2lvbiAjIGF0IGJ1aWxkIHRpbWUgaWYgbG9jYWxlIGlzIG5vdCBlbmdsaXNoCisgICAgICAgICAgICAgICAoUm9uZy1FbiBGYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNjk5ICAgRml4IFRlc3RNaWdyYXRlIHVwIG9uIEh1ZHNvbgorICAgSEJBU0UtNjE1ICAgUmVnaW9uIGJhbGFuY2VyIG9zY2lsbGF0ZXMgZHVyaW5nIGNsdXN0ZXIgc3RhcnR1cAorICAgSEJBU0UtNjEzICAgVGltZXN0YW1wLWFuY2hvcmVkIHNjYW5uaW5nIGZhaWxzIHRvIGZpbmQgYWxsIHJlY29yZHMKKyAgIEhCQVNFLTY4MSAgIE5QRSBpbiBNZW1jYWNoZQorICAgSEJBU0UtNzAxICAgU2hvd2luZyBieXRlcyBpbiBsb2cgd2hlbiBzaG91bGQgYmUgU3RyaW5nCisgICBIQkFTRS03MDIgICBkZWxldGVhbGwgZG9lc24ndAorICAgSEJBU0UtNzA0ICAgdXBkYXRlIG5ldyBzaGVsbCBkb2NzIGFuZCBjb21tYW5kcyBvbiBoZWxwIG1lbnUKKyAgIEhCQVNFLTcwOSAgIERlYWRsb2NrIHdoaWxlIHJvbGxpbmcgV0FMLWxvZyB3aGlsZSBmaW5pc2hpbmcgZmx1c2gKKyAgIEhCQVNFLTcxMCAgIElmIGNsb2NrcyBhcmUgd2F5IG9mZiwgdGhlbiB3ZSBjYW4gaGF2ZSBkYXVnaHRlciBzcGxpdCBjb21lCisgICAgICAgICAgICAgICBiZWZvcmUgcmF0aGVyIHRoYW4gYWZ0ZXIgaXRzIHBhcmVudCBpbiAuTUVUQS4KKyAgIEhCQVNFLTcxNCAgIFNob3dpbmcgYnl0ZXMgaW4gbG9nIHdoZW4gc2hvdWxkIGJlIHN0cmluZyAoMikKKyAgIEhCQVNFLTYyNyAgIERpc2FibGUgdGFibGUgZG9lc24ndCB3b3JrIHJlbGlhYmx5CisgICBIQkFTRS03MTYgICBUZXN0R2V0Mi50ZXN0R2V0Q2xvc2VzdEJlZm9yZSBmYWlscyB3aXRoIGhhZG9vcC0wLjE3LjEKKyAgIEhCQVNFLTcxNSAgIEJhc2UgSEJhc2UgMC4yIG9uIEhhZG9vcCAwLjE3LjEKKyAgIEhCQVNFLTcxOCAgIGhiYXNlIHNoZWxsIGhlbHAgaW5mbworICAgSEJBU0UtNzE3ICAgYWx0ZXIgdGFibGUgYnJva2Ugd2l0aCBuZXcgc2hlbGwgcmV0dXJucyBJbnZhbGlkQ29sdW1uTmFtZUV4Y2VwdGlvbgorICAgSEJBU0UtNTczICAgSEJhc2UgZG9lcyBub3QgcmVhZCBoYWRvb3AtKi54bWwgZm9yIGRmcyBjb25maWd1cmF0aW9uIGFmdGVyIAorICAgICAgICAgICAgICAgbW92aW5nIG91dCBoYWRvb3AvY29udHJpYgorICAgSEJBU0UtMTEgICAgVW5leHBlY3RlZCBleGl0cyBjb3JydXB0IERGUworICAgSEJBU0UtMTIgICAgV2hlbiBoYmFzZSByZWdpb25zZXJ2ZXIgcmVzdGFydHMsIGl0IHNheXMgImltcG9zc2libGUgc3RhdGUgZm9yCisgICAgICAgICAgICAgICBjcmVhdGVMZWFzZSgpIgorICAgSEJBU0UtNTc1ICAgbWFzdGVyIGRpZXMgd2l0aCBzdGFjayBvdmVyZmxvdyBlcnJvciBpZiByb290ZGlyIGlzbid0IHF1YWxpZmllZAorICAgSEJBU0UtNTgyICAgSEJhc2UgNTU0IGZvcmdvdCB0byBjbGVhciByZXN1bHRzIG9uIGVhY2ggaXRlcmF0aW9uIGNhdXNlZCBieSBhIGZpbHRlcgorICAgICAgICAgICAgICAgKENsaW50IE1vcmdhbiB2aWEgU3RhY2spCisgICBIQkFTRS01MzIgICBPZGQgaW50ZXJhY3Rpb24gYmV0d2VlbiBIUmVnaW9uLmdldCwgSFJlZ2lvbi5kZWxldGVBbGwgYW5kIGNvbXBhY3Rpb25zCisgICBIQkFTRS0xMCAgICBIUmVnaW9uU2VydmVyIGhhbmdzIHVwb24gZXhpdCBkdWUgdG8gREZTQ2xpZW50IEV4Y2VwdGlvbgorICAgSEJBU0UtNTk1ICAgUm93RmlsdGVySW50ZXJmYWNlLnJvd1Byb2Nlc3NlZCgpIGlzIGNhbGxlZCAqYmVmb3JlKiBmaGUgZmluYWwKKyAgICAgICAgICAgICAgIGZpbHRlcmluZyBkZWNpc2lvbiBpcyBtYWRlIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNTg2ICAgSFJlZ2lvbiBydW5zIEhTdG9yZSBtZW1jYWNoZSBzbmFwc2hvdHRpbmcgLS0gZml4IGl0IHNvIG9ubHkgSFN0b3JlCisgICAgICAgICAgICAgICBrbm93cyBhYm91dCB3b3JraW5ncyBvZiBtZW1jYWNoZQorICAgSEJBU0UtNTg4ICAgU3RpbGwgYSAnaG9sZScgaW4gc2Nhbm5lcnMsIGV2ZW4gYWZ0ZXIgSEJBU0UtNTMyCisgICBIQkFTRS02MDQgICBEb24ndCBhbGxvdyBDTEFTU1BBVEggZnJvbSBlbnZpcm9ubWVudCBwb2xsdXRlIHRoZSBoYmFzZSBDTEFTU1BBVEgKKyAgIEhCQVNFLTYwOCAgIEhSZWdpb25TZXJ2ZXI6OmdldFRoaXNJUCgpIGNoZWNrcyBoYWRvb3AgY29uZmlnIHZhciBmb3IgZG5zIGludGVyZmFjZSBuYW1lCisgICAgICAgICAgICAgICAoSmltIFIuIFdpbHNvbiB2aWEgU3RhY2spCisgICBIQkFTRS02MDkgICBNYXN0ZXIgZG9lc24ndCBzZWUgcmVnaW9uc2VydmVyIGVkaXRzIGJlY2F1c2Ugb2YgY2xvY2sgc2tldworICAgSEJBU0UtNjA3ICAgTXVsdGlSZWdpb25UYWJsZS5tYWtlTXVsdGlSZWdpb25UYWJsZSBpcyBub3QgZGV0ZXJtaW5pc3RpYyBlbm91Z2gKKyAgICAgICAgICAgICAgIGZvciByZWdyZXNzaW9uIHRlc3RzCisgICBIQkFTRS00MDUgICBUSUYgYW5kIFRPRiB1c2UgbG9nNGogZGlyZWN0bHkgcmF0aGVyIHRoYW4gYXBhY2hlIGNvbW1vbnMtbG9nZ2luZworICAgSEJBU0UtNjE4ICAgV2UgYWx3YXlzIGNvbXBhY3QgaWYgMiBmaWxlcywgcmVnYXJkbGVzcyBvZiB0aGUgY29tcGFjdGlvbiB0aHJlc2hvbGQgc2V0dGluZworICAgSEJBU0UtNjE5ICAgRml4ICdsb2dzJyBsaW5rIGluIFVJCisgICBIQkFTRS00NzggICBvZmZsaW5pbmcgb2YgdGFibGUgZG9lcyBub3QgcnVuIHJlbGlhYmx5CisgICBIQkFTRS00NTMgICB1bmRlY2xhcmVkIHRocm93YWJsZSBleGNlcHRpb24gZnJvbSBIVGFibGUuZ2V0CisgICBIQkFTRS02MjAgICB0ZXN0bWVyZ2V0b29sIGZhaWxpbmcgaW4gYnJhbmNoIGFuZCB0cnVuayBzaW5jZSBoYmFzZS02MTggd2VudCBpbgorICAgSEJBU0UtNTUwICAgRU9GIHRyeWluZyB0byByZWFkIHJlY29uc3RydWN0aW9uIGxvZyBzdG9wcyByZWdpb24gZGVwbG95bWVudAorICAgSEJBU0UtNTUxICAgTWFzdGVyIHN0dWNrIHNwbGl0dGluZyBzZXJ2ZXIgbG9ncyBpbiBzaHV0ZG93biBsb29wOyBvbiBlYWNoCisgICAgICAgICAgICAgICBpdGVyYXRpb24sIGVkaXRzIGFyZSBhZ2dyZWdhdGVkIHVwIGludG8gdGhlIG1pbGxpb25zCisgICBIQkFTRS01MDUgICBSZWdpb24gYXNzaWdubWVudHMgc2hvdWxkIG5ldmVyIHRpbWUgb3V0IHNvIGxvbmcgYXMgdGhlIHJlZ2lvbgorICAgICAgICAgICAgICAgc2VydmVyIHJlcG9ydHMgdGhhdCBpdCBpcyBwcm9jZXNzaW5nIHRoZSBvcGVuIHJlcXVlc3QKKyAgIEhCQVNFLTU2MSAgIEhCYXNlIHBhY2thZ2UgZG9lcyBub3QgaW5jbHVkZSBMSUNFTlNFLnR4dCBub3IgYnVpbGQueG1sCisgICBIQkFTRS01NjMgICBUZXN0Um93RmlsdGVyQWZ0ZXJXcml0ZSBlcnJvbmVvdXNseSBzZXRzIG1hc3RlciBhZGRyZXNzIHRvCisgICAgICAgICAgICAgICAwLjAuMC4wOjYwMTAwIHJhdGhlciB0aGFuIHJlbHlpbmcgb24gY29uZgorICAgSEJBU0UtNTA3ICAgVXNlIENhbGxhYmxlIHBhdHRlcm4gdG8gc2xlZXAgYmV0d2VlbiByZXRyaWVzCisgICBIQkFTRS01NjQgICBEb24ndCBkbyBhIGNhY2hlIGZsdXNoIGlmIHRoZXJlIGFyZSB6ZXJvIGVudHJpZXMgaW4gdGhlIGNhY2hlLgorICAgSEJBU0UtNTU0ICAgZmlsdGVycyBnZW5lcmF0ZSBTdGFja092ZXJmbG93RXhjZXB0aW9uCisgICBIQkFTRS01NjcgICBSZXVzZWQgQmF0Y2hVcGRhdGUgaW5zdGFuY2VzIGFjY3VtdWxhdGUgQmF0Y2hPcGVyYXRpb25zCisgICBIQkFTRS01NzcgICBOUEUgZ2V0dGluZyBzY2FubmVyCisgICBIQkFTRS0xOSAgICBDb3VudGluZ0Jsb29tRmlsdGVyIGNhbiBvdmVyZmxvdyBpdHMgc3RvcmFnZQorICAgICAgICAgICAgICAgKFN0dSBIb29kIGFuZCBCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTI4ICAgIHRocmlmdCBwdXQvbXV0YXRlUm93IG1ldGhvZHMgbmVlZCB0byB0aHJvdyBJbGxlZ2FsQXJndW1lbnQKKyAgICAgICAgICAgICAgIGV4Y2VwdGlvbnMgKERhdmUgU2ltcHNvbiB2aWEgQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQkFTRS0yICAgICBobG9nIG51bWJlcnMgc2hvdWxkIHdyYXAgYXJvdW5kIHdoZW4gdGhleSByZWFjaCA5OTkKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTQyMSAgIFRlc3RSZWdpb25TZXJ2ZXJFeGl0IGJyb2tlbgorICAgSEJBU0UtNDI2ICAgaGJhc2UgY2FuJ3QgZmluZCByZW1vdGUgZmlsZXN5c3RlbQorICAgSEJBU0UtNDM3ICAgQ2xlYXIgQ29tbWFuZCBzaG91bGQgdXNlIHN5c3RlbS5vdXQgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTQzNCwgSEJBU0UtNDM1IFRlc3RUYWJsZUluZGV4IGFuZCBUZXN0VGFibGVNYXBSZWR1Y2UgZmFpbGVkIGluIEh1ZHNvbiBidWlsZHMKKyAgIEhCQVNFLTQ0NiAgIEZ1bGx5IHF1YWxpZmllZCBoYmFzZS5yb290ZGlyIGRvZXNuJ3Qgd29yaworICAgSEJBU0UtNDM4ICAgWE1MT3V0cHV0dGVyIHN0YXRlIHNob3VsZCBiZSBpbml0aWFsaXplZC4gKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTggICAgIERlbGV0ZSB0YWJsZSBkb2VzIG5vdCByZW1vdmUgdGhlIHRhYmxlIGRpcmVjdG9yeSBpbiB0aGUgRlMKKyAgIEhCQVNFLTQyOCAgIFVuZGVyIGNvbnRpbnVvdXMgdXBsb2FkIG9mIHJvd3MsIFdyb25nUmVnaW9uRXhjZXB0aW9ucyBhcmUgdGhyb3duCisgICAgICAgICAgICAgICB0aGF0IHJlYWNoIHRoZSBjbGllbnQgZXZlbiBhZnRlciByZXRyaWVzCisgICBIQkFTRS00NjAgICBUZXN0TWlncmF0ZSBicm9rZW4gd2hlbiBIQmFzZSBtb3ZlZCB0byBzdWJwcm9qZWN0ICAgCisgICBIQkFTRS00NjIgICBVcGRhdGUgbWlncmF0aW9uIHRvb2wKKyAgIEhCQVNFLTQ3MyAgIFdoZW4gYSB0YWJsZSBpcyBkZWxldGVkLCBtYXN0ZXIgc2VuZHMgbXVsdGlwbGUgY2xvc2UgbWVzc2FnZXMgdG8KKyAgICAgICAgICAgICAgIHRoZSByZWdpb24gc2VydmVyCisgICBIQkFTRS00OTAgICBEb3VibHktYXNzaWduZWQgLk1FVEEuOyBtYXN0ZXIgdXNlcyBvbmUgYW5kIGNsaWVudHMgYW5vdGhlcgorICAgSEJBU0UtNDkyICAgaGJhc2UgVFJVTksgZG9lcyBub3QgYnVpbGQgYWdhaW5zdCBoYWRvb3AgVFJVTksKKyAgIEhCQVNFLTQ5NiAgIGltcG9zc2libGUgc3RhdGUgZm9yIGNyZWF0ZUxlYXNlIHdyaXRlcyA0MDBrIGxpbmVzIGluIGFib3V0IDE1bWlucworICAgSEJBU0UtNDcyICAgUGFzc2luZyBvbiBlZGl0cywgd2UgZHVtcCBhbGwgdG8gbG9nCisgICBIQkFTRS00OTUgICBObyBzZXJ2ZXIgYWRkcmVzcyBsaXN0ZWQgaW4gLk1FVEEuCisgICBIQkFTRS00MzMgSEJBU0UtMjUxIFJlZ2lvbiBzZXJ2ZXIgc2hvdWxkIGRlbGV0ZSByZXN0b3JlIGxvZyBhZnRlciBzdWNjZXNzZnVsCisgICAgICAgICAgICAgICByZXN0b3JlLCBTdHVjayByZXBsYXlpbmcgdGhlIGVkaXRzIG9mIGNyYXNoZWQgbWFjaGluZS4KKyAgIEhCQVNFLTI3ICAgIGhyZWdpb25pbmZvIGNlbGwgZW1wdHkgaW4gbWV0YSB0YWJsZQorICAgSEJBU0UtNTAxICAgRW1wdHkgcmVnaW9uIHNlcnZlciBhZGRyZXNzIGluIGluZm86c2VydmVyIGVudHJ5IGFuZCBhCisgICAgICAgICAgICAgICBzdGFydGNvZGUgb2YgLTEgaW4gLk1FVEEuCisgICBIQkFTRS01MTYgICBIU3RvcmVGaWxlLmZpbmFsS2V5IGRvZXMgbm90IHVwZGF0ZSB0aGUgZmluYWwga2V5IGlmIGl0IGlzIG5vdAorICAgICAgICAgICAgICAgdGhlIHRvcCByZWdpb24gb2YgYSBzcGxpdCByZWdpb24KKyAgIEhCQVNFLTUyNSAgIEhUYWJsZS5nZXRSb3coVGV4dCkgZG9lcyBub3Qgd29yayAoQ2xpbnQgTW9yZ2FuIHZpYSBCcnlhbiBEdXhidXJ5KQorICAgSEJBU0UtNTI0ICAgUHJvYmxlbXMgd2l0aCBnZXRGdWxsCisgICBIQkFTRS01MjggICB0YWJsZSAnZG9lcyBub3QgZXhpc3QnIHdoZW4gaXQgZG9lcworICAgSEJBU0UtNTMxICAgTWVyZ2UgdG9vbCB3b24ndCBtZXJnZSB0d28gb3ZlcmxhcHBpbmcgcmVnaW9ucyAocG9ydCBIQkFTRS00ODMgdG8KKyAgICAgICAgICAgICAgIHRydW5rKQorICAgSEJBU0UtNTM3ICAgV2FpdCBmb3IgaGRmcyB0byBleGl0IHNhZmUgbW9kZQorICAgSEJBU0UtNDc2ICAgUmVnZXhwUm93RmlsdGVyIGJlaGF2ZXMgaW5jb3JlY3RseSB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBzdG9yZQorICAgICAgICAgICAgICAgZmlsZXMgKENsaW50IE1vcmdhbiB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTUyNyAgIFJlZ2V4cFJvd0ZpbHRlciBkb2VzIG5vdCB3b3JrIHdoZW4gdGhlcmUgYXJlIGNvbHVtbnMgZnJvbSAKKyAgICAgICAgICAgICAgIG11bHRpcGxlIGZhbWlsaWVzIChDbGludCBNb3JnYW4gdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS01MzQgICBEb3VibGUtYXNzaWdubWVudCBhdCBTUExJVC10aW1lCisgICBIQkFTRS03MTIgICBtaWRLZXkgZm91bmQgY29tcGFjdGluZyBpcyB0aGUgZmlyc3QsIG5vdCBuZWNlc3NhcmlseSB0aGUgb3B0aW1hbAorICAgSEJBU0UtNzE5ICAgRmluZCBvdXQgd2h5IHVzZXJzIGhhdmUgbmV0d29yayBwcm9ibGVtcyBpbiBIQmFzZSBhbmQgbm90IGluIEhhZG9vcAorICAgICAgICAgICAgICAgYW5kIEhDb25uZWN0aW9uTWFuYWdlciAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTcwMyAgIEludmFsaWQgcmVnaW9ucyBsaXN0ZWQgYnkgcmVnaW9uc2VydmVyLmpzcCAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNjc0ICAgTWVtY2FjaGUgc2l6ZSB1bnJlbGlhYmxlCisgICBIQkFTRS03MjYgICBVbml0IHRlc3RzIHdvbid0IHJ1biBiZWNhdXNlIG9mIGEgdHlwbyAoU2ViYXN0aWVuIFJhaW52aWxsZSB2aWEgU3RhY2spCisgICBIQkFTRS03MjcgICBDbGllbnQgY2F1Z2h0IGluIGFuIGluZmluaXRlIGxvb3Agd2hlbiB0cnlpbmcgdG8gY29ubmVjdCB0byBjYWNoZWQKKyAgICAgICAgICAgICAgIHNlcnZlciBsb2NhdGlvbnMgKEl6YWFrIFJ1YmluIHZpYSBTdGFjaykKKyAgIEhCQVNFLTczMiAgIHNoZWxsIGZvcm1hdHRpbmcgZXJyb3Igd2l0aCB0aGUgZGVzY3JpYmUgY29tbWFuZAorICAgICAgICAgICAgICAgKEl6YWFrIFJ1YmluIHZpYSBTdGFjaykKKyAgIEhCQVNFLTczMSAgIGRlbGV0ZSwgZGVsZXRlZmMgaW4gSEJhc2Ugc2hlbGwgZG8gbm90IHdvcmsgY29ycmVjdGx5CisgICAgICAgICAgICAgICAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNzM0ICAgc2NhbiAnLk1FVEEuJywge0xJTUlUID0+IDEwfSBjcmFzaGVzIChJemFhayBSdWJpbiB2aWEgU3RhY2spCisgICBIQkFTRS03MzYgICBTaG91bGQgaGF2ZSBIVGFibGUuZGVsZXRlQWxsKFN0cmluZyByb3cpIGFuZCBIVGFibGUuZGVsZXRlQWxsKFRleHQgcm93KQorICAgICAgICAgICAgICAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS03NDAgICBUaHJpZnRTZXJ2ZXIgZ2V0dGluZyB0YWJsZSBuYW1lcyBpbmNvcnJlY3RseSAoVGltIFNlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtNzQyICAgUmVuYW1lIGdldE1ldGFpbmZvIGluIEhUYWJsZSBhcyBnZXRUYWJsZURlc2NyaXB0b3IKKyAgIEhCQVNFLTczOSAgIEhCYXNlQWRtaW4uY3JlYXRlVGFibGUoKSB1c2luZyBvbGQgSFRhYmxlRGVzY3JpcHRpb24gZG9lc24ndCB3b3JrCisgICAgICAgICAgICAgICAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNzQ0ICAgQmxvb21GaWx0ZXIgc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24gYnJva2VuCisgICBIQkFTRS03NDIgICBDb2x1bW4gbGVuZ3RoIGxpbWl0IGlzIG5vdCBlbmZvcmNlZCAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTczNyAgIFNjYW5uZXI6IGV2ZXJ5IGNlbGwgaW4gYSByb3cgaGFzIHRoZSBzYW1lIHRpbWVzdGFtcAorICAgSEJBU0UtNzAwICAgaGJhc2UuaW8uaW5kZXguaW50ZXJ2YWwgbmVlZCBiZSBjb25maWd1cmF0YWJsZSBpbiBjb2x1bW4gZmFtaWx5CisgICAgICAgICAgICAgICAoQW5kcmV3IFB1cnRlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtNjIgICAgQWxsb3cgdXNlciBhZGQgYXJiaXRyYXJ5IGtleS92YWx1ZSBwYWlycyB0byB0YWJsZSBhbmQgY29sdW1uCisgICAgICAgICAgICAgICBkZXNjcmlwdG9ycyAoQW5kcmV3IFB1cnRlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtMzQgICAgU2V0IG1lbWNhY2hlIGZsdXNoIHNpemUgcGVyIGNvbHVtbiAoQW5kcmV3IFB1cnRlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtNDIgICAgU2V0IHJlZ2lvbiBzcGxpdCBzaXplIG9uIHRhYmxlIGNyZWF0aW9uIChBbmRyZXcgUHVydGVsbCB2aWEgU3RhY2spCisgICBIQkFTRS00MyAgICBBZGQgYSByZWFkLW9ubHkgYXR0cmlidXRlIHRvIGNvbHVtbnMgKEFuZHJldyBQdXJ0ZWxsIHZpYSBTdGFjaykKKyAgIEhCQVNFLTQyNCAgIFNob3VsZCBiZSBhYmxlIHRvIGVuYWJsZS9kaXNhYmxlIC5NRVRBLiB0YWJsZQorICAgSEJBU0UtNjc5ICAgUmVnaW9uc2VydmVyIGFkZHJlc3NlcyBhcmUgc3RpbGwgbm90IHJpZ2h0IGluIHRoZSBuZXcgdGFibGVzIHBhZ2UKKyAgIEhCQVNFLTc1OCAgIFRocm93aW5nIElPRSByZWFkLW9ubHkgd2hlbiBzaG91bGQgYmUgdGhyb3dpbmcgTlNSRQorICAgSEJBU0UtNzQzICAgYmluL2hiYXNlIG1pZ3JhdGUgdXBncmFkZSBmYWlscyB3aGVuIHJlZG8gbG9ncyBleGlzdHMKKyAgIEhCQVNFLTc1NCAgIFRoZSBKUnVieSBzaGVsbCBkb2N1bWVudGF0aW9uIGlzIHdyb25nIGluICJnZXQiIGFuZCAicHV0IgorICAgICAgICAgICAgICAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS03NTYgICBJbiBIQmFzZSBzaGVsbCwgdGhlIHB1dCBjb21tYW5kIGRvZXNuJ3QgcHJvY2VzcyB0aGUgdGltZXN0YW1wCisgICAgICAgICAgICAgICAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTc1NyAgIFJFU1QgbWFuZ2xlcyB0YWJsZSBuYW1lcyAoU2lzaGVuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTcwNiAgIE9uIE9PTUUsIHJlZ2lvbnNlcnZlciBzdGlja3MgYXJvdW5kIGFuZCBkb2Vzbid0IGdvIGRvd24gd2l0aCBjbHVzdGVyCisgICAgICAgICAgICAgICAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTc1OSAgIFRlc3RNZXRhVXRpbHMgZmFpbGluZyBvbiBodWRzb24KKyAgIEhCQVNFLTc2MSAgIElPRTogU3RyZWFtIGNsb3NlZCBleGNlcHRpb24gYWxsIG92ZXIgbG9ncworICAgSEJBU0UtNzYzICAgQ2xhc3NDYXN0RXhjZXB0aW9uIGZyb20gUm93UmVzdWx0LmdldChTdHJpbmcpCisgICAgICAgICAgICAgICAoQW5kcmV3IFB1cnRlbGwgdmlhIFN0YWNrKQorICAgSEJBU0UtNzY0ICAgVGhlIG5hbWUgb2YgY29sdW1uIHJlcXVlc3QgaGFzIHBhZGRpbmcgemVybyB1c2luZyBSRVNUIGludGVyZmFjZQorICAgICAgICAgICAgICAgKFNpc2hlbiBGcmVlY2l0eSB2aWEgU3RhY2spCisgICBIQkFTRS03NTAgICBOUEUgY2F1c2VkIGJ5IFN0b3JlRmlsZVNjYW5uZXIudXBkYXRlUmVhZGVycworICAgSEJBU0UtNzY5ICAgVGVzdE1hc3RlckFkbWluIGZhaWxzIHRocm93aW5nIFJlZ2lvbk9mZmxpbmVFeGNlcHRpb24gd2hlbiB3ZSdyZQorICAgICAgICAgICAgICAgZXhwZWN0aW5nIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgorICAgSEJBU0UtNzY2ICAgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHRyeWluZyB0byBsb2FkIEhTdG9yZUZpbGUgJ2RhdGEnCisgICBIQkFTRS03NzAgICBVcGRhdGUgSEJhc2VSUEMgdG8gbWF0Y2ggaGFkb29wIDAuMTcgUlBDCisgICBIQkFTRS03ODAgICBDYW4ndCBzY2FuICcuTUVUQS4nIGZyb20gbmV3IHNoZWxsCisgICBIQkFTRS00MjQgICBTaG91bGQgYmUgYWJsZSB0byBlbmFibGUvZGlzYWJsZSAuTUVUQS4gdGFibGUKKyAgIEhCQVNFLTc3MSAgIE5hbWVzIGxlZ2FsIGluIDAuMSBhcmUgbm90IGluIDAuMjsgYnJlYWtzIG1pZ3JhdGlvbgorICAgSEJBU0UtNzg4ICAgRGl2IGJ5IHplcm8gaW4gTWFzdGVyLmpzcCAoQ2xpbnQgTW9yZ2FuIHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtNzkxICAgUm93Q291bnQgZG9lc24ndCB3b3JrIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIFN0YWNrKQorICAgSEJBU0UtNzUxICAgZGZzIGV4Y2VwdGlvbiBhbmQgcmVnaW9uc2VydmVyIHN0dWNrIGR1cmluZyBoZWF2eSB3cml0ZSBsb2FkCisgICBIQkFTRS03OTMgICBIVGFibGUuZ2V0U3RhcnRLZXlzKCkgaWdub3JlcyB0YWJsZSBuYW1lcyB3aGVuIG1hdGNoaW5nIGNvbHVtbnMKKyAgICAgICAgICAgICAgIChBbmRyZXcgUHVydGVsbCBhbmQgRHJ1IEplbnNlbiB2aWEgU3RhY2spCisgICBIQkFTRS03OTAgICBEdXJpbmcgaW1wb3J0LCBzaW5nbGUgcmVnaW9uIGJsb2NrcyByZXF1ZXN0cyBmb3IgPjEwIG1pbnV0ZXMsCisgICAgICAgICAgICAgICB0aHJlYWQgZHVtcHMsIHRocm93cyBvdXQgcGVuZGluZyByZXF1ZXN0cywgYW5kIGNvbnRpbnVlcworICAgICAgICAgICAgICAgKEpvbmF0aGFuIEdyYXkgdmlhIFN0YWNrKQorICAgCisgIElNUFJPVkVNRU5UUworICAgSEJBU0UtNTU5ICAgTVIgZXhhbXBsZSBqb2IgdG8gY291bnQgdGFibGUgcm93cworICAgSEJBU0UtNTk2ICAgRGVtb0NsaWVudC5weSAoSXZhbiBCZWd0aW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNTgxICAgQWxsb3cgYWRkaW5nIGZpbHRlcnMgdG8gVGFibGVJbnB1dEZvcm1hdCAoQXQgc2FtZSB0aW1lLCBlbnN1cmUgVElGCisgICAgICAgICAgICAgICBpcyBzdWJjbGFzc2FibGUpIChEYXZpZCBBbHZlcyB2aWEgU3RhY2spCisgICBIQkFTRS02MDMgICBXaGVuIGFuIGV4Y2VwdGlvbiBidWJibGVzIG91dCBvZiBnZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcywgd3JhcCAKKyAgICAgICAgICAgICAgIHRoZSBleGNlcHRpb24gd2l0aCBhIFJldHJpZXNFeGhhdXN0ZWRFeGNlcHRpb24KKyAgIEhCQVNFLTYwMCAgIEZpbHRlcnMgaGF2ZSBleGNlc3NpdmUgREVCVUcgbG9nZ2luZworICAgSEJBU0UtNjExICAgcmVnaW9uc2VydmVyIHNob3VsZCBkbyBiYXNpYyBoZWFsdGggY2hlY2sgYmVmb3JlIHJlcG9ydGluZworICAgICAgICAgICAgICAgYWxscy13ZWxsIHRvIHRoZSBtYXN0ZXIKKyAgIEhCQVNFLTYxNCAgIFJldGlyaW5nIHJlZ2lvbnMgaXMgbm90IHVzZWQ7IGV4cGxvaXQgb3IgcmVtb3ZlCisgICBIQkFTRS01MzggICBJbXByb3ZlIGV4Y2VwdGlvbnMgdGhhdCBjb21lIG91dCBvbiBjbGllbnQtc2lkZQorICAgSEJBU0UtNTY5ICAgRGVtb0NsaWVudC5waHAgKEppbSBSLiBXaWxzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtNTIyICAgV2hlcmUgbmV3IFRleHQoc3RyaW5nKSBtaWdodCBiZSB1c2VkIGluIGNsaWVudCBzaWRlIG1ldGhvZCBjYWxscywKKyAgICAgICAgICAgICAgIGFkZCBhbiBvdmVybG9hZCB0aGF0IHRha2VzIFN0cmluZyAoRG9uZSBhcyBwYXJ0IG9mIEhCQVNFLTgyKQorICAgSEJBU0UtNTcwICAgUmVtb3ZlIEhRTCB1bml0IHRlc3QgKERvbmUgYXMgcGFydCBvZiBIQkFTRS04MiBjb21taXQpLgorICAgSEJBU0UtNjI2ICAgVXNlIFZpc2l0b3IgcGF0dGVybiBpbiBNZXRhUmVnaW9uIHRvIHJlZHVjZSBjb2RlIGNsb25lcyBpbiBIVGFibGUKKyAgICAgICAgICAgICAgIGFuZCBIQ29ubmVjdGlvbk1hbmFnZXIgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS02MjEgICBNYWtlIE1BWF9WRVJTSU9OUyB3b3JrIGxpa2UgVFRMOiBJbiBzY2FucyBhbmQgZ2V0cywgY2hlY2sKKyAgICAgICAgICAgICAgIE1BWF9WRVJTSU9OcyBzZXR0aW5nIGFuZCByZXR1cm4gdGhhdCBtYW55IG9ubHkgcmF0aGVyIHRoYW4gd2FpdCBvbgorICAgICAgICAgICAgICAgY29tcGFjdGlvbiAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTUwNCAgIEFsbG93IEhNc2cncyBjYXJyeSBhIHBheWxvYWQ6IGUuZy4gZXhjZXB0aW9uIHRoYXQgaGFwcGVuZWQgb3ZlcgorICAgICAgICAgICAgICAgb24gdGhlIHJlbW90ZSBzaWRlLgorICAgSEJBU0UtNTgzICAgUmFuZ2VSb3dGaWx0ZXIvQ29sdW1uVmFsdWVGaWx0ZXIgdG8gYWxsb3cgY2hvaWNlIG9mIHJvd3MgYmFzZWQgb24KKyAgICAgICAgICAgICAgIGEgKGxleGljb2dyYXBoaWMpIGNvbXBhcmlzb24gdG8gY29sdW1uJ3MgdmFsdWVzCisgICAgICAgICAgICAgICAoQ2xpbnQgTW9yZ2FuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTU3OSAgIEFkZCBoYWRvb3AgMC4xNy54CisgICBIQkFTRS02NjAgICBbTWlncmF0aW9uXSBhZGRDb2x1bW4vZGVsZXRlQ29sdW1uIGZ1bmN0aW9uYWxpdHkgaW4gTWV0YVV0aWxzCisgICBIQkFTRS02MzIgICBIVGFibGUuZ2V0TWV0YWRhdGEgaXMgdmVyeSBpbmVmZmljaWVudAorICAgSEJBU0UtNjcxICAgTmV3IFVJIHBhZ2UgZGlzcGxheWluZyBhbGwgcmVnaW9ucyBpbiBhIHRhYmxlIHNob3VsZCBiZSBzb3J0ZWQKKyAgIEhCQVNFLTY3MiAgIFNvcnQgcmVnaW9ucyBpbiB0aGUgcmVnaW9uc2VydmVyIFVJCisgICBIQkFTRS02NzcgICBNYWtlIEhUYWJsZSwgSFJlZ2lvbiwgSFJlZ2lvblNlcnZlciwgSFN0b3JlLCBhbmQgSENvbHVtbkRlc2NyaXB0b3IKKyAgICAgICAgICAgICAgIHN1YmNsYXNzYWJsZSAoQ2xpbnQgTW9yZ2FuIHZpYSBTdGFjaykKKyAgIEhCQVNFLTY4MiAgIFJlZ3VsYXJpemUgdG9TdHJpbmcKKyAgIEhCQVNFLTY3MiAgIFNvcnQgcmVnaW9ucyBpbiB0aGUgcmVnaW9uc2VydmVyIFVJCisgICBIQkFTRS00NjkgICBTdHJlYW1saW5lIEhTdG9yZSBzdGFydHVwIGFuZCBjb21wYWN0aW9ucworICAgSEJBU0UtNTQ0ICAgUHVyZ2Ugc3RhcnRVcGRhdGUgZnJvbSBpbnRlcm5hbCBjb2RlIGFuZCB0ZXN0IGNhc2VzCisgICBIQkFTRS01NTcgICBIVGFibGUuZ2V0Um93KCkgc2hvdWxkIHJlY2VpdmUgUm93UmVzdWx0IG9iamVjdHMKKyAgIEhCQVNFLTQ1MiAgICJyZWdpb24gb2ZmbGluZSIgc2hvdWxkIHRocm93IElPRXhjZXB0aW9uLCBub3QgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICBIQkFTRS01NDEgICBVcGRhdGUgaGFkb29wIGphcnMuCisgICBIQkFTRS01MjMgICBwYWNrYWdlLWxldmVsIGphdmFkb2Mgc2hvdWxkIGhhdmUgZXhhbXBsZSBjbGllbnQKKyAgIEhCQVNFLTQxNSAgIFJld3JpdGUgbGVhc2VzIHRvIHVzZSBEZWxheWVkQmxvY2tpbmdRdWV1ZSBpbnN0ZWFkIG9mIHBvbGxpbmcKKyAgIEhCQVNFLTM1ICAgIE1ha2UgQmF0Y2hVcGRhdGUgcHVibGljIGluIHRoZSBBUEkKKyAgIEhCQVNFLTQwOSAgIEFkZCBidWlsZCBwYXRoIHRvIHN2bjppZ25vcmUgbGlzdCAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgSEJBU0UtNDA4ICAgQWRkIC5jbGFzc3BhdGggYW5kIC5wcm9qZWN0IHRvIHN2bjppZ25vcmUgbGlzdAorICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTQxMCAgIFNwZWVkIHVwIHRoZSB0ZXN0IHN1aXRlIChtYWtlIHRlc3QgdGltZW91dCA1IGluc3RlYWQgb2YgMTUgbWlucykuCisgICBIQkFTRS0yODEgICBTaGVsbCBzaG91bGQgYWxsb3cgZGVsZXRpb25zIGluIC5NRVRBLiBhbmQgLVJPT1QtIHRhYmxlcworICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uICYgQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQkFTRS01NiAgICBVbm5lY2Vzc2FyeSBIUUxDbGllbnQgT2JqZWN0IGNyZWF0aW9uIGluIGEgc2hlbGwgbG9vcAorICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhCQVNFLTMgICAgIHJlc3Qgc2VydmVyOiBjb25maWd1cmUgbnVtYmVyIG9mIHRocmVhZHMgZm9yIGpldHR5CisgICAgICAgICAgICAgICAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQkFTRS00MTYgICBBZGQgYXBhY2hlLXN0eWxlIGxvZ2dpbmcgdG8gUkVTVCBzZXJ2ZXIgYW5kIGFkZCBzZXR0aW5nIGxvZworICAgICAgICAgICAgICAgbGV2ZWwsIGV0Yy4KKyAgIEhCQVNFLTQwNiAgIFJlbW92ZSBIVGFibGUgYW5kIEhDb25uZWN0aW9uIGNsb3NlIG1ldGhvZHMKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTQxOCAgIE1vdmUgSE1hc3RlciBhbmQgcmVsYXRlZCBjbGFzc2VzIGludG8gbWFzdGVyIHBhY2thZ2UKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhCQVNFLTQxMCAgIFNwZWVkIHVwIHRoZSB0ZXN0IHN1aXRlIC0gQXBwYXJlbnRseSB0ZXN0IHRpbWVvdXQgd2FzIHRvbworICAgICAgICAgICAgICAgYWdncmVzc2l2ZSBmb3IgSHVkc29uLiBUZXN0TG9nUm9sbGluZyB0aW1lZCBvdXQgZXZlbiB0aG91Z2ggaXQKKyAgICAgICAgICAgICAgIHdhcyBvcGVyYXRpbmcgcHJvcGVybHkuIENoYW5nZSB0ZXN0IHRpbWVvdXQgdG8gMTAgbWludXRlcy4KKyAgIEhCQVNFLTQzNiAgIHdlYnNpdGU6IGh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZQorICAgSEJBU0UtNDE3ICAgRmFjdG9yIFRhYmxlT3BlcmF0aW9uIGFuZCBzdWJjbGFzc2VzIGludG8gc2VwYXJhdGUgZmlsZXMgZnJvbQorICAgICAgICAgICAgICAgSE1hc3RlciAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQkFTRS00NDAgICBBZGQgb3B0aW9uYWwgbG9nIHJvbGwgaW50ZXJ2YWwgc28gdGhhdCBsb2cgZmlsZXMgYXJlIGdhcmJhZ2UKKyAgICAgICAgICAgICAgIGNvbGxlY3RlZAorICAgSEJBU0UtNDA3ICAgS2VlcCBIUmVnaW9uTG9jYXRpb24gaW5mb3JtYXRpb24gaW4gTFJVIHN0cnVjdHVyZSAKKyAgIEhCQVNFLTQ0NCAgIGhiYXNlIGlzIHZlcnkgc2xvdyBhdCBkZXRlcm1pbmluZyB0YWJsZSBpcyBub3QgcHJlc2VudAorICAgSEJBU0UtNDM4ICAgWE1MT3V0cHV0dGVyIHN0YXRlIHNob3VsZCBiZSBpbml0aWFsaXplZC4KKyAgIEhCQVNFLTQxNCAgIE1vdmUgY2xpZW50IGNsYXNzZXMgaW50byBjbGllbnQgcGFja2FnZQorICAgSEJBU0UtNzkgICAgV2hlbiBIQmFzZSBuZWVkcyB0byBiZSBtaWdyYXRlZCwgaXQgc2hvdWxkIGRpc3BsYXkgYSBtZXNzYWdlIG9uCisgICAgICAgICAgICAgICBzdGRvdXQsIG5vdCBqdXN0IGluIHRoZSBsb2dzCisgICBIQkFTRS00NjEgICBTaW1wbGlmeSBsZWFzZXMuCisgICBIQkFTRS00MTkgICBNb3ZlIFJlZ2lvblNlcnZlciBhbmQgcmVsYXRlZCBjbGFzc2VzIGludG8gcmVnaW9uc2VydmVyIHBhY2thZ2UKKyAgIEhCQVNFLTQ1NyAgIEZhY3RvciBNYXN0ZXIgaW50byBNYXN0ZXIsIFJlZ2lvbk1hbmFnZXIsIGFuZCBTZXJ2ZXJNYW5hZ2VyCisgICBIQkFTRS00NjQgICBIQkFTRS00MTkgaW50cm9kdWNlZCBqYXZhZG9jIGVycm9ycworICAgSEJBU0UtNDY4ICAgTW92ZSBIU3RvcmVLZXkgYmFjayB0byBvLmEuaC5oCisgICBIQkFTRS00NDIgICBNb3ZlIGludGVybmFsIGNsYXNzZXMgb3V0IG9mIEhSZWdpb25TZXJ2ZXIKKyAgIEhCQVNFLTQ2NiAgIE1vdmUgSE1hc3RlckludGVyZmFjZSwgSFJlZ2lvbkludGVyZmFjZSwgYW5kIAorICAgICAgICAgICAgICAgSE1hc3RlclJlZ2lvbkludGVyZmFjZSBpbnRvIG8uYS5oLmguaXBjCisgICBIQkFTRS00NzkgICBTcGVlZCB1cCBUZXN0TG9nUm9sbGluZworICAgSEJBU0UtNDgwICAgVG9vbCB0byBtYW51YWxseSBtZXJnZSB0d28gcmVnaW9ucworICAgSEJBU0UtNDc3ICAgQWRkIHN1cHBvcnQgZm9yIGFuIEhCQVNFX0NMQVNTUEFUSAorICAgSEJBU0UtNDQzICAgTW92ZSBpbnRlcm5hbCBjbGFzc2VzIG91dCBvZiBIU3RvcmUKKyAgIEhCQVNFLTUxNSAgIEF0IGxlYXN0IGRvdWJsZSBkZWZhdWx0IHRpbWVvdXRzIGJldHdlZW4gcmVnaW9uc2VydmVyIGFuZCBtYXN0ZXIKKyAgIEhCQVNFLTUyOSAgIFJlZ2lvblNlcnZlciBuZWVkcyB0byByZWNvdmVyIGlmIGRhdGFub2RlIGdvZXMgZG93bgorICAgSEJBU0UtNDU2ICAgQ2xlYXJseSBzdGF0ZSB3aGljaCBwb3J0cyBuZWVkIHRvIGJlIG9wZW5lZCBpbiBvcmRlciB0byBydW4gSEJhc2UKKyAgIEhCQVNFLTUzNiAgIFJlbW92ZSBNaW5pREZTIHN0YXJ0dXAgZnJvbSBNaW5pSEJhc2VDbHVzdGVyCisgICBIQkFTRS01MjEgICBJbXByb3ZlIGNsaWVudCBzY2FubmVyIGludGVyZmFjZQorICAgSEJBU0UtNTYyICAgTW92ZSBFeGNlcHRpb25zIHRvIHN1YnBhY2thZ2VzIChKZWFuLURhbmllbCBDcnlhbnMgdmlhIFN0YWNrKQorICAgSEJBU0UtNjMxICAgSFRhYmxlLmdldFJvdygpIGZvciBvbmx5IGEgY29sdW1uIGZhbWlseQorICAgICAgICAgICAgICAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS03MzEgICBBZGQgYSBtZXRhIHJlZnJlc2ggdGFnIHRvIHRoZSBXZWIgdWkgZm9yIG1hc3RlciBhbmQgcmVnaW9uIHNlcnZlcgorICAgICAgICAgICAgICAgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS03MzUgICBoYmFzZSBzaGVsbCBkb2Vzbid0IHRyYXAgQ1RSTC1DIHNpZ25hbCAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTczMCAgIE9uIHN0YXJ0dXAsIHJpbnNlIFNUQVJUQ09ERSBhbmQgU0VSVkVSIGZyb20gLk1FVEEuCisgICAgICAgICAgICAgICAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTczOCAgIG92ZXJ2aWV3Lmh0bWwgaW4gbmVlZCBvZiB1cGRhdGluZyAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNzQ1ICAgc2NhbGluZyBvZiBvbmUgcmVnaW9uc2VydmVyLCBpbXByb3ZpbmcgbWVtb3J5IGFuZCBjcHUgdXNhZ2UgKHBhcnRpYWwpCisgICAgICAgICAgICAgICAoTE4gdmlhIFN0YWNrKQorICAgSEJBU0UtNzQ2ICAgQmF0Y2hpbmcgcm93IG11dGF0aW9ucyB2aWEgdGhyaWZ0IChUaW0gU2VsbCB2aWEgU3RhY2spCisgICBIQkFTRS03NzIgICBVcCBkZWZhdWx0IGxlYXNlIHBlcmlvZCBmcm9tIDYwIHRvIDEyMCBzZWNvbmRzCisgICBIQkFTRS03NzkgICBUZXN0IGNoYW5naW5nIGhiYXNlLmhyZWdpb24ubWVtY2FjaGUuYmxvY2subXVsdGlwbGllciB0byAyCisgICBIQkFTRS03ODMgICBGb3Igc2luZ2xlIHJvdywgc2luZ2xlIGZhbWlseSByZXRyaWV2YWwsIGdldFJvdygpIHdvcmtzIGhhbGYKKyAgICAgICAgICAgICAgIGFzIGZhc3QgYXMgZ2V0U2Nhbm5lcigpLm5leHQoKSAoSmVhbi1EYW5pZWwgQ3J5YW5zIHZpYSBTdGFjaykKKyAgIEhCQVNFLTc4OSAgIGFkZCBjbG92ZXIgY292ZXJhZ2UgcmVwb3J0IHRhcmdldHMgKFJvbmctZW4gRmFuIHZpYSBTdGFjaykKKworICBORVcgRkVBVFVSRVMKKyAgIEhCQVNFLTQ3ICAgIE9wdGlvbiB0byBzZXQgVFRMIGZvciBjb2x1bW5zIGluIGhiYXNlCisgICAgICAgICAgICAgICAoQW5kcmV3IFB1cnRlbGwgdmlhIEJyeWFuIER1eGJ1cnkgYW5kIFN0YWNrKQorICAgSEJBU0UtMjMgICAgVUkgbGlzdGluZyByZWdpb25zIHNob3VsZCBiZSBzb3J0ZWQgYnkgYWRkcmVzcyBhbmQgc2hvdyBhZGRpdGlvbmFsCisgICAgICAgICAgICAgICByZWdpb24gc3RhdGUgKEplYW4tRGFuaWVsIENyeWFucyB2aWEgU3RhY2spCisgICBIQkFTRS02MzkgICBBZGQgSEJhc2VBZG1pbi5nZXRUYWJsZURlc2NyaXB0b3IgZnVuY3Rpb24KKyAgIEhCQVNFLTUzMyAgIFJlZ2lvbiBIaXN0b3JpYW4KKyAgIEhCQVNFLTQ4NyAgIFJlcGxhY2UgaHFsIHcvIGEgaGJhc2UtZnJpZW5kbHkgamlyYiBvciBqeXRob24gc2hlbGwKKyAgIEhCQVNFLTU0OCAgIFRvb2wgdG8gb25saW5lIHNpbmdsZSByZWdpb24KKyAgIEhCQVNFLTcxICAgIE1hc3RlciBzaG91bGQgcmViYWxhbmNlIHJlZ2lvbiBhc3NpZ25tZW50cyBwZXJpb2RpY2FsbHkKKyAgIEhCQVNFLTUxMiAgIEFkZCBjb25maWd1cmF0aW9uIGZvciBnbG9iYWwgYWdncmVnYXRlIG1lbWNhY2hlIHNpemUKKyAgIEhCQVNFLTQwICAgIEFkZCBhIG1ldGhvZCBvZiBnZXR0aW5nIG11bHRpcGxlIChidXQgbm90IGFsbCkgY2VsbHMgZm9yIGEgcm93CisgICAgICAgICAgICAgICBhdCBvbmNlCisgICBIQkFTRS01MDYgICBXaGVuIGFuIGV4Y2VwdGlvbiBoYXMgdG8gZXNjYXBlIFNlcnZlckNhbGxhYmxlIGR1ZSB0byBleGhhdXN0ZWQKKyAgICAgICAgICAgICAgIHJldHJpZXMsIHNob3cgYWxsIHRoZSBleGNlcHRpb25zIHRoYXQgbGVhZCB0byB0aGlzIHNpdHVhdGlvbgorICAgSEJBU0UtNzQ3ICAgQWRkIGEgc2ltcGxlIHdheSB0byBkbyBiYXRjaCB1cGRhdGVzIG9mIG1hbnkgcm93cyAoSmVhbi1EYW5pZWwKKyAgICAgICAgICAgICAgIENyeWFucyB2aWEgSmltSykKKyAgIEhCQVNFLTczMyAgIEVuaGFuY2UgQ2VsbCBzbyB0aGF0IGl0IGNhbiBjb250YWluIG11bHRpcGxlIHZhbHVlcyBhdCBtdWx0aXBsZQorICAgICAgICAgICAgICAgdGltZXN0YW1wcworICAgSEJBU0UtNTExICAgRG8gZXhwb25lbnRpYWwgYmFja29mZiBpbiBjbGllbnRzIG9uIE5TUkUsIFdSRSwgSVNFLCBldGMuCisgICAgICAgICAgICAgICAoQW5kcmV3IFB1cnRlbGwgdmlhIEppbSBLZWxsZXJtYW4pCisgICAKKyAgT1BUSU1JWkFUSU9OUworICAgSEJBU0UtNDMwICAgUGVyZm9ybWFuY2U6IFNjYW5uZXJzIGFuZCBnZXRSb3cgcmV0dXJuIG1hcHMgd2l0aCBkdXBsaWNhdGUgZGF0YQorCitSZWxlYXNlIDAuMS4zIC0gMDcvMjUvMjAwOAorCisgIEJVRyBGSVhFUworICAgSEJBU0UtNjQ0ICAgRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uIGJ1dCBSZWdpb25TZXJ2ZXIgZG9lc24ndCByZXN0YXJ0CisgICBIQkFTRS02NDUgICBFT0ZFeGNlcHRpb24gb3BlbmluZyByZWdpb24gKEhCQVNFLTU1MCByZWR1eCkKKyAgIEhCQVNFLTY0MSAgIEltcHJvdmUgbWFzdGVyIHNwbGl0IGxvZ2dpbmcKKyAgIEhCQVNFLTY0MiAgIFNwbGl0dGluZyBsb2cgaW4gYSBob3N0aWxlIGVudmlyb25tZW50IC0tIGJhZCBoZGZzIC0tIHdlIGRyb3AKKyAgICAgICAgICAgICAgIHdyaXRlLWFoZWFkLWxvZyBlZGl0cworICAgSEJBU0UtNjQ2ICAgRU9GRXhjZXB0aW9uIG9wZW5pbmcgSFN0b3JlRmlsZSBpbmZvIGZpbGUgKHNwaW4gb24gSEJBU0UtNjQ1IGFuZCA1NTApCisgICBIQkFTRS02NDggICBJZiBtYXBmaWxlIGluZGV4IGlzIGVtcHR5LCBydW4gcmVwYWlyCisgICBIQkFTRS02NTkgICBITG9nI2NhY2hlRmx1c2hMb2NrIG5vdCBjbGVhcmVkOyBoYW5ncyBhIHJlZ2lvbgorICAgSEJBU0UtNjYzICAgSW5jb3JyZWN0IHNlcXVlbmNlIG51bWJlciBmb3IgY2FjaGUgZmx1c2gKKyAgIEhCQVNFLTY1MiAgIERyb3BwaW5nIHRhYmxlIGZhaWxzIHNpbGVudGx5IGlmIHRhYmxlIGlzbid0IGRpc2FibGVkIAorICAgSEJBU0UtNjc0ICAgTWVtY2FjaGUgc2l6ZSB1bnJlbGlhYmxlCisgICBIQkFTRS02NjUgICBzZXJ2ZXIgc2lkZSBzY2FubmVyIGRvZXNuJ3QgaG9ub3Igc3RvcCByb3cKKyAgIEhCQVNFLTY4MSAgIE5QRSBpbiBNZW1jYWNoZSAoQ2xpbnQgTW9yZ2FuIHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtNjgwICAgY29uZmlnIHBhcmFtZXRlciBoYmFzZS5pby5pbmRleC5pbnRlcnZhbCBzaG91bGQgYmUKKyAgICAgICAgICAgICAgIGhiYXNlLmluZGV4LmludGVydmFsLCBhY2Nyb2RpbmcgdG8gSEJhc2VNYXBGaWxlLkhiYXNlV3JpdGVyCisgICAgICAgICAgICAgICAoTE4gdmlhIFN0YWNrKQorICAgSEJBU0UtNjg0ICAgdW5uZWNlc3NhcnkgaXRlcmF0aW9uIGluIEhNZW1jYWNoZS5pbnRlcm5hbEdldD8gZ290IG11Y2ggYmV0dGVyCisgICAgICAgICAgICAgICByZWFkaW5nIHBlcmZvcm1hbmNlIGFmdGVyIGJyZWFrIGl0IChMTiB2aWEgU3RhY2spCisgICBIQkFTRS02ODYgICBNZW1jYWNoZVNjYW5uZXIgZGlkbid0IHJldHVybiB0aGUgZmlyc3Qgcm93KGlmIGl0IGV4aXN0cyksCisgICAgICAgICAgICAgICBiZWNhdXNlIEhTY2FubmVySW50ZXJmYWNlJ3Mgb3V0cHV0IGluY29ycmVjdCAoTE4gdmlhIEppbSBLZWxsZXJtYW4pCisgICBIQkFTRS02MTMgICBUaW1lc3RhbXAtYW5jaG9yZWQgc2Nhbm5pbmcgZmFpbHMgdG8gZmluZCBhbGwgcmVjb3JkcworICAgSEJBU0UtNzA5ICAgRGVhZGxvY2sgd2hpbGUgcm9sbGluZyBXQUwtbG9nIHdoaWxlIGZpbmlzaGluZyBmbHVzaAorICAgSEJBU0UtNzA3ICAgSGlnaC1sb2FkIGltcG9ydCBvZiBkYXRhIGludG8gc2luZ2xlIHRhYmxlL2ZhbWlseSBuZXZlciB0cmlnZ2VycyBzcGxpdAorICAgSEJBU0UtNzEwICAgSWYgY2xvY2tzIGFyZSB3YXkgb2ZmLCB0aGVuIHdlIGNhbiBoYXZlIGRhdWdodGVyIHNwbGl0IGNvbWUKKyAgICAgICAgICAgICAgIGJlZm9yZSByYXRoZXIgdGhhbiBhZnRlciBpdHMgcGFyZW50IGluIC5NRVRBLgorCitSZWxlYXNlIDAuMS4yIC0gMDUvMTMvMjAwOAorCisgIEJVRyBGSVhFUworICAgSEJBU0UtNTc3ICAgTlBFIGdldHRpbmcgc2Nhbm5lcgorICAgSEJBU0UtNTc0ICAgSEJhc2UgZG9lcyBub3QgbG9hZCBoYWRvb3AgbmF0aXZlIGxpYnMgKFJvbmctRW4gRmFuIHZpYSBTdGFjaykuCisgICBIQkFTRS0xMSAgICBVbmV4cGVjdGVkIGV4aXRzIGNvcnJ1cHQgREZTIC0gYmVzdCB3ZSBjYW4gZG8gdW50aWwgd2UgaGF2ZSBhdAorICAgICAgICAgICAgICAgbGVhc3QgYSBzdWJzZXQgb2YgSEFET09QLTE3MDAKKyAgIEhCQVNFLTU3MyAgIEhCYXNlIGRvZXMgbm90IHJlYWQgaGFkb29wLSoueG1sIGZvciBkZnMgY29uZmlndXJhdGlvbiBhZnRlcgorICAgICAgICAgICAgICAgbW92aW5nIG91dCBoYWRvb3AvY29udHJpYgorICAgSEJBU0UtMTIgICAgd2hlbiBoYmFzZSByZWdpb25zZXJ2ZXIgcmVzdGFydHMsIGl0IHNheXMgImltcG9zc2libGUgc3RhdGUgZm9yCisgICAgICAgICAgICAgICBjcmVhdGVMZWFzZSgpIgorICAgSEJBU0UtNTc1ICAgbWFzdGVyIGRpZXMgd2l0aCBzdGFjayBvdmVyZmxvdyBlcnJvciBpZiByb290ZGlyIGlzbid0IHF1YWxpZmllZAorICAgSEJBU0UtNTAwICAgUmVnaW9uc2VydmVyIHN0dWNrIG9uIGV4aXQKKyAgIEhCQVNFLTU4MiAgIEhCYXNlIDU1NCBmb3Jnb3QgdG8gY2xlYXIgcmVzdWx0cyBvbiBlYWNoIGl0ZXJhdGlvbiBjYXVzZWQgYnkgYSBmaWx0ZXIKKyAgICAgICAgICAgICAgIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNTMyICAgT2RkIGludGVyYWN0aW9uIGJldHdlZW4gSFJlZ2lvbi5nZXQsIEhSZWdpb24uZGVsZXRlQWxsIGFuZCBjb21wYWN0aW9ucworICAgSEJBU0UtNTkwICAgSEJhc2UgbWlncmF0aW9uIHRvb2wgZG9lcyBub3QgZ2V0IGNvcnJlY3QgRmlsZVN5c3RlbSBvciByb290CisgICAgICAgICAgICAgICBkaXJlY3RvcnkgaWYgY29uZmlndXJhdGlvbiBpcyBub3QgY29ycmVjdAorICAgSEJBU0UtNTk1ICAgUm93RmlsdGVySW50ZXJmYWNlLnJvd1Byb2Nlc3NlZCgpIGlzIGNhbGxlZCAqYmVmb3JlKiBmaGUgZmluYWwKKyAgICAgICAgICAgICAgIGZpbHRlcmluZyBkZWNpc2lvbiBpcyBtYWRlIChDbGludCBNb3JnYW4gdmlhIFN0YWNrKQorICAgSEJBU0UtNTg2ICAgSFJlZ2lvbiBydW5zIEhTdG9yZSBtZW1jYWNoZSBzbmFwc2hvdHRpbmcgLS0gZml4IGl0IHNvIG9ubHkgSFN0b3JlCisgICAgICAgICAgICAgICBrbm93cyBhYm91dCB3b3JraW5ncyBvZiBtZW1jYWNoZQorICAgSEJBU0UtNTcyICAgQmFja3BvcnQgSEJBU0UtNTEyIHRvIDAuMSBicmFuY2gKKyAgIEhCQVNFLTU4OCAgIFN0aWxsIGEgJ2hvbGUnIGluIHNjYW5uZXJzLCBldmVuIGFmdGVyIEhCQVNFLTUzMgorICAgSEJBU0UtNjA0ICAgRG9uJ3QgYWxsb3cgQ0xBU1NQQVRIIGZyb20gZW52aXJvbm1lbnQgcG9sbHV0ZSB0aGUgaGJhc2UgQ0xBU1NQQVRICisgICBIQkFTRS02MDggICBIUmVnaW9uU2VydmVyOjpnZXRUaGlzSVAoKSBjaGVja3MgaGFkb29wIGNvbmZpZyB2YXIgZm9yIGRucyBpbnRlcmZhY2UgbmFtZQorICAgICAgICAgICAgICAgKEppbSBSLiBXaWxzb24gdmlhIFN0YWNrKQorICAgSEJBU0UtNjA5ICAgTWFzdGVyIGRvZXNuJ3Qgc2VlIHJlZ2lvbnNlcnZlciBlZGl0cyBiZWNhdXNlIG9mIGNsb2NrIHNrZXcKKyAgIEhCQVNFLTYwNyAgIE11bHRpUmVnaW9uVGFibGUubWFrZU11bHRpUmVnaW9uVGFibGUgaXMgbm90IGRldGVybWluaXN0aWMgZW5vdWdoCisgICAgICAgICAgICAgICBmb3IgcmVncmVzc2lvbiB0ZXN0cworICAgSEJBU0UtNDc4ICAgb2ZmbGluaW5nIG9mIHRhYmxlIGRvZXMgbm90IHJ1biByZWxpYWJseQorICAgSEJBU0UtNjE4ICAgV2UgYWx3YXlzIGNvbXBhY3QgaWYgMiBmaWxlcywgcmVnYXJkbGVzcyBvZiB0aGUgY29tcGFjdGlvbiB0aHJlc2hvbGQgc2V0dGluZworICAgSEJBU0UtNjE5ICAgRml4ICdsb2dzJyBsaW5rIGluIFVJCisgICBIQkFTRS02MjAgICB0ZXN0bWVyZ2V0b29sIGZhaWxpbmcgaW4gYnJhbmNoIGFuZCB0cnVuayBzaW5jZSBoYmFzZS02MTggd2VudCBpbgorICAgCisgIElNUFJPVkVNRU5UUworICAgSEJBU0UtNTU5ICAgTVIgZXhhbXBsZSBqb2IgdG8gY291bnQgdGFibGUgcm93cworICAgSEJBU0UtNTc4ICAgVXBncmFkZSBicmFuY2ggdG8gMC4xNi4zIGhhZG9vcC4KKyAgIEhCQVNFLTU5NiAgIERlbW9DbGllbnQucHkgKEl2YW4gQmVndGluIHZpYSBTdGFjaykKKworCitSZWxlYXNlIDAuMS4xIC0gMDQvMTEvMjAwOAorCisgIEJVRyBGSVhFUworICAgSEJBU0UtNTUwICAgRU9GIHRyeWluZyB0byByZWFkIHJlY29uc3RydWN0aW9uIGxvZyBzdG9wcyByZWdpb24gZGVwbG95bWVudAorICAgSEJBU0UtNTUxICAgTWFzdGVyIHN0dWNrIHNwbGl0dGluZyBzZXJ2ZXIgbG9ncyBpbiBzaHV0ZG93biBsb29wOyBvbiBlYWNoCisgICAgICAgICAgICAgICBpdGVyYXRpb24sIGVkaXRzIGFyZSBhZ2dyZWdhdGVkIHVwIGludG8gdGhlIG1pbGxpb25zCisgICBIQkFTRS01MDUgICBSZWdpb24gYXNzaWdubWVudHMgc2hvdWxkIG5ldmVyIHRpbWUgb3V0IHNvIGxvbmcgYXMgdGhlIHJlZ2lvbgorICAgICAgICAgICAgICAgc2VydmVyIHJlcG9ydHMgdGhhdCBpdCBpcyBwcm9jZXNzaW5nIHRoZSBvcGVuIHJlcXVlc3QKKyAgIEhCQVNFLTU1MiAgIEZpeCBibG9vbSBmaWx0ZXIgYnVncyAoQW5kcnplaiBCaWFsZWNraSB2aWEgSmltIEtlbGxlcm1hbikKKyAgIEhCQVNFLTUwNyAgIEFkZCBzbGVlcCBiZXR3ZWVuIHJldHJpZXMKKyAgIEhCQVNFLTU1NSAgIE9ubHkgb25lIFdvcmtlciBpbiBIUlM7IG9uIHN0YXJ0dXAsIGlmIGFzc2lnbmVkIHRlbnMgb2YgcmVnaW9ucywKKyAgICAgICAgICAgICAgIGhhdm9jIG9mIHJlYXNzaWdubWVudHMgYmVjYXVzZSBvcGVuIHByb2Nlc3NpbmcgaXMgZG9uZSBpbiBzZXJpZXMKKyAgIEhCQVNFLTU0NyAgIFVJIHNob3dzIGhhZG9vcCB2ZXJzaW9uLCBub3QgaGJhc2UgdmVyc2lvbgorICAgSEJBU0UtNTYxICAgSEJhc2UgcGFja2FnZSBkb2VzIG5vdCBpbmNsdWRlIExJQ0VOU0UudHh0IG5vciBidWlsZC54bWwKKyAgIEhCQVNFLTU1NiAgIEFkZCAwLjE2LjIgdG8gaGJhc2UgYnJhbmNoIC0tIGlmIGl0IHdvcmtzCisgICBIQkFTRS01NjMgICBUZXN0Um93RmlsdGVyQWZ0ZXJXcml0ZSBlcnJvbmVvdXNseSBzZXRzIG1hc3RlciBhZGRyZXNzIHRvCisgICAgICAgICAgICAgICAwLjAuMC4wOjYwMTAwIHJhdGhlciB0aGFuIHJlbHlpbmcgb24gY29uZgorICAgSEJBU0UtNTU0ICAgZmlsdGVycyBnZW5lcmF0ZSBTdGFja092ZXJmbG93RXhjZXB0aW9uIChDbGludCBNb3JnYW4gdmlhCisgICAgICAgICAgICAgICBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtNTY3ICAgUmV1c2VkIEJhdGNoVXBkYXRlIGluc3RhbmNlcyBhY2N1bXVsYXRlIEJhdGNoT3BlcmF0aW9ucworCisgIE5FVyBGRUFUVVJFUworICAgSEJBU0UtNTQ4ICAgVG9vbCB0byBvbmxpbmUgc2luZ2xlIHJlZ2lvbgorCitSZWxlYXNlIDAuMS4wCisKKyAgSU5DT01QQVRJQkxFIENIQU5HRVMKKyAgIEhBRE9PUC0yNzUwIERlcHJlY2F0ZWQgbWV0aG9kcyBzdGFydEJhdGNoVXBkYXRlLCBjb21taXRCYXRjaCwgYWJvcnRCYXRjaCwgCisgICAgICAgICAgICAgICBhbmQgcmVuZXdMZWFzZSBoYXZlIGJlZW4gcmVtb3ZlZCBmcm9tIEhUYWJsZSAoQnJ5YW4gRHV4YnVyeSB2aWEKKyAgICAgICAgICAgICAgIEppbSBLZWxsZXJtYW4pCisgICBIQURPT1AtMjc4NiBNb3ZlIGhiYXNlIG91dCBvZiBoYWRvb3AgY29yZQorICAgSEJBU0UtNDAzICAgRml4IGJ1aWxkIGFmdGVyIG1vdmUgb2YgaGJhc2UgaW4gc3ZuCisgICBIQkFTRS00OTQgICBVcCBJUEMgdmVyc2lvbiBvbiAwLjEgYnJhbmNoIHNvIHdlIGNhbm5vdCBtaXN0YWtlbmx5IGNvbm5lY3QKKyAgICAgICAgICAgICAgIHdpdGggYSBoYmFzZSBmcm9tIDAuMTYuMAorCisgIE5FVyBGRUFUVVJFUworICAgSEJBU0UtNTA2ICAgV2hlbiBhbiBleGNlcHRpb24gaGFzIHRvIGVzY2FwZSBTZXJ2ZXJDYWxsYWJsZSBkdWUgdG8gZXhoYXVzdGVkIHJldHJpZXMsIAorICAgICAgICAgICAgICAgc2hvdyBhbGwgdGhlIGV4Y2VwdGlvbnMgdGhhdCBsZWFkIHRvIHRoaXMgc2l0dWF0aW9uCisKKyAgT1BUSU1JWkFUSU9OUworCisgIEJVRyBGSVhFUworICAgSEFET09QLTI3MzEgVW5kZXIgbG9hZCwgcmVnaW9ucyBiZWNvbWUgZXh0cmVtZWx5IGxhcmdlIGFuZCBldmVudHVhbGx5IGNhdXNlCisgICAgICAgICAgICAgICByZWdpb24gc2VydmVycyB0byBiZWNvbWUgdW5yZXNwb25zaXZlCisgICBIQURPT1AtMjY5MyBOUEUgaW4gZ2V0Q2xvc2VzdFJvd0JlZm9yZSAoQnJ5YW4gRHV4YnVyeSAmIFN0YWNrKQorICAgSEFET09QLTI1OTkgU29tZSBtaW5vciBpbXByb3ZlbWVudHMgdG8gY2hhbmdlcyBpbiBIQURPT1AtMjQ0MworICAgICAgICAgICAgICAgKEJyeWFuIER1eGJ1cnkgJiBTdGFjaykKKyAgIEhBRE9PUC0yNzczIE1hc3RlciBtYXJrcyByZWdpb24gb2ZmbGluZSB3aGVuIGl0IGlzIHJlY292ZXJpbmcgZnJvbSBhIHJlZ2lvbgorICAgICAgICAgICAgICAgc2VydmVyIGRlYXRoCisgICBIQkFTRS00MjUgICBGaXggZG9jLiBzbyBpdCBhY2NvbW9kYXRlcyBuZXcgaGJhc2UgdW50ZXRoZXJlZCBjb250ZXh0CisgICBIQmFzZS00MjEgICBUZXN0UmVnaW9uU2VydmVyRXhpdCBicm9rZW4KKyAgIEhCQVNFLTQyNiAgIGhiYXNlIGNhbid0IGZpbmQgcmVtb3RlIGZpbGVzeXN0ZW0KKyAgIEhCQVNFLTQ0NiAgIEZ1bGx5IHF1YWxpZmllZCBoYmFzZS5yb290ZGlyIGRvZXNuJ3Qgd29yaworICAgSEJBU0UtNDI4ICAgVW5kZXIgY29udGludW91cyB1cGxvYWQgb2Ygcm93cywgV3JvbmdSZWdpb25FeGNlcHRpb25zIGFyZQorICAgICAgICAgICAgICAgdGhyb3duIHRoYXQgcmVhY2ggdGhlIGNsaWVudCBldmVuIGFmdGVyIHJldHJpZXMKKyAgIEhCQVNFLTQ5MCAgIERvdWJseS1hc3NpZ25lZCAuTUVUQS47IG1hc3RlciB1c2VzIG9uZSBhbmQgY2xpZW50cyBhbm90aGVyCisgICBIQkFTRS00OTYgICBpbXBvc3NpYmxlIHN0YXRlIGZvciBjcmVhdGVMZWFzZSB3cml0ZXMgNDAwayBsaW5lcyBpbiBhYm91dCAxNW1pbnMKKyAgIEhCQVNFLTQ3MiAgIFBhc3Npbmcgb24gZWRpdHMsIHdlIGR1bXAgYWxsIHRvIGxvZworICAgSEJBU0UtNzkgICAgV2hlbiBIQmFzZSBuZWVkcyB0byBiZSBtaWdyYXRlZCwgaXQgc2hvdWxkIGRpc3BsYXkgYSBtZXNzYWdlIG9uCisgICAgICAgICAgICAgICBzdGRvdXQsIG5vdCBqdXN0IGluIHRoZSBsb2dzCisgICBIQkFTRS00OTUgICBObyBzZXJ2ZXIgYWRkcmVzcyBsaXN0ZWQgaW4gLk1FVEEuCisgICBIQkFTRS00MzMgSEJBU0UtMjUxIFJlZ2lvbiBzZXJ2ZXIgc2hvdWxkIGRlbGV0ZSByZXN0b3JlIGxvZyBhZnRlciBzdWNjZXNzZnVsCisgICAgICAgICAgICAgICByZXN0b3JlLCBTdHVjayByZXBsYXlpbmcgdGhlIGVkaXRzIG9mIGNyYXNoZWQgbWFjaGluZS4KKyAgIEhCQVNFLTI3ICAgIGhyZWdpb25pbmZvIGNlbGwgZW1wdHkgaW4gbWV0YSB0YWJsZQorICAgSEJBU0UtNTAxICAgRW1wdHkgcmVnaW9uIHNlcnZlciBhZGRyZXNzIGluIGluZm86c2VydmVyIGVudHJ5IGFuZCBhCisgICAgICAgICAgICAgICBzdGFydGNvZGUgb2YgLTEgaW4gLk1FVEEuCisgICBIQkFTRS01MTYgICBIU3RvcmVGaWxlLmZpbmFsS2V5IGRvZXMgbm90IHVwZGF0ZSB0aGUgZmluYWwga2V5IGlmIGl0IGlzIG5vdAorICAgICAgICAgICAgICAgdGhlIHRvcCByZWdpb24gb2YgYSBzcGxpdCByZWdpb24KKyAgIEhCQVNFLTUyNCAgIFByb2JsZW1zIHdpdGggZ2V0RnVsbAorICAgSEJBU0UtNTE0ICAgdGFibGUgJ2RvZXMgbm90IGV4aXN0JyB3aGVuIGl0IGRvZXMKKyAgIEhCQVNFLTUzNyAgIFdhaXQgZm9yIGhkZnMgdG8gZXhpdCBzYWZlIG1vZGUKKyAgIEhCQVNFLTUzNCAgIERvdWJsZS1hc3NpZ25tZW50IGF0IFNQTElULXRpbWUKKyAgIAorICBJTVBST1ZFTUVOVFMKKyAgIEhBRE9PUC0yNTU1IFJlZmFjdG9yIHRoZSBIVGFibGUjZ2V0IGFuZCBIVGFibGUjZ2V0Um93IG1ldGhvZHMgdG8gYXZvaWQKKyAgICAgICAgICAgICAgIHJlcGV0aXRpb24gb2YgcmV0cnktb24tZmFpbHVyZSBsb2dpYyAodGhhbmtzIHRvIFBldGVyIERvbGFuIGFuZAorICAgICAgICAgICAgICAgQnJ5YW4gRHV4YnVyeSkKKyAgIEhCQVNFLTI4MSAgIFNoZWxsIHNob3VsZCBhbGxvdyBkZWxldGlvbnMgaW4gLk1FVEEuIGFuZCAtUk9PVC0gdGFibGVzCisgICBIQkFTRS00ODAgICBUb29sIHRvIG1hbnVhbGx5IG1lcmdlIHR3byByZWdpb25zCisgICBIQkFTRS00NzcgICBBZGQgc3VwcG9ydCBmb3IgYW4gSEJBU0VfQ0xBU1NQQVRICisgICBIQkFTRS01MTUgICBBdCBsZWFzdCBkb3VibGUgZGVmYXVsdCB0aW1lb3V0cyBiZXR3ZWVuIHJlZ2lvbnNlcnZlciBhbmQgbWFzdGVyCisgICBIQkFTRS00ODIgICBwYWNrYWdlLWxldmVsIGphdmFkb2Mgc2hvdWxkIGhhdmUgZXhhbXBsZSBjbGllbnQgb3IgYXQgbGVhc3QgCisgICAgICAgICAgICAgICBwb2ludCBhdCB0aGUgRkFRCisgICBIQkFTRS00OTcgICBSZWdpb25TZXJ2ZXIgbmVlZHMgdG8gcmVjb3ZlciBpZiBkYXRhbm9kZSBnb2VzIGRvd24KKyAgIEhCQVNFLTQ1NiAgIENsZWFybHkgc3RhdGUgd2hpY2ggcG9ydHMgbmVlZCB0byBiZSBvcGVuZWQgaW4gb3JkZXIgdG8gcnVuIEhCYXNlCisgICBIQkFTRS00ODMgICBNZXJnZSB0b29sIHdvbid0IG1lcmdlIHR3byBvdmVybGFwcGluZyByZWdpb25zCisgICBIQkFTRS00NzYgICBSZWdleHBSb3dGaWx0ZXIgYmVoYXZlcyBpbmNvcmVjdGx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIHN0b3JlCisgICAgICAgICAgICAgICBmaWxlcyAoQ2xpbnQgTW9yZ2FuIHZpYSBKaW0gS2VsbGVybWFuKQorICAgSEJBU0UtNTI3ICAgUmVnZXhwUm93RmlsdGVyIGRvZXMgbm90IHdvcmsgd2hlbiB0aGVyZSBhcmUgY29sdW1ucyBmcm9tIAorICAgICAgICAgICAgICAgbXVsdGlwbGUgZmFtaWxpZXMgKENsaW50IE1vcmdhbiB2aWEgSmltIEtlbGxlcm1hbikKKyAgICAgICAgICAgICAgCitSZWxlYXNlIDAuMTYuMAorCisgIDIwMDgvMDIvMDQgICBIQmFzZSBpcyBub3cgYSBzdWJwcm9qZWN0IG9mIEhhZG9vcC4gVGhlIGZpcnN0IEhCYXNlIHJlbGVhc2UgYXMKKyAgICAgICAgICAgICAgIGEgc3VicHJvamVjdCB3aWxsIGJlIHJlbGVhc2UgMC4xLjAgd2hpY2ggd2lsbCBiZSBlcXVpdmFsZW50IHRvCisgICAgICAgICAgICAgICB0aGUgdmVyc2lvbiBvZiBIQmFzZSBpbmNsdWRlZCBpbiBIYWRvb3AgMC4xNi4wLiBJbiBvcmRlciB0bworICAgICAgICAgICAgICAgYWNjb21wbGlzaCB0aGlzLCB0aGUgSEJhc2UgcG9ydGlvbiBvZiBIQkFTRS0yODggKGZvcm1lcmx5IAorICAgICAgICAgICAgICAgSEFET09QLTEzOTgpIGhhcyBiZWVuIGJhY2tlZCBvdXQuIE9uY2UgMC4xLjAgaXMgZnJvemVuIChkZXBlbmRpbmcKKyAgICAgICAgICAgICAgIG1vc3RseSBvbiBjaGFuZ2VzIHRvIGluZnJhc3RydWN0dXJlIGR1ZSB0byBiZWNvbWluZyBhIHN1YiBwcm9qZWN0CisgICAgICAgICAgICAgICBpbnN0ZWFkIG9mIGEgY29udHJpYiBwcm9qZWN0KSwgdGhpcyBwYXRjaCB3aWxsIHJlLWFwcGVhciBvbiBIQmFzZQorICAgICAgICAgICAgICAgdHJ1bmsuCisKKyAgSU5DT01QQVRJQkxFIENIQU5HRVMKKyAgIEhBRE9PUC0yMDU2IEEgdGFibGUgd2l0aCByb3cga2V5cyBjb250YWluaW5nIGNvbG9uIGZhaWxzIHRvIHNwbGl0IHJlZ2lvbnMKKyAgIEhBRE9PUC0yMDc5IEZpeCBnZW5lcmF0ZWQgSExvZywgSFJlZ2lvbiBuYW1lcworICAgSEFET09QLTI0OTUgTWlub3IgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRzOiBTbGltLWRvd24gQmF0Y2hPcGVyYXRpb24sIGV0Yy4gCisgICBIQURPT1AtMjUwNiBSZW1vdmUgdGhlIGFsZ2VicmEgcGFja2FnZQorICAgSEFET09QLTI1MTkgUGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRzOiBDdXN0b21pemVkIFJQQyBzZXJpYWxpemF0aW9uCisgICBIQURPT1AtMjQ3OCBSZXN0cnVjdHVyZSBob3cgSEJhc2UgbGF5cyBvdXQgZmlsZXMgaW4gdGhlIGZpbGUgc3lzdGVtIChwaGFzZSAxKQorICAgICAgICAgICAgICAgKHRlc3QgaW5wdXQgZGF0YSkKKyAgIEhBRE9PUC0yNDc4IFJlc3RydWN0dXJlIGhvdyBIQmFzZSBsYXlzIG91dCBmaWxlcyBpbiB0aGUgZmlsZSBzeXN0ZW0gKHBoYXNlIDIpCisgICAgICAgICAgICAgICBJbmNsdWRlcyBtaWdyYXRpb24gdG9vbCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLk1pZ3JhdGUKKyAgIEhBRE9PUC0yNTU4IG9yZy5vbmVsYWIuZmlsdGVyLkJsb29tRmlsdGVyIGNsYXNzIHVzZXMgOFggdGhlIG1lbW9yeSBpdCBzaG91bGQKKyAgICAgICAgICAgICAgIGJlIHVzaW5nCisKKyAgTkVXIEZFQVRVUkVTCisgICAgSEFET09QLTIwNjEgQWRkIG5ldyBCYXNlNjQgZGlhbGVjdHMKKyAgICBIQURPT1AtMjA4NCBBZGQgYSBMb2NhbEhCYXNlQ2x1c3RlcgorICAgIEhBRE9PUC0yMDY4IFJFU1RmdWwgaW50ZXJmYWNlIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgICBIQURPT1AtMjMxNiBSdW4gUkVTVCBzZXJ2bGV0IG91dHNpZGUgb2YgbWFzdGVyCisgICAgICAgICAgICAgICAgKEJyeWFuIER1eGJ1cnkgJiBTdGFjaykKKyAgICBIQURPT1AtMTU1MCBObyBtZWFucyBvZiBkZWxldGluZyBhJ3JvdycgKEJyeWFuIER1eGJ1ZXJ5IHZpYSBTdGFjaykKKyAgICBIQURPT1AtMjM4NCBEZWxldGUgYWxsIG1lbWJlcnMgb2YgYSBjb2x1bW4gZmFtaWx5IG9uIGEgc3BlY2lmaWMgcm93CisgICAgICAgICAgICAgICAgKEJyeWFuIER1eGJ1cnkgdmlhIFN0YWNrKQorICAgIEhBRE9PUC0yMzk1IEltcGxlbWVudCAiQUxURVIgVEFCTEUgLi4uIENIQU5HRSBjb2x1bW4iIG9wZXJhdGlvbgorICAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgICBIQURPT1AtMjI0MCBUcnVuY2F0ZSBmb3IgaGJhc2UgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgICBIQURPT1AtMjM4OSBQcm92aWRlIG11bHRpcGxlIGxhbmd1YWdlIGJpbmRpbmdzIGZvciBIQmFzZSAoVGhyaWZ0KQorICAgICAgICAgICAgICAgIChEYXZpZCBTaW1wc29uIHZpYSBTdGFjaykKKworICBPUFRJTUlaQVRJT05TCisgICBIQURPT1AtMjQ3OSBTYXZlIG9uIG51bWJlciBvZiBUZXh0IG9iamVjdCBjcmVhdGlvbnMKKyAgIEhBRE9PUC0yNDg1IE1ha2UgbWFwZmlsZSBpbmRleCBpbnRlcnZhbCBjb25maWd1cmFibGUgKFNldCBkZWZhdWx0IHRvIDMyCisgICAgICAgICAgICAgICBpbnN0ZWFkIG9mIDEyOCkKKyAgIEhBRE9PUC0yNTUzIERvbid0IG1ha2UgTG9uZyBvYmplY3RzIGNhbGN1bGF0aW5nIGhiYXNlIHR5cGUgaGFzaCBjb2RlcworICAgSEFET09QLTIzNzcgSG9sZGluZyBvcGVuIE1hcEZpbGUuUmVhZGVycyBpcyBleHBlbnNpdmUsIHNvIHVzZSBsZXNzIG9mIHRoZW0KKyAgIEhBRE9PUC0yNDA3IEtlZXBpbmcgTWFwRmlsZS5SZWFkZXIgb3BlbiBpcyBleHBlbnNpdmU6IFBhcnQgMgorICAgSEFET09QLTI1MzMgUGVyZm9ybWFuY2U6IFNjYW5uaW5nLCBqdXN0IGNyZWF0aW5nIE1hcFdyaXRhYmxlIGluIG5leHQKKyAgICAgICAgICAgICAgIGNvbnN1bWVzID4yMCUgQ1BVCisgICBIQURPT1AtMjQ0MyBLZWVwIGxhenkgY2FjaGUgb2YgcmVnaW9ucyBpbiBjbGllbnQgcmF0aGVyIHRoYW4gYW4KKyAgICAgICAgICAgICAgICdhdXRob3JpdGF0aXZlJyBsaXN0IChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNjAwIFBlcmZvcm1hbmNlOiBIU3RvcmUuZ2V0Um93S2V5QXRPckJlZm9yZSBzaG91bGQgdXNlCisgICAgICAgICAgICAgICBNYXBGaWxlLlJlYWRlciNnZXRDbG9zZXN0IChiZWZvcmUpCisgICAgICAgICAgICAgICAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisKKyAgQlVHIEZJWEVTCisgICBIQURPT1AtMjA1OSBJbiB0ZXN0cywgZXhjZXB0aW9ucyBpbiBtaW4gZGZzIHNodXRkb3duIHNob3VsZCBub3QgZmFpbCB0ZXN0CisgICAgICAgICAgICAgICAoZS5nLiBuaWdodGx5ICMyNzIpCisgICBIQURPT1AtMjA2NCBUZXN0U3BsaXQgYXNzZXJ0aW9uIGFuZCBOUEUgZmFpbHVyZXMgKFBhdGNoIGJ1aWxkICM5NTIgYW5kICM5NTMpCisgICBIQURPT1AtMjEyNCBVc2Ugb2YgYGhvc3RuYW1lYCBkb2VzIG5vdCB3b3JrIG9uIEN5Z3dpbiBpbiBzb21lIGNhc2VzCisgICBIQURPT1AtMjA4MyBUZXN0VGFibGVJbmRleCBmYWlsZWQgaW4gIzk3MCBhbmQgIzk1NgorICAgSEFET09QLTIxMDkgRml4ZWQgcmFjZSBjb25kaXRpb24gaW4gcHJvY2Vzc2luZyBzZXJ2ZXIgbGVhc2UgdGltZW91dC4KKyAgIEhBRE9PUC0yMTM3IGhxbC5qc3AgOiBUaGUgY2hhcmFjdGVyIDB4MTkgaXMgbm90IHZhbGlkCisgICBIQURPT1AtMjEwOSBGaXggYW5vdGhlciByYWNlIGNvbmRpdGlvbiBpbiBwcm9jZXNzaW5nIGRlYWQgc2VydmVycywKKyAgICAgICAgICAgICAgIEZpeCBlcnJvciBvbmxpbmUgbWV0YSByZWdpb25zOiB3YXMgdXNpbmcgcmVnaW9uIG5hbWUgYW5kIG5vdAorICAgICAgICAgICAgICAgc3RhcnRLZXkgYXMga2V5IGZvciBtYXAucHV0LiBDaGFuZ2UgVGVzdFJlZ2lvblNlcnZlckV4aXQgdG8KKyAgICAgICAgICAgICAgIGFsd2F5cyBraWxsIHRoZSByZWdpb24gc2VydmVyIGZvciB0aGUgTUVUQSByZWdpb24uIFRoaXMgbWFrZXMKKyAgICAgICAgICAgICAgIHRoZSB0ZXN0IG1vcmUgZGV0ZXJtaW5pc3RpYyBhbmQgZ2V0dGluZyBNRVRBIHJlYXNzaWduZWQgd2FzCisgICAgICAgICAgICAgICBwcm9ibGVtYXRpYy4KKyAgIEhBRE9PUC0yMTU1IE1ldGhvZCBleHBlY3RpbmcgSEJhc2VDb25maWd1cmF0aW9uIHRocm93cyBOUEUgd2hlbiBnaXZlbiBDb25maWd1cmF0aW9uCisgICBIQURPT1AtMjE1NiBCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZm9yIHVuLW5hbWVkIEhUYWJsZURlc2NyaXB0b3JzCisgICBIQURPT1AtMjE2MSBnZXRSb3coKSBpcyBvcmRlcnMgb2YgbWFnbml0dWRlcyBzbG93ZXIgdGhhbiBnZXQoKSwgZXZlbiBvbiByb3dzCisgICAgICAgICAgICAgICB3aXRoIG9uZSBjb2x1bW4gKENsaW50IE1vcmdhbiBhbmQgU3RhY2spCisgICBIQURPT1AtMjA0MCBIdWRzb24gaGFuZ3MgQUZURVIgdGVzdCBoYXMgZmluaXNoZWQKKyAgIEhBRE9PUC0yMjc0IEV4Y2VzcyBzeW5jaHJvbml6YXRpb24gaW50cm9kdWNlZCBieSBIQURPT1AtMjEzOSBuZWdhdGl2ZWx5CisgICAgICAgICAgICAgICBpbXBhY3RzIHBlcmZvcm1hbmNlCisgICBIQURPT1AtMjE5NiBGaXggaG93IGhiYXNlIHNpdHMgaW4gaGFkb29wICdwYWNrYWdlJyBwcm9kdWN0CisgICBIQURPT1AtMjI3NiBBZGRyZXNzIHJlZ3Jlc3Npb24gY2F1c2VkIGJ5IEhBRE9PUC0yMjc0LCBmaXggSEFET09QLTIxNzMgKFdoZW4KKyAgICAgICAgICAgICAgIHRoZSBtYXN0ZXIgdGltZXMgb3V0IGEgcmVnaW9uIHNlcnZlcnMgbGVhc2UsIHRoZSByZWdpb24gc2VydmVyCisgICAgICAgICAgICAgICBtYXkgbm90IHJlc3RhcnQpCisgICBIQURPT1AtMjI1MyBnZXRSb3cgY2FuIHJldHVybiBIQkFTRTo6REVMRVRFVkFMIGNlbGxzCisgICAgICAgICAgICAgICAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQURPT1AtMjI5NSBGaXggYXNzaWduaW5nIGEgcmVnaW9uIHRvIG11bHRpcGxlIHNlcnZlcnMKKyAgIEhBRE9PUC0yMjM0IFRhYmxlSW5wdXRGb3JtYXQgZXJyb25lb3VzbHkgYWdncmVnYXRlcyBtYXAgdmFsdWVzCisgICBIQURPT1AtMjMwOCBudWxsIHJlZ2lvbmluZm8gYnJlYWtzIG1ldGEgc2Nhbm5lcgorICAgSEFET09QLTIzMDQgQWJicmV2aWF0ZWQgc3ltYm9sIHBhcnNpbmcgZXJyb3Igb2YgZGlyIHBhdGggaW4gamFyIGNvbW1hbmQKKyAgICAgICAgICAgICAgIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgICBIQURPT1AtMjMyMCBDb21taXR0ZWQgVGVzdEdldDIgaXMgbWFuYWdsZWQgKGJyZWFrcyBidWlsZCkuCisgICBIQURPT1AtMjMyMiBnZXRSb3cocm93LCBUUykgY2xpZW50IGludGVyZmFjZSBub3QgcHJvcGVybHkgY29ubmVjdGVkCisgICBIQURPT1AtMjMwOSBDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGRvaW5nIGdldCBvZiBhbGwgcmVnaW9uIHN0YXJ0IGtleXMKKyAgIEhBRE9PUC0yMzIxIFRlc3RTY2FubmVyMiBkb2VzIG5vdCByZWxlYXNlIHJlc291cmNlcyB3aGljaCBzb21ldGltZXMgY2F1c2UgdGhlCisgICAgICAgICAgICAgICB0ZXN0IHRvIHRpbWUgb3V0CisgICBIQURPT1AtMjMxNSBSRVNUIHNlcnZsZXQgZG9lc24ndCB0cmVhdCAvIGNoYXJhY3RlcnMgaW4gcm93IGtleSBjb3JyZWN0bHkKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMzMyIE1ldGEgdGFibGUgZGF0YSBzZWxlY3Rpb24gaW4gSGJhc2UgU2hlbGwKKyAgICAgICAgICAgICAgIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgICBIQURPT1AtMjM0NyBSRVNUIHNlcnZsZXQgbm90IHRocmVhZCBzYWZlIGJ1dCBydW4gaW4gYSB0aHJlYWRlZCBtYW5uZXIKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMzY1IFJlc3VsdCBvZiBIYXNoRnVuY3Rpb24uaGFzaCgpIGNvbnRhaW5zIGFsbCBpZGVudGljYWwgdmFsdWVzCisgICBIQURPT1AtMjM2MiBMZWFraW5nIGhkZnMgZmlsZSBoYW5kbGUgb24gcmVnaW9uIHNwbGl0CisgICBIQURPT1AtMjMzOCBGaXggTnVsbFBvaW50ZXJFeGNlcHRpb24gaW4gbWFzdGVyIHNlcnZlci4KKyAgIEhBRE9PUC0yMzgwIFJFU1Qgc2VydmxldCB0aHJvd3MgTlBFIHdoZW4gYW55IHZhbHVlIG5vZGUgaGFzIGFuIGVtcHR5IHN0cmluZworICAgICAgICAgICAgICAgKEJyeWFuIER1eGJ1cnkgdmlhIFN0YWNrKQorICAgSEFET09QLTIzNTAgU2Nhbm5lciBhcGkgcmV0dXJucyBudWxsIHJvdyBuYW1lcywgb3Igc2tpcHMgcm93IG5hbWVzIGlmCisgICAgICAgICAgICAgICBkaWZmZXJlbnQgY29sdW1uIGZhbWlsaWVzIGRvIG5vdCBoYXZlIGVudHJpZXMgZm9yIHNvbWUgcm93cworICAgSEFET09QLTIyODMgQWxyZWFkeUJlaW5nQ3JlYXRlZEV4Y2VwdGlvbiAoV2FzOiBTdHVjayByZXBsYXkgb2YgZmFpbGVkCisgICAgICAgICAgICAgICByZWdpb25zZXJ2ZXIgZWRpdHMpCisgICBIQURPT1AtMjM5MiBUZXN0UmVnaW9uU2VydmVyRXhpdCBoYXMgbmV3IGZhaWx1cmUgbW9kZSBzaW5jZSBIQURPT1AtMjMzOAorICAgSEFET09QLTIzMjQgRml4IGFzc2VydGlvbiBmYWlsdXJlcyBpbiBUZXN0VGFibGVNYXBSZWR1Y2UKKyAgIEhBRE9PUC0yMzk2IE5QRSBpbiBITWFzdGVyLmNhbmNlbExlYXNlCisgICBIQURPT1AtMjM5NyBUaGUgb25seSB0aW1lIHRoYXQgYSBtZXRhIHNjYW5uZXIgc2hvdWxkIHRyeSB0byByZWNvdmVyIGEgbG9nIGlzCisgICAgICAgICAgICAgICB3aGVuIHRoZSBtYXN0ZXIgaXMgc3RhcnRpbmcKKyAgIEhBRE9PUC0yNDE3IEZpeCBjcml0aWNhbCBzaHV0ZG93biBwcm9ibGVtIGludHJvZHVjZWQgYnkgSEFET09QLTIzMzgKKyAgIEhBRE9PUC0yNDE4IEZpeCBhc3NlcnRpb24gZmFpbHVyZXMgaW4gVGVzdFRhYmxlTWFwUmVkdWNlLCBUZXN0VGFibGVJbmRleCwKKyAgICAgICAgICAgICAgIGFuZCBUZXN0VGFibGVKb2luTWFwUmVkdWNlCisgICBIQURPT1AtMjQxNCBGaXggQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGluIGJsb29tIGZpbHRlcnMuCisgICBIQURPT1AtMjQzMCBNYXN0ZXIgd2lsbCBub3Qgc2h1dCBkb3duIGlmIHRoZXJlIGFyZSBubyBhY3RpdmUgcmVnaW9uIHNlcnZlcnMKKyAgIEhBRE9PUC0yMTk5IEFkZCB0b29scyBmb3IgZ29pbmcgZnJvbSBocmVnaW9uIGZpbGVuYW1lIHRvIHJlZ2lvbiBuYW1lIGluIGxvZ3MKKyAgIEhBRE9PUC0yNDQxIEZpeCBidWlsZCBmYWlsdXJlcyBpbiBUZXN0SEJhc2VDbHVzdGVyCisgICBIQURPT1AtMjQ1MSBFbmQga2V5IGlzIGluY29ycmVjdGx5IGFzc2lnbmVkIGluIG1hbnkgcmVnaW9uIHNwbGl0cworICAgSEFET09QLTI0NTUgRXJyb3IgaW4gSGVscC1zdHJpbmcgb2YgQ1JFQVRFIGNvbW1hbmQgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNDY1IFdoZW4gc3BsaXQgcGFyZW50IHJlZ2lvbnMgYXJlIGNsZWFuZWQgdXAsIG5vdCBhbGwgdGhlIGNvbHVtbnMgYXJlCisgICAgICAgICAgICAgICBkZWxldGVkCisgICBIQURPT1AtMjQ2OCBUZXN0UmVnaW9uU2VydmVyRXhpdCBmYWlsZWQgaW4gSGFkb29wLU5pZ2h0bHkgIzMzOAorICAgSEFET09QLTI0Njcgc2Nhbm5lciB0cnVuY2F0ZXMgcmVzdWx0c2V0IHdoZW4gPiAxIGNvbHVtbiBmYW1pbGllcworICAgSEFET09QLTI1MDMgUkVTVCBJbnNlcnQgLyBTZWxlY3QgZW5jb2RpbmcgaXNzdWUgKEJyeWFuIER1eGJ1cnkgdmlhIFN0YWNrKQorICAgSEFET09QLTI1MDUgZm9ybWF0dGVyIGNsYXNzZXMgbWlzc2luZyBhcGFjaGUgbGljZW5zZQorICAgSEFET09QLTI1MDQgUkVTVCBzZXJ2bGV0IG1ldGhvZCBmb3IgZGVsZXRpbmcgYSBzY2FubmVyIHdhcyBub3QgcHJvcGVybHkKKyAgICAgICAgICAgICAgIG1hcHBlZCAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQURPT1AtMjUwNyBSRVNUIHNlcnZsZXQgZG9lcyBub3QgcHJvcGVybHkgYmFzZTY0IHJvdyBrZXlzIGFuZCBjb2x1bW4gbmFtZXMKKyAgICAgICAgICAgICAgIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNTMwIE1pc3NpbmcgdHlwZSBpbiBuZXcgaGJhc2UgY3VzdG9tIFJQQyBzZXJpYWxpemVyCisgICBIQURPT1AtMjQ5MCBGYWlsdXJlIGluIG5pZ2h0bHkgIzM0NiAoQWRkZWQgZGVidWdnaW5nIG9mIGh1ZHNvbiBmYWlsdXJlcykuCisgICBIQURPT1AtMjU1OCBmaXhlcyBmb3IgYnVpbGQgdXAgb24gaHVkc29uIChwYXJ0IDEsIHBhcnQgMiwgcGFydCAzLCBwYXJ0IDQpCisgICBIQURPT1AtMjUwMCBVbnJlYWRhYmxlIHJlZ2lvbiBraWxscyByZWdpb24gc2VydmVycworICAgSEFET09QLTI1NzkgSW5pdGlhbGl6aW5nIGEgbmV3IEhUYWJsZSBvYmplY3QgYWdhaW5zdCBhIG5vbmV4aXN0ZW50IHRhYmxlCisgICAgICAgICAgICAgICB0aHJvd3MgYSBOb1NlcnZlckZvclJlZ2lvbkV4Y2VwdGlvbiBpbnN0ZWFkIG9mIGEKKyAgICAgICAgICAgICAgIFRhYmxlTm90Rm91bmRFeGNlcHRpb24gd2hlbiBhIGRpZmZlcmVudCB0YWJsZSBoYXMgYmVlbiBjcmVhdGVkCisgICAgICAgICAgICAgICBwcmV2aW91c2x5IChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNTg3IFNwbGl0cyBibG9ja2VkIGJ5IGNvbXBhY3Rpb25zIGNhdXNlIHJlZ2lvbiB0byBiZSBvZmZsaW5lIGZvcgorICAgICAgICAgICAgICAgZHVyYXRpb24gb2YgY29tcGFjdGlvbi4gCisgICBIQURPT1AtMjU5MiBTY2FubmluZywgYSByZWdpb24gY2FuIGxldCBvdXQgYSByb3cgdGhhdCBpdHMgbm90IHN1cHBvc2VkCisgICAgICAgICAgICAgICB0byBoYXZlCisgICBIQURPT1AtMjQ5MyBoYmFzZSB3aWxsIHNwbGl0IG9uIHJvdyB3aGVuIHRoZSBzdGFydCBhbmQgZW5kIHJvdyBpcyB0aGUKKyAgICAgICAgICAgICAgIHNhbWUgY2F1c2UgZGF0YSBsb3NzIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNjI5IFNoZWxsIGRpZ2VzdHMgZ2FyYmFnZSB3aXRob3V0IGNvbXBsYWludAorICAgSEFET09QLTI2MTkgQ29tcGFjdGlvbiBlcnJvcnMgYWZ0ZXIgYSByZWdpb24gc3BsaXRzCisgICBIQURPT1AtMjYyMSBNZW1jYWNoZSBmbHVzaCBmbHVzaGluZyBldmVyeSA2MCBzZWNzIHdpdGggb3V0IGNvbnNpZGVyaW5nCisgICAgICAgICAgICAgICB0aGUgbWF4IG1lbWNhY2hlIHNpemUKKyAgIEhBRE9PUC0yNTg0IFdlYiBVSSBkaXNwbGF5cyBhbiBJT0V4Y2VwdGlvbiBpbnN0ZWFkIG9mIHRoZSBUYWJsZXMKKyAgIEhBRE9PUC0yNjUwIFJlbW92ZSBXcml0YWJsZXMuY2xvbmUgYW5kIHVzZSBXcml0YWJsZVV0aWxzLmNsb25lIGZyb20KKyAgICAgICAgICAgICAgIGhhZG9vcCBpbnN0ZWFkCisgICBIQURPT1AtMjY2OCBEb2N1bWVudGF0aW9uIGFuZCBpbXByb3ZlZCBsb2dnaW5nIHNvIGZhY3QgdGhhdCBoYmFzZSBub3cKKyAgICAgICAgICAgICAgIHJlcXVpcmVzIG1pZ3JhdGlvbiBjb21lcyBhcyBsZXNzIG9mIGEgc3VycHJpc2UKKyAgIEhBRE9PUC0yNjg2IFJlbW92ZWQgdGFibGVzIHN0aWNrIGFyb3VuZCBpbiAuTUVUQS4KKyAgIEhBRE9PUC0yNjg4IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBwcm9jZXNzaW5nIGEgc2h1dGRvd24gc3RvcHMKKyAgICAgICAgICAgICAgIHNlcnZlciBnb2luZyBkb3duIGFuZCByZXN1bHRzIGluIG1pbGxpb25zIG9mIGxpbmVzIG9mIG91dHB1dAorICAgSEFET09QLTI3MDYgSEJhc2UgU2hlbGwgY3Jhc2gKKyAgIEhBRE9PUC0yNzEyIHVuZGVyIGxvYWQsIHJlZ2lvbnMgd29uJ3Qgc3BsaXQKKyAgIEhBRE9PUC0yNjc1IE9wdGlvbnMgbm90IHBhc3NlZCB0byByZXN0L3RocmlmdAorICAgSEFET09QLTI3MjIgUHJldmVudCB1bmludGVudGlvbmFsIHRocmVhZCBleGl0IGluIHJlZ2lvbiBzZXJ2ZXIgYW5kIG1hc3RlcgorICAgSEFET09QLTI3MTggQ29weSBDb25zdHJ1Y3RvciBIQmFzZUNvbmZpZ3VyYXRpb24oQ29uZmlndXJhdGlvbikgd2lsbCBvdmVycmlkZQorICAgICAgICAgICAgICAgaGJhc2UgY29uZmlndXJhdGlvbnMgaWYgYXJndW1hbnQgaXMgbm90IGFuIGluc3RhbmNlIG9mCisgICAgICAgICAgICAgICBIQmFzZUNvbmZpZ3VyYXRpb24uCisgICBIQURPT1AtMjc1MyBCYWNrIG91dCAyNzE4OyBwcm9ncmFtbWF0aWMgY29uZmlnIHdvcmtzIGJ1dCBoYmFzZSp4bWwgY29uZgorICAgICAgICAgICAgICAgaXMgb3ZlcnJpZGRlbgorICAgSEFET09QLTI3MTggQ29weSBDb25zdHJ1Y3RvciBIQmFzZUNvbmZpZ3VyYXRpb24oQ29uZmlndXJhdGlvbikgd2lsbCBvdmVycmlkZQorICAgICAgICAgICAgICAgaGJhc2UgY29uZmlndXJhdGlvbnMgaWYgYXJndW1hbnQgaXMgbm90IGFuIGluc3RhbmNlIG9mCisgICAgICAgICAgICAgICBIQmFzZUNvbmZpZ3VyYXRpb24gKFB1dCBpdCBiYWNrIGFnYWluKS4KKyAgIEhBRE9PUC0yNjMxIDI0NDMgYnJlYWtzIEhUYWJsZS5nZXRTdGFydEtleXMgd2hlbiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lCisgICAgICAgICAgICAgICB0YWJsZSBvciB0YWJsZSB5b3UgYXJlIGVudW1lcmF0aW5nIGlzbid0IHRoZSBmaXJzdCB0YWJsZQorICAgRGVsZXRlIGVtcHR5IGZpbGU6IHNyYy9jb250cmliL2hiYXNlL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC8KKyAgICAgICAgICAgICAgIFRhYmxlT3V0cHV0Q29sbGVjdG9yLmphdmEgcGVyIE5pZ2VsIERhbGV5CisgICAKKyAgSU1QUk9WRU1FTlRTCisgICBIQURPT1AtMjQwMSBBZGQgY29udmVuaWVuY2UgcHV0IG1ldGhvZCB0aGF0IHRha2VzIHdyaXRhYmxlCisgICAgICAgICAgICAgICAoSm9oYW4gT3NrYXJzc29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMDc0IFNpbXBsZSBzd2l0Y2ggdG8gZW5hYmxlIERFQlVHIGxldmVsLWxvZ2dpbmcgaW4gaGJhc2UKKyAgIEhBRE9PUC0yMDg4IE1ha2UgaGJhc2UgcnVubmFibGUgaW4gJEhBRE9PUF9IT01FL2J1aWxkKC9jb250cmliL2hiYXNlKQorICAgSEFET09QLTIxMjYgVXNlIEJvYiBKZW5raW5zJyBoYXNoIGZvciBibG9vbSBmaWx0ZXJzCisgICBIQURPT1AtMjE1NyBNYWtlIFNjYW5uZXJzIGltcGxlbWVudCBJdGVyYWJsZQorICAgSEFET09QLTIxNzYgSHRhYmxlLmRlbGV0ZUFsbCBkb2N1bWVudGF0aW9uIGlzIGFtYmlndW91cworICAgSEFET09QLTIxMzkgKHBoYXNlIDEpIEluY3JlYXNlIHBhcmFsbGVsaXNtIGluIHJlZ2lvbiBzZXJ2ZXJzLgorICAgSEFET09QLTIyNjcgW0hiYXNlIFNoZWxsXSBDaGFuZ2UgdGhlIHByb21wdCdzIHRpdGxlIGZyb20gJ2hiYXNlJyB0byAnaHFsJy4KKyAgICAgICAgICAgICAgIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgICBIQURPT1AtMjEzOSAocGhhc2UgMikgTWFrZSByZWdpb24gc2VydmVyIG1vcmUgZXZlbnQgZHJpdmVuCisgICBIQURPT1AtMjI4OSBVc2VsZXNzIGVmZm9ydHMgb2YgbG9va2luZyBmb3IgdGhlIG5vbi1leGlzdGFudCB0YWJsZSBpbiBzZWxlY3QKKyAgICAgICAgICAgICAgIGNvbW1hbmQuCisgICAgICAgICAgICAgICAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgSEFET09QLTIyNTcgU2hvdyBhIHRvdGFsIG9mIGFsbCByZXF1ZXN0cyBhbmQgcmVnaW9ucyBvbiB0aGUgd2ViIHVpCisgICAgICAgICAgICAgICAoUGF1bCBTYWFiIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMjYxIEhUYWJsZS5hYm9ydCBubyBsb25nZXIgdGhyb3dzIGV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyBhY3RpdmUgdXBkYXRlLgorICAgSEFET09QLTIyODcgTWFrZSBoYmFzZSB1bml0IHRlc3RzIHRha2UgbGVzcyB0aW1lIHRvIGNvbXBsZXRlLgorICAgSEFET09QLTIyNjIgUmV0cnkgbiB0aW1lcyBpbnN0ZWFkIG9mIG4qKjIgdGltZXMuCisgICBIQURPT1AtMTYwOCBSZWxhdGlvbmFsIEFsZ3JlYnJhIE9wZXJhdG9ycworICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMTk4IEhUYWJsZSBzaG91bGQgaGF2ZSBtZXRob2QgdG8gcmV0dXJuIHRhYmxlIG1ldGFkYXRhCisgICBIQURPT1AtMjI5NiBoYmFzZSBzaGVsbDogcGhhbnRvbSBjb2x1bW5zIHNob3cgdXAgZnJvbSBzZWxlY3QgY29tbWFuZAorICAgSEFET09QLTIyOTcgU3lzdGVtLmV4aXQoKSBIYW5kbGluZyBpbiBoYmFzZSBzaGVsbCBqYXIgY29tbWFuZAorICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMjI0IEFkZCBIVGFibGUuZ2V0Um93KFJPVywgdHMpCisgICAgICAgICAgICAgICAoQnJ5YW4gRHV4YnVyeSB2aWEgU3RhY2spCisgICBIQURPT1AtMjMzOSBEZWxldGUgY29tbWFuZCB3aXRoIG5vIFdIRVJFIGNsYXVzZQorICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMjk5IFN1cHBvcnQgaW5jbHVzaXZlIHNjYW5zIChCcnlhbiBEdXhidXJ5IHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMzMzIENsaWVudCBzaWRlIHJldHJpZXMgaGFwcGVuIGF0IHRoZSB3cm9uZyBsZXZlbAorICAgSEFET09QLTIzNTcgQ29tcGFjdGlvbiBjbGVhbnVwOyBsZXNzIGRlbGV0aW5nICsgcHJldmVudCBwb3NzaWJsZSBmaWxlIGxlYWtzCisgICBIQURPT1AtMjM5MiBUZXN0UmVnaW9uU2VydmVyRXhpdCBoYXMgbmV3IGZhaWx1cmUgbW9kZSBzaW5jZSBIQURPT1AtMjMzOAorICAgSEFET09QLTIzNzAgQWxsb3cgY29sdW1uIGZhbWlsaWVzIHdpdGggYW4gdW5saW1pdGVkIG51bWJlciBvZiB2ZXJzaW9ucworICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yMDQ3IEFkZCBhbiAnLS1tYXN0ZXI9WCcgYW5kICctLWh0bWwnIGNvbW1hbmQtbGluZSBwYXJhbWV0ZXJzIHRvIHNoZWxsCisgICAgICAgICAgICAgICAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgSEFET09QLTIzNTEgSWYgc2VsZWN0IGNvbW1hbmQgcmV0dXJucyBubyByZXN1bHQsIGl0IGRvZXNuJ3QgbmVlZCB0byBzaG93IHRoZQorICAgICAgICAgICAgICAgaGVhZGVyIGluZm9ybWF0aW9uIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgICBIQURPT1AtMjI4NSBBZGQgYmVpbmcgYWJsZSB0byBzaHV0ZG93biByZWdpb25zZXJ2ZXJzIChEZW5uaXMgS3ViZXMgdmlhIFN0YWNrKQorICAgSEFET09QLTI0NTggSFN0b3JlRmlsZS53cml0ZVNwbGl0SW5mbyBzaG91bGQganVzdCBjYWxsIAorICAgICAgICAgICAgICAgSFN0b3JlRmlsZS5SZWZlcmVuY2Uud3JpdGUKKyAgIEhBRE9PUC0yNDcxIEFkZCByZWFkaW5nL3dyaXRpbmcgTWFwRmlsZSB0byBQZXJmb3JtYW5jZUV2YWx1YXRpb24gc3VpdGUKKyAgIEhBRE9PUC0yNTIyIFNlcGFyYXRlIE1hcEZpbGUgYmVuY2htYXJrIGZyb20gUGVyZm9ybWFuY2VFdmFsdWF0aW9uCisgICAgICAgICAgICAgICAoVG9tIFdoaXRlIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNTAyIEluc2VydC9TZWxlY3QgdGltZXN0YW1wLCBUaW1lc3RhbXAgZGF0YSB0eXBlIGluIEhRTAorICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgIEhBRE9PUC0yNDUwIFNob3cgdmVyc2lvbiAoYW5kIHN2biByZXZpc2lvbikgaW4gaGJhc2Ugd2ViIHVpCisgICBIQURPT1AtMjQ3MiBSYW5nZSBzZWxlY3Rpb24gdXNpbmcgZmlsdGVyIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgICBIQURPT1AtMjU0OCBNYWtlIFRhYmxlTWFwIGFuZCBUYWJsZVJlZHVjZSBnZW5lcmljCisgICAgICAgICAgICAgICAoRnJlZGVyaWsgSGVkYmVyZyB2aWEgU3RhY2spCisgICBIQURPT1AtMjU1NyBTaGVsbCBjb3VudCBmdW5jdGlvbiAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgSEFET09QLTI1ODkgQ2hhbmdlIGFuIGNsYXNzZXMvcGFja2FnZSBuYW1lIGZyb20gU2hlbGwgdG8gaHFsCisgICAgICAgICAgICAgICAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgSEFET09QLTI1NDUgaGJhc2UgcmVzdCBzZXJ2ZXIgc2hvdWxkIGJlIHN0YXJ0ZWQgd2l0aCBoYmFzZS1kYWVtb24uc2gKKyAgIEhBRE9PUC0yNTI1IFNhbWUgMiBsaW5lcyByZXBlYXRlZCAxMSBtaWxsaW9uIHRpbWVzIGluIEhNYXN0ZXIgbG9nIHVwb24KKyAgICAgICAgICAgICAgIEhNYXN0ZXIgc2h1dGRvd24KKyAgIEhBRE9PUC0yNjE2IGhiYXNlIG5vdCBzcGxpdGluZyB3aGVuIHRoZSB0b3RhbCBzaXplIG9mIHJlZ2lvbiByZWFjaGVzIG1heAorICAgICAgICAgICAgICAgcmVnaW9uIHNpemUgKiAxLjUKKyAgIEhBRE9PUC0yNjQzIE1ha2UgbWlncmF0aW9uIHRvb2wgc21hcnRlci4KKyAgIAorUmVsZWFzZSAwLjE1LjEKK0JyYW5jaCAwLjE1CisKKyAgSU5DT01QQVRJQkxFIENIQU5HRVMKKyAgICBIQURPT1AtMTkzMSBIYmFzZSBzY3JpcHRzIHRha2UgLS1BUkc9QVJHX1ZBTFVFIHdoZW4gc2hvdWxkIGJlIGxpa2UgaGFkb29wCisgICAgICAgICAgICAgICAgYW5kIGRvIC0tLUFSRyBBUkdfVkFMVUUKKworICBORVcgRkVBVFVSRVMKKyAgICBIQURPT1AtMTc2OCBGUyBjb21tYW5kIHVzaW5nIEhhZG9vcCBGc1NoZWxsIG9wZXJhdGlvbnMKKyAgICAgICAgICAgICAgICAoRWR3YXJkIFlvb24gdmlhIFN0YWNrKQorICAgIEhBRE9PUC0xNzg0IERlbGV0ZTogRml4IHNjYW5uZXJzIGFuZCBnZXRzIHNvIHRoZXkgd29yayBwcm9wZXJseSBpbiBwcmVzZW5jZQorICAgICAgICAgICAgICAgIG9mIGRlbGV0ZXMuIEFkZGVkIGEgZGVsZXRlQWxsIHRvIHJlbW92ZSBhbGwgY2VsbHMgZXF1YWwgdG8gb3IKKyAgICAgICAgICAgICAgICBvbGRlciB0aGFuIHBhc3NlZCB0aW1lc3RhbXAuICBGaXhlZCBjb21wYWN0aW9uIHNvIGRlbGV0ZWQgY2VsbHMKKyAgICAgICAgICAgICAgICBkbyBub3QgbWFrZSBpdCBvdXQgaW50byBjb21wYWN0ZWQgb3V0cHV0LiAgRW5zdXJlIGFsc28gdGhhdAorICAgICAgICAgICAgICAgIHZlcnNpb25zID4gY29sdW1uIG1heCBhcmUgZHJvcHBlZCBjb21wYWN0aW5nLgorICAgIEhBRE9PUC0xNzIwIEFkZGl0aW9uIG9mIEhRTCAoSGJhc2UgUXVlcnkgTGFuZ3VhZ2UpIHN1cHBvcnQgaW4gSGJhc2UgU2hlbGwuCisgICAgICAgICAgICAgICAgVGhlIG9sZCBzaGVsbCBzeW50YXggaGFzIGJlZW4gcmVwbGFjZWQgYnkgSFFMLCBhIHNtYWxsIFNRTC1saWtlCisgICAgICAgICAgICAgICAgc2V0IG9mIG9wZXJhdG9ycywgZm9yIGNyZWF0aW5nLCBhbHRlcmluZywgZHJvcHBpbmcsIGluc2VydGluZywKKyAgICAgICAgICAgICAgICBkZWxldGluZywgYW5kIHNlbGVjdGluZywgZXRjLiwgZGF0YSBpbiBoYmFzZS4KKyAgICAgICAgICAgICAgICAoSW5jaHVsIFNvbmcgYW5kIEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgICBIQURPT1AtMTkxMyBCdWlsZCBhIEx1Y2VuZSBpbmRleCBvbiBhbiBIQmFzZSB0YWJsZQorICAgICAgICAgICAgICAgIChOaW5nIExpIHZpYSBTdGFjaykKKyAgICBIQURPT1AtMTk1NyBXZWIgVUkgd2l0aCByZXBvcnQgb24gY2x1c3RlciBzdGF0ZSBhbmQgYmFzaWMgYnJvd3Npbmcgb2YgdGFibGVzCisKKyAgT1BUSU1JWkFUSU9OUworCisgIEJVRyBGSVhFUworICAgIEhBRE9PUC0xNTI3IFJlZ2lvbiBzZXJ2ZXIgd29uJ3Qgc3RhcnQgYmVjYXVzZSBsb2dkaXIgZXhpc3RzCisgICAgSEFET09QLTE3MjMgSWYgbWFzdGVyIGFza3MgcmVnaW9uIHNlcnZlciB0byBzaHV0IGRvd24sIGJ5LXBhc3MgcmV0dXJuIG9mCisgICAgICAgICAgICAgICAgc2h1dGRvd24gbWVzc2FnZQorICAgIEhBRE9PUC0xNzI5IFJlY2VudCByZW5hbWluZyBvciBNRVRBIHRhYmxlcyBicmVha3MgaGJhc2Ugc2hlbGwKKyAgICBIQURPT1AtMTczMCB1bmV4cGVjdGVkIG51bGwgdmFsdWUgY2F1c2VzIE1FVEEgc2Nhbm5lciB0byBleGl0IChzaWxlbnRseSkKKyAgICBIQURPT1AtMTc0NyBPbiBhIGNsdXN0ZXIsIG9uIHJlc3RhcnQsIHJlZ2lvbnMgbXVsdGlwbHkgYXNzaWduZWQKKyAgICBIQURPT1AtMTc3NiBGaXggZm9yIHNwb3JhZGljIGNvbXBhY3Rpb24gZmFpbHVyZXMgY2xvc2luZyBhbmQgbW92aW5nCisgICAgICAgICAgICAgICAgY29tcGFjdGlvbiByZXN1bHQKKyAgICBIQURPT1AtMTc4MCBSZWdpb25zIGFyZSBzdGlsbCBiZWluZyBkb3VibHkgYXNzaWduZWQKKyAgICBIQURPT1AtMTc5NyBGaXggTlBFcyBpbiBNZXRhU2Nhbm5lciBjb25zdHJ1Y3RvcgorICAgIEhBRE9PUC0xNzk5IEluY29ycmVjdCBjbGFzc3BhdGggaW4gYmluYXJ5IHZlcnNpb24gb2YgSGFkb29wCisgICAgSEFET09QLTE4MDUgUmVnaW9uIHNlcnZlciBoYW5nIG9uIGV4aXQKKyAgICBIQURPT1AtMTc4NSBUYWJsZUlucHV0Rm9ybWF0LlRhYmxlUmVjb3JkUmVhZGVyLm5leHQgaGFzIGEgYnVnCisgICAgICAgICAgICAgICAgKE5pbmcgTGkgdmlhIFN0YWNrKQorICAgIEhBRE9PUC0xODAwIG91dHB1dCBzaG91bGQgZGVmYXVsdCB1dGY4IGVuY29kaW5nCisgICAgSEFET09QLTE4MDEgV2hlbiBoZGZzIGlzIHlhbmtlZCBvdXQgZnJvbSB1bmRlciBoYmFzZSwgaGJhc2Ugc2hvdWxkIGdvIGRvd24gZ3JhY2VmdWxseQorICAgIEhBRE9PUC0xODEzIE9PTUUgbWFrZXMgem9tYmllIG9mIHJlZ2lvbiBzZXJ2ZXIKKyAgICBIQURPT1AtMTgxNAlUZXN0Q2xlYW5SZWdpb25TZXJ2ZXJFeGl0IGZhaWxzIHRvbyBvZnRlbiBvbiBIdWRzb24KKyAgICBIQURPT1AtMTgyMCBSZWdpb25zZXJ2ZXIgY3JlYXRlcyBobG9ncyB3aXRob3V0IGJvdW5kCisgICAgICAgICAgICAgICAgKHJldmVydGVkIDIwMDcvMDkvMjUpIChGaXhlZCAyMDA3LzA5LzMwKQorICAgIEhBRE9PUC0xODIxIFJlcGxhY2UgYWxsIFN0cmluZy5nZXRCeXRlcygpIHdpdGggU3RyaW5nLmdldEJ5dGVzKCJVVEYtOCIpCisgICAgSEFET09QLTE4MzIgbGlzdFRhYmxlcygpIHJldHVybnMgZHVwbGljYXRlIHRhYmxlcworICAgIEhBRE9PUC0xODM0IFNjYW5uZXJzIGlnbm9yZSB0aW1lc3RhbXAgcGFzc2VkIG9uIGNyZWF0aW9uCisgICAgSEFET09QLTE4NDcgTWFueSBIQmFzZSB0ZXN0cyBkbyBub3QgZmFpbCB3ZWxsLgorICAgIEhBRE9PUC0xODQ3IE1hbnkgSEJhc2UgdGVzdHMgZG8gbm90IGZhaWwgd2VsbC4gKHBoYXNlIDIpCisgICAgSEFET09QLTE4NzAgT25jZSBmaWxlIHN5c3RlbSBmYWlsdXJlIGhhcyBiZWVuIGRldGVjdGVkLCBkb24ndCBjaGVjayBpdCBhZ2FpbgorICAgICAgICAgICAgICAgIGFuZCBnZXQgb24gd2l0aCBzaHV0dGluZyBkb3duIHRoZSBoYmFzZSBjbHVzdGVyLgorICAgIEhBRE9PUC0xODg4IE51bGxQb2ludGVyRXhjZXB0aW9uIGluIEhNZW1jYWNoZVNjYW5uZXIgKHJlcHJpc2UpCisgICAgSEFET09QLTE5MDMgUG9zc2libGUgZGF0YSBsb3NzIGlmIEV4Y2VwdGlvbiBoYXBwZW5zIGJldHdlZW4gc25hcHNob3QgYW5kCisgICAgICAgICAgICAgICAgZmx1c2ggdG8gZGlzay4KKyAgICBIQURPT1AtMTkyMCBXcmFwcGVyIHNjcmlwdHMgYnJva2VuIHdoZW4gaGFkb29wIGluIG9uZSBsb2NhdGlvbiBhbmQgaGJhc2UgaW4KKyAgICAgICAgICAgICAgICBhbm90aGVyCisgICAgSEFET09QLTE5MjMsIEhBRE9PUC0xOTI0IGEpIHRlc3RzIGZhaWwgc3BvcmFkaWNhbGx5IGJlY2F1c2Ugc2V0IHVwIGFuZCB0ZWFyCisgICAgICAgICAgICAgICAgIGRvd24gaXMgaW5jb25zaXN0ZW50IGIpIFRlc3RERlNBYm9ydCBmYWlsZWQgaW4gbmlnaHRseSAjMjQyCisgICAgSEFET09QLTE5MjkgQWRkIGhiYXNlLWRlZmF1bHQueG1sIHRvIGhiYXNlIGphcgorICAgIEhBRE9PUC0xOTQxIFN0b3BSb3dGaWx0ZXIgdGhyb3dzIE5QRSB3aGVuIHBhc3NlZCBudWxsIHJvdworICAgIEhBRE9PUC0xOTY2IE1ha2UgSEJhc2UgdW5pdCB0ZXN0cyBtb3JlIHJlbGlhYmxlIGluIHRoZSBIdWRzb24gZW52aXJvbm1lbnQuCisgICAgSEFET09QLTE5NzUgSEJhc2UgdGVzdHMgZmFpbGluZyB3aXRoIGphdmEubGFuZy5OdW1iZXJGb3JtYXRFeGNlcHRpb24KKyAgICBIQURPT1AtMTk5MCBSZWdyZXNzaW9uIHRlc3QgaW5zdGFiaWxpdHkgYWZmZWN0cyBuaWdodGx5IGFuZCBwYXRjaCBidWlsZHMKKyAgICBIQURPT1AtMTk5NiBUZXN0SFN0b3JlRmlsZSBmYWlscyBvbiB3aW5kb3dzIGlmIHJ1biBtdWx0aXBsZSB0aW1lcworICAgIEhBRE9PUC0xOTM3IFdoZW4gdGhlIG1hc3RlciB0aW1lcyBvdXQgYSByZWdpb24gc2VydmVyJ3MgbGVhc2UsIGl0IGlzIHRvbyAKKyAgICAgICAgICAgICAgICBhZ2dyZXNzaXZlIGluIHJlY2xhaW1pbmcgdGhlIHNlcnZlcidzIGxvZy4KKyAgICBIQURPT1AtMjAwNCB3ZWJhcHAgaHFsIGZvcm1hdHRpbmcgYnVncyAKKyAgICBIQURPT1BfMjAxMSBNYWtlIGhiYXNlIGRhZW1vbiBzY3JpcHRzIHRha2UgYXJncyBpbiBzYW1lIG9yZGVyIGFzIGhhZG9vcAorICAgICAgICAgICAgICAgIGRhZW1vbiBzY3JpcHRzCisgICAgSEFET09QLTIwMTcgVGVzdFJlZ2lvblNlcnZlckFib3J0IGZhaWx1cmUgaW4gcGF0Y2ggYnVpbGQgIzkwMyBhbmQKKyAgICAgICAgICAgICAgICBuaWdodGx5ICMyNjYKKyAgICBIQURPT1AtMjAyOSBUZXN0TG9nUm9sbGluZyBmYWlscyB0b28gb2Z0ZW4gaW4gcGF0Y2ggYW5kIG5pZ2h0bGllcworICAgIEhBRE9PUC0yMDM4IFRlc3RDbGVhblJlZ2lvbkV4aXQgZmFpbGVkIGluIHBhdGNoIGJ1aWxkICM5MjcKKworICBJTVBST1ZFTUVOVFMKKyAgICBIQURPT1AtMTczNyBNYWtlIEhDb2x1bW5EZXNjcmlwdG9yIGRhdGEgcHVibGljYWxseSBtZW1iZXJzIHNldHRhYmxlCisgICAgSEFET09QLTE3NDYgQ2xlYW4gdXAgZmluZGJ1Z3Mgd2FybmluZ3MKKyAgICBIQURPT1AtMTc1NyBCbG9vbWZpbHRlcnM6IHNpbmdsZSBhcmd1bWVudCBjb25zdHJ1Y3RvciwgdXNlIGVudW0gZm9yIGJsb29tCisgICAgICAgICAgICAgICAgZmlsdGVyIHR5cGVzCisgICAgSEFET09QLTE3NjAgVXNlIG5ldyBNYXBXcml0YWJsZSBhbmQgU29ydGVkTWFwV3JpdGFibGUgY2xhc3NlcyBmcm9tCisgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS5oYWRvb3AuaW8KKyAgICBIQURPT1AtMTc5MyAoUGhhc2UgMSkgUmVtb3ZlIFRlc3RIQ2xpZW50IChQaGFzZTIpIHJlbW92ZSBIQ2xpZW50LgorICAgIEhBRE9PUC0xNzk0IFJlbW92ZSBkZXByZWNhdGVkIEFQSXMKKyAgICBIQURPT1AtMTgwMiBTdGFydHVwIHNjcmlwdHMgc2hvdWxkIHdhaXQgdW50aWwgaGRmcyBhcyBjbGVhcmVkICdzYWZlIG1vZGUnCisgICAgSEFET09QLTE4MzMgYmluL3N0b3BfaGJhc2Uuc2ggcmV0dXJucyBiZWZvcmUgaXQgY29tcGxldGVzCisgICAgICAgICAgICAgICAgKEl6YWFrIFJ1YmluIHZpYSBTdGFjaykgCisgICAgSEFET09QLTE4MzUgVXBkYXRlZCBEb2N1bWVudGF0aW9uIGZvciBIQmFzZSBzZXR1cC9pbnN0YWxsYXRpb24KKyAgICAgICAgICAgICAgICAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorICAgIEhBRE9PUC0xODY4IE1ha2UgZGVmYXVsdCBjb25maWd1cmF0aW9uIG1vcmUgcmVzcG9uc2l2ZQorICAgIEhBRE9PUC0xODg0IFJlbW92ZSB1c2VsZXNzIGRlYnVnZ2luZyBsb2cgbWVzc2FnZXMgZnJvbSBoYmFzZS5tYXByZWQKKyAgICBIQURPT1AtMTg1NiBBZGQgSmFyIGNvbW1hbmQgdG8gaGJhc2Ugc2hlbGwgdXNpbmcgSGFkb29wIFJ1bkphciB1dGlsCisgICAgICAgICAgICAgICAgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAgICBIQURPT1AtMTkyOCBIYXZlIG1hc3RlciBwYXNzIHRoZSByZWdpb25zZXJ2ZXIgdGhlIGZpbGVzeXN0ZW0gdG8gdXNlCisgICAgSEFET09QLTE3ODkgT3V0cHV0IGZvcm1hdHRpbmcKKyAgICBIQURPT1AtMTk2MCBJZiBhIHJlZ2lvbiBzZXJ2ZXIgY2Fubm90IHRhbGsgdG8gdGhlIG1hc3RlciBiZWZvcmUgaXRzIGxlYXNlCisgICAgICAgICAgICAgICAgdGltZXMgb3V0LCBpdCBzaG91bGQgc2h1dCBpdHNlbGYgZG93bgorICAgIEhBRE9PUC0yMDM1IEFkZCBsb2dvIHRvIHdlYmFwcHMKKworCitCZWxvdyBhcmUgdGhlIGxpc3Qgb2YgY2hhbmdlcyBiZWZvcmUgMjAwNy0wOC0xOAorCisgIDEuIEhBRE9PUC0xMzg0LiBIQmFzZSBvbW5pYnVzIHBhdGNoLiAoamltaywgVnVrIEVyY2Vnb3ZhYywgYW5kIE1pY2hhZWwgU3RhY2spCisgIDIuIEhBRE9PUC0xNDAyLiBGaXggamF2YWRvYyB3YXJuaW5ncyBpbiBoYmFzZSBjb250cmliLiAoTWljaGFlbCBTdGFjaykKKyAgMy4gSEFET09QLTE0MDQuIEhCYXNlIGNvbW1hbmQtbGluZSBzaHV0ZG93biBmYWlsaW5nIChNaWNoYWVsIFN0YWNrKQorICA0LiBIQURPT1AtMTM5Ny4gUmVwbGFjZSBjdXN0b20gaGJhc2UgbG9ja2luZyB3aXRoIAorICAgICBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrIChNaWNoYWVsIFN0YWNrKQorICA1LiBIQURPT1AtMTQwMy4gSEJhc2UgcmVsaWFiaWxpdHkgLSBtYWtlIG1hc3RlciBhbmQgcmVnaW9uIHNlcnZlciBtb3JlIGZhdWx0CisgICAgIHRvbGVyYW50LgorICA2LiBIQURPT1AtMTQxOC4gSEJhc2UgbWlzY2VsbGFuZW91czogdW5pdCB0ZXN0IGZvciBIQ2xpZW50LCBjbGllbnQgdG8gZG8KKyAgICAgJ1BlcmZvcm1hbmNlIEV2YWx1YXRpb24nLCBldGMuCisgIDcuIEhBRE9PUC0xNDIwLCBIQURPT1AtMTQyMy4gRmluZGJ1Z3MgY2hhbmdlcywgcmVtb3ZlIHJlZmVyZW5jZSB0byByZW1vdmVkIAorICAgICBjbGFzcyBITG9ja2luZy4KKyAgOC4gSEFET09QLTE0MjQuIFRlc3RIQmFzZUNsdXN0ZXIgZmFpbHMgd2l0aCBJbGxlZ2FsTW9uaXRvclN0YXRlRXhjZXB0aW9uLiBGaXgKKyAgICAgcmVncmVzc2lvbiBpbnRyb2R1Y2VkIGJ5IEhBRE9PUC0xMzk3LgorICA5LiBIQURPT1AtMTQyNi4gTWFrZSBoYmFzZSBzY3JpcHRzIGV4ZWN1dGFibGUgKyBhZGQgdGVzdCBjbGFzc2VzIHRvIENMQVNTUEFUSC4KKyAxMC4gSEFET09QLTE0MzAuIEhCYXNlIHNodXRkb3duIGxlYXZlcyByZWdpb25zZXJ2ZXJzIHVwLgorIDExLiBIQURPT1AtMTM5Mi4gUGFydDE6IGluY2x1ZGVzIGNyZWF0ZS9kZWxldGUgdGFibGU7IGVuYWJsZS9kaXNhYmxlIHRhYmxlOworICAgICBhZGQvcmVtb3ZlIGNvbHVtbi4KKyAxMi4gSEFET09QLTEzOTIuIFBhcnQyOiBpbmNsdWRlcyB0YWJsZSBjb21wYWN0aW9uIGJ5IG1lcmdpbmcgYWRqYWNlbnQgcmVnaW9ucworICAgICB0aGF0IGhhdmUgc2hydW5rIGluIHNpemUuCisgMTMuIEhBRE9PUC0xNDQ1IFN1cHBvcnQgdXBkYXRlcyBhY3Jvc3MgcmVnaW9uIHNwbGl0cyBhbmQgY29tcGFjdGlvbnMKKyAxNC4gSEFET09QLTE0NjAgT24gc2h1dGRvd24gSU9FeGNlcHRpb24gd2l0aCBjb21wbGFpbnQgJ0Nhbm5vdCBjYW5jZWwgbGVhc2UKKyAgICAgdGhhdCBpcyBub3QgaGVsZCcKKyAxNS4gSEFET09QLTE0MjEgRmFpbG92ZXIgZGV0ZWN0aW9uLCBzcGxpdCBsb2cgZmlsZXMuCisgICAgIEZvciB0aGUgZmlsZXMgbW9kaWZpZWQsIGFsc28gY2xlYW4gdXAgamF2YWRvYywgY2xhc3MsIGZpZWxkIGFuZCBtZXRob2QgCisgICAgIHZpc2liaWxpdHkgKEhBRE9PUC0xNDY2KQorIDE2LiBIQURPT1AtMTQ3OSBGaXggTlBFIGluIEhTdG9yZSNnZXQgaWYgc3RvcmUgZmlsZSBvbmx5IGhhcyBrZXlzIDwgcGFzc2VkIGtleS4KKyAxNy4gSEFET09QLTE0NzYgRGlzdHJpYnV0ZWQgdmVyc2lvbiBvZiAnUGVyZm9ybWFuY2UgRXZhbHVhdGlvbicgc2NyaXB0CisgMTguIEhBRE9PUC0xNDY5IEFzeWNocm9ub3VzIHRhYmxlIGNyZWF0aW9uCisgMTkuIEhBRE9PUC0xNDE1IEludGVncmF0ZSBCU0QgbGljZW5zZWQgYmxvb20gZmlsdGVyIGltcGxlbWVudGF0aW9uLgorIDIwLiBIQURPT1AtMTQ2NSBBZGQgY2x1c3RlciBzdG9wL3N0YXJ0IHNjcmlwdHMgZm9yIGhiYXNlCisgMjEuIEhBRE9PUC0xNDE1IFByb3ZpZGUgY29uZmlndXJhYmxlIHBlci1jb2x1bW4gYmxvb20gZmlsdGVycyAtIHBhcnQgMi4KKyAyMi4gSEFET09QLTE0OTguIFJlcGxhY2UgYm94ZWQgdHlwZXMgd2l0aCBwcmltaXRpdmVzIGluIG1hbnkgcGxhY2VzLgorIDIzLiBIQURPT1AtMTUwOS4gIE1hZGUgbWV0aG9kcy9pbm5lciBjbGFzc2VzIGluIEhSZWdpb25TZXJ2ZXIgYW5kIEhDbGllbnQgcHJvdGVjdGVkCisgICAgIGluc3RlYWQgb2YgcHJpdmF0ZSBmb3IgZWFzaWVyIGV4dGVuc2lvbi4gQWxzbyBtYWRlIEhSZWdpb24gYW5kIEhSZWdpb25JbmZvIHB1YmxpYyB0b28uCisgICAgIEFkZGVkIGFuIGhiYXNlLWRlZmF1bHQueG1sIHByb3BlcnR5IGZvciBzcGVjaWZ5aW5nIHdoYXQgSFJlZ2lvbkludGVyZmFjZSBleHRlbnNpb24gdG8gdXNlCisgICAgIGZvciBwcm94eSBzZXJ2ZXIgY29ubmVjdGlvbi4gKEphbWVzIEtlbm5lZHkgdmlhIEppbSBLZWxsZXJtYW4pCisgMjQuIEhBRE9PUC0xNTM0LiBbaGJhc2VdIE1lbWNhY2hlIHNjYW5uZXIgZmFpbHMgaWYgc3RhcnQga2V5IG5vdCBwcmVzZW50CisgMjUuIEhBRE9PUC0xNTM3LiBDYXRjaCBleGNlcHRpb25zIGluIHRlc3RDbGVhblJlZ2lvblNlcnZlckV4aXQgc28gd2UgY2FuIHNlZQorICAgICB3aGF0IGlzIGZhaWxpbmcuCisgMjYuIEhBRE9PUC0xNTQzIFtoYmFzZV0gQWRkIEhDbGllbnQudGFibGVFeGlzdHMKKyAyNy4gSEFET09QLTE1MTkgW2hiYXNlXSBtYXAvcmVkdWNlIGludGVyZmFjZSBmb3IgSEJhc2UuICAoVnVrIEVyY2Vnb3ZhYyBhbmQKKyAgICAgSmltIEtlbGxlcm1hbikKKyAyOC4gSEFET09QLTE1MjMgSHVuZyByZWdpb24gc2VydmVyIHdhaXRpbmcgb24gd3JpdGUgbG9ja3MgCisgMjkuIEhBRE9PUC0xNTYwIE5QRSBpbiBNaW5pSEJhc2VDbHVzdGVyIG9uIFdpbmRvd3MKKyAzMC4gSEFET09QLTE1MzEgQWRkIFJvd0ZpbHRlciB0byBIUmVnaW9uLkhTY2FubmVyCisgICAgIEFkZHMgYSByb3cgZmlsdGVyaW5nIGludGVyZmFjZSBhbmQgdHdvIGltcGxlbWVuZW50YXRpb25zOiBBIHBhZ2Ugc2Nhbm5lciwKKyAgICAgYW5kIGEgcmVnZXggcm93L2NvbHVtbi1kYXRhIG1hdGNoZXIuIChKYW1lcyBLZW5uZWR5IHZpYSBTdGFjaykKKyAzMS4gSEFET09QLTE1NjYgS2V5LW1ha2luZyB1dGlsaXR5CisgMzIuIEhBRE9PUC0xNDE1IFByb3ZpZGUgY29uZmlndXJhYmxlIHBlci1jb2x1bW4gYmxvb20gZmlsdGVycy4gCisgICAgIEhBRE9PUC0xNDY2IENsZWFuIHVwIHZpc2liaWxpdHkgYW5kIGphdmFkb2MgaXNzdWVzIGluIEhCYXNlLgorIDMzLiBIQURPT1AtMTUzOCBQcm92aWRlIGNhcGFiaWxpdHkgZm9yIGNsaWVudCBzcGVjaWZpZWQgdGltZSBzdGFtcHMgaW4gSEJhc2UKKyAgICAgSEFET09QLTE0NjYgQ2xlYW4gdXAgdmlzaWJpbGl0eSBhbmQgamF2YWRvYyBpc3N1ZXMgaW4gSEJhc2UuCisgMzQuIEhBRE9PUC0xNTg5IEV4Y2VwdGlvbiBoYW5kbGluZyBpbiBIQmFzZSBpcyBicm9rZW4gb3ZlciBjbGllbnQgc2VydmVyIGNvbm5lY3Rpb25zCisgMzUuIEhBRE9PUC0xMzc1IGEgc2ltcGxlIHBhcnNlciBmb3IgaGJhc2UgKEVkd2FyZCBZb29uIHZpYSBTdGFjaykKKyAzNi4gSEFET09QLTE2MDAgVXBkYXRlIGxpY2Vuc2UgaW4gSEJhc2UgY29kZQorIDM3LiBIQURPT1AtMTU4OSBFeGNlcHRpb24gaGFuZGxpbmcgaW4gSEJhc2UgaXMgYnJva2VuIG92ZXIgY2xpZW50IHNlcnZlcgorIDM4LiBIQURPT1AtMTU3NCBDb25jdXJyZW50IGNyZWF0ZXMgb2YgYSB0YWJsZSBuYW1lZCAnWCcgYWxsIHN1Y2NlZWQKKyAzOS4gSEFET09QLTE1ODEgVW4tb3BlbmFibGUgdGFibGVuYW1lIGJ1ZworIDQwLiBIQURPT1AtMTYwNyBbc2hlbGxdIENsZWFyIHNjcmVlbiBjb21tYW5kIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spCisgNDEuIEhBRE9PUC0xNjE0IFtoYmFzZV0gSENsaWVudCBkb2VzIG5vdCBwcm90ZWN0IGl0c2VsZiBmcm9tIHNpbXVsdGFuZW91cyB1cGRhdGVzCisgNDIuIEhBRE9PUC0xNDY4IEFkZCBIQmFzZSBiYXRjaCB1cGRhdGUgdG8gcmVkdWNlIFJQQyBvdmVyaGVhZAorIDQzLiBIQURPT1AtMTYxNiBTcG9yYWRpYyBUZXN0VGFibGUgZmFpbHVyZXMKKyA0NC4gSEFET09QLTE2MTUgUmVwbGFjaW5nIHRocmVhZCBub3RpZmljYXRpb24tYmFzZWQgcXVldWUgd2l0aCAKKyAgICAgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZSBpbiBITWFzdGVyLCBIUmVnaW9uU2VydmVyCisgNDUuIEhBRE9PUC0xNjA2IFVwZGF0ZWQgaW1wbGVtZW50YXRpb24gb2YgUm93RmlsdGVyU2V0LCBSb3dGaWx0ZXJJbnRlcmZhY2UKKyAgICAgKEl6YWFrIFJ1YmluIHZpYSBTdGFjaykKKyA0Ni4gSEFET09QLTE1NzkgQWRkIG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyIGFuZCBTdG9wUm93RmlsdGVyIGZpbHRlcnMKKyAgICAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorIDQ3LiBIQURPT1AtMTYzNyBGaXggdG8gSFNjYW5uZXIgdG8gU3VwcG9ydCBGaWx0ZXJzLCBBZGQgRmlsdGVyIFRlc3RzIHRvCisgICAgIFRlc3RTY2FubmVyMiAoSXphYWsgUnViaW4gdmlhIFN0YWNrKQorIDQ4LiBIQURPT1AtMTUxNiBIQ2xpZW50IGZhaWxzIHRvIHJlYWRqdXN0IHdoZW4gUk9PVCBvciBNRVRBIHJlZGVwbG95ZWQgb24gbmV3CisgICAgIHJlZ2lvbiBzZXJ2ZXIKKyA0OS4gSEFET09QLTE2NDYgUmVnaW9uU2VydmVyIE9PTUUncyB1bmRlciBzdXN0YWluZWQsIHN1YnN0YW50aWFsIGxvYWRpbmcgYnkKKyAgICAgMTAgY29uY3VycmVudCBjbGllbnRzCisgNTAuIEhBRE9PUC0xNDY4IEFkZCBIQmFzZSBiYXRjaCB1cGRhdGUgdG8gcmVkdWNlIFJQQyBvdmVyaGVhZCAocmVzdHJpY3QgYmF0Y2hlcworICAgICB0byBhIHNpbmdsZSByb3cgYXQgYSB0aW1lKQorIDUxLiBIQURPT1AtMTUyOCBIQ2xpZW50IGZvciBtdWx0aXBsZSB0YWJsZXMgKHBoYXNlIDEpIChKYW1lcyBLZW5uZWR5ICYgSmltSykKKyA1Mi4gSEFET09QLTE1MjggSENsaWVudCBmb3IgbXVsdGlwbGUgdGFibGVzIChwaGFzZSAyKSBhbGwgSEJhc2UgY2xpZW50IHNpZGUgY29kZQorICAgICAoZXhjZXB0IFRlc3RIQ2xpZW50IGFuZCBIQmFzZVNoZWxsKSBoYXZlIGJlZW4gY29udmVydGVkIHRvIHVzZSB0aGUgbmV3IGNsaWVudAorICAgICBzaWRlIG9iamVjdHMgKEhUYWJsZS9IQmFzZUFkbWluL0hDb25uZWN0aW9uKSBpbnN0ZWFkIG9mIEhDbGllbnQuCisgNTMuIEhBRE9PUC0xNTI4IEhDbGllbnQgZm9yIG11bHRpcGxlIHRhYmxlcyAtIGV4cG9zZSBjbG9zZSB0YWJsZSBmdW5jdGlvbgorIDU0LiBIQURPT1AtMTQ2NiBDbGVhbiB1cCB3YXJuaW5ncywgdmlzaWJpbGl0eSBhbmQgamF2YWRvYyBpc3N1ZXMgaW4gSEJhc2UuCisgNTUuIEhBRE9PUC0xNjYyIE1ha2UgcmVnaW9uIHNwbGl0cyBmYXN0ZXIKKyA1Ni4gSEFET09QLTE2NzggT24gcmVnaW9uIHNwbGl0LCBtYXN0ZXIgc2hvdWxkIGRlc2lnbmF0ZSB3aGljaCBob3N0IHNob3VsZCAKKyAgICAgc2VydmUgZGF1Z2h0ZXIgc3BsaXRzLiBQaGFzZSAxOiBNYXN0ZXIgYmFsYW5jZXMgbG9hZCBmb3IgbmV3IHJlZ2lvbnMgYW5kCisgICAgIHdoZW4gYSByZWdpb24gc2VydmVyIGZhaWxzLgorIDU3LiBIQURPT1AtMTY3OCBPbiByZWdpb24gc3BsaXQsIG1hc3RlciBzaG91bGQgZGVzaWduYXRlIHdoaWNoIGhvc3Qgc2hvdWxkIAorICAgICBzZXJ2ZSBkYXVnaHRlciBzcGxpdHMuIFBoYXNlIDI6IE1hc3RlciBhc3NpZ25zIGNoaWxkcmVuIG9mIHNwbGl0IHJlZ2lvbgorICAgICBpbnN0ZWFkIG9mIEhSZWdpb25TZXJ2ZXIgc2VydmluZyBib3RoIGNoaWxkcmVuLgorIDU4LiBIQURPT1AtMTcxMCBBbGwgdXBkYXRlcyBzaG91bGQgYmUgYmF0Y2ggdXBkYXRlcworIDU5LiBIQURPT1AtMTcxMSBIVGFibGUgQVBJIHNob3VsZCB1c2UgaW50ZXJmYWNlcyBpbnN0ZWFkIG9mIGNvbmNyZXRlIGNsYXNzZXMgYXMKKyAgICAgbWV0aG9kIHBhcmFtZXRlcnMgYW5kIHJldHVybiB2YWx1ZXMKKyA2MC4gSEFET09QLTE2NDQgQ29tcGFjdGlvbnMgc2hvdWxkIG5vdCBibG9jayB1cGRhdGVzCisgNjAuIEhBRE9PUC0xNjcyIEhCYXNlIFNoZWxsIHNob3VsZCB1c2UgbmV3IGNsaWVudCBjbGFzc2VzCisgICAgIChFZHdhcmQgWW9vbiB2aWEgU3RhY2spLgorIDYxLiBIQURPT1AtMTcwOSBNYWtlIEhSZWdpb25JbnRlcmZhY2UgbW9yZSBsaWtlIHRoYXQgb2YgSFRhYmxlCisgICAgIEhBRE9PUC0xNzI1IENsaWVudCBmaW5kIG9mIHRhYmxlIHJlZ2lvbnMgc2hvdWxkIG5vdCBpbmNsdWRlIG9mZmxpbmVkLCBzcGxpdCBwYXJlbnRzCmRpZmYgLS1naXQgYS9MSUNFTlNFLnR4dCBiL0xJQ0VOU0UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2NDU2OTUKLS0tIC9kZXYvbnVsbAorKysgYi9MSUNFTlNFLnR4dApAQCAtMCwwICsxLDIwMiBAQAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKworICAgQVBQRU5ESVg6IEhvdyB0byBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLgorCisgICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZworICAgICAgYm9pbGVycGxhdGUgbm90aWNlLCB3aXRoIHRoZSBmaWVsZHMgZW5jbG9zZWQgYnkgYnJhY2tldHMgIltdIgorICAgICAgcmVwbGFjZWQgd2l0aCB5b3VyIG93biBpZGVudGlmeWluZyBpbmZvcm1hdGlvbi4gKERvbid0IGluY2x1ZGUKKyAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCisgICAgICBjb21tZW50IHN5bnRheCBmb3IgdGhlIGZpbGUgZm9ybWF0LiBXZSBhbHNvIHJlY29tbWVuZCB0aGF0IGEKKyAgICAgIGZpbGUgb3IgY2xhc3MgbmFtZSBhbmQgZGVzY3JpcHRpb24gb2YgcHVycG9zZSBiZSBpbmNsdWRlZCBvbiB0aGUKKyAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgorICAgICAgaWRlbnRpZmljYXRpb24gd2l0aGluIHRoaXJkLXBhcnR5IGFyY2hpdmVzLgorCisgICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KZGlmZiAtLWdpdCBhL05PVElDRS50eHQgYi9OT1RJQ0UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmYjdkNzQKLS0tIC9kZXYvbnVsbAorKysgYi9OT1RJQ0UudHh0CkBAIC0wLDAgKzEsNDQgQEAKK1RoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgVGhlIEFwYWNoZSBTb2Z0d2FyZQorRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuCisKK0luIGFkZGl0aW9uLCB0aGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5OgorCisKK0V1cm9wZWFuIENvbW1pc3Npb24gcHJvamVjdCBPbmVMYWIgKGh0dHA6Ly93d3cub25lLWxhYi5vcmcpCisKKworRmFjZWJvb2ssIEluYy4gKGh0dHA6Ly9kZXZlbG9wZXJzLmZhY2Vib29rLmNvbS90aHJpZnQvIC0tIFBhZ2UgaW5jbHVkZXMgdGhlIFRocmlmdCBTb2Z0d2FyZSBMaWNlbnNlKQorCisKK0pVbml0IChodHRwOi8vd3d3Lmp1bml0Lm9yZy8pCisKKworTWljaGFlbCBHb3R0ZXNtYW4gZGV2ZWxvcGVkIEFnaWxlSlNPTi4gIEl0cyBzb3VyY2UgY29kZSBpcyBoZXJlOgorCisgaHR0cDovL2dpdGh1Yi5jb20vZ290dGVzbW0vYWdpbGUtanNvbi0yLjAvdHJlZS9tYXN0ZXIKKworSXQgaGFzIHRoaXMgbGljZW5zZSBhdCB0aGUgaGVhZCBvZiB0aGUgZWFjaCBzb3VyY2UgZmlsZToKKworICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKKyAqIGNvcHkKKyAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0bworICogZGVhbAorICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlCisgKiByaWdodHMKKyAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKKyAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcworICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKyAqCisgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgorICogYWxsCisgKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorICoKKyAqIFRoZSBTb2Z0d2FyZSBzaGFsbCBiZSB1c2VkIGZvciBHb29kLCBub3QgRXZpbC4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKKyAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKKyAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCisgKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCisgKiBUSEUgU09GVFdBUkUuCmRpZmYgLS1naXQgYS9SRUFETUUudHh0IGIvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTY4MzEyCi0tLSAvZGV2L251bGwKKysrIGIvUkVBRE1FLnR4dApAQCAtMCwwICsxIEBACitTZWUgdGhlIGRvY3MgZGlyZWN0b3J5IG9yIGh0dHA6Ly9oYmFzZS5vcmcKZGlmZiAtLWdpdCBhL2Jpbi9Gb3JtYXR0ZXIucmIgYi9iaW4vRm9ybWF0dGVyLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3OTMyOTAKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vRm9ybWF0dGVyLnJiCkBAIC0wLDAgKzEsMTM3IEBACisjIFJlc3VsdHMgZm9ybWF0dGVyCittb2R1bGUgRm9ybWF0dGVyCisgICMgQmFzZSBhYnN0cmFjdCBjbGFzcyBmb3IgcmVzdWx0cyBmb3JtYXR0aW5nLgorICBjbGFzcyBGb3JtYXR0ZXIKKyAgICAjIFRha2VzIGFuIG91dHB1dCBzdHJlYW0gYW5kIGEgcHJpbnQgd2lkdGguCisgICAgZGVmIGluaXRpYWxpemUobywgdyA9IDEwMCkKKyAgICAgIHJhaXNlIFR5cGVFcnJvci5uZXcoIlR5cGUgJXMgb2YgcGFyYW1ldGVyICVzIGlzIG5vdCBJTyIgJSBbby5jbGFzcywgb10pIFwKKyAgICAgICAgdW5sZXNzIG8uaW5zdGFuY2Vfb2Y/IElPCisgICAgICBAb3V0ID0gbworICAgICAgQG1heFdpZHRoID0gdworICAgICAgQHJvd0NvdW50ID0gMAorICAgIGVuZAorCisgICAgYXR0cl9yZWFkZXIgOnJvd0NvdW50CisKKyAgICBkZWYgaGVhZGVyKGFyZ3MgPSBbXSwgd2lkdGhzID0gW10pCisgICAgICByb3coYXJncywgZmFsc2UsIHdpZHRocykgaWYgYXJncy5sZW5ndGggPiAwCisgICAgICBAcm93Q291bnQgPSAwCisgICAgZW5kCisgICAgCisgICAgIyBPdXRwdXQgYSByb3cuCisgICAgIyBJbnNldCBpcyB3aGV0aGVyIG9yIG5vdCB0byBvZmZzZXQgcm93IGJ5IGEgc3BhY2UuCisgICAgZGVmIHJvdyhhcmdzID0gW10sIGluc2V0ID0gdHJ1ZSwgd2lkdGhzID0gW10pCisgICAgICBpZiBub3QgYXJncyBvciBhcmdzLmxlbmd0aCA9PSAwCisgICAgICAgICMgUHJpbnQgb3V0IG5vdGhpbmcKKyAgICAgICAgcmV0dXJuCisgICAgICBlbmQKKyAgICAgIGlmIGFyZ3MuY2xhc3MgPT0gU3RyaW5nCisgICAgICAgIG91dHB1dChAbWF4V2lkdGgsIGFyZ3MpCisgICAgICAgIHB1dHMKKyAgICAgICAgcmV0dXJuCisgICAgICBlbmQKKyAgICAgICMgVE9ETzogTG9vayBhdCB0aGUgdHlwZS4gIElzIGl0IFJvd1Jlc3VsdD8KKyAgICAgIGlmIGFyZ3MubGVuZ3RoID09IDEKKyAgICAgICAgc3BsaXRzID0gc3BsaXQoQG1heFdpZHRoLCBkdW1wKGFyZ3NbMF0pKQorICAgICAgICBmb3IgbCBpbiBzcGxpdHMKKyAgICAgICAgICBvdXRwdXQoQG1heFdpZHRoLCBsKQorICAgICAgICAgIHB1dHMKKyAgICAgICAgZW5kCisgICAgICBlbHNpZiBhcmdzLmxlbmd0aCA9PSAyCisgICAgICAgIGNvbDF3aWR0aCA9IChub3Qgd2lkdGhzIG9yIHdpZHRocy5sZW5ndGggPT0gMCkgPyBAbWF4V2lkdGggLyA0IDogQG1heFdpZHRoICogd2lkdGhzWzBdIC8gMTAwCisgICAgICAgIGNvbDJ3aWR0aCA9IChub3Qgd2lkdGhzIG9yIHdpZHRocy5sZW5ndGggPCAyKSA/IEBtYXhXaWR0aCAtIGNvbDF3aWR0aCAtIDIgOiBAbWF4V2lkdGggKiB3aWR0aHNbMV0gLyAxMDAgLSAyCisgICAgICAgIHNwbGl0czEgPSBzcGxpdChjb2wxd2lkdGgsIGR1bXAoYXJnc1swXSkpCisgICAgICAgIHNwbGl0czIgPSBzcGxpdChjb2wyd2lkdGgsIGR1bXAoYXJnc1sxXSkpCisgICAgICAgIGJpZ2dlc3QgPSAoc3BsaXRzMi5sZW5ndGggPiBzcGxpdHMxLmxlbmd0aCk/IHNwbGl0czIubGVuZ3RoOiBzcGxpdHMxLmxlbmd0aAorICAgICAgICBpbmRleCA9IDAKKyAgICAgICAgd2hpbGUgaW5kZXggPCBiaWdnZXN0CisgICAgICAgICAgaWYgaW5zZXQKKyAgICAgICAgICAgICMgSW5zZXQgYnkgb25lIHNwYWNlIGlmIGluc2V0IGlzIHNldC4KKyAgICAgICAgICAgIEBvdXQucHJpbnQoIiAiKQorICAgICAgICAgIGVuZAorICAgICAgICAgIG91dHB1dChjb2wxd2lkdGgsIHNwbGl0czFbaW5kZXhdKQorICAgICAgICAgIGlmIG5vdCBpbnNldAorICAgICAgICAgICAgIyBBZGQgZXh0cmEgc3BhY2Ugc28gc2Vjb25kIGNvbHVtbiBsaW5lcyB1cCB3LyBzZWNvbmQgY29sdW1uIG91dHB1dAorICAgICAgICAgICAgQG91dC5wcmludCgiICIpCisgICAgICAgICAgZW5kCisgICAgICAgICAgQG91dC5wcmludCgiICIpCisgICAgICAgICAgb3V0cHV0KGNvbDJ3aWR0aCwgc3BsaXRzMltpbmRleF0pCisgICAgICAgICAgaW5kZXggKz0gMQorICAgICAgICAgIHB1dHMKKyAgICAgICAgZW5kCisgICAgICBlbHNlCisgICAgICAgICMgUHJpbnQgYSBzcGFjZSB0byBzZXQgb2ZmIG11bHRpLWNvbHVtbiByb3dzCisgICAgICAgIHByaW50ICcgJworICAgICAgICBmaXJzdCA9IHRydWUKKyAgICAgICAgZm9yIGUgaW4gYXJncworICAgICAgICAgIEBvdXQucHJpbnQgIiAiIHVubGVzcyBmaXJzdAorICAgICAgICAgIGZpcnN0ID0gZmFsc2UKKyAgICAgICAgICBAb3V0LnByaW50IGUKKyAgICAgICAgZW5kCisgICAgICAgIHB1dHMKKyAgICAgIGVuZAorICAgICAgQHJvd0NvdW50ICs9IDEKKyAgICBlbmQKKworICAgIGRlZiBzcGxpdCh3aWR0aCwgc3RyKQorICAgICAgcmVzdWx0ID0gW10KKyAgICAgIGluZGV4ID0gMAorICAgICAgd2hpbGUgaW5kZXggPCBzdHIubGVuZ3RoIGRvCisgICAgICAgIHJlc3VsdCA8PCBzdHIuc2xpY2UoaW5kZXgsIHdpZHRoKQorICAgICAgICBpbmRleCArPSB3aWR0aAorICAgICAgZW5kCisgICAgICByZXN1bHQKKyAgICBlbmQKKworICAgIGRlZiBkdW1wKHN0cikKKyAgICAgIGlmIHN0ci5pbnN0YW5jZV9vZj8gRml4bnVtCisgICAgICAgICAgcmV0dXJuCisgICAgICBlbmQKKyAgICAgICMgUmVtb3ZlIGRvdWJsZS1xdW90ZXMgYWRkZWQgYnkgJ2R1bXAnLgorICAgICAgcmV0dXJuIHN0ci5kdW1wWzEuLi0yXQorICAgIGVuZAorCisgICAgZGVmIG91dHB1dCh3aWR0aCwgc3RyKQorICAgICAgIyBNYWtlIHVwIGEgc3BlYyBmb3IgcHJpbnRmCisgICAgICBzcGVjID0gIiUlLSVkcyIgJSB3aWR0aAorICAgICAgQG91dC5wcmludGYoc3BlYywgc3RyKQorICAgIGVuZAorCisgICAgZGVmIGZvb3RlcihzdGFydFRpbWUgPSBuaWwsIHJvd0NvdW50ID0gbmlsKQorICAgICAgaWYgbm90IHJvd0NvdW50CisgICAgICAgIHJvd0NvdW50ID0gQHJvd0NvdW50CisgICAgICBlbmQKKyAgICAgIGlmIG5vdCBzdGFydFRpbWUKKyAgICAgICAgcmV0dXJuCisgICAgICBlbmQKKyAgICAgICMgT25seSBvdXRwdXQgZWxhcHNlZCB0aW1lIGFuZCByb3cgY291bnQgaWYgc3RhcnRUaW1lIHBhc3NlZAorICAgICAgQG91dC5wdXRzKCIlZCByb3cocykgaW4gJS40ZiBzZWNvbmRzIiAlIFtyb3dDb3VudCwgVGltZS5ub3cgLSBzdGFydFRpbWVdKQorICAgIGVuZAorICBlbmQKKyAgICAgCisKKyAgY2xhc3MgQ29uc29sZSA8IEZvcm1hdHRlcgorICBlbmQKKworICBjbGFzcyBYSFRNTEZvcm1hdHRlciA8IEZvcm1hdHRlcgorICAgICMgaHR0cDovL3d3dy5nZXJtYW5lLXNvZnR3YXJlLmNvbS9zb2Z0d2FyZS9yZXhtbC9kb2MvY2xhc3Nlcy9SRVhNTC9Eb2N1bWVudC5odG1sCisgICAgIyBodHRwOi8vd3d3LmNydW1teS5jb20vd3JpdGluZy9SdWJ5Q29va2Jvb2svdGVzdF9yZXN1bHRzLzc1OTQyLmh0bWwKKyAgZW5kCisKKyAgY2xhc3MgSlNPTiA8IEZvcm1hdHRlcgorICBlbmQKKworICAjIERvIGEgYml0IG9mIHRlc3RpbmcuCisgIGlmICQwID09IF9fRklMRV9fCisgICAgZm9ybWF0dGVyID0gQ29uc29sZS5uZXcoU1RET1VUKQorICAgIG5vdyA9IFRpbWUubm93CisgICAgZm9ybWF0dGVyLmhlYWRlcihbJ2EnLCAnYiddKQorICAgIGZvcm1hdHRlci5yb3coWydhJywgJ2InXSkKKyAgICBmb3JtYXR0ZXIucm93KFsneHh4eHh4eHh4IHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4eCB4eHh4eHh4eHggeHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4eHh4eCB4eHh4eHh4eHggeHh4eHh4eHh4eHh4eHgnXSkKKyAgICBmb3JtYXR0ZXIucm93KFsneXl5eXl5IHl5eXl5eSB5eXl5eSB5eXknLCAneHh4eHh4eHh4IHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4eCB4eHh4eHh4eHggeHh4eHh4eHh4eHh4IHh4eHh4eHh4eHh4eHh4eCB4eHh4eHh4eHggeHh4eHh4eHh4eHh4eHggIHh4eCB4eCB4IHh4IHh4eCB4eCB4eCB4eCB4IHh4IHggeCB4eHggeCB4IHh4eCB4IHggeHggeCB4IHggeCB4IHggeHggJ10pCisgICAgZm9ybWF0dGVyLnJvdyhbIk5BTUUgPT4gJ3RhYmxlMScsIEZBTUlMSUVTID0+IFt7TkFNRSA9PiAnZmFtMicsIFZFUlNJT05TID0+IDMsIENPTVBSRVNTSU9OID0+ICdOT05FJywgSU5fTUVNT1JZID0+IGZhbHNlLCBCTE9DS0NBQ0hFID0+IGZhbHNlLCBMRU5HVEggPT4gMjE0NzQ4MzY0NywgVFRMID0+IEZPUkVWRVIsIEJMT09NRklMVEVSID0+IE5PTkV9LCB7TkFNRSA9PiAnZmFtMScsIFZFUlNJT05TID0+IDMsIENPTVBSRVNTSU9OID0+ICdOT05FJywgSU5fTUVNT1JZID0+IGZhbHNlLCBCTE9DS0NBQ0hFID0+IGZhbHNlLCBMRU5HVEggPT4gMjE0NzQ4MzY0NywgVFRMID0+IEZPUkVWRVIsIEJMT09NRklMVEVSID0+IE5PTkV9XSJdKQorICAgIGZvcm1hdHRlci5mb290ZXIobm93KQorICBlbmQKK2VuZAorCisKZGlmZiAtLWdpdCBhL2Jpbi9IQmFzZS5yYiBiL2Jpbi9IQmFzZS5yYgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzhiMDcyCi0tLSAvZGV2L251bGwKKysrIGIvYmluL0hCYXNlLnJiCkBAIC0wLDAgKzEsNTU2IEBACisjIEhCYXNlIHJ1YnkgY2xhc3Nlcy4KKyMgSGFzIHdyYXBwZXIgY2xhc3NlcyBmb3Igb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW4KKyMgYW5kIGZvciBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlLiAgQ2xhc3NlcyB0YWtlCisjIEZvcm1hdHRlcnMgb24gY29uc3RydWN0aW9uIGFuZCBvdXRwdXRzIGFueSByZXN1bHRzIHVzaW5nCisjIEZvcm1hdHRlciBtZXRob2RzLiAgVGhlc2UgY2xhc3NlcyBhcmUgb25seSByZWFsbHkgZm9yIHVzZSBieQorIyB0aGUgaGlyYi5yYiBIQmFzZSBTaGVsbCBzY3JpcHQ7IHRoZXkgZG9uJ3QgbWFrZSBtdWNoIHNlbnNlIGVsc2V3aGVyZS4KKyMgRm9yIGV4YW1wbGUsIHRoZSBleGlzdHMgbWV0aG9kIG9uIEFkbWluIGNsYXNzIHByaW50cyB0byB0aGUgZm9ybWF0dGVyCisjIHdoZXRoZXIgdGhlIHRhYmxlIGV4aXN0cyBhbmQgcmV0dXJucyBuaWwgcmVnYXJkbGVzcy4KK2luY2x1ZGUgSmF2YQoraW5jbHVkZV9jbGFzcygnamF2YS5sYW5nLkludGVnZXInKSB7fHBhY2thZ2UsbmFtZXwgIkoje25hbWV9IiB9CitpbmNsdWRlX2NsYXNzKCdqYXZhLmxhbmcuTG9uZycpIHt8cGFja2FnZSxuYW1lfCAiSiN7bmFtZX0iIH0KK2luY2x1ZGVfY2xhc3MoJ2phdmEubGFuZy5Cb29sZWFuJykge3xwYWNrYWdlLG5hbWV8ICJKI3tuYW1lfSIgfQorCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW4KK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50cworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbAoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkNvbXByZXNzaW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3IKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlcworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm8KKworbW9kdWxlIEhCYXNlCisgIENPTFVNTiA9ICJDT0xVTU4iCisgIENPTFVNTlMgPSAiQ09MVU1OUyIKKyAgVElNRVNUQU1QID0gIlRJTUVTVEFNUCIKKyAgTkFNRSA9IEhDb25zdGFudHM6Ok5BTUUKKyAgVkVSU0lPTlMgPSBIQ29uc3RhbnRzOjpWRVJTSU9OUworICBJTl9NRU1PUlkgPSBIQ29uc3RhbnRzOjpJTl9NRU1PUlkKKyAgU1RPUFJPVyA9ICJTVE9QUk9XIgorICBTVEFSVFJPVyA9ICJTVEFSVFJPVyIKKyAgRU5EUk9XID0gU1RPUFJPVworICBMSU1JVCA9ICJMSU1JVCIKKyAgTUVUSE9EID0gIk1FVEhPRCIKKyAgTUFYTEVOR1RIID0gIk1BWExFTkdUSCIKKworICAjIFdyYXBwZXIgZm9yIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluCisgIGNsYXNzIEFkbWluCisgICAgZGVmIGluaXRpYWxpemUoY29uZmlndXJhdGlvbiwgZm9ybWF0dGVyKQorICAgICAgQGFkbWluID0gSEJhc2VBZG1pbi5uZXcoY29uZmlndXJhdGlvbikKKyAgICAgIEBmb3JtYXR0ZXIgPSBmb3JtYXR0ZXIKKyAgICBlbmQKKyAgIAorICAgIGRlZiBsaXN0CisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIGZvciB0IGluIEBhZG1pbi5saXN0VGFibGVzKCkKKyAgICAgICAgQGZvcm1hdHRlci5yb3coW3QuZ2V0TmFtZUFzU3RyaW5nKCldKQorICAgICAgZW5kCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgZGVzY3JpYmUodGFibGVOYW1lKQorICAgICAgbm93ID0gVGltZS5ub3cgCisgICAgICBAZm9ybWF0dGVyLmhlYWRlcihbIkRFU0NSSVBUSU9OIiwgIkVOQUJMRUQiXSwgWzY0XSkKKyAgICAgIGZvdW5kID0gZmFsc2UKKyAgICAgIHRhYmxlcyA9IEBhZG1pbi5saXN0VGFibGVzKCkudG9fYQorICAgICAgdGFibGVzLnB1c2goSFRhYmxlRGVzY3JpcHRvcjo6TUVUQV9UQUJMRURFU0MsIEhUYWJsZURlc2NyaXB0b3I6OlJPT1RfVEFCTEVERVNDKQorICAgICAgZm9yIHQgaW4gdGFibGVzCisgICAgICAgIGlmIHQuZ2V0TmFtZUFzU3RyaW5nKCkgPT0gdGFibGVOYW1lCisgICAgICAgICAgQGZvcm1hdHRlci5yb3coW3QudG9fcywgIiVzIiAlIFtAYWRtaW4uaXNUYWJsZUVuYWJsZWQodGFibGVOYW1lKV1dLCB0cnVlLCBbNjRdKQorICAgICAgICAgIGZvdW5kID0gdHJ1ZQorICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgICAgaWYgbm90IGZvdW5kCisgICAgICAgIHJhaXNlIEFyZ3VtZW50RXJyb3IubmV3KCJGYWlsZWQgdG8gZmluZCB0YWJsZSBuYW1lZCAiICsgdGFibGVOYW1lKQorICAgICAgZW5kCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgZXhpc3RzKHRhYmxlTmFtZSkKKyAgICAgIG5vdyA9IFRpbWUubm93IAorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgZSA9IEBhZG1pbi50YWJsZUV4aXN0cyh0YWJsZU5hbWUpCisgICAgICBAZm9ybWF0dGVyLnJvdyhbZS50b19zXSkKKyAgICAgIEBmb3JtYXR0ZXIuZm9vdGVyKG5vdykKKyAgICBlbmQKKworICAgIGRlZiBmbHVzaCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIEBhZG1pbi5mbHVzaCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgY29tcGFjdCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIEBhZG1pbi5jb21wYWN0KHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkKKyAgICAgIEBmb3JtYXR0ZXIuZm9vdGVyKG5vdykKKyAgICBlbmQKKworICAgIGRlZiBtYWpvcl9jb21wYWN0KHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkKKyAgICAgIG5vdyA9IFRpbWUubm93IAorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgQGFkbWluLm1ham9yQ29tcGFjdCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgc3BsaXQodGFibGVOYW1lT3JSZWdpb25OYW1lKQorICAgICAgbm93ID0gVGltZS5ub3cgCisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICBAYWRtaW4uc3BsaXQodGFibGVOYW1lT3JSZWdpb25OYW1lKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIGVuYWJsZSh0YWJsZU5hbWUpCisgICAgICAjIFRPRE86IE5lZWQgYW4gaXNFbmFibGVkIG1ldGhvZAorICAgICAgbm93ID0gVGltZS5ub3cgCisgICAgICBAYWRtaW4uZW5hYmxlVGFibGUodGFibGVOYW1lKQorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIGRpc2FibGUodGFibGVOYW1lKQorICAgICAgIyBUT0RPOiBOZWVkIGFuIGlzRGlzYWJsZWQgbWV0aG9kCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIEBhZG1pbi5kaXNhYmxlVGFibGUodGFibGVOYW1lKQorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIGVuYWJsZV9yZWdpb24ocmVnaW9uTmFtZSkKKyAgICAgIG9ubGluZShyZWdpb25OYW1lLCBmYWxzZSkKKyAgICBlbmQKKworICAgIGRlZiBkaXNhYmxlX3JlZ2lvbihyZWdpb25OYW1lKQorICAgICAgb25saW5lKHJlZ2lvbk5hbWUsIHRydWUpCisgICAgZW5kCisgICAKKyAgICBkZWYgb25saW5lKHJlZ2lvbk5hbWUsIG9uT3JPZmYpCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIG1ldGEgPSBIVGFibGUubmV3KEhDb25zdGFudHM6Ok1FVEFfVEFCTEVfTkFNRSkKKyAgICAgIGJ5dGVzID0gQnl0ZXMudG9CeXRlcyhyZWdpb25OYW1lKQorICAgICAgaHJpQnl0ZXMgPSBtZXRhLmdldChieXRlcywgSENvbnN0YW50czo6Q09MX1JFR0lPTklORk8pLmdldFZhbHVlKCkKKyAgICAgIGhyaSA9IFdyaXRhYmxlcy5nZXRXcml0YWJsZShocmlCeXRlcywgSFJlZ2lvbkluZm8ubmV3KCkpOworICAgICAgaHJpLnNldE9mZmxpbmUob25Pck9mZikKKyAgICAgIHAgaHJpCisgICAgICBidSA9IEJhdGNoVXBkYXRlLm5ldyhieXRlcykKKyAgICAgIGJ1LnB1dChIQ29uc3RhbnRzOjpDT0xfUkVHSU9OSU5GTywgV3JpdGFibGVzLmdldEJ5dGVzKGhyaSkpCisgICAgICBtZXRhLmNvbW1pdChidSk7CisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgZHJvcCh0YWJsZU5hbWUpCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIGlmIEBhZG1pbi5pc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpCisgICAgICAgIHJhaXNlIElPRXJyb3IubmV3KCJUYWJsZSAiICsgdGFibGVOYW1lICsgIiBpcyBlbmFibGVkLiBEaXNhYmxlIGl0IGZpcnN0IikKKyAgICAgIGVsc2UKKyAgICAgICAgQGFkbWluLmRlbGV0ZVRhYmxlKHRhYmxlTmFtZSkKKyAgICAgIGVuZAorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIHRydW5jYXRlKHRhYmxlTmFtZSkKKyAgICAgIG5vdyA9IFRpbWUubm93CisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICBoVGFibGUgPSBIVGFibGUubmV3KHRhYmxlTmFtZSkKKyAgICAgIHRhYmxlRGVzY3JpcHRpb24gPSBoVGFibGUuZ2V0VGFibGVEZXNjcmlwdG9yKCkKKyAgICAgIHB1dHMgJ1RydW5jYXRpbmcgJyArIHRhYmxlTmFtZSArICc7IGl0IG1heSB0YWtlIGEgd2hpbGUnCisgICAgICBwdXRzICdEaXNhYmxpbmcgdGFibGUuLi4nCisgICAgICBkaXNhYmxlKHRhYmxlTmFtZSkKKyAgICAgIHB1dHMgJ0Ryb3BwaW5nIHRhYmxlLi4uJworICAgICAgZHJvcCh0YWJsZU5hbWUpCisgICAgICBwdXRzICdDcmVhdGluZyB0YWJsZS4uLicKKyAgICAgIEBhZG1pbi5jcmVhdGVUYWJsZSh0YWJsZURlc2NyaXB0aW9uKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgIyBQYXNzIHRhYmxlbmFtZSBhbmQgYW4gYXJyYXkgb2YgSGFzaGVzCisgICAgZGVmIGNyZWF0ZSh0YWJsZU5hbWUsIGFyZ3MpCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgICMgUGFzcyB0YWJsZSBuYW1lIGFuZCBhbiBhcnJheSBvZiBIYXNoZXMuICBMYXRlciwgdGVzdCB0aGUgbGFzdAorICAgICAgIyBhcnJheSB0byBzZWUgaWYgaXRzIHRhYmxlIG9wdGlvbnMgcmF0aGVyIHRoYW4gY29sdW1uIGZhbWlseSBzcGVjLgorICAgICAgcmFpc2UgVHlwZUVycm9yLm5ldygiVGFibGUgbmFtZSBtdXN0IGJlIG9mIHR5cGUgU3RyaW5nIikgXAorICAgICAgICB1bmxlc3MgdGFibGVOYW1lLmluc3RhbmNlX29mPyBTdHJpbmcKKyAgICAgICMgRm9yIG5vdyBwcmVzdW1lIGFsbCB0aGUgcmVzdCBvZiB0aGUgYXJncyBhcmUgY29sdW1uIGZhbWlseQorICAgICAgIyBoYXNoIHNwZWNpZmljYXRpb25zLiBUT0RPOiBBZGQgdGFibGUgb3B0aW9ucyBoYW5kbGluZy4KKyAgICAgIGh0ZCA9IEhUYWJsZURlc2NyaXB0b3IubmV3KHRhYmxlTmFtZSkKKyAgICAgIGZvciBhcmcgaW4gYXJncworICAgICAgICBpZiBhcmcuaW5zdGFuY2Vfb2Y/IFN0cmluZworICAgICAgICAgIGh0ZC5hZGRGYW1pbHkoSENvbHVtbkRlc2NyaXB0b3IubmV3KG1ha2VDb2x1bW5OYW1lKGFyZykpKQorICAgICAgICBlbHNlCisgICAgICAgICAgcmFpc2UgVHlwZUVycm9yLm5ldyhhcmcuY2xhc3MudG9fcyArICIgb2YgIiArIGFyZy50b19zICsgIiBpcyBub3Qgb2YgSGFzaCB0eXBlIikgXAorICAgICAgICAgICAgdW5sZXNzIGFyZy5pbnN0YW5jZV9vZj8gSGFzaAorICAgICAgICAgIGh0ZC5hZGRGYW1pbHkoaGNkKGFyZykpCisgICAgICAgIGVuZAorICAgICAgZW5kCisgICAgICBAYWRtaW4uY3JlYXRlVGFibGUoaHRkKQorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIGFsdGVyKHRhYmxlTmFtZSwgYXJncykKKyAgICAgIG5vdyA9IFRpbWUubm93CisgICAgICByYWlzZSBUeXBlRXJyb3IubmV3KCJUYWJsZSBuYW1lIG11c3QgYmUgb2YgdHlwZSBTdHJpbmciKSBcCisgICAgICAgIHVubGVzcyB0YWJsZU5hbWUuaW5zdGFuY2Vfb2Y/IFN0cmluZworICAgICAgaHRkID0gQGFkbWluLmdldFRhYmxlRGVzY3JpcHRvcih0YWJsZU5hbWUudG9famF2YV9ieXRlcykKKyAgICAgIG1ldGhvZCA9IGFyZ3MuZGVsZXRlKE1FVEhPRCkKKyAgICAgIGlmIG1ldGhvZCA9PSAiZGVsZXRlIgorICAgICAgICBAYWRtaW4uZGVsZXRlQ29sdW1uKHRhYmxlTmFtZSwgbWFrZUNvbHVtbk5hbWUoYXJnc1tOQU1FXSkpCisgICAgICBlbHNpZiBtZXRob2QgPT0gInRhYmxlX2F0dCIKKyAgICAgICAgYXJnc1tNQVhfRklMRVNJWkVdPyBodGQuc2V0TWF4RmlsZVNpemUoSkxvbmcudmFsdWVPZihhcmdzW01BWF9GSUxFU0laRV0pKSA6ICAKKyAgICAgICAgICBodGQuc2V0TWF4RmlsZVNpemUoSFRhYmxlRGVzY3JpcHRvcjo6REVGQVVMVF9NQVhfRklMRVNJWkUpOworICAgICAgICBhcmdzW1JFQURPTkxZXT8gaHRkLnNldFJlYWRPbmx5KEpCb29sZWFuLnZhbHVlT2YoYXJnc1tSRUFET05MWV0pKSA6IAorICAgICAgICAgIGh0ZC5zZXRSZWFkT25seShIVGFibGVEZXNjcmlwdG9yOjpERUZBVUxUX1JFQURPTkxZKTsKKyAgICAgICAgYXJnc1tNRU1DQUNIRV9GTFVTSFNJWkVdPyAKKyAgICAgICAgICBodGQuc2V0TWVtY2FjaGVGbHVzaFNpemUoSkxvbmcudmFsdWVPZihhcmdzW01FTUNBQ0hFX0ZMVVNIU0laRV0pKSA6CisgICAgICAgICAgaHRkLnNldE1lbWNhY2hlRmx1c2hTaXplKEhUYWJsZURlc2NyaXB0b3I6OkRFRkFVTFRfTUVNQ0FDSEVfRkxVU0hfU0laRSk7CisgICAgICAgIEBhZG1pbi5tb2RpZnlUYWJsZSh0YWJsZU5hbWUudG9famF2YV9ieXRlcywgaHRkKQorICAgICAgZWxzZQorICAgICAgICBkZXNjcmlwdG9yID0gaGNkKGFyZ3MpIAorICAgICAgICBpZiAoaHRkLmhhc0ZhbWlseShkZXNjcmlwdG9yLmdldE5hbWVBc1N0cmluZygpLnRvX2phdmFfYnl0ZXMpKQorICAgICAgICAgIEBhZG1pbi5tb2RpZnlDb2x1bW4odGFibGVOYW1lLCBkZXNjcmlwdG9yLmdldE5hbWVBc1N0cmluZygpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IpOworICAgICAgICBlbHNlCisgICAgICAgICAgQGFkbWluLmFkZENvbHVtbih0YWJsZU5hbWUsIGRlc2NyaXB0b3IpOworICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgICAgQGZvcm1hdHRlci5oZWFkZXIoKQorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIGNsb3NlX3JlZ2lvbihyZWdpb25OYW1lLCBzZXJ2ZXIpCisgICAgICBub3cgPSBUaW1lLm5vdworICAgICAgcyA9IG5pbAorICAgICAgcyA9IFtzZXJ2ZXJdLnRvX2phdmEgaWYgc2VydmVyCisgICAgICBAYWRtaW4uY2xvc2VSZWdpb24ocmVnaW9uTmFtZSwgcykKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIEBmb3JtYXR0ZXIuZm9vdGVyKG5vdykKKyAgICBlbmQKKworICAgICMgTWFrZSBhIGxlZ2FsIGNvbHVtbiAgbmFtZSBvZiB0aGUgcGFzc2VkIFN0cmluZworICAgICMgQ2hlY2sgc3RyaW5nIGVuZHMgaW4gY29sb24uIElmIG5vdCwgYWRkIGl0LgorICAgIGRlZiBtYWtlQ29sdW1uTmFtZShhcmcpCisgICAgICBpbmRleCA9IGFyZy5pbmRleCgnOicpCisgICAgICBpZiBub3QgaW5kZXgKKyAgICAgICAgIyBBZGQgYSBjb2xvbi4gIElmIGFscmVhZHkgYSBjb2xvbiwgaXRzIGluIHRoZSByaWdodCBwbGFjZSwKKyAgICAgICAgIyBvciBhbiBleGNlcHRpb24gd2lsbCBjb21lIHVwIG91dCBvZiB0aGUgYWRkRmFtaWx5CisgICAgICAgIGFyZyA8PCAnOicKKyAgICAgIGVuZAorICAgICAgYXJnCisgICAgZW5kCisKKyAgICBkZWYgc2h1dGRvd24oKQorICAgICAgQGFkbWluLnNodXRkb3duKCkKKyAgICBlbmQKKworICAgIGRlZiBoY2QoYXJnKQorICAgICAgIyBSZXR1cm4gYSBuZXcgSENvbHVtbkRlc2NyaXB0b3IgbWFkZSBvZiBwYXNzZWQgYXJncworICAgICAgIyBUT0RPOiBUaGlzIGlzIGJyaXR0bGUgY29kZS4KKyAgICAgICMgSGVyZSBpcyBjdXJyZW50IEhDRCBjb25zdHJ1Y3RvcjoKKyAgICAgICMgcHVibGljIEhDb2x1bW5EZXNjcmlwdG9yKGZpbmFsIGJ5dGUgW10gZmFtaWx5TmFtZSwgZmluYWwgaW50IG1heFZlcnNpb25zLAorICAgICAgIyBmaW5hbCBTdHJpbmcgY29tcHJlc3Npb24sIGZpbmFsIGJvb2xlYW4gaW5NZW1vcnksCisgICAgICAjIGZpbmFsIGJvb2xlYW4gYmxvY2tDYWNoZUVuYWJsZWQsIGZpbmFsIGludCBibG9ja3NpemUsCisgICAgICAjIGZpbmFsIGludCBtYXhWYWx1ZUxlbmd0aCwKKyAgICAgICMgZmluYWwgaW50IHRpbWVUb0xpdmUsIGZpbmFsIGJvb2xlYW4gYmxvb21GaWx0ZXIpIHsKKyAgICAgIG5hbWUgPSBhcmdbTkFNRV0KKyAgICAgIHJhaXNlIEFyZ3VtZW50RXJyb3IubmV3KCJDb2x1bW4gZmFtaWx5ICIgKyBhcmcgKyAiIG11c3QgaGF2ZSBhIG5hbWUiKSBcCisgICAgICAgIHVubGVzcyBuYW1lCisgICAgICBuYW1lID0gbWFrZUNvbHVtbk5hbWUobmFtZSkKKyAgICAgICMgVE9ETzogV2hhdCBlbmNvZGluZyBhcmUgU3RyaW5ncyBpbiBqcnVieT8KKyAgICAgIHJldHVybiBIQ29sdW1uRGVzY3JpcHRvci5uZXcobmFtZS50b19qYXZhX2J5dGVzLAorICAgICAgICAjIEpSdWJ5IHVzZXMgbG9uZ3MgZm9yIGludHMuIE5lZWQgdG8gY29udmVydC4gIEFsc28gY29uc3RhbnRzIGFyZSBTdHJpbmcgCisgICAgICAgIGFyZ1tWRVJTSU9OU10/IEpJbnRlZ2VyLm5ldyhhcmdbVkVSU0lPTlNdKTogSENvbHVtbkRlc2NyaXB0b3I6OkRFRkFVTFRfVkVSU0lPTlMsCisgICAgICAgIGFyZ1tIQ29sdW1uRGVzY3JpcHRvcjo6Q09NUFJFU1NJT05dPyBhcmdbSENvbHVtbkRlc2NyaXB0b3I6OkNPTVBSRVNTSU9OXTogSENvbHVtbkRlc2NyaXB0b3I6OkRFRkFVTFRfQ09NUFJFU1NJT04sCisgICAgICAgIGFyZ1tJTl9NRU1PUlldPyBKQm9vbGVhbi52YWx1ZU9mKGFyZ1tJTl9NRU1PUlldKTogSENvbHVtbkRlc2NyaXB0b3I6OkRFRkFVTFRfSU5fTUVNT1JZLAorICAgICAgICBhcmdbSENvbHVtbkRlc2NyaXB0b3I6OkJMT0NLQ0FDSEVdPyBKQm9vbGVhbi52YWx1ZU9mKGFyZ1tIQ29sdW1uRGVzY3JpcHRvcjo6QkxPQ0tDQUNIRV0pOiBIQ29sdW1uRGVzY3JpcHRvcjo6REVGQVVMVF9CTE9DS0NBQ0hFLAorICAgICAgICBhcmdbSENvbHVtbkRlc2NyaXB0b3I6OkJMT0NLU0laRV0/IEpJbnRlZ2VyLnZhbHVlT2YoYXJnW0hDb2x1bW5EZXNjcmlwdG9yOjpCTE9DS1NJWkVdKTogSENvbHVtbkRlc2NyaXB0b3I6OkRFRkFVTFRfQkxPQ0tTSVpFLAorICAgICAgICBhcmdbSENvbHVtbkRlc2NyaXB0b3I6OkxFTkdUSF0/IEpJbnRlZ2VyLm5ldyhhcmdbSENvbHVtbkRlc2NyaXB0b3I6OkxFTkdUSF0pOiBIQ29sdW1uRGVzY3JpcHRvcjo6REVGQVVMVF9MRU5HVEgsCisgICAgICAgIGFyZ1tIQ29sdW1uRGVzY3JpcHRvcjo6VFRMXT8gSkludGVnZXIubmV3KGFyZ1tIQ29sdW1uRGVzY3JpcHRvcjo6VFRMXSk6IEhDb2x1bW5EZXNjcmlwdG9yOjpERUZBVUxUX1RUTCwKKyAgICAgICAgYXJnW0hDb2x1bW5EZXNjcmlwdG9yOjpCTE9PTUZJTFRFUl0/IEpCb29sZWFuLnZhbHVlT2YoYXJnW0hDb2x1bW5EZXNjcmlwdG9yOjpCTE9PTUZJTFRFUl0pOiBIQ29sdW1uRGVzY3JpcHRvcjo6REVGQVVMVF9CTE9PTUZJTFRFUikKKyAgICBlbmQKKyAgZW5kCisKKyAgIyBXcmFwcGVyIGZvciBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlCisgIGNsYXNzIFRhYmxlCisgICAgZGVmIGluaXRpYWxpemUoY29uZmlndXJhdGlvbiwgdGFibGVOYW1lLCBmb3JtYXR0ZXIpCisgICAgICBAdGFibGUgPSBIVGFibGUubmV3KGNvbmZpZ3VyYXRpb24sIHRhYmxlTmFtZSkKKyAgICAgIEBmb3JtYXR0ZXIgPSBmb3JtYXR0ZXIKKyAgICBlbmQKKworICAgICMgRGVsZXRlIGEgY2VsbAorICAgIGRlZiBkZWxldGUocm93LCBjb2x1bW4sIHRpbWVzdGFtcCA9IEhDb25zdGFudHM6OkxBVEVTVF9USU1FU1RBTVApCisgICAgICBub3cgPSBUaW1lLm5vdyAKKyAgICAgIGJ1ID0gQmF0Y2hVcGRhdGUubmV3KHJvdywgdGltZXN0YW1wKQorICAgICAgYnUuZGVsZXRlKGNvbHVtbikKKyAgICAgIEB0YWJsZS5jb21taXQoYnUpCisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgZGVsZXRlYWxsKHJvdywgY29sdW1uID0gbmlsLCB0aW1lc3RhbXAgPSBIQ29uc3RhbnRzOjpMQVRFU1RfVElNRVNUQU1QKQorICAgICAgbm93ID0gVGltZS5ub3cgCisgICAgICBAdGFibGUuZGVsZXRlQWxsKHJvdywgY29sdW1uLCB0aW1lc3RhbXApCisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisKKyAgICBkZWYgZ2V0QWxsQ29sdW1ucworICAgICAgIGh0ZCA9IEB0YWJsZS5nZXRUYWJsZURlc2NyaXB0b3IoKQorICAgICAgIHJlc3VsdCA9IFtdCisgICAgICAgZm9yIGYgaW4gaHRkLmdldEZhbWlsaWVzKCkKKyAgICAgICAgIG4gPSBmLmdldE5hbWVBc1N0cmluZygpCisgICAgICAgICBuIDw8ICc6JworICAgICAgICAgcmVzdWx0IDw8IG4KKyAgICAgICBlbmQKKyAgICAgICByZXN1bHQKKyAgICBlbmQKKworICAgIGRlZiBzY2FuKGFyZ3MgPSB7fSkKKyAgICAgIG5vdyA9IFRpbWUubm93IAorICAgICAgbGltaXQgPSAtMQorICAgICAgbWF4bGVuZ3RoID0gLTEKKyAgICAgIGlmIGFyZ3MgIT0gbmlsIGFuZCBhcmdzLmxlbmd0aCA+IDAKKyAgICAgICAgbGltaXQgPSBhcmdzWyJMSU1JVCJdIHx8IC0xIAorICAgICAgICBtYXhsZW5ndGggPSBhcmdzWyJNQVhMRU5HVEgiXSB8fCAtMSAKKyAgICAgICAgZmlsdGVyID0gYXJnc1siRklMVEVSIl0gfHwgbmlsCisgICAgICAgIHN0YXJ0cm93ID0gYXJnc1siU1RBUlRST1ciXSB8fCAiIgorICAgICAgICBzdG9wcm93ID0gYXJnc1siU1RPUFJPVyJdIHx8IG5pbAorICAgICAgICB0aW1lc3RhbXAgPSBhcmdzWyJUSU1FU1RBTVAiXSB8fCBIQ29uc3RhbnRzOjpMQVRFU1RfVElNRVNUQU1QCisgICAgICAgIGNvbHVtbnMgPSBhcmdzWyJDT0xVTU5TIl0gfHwgZ2V0QWxsQ29sdW1ucygpCisgICAgICAgIAorICAgICAgICBpZiBjb2x1bW5zLmNsYXNzID09IFN0cmluZworICAgICAgICAgIGNvbHVtbnMgPSBbY29sdW1uc10KKyAgICAgICAgZWxzaWYgY29sdW1ucy5jbGFzcyAhPSBBcnJheQorICAgICAgICAgIHJhaXNlIEFyZ3VtZW50RXJyb3IubmV3KCJDT0xVTU5TIG11c3QgYmUgc3BlY2lmaWVkIGFzIGEgU3RyaW5nIG9yIGFuIEFycmF5IikKKyAgICAgICAgZW5kCisgICAgICAgIGNzID0gY29sdW1ucy50b19qYXZhKGphdmEubGFuZy5TdHJpbmcpCisgICAgICAgIAorICAgICAgICBpZiBzdG9wcm93CisgICAgICAgICAgcyA9IEB0YWJsZS5nZXRTY2FubmVyKGNzLCBzdGFydHJvdywgc3RvcHJvdywgdGltZXN0YW1wKQorICAgICAgICBlbHNlCisgICAgICAgICAgcyA9IEB0YWJsZS5nZXRTY2FubmVyKGNzLCBzdGFydHJvdywgdGltZXN0YW1wLCBmaWx0ZXIpIAorICAgICAgICBlbmQKKyAgICAgIGVsc2UKKyAgICAgICAgY29sdW1ucyA9IGdldEFsbENvbHVtbnMoKQorICAgICAgICBzID0gQHRhYmxlLmdldFNjYW5uZXIoY29sdW1ucy50b19qYXZhKGphdmEubGFuZy5TdHJpbmcpKQorICAgICAgZW5kCisgICAgICBjb3VudCA9IDAKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKFsiUk9XIiwgIkNPTFVNTitDRUxMIl0pCisgICAgICBpID0gcy5pdGVyYXRvcigpCisgICAgICB3aGlsZSBpLmhhc05leHQoKQorICAgICAgICByID0gaS5uZXh0KCkKKyAgICAgICAgcm93ID0gU3RyaW5nLmZyb21famF2YV9ieXRlcyByLmdldFJvdygpCisgICAgICAgIGZvciBrLCB2IGluIHIKKyAgICAgICAgICBjb2x1bW4gPSBTdHJpbmcuZnJvbV9qYXZhX2J5dGVzIGsKKyAgICAgICAgICBjZWxsID0gdG9TdHJpbmcoY29sdW1uLCB2LCBtYXhsZW5ndGgpCisgICAgICAgICAgQGZvcm1hdHRlci5yb3coW3JvdywgImNvbHVtbj0lcywgJXMiICUgW2NvbHVtbiwgY2VsbF1dKQorICAgICAgICBlbmQKKyAgICAgICAgY291bnQgKz0gMQorICAgICAgICBpZiBsaW1pdCAhPSAtMSBhbmQgY291bnQgPj0gbGltaXQKKyAgICAgICAgICBicmVhaworICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93KQorICAgIGVuZAorCisgICAgZGVmIHB1dChyb3csIGNvbHVtbiwgdmFsdWUsIHRpbWVzdGFtcCA9IG5pbCkKKyAgICAgIG5vdyA9IFRpbWUubm93IAorICAgICAgYnUgPSBuaWwKKyAgICAgIGlmIHRpbWVzdGFtcAorICAgICAgICBidSA9IEJhdGNoVXBkYXRlLm5ldyhyb3csIHRpbWVzdGFtcCkKKyAgICAgIGVsc2UKKyAgICAgICAgYnUgPSBCYXRjaFVwZGF0ZS5uZXcocm93KQorICAgICAgZW5kCisgICAgICBidS5wdXQoY29sdW1uLCB2YWx1ZS50b19qYXZhX2J5dGVzKQorICAgICAgQHRhYmxlLmNvbW1pdChidSkKKyAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgIEBmb3JtYXR0ZXIuZm9vdGVyKG5vdykKKyAgICBlbmQKKworICAgIGRlZiBpc01ldGFUYWJsZSgpCisgICAgICB0biA9IEB0YWJsZS5nZXRUYWJsZU5hbWUoKQorICAgICAgcmV0dXJuIEJ5dGVzLmVxdWFscyh0biwgSENvbnN0YW50czo6TUVUQV9UQUJMRV9OQU1FKSB8fAorICAgICAgICBCeXRlcy5lcXVhbHModG4sIEhDb25zdGFudHM6OlJPT1RfVEFCTEVfTkFNRSkKKyAgICBlbmQKKworICAgICMgTWFrZSBhIFN0cmluZyBvZiB0aGUgcGFzc2VkIGNlbGwuCisgICAgIyBJbnRlcmNlcHQgY2VsbHMgd2hvc2UgZm9ybWF0IHdlIGtub3cgc3VjaCBhcyB0aGUgaW5mbzpyZWdpb25pbmZvIGluIC5NRVRBLgorICAgIGRlZiB0b1N0cmluZyhjb2x1bW4sIGNlbGwsIG1heGxlbmd0aCkKKyAgICAgIGlmIGlzTWV0YVRhYmxlKCkKKyAgICAgICAgaWYgY29sdW1uID09ICdpbmZvOnJlZ2lvbmluZm8nCisgICAgICAgICAgaHJpID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvT3JOdWxsKGNlbGwuZ2V0VmFsdWUoKSkKKyAgICAgICAgICByZXR1cm4gInRpbWVzdGFtcD0lZCwgdmFsdWU9JXMiICUgW2NlbGwuZ2V0VGltZXN0YW1wKCksIGhyaS50b1N0cmluZygpXQorICAgICAgICBlbHNpZiBjb2x1bW4gPT0gJ2luZm86c2VydmVyc3RhcnRjb2RlJworICAgICAgICAgIHJldHVybiAidGltZXN0YW1wPSVkLCB2YWx1ZT0lcyIgJSBbY2VsbC5nZXRUaW1lc3RhbXAoKSwgXAorICAgICAgICAgICAgQnl0ZXMudG9Mb25nKGNlbGwuZ2V0VmFsdWUoKSldCisgICAgICAgIGVuZAorICAgICAgZW5kCisgICAgICBjZWxsLnRvU3RyaW5nKCkKKyAgICAgIHZhbCA9IGNlbGwudG9TdHJpbmcoKQorICAgICAgbWF4bGVuZ3RoICE9IC0xID8gdmFsWzAsIG1heGxlbmd0aF0gOiB2YWwgICAgCisgICAgZW5kCisgIAorICAgICMgR2V0IGZyb20gdGFibGUKKyAgICBkZWYgZ2V0KHJvdywgYXJncyA9IHt9KQorICAgICAgbm93ID0gVGltZS5ub3cgCisgICAgICByZXN1bHQgPSBuaWwKKyAgICAgIGlmIGFyZ3MgPT0gbmlsIG9yIGFyZ3MubGVuZ3RoID09IDAgb3IgKGFyZ3MubGVuZ3RoID09IDEgYW5kIGFyZ3NbTUFYTEVOR1RIXSAhPSBuaWwpCisgICAgICAgIHJlc3VsdCA9IEB0YWJsZS5nZXRSb3cocm93LnRvX2phdmFfYnl0ZXMpCisgICAgICBlbHNlCisgICAgICAgICMgSXRzIGEgaGFzaC4KKyAgICAgICAgY29sdW1ucyA9IGFyZ3NbQ09MVU1OXSAKKyAgICAgICAgaWYgY29sdW1ucyA9PSBuaWwKKyAgICAgICAgICAjIE1heWJlIHRoZXkgdXNlZCB0aGUgQ09MVU1OUyBrZXkKKyAgICAgICAgICBjb2x1bW5zID0gYXJnc1tDT0xVTU5TXQorICAgICAgICBlbmQKKyAgICAgICAgaWYgY29sdW1ucyA9PSBuaWwKKyAgICAgICAgICAjIE1heSBoYXZlIHBhc3NlZCBUSU1FU1RBTVAgYW5kIHJvdyBvbmx5OyB3YW50cyBhbGwgY29sdW1ucyBmcm9tIHRzLgorICAgICAgICAgIHRzID0gYXJnc1tUSU1FU1RBTVBdIAorICAgICAgICAgIGlmIG5vdCB0cworICAgICAgICAgICAgcmFpc2UgQXJndW1lbnRFcnJvci5uZXcoIkZhaWxlZCBwYXJzZSBvZiAiICsgYXJncyArICIsICIgKyBhcmdzLmNsYXNzKQorICAgICAgICAgIGVuZAorICAgICAgICAgIHJlc3VsdCA9IEB0YWJsZS5nZXRSb3cocm93LnRvX2phdmFfYnl0ZXMsIHRzKQorICAgICAgICBlbHNlCisgICAgICAgICAgIyBDb2x1bW5zIGFyZSBub24tbmlsCisgICAgICAgICAgaWYgY29sdW1ucy5jbGFzcyA9PSBTdHJpbmcKKyAgICAgICAgICAgICMgU2luZ2xlIGNvbHVtbgorICAgICAgICAgICAgcmVzdWx0ID0gQHRhYmxlLmdldChyb3csIGNvbHVtbnMsCisgICAgICAgICAgICAgIGFyZ3NbVElNRVNUQU1QXT8gYXJnc1tUSU1FU1RBTVBdOiBIQ29uc3RhbnRzOjpMQVRFU1RfVElNRVNUQU1QLAorICAgICAgICAgICAgICBhcmdzW1ZFUlNJT05TXT8gYXJnc1tWRVJTSU9OU106IDEpCisgICAgICAgICAgZWxzaWYgY29sdW1ucy5jbGFzcyA9PSBBcnJheQorICAgICAgICAgICAgcmVzdWx0ID0gQHRhYmxlLmdldFJvdyhyb3csIGNvbHVtbnMudG9famF2YSg6c3RyaW5nKSwKKyAgICAgICAgICAgICAgYXJnc1tUSU1FU1RBTVBdPyBhcmdzW1RJTUVTVEFNUF06IEhDb25zdGFudHM6OkxBVEVTVF9USU1FU1RBTVApCisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgcmFpc2UgQXJndW1lbnRFcnJvci5uZXcoIkZhaWxlZCBwYXJzZSBjb2x1bW4gYXJndW1lbnQgdHlwZSAiICsKKyAgICAgICAgICAgICAgYXJncyArICIsICIgKyBhcmdzLmNsYXNzKQorICAgICAgICAgIGVuZAorICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgICAgIyBQcmludCBvdXQgcmVzdWx0cy4gIFJlc3VsdCBjYW4gYmUgQ2VsbCBvciBSb3dSZXN1bHQuCisgICAgICBtYXhsZW5ndGggPSBhcmdzW01BWExFTkdUSF0gfHwgLTEKKyAgICAgIGggPSBuaWwKKyAgICAgIGlmIHJlc3VsdC5pbnN0YW5jZV9vZj8gUm93UmVzdWx0CisgICAgICAgIGggPSBTdHJpbmcuZnJvbV9qYXZhX2J5dGVzIHJlc3VsdC5nZXRSb3coKQorICAgICAgICBAZm9ybWF0dGVyLmhlYWRlcihbIkNPTFVNTiIsICJDRUxMIl0pCisgICAgICAgIGlmIHJlc3VsdAorICAgICAgICAgIGZvciBrLCB2IGluIHJlc3VsdAorICAgICAgICAgICAgY29sdW1uID0gU3RyaW5nLmZyb21famF2YV9ieXRlcyBrCisgICAgICAgICAgICBAZm9ybWF0dGVyLnJvdyhbY29sdW1uLCB0b1N0cmluZyhjb2x1bW4sIHYsIG1heGxlbmd0aCldKQorICAgICAgICAgIGVuZAorICAgICAgICBlbmQKKyAgICAgIGVsc2UKKyAgICAgICAgIyBQcmVzdW1lIENlbGxzCisgICAgICAgIEBmb3JtYXR0ZXIuaGVhZGVyKCkKKyAgICAgICAgaWYgcmVzdWx0IAorICAgICAgICAgIGZvciBjIGluIHJlc3VsdAorICAgICAgICAgICAgQGZvcm1hdHRlci5yb3coW3RvU3RyaW5nKG5pbCwgYywgbWF4bGVuZ3RoKV0pCisgICAgICAgICAgZW5kCisgICAgICAgIGVuZAorICAgICAgZW5kCisgICAgICBAZm9ybWF0dGVyLmZvb3Rlcihub3cpCisgICAgZW5kCisgICAgCisgICAgZGVmIGNvdW50KGludGVydmFsID0gMTAwMCkKKyAgICAgIG5vdyA9IFRpbWUubm93CisgICAgICBjb2x1bW5zID0gZ2V0QWxsQ29sdW1ucygpCisgICAgICBjcyA9IGNvbHVtbnMudG9famF2YShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAgcyA9IEB0YWJsZS5nZXRTY2FubmVyKGNzKQorICAgICAgY291bnQgPSAwCisgICAgICBpID0gcy5pdGVyYXRvcigpCisgICAgICBAZm9ybWF0dGVyLmhlYWRlcigpCisgICAgICB3aGlsZSBpLmhhc05leHQoKQorICAgICAgICByID0gaS5uZXh0KCkKKyAgICAgICAgY291bnQgKz0gMQorICAgICAgICBpZiBjb3VudCAlIGludGVydmFsID09IDAKKyAgICAgICAgICBAZm9ybWF0dGVyLnJvdyhbIkN1cnJlbnQgY291bnQ6ICIgKyBjb3VudC50b19zICsgIiwgcm93OiAiICsgXAorICAgICAgICAgICAgKFN0cmluZy5mcm9tX2phdmFfYnl0ZXMgci5nZXRSb3coKSldKQorICAgICAgICBlbmQKKyAgICAgIGVuZAorICAgICAgQGZvcm1hdHRlci5mb290ZXIobm93LCBjb3VudCkKKyAgICBlbmQKKyAgICAKKyAgZW5kCisKKyAgIyBUZXN0aW5nLiBUbyBydW4gdGhpcyB0ZXN0LCB0aGVyZSBuZWVkcyB0byBiZSBhbiBoYmFzZSBjbHVzdGVyIHVwIGFuZAorICAjIHJ1bm5pbmcuICBUaGVuIGRvOiAke0hCQVNFX0hPTUV9L2Jpbi9oYmFzZSBvcmcuanJ1YnkuTWFpbiBiaW4vSEJhc2UucmIKKyAgaWYgJDAgPT0gX19GSUxFX18KKyAgICAjIEFkZCB0aGlzIGRpcmVjdG9yeSB0byBMT0FEX1BBVEg7IHByZXN1bXB0aW9uIGlzIHRoYXQgRm9ybWF0dGVyIG1vZHVsZQorICAgICMgc2l0cyBiZXNpZGUgdGhpcyBvbmUuICBUaGVuIGxvYWQgaXQgdXAuCisgICAgJExPQURfUEFUSC51bnNoaWZ0IEZpbGUuZGlybmFtZSgkUFJPR1JBTV9OQU1FKQorICAgIHJlcXVpcmUgJ0Zvcm1hdHRlcicKKyAgICAjIE1ha2UgYSBjb25zb2xlIGZvcm1hdHRlcgorICAgIGZvcm1hdHRlciA9IEZvcm1hdHRlcjo6Q29uc29sZS5uZXcoU1RET1VUKQorICAgICMgTm93IGFkZCBpbiBqYXZhIGFuZCBoYmFzZSBjbGFzc2VzCisgICAgY29uZmlndXJhdGlvbiA9IEhCYXNlQ29uZmlndXJhdGlvbi5uZXcoKQorICAgIGFkbWluID0gQWRtaW4ubmV3KGNvbmZpZ3VyYXRpb24sIGZvcm1hdHRlcikKKyAgICAjIERyb3Agb2xkIHRhYmxlLiAgSWYgaXQgZG9lcyBub3QgZXhpc3QsIGdldCBhbiBleGNlcHRpb24uICBDYXRjaCBhbmQKKyAgICAjIGNvbnRpbnVlCisgICAgVEVTVFRBQkxFID0gIkhCYXNlX3JiX3Rlc3R0YWJsZSIKKyAgICBiZWdpbgorICAgICAgYWRtaW4uZGlzYWJsZShURVNUVEFCTEUpCisgICAgICBhZG1pbi5kcm9wKFRFU1RUQUJMRSkKKyAgICByZXNjdWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVGFibGVOb3RGb3VuZEV4Y2VwdGlvbgorICAgICAgIyBKdXN0IHN1cHByZXNzIG5vdCBmb3VuZCBleGNlcHRpb24KKyAgICBlbmQKKyAgICBhZG1pbi5jcmVhdGUoVEVTVFRBQkxFLCBbe05BTUUgPT4gJ3gnLCBWRVJTSU9OUyA9PiA1fV0pCisgICAgIyBQcmVzdW1lIGl0IGV4aXN0cy4gIElmIGl0IGRvZXNuJ3QsIG5leHQgaXRlbXMgd2lsbCBmYWlsLgorICAgIHRhYmxlID0gVGFibGUubmV3KGNvbmZpZ3VyYXRpb24sIFRFU1RUQUJMRSwgZm9ybWF0dGVyKSAKKyAgICBmb3IgaSBpbiAxLi4xMAorICAgICAgdGFibGUucHV0KCd4JWQnICUgaSwgJ3g6JWQnICUgaSwgJ3glZCcgJSBpKQorICAgIGVuZAorICAgIHRhYmxlLmdldCgneDEnLCB7Q09MVU1OID0+ICd4OjEnfSkKKyAgICBpZiBmb3JtYXR0ZXIucm93Q291bnQoKSAhPSAxCisgICAgICByYWlzZSBJT0Vycm9yLm5ldygiRmFpbGVkIGZpcnN0IHB1dCIpCisgICAgZW5kCisgICAgdGFibGUuc2NhbihbJ3g6J10pCisgICAgaWYgZm9ybWF0dGVyLnJvd0NvdW50KCkgIT0gMTAKKyAgICAgIHJhaXNlIElPRXJyb3IubmV3KCJGYWlsZWQgc2NhbiBvZiBleHBlY3RlZCAxMCByb3dzIikKKyAgICBlbmQKKyAgICAjIFZlcmlmeSB0aGF0IGxpbWl0IHdvcmtzLgorICAgIHRhYmxlLnNjYW4oWyd4OiddLCB7TElNSVQgPT4gM30pCisgICAgaWYgZm9ybWF0dGVyLnJvd0NvdW50KCkgIT0gMworICAgICAgcmFpc2UgSU9FcnJvci5uZXcoIkZhaWxlZCBzY2FuIG9mIGV4cGVjdGVkIDMgcm93cyIpCisgICAgZW5kCisgICAgIyBTaG91bGQgb25seSBiZSB0d28gcm93cyBpZiB3ZSBzdGFydCBhdCA4IChSb3cgeDEwIHNvcnRzIGJlc2lkZSB4MSkuCisgICAgdGFibGUuc2NhbihbJ3g6J10sIHtTVEFSVFJPVyA9PiAneDgnLCBMSU1JVCA9PiAzfSkKKyAgICBpZiBmb3JtYXR0ZXIucm93Q291bnQoKSAhPSAyCisgICAgICByYWlzZSBJT0Vycm9yLm5ldygiRmFpbGVkIHNjYW4gb2YgZXhwZWN0ZWQgMiByb3dzIikKKyAgICBlbmQKKyAgICAjIFNjYW4gYmV0d2VlbiB0d28gcm93cworICAgIHRhYmxlLnNjYW4oWyd4OiddLCB7U1RBUlRST1cgPT4gJ3g1JywgRU5EUk9XID0+ICd4OCd9KQorICAgIGlmIGZvcm1hdHRlci5yb3dDb3VudCgpICE9IDMKKyAgICAgIHJhaXNlIElPRXJyb3IubmV3KCJGYWlsZWQgZW5kcm93IHRlc3QiKQorICAgIGVuZAorICAgICMgVmVyaWZ5IHRoYXQgZGVsZXRlIHdvcmtzCisgICAgdGFibGUuZGVsZXRlKCd4MScsICd4OjEnKTsKKyAgICB0YWJsZS5zY2FuKFsneDoxJ10pCisgICAgc2NhbjEgPSBmb3JtYXR0ZXIucm93Q291bnQoKQorICAgIHRhYmxlLnNjYW4oWyd4OiddKQorICAgIHNjYW4yID0gZm9ybWF0dGVyLnJvd0NvdW50KCkKKyAgICBpZiBzY2FuMSAhPSAwIG9yIHNjYW4yICE9IDkKKyAgICAgIHJhaXNlIElPRXJyb3IubmV3KCJGYWlsZWQgZGVsZXRlIHRlc3QiKQorICAgIGVuZAorICAgICMgVmVyaWZ5IHRoYXQgZGVsZXRhbGwgd29ya3MKKyAgICB0YWJsZS5wdXQoJ3gyJywgJ3g6MScsICd4OjEnKQorICAgIHRhYmxlLmRlbGV0ZWFsbCgneDInKQorICAgIHRhYmxlLnNjYW4oWyd4OjInXSkKKyAgICBzY2FuMSA9IGZvcm1hdHRlci5yb3dDb3VudCgpCisgICAgdGFibGUuc2NhbihbJ3g6J10pCisgICAgc2NhbjIgPSBmb3JtYXR0ZXIucm93Q291bnQoKQorICAgIGlmIHNjYW4xICE9IDAgb3Igc2NhbjIgIT0gOAorICAgICAgcmFpc2UgSU9FcnJvci5uZXcoIkZhaWxlZCBkZWxldGVhbGwgdGVzdCIpCisgICAgZW5kCisgICAgYWRtaW4uZGlzYWJsZShURVNUVEFCTEUpCisgICAgYWRtaW4uZHJvcChURVNUVEFCTEUpCisgIGVuZAorZW5kCmRpZmYgLS1naXQgYS9iaW4vY29weV90YWJsZS5yYiBiL2Jpbi9jb3B5X3RhYmxlLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliYmM0NTIKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vY29weV90YWJsZS5yYgpAQCAtMCwwICsxLDE0OSBAQAorIyBTY3JpcHQgdGhhdCBjb3BpZXMgdGFibGUgaW4gaGJhc2UuICBBcyB3cml0dGVuLCB3aWxsIG5vdCB3b3JrIGZvciByYXJlCisjIGNhc2Ugd2hlcmUgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSByZWdpb24gaW4gLk1FVEEuIHRhYmxlLiAgRG9lcyB0aGUKKyMgdXBkYXRlIG9mIHRoZSBoYmFzZSAuTUVUQS4gYW5kIGNvcGllcyB0aGUgZGlyZWN0b3JpZXMgaW4gZmlsZXN5c3RlbS4gIAorIyBIQmFzZSBNVVNUIGJlIHNodXRkb3duIHdoZW4geW91IHJ1biB0aGlzIHNjcmlwdC4KKyMKKyMgVG8gc2VlIHVzYWdlIGZvciB0aGlzIHNjcmlwdCwgcnVuOiAKKyMKKyMgICR7SEJBU0VfSE9NRX0vYmluL2hiYXNlIG9yZy5qcnVieS5NYWluIHJlbmFtZV90YWJsZS5yYgorIworaW5jbHVkZSBKYXZhCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5NZXRhVXRpbHMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkZTVXRpbHMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFN0b3JlS2V5CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm8KK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZQoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5ITG9nRWRpdAoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aAoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW0KK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlVXRpbAoraW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3RvcnkKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcAorCisjIE5hbWUgb2YgdGhpcyBzY3JpcHQKK05BTUUgPSAiY29weV90YWJsZSIKKworIyBQcmludCB1c2FnZSBmb3IgdGhpcyBzY3JpcHQKK2RlZiB1c2FnZQorICBwdXRzICdVc2FnZTogJXMucmIgPE9MRF9OQU1FPiA8TkVXX05BTUU+JyAlIE5BTUUKKyAgZXhpdCEKK2VuZAorCisjIFBhc3NlZCAnZGlyJyBleGlzdHMgYW5kIGlzIGEgZGlyZWN0b3J5IGVsc2UgZXhjZXB0aW9uCitkZWYgaXNEaXJFeGlzdHMoZnMsIGRpcikKKyAgcmFpc2UgSU9FcnJvci5uZXcoIkRvZXMgbm90IGV4aXQ6ICIgKyBkaXIudG9TdHJpbmcoKSkgdW5sZXNzIGZzLmV4aXN0cyhkaXIpCisgIHJhaXNlIElPRXJyb3IubmV3KCJOb3QgYSBkaXJlY3Rvcnk6ICIgKyBkaXIudG9TdHJpbmcoKSkgdW5sZXNzIGZzLmlzRGlyZWN0b3J5KGRpcikKK2VuZAorCisjIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVnaW9uIGJlbG9uZ3MgdG8gcGFzc2VkIHRhYmxlCitkZWYgaXNUYWJsZVJlZ2lvbih0YWJsZU5hbWUsIGhyaSkKKyAgcmV0dXJuIEJ5dGVzLmVxdWFscyhocmkuZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLCB0YWJsZU5hbWUpCitlbmQKKworIyBDcmVhdGUgbmV3IEhSSSBiYXNlZCBvZmYgcGFzc2VkICdvbGRIUkknCitkZWYgY3JlYXRlSFJJKHRhYmxlTmFtZSwgb2xkSFJJKQorICBodGQgPSBvbGRIUkkuZ2V0VGFibGVEZXNjKCkKKyAgbmV3SHRkID0gSFRhYmxlRGVzY3JpcHRvci5uZXcodGFibGVOYW1lKQorICBmb3IgZmFtaWx5IGluIGh0ZC5nZXRGYW1pbGllcygpCisgICAgbmV3SHRkLmFkZEZhbWlseShmYW1pbHkpCisgIGVuZAorICByZXR1cm4gSFJlZ2lvbkluZm8ubmV3KG5ld0h0ZCwgb2xkSFJJLmdldFN0YXJ0S2V5KCksIG9sZEhSSS5nZXRFbmRLZXkoKSwKKyAgICBvbGRIUkkuaXNTcGxpdCgpKQorZW5kCisKKyMgQ2hlY2sgYXJndW1lbnRzCitpZiBBUkdWLnNpemUgIT0gMgorICB1c2FnZQorZW5kCisKKyMgQ2hlY2sgZ29vZCB0YWJsZSBuYW1lcyB3ZXJlIHBhc3NlZC4KK29sZFRhYmxlTmFtZSA9IEhUYWJsZURlc2NyaXB0b3IuaXNMZWdhbFRhYmxlTmFtZShBUkdWWzBdLnRvX2phdmFfYnl0ZXMpCituZXdUYWJsZU5hbWUgPSBIVGFibGVEZXNjcmlwdG9yLmlzTGVnYWxUYWJsZU5hbWUoQVJHVlsxXS50b19qYXZhX2J5dGVzKQorCisjIEdldCBjb25maWd1cmF0aW9uIHRvIHVzZS4KK2MgPSBIQmFzZUNvbmZpZ3VyYXRpb24ubmV3KCkKKworIyBTZXQgaGFkb29wIGZpbGVzeXN0ZW0gY29uZmlndXJhdGlvbiB1c2luZyB0aGUgaGJhc2Uucm9vdGRpci4KKyMgT3RoZXJ3aXNlLCB3ZSdsbCBhbHdheXMgdXNlIGxvY2FsaG9zdCB0aG91Z2ggdGhlIGhiYXNlLnJvb3RkaXIKKyMgbWlnaHQgYmUgcG9pbnRpbmcgYXQgaGRmcyBsb2NhdGlvbi4KK2Muc2V0KCJmcy5kZWZhdWx0Lm5hbWUiLCBjLmdldChIQ29uc3RhbnRzOjpIQkFTRV9ESVIpKQorZnMgPSBGaWxlU3lzdGVtLmdldChjKQorCisjIElmIG5ldyB0YWJsZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpdCwgY3JlYXRlIGl0LiAgS2VlcCBnb2luZyBpZiBhbHJlYWR5CisjIGV4aXN0cyBiZWNhdXNlIG1heWJlIHdlIGFyZSByZXJ1bm5pbmcgc2NyaXB0IGJlY2F1c2UgaXQgZmFpbGVkIGZpcnN0CisjIHRpbWUuCityb290ZGlyID0gRlNVdGlscy5nZXRSb290RGlyKGMpCitvbGRUYWJsZURpciA9IFBhdGgubmV3KHJvb3RkaXIsIFBhdGgubmV3KEJ5dGVzLnRvU3RyaW5nKG9sZFRhYmxlTmFtZSkpKQoraXNEaXJFeGlzdHMoZnMsIG9sZFRhYmxlRGlyKQorbmV3VGFibGVEaXIgPSBQYXRoLm5ldyhyb290ZGlyLCBCeXRlcy50b1N0cmluZyhuZXdUYWJsZU5hbWUpKQoraWYgIWZzLmV4aXN0cyhuZXdUYWJsZURpcikKKyAgZnMubWtkaXJzKG5ld1RhYmxlRGlyKQorZW5kCisKKyMgR2V0IGEgbG9nZ2VyIGFuZCBhIG1ldGF1dGlscyBpbnN0YW5jZS4KK0xPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKE5BTUUpCit1dGlscyA9IE1ldGFVdGlscy5uZXcoYykKKworIyBTdGFydC4gIEdldCBhbGwgbWV0YSByb3dzLgorYmVnaW4KKyAgIyBHZXQgbGlzdCBvZiBhbGwgLk1FVEEuIHJlZ2lvbnMgdGhhdCBjb250YWluIG9sZCB0YWJsZSBuYW1lCisgIG1ldGFzID0gdXRpbHMuZ2V0TUVUQVJvd3Mob2xkVGFibGVOYW1lKQorICBpbmRleCA9IDAKKyAgZm9yIG1ldGEgaW4gbWV0YXMKKyAgICAjIEZvciBlYWNoIHJvdyB3ZSBmaW5kLCBtb3ZlIGl0cyByZWdpb24gZnJvbSBvbGQgdG8gbmV3IHRhYmxlLgorICAgICMgTmVlZCB0byB1cGRhdGUgdGhlIGVuY29kZWQgbmFtZSBpbiB0aGUgaHJpIGFzIHdlIG1vdmUuCisgICAgIyBBZnRlciBtb3ZlLCBkZWxldGUgb2xkIGVudHJ5IGFuZCBjcmVhdGUgYSBuZXcuCisgICAgTE9HLmluZm8oIlNjYW5uaW5nICIgKyBtZXRhLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKQorICAgIG1ldGFSZWdpb24gPSB1dGlscy5nZXRNZXRhUmVnaW9uKG1ldGEpCisgICAgc2Nhbm5lciA9IG1ldGFSZWdpb24uZ2V0U2Nhbm5lcihIQ29uc3RhbnRzOjpDT0xfUkVHSU9OSU5GT19BUlJBWSwgb2xkVGFibGVOYW1lLAorICAgICAgSENvbnN0YW50czo6TEFURVNUX1RJTUVTVEFNUCwgbmlsKSAKKyAgICBiZWdpbgorICAgICAga2V5ID0gSFN0b3JlS2V5Lm5ldygpCisgICAgICB2YWx1ZSA9IFRyZWVNYXAubmV3KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpCisgICAgICB3aGlsZSBzY2FubmVyLm5leHQoa2V5LCB2YWx1ZSkKKyAgICAgICAgaW5kZXggPSBpbmRleCArIDEKKyAgICAgICAga2V5U3RyID0ga2V5LnRvU3RyaW5nKCkKKyAgICAgICAgb2xkSFJJID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKHZhbHVlLmdldChIQ29uc3RhbnRzOjpDT0xfUkVHSU9OSU5GTykpCisgICAgICAgIGlmICFvbGRIUkkKKyAgICAgICAgICByYWlzZSBJT0Vycm9yLm5ldyhpbmRleC50b19zICsgIiBIUmVnaW9uSW5mbyBpcyBudWxsIGZvciAiICsga2V5U3RyKQorICAgICAgICBlbmQKKyAgICAgICAgdW5sZXNzIGlzVGFibGVSZWdpb24ob2xkVGFibGVOYW1lLCBvbGRIUkkpCisgICAgICAgICAgIyBJZiBoZXJlLCB3ZSBwYXNzZWQgb3V0IHRoZSB0YWJsZS4gIEJyZWFrLgorICAgICAgICAgIGJyZWFrCisgICAgICAgIGVuZAorICAgICAgICBvbGRSRGlyID0gUGF0aC5uZXcob2xkVGFibGVEaXIsIFBhdGgubmV3KG9sZEhSSS5nZXRFbmNvZGVkTmFtZSgpLnRvX3MpKQorICAgICAgICBpZiAhZnMuZXhpc3RzKG9sZFJEaXIpCisgICAgICAgICAgTE9HLndhcm4ob2xkUkRpci50b1N0cmluZygpICsgIiBkb2VzIG5vdCBleGlzdCAtLSByZWdpb24gIiArCisgICAgICAgICAgICBvbGRIUkkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpCisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIyBOb3cgbWFrZSBhIG5ldyBIUmVnaW9uSW5mbyB0byBhZGQgdG8gLk1FVEEuIGZvciB0aGUgbmV3IHJlZ2lvbi4KKyAgICAgICAgICBuZXdIUkkgPSBjcmVhdGVIUkkobmV3VGFibGVOYW1lLCBvbGRIUkkpCisgICAgICAgICAgbmV3UkRpciA9IFBhdGgubmV3KG5ld1RhYmxlRGlyLCBQYXRoLm5ldyhuZXdIUkkuZ2V0RW5jb2RlZE5hbWUoKS50b19zKSkKKyAgICAgICAgICAjIE1vdmUgdGhlIHJlZ2lvbiBpbiBmaWxlc3lzdGVtCisgICAgICAgICAgTE9HLmluZm8oIkNvcHlpbmcgIiArIG9sZFJEaXIudG9TdHJpbmcoKSArICIgYXMgIiArIG5ld1JEaXIudG9TdHJpbmcoKSkKKyAgICAgICAgICBGaWxlVXRpbC5jb3B5KGZzLCBvbGRSRGlyLCBmcywgbmV3UkRpciwgZmFsc2UsIHRydWUsIGMpCisgICAgICAgICAgIyBDcmVhdGUgJ25ldycgcmVnaW9uCisgICAgICAgICAgbmV3UiA9IEhSZWdpb24ubmV3KHJvb3RkaXIsIHV0aWxzLmdldExvZygpLCBmcywgYywgbmV3SFJJLCBuaWwpCisgICAgICAgICAgIyBBZGQgbmV3IHJvdy4gTk9URTogUHJlc3VtcHRpb24gaXMgdGhhdCBvbmx5IG9uZSAuTUVUQS4gcmVnaW9uLiBJZiBub3QsCisgICAgICAgICAgIyBuZWVkIHRvIGRvIHRoZSB3b3JrIHRvIGZpZ3VyZSBwcm9wZXIgcmVnaW9uIHRvIGFkZCB0aGlzIG5ldyByZWdpb24gdG8uCisgICAgICAgICAgTE9HLmluZm8oIkFkZGluZyB0byBtZXRhOiAiICsgbmV3Ui50b1N0cmluZygpKQorICAgICAgICAgIEhSZWdpb24uYWRkUmVnaW9uVG9NRVRBKG1ldGFSZWdpb24sIG5ld1IpCisgICAgICAgICAgTE9HLmluZm8oIkRvbmUgY29weWluZzogIiArIEJ5dGVzLnRvU3RyaW5nKGtleS5nZXRSb3coKSkpCisgICAgICAgIGVuZAorICAgICAgICAjIE5lZWQgdG8gY2xlYXIgdmFsdWUgZWxzZSB3ZSBrZWVwIGFwcGVuZGluZyB2YWx1ZXMuCisgICAgICAgIHZhbHVlLmNsZWFyKCkKKyAgICAgIGVuZAorICAgIGVuc3VyZQorICAgICAgc2Nhbm5lci5jbG9zZSgpCisgICAgZW5kCisgIGVuZAorZW5zdXJlCisgIHV0aWxzLnNodXRkb3duKCkKK2VuZApkaWZmIC0tZ2l0IGEvYmluL2hiYXNlIGIvYmluL2hiYXNlCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmU3M2U4YzcKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vaGJhc2UKQEAgLTAsMCArMSwyMTkgQEAKKyMhIC91c3IvYmluL2VudiBiYXNoCisjCisjLyoqCisjICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisjICoKKyMgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisjICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisjICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorIyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyMgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjICoKKyMgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjICoKKyMgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisjICovCisjIAorIyBUaGUgaGJhc2UgY29tbWFuZCBzY3JpcHQuICBCYXNlZCBvbiB0aGUgaGFkb29wIGNvbW1hbmQgc2NyaXB0IHB1dHRpbmcKKyMgaW4gaGJhc2UgY2xhc3NlcywgbGlicyBhbmQgY29uZmlndXJhdGlvbnMgYWhlYWQgb2YgaGFkb29wJ3MuCisjCisjIFRPRE86IE5hcnJvdyB0aGUgYW1vdW50IG9mIGR1cGxpY2F0ZWQgY29kZS4KKyMKKyMgRW52aXJvbm1lbnQgVmFyaWFibGVzOgorIworIyAgIEpBVkFfSE9NRSAgICAgICAgVGhlIGphdmEgaW1wbGVtZW50YXRpb24gdG8gdXNlLiAgT3ZlcnJpZGVzIEpBVkFfSE9NRS4KKyMKKyMgICBIQkFTRV9DTEFTU1BBVEggIEV4dHJhIEphdmEgQ0xBU1NQQVRIIGVudHJpZXMuCisjCisjICAgSEJBU0VfSEVBUFNJWkUgICBUaGUgbWF4aW11bSBhbW91bnQgb2YgaGVhcCB0byB1c2UsIGluIE1CLiAKKyMgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgaXMgMTAwMC4KKyMKKyMgICBIQkFTRV9PUFRTICAgICAgIEV4dHJhIEphdmEgcnVudGltZSBvcHRpb25zLgorIworIyAgIEhCQVNFX0NPTkZfRElSICAgQWx0ZXJuYXRlIGNvbmYgZGlyLiBEZWZhdWx0IGlzICR7SEJBU0VfSE9NRX0vY29uZi4KKyMKKyMgICBIQkFTRV9ST09UX0xPR0dFUiBUaGUgcm9vdCBhcHBlbmRlci4gRGVmYXVsdCBpcyBJTkZPLGNvbnNvbGUKKyMKK2Jpbj1gZGlybmFtZSAiJDAiYAorYmluPWBjZCAiJGJpbiI7IHB3ZGAKKworIyBUaGlzIHdpbGwgc2V0IEhCQVNFX0hPTUUsIGV0Yy4KKy4gIiRiaW4iL2hiYXNlLWNvbmZpZy5zaAorCitjeWd3aW49ZmFsc2UKK2Nhc2UgImB1bmFtZWAiIGluCitDWUdXSU4qKSBjeWd3aW49dHJ1ZTs7Citlc2FjCisKKyMgaWYgbm8gYXJncyBzcGVjaWZpZWQsIHNob3cgdXNhZ2UKK2lmIFsgJCMgPSAwIF07IHRoZW4KKyAgZWNobyAiVXNhZ2U6IGhiYXNlIDxjb21tYW5kPiIKKyAgZWNobyAid2hlcmUgPGNvbW1hbmQ+IGlzIG9uZSBvZjoiCisgIGVjaG8gIiAgc2hlbGwgICAgICAgICAgICBydW4gdGhlIEhCYXNlIHNoZWxsIgorICBlY2hvICIgIG1hc3RlciAgICAgICAgICAgcnVuIGFuIEhCYXNlIEhNYXN0ZXIgbm9kZSIgCisgIGVjaG8gIiAgcmVnaW9uc2VydmVyICAgICBydW4gYW4gSEJhc2UgSFJlZ2lvblNlcnZlciBub2RlIiAKKyAgZWNobyAiICByZXN0ICAgICAgICAgICAgIHJ1biBhbiBIQmFzZSBSRVNUIHNlcnZlciIgCisgIGVjaG8gIiAgdGhyaWZ0ICAgICAgICAgICBydW4gYW4gSEJhc2UgVGhyaWZ0IHNlcnZlciIgCisgIGVjaG8gIiAgem9va2VlcGVyICAgICAgICBydW4gYSBab29rZWVwZXIgc2VydmVyIgorICBlY2hvICIgIG1pZ3JhdGUgICAgICAgICAgdXBncmFkZSBhbiBoYmFzZS5yb290ZGlyIgorICBlY2hvICIgb3IiCisgIGVjaG8gIiAgQ0xBU1NOQU1FICAgICAgICBydW4gdGhlIGNsYXNzIG5hbWVkIENMQVNTTkFNRSIKKyAgZWNobyAiTW9zdCBjb21tYW5kcyBwcmludCBoZWxwIHdoZW4gaW52b2tlZCB3L28gcGFyYW1ldGVycy4iCisgIGV4aXQgMQorZmkKKworIyBnZXQgYXJndW1lbnRzCitDT01NQU5EPSQxCitzaGlmdAorCisjIFNvdXJjZSB0aGUgaGJhc2UtZW52LnNoLiAgV2lsbCBoYXZlIEpBVkFfSE9NRSBkZWZpbmVkLgoraWYgWyAtZiAiJHtIQkFTRV9DT05GX0RJUn0vaGJhc2UtZW52LnNoIiBdOyB0aGVuCisgIC4gIiR7SEJBU0VfQ09ORl9ESVJ9L2hiYXNlLWVudi5zaCIKK2ZpCisKKyMgc29tZSBKYXZhIHBhcmFtZXRlcnMKK2lmIFsgIiRKQVZBX0hPTUUiICE9ICIiIF07IHRoZW4KKyAgI2VjaG8gInJ1biBqYXZhIGluICRKQVZBX0hPTUUiCisgIEpBVkFfSE9NRT0kSkFWQV9IT01FCitmaQorICAKK2lmIFsgIiRKQVZBX0hPTUUiID0gIiIgXTsgdGhlbgorICBlY2hvICJFcnJvcjogSkFWQV9IT01FIGlzIG5vdCBzZXQuIgorICBleGl0IDEKK2ZpCisKK0pBVkE9JEpBVkFfSE9NRS9iaW4vamF2YQorSkFWQV9IRUFQX01BWD0tWG14MTAwMG0gCisKKyMgY2hlY2sgZW52dmFycyB3aGljaCBtaWdodCBvdmVycmlkZSBkZWZhdWx0IGFyZ3MKK2lmIFsgIiRIQkFTRV9IRUFQU0laRSIgIT0gIiIgXTsgdGhlbgorICAjZWNobyAicnVuIHdpdGggaGVhcHNpemUgJEhCQVNFX0hFQVBTSVpFIgorICBKQVZBX0hFQVBfTUFYPSItWG14IiIkSEJBU0VfSEVBUFNJWkUiIm0iCisgICNlY2hvICRKQVZBX0hFQVBfTUFYCitmaQorCisjIHNvIHRoYXQgZmlsZW5hbWVzIHcvIHNwYWNlcyBhcmUgaGFuZGxlZCBjb3JyZWN0bHkgaW4gbG9vcHMgYmVsb3cKK0lGUz0KKworIyBDTEFTU1BBVEggaW5pdGlhbGx5IGNvbnRhaW5zICRIQkFTRV9DT05GX0RJUgorQ0xBU1NQQVRIPSIke0hCQVNFX0NPTkZfRElSfSIKKworCitDTEFTU1BBVEg9JHtDTEFTU1BBVEh9OiRKQVZBX0hPTUUvbGliL3Rvb2xzLmphcgorCisjIGZvciBkZXZlbG9wZXJzLCBhZGQgaGJhc2UgY2xhc3NlcyB0byBDTEFTU1BBVEgKK2lmIFsgLWQgIiRIQkFTRV9IT01FL2J1aWxkL2NsYXNzZXMiIF07IHRoZW4KKyAgQ0xBU1NQQVRIPSR7Q0xBU1NQQVRIfTokSEJBU0VfSE9NRS9idWlsZC9jbGFzc2VzCitmaQoraWYgWyAtZCAiJEhCQVNFX0hPTUUvYnVpbGQvdGVzdCIgXTsgdGhlbgorICBDTEFTU1BBVEg9JHtDTEFTU1BBVEh9OiRIQkFTRV9IT01FL2J1aWxkL3Rlc3QKK2ZpCitpZiBbIC1kICIkSEJBU0VfSE9NRS9idWlsZC93ZWJhcHBzIiBdOyB0aGVuCisgIENMQVNTUEFUSD0ke0NMQVNTUEFUSH06JEhCQVNFX0hPTUUvYnVpbGQKK2ZpCisKKyMgZm9yIHJlbGVhc2VzLCBhZGQgaGJhc2UgJiB3ZWJhcHBzIHRvIENMQVNTUEFUSAorZm9yIGYgaW4gJEhCQVNFX0hPTUUvaGJhc2UqLmphcjsgZG8KKyAgaWYgWyAtZiAkZiBdOyB0aGVuCisgICAgQ0xBU1NQQVRIPSR7Q0xBU1NQQVRIfTokZjsKKyAgZmkKK2RvbmUKK2lmIFsgLWQgIiRIQkFTRV9IT01FL3dlYmFwcHMiIF07IHRoZW4KKyAgQ0xBU1NQQVRIPSR7Q0xBU1NQQVRIfTokSEJBU0VfSE9NRQorZmkKKworIyBBZGQgbGlicyB0byBDTEFTU1BBVEgKK2ZvciBmIGluICRIQkFTRV9IT01FL2xpYi8qLmphcjsgZG8KKyAgQ0xBU1NQQVRIPSR7Q0xBU1NQQVRIfTokZjsKK2RvbmUKKworZm9yIGYgaW4gJEhCQVNFX0hPTUUvbGliL2pzcC0yLjEvKi5qYXI7IGRvCisgIENMQVNTUEFUSD0ke0NMQVNTUEFUSH06JGY7Citkb25lCisKKyMgYWRkIHVzZXItc3BlY2lmaWVkIENMQVNTUEFUSCBsYXN0CitpZiBbICIkSEJBU0VfQ0xBU1NQQVRIIiAhPSAiIiBdOyB0aGVuCisgIENMQVNTUEFUSD0ke0NMQVNTUEFUSH06JHtIQkFTRV9DTEFTU1BBVEh9CitmaQorCisjIGRlZmF1bHQgbG9nIGRpcmVjdG9yeSAmIGZpbGUKK2lmIFsgIiRIQkFTRV9MT0dfRElSIiA9ICIiIF07IHRoZW4KKyAgSEJBU0VfTE9HX0RJUj0iJEhCQVNFX0hPTUUvbG9ncyIKK2ZpCitpZiBbICIkSEJBU0VfTE9HRklMRSIgPSAiIiBdOyB0aGVuCisgIEhCQVNFX0xPR0ZJTEU9J2hiYXNlLmxvZycKK2ZpCisKKyMgY3lnd2luIHBhdGggdHJhbnNsYXRpb24KK2lmICRjeWd3aW47IHRoZW4KKyAgQ0xBU1NQQVRIPWBjeWdwYXRoIC1wIC13ICIkQ0xBU1NQQVRIImAKKyAgSEJBU0VfSE9NRT1gY3lncGF0aCAtZCAiJEhCQVNFX0hPTUUiYAorICBIQkFTRV9MT0dfRElSPWBjeWdwYXRoIC1kICIkSEJBU0VfTE9HX0RJUiJgCitmaQorIyBzZXR1cCAnamF2YS5saWJyYXJ5LnBhdGgnIGZvciBuYXRpdmUtaGFkb29wIGNvZGUgaWYgbmVjZXNzYXJ5CitKQVZBX0xJQlJBUllfUEFUSD0nJworaWYgWyAtZCAiJHtIQkFTRV9IT01FfS9idWlsZC9uYXRpdmUiIC1vIC1kICIke0hCQVNFX0hPTUV9L2xpYi9uYXRpdmUiIF07IHRoZW4KKyAgSkFWQV9QTEFURk9STT1gQ0xBU1NQQVRIPSR7Q0xBU1NQQVRIfSAke0pBVkF9IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUGxhdGZvcm1OYW1lIHwgc2VkIC1lICJzLyAvXy9nImAKKworICBpZiBbIC1kICIkSEJBU0VfSE9NRS9idWlsZC9uYXRpdmUiIF07IHRoZW4KKyAgICBKQVZBX0xJQlJBUllfUEFUSD0ke0hCQVNFX0hPTUV9L2J1aWxkL25hdGl2ZS8ke0pBVkFfUExBVEZPUk19L2xpYgorICBmaQorCisgIGlmIFsgLWQgIiR7SEJBU0VfSE9NRX0vbGliL25hdGl2ZSIgXTsgdGhlbgorICAgIGlmIFsgIngkSkFWQV9MSUJSQVJZX1BBVEgiICE9ICJ4IiBdOyB0aGVuCisgICAgICBKQVZBX0xJQlJBUllfUEFUSD0ke0pBVkFfTElCUkFSWV9QQVRIfToke0hCQVNFX0hPTUV9L2xpYi9uYXRpdmUvJHtKQVZBX1BMQVRGT1JNfQorICAgIGVsc2UKKyAgICAgIEpBVkFfTElCUkFSWV9QQVRIPSR7SEJBU0VfSE9NRX0vbGliL25hdGl2ZS8ke0pBVkFfUExBVEZPUk19CisgICAgZmkKKyAgZmkKK2ZpCisKKyMgY3lnd2luIHBhdGggdHJhbnNsYXRpb24KK2lmICRjeWd3aW47IHRoZW4KKyAgSkFWQV9MSUJSQVJZX1BBVEg9YGN5Z3BhdGggLXAgIiRKQVZBX0xJQlJBUllfUEFUSCJgCitmaQorIAorIyByZXN0b3JlIG9yZGluYXJ5IGJlaGF2aW91cgordW5zZXQgSUZTCisKKyMgZmlndXJlIG91dCB3aGljaCBjbGFzcyB0byBydW4KK2lmIFsgIiRDT01NQU5EIiA9ICJzaGVsbCIgXSA7IHRoZW4KKyAgQ0xBU1M9Im9yZy5qcnVieS5NYWluICR7SEJBU0VfSE9NRX0vYmluL2hpcmIucmIiCitlbGlmIFsgIiRDT01NQU5EIiA9ICJtYXN0ZXIiIF0gOyB0aGVuCisgIENMQVNTPSdvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXIuSE1hc3RlcicKK2VsaWYgWyAiJENPTU1BTkQiID0gInJlZ2lvbnNlcnZlciIgXSA7IHRoZW4KKyAgQ0xBU1M9J29yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uU2VydmVyJworZWxpZiBbICIkQ09NTUFORCIgPSAicmVzdCIgXSA7IHRoZW4KKyAgQ0xBU1M9J29yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuRGlzcGF0Y2hlcicKK2VsaWYgWyAiJENPTU1BTkQiID0gInRocmlmdCIgXSA7IHRoZW4KKyAgQ0xBU1M9J29yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5UaHJpZnRTZXJ2ZXInCitlbGlmIFsgIiRDT01NQU5EIiA9ICJtaWdyYXRlIiBdIDsgdGhlbgorICBDTEFTUz0nb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5NaWdyYXRlJworZWxpZiBbICIkQ09NTUFORCIgPSAiem9va2VlcGVyIiBdIDsgdGhlbgorICBDTEFTUz0nb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyLkhRdW9ydW1QZWVyJworZWxzZQorICBDTEFTUz0kQ09NTUFORAorZmkKKworIyBIYXZlIEpWTSBkdW1wIGhlYXAgaWYgd2UgcnVuIG91dCBvZiBtZW1vcnkuICBGaWxlcyB3aWxsIGJlICdsYXVuY2ggZGlyZWN0b3J5JworIyBhbmQgYXJlIG5hbWVkIGxpa2UgdGhlIGZvbGxvd2luZzogamF2YV9waWQyMTYxMi5ocHJvZi4gQXBwYXJlbnRseSBpdCBkb2Vzbid0CisjICdjb3N0JyB0byBoYXZlIHRoaXMgZmxhZyBlbmFibGVkLiBJdHMgYSAxLjYgZmxhZyBvbmx5LiBTZWU6CisjIGh0dHA6Ly9ibG9ncy5zdW4uY29tL2FsYW5iL2VudHJ5L291dG9mbWVtb3J5ZXJyb3JfbG9va3NfYV9iaXRfYmV0dGVyCitIQkFTRV9PUFRTPSIkSEJBU0VfT1BUUyAtWFg6K0hlYXBEdW1wT25PdXRPZk1lbW9yeUVycm9yIgorSEJBU0VfT1BUUz0iJEhCQVNFX09QVFMgLURoYmFzZS5sb2cuZGlyPSRIQkFTRV9MT0dfRElSIgorSEJBU0VfT1BUUz0iJEhCQVNFX09QVFMgLURoYmFzZS5sb2cuZmlsZT0kSEJBU0VfTE9HRklMRSIKK0hCQVNFX09QVFM9IiRIQkFTRV9PUFRTIC1EaGJhc2UuaG9tZS5kaXI9JEhCQVNFX0hPTUUiCitIQkFTRV9PUFRTPSIkSEJBU0VfT1BUUyAtRGhiYXNlLmlkLnN0cj0kSEJBU0VfSURFTlRfU1RSSU5HIgorSEJBU0VfT1BUUz0iJEhCQVNFX09QVFMgLURoYmFzZS5yb290LmxvZ2dlcj0ke0hCQVNFX1JPT1RfTE9HR0VSOi1JTkZPLGNvbnNvbGV9IgoraWYgWyAieCRKQVZBX0xJQlJBUllfUEFUSCIgIT0gIngiIF07IHRoZW4KKyAgSEJBU0VfT1BUUz0iJEhCQVNFX09QVFMgLURqYXZhLmxpYnJhcnkucGF0aD0kSkFWQV9MSUJSQVJZX1BBVEgiCitmaQorCisjIHJ1biBpdAorZXhlYyAiJEpBVkEiICRKQVZBX0hFQVBfTUFYICRIQkFTRV9PUFRTIC1jbGFzc3BhdGggIiRDTEFTU1BBVEgiICRDTEFTUyAiJEAiCmRpZmYgLS1naXQgYS9iaW4vaGJhc2UtY29uZmlnLnNoIGIvYmluL2hiYXNlLWNvbmZpZy5zaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYWQ4MDM5Ci0tLSAvZGV2L251bGwKKysrIGIvYmluL2hiYXNlLWNvbmZpZy5zaApAQCAtMCwwICsxLDczIEBACisjCisjLyoqCisjICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisjICoKKyMgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisjICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisjICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorIyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyMgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjICoKKyMgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjICoKKyMgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisjICovCisKKyMgaW5jbHVkZWQgaW4gYWxsIHRoZSBoYmFzZSBzY3JpcHRzIHdpdGggc291cmNlIGNvbW1hbmQKKyMgc2hvdWxkIG5vdCBiZSBleGVjdXRhYmxlIGRpcmVjdGx5CisjIGFsc28gc2hvdWxkIG5vdCBiZSBwYXNzZWQgYW55IGFyZ3VtZW50cywgc2luY2Ugd2UgbmVlZCBvcmlnaW5hbCAkKgorIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL2hhZG9vcC1lbnYuc2guCisKKyMgcmVzb2x2ZSBsaW5rcyAtICQwIG1heSBiZSBhIHNvZnRsaW5rCisKK3RoaXM9IiQwIgord2hpbGUgWyAtaCAiJHRoaXMiIF07IGRvCisgIGxzPWBscyAtbGQgIiR0aGlzImAKKyAgbGluaz1gZXhwciAiJGxzIiA6ICcuKi0+IFwoLipcKSQnYAorICBpZiBleHByICIkbGluayIgOiAnLiovLionID4gL2Rldi9udWxsOyB0aGVuCisgICAgdGhpcz0iJGxpbmsiCisgIGVsc2UKKyAgICB0aGlzPWBkaXJuYW1lICIkdGhpcyJgLyIkbGluayIKKyAgZmkKK2RvbmUKKworIyBjb252ZXJ0IHJlbGF0aXZlIHBhdGggdG8gYWJzb2x1dGUgcGF0aAorYmluPWBkaXJuYW1lICIkdGhpcyJgCitzY3JpcHQ9YGJhc2VuYW1lICIkdGhpcyJgCitiaW49YGNkICIkYmluIjsgcHdkYAordGhpcz0iJGJpbi8kc2NyaXB0IgorCisjIHRoZSByb290IG9mIHRoZSBoYmFzZSBpbnN0YWxsYXRpb24KK2V4cG9ydCBIQkFTRV9IT01FPWBkaXJuYW1lICIkdGhpcyJgLy4uCisKKyNjaGVjayB0byBzZWUgaWYgdGhlIGNvbmYgZGlyIG9yIGhiYXNlIGhvbWUgYXJlIGdpdmVuIGFzIGFuIG9wdGlvbmFsIGFyZ3VtZW50cword2hpbGUgWyAkIyAtZ3QgMSBdCitkbworICBpZiBbICItLWNvbmZpZyIgPSAiJDEiIF0KKyAgdGhlbgorICAgIHNoaWZ0CisgICAgY29uZmRpcj0kMQorICAgIHNoaWZ0CisgICAgSEJBU0VfQ09ORl9ESVI9JGNvbmZkaXIKKyAgZWxpZiBbICItLWhvc3RzIiA9ICIkMSIgXQorICB0aGVuCisgICAgc2hpZnQKKyAgICBob3N0cz0kMQorICAgIHNoaWZ0CisgICAgSEJBU0VfUkVHSU9OU0VSVkVSUz0kaG9zdHMKKyAgZWxzZQorICAgICMgUHJlc3VtZSB3ZSBhcmUgYXQgZW5kIG9mIG9wdGlvbnMgYW5kIGJyZWFrCisgICAgYnJlYWsKKyAgZmkKK2RvbmUKKyAKKyMgQWxsb3cgYWx0ZXJuYXRlIGhiYXNlIGNvbmYgZGlyIGxvY2F0aW9uLgorSEJBU0VfQ09ORl9ESVI9IiR7SEJBU0VfQ09ORl9ESVI6LSRIQkFTRV9IT01FL2NvbmZ9IgorIyBMaXN0IG9mIGhiYXNlIHJlZ2lvbnMgc2VydmVycy4KK0hCQVNFX1JFR0lPTlNFUlZFUlM9IiR7SEJBU0VfUkVHSU9OU0VSVkVSUzotJEhCQVNFX0NPTkZfRElSL3JlZ2lvbnNlcnZlcnN9IgpkaWZmIC0tZ2l0IGEvYmluL2hiYXNlLWRhZW1vbi5zaCBiL2Jpbi9oYmFzZS1kYWVtb24uc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDZiMzcxZQotLS0gL2Rldi9udWxsCisrKyBiL2Jpbi9oYmFzZS1kYWVtb24uc2gKQEAgLTAsMCArMSwxNjggQEAKKyMhL3Vzci9iaW4vZW52IGJhc2gKKyMKKyMvKioKKyMgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyMgKgorIyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisjICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgKgorIyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgKgorIyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgKi8KKyMgCisjIFJ1bnMgYSBIYWRvb3AgaGJhc2UgY29tbWFuZCBhcyBhIGRhZW1vbi4KKyMKKyMgRW52aXJvbm1lbnQgVmFyaWFibGVzCisjCisjICAgSEJBU0VfQ09ORl9ESVIgICBBbHRlcm5hdGUgaGJhc2UgY29uZiBkaXIuIERlZmF1bHQgaXMgJHtIQkFTRV9IT01FfS9jb25mLgorIyAgIEhCQVNFX0xPR19ESVIgICAgV2hlcmUgbG9nIGZpbGVzIGFyZSBzdG9yZWQuICBQV0QgYnkgZGVmYXVsdC4KKyMgICBIQkFTRV9QSURfRElSICAgIFRoZSBwaWQgZmlsZXMgYXJlIHN0b3JlZC4gL3RtcCBieSBkZWZhdWx0LgorIyAgIEhCQVNFX0lERU5UX1NUUklORyAgIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGlzIGluc3RhbmNlIG9mIGhhZG9vcC4gJFVTRVIgYnkgZGVmYXVsdAorIyAgIEhCQVNFX05JQ0VORVNTIFRoZSBzY2hlZHVsaW5nIHByaW9yaXR5IGZvciBkYWVtb25zLiBEZWZhdWx0cyB0byAwLgorIworIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL2hhZG9vcC1kYWVtb24uc2gKKwordXNhZ2U9IlVzYWdlOiBoYmFzZS1kYWVtb24uc2ggWy0tY29uZmlnIDxjb25mLWRpcj5dXAorIChzdGFydHxzdG9wKSA8aGJhc2UtY29tbWFuZD4gXAorIDxhcmdzLi4uPiIKKworIyBpZiBubyBhcmdzIHNwZWNpZmllZCwgc2hvdyB1c2FnZQoraWYgWyAkIyAtbGUgMSBdOyB0aGVuCisgIGVjaG8gJHVzYWdlCisgIGV4aXQgMQorZmkKKworYmluPWBkaXJuYW1lICIkMCJgCitiaW49YGNkICIkYmluIjsgcHdkYAorCisuICIkYmluIi9oYmFzZS1jb25maWcuc2gKKworIyBnZXQgYXJndW1lbnRzCitzdGFydFN0b3A9JDEKK3NoaWZ0CisKK2NvbW1hbmQ9JDEKK3NoaWZ0CisKK2hiYXNlX3JvdGF0ZV9sb2cgKCkKK3sKKyAgICBsb2c9JDE7CisgICAgbnVtPTU7CisgICAgaWYgWyAtbiAiJDIiIF07IHRoZW4KKyAgICBudW09JDIKKyAgICBmaQorICAgIGlmIFsgLWYgIiRsb2ciIF07IHRoZW4gIyByb3RhdGUgbG9ncworICAgIHdoaWxlIFsgJG51bSAtZ3QgMSBdOyBkbworICAgICAgICBwcmV2PWBleHByICRudW0gLSAxYAorICAgICAgICBbIC1mICIkbG9nLiRwcmV2IiBdICYmIG12ICIkbG9nLiRwcmV2IiAiJGxvZy4kbnVtIgorICAgICAgICBudW09JHByZXYKKyAgICBkb25lCisgICAgbXYgIiRsb2ciICIkbG9nLiRudW0iOworICAgIGZpCit9CisKK2lmIFsgLWYgIiR7SEJBU0VfQ09ORl9ESVJ9L2hiYXNlLWVudi5zaCIgXTsgdGhlbgorICAuICIke0hCQVNFX0NPTkZfRElSfS9oYmFzZS1lbnYuc2giCitmaQorCisjIGdldCBsb2cgZGlyZWN0b3J5CitpZiBbICIkSEJBU0VfTE9HX0RJUiIgPSAiIiBdOyB0aGVuCisgIGV4cG9ydCBIQkFTRV9MT0dfRElSPSIkSEJBU0VfSE9NRS9sb2dzIgorZmkKK21rZGlyIC1wICIkSEJBU0VfTE9HX0RJUiIKKworaWYgWyAiJEhCQVNFX1BJRF9ESVIiID0gIiIgXTsgdGhlbgorICBIQkFTRV9QSURfRElSPS90bXAKK2ZpCisKK2lmIFsgIiRIQkFTRV9JREVOVF9TVFJJTkciID0gIiIgXTsgdGhlbgorICBleHBvcnQgSEJBU0VfSURFTlRfU1RSSU5HPSIkVVNFUiIKK2ZpCisKKyMgU29tZSB2YXJpYWJsZXMKKyMgV29yayBvdXQgamF2YSBsb2NhdGlvbiBzbyBjYW4gcHJpbnQgdmVyc2lvbiBpbnRvIGxvZy4KK2lmIFsgIiRKQVZBX0hPTUUiICE9ICIiIF07IHRoZW4KKyAgI2VjaG8gInJ1biBqYXZhIGluICRKQVZBX0hPTUUiCisgIEpBVkFfSE9NRT0kSkFWQV9IT01FCitmaQoraWYgWyAiJEpBVkFfSE9NRSIgPSAiIiBdOyB0aGVuCisgIGVjaG8gIkVycm9yOiBKQVZBX0hPTUUgaXMgbm90IHNldC4iCisgIGV4aXQgMQorZmkKK0pBVkE9JEpBVkFfSE9NRS9iaW4vamF2YQorZXhwb3J0IEhCQVNFX0xPR0ZJTEU9aGJhc2UtJEhCQVNFX0lERU5UX1NUUklORy0kY29tbWFuZC0kSE9TVE5BTUUubG9nCitleHBvcnQgSEJBU0VfUk9PVF9MT0dHRVI9IklORk8sRFJGQSIKK2xvZ291dD0kSEJBU0VfTE9HX0RJUi9oYmFzZS0kSEJBU0VfSURFTlRfU1RSSU5HLSRjb21tYW5kLSRIT1NUTkFNRS5vdXQgIAorbG9nbG9nPSIke0hCQVNFX0xPR19ESVJ9LyR7SEJBU0VfTE9HRklMRX0iCitwaWQ9JEhCQVNFX1BJRF9ESVIvaGJhc2UtJEhCQVNFX0lERU5UX1NUUklORy0kY29tbWFuZC5waWQKKworIyBTZXQgZGVmYXVsdCBzY2hlZHVsaW5nIHByaW9yaXR5CitpZiBbICIkSEJBU0VfTklDRU5FU1MiID0gIiIgXTsgdGhlbgorICAgIGV4cG9ydCBIQkFTRV9OSUNFTkVTUz0wCitmaQorCitjYXNlICRzdGFydFN0b3AgaW4KKworICAoc3RhcnQpCisgICAgbWtkaXIgLXAgIiRIQkFTRV9QSURfRElSIgorICAgIGlmIFsgLWYgJHBpZCBdOyB0aGVuCisgICAgICBpZiBraWxsIC0wIGBjYXQgJHBpZGAgPiAvZGV2L251bGwgMj4mMTsgdGhlbgorICAgICAgICBlY2hvICRjb21tYW5kIHJ1bm5pbmcgYXMgcHJvY2VzcyBgY2F0ICRwaWRgLiAgU3RvcCBpdCBmaXJzdC4KKyAgICAgICAgZXhpdCAxCisgICAgICBmaQorICAgIGZpCisKKyAgICBoYmFzZV9yb3RhdGVfbG9nICRsb2dvdXQKKyAgICBlY2hvIHN0YXJ0aW5nICRjb21tYW5kLCBsb2dnaW5nIHRvICRsb2dvdXQKKyAgICAjIEFkZCB0byB0aGUgY29tbWFuZCBsb2cgZmlsZSB2aXRhbCBzdGF0cyBvbiBvdXIgZW52aXJvbm1lbnQuCisgICAgZWNobyAiYGRhdGVgIFN0YXJ0aW5nICRjb21tYW5kIG9uIGBob3N0bmFtZWAiID4+ICRsb2dsb2cKKyAgICBlY2hvICJ1bGltaXQgLW4gYHVsaW1pdCAtbmAiID4+ICRsb2dsb2cgMj4mMQorICAgIG5vaHVwIG5pY2UgLW4gJEhCQVNFX05JQ0VORVNTICIkSEJBU0VfSE9NRSIvYmluL2hiYXNlIFwKKyAgICAgICAgLS1jb25maWcgIiR7SEJBU0VfQ09ORl9ESVJ9IiBcCisgICAgICAgICRjb21tYW5kICRzdGFydFN0b3AgIiRAIiA+ICIkbG9nb3V0IiAyPiYxIDwgL2Rldi9udWxsICYKKyAgICBlY2hvICQhID4gJHBpZAorICAgIHNsZWVwIDE7IGhlYWQgIiRsb2dvdXQiCisgICAgOzsKKworICAoc3RvcCkKKyAgICBpZiBbIC1mICRwaWQgXTsgdGhlbgorICAgICAgaWYga2lsbCAtMCBgY2F0ICRwaWRgID4gL2Rldi9udWxsIDI+JjE7IHRoZW4KKyAgICAgICAgZWNobyAtbiBzdG9wcGluZyAkY29tbWFuZAorICAgICAgICBlY2hvICJgZGF0ZWAgU3RvcHBpbmcgJGNvbW1hbmQiID4+ICRsb2dsb2cKKyAgICAgICAgaWYgWyAiJGNvbW1hbmQiID0gIm1hc3RlciIgXTsgdGhlbgorICAgICAgICAgIG5vaHVwIG5pY2UgLW4gJEhCQVNFX05JQ0VORVNTICIkSEJBU0VfSE9NRSIvYmluL2hiYXNlIFwKKyAgICAgICAgICAgICAgLS1jb25maWcgIiR7SEJBU0VfQ09ORl9ESVJ9IiBcCisgICAgICAgICAgICAgICRjb21tYW5kICRzdGFydFN0b3AgIiRAIiA+ICIkbG9nb3V0IiAyPiYxIDwgL2Rldi9udWxsICYKKyAgICAgICAgZWxzZQorICAgICAgICAgIGVjaG8gImBkYXRlYCBLaWxsaW5nICRjb21tYW5kIiA+PiAkbG9nbG9nCisgICAgICAgICAga2lsbCBgY2F0ICRwaWRgID4gL2Rldi9udWxsIDI+JjEKKyAgICAgICAgZmkKKyAgICAgICAgd2hpbGUga2lsbCAtMCBgY2F0ICRwaWRgID4gL2Rldi9udWxsIDI+JjE7IGRvCisgICAgICAgICAgZWNobyAtbiAiLiIKKyAgICAgICAgICBzbGVlcCAxOworICAgICAgICBkb25lCisgICAgICAgIGVjaG8KKyAgICAgIGVsc2UKKyAgICAgICAgZWNobyBubyAkY29tbWFuZCB0byBzdG9wCisgICAgICBmaQorICAgIGVsc2UKKyAgICAgIGVjaG8gbm8gJGNvbW1hbmQgdG8gc3RvcAorICAgIGZpCisgICAgOzsKKworICAoKikKKyAgICBlY2hvICR1c2FnZQorICAgIGV4aXQgMQorICAgIDs7CisKK2VzYWMKZGlmZiAtLWdpdCBhL2Jpbi9oYmFzZS1kYWVtb25zLnNoIGIvYmluL2hiYXNlLWRhZW1vbnMuc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMTY2YWYzMwotLS0gL2Rldi9udWxsCisrKyBiL2Jpbi9oYmFzZS1kYWVtb25zLnNoCkBAIC0wLDAgKzEsNDIgQEAKKyMhL3Vzci9iaW4vZW52IGJhc2gKKyMKKyMvKioKKyMgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyMgKgorIyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisjICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgKgorIyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgKgorIyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgKi8KKyMgCisjIFJ1biBhIGhiYXNlIGNvbW1hbmQgb24gYWxsIHNsYXZlIGhvc3RzLgorIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL2hhZG9vcC1kYWVtb25zLnNoCisKK3VzYWdlPSJVc2FnZTogaGJhc2UtZGFlbW9ucy5zaCBbLS1jb25maWcgPGhiYXNlLWNvbmZkaXI+XSBcCisgWy0taG9zdHMgcmVnaW9uc2VydmVyc2ZpbGVdIFtzdGFydHxzdG9wXSBjb21tYW5kIGFyZ3MuLi4iCisKKyMgaWYgbm8gYXJncyBzcGVjaWZpZWQsIHNob3cgdXNhZ2UKK2lmIFsgJCMgLWxlIDEgXTsgdGhlbgorICBlY2hvICR1c2FnZQorICBleGl0IDEKK2ZpCisKK2Jpbj1gZGlybmFtZSAiJDAiYAorYmluPWBjZCAiJGJpbiI7IHB3ZGAKKworLiAkYmluL2hiYXNlLWNvbmZpZy5zaAorCitleGVjICIkYmluL3JlZ2lvbnNlcnZlcnMuc2giIC0tY29uZmlnICIke0hCQVNFX0NPTkZfRElSfSIgXAorIGNkICIke0hCQVNFX0hPTUV9IiBcOyBcCisgIiRiaW4vaGJhc2UtZGFlbW9uLnNoIiAtLWNvbmZpZyAiJHtIQkFTRV9DT05GX0RJUn0iICIkQCIKZGlmZiAtLWdpdCBhL2Jpbi9oYmFzZS16b29rZWVwZXIuc2ggYi9iaW4vaGJhc2Utem9va2VlcGVyLnNoCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjg1OWZhYWIKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vaGJhc2Utem9va2VlcGVyLnNoCkBAIC0wLDAgKzEsNDIgQEAKKyMhL3Vzci9iaW4vZW52IGJhc2gKKyMKKyMvKioKKyMgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyMgKgorIyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisjICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgKgorIyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgKgorIyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgKi8KKyMgCisjIFJ1biBhIGhiYXNlIGNvbW1hbmQgb24gYWxsIHNsYXZlIGhvc3RzLgorIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL2hhZG9vcC1kYWVtb25zLnNoCisKK3VzYWdlPSJVc2FnZTogaGJhc2UtZGFlbW9ucy5zaCBbLS1jb25maWcgPGhiYXNlLWNvbmZkaXI+XSBcCisgW3N0YXJ0fHN0b3BdIGNvbW1hbmQgYXJncy4uLiIKKworIyBpZiBubyBhcmdzIHNwZWNpZmllZCwgc2hvdyB1c2FnZQoraWYgWyAkIyAtbGUgMSBdOyB0aGVuCisgIGVjaG8gJHVzYWdlCisgIGV4aXQgMQorZmkKKworYmluPWBkaXJuYW1lICIkMCJgCitiaW49YGNkICIkYmluIjsgcHdkYAorCisuICRiaW4vaGJhc2UtY29uZmlnLnNoCisKK2V4ZWMgIiRiaW4vem9va2VlcGVyLnNoIiAtLWNvbmZpZyAiJHtIQkFTRV9DT05GX0RJUn0iIFwKKyBjZCAiJHtIQkFTRV9IT01FfSIgXDsgXAorICIkYmluL2hiYXNlLWRhZW1vbi5zaCIgLS1jb25maWcgIiR7SEJBU0VfQ09ORl9ESVJ9IiAiJEAiCmRpZmYgLS1naXQgYS9iaW4vaGlyYi5yYiBiL2Jpbi9oaXJiLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczZmNkZTQKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vaGlyYi5yYgpAQCAtMCwwICsxLDQ0NCBAQAorIyBGaWxlIHBhc3NlZCB0byBvcmcuanJ1YnkuTWFpbiBieSBiaW4vaGJhc2UuICBQb2xsdXRlcyBqaXJiIHdpdGggaGJhc2UgaW1wb3J0cworIyBhbmQgaGJhc2UgIGNvbW1hbmRzIGFuZCB0aGVuIGxvYWRzIGppcmIuICBPdXRwdXRzIGEgYmFubmVyIHRoYXQgdGVsbHMgdXNlcgorIyB3aGVyZSB0byBmaW5kIGhlbHAsIHNoZWxsIHZlcnNpb24sIGFuZCBsb2FkcyB1cCBhIGN1c3RvbSBoaXJiLgorCisjIFRPRE86IEFkZCAnZGVidWcnIHN1cHBvcnQgKGNsaWVudC1zaWRlIGxvZ3Mgc2hvdyBpbiBzaGVsbCkuICBBZGQgaXQgYXMKKyMgY29tbWFuZC1saW5lIG9wdGlvbiBhbmQgYXMgY29tbWFuZC4KKyMgVE9ETzogSW50ZXJydXB0IGEgdGFibGUgY3JlYXRpb24gb3IgYSBjb25uZWN0aW9uIHRvIGEgYmFkIG1hc3Rlci4gIEN1cnJlbnRseQorIyBoYXMgdG8gdGltZSBvdXQuICBCZWxvdyB3ZSd2ZSBzZXQgZG93biB0aGUgcmV0cmllcyBmb3IgcnBjIGFuZCBoYmFzZSBidXQKKyMgc3RpbGwgY2FuIGJlIGFubm95aW5nIChBbmQgdGhlcmUgc2VlbSB0byBiZSB0aW1lcyB3aGVuIHdlJ2xsIHJldHJ5IGZvcgorIyBldmVyIHJlZ2FyZGxlc3MpCisjIFRPRE86IEFkZCBzdXBwb3J0IGZvciBsaXN0aW5nIGFuZCBtYW5pcHVsYXRpbmcgY2F0YWxvZyB0YWJsZXMsIGV0Yy4KKyMgVE9ETzogRW5jb2Rpbmc7IG5lZWQgdG8ga25vdyBob3cgdG8gZ28gZnJvbSBydWJ5IFN0cmluZyB0byBVVEYtOCBieXRlcworCisjIFJ1biB0aGUgamF2YSBtYWdpYyBpbmNsdWRlIGFuZCBpbXBvcnQgYmFzaWMgSEJhc2UgdHlwZXMgdGhhdCB3aWxsIGhlbHAgZWFzZQorIyBoYmFzZSBoYWNraW5nLgoraW5jbHVkZSBKYXZhCisKKyMgU29tZSBnb29kaWVzIGZvciBoaXJiLiBTaG91bGQgdGhlc2UgYmUgbGVmdCB1cCB0byB0aGUgdXNlcidzIGRpc2NyZXRpb24/CityZXF1aXJlICdpcmIvY29tcGxldGlvbicKKworIyBBZGQgdGhlICRIQkFTRV9IT01FL2JpbiBkaXJlY3RvcnksIHRoZSBsb2NhdGlvbiBvZiB0aGlzIHNjcmlwdCwgdG8gdGhlIHJ1YnkKKyMgbG9hZCBwYXRoIHNvIEkgY2FuIGxvYWQgdXAgbXkgSEJhc2UgcnVieSBtb2R1bGVzCiskTE9BRF9QQVRILnVuc2hpZnQgRmlsZS5kaXJuYW1lKCRQUk9HUkFNX05BTUUpCisjIFJlcXVpcmUgZm9ybWF0dGVyIGFuZCBoYmFzZQorcmVxdWlyZSAnRm9ybWF0dGVyJworcmVxdWlyZSAnSEJhc2UnCisKKyMgU2VlIGlmIHRoZXJlIGFyZSBhcmdzIGZvciB0aGlzIHNoZWxsLiBJZiBhbnksIHJlYWQgYW5kIHRoZW4gc3RyaXAgZnJvbSBBUkdWCisjIHNvIHRoZXkgZG9uJ3QgZ28gdGhyb3VnaCB0byBpcmIuICBPdXRwdXQgc2hlbGwgJ3VzYWdlJyBpZiB1c2VyIHR5cGVzICctLWhlbHAnCitjbWRsaW5lX2hlbHAgPSA8PEhFUkUgIyBIRVJFIGRvY3VtZW50IG91dHB1dCBhcyBzaGVsbCB1c2FnZQorSEJhc2UgU2hlbGwgY29tbWFuZC1saW5lIG9wdGlvbnM6CisgZm9ybWF0ICAgICAgICBGb3JtYXR0ZXIgZm9yIG91dHB1dHRpbmcgcmVzdWx0czogY29uc29sZSB8IGh0bWwuIERlZmF1bHQ6IGNvbnNvbGUKKyBmb3JtYXQtd2lkdGggIFdpZHRoIG9mIHRhYmxlIG91dHB1dHMuIERlZmF1bHQ6IDExMCBjaGFyYWN0ZXJzLgorIG1hc3RlciAgICAgICAgSEJhc2UgbWFzdGVyIHNoZWxsIHNob3VsZCBjb25uZWN0IHRvOiBlLmcgLS1tYXN0ZXI9ZXhhbXBsZTo2MDAwMAorSEVSRQorbWFzdGVyID0gbmlsCitmb3VuZCA9IFtdCitmb3JtYXQgPSAnY29uc29sZScKK2Zvcm1hdF93aWR0aCA9IDExMAorZm9yIGFyZyBpbiBBUkdWCisgIGlmIGFyZyA9fiAvXi0tbWFzdGVyPSguKykvaQorICAgIG1hc3RlciA9ICQxCisgICAgZm91bmQucHVzaChhcmcpCisgIGVsc2lmIGFyZyA9fiAvXi0tZm9ybWF0PSguKykvaQorICAgIGZvcm1hdCA9ICQxCisgICAgaWYgZm9ybWF0ID1+IC9eaHRtbCQvaQorICAgICAgcmFpc2UgTm9NZXRob2RFcnJvci5uZXcoIk5vdCB5ZXQgaW1wbGVtZW50ZWQiKQorICAgIGVsc2lmIGZvcm1hdCA9fiAvXmNvbnNvbGUkL2kKKyAgICAgICMgVGhpcyBpcyBkZWZhdWx0CisgICAgZWxzZQorICAgICAgcmFpc2UgQXJndW1lbnRFcnJvci5uZXcoIlVuc3VwcG9ydGVkIGZvcm1hdCAiICsgYXJnKQorICAgIGVuZAorICAgIGZvdW5kLnB1c2goYXJnKQorICBlbHNpZiBhcmcgPX4gL14tLWZvcm1hdC13aWR0aD0oLispL2kKKyAgICBmb3JtYXRfd2lkdGggPSAkMS50b19pCisgICAgZm91bmQucHVzaChhcmcpCisgIGVsc2lmIGFyZyA9PSAnLWgnIHx8IGFyZyA9PSAnLS1oZWxwJworICAgIHB1dHMgY21kbGluZV9oZWxwCisgICAgZXhpdAorICBlbHNlCisgICAgIyBQcmVzdW1lIGl0IGEgc2NyaXB0IGFuZCB0cnkgcnVubmluZyBpdC4gIFdpbGwgZ28gb24gdG8gcnVuIHRoZSBzaGVsbCB1bmxlc3MKKyAgICAjIHNjcmlwdCBjYWxscyAnZXhpdCcgb3IgJ2V4aXQgMCcgb3IgJ2V4aXQgZXJyY29kZScuCisgICAgbG9hZChhcmcpCisgIGVuZAorZW5kCitmb3IgYXJnIGluIGZvdW5kCisgIEFSR1YuZGVsZXRlKGFyZykKK2VuZAorIyBQcmVzdW1lIGNvbnNvbGUgZm9ybWF0LgorQGZvcm1hdHRlciA9IEZvcm1hdHRlcjo6Q29uc29sZS5uZXcoU1RET1VULCBmb3JtYXRfd2lkdGgpCisjIFRPRE8sIGV0Yy4gIEBmb3JtYXR0ZXIgPSBGb3JtYXR0ZXI6OlhIVE1MLm5ldyhTVERPVVQpCisKKyMgU2V0dXAgdGhlIEhCYXNlIG1vZHVsZS4gIENyZWF0ZSBhIGNvbmZpZ3VyYXRpb24uICBJZiBhIG1hc3Rlciwgc2V0IGl0LgorIyBUdXJuIG9mZiByZXRyaWVzIGluIGhiYXNlIGFuZCBpcGMuICBIdW1hbiBkb2Vzbid0IHdhbnQgdG8gd2FpdCBvbiBOIHJldHJpZXMuCitAY29uZmlndXJhdGlvbiA9IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbi5uZXcoKQorQGNvbmZpZ3VyYXRpb24uc2V0KCJoYmFzZS5tYXN0ZXIiLCBtYXN0ZXIpIGlmIG1hc3RlcgorQGNvbmZpZ3VyYXRpb24uc2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCA1KQorQGNvbmZpZ3VyYXRpb24uc2V0SW50KCJpcGMuY2xpZW50LmNvbm5lY3QubWF4LnJldHJpZXMiLCAzKQorCisjIERvIGxhenkgY3JlYXRlIG9mIGFkbWluIGJlY2F1c2UgaWYgd2UgYXJlIHBvaW50ZWQgYXQgYmFkIG1hc3RlciwgaXQgd2lsbCBoYW5nCisjIHNoZWxsIG9uIHN0YXJ0dXAgdHJ5aW5nIHRvIGNvbm5lY3QuCitAYWRtaW4gPSBuaWwKKworIyBQcm9tb3RlIGhiYXNlIGNvbnN0YW50cyB0byBiZSBjb25zdGFudHMgb2YgdGhpcyBtb2R1bGUgc28gY2FuCisjIGJlIHVzZWQgYmFyZSBhcyBrZXlzIGluICdjcmVhdGUnLCAnYWx0ZXInLCBldGMuIFRvIHNlZSBjb25zdGFudHMKKyMgaW4gSVJCLCB0eXBlICdPYmplY3QuY29uc3RhbnRzJy4gRG9uJ3QgcHJvbW90ZSBkZWZhdWx0cyBiZWNhdXNlCisjIGZsYXR0ZW5zIGFsbCB0eXBlcyB0byBTdHJpbmcuICBDYW4gYmUgY29uZnVzaW5nLgorZGVmIHByb21vdGVDb25zdGFudHMoY29uc3RhbnRzKQorICAjIFRoZSBjb25zdGFudHMgdG8gaW1wb3J0IGFyZSBhbGwgaW4gdXBwZXJjYXNlCisgIGZvciBjIGluIGNvbnN0YW50cworICAgIGlmIGMgPT0gYy51cGNhc2UKKyAgICAgIGV2YWwoIiVzID0gXCIlc1wiIiAlIFtjLCBjXSkgdW5sZXNzIGMgPX4gL0RFRkFVTFRfLiovCisgICAgZW5kCisgIGVuZAorZW5kCitwcm9tb3RlQ29uc3RhbnRzKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yLmNvbnN0YW50cykKK3Byb21vdGVDb25zdGFudHMob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvci5jb25zdGFudHMpCitwcm9tb3RlQ29uc3RhbnRzKEhCYXNlLmNvbnN0YW50cykKKworIyBTdGFydCBvZiB0aGUgaGJhc2Ugc2hlbGwgY29tbWFuZHMuCisKKyMgR2VuZXJhbCBzaGVsbCBtZXRob2RzCisKK2RlZiB0b29scworICAjIEhlbHAgZm9yIGhiYXNlIHNoZWxsIHN1cmdlcnkgdG9vbHMKKyAgaCAgPSA8PEhFUkUKK0hCQVNFIFNVUkdFUlkgVE9PTFM6CisgY2xvc2VfcmVnaW9uICAgIENsb3NlIGEgc2luZ2xlIHJlZ2lvbi4gT3B0aW9uYWxseSBzcGVjaWZ5IHJlZ2lvbnNlcnZlci4KKyAgICAgICAgICAgICAgICAgRXhhbXBsZXM6CisgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICBoYmFzZT4gY2xvc2VfcmVnaW9uICdSRUdJT05OQU1FJworICAgICAgICAgICAgICAgICBoYmFzZT4gY2xvc2VfcmVnaW9uICdSRUdJT05OQU1FJywgJ1JFR0lPTlNFUlZFUl9JUDpQT1JUJworCisgY29tcGFjdCAgICAgICAgIENvbXBhY3QgYWxsIHJlZ2lvbnMgaW4gcGFzc2VkIHRhYmxlIG9yIHBhc3MgYSByZWdpb24gcm93CisgICAgICAgICAgICAgICAgIHRvIGNvbXBhY3QgYW4gaW5kaXZpZHVhbCByZWdpb24KKworIGRpc2FibGVfcmVnaW9uICBEaXNhYmxlIGEgc2luZ2xlIHJlZ2lvbgorCisgZW5hYmxlX3JlZ2lvbiAgIEVuYWJsZSBhIHNpbmdsZSByZWdpb24uIEZvciBleGFtcGxlOgorICAKKyAgICAgICAgICAgICAgICAgaGJhc2U+IGVuYWJsZV9yZWdpb24gJ1JFR0lPTk5BTUUnCisgCisgZmx1c2ggICAgICAgICAgIEZsdXNoIGFsbCByZWdpb25zIGluIHBhc3NlZCB0YWJsZSBvciBwYXNzIGEgcmVnaW9uIHJvdyB0bworICAgICAgICAgICAgICAgICBmbHVzaCBhbiBpbmRpdmlkdWFsIHJlZ2lvbi4gIEZvciBleGFtcGxlOgorCisgICAgICAgICAgICAgICAgIGhiYXNlPiBmbHVzaCAnVEFCTEVOQU1FJworICAgICAgICAgICAgICAgICBoYmFzZT4gZmx1c2ggJ1JFR0lPTk5BTUUnCisKKyBtYWpvcl9jb21wYWN0ICAgUnVuIG1ham9yIGNvbXBhY3Rpb24gb24gcGFzc2VkIHRhYmxlIG9yIHBhc3MgYSByZWdpb24gcm93CisgICAgICAgICAgICAgICAgIHRvIG1ham9yIGNvbXBhY3QgYW4gaW5kaXZpZHVhbCByZWdpb24KKworIHNwbGl0ICAgICAgICAgICBTcGxpdCB0YWJsZSBvciBwYXNzIGEgcmVnaW9uIHJvdyB0byBzcGxpdCBpbmRpdmlkdWFsIHJlZ2lvbgorCitBYm92ZSBjb21tYW5kcyBhcmUgZm9yICdleHBlcnRzJy1vbmx5IGFzIG1pc3VzZSBjYW4gZGFtYWdlIGFuIGluc3RhbGwKK0hFUkUKKyAgcHV0cyBoCitlbmQKKworZGVmIGhlbHAKKyAgIyBPdXRwdXQgaGVscC4gIEhlbHAgdXNlZCB0byBiZSBhIGRpY3Rpb25hcnkgb2YgbmFtZSB0byBzaG9ydCBhbmQgbG9uZworICAjIGRlc2NyaXB0aW9ucyBlbWl0dGVkIHVzaW5nIEZvcm1hdHRlcnMgYnV0IGF3a3dhcmQgZ2V0dGluZyBpdCB0byBzaG93CisgICMgbmljZWx5IG9uIGNvbnNvbGU7IGluc3RlYWQgdXNlIGEgSEVSRSBkb2N1bWVudC4gIE1lYW5zIHdlIGNhbid0CisgICMgb3V0cHV0IGhlbHAgb3RoZXIgdGhhbiBvbiBjb25zb2xlIGJ1dCBub3QgYW4gaXNzdWUgYXQgdGhlIG1vbWVudC4KKyAgIyBUT0RPOiBBZGQgaGVscCB0byB0aGUgY29tbWFuZHMgdGhlbXNlbHZlcyByYXRoZXIgdGhhbiBrZWVwIGl0IGRpc3RpbmN0CisgIGggID0gPDxIRVJFCitIQkFTRSBTSEVMTCBDT01NQU5EUzoKKyBhbHRlciAgICAgQWx0ZXIgY29sdW1uIGZhbWlseSBzY2hlbWE7ICBwYXNzIHRhYmxlIG5hbWUgYW5kIGEgZGljdGlvbmFyeQorICAgICAgICAgICBzcGVjaWZ5aW5nIG5ldyBjb2x1bW4gZmFtaWx5IHNjaGVtYS4gRGljdGlvbmFyaWVzIGFyZSBkZXNjcmliZWQKKyAgICAgICAgICAgYmVsb3cgaW4gdGhlIEdFTkVSQUwgTk9URVMgc2VjdGlvbi4gIERpY3Rpb25hcnkgbXVzdCBpbmNsdWRlIG5hbWUKKyAgICAgICAgICAgb2YgY29sdW1uIGZhbWlseSB0byBhbHRlci4gIEZvciBleGFtcGxlLCAKKyAgICAgICAgICAgCisgICAgICAgICAgIFRvIGNoYW5nZSBvciBhZGQgdGhlICdmMScgY29sdW1uIGZhbWlseSBpbiB0YWJsZSAndDEnIGZyb20gZGVmYXVsdHMKKyAgICAgICAgICAgdG8gaW5zdGVhZCBrZWVwIGEgbWF4aW11bSBvZiA1IGNlbGwgVkVSU0lPTlMsIGRvOgorICAgICAgICAgICBoYmFzZT4gYWx0ZXIgJ3QxJywge05BTUUgPT4gJ2YxJywgVkVSU0lPTlMgPT4gNX0KKyAgICAgICAgICAgCisgICAgICAgICAgIFRvIGRlbGV0ZSB0aGUgJ2YxJyBjb2x1bW4gZmFtaWx5IGluIHRhYmxlICd0MScsIGRvOgorICAgICAgICAgICBoYmFzZT4gYWx0ZXIgJ3QxJywge05BTUUgPT4gJ2YxJywgTUVUSE9EID0+ICdkZWxldGUnfQorCisgICAgICAgICAgIFlvdSBjYW4gYWxzbyBjaGFuZ2UgdGFibGUtc2NvcGUgYXR0cmlidXRlcyBsaWtlIE1BWF9GSUxFU0laRQorICAgICAgICAgICBNRU1DQUNIRV9GTFVTSFNJWkUgYW5kIFJFQURPTkxZLgorCisgICAgICAgICAgIEZvciBleGFtcGxlLCB0byBjaGFuZ2UgdGhlIG1heCBzaXplIG9mIGEgZmFtaWx5IHRvIDEyOE1CLCBkbzoKKyAgICAgICAgICAgaGJhc2U+IGFsdGVyICd0MScsIHtNRVRIT0QgPT4gJ3RhYmxlX2F0dCcsIE1BWF9GSUxFU0laRSA9PiAnMTM0MjE3NzI4J30KKyAgICAgICAgICAgCisgY291bnQgICAgIENvdW50IHRoZSBudW1iZXIgb2Ygcm93cyBpbiBhIHRhYmxlLiBUaGlzIG9wZXJhdGlvbiBtYXkgdGFrZSBhIExPTkcKKyAgICAgICAgICAgdGltZSAoUnVuICckSEFET09QX0hPTUUvYmluL2hhZG9vcCBqYXIgaGJhc2UuamFyIHJvd2NvdW50JyB0byBydW4gYQorICAgICAgICAgICBjb3VudGluZyBtYXByZWR1Y2Ugam9iKS4gQ3VycmVudCBjb3VudCBpcyBzaG93biBldmVyeSAxMDAwIHJvd3MgYnkKKyAgICAgICAgICAgZGVmYXVsdC4gQ291bnQgaW50ZXJ2YWwgbWF5IGJlIG9wdGlvbmFsbHkgc3BlY2lmaWVkLiBFeGFtcGxlczoKKyAgICAgICAgICAgCisgICAgICAgICAgIGhiYXNlPiBjb3VudCAndDEnCisgICAgICAgICAgIGhiYXNlPiBjb3VudCAndDEnLCAxMDAwMDAKKworIGNyZWF0ZSAgICBDcmVhdGUgdGFibGU7IHBhc3MgdGFibGUgbmFtZSwgYSBkaWN0aW9uYXJ5IG9mIHNwZWNpZmljYXRpb25zIHBlcgorICAgICAgICAgICBjb2x1bW4gZmFtaWx5LCBhbmQgb3B0aW9uYWxseSBhIGRpY3Rpb25hcnkgb2YgdGFibGUgY29uZmlndXJhdGlvbi4KKyAgICAgICAgICAgRGljdGlvbmFyaWVzIGFyZSBkZXNjcmliZWQgYmVsb3cgaW4gdGhlIEdFTkVSQUwgTk9URVMgc2VjdGlvbi4KKyAgICAgICAgICAgRXhhbXBsZXM6CisKKyAgICAgICAgICAgaGJhc2U+IGNyZWF0ZSAndDEnLCB7TkFNRSA9PiAnZjEnLCBWRVJTSU9OUyA9PiA1fQorICAgICAgICAgICBoYmFzZT4gY3JlYXRlICd0MScsIHtOQU1FID0+ICdmMSd9LCB7TkFNRSA9PiAnZjInfSwge05BTUUgPT4gJ2YzJ30KKyAgICAgICAgICAgaGJhc2U+ICMgVGhlIGFib3ZlIGluIHNob3J0aGFuZCB3b3VsZCBiZSB0aGUgZm9sbG93aW5nOgorICAgICAgICAgICBoYmFzZT4gY3JlYXRlICd0MScsICdmMScsICdmMicsICdmMycKKyAgICAgICAgICAgaGJhc2U+IGNyZWF0ZSAndDEnLCB7TkFNRSA9PiAnZjEnLCBWRVJTSU9OUyA9PiAxLCBUVEwgPT4gMjU5MjAwMCwgXFwKKyAgICAgICAgICAgICBCTE9DS0NBQ0hFID0+IHRydWV9CisKKyBkZXNjcmliZSAgRGVzY3JpYmUgdGhlIG5hbWVkIHRhYmxlOiBlLmcuICJoYmFzZT4gZGVzY3JpYmUgJ3QxJyIKKworIGRlbGV0ZSAgICBQdXQgYSBkZWxldGUgY2VsbCB2YWx1ZSBhdCBzcGVjaWZpZWQgdGFibGUvcm93L2NvbHVtbiBhbmQgb3B0aW9uYWxseQorICAgICAgICAgICB0aW1lc3RhbXAgY29vcmRpbmF0ZXMuICBEZWxldGVzIG11c3QgbWF0Y2ggdGhlIGRlbGV0ZWQgY2VsbCdzCisgICAgICAgICAgIGNvb3JkaW5hdGVzIGV4YWN0bHkuICBXaGVuIHNjYW5uaW5nLCBhIGRlbGV0ZSBjZWxsIHN1cHByZXNzZXMgb2xkZXIKKyAgICAgICAgICAgdmVyc2lvbnMuIFRha2VzIGFyZ3VtZW50cyBsaWtlIHRoZSAncHV0JyBjb21tYW5kIGRlc2NyaWJlZCBiZWxvdworIAorIGRlbGV0ZWFsbCBEZWxldGUgYWxsIGNlbGxzIGluIGEgZ2l2ZW4gcm93OyBwYXNzIGEgdGFibGUgbmFtZSwgcm93LCBhbmQgb3B0aW9uYWxseSAKKyAgICAgICAgICAgYSBjb2x1bW4gYW5kIHRpbWVzdGFtcAorCisgZGlzYWJsZSAgIERpc2FibGUgdGhlIG5hbWVkIHRhYmxlOiBlLmcuICJoYmFzZT4gZGlzYWJsZSAndDEnIgorIAorIGRyb3AgICAgICBEcm9wIHRoZSBuYW1lZCB0YWJsZS4gVGFibGUgbXVzdCBmaXJzdCBiZSBkaXNhYmxlZC4gSWYgdGFibGUgaGFzCisgICAgICAgICAgIG1vcmUgdGhhbiBvbmUgcmVnaW9uLCBydW4gYSBtYWpvciBjb21wYWN0aW9uIG9uIC5NRVRBLjoKKworICAgICAgICAgICBoYmFzZT4gbWFqb3JfY29tcGFjdCAiLk1FVEEuIgorCisgZW5hYmxlICAgIEVuYWJsZSB0aGUgbmFtZWQgdGFibGUKKworIGV4aXN0cyAgICBEb2VzIHRoZSBuYW1lZCB0YWJsZSBleGlzdD8gZS5nLiAiaGJhc2U+IGV4aXN0cyAndDEnIgorCisgZXhpdCAgICAgIFR5cGUgImhiYXNlPiBleGl0IiB0byBsZWF2ZSB0aGUgSEJhc2UgU2hlbGwKKworIGdldCAgICAgICBHZXQgcm93IG9yIGNlbGwgY29udGVudHM7IHBhc3MgdGFibGUgbmFtZSwgcm93LCBhbmQgb3B0aW9uYWxseQorICAgICAgICAgICBhIGRpY3Rpb25hcnkgb2YgY29sdW1uKHMpLCB0aW1lc3RhbXAgYW5kIHZlcnNpb25zLiAgRXhhbXBsZXM6CisKKyAgICAgICAgICAgaGJhc2U+IGdldCAndDEnLCAncjEnCisgICAgICAgICAgIGhiYXNlPiBnZXQgJ3QxJywgJ3IxJywge0NPTFVNTiA9PiAnYzEnfQorICAgICAgICAgICBoYmFzZT4gZ2V0ICd0MScsICdyMScsIHtDT0xVTU4gPT4gWydjMScsICdjMicsICdjMyddfQorICAgICAgICAgICBoYmFzZT4gZ2V0ICd0MScsICdyMScsIHtDT0xVTU4gPT4gJ2MxJywgVElNRVNUQU1QID0+IHRzMX0KKyAgICAgICAgICAgaGJhc2U+IGdldCAndDEnLCAncjEnLCB7Q09MVU1OID0+ICdjMScsIFRJTUVTVEFNUCA9PiB0czEsIFxcCisgICAgICAgICAgICAgVkVSU0lPTlMgPT4gNH0KKworIGxpc3QgICAgICBMaXN0IGFsbCB0YWJsZXMgaW4gaGJhc2UKKworIHB1dCAgICAgICBQdXQgYSBjZWxsICd2YWx1ZScgYXQgc3BlY2lmaWVkIHRhYmxlL3Jvdy9jb2x1bW4gYW5kIG9wdGlvbmFsbHkKKyAgICAgICAgICAgdGltZXN0YW1wIGNvb3JkaW5hdGVzLiAgVG8gcHV0IGEgY2VsbCB2YWx1ZSBpbnRvIHRhYmxlICd0MScgYXQKKyAgICAgICAgICAgcm93ICdyMScgdW5kZXIgY29sdW1uICdjMScgbWFya2VkIHdpdGggdGhlIHRpbWUgJ3RzMScsIGRvOgorCisgICAgICAgICAgIGhiYXNlPiBwdXQgJ3QxJywgJ3IxJywgJ2MxJywgJ3ZhbHVlJywgdHMxCisKKyB0b29scyAgICAgTGlzdGluZyBvZiBoYmFzZSBzdXJnZXJ5IHRvb2xzCisKKyBzY2FuICAgICAgU2NhbiBhIHRhYmxlOyBwYXNzIHRhYmxlIG5hbWUgYW5kIG9wdGlvbmFsbHkgYSBkaWN0aW9uYXJ5IG9mIHNjYW5uZXIgCisgICAgICAgICAgIHNwZWNpZmljYXRpb25zLiAgU2Nhbm5lciBzcGVjaWZpY2F0aW9ucyBtYXkgaW5jbHVkZSBvbmUgb3IgbW9yZSBvZiAKKyAgICAgICAgICAgdGhlIGZvbGxvd2luZzogTElNSVQsIFNUQVJUUk9XLCBTVE9QUk9XLCBUSU1FU1RBTVAsIG9yIENPTFVNTlMuICBJZiAKKyAgICAgICAgICAgbm8gY29sdW1ucyBhcmUgc3BlY2lmaWVkLCBhbGwgY29sdW1ucyB3aWxsIGJlIHNjYW5uZWQuICBUbyBzY2FuIGFsbCAKKyAgICAgICAgICAgbWVtYmVycyBvZiBhIGNvbHVtbiBmYW1pbHksIGxlYXZlIHRoZSBxdWFsaWZpZXIgZW1wdHkgYXMgaW4gCisgICAgICAgICAgICdjb2xfZmFtaWx5OicuICBFeGFtcGxlczoKKyAgICAgICAgICAgCisgICAgICAgICAgIGhiYXNlPiBzY2FuICcuTUVUQS4nCisgICAgICAgICAgIGhiYXNlPiBzY2FuICcuTUVUQS4nLCB7Q09MVU1OUyA9PiAnaW5mbzpyZWdpb25pbmZvJ30KKyAgICAgICAgICAgaGJhc2U+IHNjYW4gJ3QxJywge0NPTFVNTlMgPT4gWydjMScsICdjMiddLCBMSU1JVCA9PiAxMCwgXFwKKyAgICAgICAgICAgICBTVEFSVFJPVyA9PiAneHl6J30KKworIHNodXRkb3duICBTaHV0IGRvd24gdGhlIGNsdXN0ZXIuCisKKyB0cnVuY2F0ZSAgRGlzYWJsZXMsIGRyb3BzIGFuZCByZWNyZWF0ZXMgdGhlIHNwZWNpZmllZCB0YWJsZS4KKyAgICAgICAgICAgCisgdmVyc2lvbiAgIE91dHB1dCB0aGlzIEhCYXNlIHZlcnNpb24KKworR0VORVJBTCBOT1RFUzoKK1F1b3RlIGFsbCBuYW1lcyBpbiB0aGUgaGJhc2Ugc2hlbGwgc3VjaCBhcyB0YWJsZSBhbmQgY29sdW1uIG5hbWVzLiAgRG9uJ3QKK2ZvcmdldCBjb21tYXMgZGVsaW1pdCBjb21tYW5kIHBhcmFtZXRlcnMuICBUeXBlIDxSRVRVUk4+IGFmdGVyIGVudGVyaW5nIGEKK2NvbW1hbmQgdG8gcnVuIGl0LiAgRGljdGlvbmFyaWVzIG9mIGNvbmZpZ3VyYXRpb24gdXNlZCBpbiB0aGUgY3JlYXRpb24gYW5kCithbHRlcmF0aW9uIG9mIHRhYmxlcyBhcmUgcnVieSBIYXNoZXMuIFRoZXkgbG9vayBsaWtlIHRoaXM6CisKKyAgeydrZXkxJyA9PiAndmFsdWUxJywgJ2tleTInID0+ICd2YWx1ZTInLCAuLi59CisKK1RoZXkgYXJlIG9wZW5lZCBhbmQgY2xvc2VkIHdpdGggY3VybGV5LWJyYWNlcy4gIEtleS92YWx1ZXMgYXJlIGRlbGltaXRlZCBieQordGhlICc9PicgY2hhcmFjdGVyIGNvbWJpbmF0aW9uLiAgVXN1YWxseSBrZXlzIGFyZSBwcmVkZWZpbmVkIGNvbnN0YW50cyBzdWNoIGFzCitOQU1FLCBWRVJTSU9OUywgQ09NUFJFU1NJT04sIGV0Yy4gIENvbnN0YW50cyBkbyBub3QgbmVlZCB0byBiZSBxdW90ZWQuICBUeXBlCisnT2JqZWN0LmNvbnN0YW50cycgdG8gc2VlIGEgKG1lc3N5KSBsaXN0IG9mIGFsbCBjb25zdGFudHMgaW4gdGhlIGVudmlyb25tZW50LgorCitUaGlzIEhCYXNlIHNoZWxsIGlzIHRoZSBKUnVieSBJUkIgd2l0aCB0aGUgYWJvdmUgSEJhc2Utc3BlY2lmaWMgY29tbWFuZHMgYWRkZWQuCitGb3IgbW9yZSBvbiB0aGUgSEJhc2UgU2hlbGwsIHNlZSBodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZS9TaGVsbAorSEVSRQorICBwdXRzIGgKK2VuZAorCitkZWYgdmVyc2lvbgorICAjIE91dHB1dCB2ZXJzaW9uLgorICBwdXRzICJWZXJzaW9uOiAje29yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuVmVyc2lvbkluZm8uZ2V0VmVyc2lvbigpfSxcCisgciN7b3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5WZXJzaW9uSW5mby5nZXRSZXZpc2lvbigpfSxcCisgI3tvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlZlcnNpb25JbmZvLmdldERhdGUoKX0iCitlbmQKKworZGVmIHNodXRkb3duCisgIGFkbWluKCkuc2h1dGRvd24oKQorZW5kIAorCisjIERETAorCitkZWYgYWRtaW4oKQorICBAYWRtaW4gPSBIQmFzZTo6QWRtaW4ubmV3KEBjb25maWd1cmF0aW9uLCBAZm9ybWF0dGVyKSB1bmxlc3MgQGFkbWluCisgIEBhZG1pbgorZW5kCisKK2RlZiB0YWJsZSh0YWJsZSkKKyAgIyBDcmVhdGUgbmV3IG9uZSBlYWNoIHRpbWUKKyAgSEJhc2U6OlRhYmxlLm5ldyhAY29uZmlndXJhdGlvbiwgdGFibGUsIEBmb3JtYXR0ZXIpCitlbmQKKworZGVmIGNyZWF0ZSh0YWJsZSwgKmFyZ3MpCisgIGFkbWluKCkuY3JlYXRlKHRhYmxlLCBhcmdzKQorZW5kCisKK2RlZiBkcm9wKHRhYmxlKQorICBhZG1pbigpLmRyb3AodGFibGUpCitlbmQKKworZGVmIGFsdGVyKHRhYmxlLCBhcmdzKQorICBhZG1pbigpLmFsdGVyKHRhYmxlLCBhcmdzKSAKK2VuZAorCisjIEFkbWluaXN0cmF0aW9uCisKK2RlZiBsaXN0CisgIGFkbWluKCkubGlzdCgpCitlbmQKKworZGVmIGRlc2NyaWJlKHRhYmxlKQorICBhZG1pbigpLmRlc2NyaWJlKHRhYmxlKQorZW5kCisgIAorZGVmIGVuYWJsZSh0YWJsZSkKKyAgYWRtaW4oKS5lbmFibGUodGFibGUpCitlbmQKKworZGVmIGRpc2FibGUodGFibGUpCisgIGFkbWluKCkuZGlzYWJsZSh0YWJsZSkKK2VuZAorCitkZWYgZW5hYmxlX3JlZ2lvbihyZWdpb25OYW1lKQorICBhZG1pbigpLmVuYWJsZV9yZWdpb24ocmVnaW9uTmFtZSkKK2VuZAorCitkZWYgZGlzYWJsZV9yZWdpb24ocmVnaW9uTmFtZSkKKyAgYWRtaW4oKS5kaXNhYmxlX3JlZ2lvbihyZWdpb25OYW1lKQorZW5kCisKK2RlZiBleGlzdHModGFibGUpCisgIGFkbWluKCkuZXhpc3RzKHRhYmxlKQorZW5kCisKK2RlZiB0cnVuY2F0ZSh0YWJsZSkKKyAgYWRtaW4oKS50cnVuY2F0ZSh0YWJsZSkKK2VuZAorCitkZWYgY2xvc2VfcmVnaW9uKHJlZ2lvbk5hbWUsIHNlcnZlciA9IG5pbCkKKyAgYWRtaW4oKS5jbG9zZV9yZWdpb24ocmVnaW9uTmFtZSwgc2VydmVyKQorZW5kCisgIAorIyBDUlVECisgIAorZGVmIGdldCh0YWJsZSwgcm93LCBhcmdzID0ge30pCisgIHRhYmxlKHRhYmxlKS5nZXQocm93LCBhcmdzKQorZW5kCisKK2RlZiBwdXQodGFibGUsIHJvdywgY29sdW1uLCB2YWx1ZSwgdGltZXN0YW1wID0gbmlsKQorICB0YWJsZSh0YWJsZSkucHV0KHJvdywgY29sdW1uLCB2YWx1ZSwgdGltZXN0YW1wKQorZW5kCisgIAorZGVmIHNjYW4odGFibGUsIGFyZ3MgPSB7fSkKKyAgdGFibGUodGFibGUpLnNjYW4oYXJncykKK2VuZAorICAKK2RlZiBkZWxldGUodGFibGUsIHJvdywgY29sdW1uLAorICAgIHRpbWVzdGFtcCA9IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM6OkxBVEVTVF9USU1FU1RBTVApCisgIHRhYmxlKHRhYmxlKS5kZWxldGUocm93LCBjb2x1bW4sIHRpbWVzdGFtcCkKK2VuZAorCitkZWYgZGVsZXRlYWxsKHRhYmxlLCByb3csIGNvbHVtbiA9IG5pbCwKKyAgICB0aW1lc3RhbXAgPSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOjpMQVRFU1RfVElNRVNUQU1QKQorICB0YWJsZSh0YWJsZSkuZGVsZXRlYWxsKHJvdywgY29sdW1uLCB0aW1lc3RhbXApCitlbmQKKworZGVmIGNvdW50KHRhYmxlLCBpbnRlcnZhbCA9IDEwMDApCisgIHRhYmxlKHRhYmxlKS5jb3VudChpbnRlcnZhbCkKK2VuZAorCitkZWYgZmx1c2godGFibGVOYW1lT3JSZWdpb25OYW1lKQorICBhZG1pbigpLmZsdXNoKHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkKK2VuZAorCitkZWYgY29tcGFjdCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgIGFkbWluKCkuY29tcGFjdCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCitlbmQKKworZGVmIG1ham9yX2NvbXBhY3QodGFibGVOYW1lT3JSZWdpb25OYW1lKQorICBhZG1pbigpLm1ham9yX2NvbXBhY3QodGFibGVOYW1lT3JSZWdpb25OYW1lKQorZW5kCisKK2RlZiBzcGxpdCh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgIGFkbWluKCkuc3BsaXQodGFibGVOYW1lT3JSZWdpb25OYW1lKQorZW5kCisKKyMgT3V0cHV0IGEgYmFubmVyIG1lc3NhZ2UgdGhhdCB0ZWxscyB1c2VycyB3aGVyZSB0byBnbyBmb3IgaGVscAorcHV0cyA8PEhFUkUKK0hCYXNlIFNoZWxsOyBlbnRlciAnaGVscDxSRVRVUk4+JyBmb3IgbGlzdCBvZiBzdXBwb3J0ZWQgY29tbWFuZHMuCitIRVJFCit2ZXJzaW9uCisKK3JlcXVpcmUgImlyYiIKKworbW9kdWxlIElSQgorICAjIFN1YmNsYXNzIG9mIElSQiBzbyBjYW4gaW50ZXJjZXB0IG1ldGhvZHMKKyAgY2xhc3MgSElSQiA8IElyYgorICAgIGRlZiBpbml0aWFsaXplCisgICAgICAjIFRoaXMgaXMgdWdseS4gIE91ciAnaGVscCcgbWV0aG9kIGFib3ZlIHByb3Zva2VzIHRoZSBmb2xsb3dpbmcgbWVzc2FnZQorICAgICAgIyBvbiBpcmIgY29uc3RydWN0aW9uOiAnaXJiOiB3YXJuOiBjYW4ndCBhbGlhcyBoZWxwIGZyb20gaXJiX2hlbHAuJworICAgICAgIyBCZWxvdywgd2UgcmVzZXQgdGhlIG91dHB1dCBzbyBpdHMgcG9pbnRlZCBhdCAvZGV2L251bGwgZHVyaW5nIGlyYgorICAgICAgIyBjb25zdHJ1Y3Rpb24ganVzdCBzbyB0aGlzIG1lc3NhZ2UgZG9lcyBub3QgY29tZSBvdXQgYWZ0ZXIgd2UgZW1pdAorICAgICAgIyB0aGUgYmFubmVyLiAgT3RoZXIgYXR0ZW1wdHMgYXQgcGxheWluZyB3aXRoIHRoZSBoYXNoIG9mIG1ldGhvZHMKKyAgICAgICMgZG93biBpbiBJUkIgZGlkbid0IHNlZW0gdG8gd29yay4gSSB0aGluayB0aGUgd29yc3QgdGhpbmcgdGhhdCBjYW4KKyAgICAgICMgaGFwcGVuIGlzIHRoZSBzaGVsbCBleGl0aW5nIGJlY2F1c2Ugb2YgZmFpbGVkIElSQiBjb25zdHJ1Y3Rpb24gd2l0aAorICAgICAgIyBubyBlcnJvciAodGhvdWdoIHdlJ3JlIG5vdCBibGFua2luZyBTVERFUlIpCisgICAgICBiZWdpbgorICAgICAgICBmID0gRmlsZS5vcGVuKCIvZGV2L251bGwiLCAidyIpCisgICAgICAgICRzdGRvdXQgPSBmCisgICAgICAgIHN1cGVyCisgICAgICBlbnN1cmUKKyAgICAgICAgZi5jbG9zZSgpCisgICAgICAgICRzdGRvdXQgPSBTVERPVVQKKyAgICAgIGVuZAorICAgIGVuZCAKKyAgICAKKyAgICBkZWYgb3V0cHV0X3ZhbHVlCisgICAgICAjIFN1cHByZXNzIG91dHB1dCBpZiBsYXN0X3ZhbHVlIGlzICduaWwnCisgICAgICAjIE90aGVyd2lzZSwgd2hlbiB1c2VyIHR5cGVzIGhlbHAsIGdldCB1Z2x5ICduaWwnCisgICAgICAjIGFmdGVyIGFsbCBvdXRwdXQuCisgICAgICBpZiBAY29udGV4dC5sYXN0X3ZhbHVlICE9IG5pbAorICAgICAgICBzdXBlcgorICAgICAgZW5kCisgICAgZW5kCisgIGVuZAorCisgIGRlZiBJUkIuc3RhcnQoYXBfcGF0aCA9IG5pbCkKKyAgICAkMCA9IEZpbGU6OmJhc2VuYW1lKGFwX3BhdGgsICIucmIiKSBpZiBhcF9wYXRoCisKKyAgICBJUkIuc2V0dXAoYXBfcGF0aCkKKyAgICBAQ09ORls6SVJCX05BTUVdID0gJ2hiYXNlJworICAgIEBDT05GWzpBUF9OQU1FXSA9ICdoYmFzZScKKyAgICAKKyAgICBpZiBAQ09ORls6U0NSSVBUXQorICAgICAgaGlyYiA9IEhJUkIubmV3KG5pbCwgQENPTkZbOlNDUklQVF0pCisgICAgZWxzZQorICAgICAgaGlyYiA9IEhJUkIubmV3CisgICAgZW5kCisKKyAgICBAQ09ORls6SVJCX1JDXS5jYWxsKGhpcmIuY29udGV4dCkgaWYgQENPTkZbOklSQl9SQ10KKyAgICBAQ09ORls6TUFJTl9DT05URVhUXSA9IGhpcmIuY29udGV4dAorCisgICAgY2F0Y2goOklSQl9FWElUKSBkbworICAgICAgaGlyYi5ldmFsX2lucHV0CisgICAgZW5kCisgIGVuZAorZW5kCisKK0lSQi5zdGFydApkaWZmIC0tZ2l0IGEvYmluL3JlZ2lvbnNlcnZlcnMuc2ggYi9iaW4vcmVnaW9uc2VydmVycy5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5iODhhZDQ1Ci0tLSAvZGV2L251bGwKKysrIGIvYmluL3JlZ2lvbnNlcnZlcnMuc2gKQEAgLTAsMCArMSw3NCBAQAorIyEvdXNyL2Jpbi9lbnYgYmFzaAorIworIy8qKgorIyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorIyAqCisjICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorIyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisjICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorIyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisjICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIyAqCisjICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIyAqCisjICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIyAqLworIyAKKyMgUnVuIGEgc2hlbGwgY29tbWFuZCBvbiBhbGwgcmVnaW9uc2VydmVyIGhvc3RzLgorIworIyBFbnZpcm9ubWVudCBWYXJpYWJsZXMKKyMKKyMgICBIQkFTRV9SRUdJT05TRVJWRVJTICAgIEZpbGUgbmFtaW5nIHJlbW90ZSBob3N0cy4KKyMgICAgIERlZmF1bHQgaXMgJHtIQURPT1BfQ09ORl9ESVJ9L3JlZ2lvbnNlcnZlcnMKKyMgICBIQURPT1BfQ09ORl9ESVIgIEFsdGVybmF0ZSBjb25mIGRpci4gRGVmYXVsdCBpcyAke0hBRE9PUF9IT01FfS9jb25mLgorIyAgIEhCQVNFX0NPTkZfRElSICBBbHRlcm5hdGUgaGJhc2UgY29uZiBkaXIuIERlZmF1bHQgaXMgJHtIQkFTRV9IT01FfS9jb25mLgorIyAgIEhBRE9PUF9TTEFWRV9TTEVFUCBTZWNvbmRzIHRvIHNsZWVwIGJldHdlZW4gc3Bhd25pbmcgcmVtb3RlIGNvbW1hbmRzLgorIyAgIEhBRE9PUF9TU0hfT1BUUyBPcHRpb25zIHBhc3NlZCB0byBzc2ggd2hlbiBydW5uaW5nIHJlbW90ZSBjb21tYW5kcy4KKyMKKyMgTW9kZWxsZWQgYWZ0ZXIgJEhBRE9PUF9IT01FL2Jpbi9zbGF2ZXMuc2guCisKK3VzYWdlPSJVc2FnZTogcmVnaW9uc2VydmVycyBbLS1jb25maWcgPGhiYXNlLWNvbmZkaXI+XSBjb21tYW5kLi4uIgorCisjIGlmIG5vIGFyZ3Mgc3BlY2lmaWVkLCBzaG93IHVzYWdlCitpZiBbICQjIC1sZSAwIF07IHRoZW4KKyAgZWNobyAkdXNhZ2UKKyAgZXhpdCAxCitmaQorCitiaW49YGRpcm5hbWUgIiQwImAKK2Jpbj1gY2QgIiRiaW4iOyBwd2RgCisKKy4gIiRiaW4iL2hiYXNlLWNvbmZpZy5zaAorCisjIElmIHRoZSByZWdpb25zZXJ2ZXJzIGZpbGUgaXMgc3BlY2lmaWVkIGluIHRoZSBjb21tYW5kIGxpbmUsCisjIHRoZW4gaXQgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBkZWZpbml0aW9uIGluIAorIyBoYmFzZS1lbnYuc2guIFNhdmUgaXQgaGVyZS4KK0hPU1RMSVNUPSRIQkFTRV9SRUdJT05TRVJWRVJTCisKK2lmIFsgLWYgIiR7SEJBU0VfQ09ORl9ESVJ9L2hiYXNlLWVudi5zaCIgXTsgdGhlbgorICAuICIke0hCQVNFX0NPTkZfRElSfS9oYmFzZS1lbnYuc2giCitmaQorCitpZiBbICIkSE9TVExJU1QiID0gIiIgXTsgdGhlbgorICBpZiBbICIkSEJBU0VfUkVHSU9OU0VSVkVSUyIgPSAiIiBdOyB0aGVuCisgICAgZXhwb3J0IEhPU1RMSVNUPSIke0hCQVNFX0NPTkZfRElSfS9yZWdpb25zZXJ2ZXJzIgorICBlbHNlCisgICAgZXhwb3J0IEhPU1RMSVNUPSIke0hCQVNFX1JFR0lPTlNFUlZFUlN9IgorICBmaQorZmkKKworZm9yIHJlZ2lvbnNlcnZlciBpbiBgY2F0ICIkSE9TVExJU1QiYDsgZG8KKyBzc2ggJEhCQVNFX1NTSF9PUFRTICRyZWdpb25zZXJ2ZXIgJCIke0AvLyAvXFwgfSIgXAorICAgMj4mMSB8IHNlZCAicy9eLyRyZWdpb25zZXJ2ZXI6IC8iICYKKyBpZiBbICIkSEJBU0VfU0xBVkVfU0xFRVAiICE9ICIiIF07IHRoZW4KKyAgIHNsZWVwICRIQkFTRV9TTEFWRV9TTEVFUAorIGZpCitkb25lCisKK3dhaXQKZGlmZiAtLWdpdCBhL2Jpbi9yZW5hbWVfdGFibGUucmIgYi9iaW4vcmVuYW1lX3RhYmxlLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmNDY4YWEKLS0tIC9kZXYvbnVsbAorKysgYi9iaW4vcmVuYW1lX3RhYmxlLnJiCkBAIC0wLDAgKzEsMTU0IEBACisjIFNjcmlwdCB0aGF0IHJlbmFtZXMgdGFibGUgaW4gaGJhc2UuICBBcyB3cml0dGVuLCB3aWxsIG5vdCB3b3JrIGZvciByYXJlCisjIGNhc2Ugd2hlcmUgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSByZWdpb24gaW4gLk1FVEEuIHRhYmxlLiAgRG9lcyB0aGUKKyMgdXBkYXRlIG9mIHRoZSBoYmFzZSAuTUVUQS4gYW5kIG1vdmVzIHRoZSBkaXJlY3RvcmllcyBpbiBmaWxlc3lzdGVtLiAgCisjIEhCYXNlIE1VU1QgYmUgc2h1dGRvd24gd2hlbiB5b3UgcnVuIHRoaXMgc2NyaXB0LiAgT24gc3VjY2Vzc2Z1bCByZW5hbWUsCisjIERPRVMgTk9UIHJlbW92ZSBvbGQgZGlyZWN0b3J5IGZyb20gZmlsZXN5c3RlbSBiZWNhdXNlIHdhcyBhZnJhaWQgdGhpcworIyBzY3JpcHQgY291bGQgcmVtb3ZlIHRoZSBvcmlnaW5hbCB0YWJsZSBvbiBlcnJvci4KKyMKKyMgVG8gc2VlIHVzYWdlIGZvciB0aGlzIHNjcmlwdCwgcnVuOiAKKyMKKyMgICR7SEJBU0VfSE9NRX0vYmluL2hiYXNlIG9yZy5qcnVieS5NYWluIHJlbmFtZV90YWJsZS5yYgorIworaW5jbHVkZSBKYXZhCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5NZXRhVXRpbHMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkZTVXRpbHMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXMKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFN0b3JlS2V5CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm8KK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZQoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5ITG9nRWRpdAoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aAoraW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW0KK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2cKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXAKKworIyBOYW1lIG9mIHRoaXMgc2NyaXB0CitOQU1FID0gInJlbmFtZV90YWJsZSIKKworIyBQcmludCB1c2FnZSBmb3IgdGhpcyBzY3JpcHQKK2RlZiB1c2FnZQorICBwdXRzICdVc2FnZTogJXMucmIgPE9MRF9OQU1FPiA8TkVXX05BTUU+JyAlIE5BTUUKKyAgZXhpdCEKK2VuZAorCisjIFBhc3NlZCAnZGlyJyBleGlzdHMgYW5kIGlzIGEgZGlyZWN0b3J5IGVsc2UgZXhjZXB0aW9uCitkZWYgaXNEaXJFeGlzdHMoZnMsIGRpcikKKyAgcmFpc2UgSU9FcnJvci5uZXcoIkRvZXMgbm90IGV4aXQ6ICIgKyBkaXIudG9TdHJpbmcoKSkgdW5sZXNzIGZzLmV4aXN0cyhkaXIpCisgIHJhaXNlIElPRXJyb3IubmV3KCJOb3QgYSBkaXJlY3Rvcnk6ICIgKyBkaXIudG9TdHJpbmcoKSkgdW5sZXNzIGZzLmlzRGlyZWN0b3J5KGRpcikKK2VuZAorCisjIFJldHVybnMgdHJ1ZSBpZiB0aGUgcmVnaW9uIGJlbG9uZ3MgdG8gcGFzc2VkIHRhYmxlCitkZWYgaXNUYWJsZVJlZ2lvbih0YWJsZU5hbWUsIGhyaSkKKyAgcmV0dXJuIEJ5dGVzLmVxdWFscyhocmkuZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLCB0YWJsZU5hbWUpCitlbmQKKworIyBDcmVhdGUgbmV3IEhSSSBiYXNlZCBvZmYgcGFzc2VkICdvbGRIUkknCitkZWYgY3JlYXRlSFJJKHRhYmxlTmFtZSwgb2xkSFJJKQorICBodGQgPSBvbGRIUkkuZ2V0VGFibGVEZXNjKCkKKyAgbmV3SHRkID0gSFRhYmxlRGVzY3JpcHRvci5uZXcodGFibGVOYW1lKQorICBmb3IgZmFtaWx5IGluIGh0ZC5nZXRGYW1pbGllcygpCisgICAgbmV3SHRkLmFkZEZhbWlseShmYW1pbHkpCisgIGVuZAorICByZXR1cm4gSFJlZ2lvbkluZm8ubmV3KG5ld0h0ZCwgb2xkSFJJLmdldFN0YXJ0S2V5KCksIG9sZEhSSS5nZXRFbmRLZXkoKSwKKyAgICBvbGRIUkkuaXNTcGxpdCgpKQorZW5kCisKKyMgQ2hlY2sgYXJndW1lbnRzCitpZiBBUkdWLnNpemUgIT0gMgorICB1c2FnZQorZW5kCisKKyMgQ2hlY2sgZ29vZCB0YWJsZSBuYW1lcyB3ZXJlIHBhc3NlZC4KK29sZFRhYmxlTmFtZSA9IEhUYWJsZURlc2NyaXB0b3IuaXNMZWdhbFRhYmxlTmFtZShBUkdWWzBdLnRvX2phdmFfYnl0ZXMpCituZXdUYWJsZU5hbWUgPSBIVGFibGVEZXNjcmlwdG9yLmlzTGVnYWxUYWJsZU5hbWUoQVJHVlsxXS50b19qYXZhX2J5dGVzKQorCisjIEdldCBjb25maWd1cmF0aW9uIHRvIHVzZS4KK2MgPSBIQmFzZUNvbmZpZ3VyYXRpb24ubmV3KCkKKworIyBTZXQgaGFkb29wIGZpbGVzeXN0ZW0gY29uZmlndXJhdGlvbiB1c2luZyB0aGUgaGJhc2Uucm9vdGRpci4KKyMgT3RoZXJ3aXNlLCB3ZSdsbCBhbHdheXMgdXNlIGxvY2FsaG9zdCB0aG91Z2ggdGhlIGhiYXNlLnJvb3RkaXIKKyMgbWlnaHQgYmUgcG9pbnRpbmcgYXQgaGRmcyBsb2NhdGlvbi4KK2Muc2V0KCJmcy5kZWZhdWx0Lm5hbWUiLCBjLmdldChIQ29uc3RhbnRzOjpIQkFTRV9ESVIpKQorZnMgPSBGaWxlU3lzdGVtLmdldChjKQorCisjIElmIG5ldyB0YWJsZSBkaXJlY3RvcnkgZG9lcyBub3QgZXhpdCwgY3JlYXRlIGl0LiAgS2VlcCBnb2luZyBpZiBhbHJlYWR5CisjIGV4aXN0cyBiZWNhdXNlIG1heWJlIHdlIGFyZSByZXJ1bm5pbmcgc2NyaXB0IGJlY2F1c2UgaXQgZmFpbGVkIGZpcnN0CisjIHRpbWUuCityb290ZGlyID0gRlNVdGlscy5nZXRSb290RGlyKGMpCitvbGRUYWJsZURpciA9IFBhdGgubmV3KHJvb3RkaXIsIFBhdGgubmV3KEJ5dGVzLnRvU3RyaW5nKG9sZFRhYmxlTmFtZSkpKQoraXNEaXJFeGlzdHMoZnMsIG9sZFRhYmxlRGlyKQorbmV3VGFibGVEaXIgPSBQYXRoLm5ldyhyb290ZGlyLCBCeXRlcy50b1N0cmluZyhuZXdUYWJsZU5hbWUpKQoraWYgIWZzLmV4aXN0cyhuZXdUYWJsZURpcikKKyAgZnMubWtkaXJzKG5ld1RhYmxlRGlyKQorZW5kCisKKyMgR2V0IGEgbG9nZ2VyIGFuZCBhIG1ldGF1dGlscyBpbnN0YW5jZS4KK0xPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKE5BTUUpCit1dGlscyA9IE1ldGFVdGlscy5uZXcoYykKKworIyBTdGFydC4gIEdldCBhbGwgbWV0YSByb3dzLgorYmVnaW4KKyAgIyBHZXQgbGlzdCBvZiBhbGwgLk1FVEEuIHJlZ2lvbnMgdGhhdCBjb250YWluIG9sZCB0YWJsZSBuYW1lCisgIG1ldGFzID0gdXRpbHMuZ2V0TUVUQVJvd3Mob2xkVGFibGVOYW1lKQorICBpbmRleCA9IDAKKyAgZm9yIG1ldGEgaW4gbWV0YXMKKyAgICAjIEZvciBlYWNoIHJvdyB3ZSBmaW5kLCBtb3ZlIGl0cyByZWdpb24gZnJvbSBvbGQgdG8gbmV3IHRhYmxlLgorICAgICMgTmVlZCB0byB1cGRhdGUgdGhlIGVuY29kZWQgbmFtZSBpbiB0aGUgaHJpIGFzIHdlIG1vdmUuCisgICAgIyBBZnRlciBtb3ZlLCBkZWxldGUgb2xkIGVudHJ5IGFuZCBjcmVhdGUgYSBuZXcuCisgICAgTE9HLmluZm8oIlNjYW5uaW5nICIgKyBtZXRhLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKQorICAgIG1ldGFSZWdpb24gPSB1dGlscy5nZXRNZXRhUmVnaW9uKG1ldGEpCisgICAgc2Nhbm5lciA9IG1ldGFSZWdpb24uZ2V0U2Nhbm5lcihIQ29uc3RhbnRzOjpDT0xfUkVHSU9OSU5GT19BUlJBWSwgb2xkVGFibGVOYW1lLAorICAgICAgSENvbnN0YW50czo6TEFURVNUX1RJTUVTVEFNUCwgbmlsKSAKKyAgICBiZWdpbgorICAgICAga2V5ID0gSFN0b3JlS2V5Lm5ldygpCisgICAgICB2YWx1ZSA9IFRyZWVNYXAubmV3KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpCisgICAgICB3aGlsZSBzY2FubmVyLm5leHQoa2V5LCB2YWx1ZSkKKyAgICAgICAgaW5kZXggPSBpbmRleCArIDEKKyAgICAgICAga2V5U3RyID0ga2V5LnRvU3RyaW5nKCkKKyAgICAgICAgb2xkSFJJID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKHZhbHVlLmdldChIQ29uc3RhbnRzOjpDT0xfUkVHSU9OSU5GTykpCisgICAgICAgIGlmICFvbGRIUkkKKyAgICAgICAgICByYWlzZSBJT0Vycm9yLm5ldyhpbmRleC50b19zICsgIiBIUmVnaW9uSW5mbyBpcyBudWxsIGZvciAiICsga2V5U3RyKQorICAgICAgICBlbmQKKyAgICAgICAgdW5sZXNzIGlzVGFibGVSZWdpb24ob2xkVGFibGVOYW1lLCBvbGRIUkkpCisgICAgICAgICAgIyBJZiBoZXJlLCB3ZSBwYXNzZWQgb3V0IHRoZSB0YWJsZS4gIEJyZWFrLgorICAgICAgICAgIGJyZWFrCisgICAgICAgIGVuZAorICAgICAgICBvbGRSRGlyID0gUGF0aC5uZXcob2xkVGFibGVEaXIsIFBhdGgubmV3KG9sZEhSSS5nZXRFbmNvZGVkTmFtZSgpLnRvX3MpKQorICAgICAgICBpZiAhZnMuZXhpc3RzKG9sZFJEaXIpCisgICAgICAgICAgTE9HLndhcm4ob2xkUkRpci50b1N0cmluZygpICsgIiBkb2VzIG5vdCBleGlzdCAtLSByZWdpb24gIiArCisgICAgICAgICAgICBvbGRIUkkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpCisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIyBOb3cgbWFrZSBhIG5ldyBIUmVnaW9uSW5mbyB0byBhZGQgdG8gLk1FVEEuIGZvciB0aGUgbmV3IHJlZ2lvbi4KKyAgICAgICAgICBuZXdIUkkgPSBjcmVhdGVIUkkobmV3VGFibGVOYW1lLCBvbGRIUkkpCisgICAgICAgICAgbmV3UkRpciA9IFBhdGgubmV3KG5ld1RhYmxlRGlyLCBQYXRoLm5ldyhuZXdIUkkuZ2V0RW5jb2RlZE5hbWUoKS50b19zKSkKKyAgICAgICAgICAjIE1vdmUgdGhlIHJlZ2lvbiBpbiBmaWxlc3lzdGVtCisgICAgICAgICAgTE9HLmluZm8oIlJlbmFtaW5nICIgKyBvbGRSRGlyLnRvU3RyaW5nKCkgKyAiIGFzICIgKyBuZXdSRGlyLnRvU3RyaW5nKCkpCisgICAgICAgICAgZnMucmVuYW1lKG9sZFJEaXIsIG5ld1JEaXIpCisgICAgICAgICAgIyBSZW1vdmluZyBvbGQgcmVnaW9uIGZyb20gbWV0YQorICAgICAgICAgIExPRy5pbmZvKCJSZW1vdmluZyAiICsgQnl0ZXMudG9TdHJpbmcoa2V5LmdldFJvdygpKSArICIgZnJvbSAuTUVUQS4iKQorICAgICAgICAgIG1ldGFSZWdpb24uZGVsZXRlQWxsKGtleS5nZXRSb3coKSwgSENvbnN0YW50czo6TEFURVNUX1RJTUVTVEFNUCkKKyAgICAgICAgICAjIENyZWF0ZSAnbmV3JyByZWdpb24KKyAgICAgICAgICBuZXdSID0gSFJlZ2lvbi5uZXcocm9vdGRpciwgdXRpbHMuZ2V0TG9nKCksIGZzLCBjLCBuZXdIUkksIG5pbCkKKyAgICAgICAgICAjIEFkZCBuZXcgcm93LiBOT1RFOiBQcmVzdW1wdGlvbiBpcyB0aGF0IG9ubHkgb25lIC5NRVRBLiByZWdpb24uIElmIG5vdCwKKyAgICAgICAgICAjIG5lZWQgdG8gZG8gdGhlIHdvcmsgdG8gZmlndXJlIHByb3BlciByZWdpb24gdG8gYWRkIHRoaXMgbmV3IHJlZ2lvbiB0by4KKyAgICAgICAgICBMT0cuaW5mbygiQWRkaW5nIHRvIG1ldGE6ICIgKyBuZXdSLnRvU3RyaW5nKCkpCisgICAgICAgICAgSFJlZ2lvbi5hZGRSZWdpb25Ub01FVEEobWV0YVJlZ2lvbiwgbmV3UikKKyAgICAgICAgICBMT0cuaW5mbygiRG9uZSBtb3Zpbmc6ICIgKyBCeXRlcy50b1N0cmluZyhrZXkuZ2V0Um93KCkpKQorICAgICAgICBlbmQKKyAgICAgICAgIyBOZWVkIHRvIGNsZWFyIHZhbHVlIGVsc2Ugd2Uga2VlcCBhcHBlbmRpbmcgdmFsdWVzLgorICAgICAgICB2YWx1ZS5jbGVhcigpCisgICAgICBlbmQKKyAgICBlbnN1cmUKKyAgICAgIHNjYW5uZXIuY2xvc2UoKQorICAgIGVuZAorICBlbmQKKyAgTE9HLmluZm8oIlJlbmFtZWQgdGFibGUgLS0gbWFudWFsbHkgZGVsZXRlICIgKyBvbGRUYWJsZURpci50b1N0cmluZygpKTsKK2Vuc3VyZQorICB1dGlscy5zaHV0ZG93bigpCitlbmQKZGlmZiAtLWdpdCBhL2Jpbi9zdGFydC1oYmFzZS5zaCBiL2Jpbi9zdGFydC1oYmFzZS5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4zMjRmYTY0Ci0tLSAvZGV2L251bGwKKysrIGIvYmluL3N0YXJ0LWhiYXNlLnNoCkBAIC0wLDAgKzEsNDUgQEAKKyMhL3Vzci9iaW4vZW52IGJhc2gKKyMKKyMvKioKKyMgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyMgKgorIyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisjICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgKgorIyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgKgorIyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgKi8KKworIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL3N0YXJ0LWhiYXNlLnNoLgorCisjIFN0YXJ0IGhhZG9vcCBoYmFzZSBkYWVtb25zLgorIyBSdW4gdGhpcyBvbiBtYXN0ZXIgbm9kZS4KK3VzYWdlPSJVc2FnZTogc3RhcnQtaGJhc2Uuc2giCisKK2Jpbj1gZGlybmFtZSAiJDAiYAorYmluPWBjZCAiJGJpbiI7IHB3ZGAKKworLiAiJGJpbiIvaGJhc2UtY29uZmlnLnNoCisKKyMgc3RhcnQgaGJhc2UgZGFlbW9ucworIyBUT0RPOiBQVVQgQkFDSyAhISEgIiR7SEFET09QX0hPTUV9Ii9iaW4vaGFkb29wIGRmc2FkbWluIC1zYWZlbW9kZSB3YWl0CitlcnJDb2RlPSQ/CitpZiBbICRlcnJDb2RlIC1uZSAwIF0KK3RoZW4KKyAgZXhpdCAkZXJyQ29kZQorZmkKKyIkYmluIi9oYmFzZS16b29rZWVwZXIuc2ggLS1jb25maWcgIiR7SEJBU0VfQ09ORl9ESVJ9IiBcCisgIHN0YXJ0IHpvb2tlZXBlcgorIiRiaW4iL2hiYXNlLWRhZW1vbi5zaCAtLWNvbmZpZyAiJHtIQkFTRV9DT05GX0RJUn0iIHN0YXJ0IG1hc3RlciAKKyIkYmluIi9oYmFzZS1kYWVtb25zLnNoIC0tY29uZmlnICIke0hCQVNFX0NPTkZfRElSfSIgXAorICAtLWhvc3RzICIke0hCQVNFX1JFR0lPTlNFUlZFUlN9IiBzdGFydCByZWdpb25zZXJ2ZXIKZGlmZiAtLWdpdCBhL2Jpbi9zdG9wLWhiYXNlLnNoIGIvYmluL3N0b3AtaGJhc2Uuc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMDcxYWU1NQotLS0gL2Rldi9udWxsCisrKyBiL2Jpbi9zdG9wLWhiYXNlLnNoCkBAIC0wLDAgKzEsMzQgQEAKKyMhL3Vzci9iaW4vZW52IGJhc2gKKyMKKyMvKioKKyMgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyMgKgorIyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisjICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMgKgorIyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMgKgorIyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyMgKi8KKworIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL3N0b3AtaGJhc2Uuc2guCisKKyMgU3RvcCBoYWRvb3AgaGJhc2UgZGFlbW9ucy4gIFJ1biB0aGlzIG9uIG1hc3RlciBub2RlLgorCitiaW49YGRpcm5hbWUgIiQwImAKK2Jpbj1gY2QgIiRiaW4iOyBwd2RgCisKKy4gIiRiaW4iL2hiYXNlLWNvbmZpZy5zaAorCisiJGJpbiIvaGJhc2UtZGFlbW9uLnNoIC0tY29uZmlnICIke0hCQVNFX0NPTkZfRElSfSIgc3RvcCBtYXN0ZXIKKyIkYmluIi9oYmFzZS16b29rZWVwZXIuc2ggLS1jb25maWcgIiR7SEJBU0VfQ09ORl9ESVJ9IiBcCisgIHN0b3Agem9va2VlcGVyCmRpZmYgLS1naXQgYS9iaW4vem9va2VlcGVyLnNoIGIvYmluL3pvb2tlZXBlci5zaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi41ODNmMmJkCi0tLSAvZGV2L251bGwKKysrIGIvYmluL3pvb2tlZXBlci5zaApAQCAtMCwwICsxLDYyIEBACisjIS91c3IvYmluL2VudiBiYXNoCisjCisjLyoqCisjICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisjICoKKyMgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisjICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisjICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorIyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyMgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjICoKKyMgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjICoKKyMgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisjICovCisjIAorIyBSdW4gYSBzaGVsbCBjb21tYW5kIG9uIGFsbCByZWdpb25zZXJ2ZXIgaG9zdHMuCisjCisjIEVudmlyb25tZW50IFZhcmlhYmxlcworIworIyAgIEhBRE9PUF9DT05GX0RJUiAgQWx0ZXJuYXRlIGNvbmYgZGlyLiBEZWZhdWx0IGlzICR7SEFET09QX0hPTUV9L2NvbmYuCisjICAgSEJBU0VfQ09ORl9ESVIgIEFsdGVybmF0ZSBoYmFzZSBjb25mIGRpci4gRGVmYXVsdCBpcyAke0hCQVNFX0hPTUV9L2NvbmYuCisjICAgSEFET09QX1NMQVZFX1NMRUVQIFNlY29uZHMgdG8gc2xlZXAgYmV0d2VlbiBzcGF3bmluZyByZW1vdGUgY29tbWFuZHMuCisjICAgSEFET09QX1NTSF9PUFRTIE9wdGlvbnMgcGFzc2VkIHRvIHNzaCB3aGVuIHJ1bm5pbmcgcmVtb3RlIGNvbW1hbmRzLgorIworIyBNb2RlbGxlZCBhZnRlciAkSEFET09QX0hPTUUvYmluL3NsYXZlcy5zaC4KKwordXNhZ2U9IlVzYWdlOiB6b29rZWVwZXIgWy0tY29uZmlnIDxoYmFzZS1jb25mZGlyPl0gY29tbWFuZC4uLiIKKworIyBpZiBubyBhcmdzIHNwZWNpZmllZCwgc2hvdyB1c2FnZQoraWYgWyAkIyAtbGUgMCBdOyB0aGVuCisgIGVjaG8gJHVzYWdlCisgIGV4aXQgMQorZmkKKworYmluPWBkaXJuYW1lICIkMCJgCitiaW49YGNkICIkYmluIjsgcHdkYAorCisuICIkYmluIi9oYmFzZS1jb25maWcuc2gKKworaWYgWyAtZiAiJHtIQkFTRV9DT05GX0RJUn0vaGJhc2UtZW52LnNoIiBdOyB0aGVuCisgIC4gIiR7SEJBU0VfQ09ORl9ESVJ9L2hiYXNlLWVudi5zaCIKK2ZpCisKK2lmIFsgIiRIQkFTRV9NQU5BR0VTX1pLIiA9ICIiIF07IHRoZW4KKyAgSEJBU0VfTUFOQUdFU19aSz10cnVlCitmaQorCitpZiBbICIkSEJBU0VfTUFOQUdFU19aSyIgPSAidHJ1ZSIgXTsgdGhlbgorIHNzaCAkSEJBU0VfU1NIX09QVFMgMTI3LjAuMC4xICQiJHtALy8gL1xcIH0iIDI+JjEgfCBzZWQgInMvXi9sb2NhbGhvc3Q6IC8iICYKKyBpZiBbICIkSEJBU0VfU0xBVkVfU0xFRVAiICE9ICIiIF07IHRoZW4KKyAgIHNsZWVwICRIQkFTRV9TTEFWRV9TTEVFUAorIGZpCitmaQorCit3YWl0CmRpZmYgLS1naXQgYS9idWlsZC54bWwgYi9idWlsZC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2ZlYmFjZAotLS0gL2Rldi9udWxsCisrKyBiL2J1aWxkLnhtbApAQCAtMCwwICsxLDQ2NiBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+CisKKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPHByb2plY3QgbmFtZT0iaGJhc2UiIGRlZmF1bHQ9ImphciI+CisgIDxwcm9wZXJ0eSBuYW1lPSJ2ZXJzaW9uIiB2YWx1ZT0iMC4yMC4wLWRldi0wLjE4LjMiLz4KKyAgPHByb3BlcnR5IG5hbWU9Ik5hbWUiIHZhbHVlPSJIQmFzZSIvPgorICA8cHJvcGVydHkgbmFtZT0iZmluYWwubmFtZSIgdmFsdWU9ImhiYXNlLSR7dmVyc2lvbn0iLz4KKyAgPHByb3BlcnR5IG5hbWU9InllYXIiIHZhbHVlPSIyMDA4Ii8+CisgCisgIDwhLS0gTG9hZCBhbGwgdGhlIGRlZmF1bHQgcHJvcGVydGllcywgYW5kIGFueSB0aGUgdXNlciB3YW50cyAgICAtLT4KKyAgPCEtLSB0byBjb250cmlidXRlICh3aXRob3V0IGhhdmluZyB0byB0eXBlIC1EIG9yIGVkaXQgdGhpcyBmaWxlIC0tPgorICA8cHJvcGVydHkgZmlsZT0iJHt1c2VyLmhvbWV9LyR7bmFtZX0uYnVpbGQucHJvcGVydGllcyIgLz4KKyAgPHByb3BlcnR5IGZpbGU9IiR7YmFzZWRpcn0vYnVpbGQucHJvcGVydGllcyIgLz4KKworICA8cHJvcGVydHkgbmFtZT0ic3JjLmRpciIgIGxvY2F0aW9uPSIke2Jhc2VkaXJ9L3NyYy9qYXZhIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJzcmMudGVzdCIgbG9jYXRpb249IiR7YmFzZWRpcn0vc3JjL3Rlc3QiLz4KKyAgPHByb3BlcnR5IG5hbWU9InNyYy50ZXN0ZGF0YSIgbG9jYXRpb249IiR7YmFzZWRpcn0vc3JjL3Rlc3RkYXRhIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJzcmMuZXhhbXBsZXMiIGxvY2F0aW9uPSIke2Jhc2VkaXJ9L3NyYy9leGFtcGxlcyIvPgorICA8cHJvcGVydHkgbmFtZT0ic3JjLndlYmFwcHMiIGxvY2F0aW9uPSIke2Jhc2VkaXJ9L3NyYy93ZWJhcHBzIi8+CisKKyAgPHByb3BlcnR5IG5hbWU9ImxpYi5kaXIiIHZhbHVlPSIke2Jhc2VkaXJ9L2xpYiIvPgorICA8cHJvcGVydHkgbmFtZT0iY29uZi5kaXIiIHZhbHVlPSIke2Jhc2VkaXJ9L2NvbmYiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImRvY3MuZGlyIiB2YWx1ZT0iJHtiYXNlZGlyfS9kb2NzIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJkb2NzLnNyYyIgdmFsdWU9IiR7YmFzZWRpcn0vc3JjL2RvY3MiLz4KKworICA8cHJvcGVydHkgbmFtZT0idGVzdC5vdXRwdXQiIHZhbHVlPSJubyIvPgorICA8cHJvcGVydHkgbmFtZT0idGVzdC50aW1lb3V0IiB2YWx1ZT0iNjAwMDAwIi8+CisKKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLmRpciIgbG9jYXRpb249IiR7YmFzZWRpcn0vYnVpbGQiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLmJpbiIgbG9jYXRpb249IiR7YnVpbGQuZGlyfS9iaW4iLz4KKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLmNvbmYiIGxvY2F0aW9uPSIke2J1aWxkLmRpcn0vY29uZiIvPgorICA8cHJvcGVydHkgbmFtZT0iYnVpbGQud2ViYXBwcyIgbG9jYXRpb249IiR7YnVpbGQuZGlyfS93ZWJhcHBzIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5saWIiIGxvY2F0aW9uPSIke2J1aWxkLmRpcn0vbGliIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5jbGFzc2VzIiBsb2NhdGlvbj0iJHtidWlsZC5kaXJ9L2NsYXNzZXMiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLnRlc3QiIGxvY2F0aW9uPSIke2J1aWxkLmRpcn0vdGVzdCIvPgorICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuZXhhbXBsZXMiIGxvY2F0aW9uPSIke2J1aWxkLmRpcn0vZXhhbXBsZXMiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLmRvY3MiIHZhbHVlPSIke2J1aWxkLmRpcn0vZG9jcyIvPgorICA8cHJvcGVydHkgbmFtZT0iYnVpbGQuamF2YWRvYyIgdmFsdWU9IiR7YnVpbGQuZG9jc30vYXBpIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJidWlsZC5lbmNvZGluZyIgdmFsdWU9IklTTy04ODU5LTEiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImJ1aWxkLnNyYyIgdmFsdWU9IiR7YnVpbGQuZGlyfS9zcmMiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImdlbmVyYXRlZC53ZWJhcHBzLnNyYyIgdmFsdWU9IiR7YnVpbGQuc3JjfSIvPgorCisgIDxwcm9wZXJ0eSBuYW1lPSJ0ZXN0LmJ1aWxkLmRpciIgdmFsdWU9IiR7YnVpbGQuZGlyfS90ZXN0Ii8+CisgIDxwcm9wZXJ0eSBuYW1lPSJ0ZXN0LmxvZy5kaXIiIHZhbHVlPSIke3Rlc3QuYnVpbGQuZGlyfS9sb2dzIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJ0ZXN0Lmp1bml0Lm91dHB1dC5mb3JtYXQiIHZhbHVlPSJwbGFpbiIvPgorCisgIDxwcm9wZXJ0eSBuYW1lPSJkaXN0LmRpciIgdmFsdWU9IiR7YnVpbGQuZGlyfS8ke2ZpbmFsLm5hbWV9Ii8+CisKKyAgPHByb3BlcnR5IG5hbWU9ImphdmFjLmRlcHJlY2F0aW9uIiB2YWx1ZT0ib2ZmIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJqYXZhYy5kZWJ1ZyIgdmFsdWU9Im9uIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJqYXZhYy52ZXJzaW9uIiB2YWx1ZT0iMS42Ii8+CisKKyAgPHByb3BlcnR5IG5hbWU9ImNsb3Zlci5kYi5kaXIiIGxvY2F0aW9uPSIke2J1aWxkLmRpcn0vdGVzdC9jbG92ZXIvZGIiLz4KKyAgPHByb3BlcnR5IG5hbWU9ImNsb3Zlci5yZXBvcnQuZGlyIiBsb2NhdGlvbj0iJHtidWlsZC5kaXJ9L3Rlc3QvY2xvdmVyL3JlcG9ydHMiLz4KKworCisgIDxwcm9wZXJ0eSBuYW1lPSJqYXZhZG9jLmxpbmsuamF2YSIKKyAgICB2YWx1ZT0iaHR0cDovL2phdmEuc3VuLmNvbS9qYXZhc2UvNi9kb2NzL2FwaS8iLz4KKyAgPHByb3BlcnR5IG5hbWU9ImphdmFkb2MucGFja2FnZXMiIHZhbHVlPSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS4qIi8+CisgIDxwcm9wZXJ0eSBuYW1lPSJqYXJmaWxlIiB2YWx1ZT0iJHtidWlsZC5kaXJ9LyR7ZmluYWwubmFtZX0uamFyIiAvPgorCisgIDxwcm9wZXJ0eSBuYW1lPSJjbG92ZXIuamFyIiBsb2NhdGlvbj0iJHtjbG92ZXIuaG9tZX0vbGliL2Nsb3Zlci5qYXIiLz4KKyAgPGF2YWlsYWJsZSBwcm9wZXJ0eT0iY2xvdmVyLnByZXNlbnQiIGZpbGU9IiR7Y2xvdmVyLmphcn0iLz4KKworICA8IS0tIGNoZWNrIGlmIGNsb3ZlciByZXBvcnRzIHNob3VsZCBiZSBnZW5lcmF0ZWQgLS0+CisgIDxjb25kaXRpb24gcHJvcGVydHk9ImNsb3Zlci5lbmFibGVkIj4KKyAgICA8YW5kPgorICAgICAgICA8aXNzZXQgcHJvcGVydHk9InJ1bi5jbG92ZXIiLz4KKyAgICAgICAgPGlzc2V0IHByb3BlcnR5PSJjbG92ZXIucHJlc2VudCIvPgorICAgIDwvYW5kPgorICA8L2NvbmRpdGlvbj4KKworICA8IS0tV2UgbmVlZCB0byBoYXZlIHRoZSBoYWRvb3AgamFycyByaWRlIGluIGZyb250IG9mIHRoZSBoYmFzZSBjbGFzc2VzIG9yIHdlCisgICAgZ2V0IHRoZSBiZWxvdyBleGNlcHRpb25zOgorCisgICAgIFtqdW5pdF0gamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb246IGZpbGU6L1VzZXJzL3N0YWNrL0RvY3VtZW50cy9jaGVja291dHMvaGJhc2UvdHJ1bmsvYnVpbGQvd2ViYXBwcy9kZnMKKworICAgIFdoZW4gd2UgbW92ZSBvZmYgMC4xNi4wIGhhZG9vcCwgZml4IEh0dHBTdGF0dXNTZXJ2ZXIKKyAgIC0tPgorICA8ZmlsZXNldCBpZD0ibGliLmphcnMiIGRpcj0iJHtiYXNlZGlyfSIgaW5jbHVkZXM9ImxpYi8qLmphciIvPgorICA8cGF0aCBpZD0iY2xhc3NwYXRoIj4KKyAgICA8ZmlsZXNldCByZWZpZD0ibGliLmphcnMiLz4KKyAgICA8ZmlsZXNldCBkaXI9IiR7bGliLmRpcn0vamV0dHktZXh0LyI+CisgICAgICA8aW5jbHVkZSBuYW1lPSIqamFyIiAvPgorICAgIDwvZmlsZXNldD4KKyAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7YnVpbGQuY2xhc3Nlc30iLz4KKyAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7Y29uZi5kaXJ9Ii8+CisgIDwvcGF0aD4KKworICA8dGFyZ2V0IG5hbWU9ImluaXQiPgorICAgIDxta2RpciBkaXI9IiR7YnVpbGQuZGlyfSIvPgorICAgIDxta2RpciBkaXI9IiR7YnVpbGQuY2xhc3Nlc30iLz4KKyAgICA8bWtkaXIgZGlyPSIke2J1aWxkLnRlc3R9Ii8+CisgICAgPG1rZGlyIGRpcj0iJHtidWlsZC5leGFtcGxlc30iLz4KKworICAgIDwhLS1Db3B5IHdlYmFwcHMgb3ZlciB0byBidWlsZCBkaXIuIEV4Y2x1ZGUganNwIGFuZCBnZW5lcmF0ZWQtc3JjIGphdmEKKyAgICAgIGNsYXNzZXMgLS0+CisgICAgPG1rZGlyIGRpcj0iJHtidWlsZC53ZWJhcHBzfSIvPgorICAgIDxjb3B5IHRvZGlyPSIke2J1aWxkLndlYmFwcHN9Ij4KKyAgICAgIDxmaWxlc2V0IGRpcj0iJHtzcmMud2ViYXBwc30iPgorICAgICAgICA8ZXhjbHVkZSBuYW1lPSIqKi8qLmpzcCIgLz4KKyAgICAgICAgPGV4Y2x1ZGUgbmFtZT0iKiovLioiIC8+CisgICAgICAgIDxleGNsdWRlIG5hbWU9IioqLyp+IiAvPgorICAgICAgPC9maWxlc2V0PgorICAgIDwvY29weT4KKyAgICA8IS0tQ29weSBiaW4sIGxpYiwgYW5kIGNvbmYuIHRvby0tPgorICAgIDxta2RpciBkaXI9IiR7YnVpbGQubGlifSIvPgorICAgIDxjb3B5IHRvZGlyPSIke2J1aWxkLmxpYn0iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2xpYi5kaXJ9IiAvPgorICAgIDwvY29weT4KKyAgICA8bWtkaXIgZGlyPSIke2J1aWxkLmNvbmZ9Ii8+CisgICAgPGNvcHkgdG9kaXI9IiR7YnVpbGQuY29uZn0iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2Jhc2VkaXJ9L2NvbmYiIC8+CisgICAgPC9jb3B5PgorICAgIDxta2RpciBkaXI9IiR7YnVpbGQuYmlufSIvPgorICAgIDxjb3B5IHRvZGlyPSIke2J1aWxkLmJpbn0iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2Jhc2VkaXJ9L2JpbiIgLz4KKyAgICA8L2NvcHk+CisgICAgPGNobW9kIHBlcm09InVnbyt4IiB0eXBlPSJmaWxlIj4KKyAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5iaW59IiAvPgorICAgIDwvY2htb2Q+CisgICAgPGV4ZWMgZXhlY3V0YWJsZT0ic2giPgorICAgICAgIDxhcmcgbGluZT0ic3JjL3NhdmVWZXJzaW9uLnNoICR7dmVyc2lvbn0iLz4KKyAgICA8L2V4ZWM+CisgIDwvdGFyZ2V0PgorCisgIDx0YXJnZXQgbmFtZT0iY29tcGlsZSIgZGVwZW5kcz0iY2xvdmVyLGluaXQsanNwYyI+CisgICA8IS0tQ29tcGlsZSB3aGF0cyB1bmRlciBzcmMgYW5kIGdlbmVyYXRlZCBqYXZhIGNsYXNzZXMgbWFkZSBmcm9tIGpzcC0tPgorICAgPGphdmFjCisgICAgZW5jb2Rpbmc9IiR7YnVpbGQuZW5jb2Rpbmd9IgorICAgIHNyY2Rpcj0iJHtzcmMuZGlyfTske2J1aWxkLnNyY30iCisgICAgaW5jbHVkZXM9IioqLyouamF2YSIKKyAgICBkZXN0ZGlyPSIke2J1aWxkLmNsYXNzZXN9IgorICAgIGRlYnVnPSIke2phdmFjLmRlYnVnfSIKKyAgICAgdGFyZ2V0PSIke2phdmFjLnZlcnNpb259IgorICAgICBzb3VyY2U9IiR7amF2YWMudmVyc2lvbn0iCisgICAgZGVwcmVjYXRpb249IiR7amF2YWMuZGVwcmVjYXRpb259Ij4KKyAgICAgPGNsYXNzcGF0aCByZWZpZD0iY2xhc3NwYXRoIi8+CisgICA8L2phdmFjPgorICA8L3RhcmdldD4KKwkKKyAgPHRhcmdldCBuYW1lPSJqYXIiIGRlcGVuZHM9ImNvbXBpbGUiIGRlc2NyaXB0aW9uPSJCdWlsZCBqYXIiPgorICAgIDwhLS1Db3B5IG92ZXIgYW55IHByb3BlcnRpZXMgdW5kZXIgc3JjLS0+CisgICAgPGNvcHkgdG9kaXI9IiR7YnVpbGQuY2xhc3Nlc30iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke3NyYy5kaXJ9Ij4KKyAgICAgICAgPGluY2x1ZGUgbmFtZT0iKiovKi5wcm9wZXJ0aWVzIiAvPgorICAgICAgPC9maWxlc2V0PgorICAgIDwvY29weT4KKyAgICA8amFyIGphcmZpbGU9IiR7amFyZmlsZX0iCisgICAgICAgIGJhc2VkaXI9IiR7YnVpbGQuY2xhc3Nlc30iID4KKyAgICAgIDxmaWxlc2V0IGZpbGU9IiR7YmFzZWRpcn0vY29uZi9oYmFzZS1kZWZhdWx0LnhtbCIvPgorICAgICAgPHppcGZpbGVzZXQgZGlyPSIke2J1aWxkLndlYmFwcHN9IiBwcmVmaXg9IndlYmFwcHMiLz4KKyAgIAkJPG1hbmlmZXN0PgorICAgICAgICAgICAgPGF0dHJpYnV0ZSBuYW1lPSJNYWluLUNsYXNzIiB2YWx1ZT0ib3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0RyaXZlciIgLz4KKyAgICAJPC9tYW5pZmVzdD4KKyAgICA8L2phcj4KKyAgPC90YXJnZXQ+CisKKyAgIDwhLS1Db25kaXRpb25hbGx5IGdlbmVyYXRlIHRoZSBqc3AgamF2YSBwYWdlcy4KKyAgICAgICBXZSBkbyBpdCBvbmNlIHBlciBhbnQgaW52b2NhdGlvbi4gIFNlZSBoYmFzZS01OTMuCisgICAgIC0tPgorICA8dGFyZ2V0IG5hbWU9ImpzcGMiIGRlcGVuZHM9ImluaXQiIHVubGVzcz0ianNwYy5ub3QucmVxdWlyZWQiPgorICAgIDxwYXRoIGlkPSJqc3BjLmNsYXNzcGF0aCI+CisgICAgICA8ZmlsZXNldCBkaXI9IiR7YmFzZWRpcn0vbGliLyI+CisgICAgICAgIDxpbmNsdWRlIG5hbWU9InNlcnZsZXQtYXBpKmphciIgLz4KKyAgICAgICAgPGluY2x1ZGUgbmFtZT0iY29tbW9ucy1sb2dnaW5nKmphciIgLz4KKyAgICAgICAgPGluY2x1ZGUgbmFtZT0iamV0dHktKmphciIgLz4KKyAgICAgICAgPGluY2x1ZGUgbmFtZT0iamV0dHktZXh0LypqYXIiIC8+CisgICAgICA8L2ZpbGVzZXQ+CisgICAgPC9wYXRoPgorICAgIDx0YXNrZGVmIGNsYXNzbmFtZT0ib3JnLmFwYWNoZS5qYXNwZXIuSnNwQyIgbmFtZT0ianNwY29tcGlsZXIiID4KKyAgICAgIDxjbGFzc3BhdGggcmVmaWQ9ImpzcGMuY2xhc3NwYXRoIi8+CisgICAgPC90YXNrZGVmPgorICAgIDxta2RpciBkaXI9IiR7YnVpbGQud2ViYXBwc30vbWFzdGVyL1dFQi1JTkYiLz4KKyAgICA8anNwY29tcGlsZXIKKyAgICAgdXJpcm9vdD0iJHtzcmMud2ViYXBwc30vbWFzdGVyIgorICAgICBvdXRwdXRkaXI9IiR7Z2VuZXJhdGVkLndlYmFwcHMuc3JjfSIKKyAgICAgcGFja2FnZT0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZ2VuZXJhdGVkLm1hc3RlciIKKyAgICAgd2VieG1sPSIke2J1aWxkLndlYmFwcHN9L21hc3Rlci9XRUItSU5GL3dlYi54bWwiPgorICAgIDwvanNwY29tcGlsZXI+CisgICAgPG1rZGlyIGRpcj0iJHtidWlsZC53ZWJhcHBzfS9yZWdpb25zZXJ2ZXIvV0VCLUlORiIvPgorICAgIDxqc3Bjb21waWxlcgorICAgICB1cmlyb290PSIke3NyYy53ZWJhcHBzfS9yZWdpb25zZXJ2ZXIiCisgICAgIG91dHB1dGRpcj0iJHtnZW5lcmF0ZWQud2ViYXBwcy5zcmN9IgorICAgICBwYWNrYWdlPSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5nZW5lcmF0ZWQucmVnaW9uc2VydmVyIgorICAgICB3ZWJ4bWw9IiR7YnVpbGQud2ViYXBwc30vcmVnaW9uc2VydmVyL1dFQi1JTkYvd2ViLnhtbCI+CisgICAgPC9qc3Bjb21waWxlcj4KKyAgICA8cHJvcGVydHkgbmFtZT0ianNwYy5ub3QucmVxdWlyZWQiIHZhbHVlPSJ0cnVlIiAvPgorICAgIDxlY2hvIG1lc3NhZ2U9IlNldHRpbmcganNwYy5ub3RSZXF1aXJlZCBwcm9wZXJ0eS4ganNwIHBhZ2VzIGdlbmVyYXRlZCBvbmNlIHBlciBhbnQgc2Vzc2lvbiBvbmx5IiAvPgorICA8L3RhcmdldD4KKworICA8dGFyZ2V0IG5hbWU9ImNsb3ZlciIgZGVwZW5kcz0iY2xvdmVyLnNldHVwLCBjbG92ZXIuaW5mbyIgZGVzY3JpcHRpb249Ikluc3RydW1lbnQgdGhlIFVuaXQgdGVzdHMgdXNpbmcgQ2xvdmVyLiAgVG8gdXNlLCBzcGVjaWZ5IC1EY2xvdmVyLmhvbWU9Jmx0O2Jhc2Ugb2YgY2xvdmVyIGluc3RhbGxhdGlvbiZndDsgLURydW4uY2xvdmVyPXRydWUgb24gdGhlIGNvbW1hbmQgbGluZS4iLz4KKworICA8dGFyZ2V0IG5hbWU9ImNsb3Zlci5zZXR1cCIgaWY9ImNsb3Zlci5lbmFibGVkIj4KKyAgICA8dGFza2RlZiByZXNvdXJjZT0iY2xvdmVybGliLnhtbCIgY2xhc3NwYXRoPSIke2Nsb3Zlci5qYXJ9Ii8+CisgICAgPG1rZGlyIGRpcj0iJHtjbG92ZXIuZGIuZGlyfSIvPgorICAgIDxjbG92ZXItc2V0dXAgaW5pdFN0cmluZz0iJHtjbG92ZXIuZGIuZGlyfS9oYmFzZV9jb3ZlcmFnZS5kYiI+CisgICAgICA8ZmlsZXNldCBkaXI9InNyYyIgaW5jbHVkZXM9ImphdmEvKiovKiIvPgorICAgIDwvY2xvdmVyLXNldHVwPgorICA8L3RhcmdldD4KKworICA8dGFyZ2V0IG5hbWU9ImNsb3Zlci5pbmZvIiB1bmxlc3M9ImNsb3Zlci5wcmVzZW50Ij4KKyAgICA8ZWNobz4KKyAgICAgIENsb3ZlciBub3QgZm91bmQuIENvZGUgY292ZXJhZ2UgcmVwb3J0cyBkaXNhYmxlZC4KKyAgICA8L2VjaG8+CisgIDwvdGFyZ2V0PgorCisgIDx0YXJnZXQgbmFtZT0iY2xvdmVyLmNoZWNrIj4KKyAgICA8ZmFpbCB1bmxlc3M9ImNsb3Zlci5wcmVzZW50Ij4KKyAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworICAgICAgQ2xvdmVyIG5vdCBmb3VuZC4KKyAgICAgIFBsZWFzZSBzcGVjaWZ5IC1EY2xvdmVyLmhvbWU9Jmx0O2Jhc2Ugb2YgY2xvdmVyIGluc3RhbGxhdGlvbiZndDsKKyAgICAgIG9uIHRoZSBjb21tYW5kIGxpbmUuCisgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKyAgICA8L2ZhaWw+CisgIDwvdGFyZ2V0PgorCisgIDx0YXJnZXQgbmFtZT0iZ2VuZXJhdGUtY2xvdmVyLXJlcG9ydHMiIGRlcGVuZHM9ImNsb3Zlci5jaGVjaywgY2xvdmVyIj4KKyAgICA8bWtkaXIgZGlyPSIke2Nsb3Zlci5yZXBvcnQuZGlyfSIvPgorICAgIDxjbG92ZXItcmVwb3J0PgorICAgICAgPGN1cnJlbnQgb3V0ZmlsZT0iJHtjbG92ZXIucmVwb3J0LmRpcn0iIHRpdGxlPSIke2ZpbmFsLm5hbWV9Ij4KKyAgICAgICAgPGZvcm1hdCB0eXBlPSJodG1sIi8+CisgICAgICA8L2N1cnJlbnQ+CisgICAgPC9jbG92ZXItcmVwb3J0PgorICAgIDxjbG92ZXItcmVwb3J0PgorICAgICAgPGN1cnJlbnQgb3V0ZmlsZT0iJHtjbG92ZXIucmVwb3J0LmRpcn0vY2xvdmVyLnhtbCIgdGl0bGU9IiR7ZmluYWwubmFtZX0iPgorICAgICAgICA8Zm9ybWF0IHR5cGU9InhtbCIvPgorICAgICAgPC9jdXJyZW50PgorICAgIDwvY2xvdmVyLXJlcG9ydD4KKyAgPC90YXJnZXQ+CisKKyAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+CisgIDwhLS0gUGFja2FnZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgorICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KKyAgPHRhcmdldCBuYW1lPSJwYWNrYWdlIiBkZXBlbmRzPSJqYXIsamF2YWRvYyxjb21waWxlLXRlc3QiIAorICAgICAgZGVzY3JpcHRpb249IkJ1aWxkIGRpc3RyaWJ1dGlvbiI+IAorICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9Ii8+CisgICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9IiBpbmNsdWRlRW1wdHlEaXJzPSJmYWxzZSIgZmxhdHRlbj0idHJ1ZSI+CisgICAgICA8ZmlsZXNldCBkaXI9IiR7YnVpbGQuZGlyfSI+CisgICAgICAgIDxpbmNsdWRlIG5hbWU9IiR7ZmluYWwubmFtZX0uamFyIiAvPgorICAgICAgICA8aW5jbHVkZSBuYW1lPSIke2ZpbmFsLm5hbWV9LXRlc3QuamFyIiAvPgorICAgICAgPC9maWxlc2V0PgorICAgIDwvY29weT4KKyAgICA8bWtkaXIgZGlyPSIke2Rpc3QuZGlyfS93ZWJhcHBzIi8+CisgICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L3dlYmFwcHMiPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLndlYmFwcHN9IiAvPgorICAgIDwvY29weT4KKyAgICA8bWtkaXIgZGlyPSIke2Rpc3QuZGlyfS9saWIiLz4KKyAgICA8Y29weSB0b2Rpcj0iJHtkaXN0LmRpcn0vbGliIj4KKyAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5saWJ9IiAvPgorICAgIDwvY29weT4KKyAgICA8bWtkaXIgZGlyPSIke2Rpc3QuZGlyfS9jb25mIiAvPgorICAgIDxjb3B5IHRvZGlyPSIke2Rpc3QuZGlyfS9jb25mIj4KKyAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5jb25mfSIgLz4KKyAgICA8L2NvcHk+CisgICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0vYmluIiAvPgorICAgIDxjb3B5IHRvZGlyPSIke2Rpc3QuZGlyfS9iaW4iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLmJpbn0iIC8+CisgICAgPC9jb3B5PgorICAgIDxjaG1vZCBwZXJtPSJ1Z28reCIgdHlwZT0iZmlsZSI+CisgICAgICA8ZmlsZXNldCBkaXI9IiR7ZGlzdC5kaXJ9L2JpbiIgLz4KKyAgICA8L2NobW9kPgorICAgIDxta2RpciBkaXI9IiR7ZGlzdC5kaXJ9L2RvY3MiIC8+CisgICAgPGNvcHkgdG9kaXI9IiR7ZGlzdC5kaXJ9L2RvY3MiPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2RvY3MuZGlyfSIgLz4KKyAgICAgIDxmaWxlc2V0IGRpcj0iJHtidWlsZC5kb2NzfSIvPgorICAgIDwvY29weT4KKyAgICA8Y29weSB0b2Rpcj0iJHtkaXN0LmRpcn0iPgorICAgICAgPGZpbGVzZXQgZGlyPSIuIj4KKyAgICAgICAgPGluY2x1ZGUgbmFtZT0iKi50eHQiIC8+CisgICAgICAgIDxpbmNsdWRlIG5hbWU9ImJ1aWxkLnhtbCIgLz4KKyAgICAgIDwvZmlsZXNldD4KKyAgICA8L2NvcHk+CisgICAgPG1rZGlyIGRpcj0iJHtkaXN0LmRpcn0vc3JjIiAvPgorICAgIDxjb3B5IHRvZGlyPSIke2Rpc3QuZGlyfS9zcmMiIGluY2x1ZGVFbXB0eURpcnM9InRydWUiPgorICAgICAgPGZpbGVzZXQgZGlyPSJzcmMiIGV4Y2x1ZGVzPSIqKi8qLnRlbXBsYXRlICoqL2RvY3MvYnVpbGQvKiovKiIvPgorICAgIDwvY29weT4KKyAgPC90YXJnZXQ+CisKKyAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+CisgIDwhLS0gTWFrZSByZWxlYXNlIHRhcmJhbGwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgorICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KKyAgPG1hY3JvZGVmIG5hbWU9Im1hY3JvX3RhciIgZGVzY3JpcHRpb249IldvcmtlciBNYWNybyBmb3IgdGFyIj4KKyAgICA8YXR0cmlidXRlIG5hbWU9InBhcmFtLmRlc3RmaWxlIi8+CisgICAgPGVsZW1lbnQgbmFtZT0icGFyYW0ubGlzdG9maXRlbXMiLz4KKyAgICA8c2VxdWVudGlhbD4KKyAgICAgIDx0YXIgY29tcHJlc3Npb249Imd6aXAiIGxvbmdmaWxlPSJnbnUiCisgICAgICBkZXN0ZmlsZT0iQHtwYXJhbS5kZXN0ZmlsZX0iPgorICAgICAgPHBhcmFtLmxpc3RvZml0ZW1zLz4KKyAgICAgIDwvdGFyPgorICAgIDwvc2VxdWVudGlhbD4KKyAgPC9tYWNyb2RlZj4KKyAgPHRhcmdldCBuYW1lPSJ0YXIiIGRlcGVuZHM9InBhY2thZ2UiIGRlc2NyaXB0aW9uPSJNYWtlIHJlbGVhc2UgdGFyYmFsbCI+CisgICAgPG1hY3JvX3RhciBwYXJhbS5kZXN0ZmlsZT0iJHtidWlsZC5kaXJ9LyR7ZmluYWwubmFtZX0udGFyLmd6Ij4KKyAgICAgIDxwYXJhbS5saXN0b2ZpdGVtcz4KKyAgICAgICAgPHRhcmZpbGVzZXQgZGlyPSIke2J1aWxkLmRpcn0iIG1vZGU9IjY2NCI+CisgICAgICAgICAgPGV4Y2x1ZGUgbmFtZT0iJHtmaW5hbC5uYW1lfS9iaW4vKiIgLz4KKyAgICAgICAgICA8aW5jbHVkZSBuYW1lPSIke2ZpbmFsLm5hbWV9LyoqIiAvPgorICAgICAgICA8L3RhcmZpbGVzZXQ+CisgICAgICAgIDx0YXJmaWxlc2V0IGRpcj0iJHtidWlsZC5kaXJ9IiBtb2RlPSI3NTUiPgorICAgICAgICAgIDxpbmNsdWRlIG5hbWU9IiR7ZmluYWwubmFtZX0vYmluLyoiIC8+CisgICAgICAgIDwvdGFyZmlsZXNldD4KKyAgICAgIDwvcGFyYW0ubGlzdG9maXRlbXM+CisgICAgPC9tYWNyb190YXI+CisgIDwvdGFyZ2V0PgorCisgIDx0YXJnZXQgbmFtZT0iYmluYXJ5IiBkZXBlbmRzPSJwYWNrYWdlIiBkZXNjcmlwdGlvbj0iTWFrZSB0YXJiYWxsIHdpdGhvdXQgc291cmNlIGFuZCBkb2N1bWVudGF0aW9uIj4KKyAgICA8bWFjcm9fdGFyIHBhcmFtLmRlc3RmaWxlPSIke2J1aWxkLmRpcn0vJHtmaW5hbC5uYW1lfS1iaW4udGFyLmd6Ij4KKyAgICAgIDxwYXJhbS5saXN0b2ZpdGVtcz4KKyAgICAgICAgPHRhcmZpbGVzZXQgZGlyPSIke2J1aWxkLmRpcn0iIG1vZGU9IjY2NCI+CisgICAgICAgICAgPGV4Y2x1ZGUgbmFtZT0iJHtmaW5hbC5uYW1lfS9iaW4vKiIgLz4KKyAgICAgICAgICA8ZXhjbHVkZSBuYW1lPSIke2ZpbmFsLm5hbWV9L3NyYy8qKiIgLz4KKyAgICAgICAgICA8ZXhjbHVkZSBuYW1lPSIke2ZpbmFsLm5hbWV9L2RvY3MvKioiIC8+CisgICAgICAgICAgPGluY2x1ZGUgbmFtZT0iJHtmaW5hbC5uYW1lfS8qKiIgLz4KKyAgICAgICAgPC90YXJmaWxlc2V0PgorICAgICAgICA8dGFyZmlsZXNldCBkaXI9IiR7YnVpbGQuZGlyfSIgbW9kZT0iNzU1Ij4KKyAgICAgICAgICA8aW5jbHVkZSBuYW1lPSIke2ZpbmFsLm5hbWV9L2Jpbi8qIiAvPgorICAgICAgICA8L3RhcmZpbGVzZXQ+CisgICAgICA8L3BhcmFtLmxpc3RvZml0ZW1zPgorICAgIDwvbWFjcm9fdGFyPgorICA8L3RhcmdldD4KKworICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KKyAgPCEtLSBEb2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+CisgIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgorICA8dGFyZ2V0IG5hbWU9ImRvY3MiIGRlcGVuZHM9ImZvcnJlc3QuY2hlY2siIGRlc2NyaXB0aW9uPSJHZW5lcmF0ZSBmb3JyZXN0LWJhc2VkIGRvY3VtZW50YXRpb24uIFRvIHVzZSwgc3BlY2lmeSAtRGZvcnJlc3QuaG9tZT0mbHQ7YmFzZSBvZiBBcGFjaGUgRm9ycmVzdCBpbnN0YWxsYXRpb24mZ3Q7IG9uIHRoZSBjb21tYW5kIGxpbmUuIiBpZj0iZm9ycmVzdC5ob21lIj4KKyAgICA8ZXhlYyBkaXI9IiR7ZG9jcy5zcmN9IiBleGVjdXRhYmxlPSIke2ZvcnJlc3QuaG9tZX0vYmluL2ZvcnJlc3QiIGZhaWxvbmVycm9yPSJ0cnVlIiA+CisgICAgICA8ZW52IGtleT0iSkFWQV9IT01FIiB2YWx1ZT0iJHtqYXZhNS5ob21lfSIvPgorICAgIDwvZXhlYz4KKyAgICA8Y29weSB0b2Rpcj0iJHtkb2NzLmRpcn0iPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2RvY3Muc3JjfS9idWlsZC9zaXRlLyIgLz4KKyAgICA8L2NvcHk+CisgICAgPHN0eWxlIGJhc2VkaXI9IiR7Y29uZi5kaXJ9IiBkZXN0ZGlyPSIke2RvY3MuZGlyfSIKKyAgICAgICAgICAgaW5jbHVkZXM9ImhhZG9vcC1kZWZhdWx0LnhtbCIgc3R5bGU9ImNvbmYvY29uZmlndXJhdGlvbi54c2wiLz4KKyAgPC90YXJnZXQ+CisKKyAgPHRhcmdldCBuYW1lPSJmb3JyZXN0LmNoZWNrIiB1bmxlc3M9ImZvcnJlc3QuaG9tZSIgZGVwZW5kcz0iamF2YTUuY2hlY2siPgorICAgIDxmYWlsIG1lc3NhZ2U9Iidmb3JyZXN0LmhvbWUnIGlzIG5vdCBkZWZpbmVkLiBQbGVhc2UgcGFzcyAtRGZvcnJlc3QuaG9tZT0mbHQ7YmFzZSBvZiBBcGFjaGUgRm9ycmVzdCBpbnN0YWxsYXRpb24mZ3Q7IHRvIEFudCBvbiB0aGUgY29tbWFuZC1saW5lLiIgLz4KKyAgPC90YXJnZXQ+CisKKyAgPHRhcmdldCBuYW1lPSJqYXZhNS5jaGVjayIgdW5sZXNzPSJqYXZhNS5ob21lIj4KKyAgICA8ZmFpbCBtZXNzYWdlPSInamF2YTUuaG9tZScgaXMgbm90IGRlZmluZWQuICBGb3JyZXN0IHJlcXVpcmVzIEphdmEgNS4gIFBsZWFzZSBwYXNzIC1EamF2YTUuaG9tZT0mbHQ7YmFzZSBvZiBKYXZhIDUgZGlzdHJpYnV0aW9uJmd0OyB0byBBbnQgb24gdGhlIGNvbW1hbmQtbGluZS4iIC8+CisgIDwvdGFyZ2V0PgorCisgIDwhLS0gSmF2YWRvYyAtLT4KKyAgPHRhcmdldCBuYW1lPSJqYXZhZG9jIiBkZXNjcmlwdGlvbj0iR2VuZXJhdGUgamF2YWRvYyI+CisgICAgPG1rZGlyIGRpcj0iJHtidWlsZC5qYXZhZG9jfSIvPgorICAgIDxqYXZhZG9jCisgICAgICBvdmVydmlldz0iJHtzcmMuZGlyfS9vdmVydmlldy5odG1sIgorICAgICAgcGFja2FnZW5hbWVzPSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS4qIgorICAgICAgZGVzdGRpcj0iJHtidWlsZC5qYXZhZG9jfSIKKyAgICAgIGF1dGhvcj0idHJ1ZSIKKyAgICAgIHZlcnNpb249InRydWUiCisgICAgICB1c2U9InRydWUiCisgICAgICB3aW5kb3d0aXRsZT0iJHtOYW1lfSAke3ZlcnNpb259IEFQSSIKKyAgICAgIGRvY3RpdGxlPSIke05hbWV9ICR7dmVyc2lvbn0gQVBJIgorICAgICAgYm90dG9tPSJDb3B5cmlnaHQgJmFtcDtjb3B5OyAke3llYXJ9IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIKKyAgICAgID4KKyAgICAJPHBhY2thZ2VzZXQgZGlyPSIke3NyYy5kaXJ9Ij4KKyAgICAgICAgICA8aW5jbHVkZSBuYW1lPSJvcmcvYXBhY2hlLyoqIi8+CisgICAgICAgICAgPGV4Y2x1ZGUgbmFtZT0ib3JnL29uZWxhYi8qKiIvPgorICAgIAk8L3BhY2thZ2VzZXQ+CisgICAgICAgIDxsaW5rIGhyZWY9IiR7amF2YWRvYy5saW5rLmphdmF9Ii8+CisgICAgICAgIDxjbGFzc3BhdGggPgorICAgICAgICAgIDxwYXRoIHJlZmlkPSJjbGFzc3BhdGgiIC8+CisgICAgICAgICAgPHBhdGhlbGVtZW50IHBhdGg9IiR7amF2YS5jbGFzcy5wYXRofSIvPgorICAgICAgICA8L2NsYXNzcGF0aD4KKyAgICA8L2phdmFkb2M+CisgIDwvdGFyZ2V0PgkKKworICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KKyAgPCEtLSBSdW4gdW5pdCB0ZXN0cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+CisgIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC0tPgorICA8cGF0aCBpZD0idGVzdC5jbGFzc3BhdGgiPgorICAgIDwhLS0gPT09PT09PT09PT09ICAqICAqICAqICAqICAqICBOIE8gVCBFICAqICAqICAqICAqICAqID09PT09PT09PT09PQorICAgICAgICAgICAke3NyYy50ZXN0fSAqbXVzdCogY29tZSBiZWZvcmUgcmVzdCBvZiBjbGFzcyBwYXRoLiBPdGhlcndpc2UKKyAgICAgICAgICAgICAgICAgICAgdGhlIHRlc3QgaGJhc2Utc2l0ZS54bWwgd2lsbCBub3QgYmUgZm91bmQuCisgICAgICAgICA9PT09PT09PT09PT0gICogICogICogICogICogIE4gTyBUIEUgICogICogICogICogICogPT09PT09PT09PT09IC0tPgorICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtzcmMudGVzdH0iLz4KKyAgICA8cGF0aGVsZW1lbnQgbG9jYXRpb249IiR7YnVpbGQudGVzdH0iIC8+CisgICAgPHBhdGggcmVmaWQ9ImNsYXNzcGF0aCIvPgorICAgIDxwYXRoZWxlbWVudCBsb2NhdGlvbj0iJHtidWlsZC5kaXJ9Ii8+CisgICAgPHBhdGhlbGVtZW50IHBhdGg9IiR7Y2xvdmVyLmphcn0iLz4KKyAgPC9wYXRoPgorCisgIDwhLS0nY29tcGlsZS10ZXN0JyB1c2VkIHRvIGRlcGVuZCBvbiAnY29tcGlsZScgYnV0IHJlbW92ZWQgaXQuIEh1ZHNvbiBkb2Vzbid0IGxpa2UKKyAgICAgIHJlZG9pbmcgaW5pdCBhbmQganNjcGMgYXQgdGhpcyBzdGFnZSBvZiB0aGUgZ2FtZTsgaS5lLiB0aGUgcHJlcmVxcworICAgICAgZm9yIGNvbXBpbGUuICBUT0RPOiBJbnZlc3RpZ2F0ZSB3aHkuICBGb3Igbm93LCB0ZXN0IHdpbGwgZmFpbAorICAgICAgaWYgbm90IHByZWNlZWRlZCBieSBtYW51YWwgJ2phcicgb3IgJ2NvbXBpbGUnIGludm9rYXRpb24gLS0+CisgIDx0YXJnZXQgbmFtZT0iY29tcGlsZS10ZXN0IiBkZXBlbmRzPSJjb21waWxlIiBkZXNjcmlwdGlvbj0iQnVpbGQgdGVzdCBqYXIiPgorICAgIDxqYXZhYyBlbmNvZGluZz0iJHtidWlsZC5lbmNvZGluZ30iIAorICAgICAgIHNyY2Rpcj0iJHtzcmMudGVzdH0iIAorICAgICAgIGluY2x1ZGVzPSIqKi8qLmphdmEiIAorICAgICAgIGRlc3RkaXI9IiR7YnVpbGQudGVzdH0iIAorICAgICAgIGRlYnVnPSIke2phdmFjLmRlYnVnfSIKKyAgICAgICB0YXJnZXQ9IiR7amF2YWMudmVyc2lvbn0iCisgICAgICAgc291cmNlPSIke2phdmFjLnZlcnNpb259IgorICAgICAgIGRlcHJlY2F0aW9uPSIke2phdmFjLmRlcHJlY2F0aW9ufSI+IAorICAgIDxjbGFzc3BhdGggcmVmaWQ9InRlc3QuY2xhc3NwYXRoIi8+IAorICAgIDwvamF2YWM+CisgICAgPGphciBqYXJmaWxlPSIke2J1aWxkLmRpcn0vJHtmaW5hbC5uYW1lfS10ZXN0LmphciIgPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLnRlc3R9IiBpbmNsdWRlcz0ib3JnLyoqIiAvPgorICAgICAgPGZpbGVzZXQgZGlyPSIke2J1aWxkLmNsYXNzZXN9IiAvPgorICAgICAgPGZpbGVzZXQgZGlyPSIke3NyYy50ZXN0fSIgaW5jbHVkZXM9IioqLyoucHJvcGVydGllcyIgLz4KKyAgICAgIDxtYW5pZmVzdD4KKyAgICAgICAgPGF0dHJpYnV0ZSBuYW1lPSJNYWluLUNsYXNzIgorICAgICAgICAgIHZhbHVlPSJvcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9QZXJmb3JtYW5jZUV2YWx1YXRpb24iLz4KKyAgICAgIDwvbWFuaWZlc3Q+CisgICAgPC9qYXI+CisgIDwvdGFyZ2V0PgorCisgIDx0YXJnZXQgbmFtZT0idGVzdCIgZGVwZW5kcz0iY29tcGlsZS10ZXN0IgorICAJZGVzY3JpcHRpb249IkJ1aWxkIHRlc3QgamFyIGFuZCBydW4gdGVzdHMiPgorICAgIDxkZWxldGUgZGlyPSIke3Rlc3QubG9nLmRpcn0iLz4KKyAgICA8bWtkaXIgZGlyPSIke3Rlc3QubG9nLmRpcn0iLz4KKyAgICA8anVuaXQKKyAgICAgIHByaW50c3VtbWFyeT0ieWVzIiBzaG93b3V0cHV0PSIke3Rlc3Qub3V0cHV0fSIgCisgICAgICBoYWx0b25mYWlsdXJlPSJubyIgZm9yaz0ieWVzIiBtYXhtZW1vcnk9IjUxMm0iCisgICAgICBlcnJvclByb3BlcnR5PSJ0ZXN0cy5mYWlsZWQiIGZhaWx1cmVQcm9wZXJ0eT0idGVzdHMuZmFpbGVkIgorICAgICAgdGltZW91dD0iJHt0ZXN0LnRpbWVvdXR9Ij4KKyAgICAgIAorICAgICAgPHN5c3Byb3BlcnR5IGtleT0idGVzdC5idWlsZC5kYXRhIiB2YWx1ZT0iJHtidWlsZC50ZXN0fS9kYXRhIi8+CisgICAgICA8c3lzcHJvcGVydHkga2V5PSJidWlsZC50ZXN0IiB2YWx1ZT0iJHtidWlsZC50ZXN0fSIvPgorICAgICAgPHN5c3Byb3BlcnR5IGtleT0ic3JjLnRlc3RkYXRhIiB2YWx1ZT0iJHtzcmMudGVzdGRhdGF9Ii8+CisgICAgICA8c3lzcHJvcGVydHkga2V5PSJjb250cmliLm5hbWUiIHZhbHVlPSIke25hbWV9Ii8+CisgICAgICAKKyAgICAgIDxzeXNwcm9wZXJ0eSBrZXk9InVzZXIuZGlyIiB2YWx1ZT0iJHtidWlsZC50ZXN0fS9kYXRhIi8+CisgICAgICA8c3lzcHJvcGVydHkga2V5PSJmcy5kZWZhdWx0Lm5hbWUiIHZhbHVlPSIke2ZzLmRlZmF1bHQubmFtZX0iLz4KKyAgICAgIDxzeXNwcm9wZXJ0eSBrZXk9ImhhZG9vcC50ZXN0LmxvY2Fsb3V0cHV0ZmlsZSIgdmFsdWU9IiR7aGFkb29wLnRlc3QubG9jYWxvdXRwdXRmaWxlfSIvPgorICAgICAgPHN5c3Byb3BlcnR5IGtleT0idGVzdC5sb2cuZGlyIiB2YWx1ZT0iJHtoYWRvb3AubG9nLmRpcn0iLz4gCisgICAgICA8Y2xhc3NwYXRoIHJlZmlkPSJ0ZXN0LmNsYXNzcGF0aCIvPgorICAgICAgPGZvcm1hdHRlciB0eXBlPSIke3Rlc3QuanVuaXQub3V0cHV0LmZvcm1hdH0iIC8+CisgICAgICA8YmF0Y2h0ZXN0IHRvZGlyPSIke2J1aWxkLnRlc3R9IiB1bmxlc3M9InRlc3RjYXNlIj4KKyAgICAgICAgPGZpbGVzZXQgZGlyPSIke3NyYy50ZXN0fSIKKyAgICAgICAgICAgICAgICAgaW5jbHVkZXM9IioqL1Rlc3QqLmphdmEiIGV4Y2x1ZGVzPSIqKi8ke3Rlc3QuZXhjbHVkZX0uamF2YSIgLz4KKyAgICAgIDwvYmF0Y2h0ZXN0PgorICAgICAgPGJhdGNodGVzdCB0b2Rpcj0iJHtidWlsZC50ZXN0fSIgaWY9InRlc3RjYXNlIj4KKyAgICAgICAgPGZpbGVzZXQgZGlyPSIke3NyYy50ZXN0fSIgaW5jbHVkZXM9IioqLyR7dGVzdGNhc2V9LmphdmEiLz4KKyAgICAgIDwvYmF0Y2h0ZXN0PgorICAgIDwvanVuaXQ+CisgICAgPGZhaWwgaWY9InRlc3RzLmZhaWxlZCI+VGVzdHMgZmFpbGVkITwvZmFpbD4KKyAgPC90YXJnZXQ+CisKKyAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gLS0+CisgIDwhLS0gQ2xlYW4uICBEZWxldGUgdGhlIGJ1aWxkIGZpbGVzLCBhbmQgdGhlaXIgZGlyZWN0b3JpZXMgICAgICAgICAgICAgIC0tPgorICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4KKyAgPHRhcmdldCBuYW1lPSJjbGVhbiIgZGVzY3JpcHRpb249IkNsZWFuIGFsbCBvbGQgYnVpbGRzIj4KKyAgICA8ZGVsZXRlIGRpcj0iJHtidWlsZC5kaXJ9Ii8+CisgIDwvdGFyZ2V0PgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvY29uZi9oYWRvb3AtbWV0cmljcy5wcm9wZXJ0aWVzIGIvY29uZi9oYWRvb3AtbWV0cmljcy5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlYWRiZWEKLS0tIC9kZXYvbnVsbAorKysgYi9jb25mL2hhZG9vcC1tZXRyaWNzLnByb3BlcnRpZXMKQEAgLTAsMCArMSw0NCBAQAorIyBTZWUgaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvR2FuZ2xpYU1ldHJpY3MKKyMgQW5kLCB5ZXMsIHRoaXMgZmlsZSBpcyBuYW1lZCBoYWRvb3AtbWV0cmljcy5wcm9wZXJ0aWVzIHJhdGhlciB0aGFuCisjIGhiYXNlLW1ldHJpY3MucHJvcGVydGllcyBiZWNhdXNlIHdlJ3JlIGxldmVyYWdpbmcgdGhlIGhhZG9vcCBtZXRyaWNzCisjIHBhY2thZ2UgYW5kIGhhZG9vcC1tZXRyaWNzLnByb3BlcnRpZXMgaXMgYW4gaGFyZGNvZGVkLW5hbWUsIGF0IGxlYXN0CisjIGZvciB0aGUgbW9tZW50LgorCisjIENvbmZpZ3VyYXRpb24gb2YgdGhlICJoYmFzZSIgY29udGV4dCBmb3IgbnVsbAoraGJhc2UuY2xhc3M9b3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5zcGkuTnVsbENvbnRleHQKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAiaGJhc2UiIGNvbnRleHQgZm9yIGZpbGUKKyMgaGJhc2UuY2xhc3M9b3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWV0cmljcy5maWxlLlRpbWVTdGFtcGluZ0ZpbGVDb250ZXh0CisjIGhiYXNlLnBlcmlvZD0xMAorIyBoYmFzZS5maWxlTmFtZT0vdG1wL21ldHJpY3NfaGJhc2UubG9nCisKKyMgQ29uZmlndXJhdGlvbiBvZiB0aGUgImhiYXNlIiBjb250ZXh0IGZvciBnYW5nbGlhCisjIGhiYXNlLmNsYXNzPW9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuZ2FuZ2xpYS5HYW5nbGlhQ29udGV4dAorIyBoYmFzZS5wZXJpb2Q9MTAKKyMgaGJhc2Uuc2VydmVycz1HTUVUQURIT1NUX0lQOjg2NDkKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAianZtIiBjb250ZXh0IGZvciBudWxsCitqdm0uY2xhc3M9b3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5zcGkuTnVsbENvbnRleHQKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAianZtIiBjb250ZXh0IGZvciBmaWxlCisjIGp2bS5jbGFzcz1vcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tZXRyaWNzLmZpbGUuVGltZVN0YW1waW5nRmlsZUNvbnRleHQKKyMganZtLnBlcmlvZD0xMAorIyBqdm0uZmlsZU5hbWU9L3RtcC9tZXRyaWNzX2p2bS5sb2cKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAianZtIiBjb250ZXh0IGZvciBnYW5nbGlhCisjIGp2bS5jbGFzcz1vcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLmdhbmdsaWEuR2FuZ2xpYUNvbnRleHQKKyMganZtLnBlcmlvZD0xMAorIyBqdm0uc2VydmVycz1HTUVUQURIT1NUX0lQOjg2NDkKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAicnBjIiBjb250ZXh0IGZvciBudWxsCitycGMuY2xhc3M9b3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5zcGkuTnVsbENvbnRleHQKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAicnBjIiBjb250ZXh0IGZvciBmaWxlCisjIHJwYy5jbGFzcz1vcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tZXRyaWNzLmZpbGUuVGltZVN0YW1waW5nRmlsZUNvbnRleHQKKyMgcnBjLnBlcmlvZD0xMAorIyBycGMuZmlsZU5hbWU9L3RtcC9tZXRyaWNzX3JwYy5sb2cKKworIyBDb25maWd1cmF0aW9uIG9mIHRoZSAicnBjIiBjb250ZXh0IGZvciBnYW5nbGlhCisjIHJwYy5jbGFzcz1vcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLmdhbmdsaWEuR2FuZ2xpYUNvbnRleHQKKyMgcnBjLnBlcmlvZD0xMAorIyBycGMuc2VydmVycz1HTUVUQURIT1NUX0lQOjg2NDkKZGlmZiAtLWdpdCBhL2NvbmYvaGJhc2UtZGVmYXVsdC54bWwgYi9jb25mL2hiYXNlLWRlZmF1bHQueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwZjRlOTkKLS0tIC9kZXYvbnVsbAorKysgYi9jb25mL2hiYXNlLWRlZmF1bHQueG1sCkBAIC0wLDAgKzEsNDA5IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzw/eG1sLXN0eWxlc2hlZXQgdHlwZT0idGV4dC94c2wiIGhyZWY9ImNvbmZpZ3VyYXRpb24ueHNsIj8+Cis8IS0tCisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy0tPgorPGNvbmZpZ3VyYXRpb24+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yb290ZGlyPC9uYW1lPgorICAgIDx2YWx1ZT5maWxlOi8vL3RtcC9oYmFzZS0ke3VzZXIubmFtZX0vaGJhc2U8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgZGlyZWN0b3J5IHNoYXJlZCBieSByZWdpb24gc2VydmVycy4KKyAgICBTaG91bGQgYmUgZnVsbHktcXVhbGlmaWVkIHRvIGluY2x1ZGUgdGhlIGZpbGVzeXN0ZW0gdG8gdXNlLgorICAgIEUuZzogaGRmczovL05BTUVOT0RFX1NFUlZFUjpQT1JUL0hCQVNFX1JPT1RESVIKKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UubWFzdGVyLmhvc3RuYW1lPC9uYW1lPgorICAgIDx2YWx1ZT5sb2NhbDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRoZSBob3N0IHRoYXQgdGhlIEhCYXNlIG1hc3RlciBydW5zIGF0LgorICAgICAgQSB2YWx1ZSBvZiAnbG9jYWwnIHJ1bnMgdGhlIG1hc3RlciBhbmQgcmVnaW9uc2VydmVyIGluIGEgc2luZ2xlIHByb2Nlc3MuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLm1hc3Rlci5wb3J0PC9uYW1lPgorICAgIDx2YWx1ZT42MDAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRoZSBwb3J0IG1hc3RlciBzaG91bGQgYmluZCB0by48L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UudG1wLmRpcjwvbmFtZT4KKyAgICA8dmFsdWU+L3RtcC9oYmFzZS0ke3VzZXIubmFtZX08L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UZW1wb3JhcnkgZGlyZWN0b3J5IG9uIHRoZSBsb2NhbCBmaWxlc3lzdGVtLjwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5tYXN0ZXIuaW5mby5wb3J0PC9uYW1lPgorICAgIDx2YWx1ZT42MDAxMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRoZSBwb3J0IGZvciB0aGUgaGJhc2UgbWFzdGVyIHdlYiBVSQorICAgIFNldCB0byAtMSBpZiB5b3UgZG8gbm90IHdhbnQgdGhlIGluZm8gc2VydmVyIHRvIHJ1bi4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UubWFzdGVyLmluZm8uYmluZEFkZHJlc3M8L25hbWU+CisgICAgPHZhbHVlPjAuMC4wLjA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgYWRkcmVzcyBmb3IgdGhlIGhiYXNlIG1hc3RlciB3ZWIgVUkKKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UuY2xpZW50LndyaXRlLmJ1ZmZlcjwvbmFtZT4KKyAgICA8dmFsdWU+MjA5NzE1MjwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlNpemUgb2YgdGhlIHdyaXRlIGJ1ZmZlciBpbiBieXRlcy4gQSBiaWdnZXIgYnVmZmVyIHRha2VzIG1vcmUKKyAgICBtZW1vcnkgLS0gb24gYm90aCB0aGUgY2xpZW50IGFuZCBzZXJ2ZXIgc2lkZSBzaW5jZSBzZXJ2ZXIgaW5zdGFudGlhdGVzCisgICAgdGhlIHBhc3NlZCB3cml0ZSBidWZmZXIgdG8gcHJvY2VzcyBpdCAtLSBidXQgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIFJQQy4gIAorICAgIEZvciBhbiBlc3RpbWF0ZSBvZiBzZXJ2ZXItc2lkZSBtZW1vcnktdXNlZCwgZXZhbHVhdGUKKyAgICBoYmFzZS5jbGllbnQud3JpdGUuYnVmZmVyICogaGJhc2UucmVnaW9uc2VydmVyLmhhbmRsZXIuY291bnQKKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UubWFzdGVyLm1ldGEudGhyZWFkLnJlc2NhbmZyZXF1ZW5jeTwvbmFtZT4KKyAgICA8dmFsdWU+NjAwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5Ib3cgbG9uZyB0aGUgSE1hc3RlciBzbGVlcHMgKGluIG1pbGxpc2Vjb25kcykgYmV0d2VlbiBzY2FucyBvZgorICAgIHRoZSByb290IGFuZCBtZXRhIHRhYmxlcy4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UubWFzdGVyLmxlYXNlLnBlcmlvZDwvbmFtZT4KKyAgICA8dmFsdWU+MTIwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+SE1hc3RlciBzZXJ2ZXIgbGVhc2UgcGVyaW9kIGluIG1pbGxpc2Vjb25kcy4gRGVmYXVsdCBpcworICAgIDEyMCBzZWNvbmRzLiAgUmVnaW9uIHNlcnZlcnMgbXVzdCByZXBvcnQgaW4gd2l0aGluIHRoaXMgcGVyaW9kIGVsc2UKKyAgICB0aGV5IGFyZSBjb25zaWRlcmVkIGRlYWQuICBPbiBsb2FkZWQgY2x1c3RlciwgbWF5IG5lZWQgdG8gdXAgdGhpcworICAgIHBlcmlvZC48L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyPC9uYW1lPgorICAgIDx2YWx1ZT4wLjAuMC4wOjYwMDIwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+VGhlIGhvc3QgYW5kIHBvcnQgYSBIQmFzZSByZWdpb24gc2VydmVyIHJ1bnMgYXQuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5kbnMuaW50ZXJmYWNlPC9uYW1lPgorICAgIDx2YWx1ZT5kZWZhdWx0PC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TmFtZSBvZiB0aGUgbmV0d29yayBpbnRlcmZhY2Ugd2hpY2ggYSByZWdpb25zZXJ2ZXIKKyAgICBzaG91bGQgdXNlIHRvIGRldGVybWluZSBpdCdzICJyZWFsIiBJUCBhZGRyZXNzLiAgVGhpcyBsb29rdXAKKyAgICBwcmV2ZW50cyBzdHJpbmdzIGxpa2UgImxvY2FsaG9zdCIgYW5kICIxMjcuMC4wLjEiIGZyb20gYmVpbmcKKyAgICByZXBvcnRlZCBiYWNrIHRvIHRoZSBtYXN0ZXIuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5pbmZvLnBvcnQ8L25hbWU+CisgICAgPHZhbHVlPjYwMDMwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+VGhlIHBvcnQgZm9yIHRoZSBoYmFzZSByZWdpb25zZXJ2ZXIgd2ViIFVJCisgICAgU2V0IHRvIC0xIGlmIHlvdSBkbyBub3Qgd2FudCB0aGUgaW5mbyBzZXJ2ZXIgdG8gcnVuLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuaW5mby5wb3J0LmF1dG88L25hbWU+CisgICAgPHZhbHVlPmZhbHNlPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+SW5mbyBzZXJ2ZXIgYXV0byBwb3J0IGJpbmQuIEVuYWJsZXMgYXV0b21hdGljIHBvcnQKKyAgICBzZWFyY2ggaWYgaGJhc2UucmVnaW9uc2VydmVyLmluZm8ucG9ydCBpcyBhbHJlYWR5IGluIHVzZS4KKyAgICBVc2VmdWwgZm9yIHRlc3RpbmcsIHR1cm5lZCBvZmYgYnkgZGVmYXVsdC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyLmluZm8uYmluZEFkZHJlc3M8L25hbWU+CisgICAgPHZhbHVlPjAuMC4wLjA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgYWRkcmVzcyBmb3IgdGhlIGhiYXNlIHJlZ2lvbnNlcnZlciB3ZWIgVUkKKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyLmNsYXNzPC9uYW1lPgorICAgIDx2YWx1ZT5vcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPkFuIGludGVyZmFjZSB0aGF0IGlzIGFzc2lnbmFibGUgdG8gSFJlZ2lvbkludGVyZmFjZS4gIFVzZWQgaW4gSENsaWVudCBmb3IKKyAgICBvcGVuaW5nIHByb3h5IHRvIHJlbW90ZSByZWdpb24gc2VydmVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5jbGllbnQucGF1c2U8L25hbWU+CisgICAgPHZhbHVlPjIwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5HZW5lcmFsIGNsaWVudCBwYXVzZSB2YWx1ZS4gIFVzZWQgbW9zdGx5IGFzIHZhbHVlIHRvIHdhaXQKKyAgICBiZWZvcmUgcnVubmluZyBhIHJldHJ5IG9mIGEgZmFpbGVkIGdldCwgcmVnaW9uIGxvb2t1cCwgZXRjLjwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXI8L25hbWU+CisgICAgPHZhbHVlPjEwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TWF4aW11bSByZXRyaWVzLiAgVXNlZCBhcyBtYXhpbXVtIGZvciBhbGwgcmV0cnlhYmxlCisgICAgb3BlcmF0aW9ucyBzdWNoIGFzIGZldGNoaW5nIG9mIHRoZSByb290IHJlZ2lvbiBmcm9tIHJvb3QgcmVnaW9uCisgICAgc2VydmVyLCBnZXR0aW5nIGEgY2VsbCdzIHZhbHVlLCBzdGFydGluZyBhIHJvdyB1cGRhdGUsIGV0Yy4KKyAgICBEZWZhdWx0OiAxMC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UuY2xpZW50LnNjYW5uZXIuY2FjaGluZzwvbmFtZT4KKyAgICA8dmFsdWU+MTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPk51bWJlciBvZiByb3dzIHRoYXQgd2lsbCBiZSBmZXRjaGVkIHdoZW4gY2FsbGluZyBuZXh0CisgICAgb24gYSBzY2FubmVyIGlmIGl0IGlzIG5vdCBzZXJ2ZWQgZnJvbSBtZW1vcnkuIEhpZ2hlciBjYWNoaW5nIHZhbHVlcworICAgIHdpbGwgZW5hYmxlIGZhc3RlciBzY2FubmVycyBidXQgd2lsbCBlYXQgdXAgbW9yZSBtZW1vcnkgYW5kIHNvbWUKKyAgICBjYWxscyBvZiBuZXh0IG1heSB0YWtlIGxvbmdlciBhbmQgbG9uZ2VyIHRpbWVzIHdoZW4gdGhlIGNhY2hlIGlzIGVtcHR5LgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIubGVhc2UucGVyaW9kPC9uYW1lPgorICAgIDx2YWx1ZT42MDAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPkhSZWdpb24gc2VydmVyIGxlYXNlIHBlcmlvZCBpbiBtaWxsaXNlY29uZHMuIERlZmF1bHQgaXMKKyAgICA2MCBzZWNvbmRzLiBDbGllbnRzIG11c3QgcmVwb3J0IGluIHdpdGhpbiB0aGlzIHBlcmlvZCBlbHNlIHRoZXkgYXJlCisgICAgY29uc2lkZXJlZCBkZWFkLjwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuaGFuZGxlci5jb3VudDwvbmFtZT4KKyAgICA8dmFsdWU+MTA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5Db3VudCBvZiBSUEMgU2VydmVyIGluc3RhbmNlcyBzcHVuIHVwIG9uIFJlZ2lvblNlcnZlcnMKKyAgICBTYW1lIHByb3BlcnR5IGlzIHVzZWQgYnkgdGhlIEhNYXN0ZXIgZm9yIGNvdW50IG9mIG1hc3RlciBoYW5kbGVycy4KKyAgICBEZWZhdWx0IGlzIDEwLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIubXNnaW50ZXJ2YWw8L25hbWU+CisgICAgPHZhbHVlPjMwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5JbnRlcnZhbCBiZXR3ZWVuIG1lc3NhZ2VzIGZyb20gdGhlIFJlZ2lvblNlcnZlciB0byBITWFzdGVyCisgICAgaW4gbWlsbGlzZWNvbmRzLiAgRGVmYXVsdCBpcyAzIHNlY29uZHMuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5tYXhsb2dlbnRyaWVzPC9uYW1lPgorICAgIDx2YWx1ZT4xMDAwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5Sb3RhdGUgdGhlIEhSZWdpb24gSExvZ3Mgd2hlbiBjb3VudCBvZiBlbnRyaWVzIGV4Y2VlZHMgdGhpcworICAgIHZhbHVlLiAgRGVmYXVsdDogMTAwLDAwMC4gIFZhbHVlIGlzIGNoZWNrZWQgYnkgYSB0aHJlYWQgdGhhdCBydW5zIGV2ZXJ5CisgICAgaGJhc2Uuc2VydmVyLnRocmVhZC53YWtlZnJlcXVlbmN5LgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuZmx1c2hsb2dlbnRyaWVzPC9uYW1lPgorICAgIDx2YWx1ZT4xMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5TeW5jIHRoZSBITG9nIHRvIHRoZSBIREZTIHdoZW4gaXQgaGFzIGFjY3VtdWxhdGVkIHRoaXMgbWFueQorICAgIGVudHJpZXMuIERlZmF1bHQgMTAwLiBWYWx1ZSBpcyBjaGVja2VkIG9uIGV2ZXJ5IEhMb2cuYXBwZW5kCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5vcHRpb25hbGxvZ2ZsdXNoaW50ZXJ2YWw8L25hbWU+CisgICAgPHZhbHVlPjEwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+U3luYyB0aGUgSExvZyB0byB0aGUgSERGUyBhZnRlciB0aGlzIGludGVydmFsIGlmIGl0IGhhcyBub3QKKyAgICBhY2N1bXVsYXRlZCBlbm91Z2ggZW50cmllcyB0byB0cmlnZ2VyIGEgc3luYy4gRGVmYXVsdCAxMCBzZWNvbmRzLiBVbml0czoKKyAgICBtaWxsaXNlY29uZHMuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci50aHJlYWQuc3BsaXRjb21wYWN0Y2hlY2tmcmVxdWVuY3k8L25hbWU+CisgICAgPHZhbHVlPjIwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+SG93IG9mdGVuIGEgcmVnaW9uIHNlcnZlciBydW5zIHRoZSBzcGxpdC9jb21wYWN0aW9uIGNoZWNrLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIubmJyZXNlcnZhdGlvbmJsb2NrczwvbmFtZT4KKyAgICA8dmFsdWU+NDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRoZSBudW1iZXIgb2YgcmVzZXJ2YXRpb24gYmxvY2tzIHdoaWNoIGFyZSB1c2VkIHRvIHByZXZlbnQKKyAgICB1bnN0YWJsZSByZWdpb24gc2VydmVycyBjYXVzZWQgYnkgYW4gT09NRS4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyLmRucy5pbnRlcmZhY2U8L25hbWU+CisgICAgPHZhbHVlPmRlZmF1bHQ8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgbmFtZSBvZiB0aGUgTmV0d29yayBJbnRlcmZhY2UgZnJvbSB3aGljaCBhIHJlZ2lvbiBzZXJ2ZXIgCisgICAgICBzaG91bGQgcmVwb3J0IGl0cyBJUCBhZGRyZXNzLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuZG5zLm5hbWVzZXJ2ZXI8L25hbWU+CisgICAgPHZhbHVlPmRlZmF1bHQ8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgaG9zdCBuYW1lIG9yIElQIGFkZHJlc3Mgb2YgdGhlIG5hbWUgc2VydmVyIChETlMpCisgICAgICB3aGljaCBhIHJlZ2lvbiBzZXJ2ZXIgc2hvdWxkIHVzZSB0byBkZXRlcm1pbmUgdGhlIGhvc3QgbmFtZSB1c2VkIGJ5IHRoZQorICAgICAgbWFzdGVyIGZvciBjb21tdW5pY2F0aW9uIGFuZCBkaXNwbGF5IHB1cnBvc2VzLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuZ2xvYmFsTWVtY2FjaGUudXBwZXJMaW1pdDwvbmFtZT4KKyAgICA8dmFsdWU+MC40PC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TWF4aW11bSBzaXplIG9mIGFsbCBtZW1jYWNoZXMgaW4gYSByZWdpb24gc2VydmVyIGJlZm9yZSBuZXcgCisgICAgICB1cGRhdGVzIGFyZSBibG9ja2VkIGFuZCBmbHVzaGVzIGFyZSBmb3JjZWQuIERlZmF1bHRzIHRvIDQwJSBvZiBoZWFwLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuZ2xvYmFsTWVtY2FjaGUubG93ZXJMaW1pdDwvbmFtZT4KKyAgICA8dmFsdWU+MC4yNTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPldoZW4gbWVtY2FjaGVzIGFyZSBiZWluZyBmb3JjZWQgdG8gZmx1c2ggdG8gbWFrZSByb29tIGluCisgICAgICBtZW1vcnksIGtlZXAgZmx1c2hpbmcgdW50aWwgd2UgaGl0IHRoaXMgbWFyay4gRGVmYXVsdHMgdG8gMzAlIG9mIGhlYXAuIAorICAgICAgVGhpcyB2YWx1ZSBlcXVhbCB0byBoYmFzZS5yZWdpb25zZXJ2ZXIuZ2xvYmFsbWVtY2FjaGUudXBwZXJMaW1pdCBjYXVzZXMKKyAgICAgIHRoZSBtaW5pbXVtIHBvc3NpYmxlIGZsdXNoaW5nIHRvIG9jY3VyIHdoZW4gdXBkYXRlcyBhcmUgYmxvY2tlZCBkdWUgdG8gCisgICAgICBtZW1jYWNoZSBsaW1pdGluZy4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PiAgCisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5oYmFzZW1hc3Rlci5tYXhyZWdpb25vcGVuPC9uYW1lPgorICAgIDx2YWx1ZT4xMjAwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5QZXJpb2QgdG8gd2FpdCBmb3IgYSByZWdpb24gb3Blbi4gIElmIHJlZ2lvbnNlcnZlcgorICAgIHRha2VzIGxvbmdlciB0aGFuIHRoaXMgaW50ZXJ2YWwsIGFzc2lnbiB0byBhIG5ldyByZWdpb25zZXJ2ZXIuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnMucGVyY2hlY2tpbjwvbmFtZT4KKyAgICA8dmFsdWU+MTA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5NYXhpbXVtIG51bWJlciBvZiByZWdpb25zIHRoYXQgY2FuIGJlIGFzc2lnbmVkIGluIGEgc2luZ2xlIGdvCisgICAgdG8gYSByZWdpb24gc2VydmVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5zZXJ2ZXIudGhyZWFkLndha2VmcmVxdWVuY3k8L25hbWU+CisgICAgPHZhbHVlPjEwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+VGltZSB0byBzbGVlcCBpbiBiZXR3ZWVuIHNlYXJjaGVzIGZvciB3b3JrIChpbiBtaWxsaXNlY29uZHMpLgorICAgIFVzZWQgYXMgc2xlZXAgaW50ZXJ2YWwgYnkgc2VydmljZSB0aHJlYWRzIHN1Y2ggYXMgTUVUQSBzY2FubmVyIGFuZCBsb2cgcm9sbGVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5ocmVnaW9uLm1lbWNhY2hlLmZsdXNoLnNpemU8L25hbWU+CisgICAgPHZhbHVlPjY3MTA4ODY0PC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+CisgICAgQSBIUmVnaW9uIG1lbWNhY2hlIHdpbGwgYmUgZmx1c2hlZCB0byBkaXNrIGlmIHNpemUgb2YgdGhlIG1lbWNhY2hlCisgICAgZXhjZWVkcyB0aGlzIG51bWJlciBvZiBieXRlcy4gIFZhbHVlIGlzIGNoZWNrZWQgYnkgYSB0aHJlYWQgdGhhdCBydW5zCisgICAgZXZlcnkgaGJhc2Uuc2VydmVyLnRocmVhZC53YWtlZnJlcXVlbmN5LiAgCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmhyZWdpb24ubWVtY2FjaGUuYmxvY2subXVsdGlwbGllcjwvbmFtZT4KKyAgICA8dmFsdWU+MjwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPgorICAgIEJsb2NrIHVwZGF0ZXMgaWYgbWVtY2FjaGUgaGFzIGhiYXNlLmhyZWdpb24uYmxvY2subWVtY2FjaGUKKyAgICB0aW1lIGhiYXNlLmhyZWdpb24uZmx1c2guc2l6ZSBieXRlcy4gIFVzZWZ1bCBwcmV2ZW50aW5nCisgICAgcnVuYXdheSBtZW1jYWNoZSBkdXJpbmcgc3Bpa2VzIGluIHVwZGF0ZSB0cmFmZmljLiAgV2l0aG91dCBhbgorICAgIHVwcGVyLWJvdW5kLCBtZW1jYWNoZSBmaWxscyBzdWNoIHRoYXQgd2hlbiBpdCBmbHVzaGVzIHRoZQorICAgIHJlc3VsdGFudCBmbHVzaCBmaWxlcyB0YWtlIGEgbG9uZyB0aW1lIHRvIGNvbXBhY3Qgb3Igc3BsaXQsIG9yCisgICAgd29yc2UsIHdlIE9PTUUuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmhyZWdpb24ubWF4LmZpbGVzaXplPC9uYW1lPgorICAgIDx2YWx1ZT4yNjg0MzU0NTY8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj4KKyAgICBNYXhpbXVtIEhTdG9yZUZpbGUgc2l6ZS4gSWYgYW55IG9uZSBvZiBhIGNvbHVtbiBmYW1pbGllcycgSFN0b3JlRmlsZXMgaGFzCisgICAgZ3Jvd24gdG8gZXhjZWVkIHRoaXMgdmFsdWUsIHRoZSBob3N0aW5nIEhSZWdpb24gaXMgc3BsaXQgaW4gdHdvLgorICAgIERlZmF1bHQ6IDI1Nk0uCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmhzdG9yZS5jb21wYWN0aW9uVGhyZXNob2xkPC9uYW1lPgorICAgIDx2YWx1ZT4zPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+CisgICAgSWYgbW9yZSB0aGFuIHRoaXMgbnVtYmVyIG9mIEhTdG9yZUZpbGVzIGluIGFueSBvbmUgSFN0b3JlCisgICAgKG9uZSBIU3RvcmVGaWxlIGlzIHdyaXR0ZW4gcGVyIGZsdXNoIG9mIG1lbWNhY2hlKSB0aGVuIGEgY29tcGFjdGlvbgorICAgIGlzIHJ1biB0byByZXdyaXRlIGFsbCBIU3RvcmVGaWxlcyBmaWxlcyBhcyBvbmUuICBMYXJnZXIgbnVtYmVycworICAgIHB1dCBvZmYgY29tcGFjdGlvbiBidXQgd2hlbiBpdCBydW5zLCBpdCB0YWtlcyBsb25nZXIgdG8gY29tcGxldGUuCisgICAgRHVyaW5nIGEgY29tcGFjdGlvbiwgdXBkYXRlcyBjYW5ub3QgYmUgZmx1c2hlZCB0byBkaXNrLiAgTG9uZworICAgIGNvbXBhY3Rpb25zIHJlcXVpcmUgbWVtb3J5IHN1ZmZpY2llbnQgdG8gY2FycnkgdGhlIGxvZ2dpbmcgb2YKKyAgICBhbGwgdXBkYXRlcyBhY3Jvc3MgdGhlIGR1cmF0aW9uIG9mIHRoZSBjb21wYWN0aW9uLgorICAgIAorICAgIElmIHRvbyBsYXJnZSwgY2xpZW50cyB0aW1lb3V0IGR1cmluZyBjb21wYWN0aW9uLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5oc3RvcmUuY29tcGFjdGlvbi5tYXg8L25hbWU+CisgICAgPHZhbHVlPjEwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TWF4IG51bWJlciBvZiBIU3RvcmVGaWxlcyB0byBjb21wYWN0IHBlciAnbWlub3InIGNvbXBhY3Rpb24uCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmhyZWdpb24ubWFqb3Jjb21wYWN0aW9uPC9uYW1lPgorICAgIDx2YWx1ZT44NjQwMDAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRoZSB0aW1lIChpbiBtaWxpc2Vjb25kcykgYmV0d2VlbiAnbWFqb3InIGNvbXBhY3Rpb25zIG9mIGFsbAorICAgIEhTdG9yZUZpbGVzIGluIGEgcmVnaW9uLiAgRGVmYXVsdDogMSBkYXkuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnMuc2xvcDwvbmFtZT4KKyAgICA8dmFsdWU+MC4xPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+UmViYWxhbmNlIGlmIHJlZ2lvbnNlcnZlciBoYXMgYXZlcmFnZSArIChhdmVyYWdlICogc2xvcCkgcmVnaW9ucy4KKyAgICBEZWZhdWx0IGlzIDEwJSBzbG9wLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oZmlsZS5taW4uYmxvY2tzaXplLnNpemU8L25hbWU+CisgICAgPHZhbHVlPjY1NTM2PC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TWluaW11bSBzdG9yZSBmaWxlIGJsb2NrIHNpemUuICBUaGUgc21hbGxlciB5b3UgbWFrZSB0aGlzLCB0aGUKKyAgICBiaWdnZXIgeW91ciBpbmRleCBhbmQgdGhlIGxlc3MgeW91IGZldGNoIG9uIGEgcmFuZG9tLWFjY2Vzcy4gIFNldCBzaXplIGRvd24KKyAgICBpZiB5b3UgaGF2ZSBzbWFsbCBjZWxscyBhbmQgd2FudCBmYXN0ZXIgcmFuZG9tLWFjY2VzcyBvZiBpbmRpdmlkdWFsIGNlbGxzLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5oc3RvcmUuYmxvY2tDYWNoZS5ibG9ja1NpemU8L25hbWU+CisgICAgPHZhbHVlPjE2Mzg0PC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+VGhlIHNpemUgb2YgZWFjaCBibG9jayBpbiB0aGUgYmxvY2sgY2FjaGUuCisgICAgRW5hYmxlIGJsb2NrY2FjaGluZyBvbiBhIHBlciBjb2x1bW4gZmFtaWx5IGJhc2lzOyBzZWUgdGhlIEJMT0NLQ0FDSEUgc2V0dGluZworICAgIGluIEhDb2x1bW5EZXNjcmlwdG9yLiAgQmxvY2tzIGFyZSBrZXB0IGluIGEgamF2YSBTb2Z0IFJlZmVyZW5jZSBjYWNoZSBzbyBhcmUKKyAgICBsZXQgZ28gd2hlbiBoaWdoIHByZXNzdXJlIG9uIG1lbW9yeS4gIEJsb2NrIGNhY2hpbmcgaXMgbm90IGVuYWJsZWQgYnkgZGVmYXVsdC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UuaGFzaC50eXBlPC9uYW1lPgorICAgIDx2YWx1ZT5tdXJtdXI8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgaGFzaGluZyBhbGdvcml0aG0gZm9yIHVzZSBpbiBIYXNoRnVuY3Rpb24uIFR3byB2YWx1ZXMgYXJlCisgICAgc3VwcG9ydGVkIG5vdzogbXVybXVyIChNdXJtdXJIYXNoKSBhbmQgamVua2lucyAoSmVua2luc0hhc2gpLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT56b29rZWVwZXIuc2Vzc2lvbi50aW1lb3V0PC9uYW1lPgorICAgIDx2YWx1ZT4xMDAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlpvb0tlZXBlciBzZXNzaW9uIHRpbWVvdXQuIFRoaXMgb3B0aW9uIGlzIG5vdCB1c2VkIGJ5IEhCYXNlCisgICAgICBkaXJlY3RseSwgaXQgaXMgZm9yIHRoZSBpbnRlcm5hbHMgb2YgWm9vS2VlcGVyLiBIQmFzZSBtZXJlbHkgcGFzc2VzIGl0IGluCisgICAgICB3aGVuZXZlciBhIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQgdG8gWm9vS2VlcGVyLiBJdCBpcyB1c2VkIGJ5IFpvb0tlZXBlcgorICAgICAgZm9yIGhlYXJiZWF0cy4gSW4gbWlsbGlzZWNvbmRzLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT56b29rZWVwZXIucmV0cmllczwvbmFtZT4KKyAgICA8dmFsdWU+NTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPkhvdyBtYW55IHRpbWVzIHRvIHJldHJ5IGNvbm5lY3Rpb25zIHRvIFpvb0tlZXBlci4gVXNlZCBmb3IKKyAgICAgIHJlYWRpbmcvd3JpdGluZyByb290IHJlZ2lvbiBsb2NhdGlvbiwgY2hlY2tpbmcvd3JpdGluZyBvdXQgb2Ygc2FmZSBtb2RlLgorICAgICAgVXNlZCB0b2dldGhlciB3aXRoICR7em9va2VlcGVyLnBhdXNlfSBpbiBhbiBleHBvbmVudGlhbCBiYWNrb2ZmIGZhc2hpb24KKyAgICAgIHdoZW4gbWFraW5nIHF1ZXJpZXMgdG8gWm9vS2VlcGVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT56b29rZWVwZXIucGF1c2U8L25hbWU+CisgICAgPHZhbHVlPjIwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5TbGVlcCB0aW1lIGJldHdlZW4gcmV0cmllcyB0byBab29LZWVwZXIuIEluIG1pbGxpc2Vjb25kcy4gVXNlZAorICAgICAgdG9nZXRoZXIgd2l0aCAke3pvb2tlZXBlci5yZXRyaWVzfSBpbiBhbiBleHBvbmVudGlhbCBiYWNrb2ZmIGZhc2hpb24gd2hlbgorICAgICAgbWFraW5nIHF1ZXJpZXMgdG8gWm9vS2VlcGVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT56b29rZWVwZXIuem5vZGUucGFyZW50PC9uYW1lPgorICAgIDx2YWx1ZT4vaGJhc2U8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5Sb290IFpOb2RlIGZvciBIQmFzZSBpbiBab29LZWVwZXIuIEFsbCBvZiBIQmFzZSdzIFpvb0tlZXBlcgorICAgICAgZmlsZXMgdGhhdCBhcmUgY29uZmlndXJlZCB3aXRoIGEgcmVsYXRpdmUgcGF0aCB3aWxsIGdvIHVuZGVyIHRoaXMgbm9kZS4KKyAgICAgIEJ5IGRlZmF1bHQsIGFsbCBvZiBIQmFzZSdzIFpvb0tlZXBlciBmaWxlIHBhdHNoIGFyZSBjb25maWd1cmVkIHdpdGggYQorICAgICAgcmVsYXRpdmUgcGF0aCwgc28gdGhleSB3aWxsIGFsbCBnbyB1bmRlciB0aGlzIGRpcmVjdG9yeSB1bmxlc3MgY2hhbmdlZC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+em9va2VlcGVyLnpub2RlLnJvb3RzZXJ2ZXI8L25hbWU+CisgICAgPHZhbHVlPnJvb3QtcmVnaW9uLXNlcnZlcjwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlBhdGggdG8gWk5vZGUgaG9sZGluZyByb290IHJlZ2lvbiBsb2NhdGlvbi4gVGhpcyBpcyB3cml0dGVuIGJ5CisgICAgICB0aGUgbWFzdGVyIGFuZCByZWFkIGJ5IGNsaWVudHMgYW5kIHJlZ2lvbiBzZXJ2ZXJzLiBJZiBhIHJlbGF0aXZlIHBhdGggaXMKKyAgICAgIGdpdmVuLCB0aGUgcGFyZW50IGZvbGRlciB3aWxsIGJlICR7em9va2VlcGVyLnpub2RlLnBhcmVudH0uIEJ5IGRlZmF1bHQsCisgICAgICB0aGlzIG1lYW5zIHRoZSByb290IGxvY2F0aW9uIGlzIHN0b3JlZCBhdCAvaGJhc2Uvcm9vdC1yZWdpb24tc2VydmVyLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT56b29rZWVwZXIuem5vZGUuc2FmZW1vZGU8L25hbWU+CisgICAgPHZhbHVlPnNhZmUtbW9kZTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlBhdGggdG8gZXBoZW1lcmFsIFpOb2RlIHNpZ25pZnlpbmcgY2x1c3RlciBpcyBvdXQgb2Ygc2FmZSBtb2RlLgorICAgICAgVGhpcyBpcyBjcmVhdGVkIGJ5IHRoZSBtYXN0ZXIgd2hlbiBzY2FubmluZyBpcyBkb25lLiBDbGllbnRzIHdhaXQgZm9yIHRoaXMKKyAgICAgIG5vZGUgYmVmb3JlIHF1ZXJ5aW5nIHRoZSBjbHVzdGVyLiBJZiBhIHJlbGF0aXZlIHBhdGggaXMgZ2l2ZW4sIHRoZSBwYXJlbnQKKyAgICAgIGZvbGRlciB3aWxsIGJlICR7em9va2VlcGVyLnpub2RlLnBhcmVudH0uIEJ5IGRlZmF1bHQsIHRoaXMgbWVhbnMgdGhlIHNhZmUKKyAgICAgIG1vZGUgZmxhZyBpcyBzdG9yZWQgYXQgL2hiYXNlL3NhZmUtbW9kZS4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorPC9jb25maWd1cmF0aW9uPgpkaWZmIC0tZ2l0IGEvY29uZi9oYmFzZS1lbnYuc2ggYi9jb25mL2hiYXNlLWVudi5zaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NGZhNGM1Ci0tLSAvZGV2L251bGwKKysrIGIvY29uZi9oYmFzZS1lbnYuc2gKQEAgLTAsMCArMSw2MCBAQAorIworIy8qKgorIyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorIyAqCisjICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorIyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisjICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorIyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisjICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIyAqCisjICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIyAqCisjICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIyAqLworCisjIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgaGVyZS4KKworIyBUaGUgamF2YSBpbXBsZW1lbnRhdGlvbiB0byB1c2UuICBKYXZhIDEuNiByZXF1aXJlZC4KKyMgZXhwb3J0IEpBVkFfSE9NRT0vdXNyL2phdmEvamRrMS42LjAvCisKKyMgRXh0cmEgSmF2YSBDTEFTU1BBVEggZWxlbWVudHMuICBPcHRpb25hbC4KKyMgZXhwb3J0IEhCQVNFX0NMQVNTUEFUSD0KKworIyBUaGUgbWF4aW11bSBhbW91bnQgb2YgaGVhcCB0byB1c2UsIGluIE1CLiBEZWZhdWx0IGlzIDEwMDAuCisjIGV4cG9ydCBIQkFTRV9IRUFQU0laRT0xMDAwCisKKyMgRXh0cmEgSmF2YSBydW50aW1lIG9wdGlvbnMuICBFbXB0eSBieSBkZWZhdWx0LgorIyBleHBvcnQgSEJBU0VfT1BUUz0tc2VydmVyCisKKyMgRmlsZSBuYW1pbmcgaG9zdHMgb24gd2hpY2ggSFJlZ2lvblNlcnZlcnMgd2lsbCBydW4uICAkSEJBU0VfSE9NRS9jb25mL3JlZ2lvbnNlcnZlcnMgYnkgZGVmYXVsdC4KKyMgZXhwb3J0IEhCQVNFX1JFR0lPTlNFUlZFUlM9JHtIQkFTRV9IT01FfS9jb25mL3JlZ2lvbnNlcnZlcnMKKworIyBFeHRyYSBzc2ggb3B0aW9ucy4gIEVtcHR5IGJ5IGRlZmF1bHQuCisjIGV4cG9ydCBIQkFTRV9TU0hfT1BUUz0iLW8gQ29ubmVjdFRpbWVvdXQ9MSAtbyBTZW5kRW52PUhCQVNFX0NPTkZfRElSIgorCisjIFdoZXJlIGxvZyBmaWxlcyBhcmUgc3RvcmVkLiAgJEhCQVNFX0hPTUUvbG9ncyBieSBkZWZhdWx0LgorIyBleHBvcnQgSEJBU0VfTE9HX0RJUj0ke0hCQVNFX0hPTUV9L2xvZ3MKKworIyBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhpcyBpbnN0YW5jZSBvZiBoYmFzZS4gJFVTRVIgYnkgZGVmYXVsdC4KKyMgZXhwb3J0IEhCQVNFX0lERU5UX1NUUklORz0kVVNFUgorCisjIFRoZSBzY2hlZHVsaW5nIHByaW9yaXR5IGZvciBkYWVtb24gcHJvY2Vzc2VzLiAgU2VlICdtYW4gbmljZScuCisjIGV4cG9ydCBIQkFTRV9OSUNFTkVTUz0xMAorCisjIFRoZSBkaXJlY3Rvcnkgd2hlcmUgcGlkIGZpbGVzIGFyZSBzdG9yZWQuIC90bXAgYnkgZGVmYXVsdC4KKyMgZXhwb3J0IEhCQVNFX1BJRF9ESVI9L3Zhci9oYWRvb3AvcGlkcworCisjIFNlY29uZHMgdG8gc2xlZXAgYmV0d2VlbiBzbGF2ZSBjb21tYW5kcy4gIFVuc2V0IGJ5IGRlZmF1bHQuICBUaGlzCisjIGNhbiBiZSB1c2VmdWwgaW4gbGFyZ2UgY2x1c3RlcnMsIHdoZXJlLCBlLmcuLCBzbGF2ZSByc3luY3MgY2FuCisjIG90aGVyd2lzZSBhcnJpdmUgZmFzdGVyIHRoYW4gdGhlIG1hc3RlciBjYW4gc2VydmljZSB0aGVtLgorIyBleHBvcnQgSEJBU0VfU0xBVkVfU0xFRVA9MC4xCisKKyMgVGVsbCBIQmFzZSB3aGV0aGVyIGl0IHNob3VsZCBtYW5hZ2UgaXQncyBvd24gaW5zdGFuY2Ugb2YgWm9va2VlcGVyIG9yIG5vdC4KKyMgZXhwb3J0IEhCQVNFX01BTkFHRVNfWks9dHJ1ZQpkaWZmIC0tZ2l0IGEvY29uZi9oYmFzZS1zaXRlLnhtbCBiL2NvbmYvaGJhc2Utc2l0ZS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJjY2QxZAotLS0gL2Rldi9udWxsCisrKyBiL2NvbmYvaGJhc2Utc2l0ZS54bWwKQEAgLTAsMCArMSwyNSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8P3htbC1zdHlsZXNoZWV0IHR5cGU9InRleHQveHNsIiBocmVmPSJjb25maWd1cmF0aW9uLnhzbCI/PgorPCEtLQorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCistLT4KKzxjb25maWd1cmF0aW9uPgorPC9jb25maWd1cmF0aW9uPgpkaWZmIC0tZ2l0IGEvY29uZi9sb2c0ai5wcm9wZXJ0aWVzIGIvY29uZi9sb2c0ai5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkOGZhYjgKLS0tIC9kZXYvbnVsbAorKysgYi9jb25mL2xvZzRqLnByb3BlcnRpZXMKQEAgLTAsMCArMSw0NiBAQAorIyBEZWZpbmUgc29tZSBkZWZhdWx0IHZhbHVlcyB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGJ5IHN5c3RlbSBwcm9wZXJ0aWVzCitoYmFzZS5yb290LmxvZ2dlcj1JTkZPLGNvbnNvbGUKK2hiYXNlLmxvZy5kaXI9LgoraGJhc2UubG9nLmZpbGU9aGJhc2UubG9nCisKKyMgRGVmaW5lIHRoZSByb290IGxvZ2dlciB0byB0aGUgc3lzdGVtIHByb3BlcnR5ICJoYmFzZS5yb290LmxvZ2dlciIuCitsb2c0ai5yb290TG9nZ2VyPSR7aGJhc2Uucm9vdC5sb2dnZXJ9CisKKyMgTG9nZ2luZyBUaHJlc2hvbGQKK2xvZzRqLnRocmVzaGhvbGQ9QUxMCisKKyMKKyMgRGFpbHkgUm9sbGluZyBGaWxlIEFwcGVuZGVyCisjCitsb2c0ai5hcHBlbmRlci5EUkZBPW9yZy5hcGFjaGUubG9nNGouRGFpbHlSb2xsaW5nRmlsZUFwcGVuZGVyCitsb2c0ai5hcHBlbmRlci5EUkZBLkZpbGU9JHtoYmFzZS5sb2cuZGlyfS8ke2hiYXNlLmxvZy5maWxlfQorCisjIFJvbGx2ZXIgYXQgbWlkbmlnaHQKK2xvZzRqLmFwcGVuZGVyLkRSRkEuRGF0ZVBhdHRlcm49Lnl5eXktTU0tZGQKKworIyAzMC1kYXkgYmFja3VwCisjbG9nNGouYXBwZW5kZXIuRFJGQS5NYXhCYWNrdXBJbmRleD0zMAorbG9nNGouYXBwZW5kZXIuRFJGQS5sYXlvdXQ9b3JnLmFwYWNoZS5sb2c0ai5QYXR0ZXJuTGF5b3V0CisKKyMgUGF0dGVybiBmb3JtYXQ6IERhdGUgTG9nTGV2ZWwgTG9nZ2VyTmFtZSBMb2dNZXNzYWdlCitsb2c0ai5hcHBlbmRlci5EUkZBLmxheW91dC5Db252ZXJzaW9uUGF0dGVybj0lZHtJU084NjAxfSAlcCAlYzogJW0lbgorCisjIERlYnVnZ2luZyBQYXR0ZXJuIGZvcm1hdAorI2xvZzRqLmFwcGVuZGVyLkRSRkEubGF5b3V0LkNvbnZlcnNpb25QYXR0ZXJuPSVke0lTTzg2MDF9ICUtNXAgJWN7Mn0gKCVGOiVNKCVMKSkgLSAlbSVuCisKKworIworIyBjb25zb2xlCisjIEFkZCAiY29uc29sZSIgdG8gcm9vdGxvZ2dlciBhYm92ZSBpZiB5b3Ugd2FudCB0byB1c2UgdGhpcyAKKyMKK2xvZzRqLmFwcGVuZGVyLmNvbnNvbGU9b3JnLmFwYWNoZS5sb2c0ai5Db25zb2xlQXBwZW5kZXIKK2xvZzRqLmFwcGVuZGVyLmNvbnNvbGUudGFyZ2V0PVN5c3RlbS5lcnIKK2xvZzRqLmFwcGVuZGVyLmNvbnNvbGUubGF5b3V0PW9yZy5hcGFjaGUubG9nNGouUGF0dGVybkxheW91dAorbG9nNGouYXBwZW5kZXIuY29uc29sZS5sYXlvdXQuQ29udmVyc2lvblBhdHRlcm49JWR7eXkvTU0vZGQgSEg6bW06c3N9ICVwICVjezJ9OiAlbSVuCisKKyMgQ3VzdG9tIExvZ2dpbmcgbGV2ZWxzCisKK2xvZzRqLmxvZ2dlci5vcmcuYXBhY2hlLnpvb2tlZXBlcj1FUlJPUgorI2xvZzRqLmxvZ2dlci5vcmcuYXBhY2hlLmhhZG9vcC5mcy5GU05hbWVzeXN0ZW09REVCVUcKKyNsb2c0ai5sb2dnZXIub3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U9REVCVUcKKyNsb2c0ai5sb2dnZXIub3JnLmFwYWNoZS5oYWRvb3AuZGZzPURFQlVHCmRpZmYgLS1naXQgYS9jb25mL3JlZ2lvbnNlcnZlcnMgYi9jb25mL3JlZ2lvbnNlcnZlcnMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmZiYjUwYwotLS0gL2Rldi9udWxsCisrKyBiL2NvbmYvcmVnaW9uc2VydmVycwpAQCAtMCwwICsxIEBACitsb2NhbGhvc3QKZGlmZiAtLWdpdCBhL2NvbmYvem9vLmNmZyBiL2NvbmYvem9vLmNmZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2RiNTkyCi0tLSAvZGV2L251bGwKKysrIGIvY29uZi96b28uY2ZnCkBAIC0wLDAgKzEsMTQgQEAKKyMgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgb2YgZWFjaCB0aWNrCit0aWNrVGltZT0yMDAwCisjIFRoZSBudW1iZXIgb2YgdGlja3MgdGhhdCB0aGUgaW5pdGlhbCAKKyMgc3luY2hyb25pemF0aW9uIHBoYXNlIGNhbiB0YWtlCitpbml0TGltaXQ9MTAKKyMgVGhlIG51bWJlciBvZiB0aWNrcyB0aGF0IGNhbiBwYXNzIGJldHdlZW4gCisjIHNlbmRpbmcgYSByZXF1ZXN0IGFuZCBnZXR0aW5nIGFuIGFja25vd2xlZGdlbWVudAorc3luY0xpbWl0PTUKKyMgdGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgc25hcHNob3QgaXMgc3RvcmVkLgorZGF0YURpcj0ke2hiYXNlLnRtcC5kaXJ9L3pvb2tlZXBlcgorIyB0aGUgcG9ydCBhdCB3aGljaCB0aGUgY2xpZW50cyB3aWxsIGNvbm5lY3QKK2NsaWVudFBvcnQ9MjE4MQorCitzZXJ2ZXIuMD0ke2hiYXNlLm1hc3Rlci5ob3N0bmFtZX06Mjg4ODozODg4ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZG9jcy9icm9rZW4tbGlua3MueG1sIGIvZG9jcy9icm9rZW4tbGlua3MueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5NWFhOWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL2Jyb2tlbi1saW5rcy54bWwKQEAgLTAsMCArMSwyIEBACis8YnJva2VuLWxpbmtzPgorPC9icm9rZW4tbGlua3M+CmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9idWlsdC13aXRoLWZvcnJlc3QtYnV0dG9uLnBuZyBiL2RvY3MvaW1hZ2VzL2J1aWx0LXdpdGgtZm9ycmVzdC1idXR0b24ucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhNzg3YWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL2ltYWdlcy9idWlsdC13aXRoLWZvcnJlc3QtYnV0dG9uLnBuZwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9mYXZpY29uLmljbyBiL2RvY3MvaW1hZ2VzL2Zhdmljb24uaWNvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MWJjZjcKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL2ltYWdlcy9mYXZpY29uLmljbwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9oYWRvb3AtbG9nby5qcGcgYi9kb2NzL2ltYWdlcy9oYWRvb3AtbG9nby5qcGcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODA5NTI1ZAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3MvaW1hZ2VzL2hhZG9vcC1sb2dvLmpwZwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9oYmFzZV9sb2dvX21lZC5naWYgYi9kb2NzL2ltYWdlcy9oYmFzZV9sb2dvX21lZC5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZkM2UzYwotLS0gL2Rldi9udWxsCisrKyBiL2RvY3MvaW1hZ2VzL2hiYXNlX2xvZ29fbWVkLmdpZgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9oYmFzZV9zbWFsbC5naWYgYi9kb2NzL2ltYWdlcy9oYmFzZV9zbWFsbC5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI3NTc2NQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3MvaW1hZ2VzL2hiYXNlX3NtYWxsLmdpZgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2ltYWdlcy9pbnN0cnVjdGlvbl9hcnJvdy5wbmcgYi9kb2NzL2ltYWdlcy9pbnN0cnVjdGlvbl9hcnJvdy5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZiYzcyNAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3MvaW1hZ2VzL2luc3RydWN0aW9uX2Fycm93LnBuZwpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9kb2NzL2luZGV4Lmh0bWwgYi9kb2NzL2luZGV4Lmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU3OTZlNQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3MvaW5kZXguaHRtbApAQCAtMCwwICsxLDIwNCBAQAorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L2xvb3NlLmR0ZCI+Cis8aHRtbD4KKzxoZWFkPgorPE1FVEEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgiPgorPG1ldGEgY29udGVudD0iQXBhY2hlIEZvcnJlc3QiIG5hbWU9IkdlbmVyYXRvciI+Cis8bWV0YSBuYW1lPSJGb3JyZXN0LXZlcnNpb24iIGNvbnRlbnQ9IjAuOCI+Cis8bWV0YSBuYW1lPSJGb3JyZXN0LXNraW4tbmFtZSIgY29udGVudD0icGVsdCI+Cis8dGl0bGU+SEJhc2UgRG9jdW1lbnRhdGlvbjwvdGl0bGU+Cis8bGluayB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9iYXNpYy5jc3MiIHJlbD0ic3R5bGVzaGVldCI+Cis8bGluayBtZWRpYT0ic2NyZWVuIiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9zY3JlZW4uY3NzIiByZWw9InN0eWxlc2hlZXQiPgorPGxpbmsgbWVkaWE9InByaW50IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9wcmludC5jc3MiIHJlbD0ic3R5bGVzaGVldCI+Cis8bGluayB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9wcm9maWxlLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KKzxzY3JpcHQgc3JjPSJza2luL2dldEJsYW5rLmpzIiBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD48c2NyaXB0IHNyYz0ic2tpbi9nZXRNZW51LmpzIiBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD48c2NyaXB0IHNyYz0ic2tpbi9mb250c2l6ZS5qcyIgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+Cis8bGluayByZWw9InNob3J0Y3V0IGljb24iIGhyZWY9ImltYWdlcy9mYXZpY29uLmljbyI+Cis8L2hlYWQ+Cis8Ym9keSBvbmxvYWQ9ImluaXQoKSI+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+bmRlU2V0VGV4dFNpemUoKTs8L3NjcmlwdD4KKzxkaXYgaWQ9InRvcCI+Cis8IS0tKworICAgIHxicmVhZHRyYWlsCisgICAgKy0tPgorPGRpdiBjbGFzcz0iYnJlYWR0cmFpbCI+Cis8YSBocmVmPSJodHRwOi8vd3d3LmFwYWNoZS5vcmcvIj5BcGFjaGU8L2E+ICZndDsgPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnLyI+SGFkb29wPC9hPiAmZ3Q7IDxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS8iPkhCYXNlPC9hPjxzY3JpcHQgc3JjPSJza2luL2JyZWFkY3J1bWJzLmpzIiBsYW5ndWFnZT0iSmF2YVNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD4KKzwvZGl2PgorPCEtLSsKKyAgICB8aGVhZGVyCisgICAgKy0tPgorPGRpdiBjbGFzcz0iaGVhZGVyIj4KKzwhLS0rCisgICAgfHN0YXJ0IGdyb3VwIGxvZ28KKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJncm91cGxvZ28iPgorPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnLyI+PGltZyBjbGFzcz0ibG9nb0ltYWdlIiBhbHQ9IkhhZG9vcCIgc3JjPSJpbWFnZXMvaGFkb29wLWxvZ28uanBnIiB0aXRsZT0iQXBhY2hlIEhhZG9vcCI+PC9hPgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgZ3JvdXAgbG9nbworICAgICstLT4KKzwhLS0rCisgICAgfHN0YXJ0IFByb2plY3QgTG9nbworICAgICstLT4KKzxkaXYgY2xhc3M9InByb2plY3Rsb2dvIj4KKzxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS8iPjxpbWcgY2xhc3M9ImxvZ29JbWFnZSIgYWx0PSJIQmFzZSIgc3JjPSJpbWFnZXMvaGJhc2Vfc21hbGwuZ2lmIiB0aXRsZT0iVGhlIEhhZG9vcCBkYXRhYmFzZSI+PC9hPgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgUHJvamVjdCBMb2dvCisgICAgKy0tPgorPCEtLSsKKyAgICB8c3RhcnQgU2VhcmNoCisgICAgKy0tPgorPGRpdiBjbGFzcz0ic2VhcmNoYm94Ij4KKzxmb3JtIGFjdGlvbj0iaHR0cDovL3d3dy5nb29nbGUuY29tL3NlYXJjaCIgbWV0aG9kPSJnZXQiIGNsYXNzPSJyb3VuZHRvcHNtYWxsIj4KKzxpbnB1dCB2YWx1ZT0iaGFkb29wLmFwYWNoZS5vcmciIG5hbWU9InNpdGVzZWFyY2giIHR5cGU9ImhpZGRlbiI+PGlucHV0IG9uRm9jdXM9ImdldEJsYW5rICh0aGlzLCAnU2VhcmNoIHRoZSBzaXRlIHdpdGggZ29vZ2xlJyk7IiBzaXplPSIyNSIgbmFtZT0icSIgaWQ9InF1ZXJ5IiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iU2VhcmNoIHRoZSBzaXRlIHdpdGggZ29vZ2xlIj4mbmJzcDsgCisgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBuYW1lPSJTZWFyY2giIHZhbHVlPSJTZWFyY2giIHR5cGU9InN1Ym1pdCI+Cis8L2Zvcm0+Cis8L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBzZWFyY2gKKyAgICArLS0+Cis8IS0tKworICAgIHxzdGFydCBUYWJzCisgICAgKy0tPgorPHVsIGlkPSJ0YWJzIj4KKzxsaT4KKzxhIGNsYXNzPSJ1bnNlbGVjdGVkIiBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvIj5Qcm9qZWN0PC9hPgorPC9saT4KKzxsaT4KKzxhIGNsYXNzPSJ1bnNlbGVjdGVkIiBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZSI+V2lraTwvYT4KKzwvbGk+Cis8bGkgY2xhc3M9ImN1cnJlbnQiPgorPGEgY2xhc3M9InNlbGVjdGVkIiBocmVmPSJpbmRleC5odG1sIj5IQmFzZSBEb2N1bWVudGF0aW9uPC9hPgorPC9saT4KKzwvdWw+Cis8IS0tKworICAgIHxlbmQgVGFicworICAgICstLT4KKzwvZGl2PgorPC9kaXY+Cis8ZGl2IGlkPSJtYWluIj4KKzxkaXYgaWQ9InB1Ymxpc2hlZFN0cmlwIj4KKzwhLS0rCisgICAgfHN0YXJ0IFN1YnRhYnMKKyAgICArLS0+Cis8ZGl2IGlkPSJsZXZlbDJ0YWJzIj48L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBFbmR0YWJzCisgICAgKy0tPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwhLS0KK2RvY3VtZW50LndyaXRlKCJMYXN0IFB1Ymxpc2hlZDogIiArIGRvY3VtZW50Lmxhc3RNb2RpZmllZCk7CisvLyAgLS0+PC9zY3JpcHQ+Cis8L2Rpdj4KKzwhLS0rCisgICAgfGJyZWFkdHJhaWwKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJicmVhZHRyYWlsIj4KKworICAgICAgICAgICAgICZuYnNwOworICAgICAgICAgICA8L2Rpdj4KKzwhLS0rCisgICAgfHN0YXJ0IE1lbnUsIG1haW5hcmVhCisgICAgKy0tPgorPCEtLSsKKyAgICB8c3RhcnQgTWVudQorICAgICstLT4KKzxkaXYgaWQ9Im1lbnUiPgorPGRpdiBvbmNsaWNrPSJTd2l0Y2hNZW51KCdtZW51X3NlbGVjdGVkXzEuMScsICdza2luLycpIiBpZD0ibWVudV9zZWxlY3RlZF8xLjFUaXRsZSIgY2xhc3M9Im1lbnV0aXRsZSIgc3R5bGU9ImJhY2tncm91bmQtaW1hZ2U6IHVybCgnc2tpbi9pbWFnZXMvY2hhcHRlcl9vcGVuLmdpZicpOyI+RG9jdW1lbnRhdGlvbjwvZGl2PgorPGRpdiBpZD0ibWVudV9zZWxlY3RlZF8xLjEiIGNsYXNzPSJzZWxlY3RlZG1lbnVpdGVtZ3JvdXAiIHN0eWxlPSJkaXNwbGF5OiBibG9jazsiPgorPGRpdiBjbGFzcz0ibWVudXBhZ2UiPgorPGRpdiBjbGFzcz0ibWVudXBhZ2V0aXRsZSI+T3ZlcnZpZXc8L2Rpdj4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudWl0ZW0iPgorPGEgaHJlZj0iYXBpL292ZXJ2aWV3LXN1bW1hcnkuaHRtbCNvdmVydmlld19kZXNjcmlwdGlvbiI+R2V0dGluZyBTdGFydGVkPC9hPgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJhcGkvaW5kZXguaHRtbCI+QVBJIERvY3M8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9Im1ldHJpY3MuaHRtbCI+SEJhc2UgTWV0cmljczwvYT4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudWl0ZW0iPgorPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UiPldpa2k8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlL0ZBUSI+RkFRPC9hPgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvbWFpbGluZ19saXN0cy5odG1sIj5NYWlsaW5nIExpc3RzPC9hPgorPC9kaXY+Cis8L2Rpdj4KKzxkaXYgaWQ9ImNyZWRpdCI+Cis8aHI+Cis8YSBocmVmPSJodHRwOi8vZm9ycmVzdC5hcGFjaGUub3JnLyI+PGltZyBib3JkZXI9IjAiIHRpdGxlPSJCdWlsdCB3aXRoIEFwYWNoZSBGb3JyZXN0IiBhbHQ9IkJ1aWx0IHdpdGggQXBhY2hlIEZvcnJlc3QgLSBsb2dvIiBzcmM9ImltYWdlcy9idWlsdC13aXRoLWZvcnJlc3QtYnV0dG9uLnBuZyIgc3R5bGU9IndpZHRoOiA4OHB4O2hlaWdodDogMzFweDsiPjwvYT4KKzwvZGl2PgorPGRpdiBpZD0icm91bmRib3R0b20iPgorPGltZyBzdHlsZT0iZGlzcGxheTogbm9uZSIgY2xhc3M9ImNvcm5lciIgaGVpZ2h0PSIxNSIgd2lkdGg9IjE1IiBhbHQ9IiIgc3JjPSJza2luL2ltYWdlcy9yYy1iLWwtMTUtMWJvZHktMm1lbnUtM21lbnUucG5nIj48L2Rpdj4KKzwhLS0rCisgIHxhbHRlcm5hdGl2ZSBjcmVkaXRzCisgICstLT4KKzxkaXYgaWQ9ImNyZWRpdDIiPjwvZGl2PgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgTWVudQorICAgICstLT4KKzwhLS0rCisgICAgfHN0YXJ0IGNvbnRlbnQKKyAgICArLS0+Cis8ZGl2IGlkPSJjb250ZW50Ij4KKzxkaXYgdGl0bGU9IlBvcnRhYmxlIERvY3VtZW50IEZvcm1hdCIgY2xhc3M9InBkZmxpbmsiPgorPGEgY2xhc3M9ImRpZGEiIGhyZWY9ImluZGV4LnBkZiI+PGltZyBhbHQ9IlBERiAtaWNvbiIgc3JjPSJza2luL2ltYWdlcy9wZGZkb2MuZ2lmIiBjbGFzcz0ic2tpbiI+PGJyPgorICAgICAgICBQREY8L2E+Cis8L2Rpdj4KKzxoMT5IQmFzZSBEb2N1bWVudGF0aW9uPC9oMT4KKyAgICAKKzxwPgorICAgIFRoZSBmb2xsb3dpbmcgZG9jdW1lbnRzIHByb3ZpZGUgY29uY2VwdHMgYW5kIHByb2NlZHVyZXMgdGhhdCB3aWxsIGhlbHAgeW91IAorICAgIGdldCBzdGFydGVkIHVzaW5nIEhCYXNlLiBJZiB5b3UgaGF2ZSBtb3JlIHF1ZXN0aW9ucywgeW91IGNhbiBhc2sgdGhlIAorICAgIDxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS9tYWlsaW5nX2xpc3RzLmh0bWwiPm1haWxpbmcgbGlzdDwvYT4gb3IgYnJvd3NlIHRoZSBhcmNoaXZlcy4KKyAgICA8L3A+CisgICAgCis8dWw+CisgICAgICAKKzxsaT4KKzxhIGhyZWY9ImFwaS9vdmVydmlldy1zdW1tYXJ5Lmh0bWwjb3ZlcnZpZXdfZGVzY3JpcHRpb24iPkdldHRpbmcgU3RhcnRlZDwvYT4KKzwvbGk+CisgICAgICAKKzxsaT4KKzxhIGhyZWY9ImFwaS9pbmRleC5odG1sIj5BUEkgRG9jczwvYT4KKzwvbGk+CisgICAgICAKKzxsaT4KKzxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlIj5XaWtpPC9hPgorPC9saT4KKyAgICAgIAorPGxpPgorPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UvRkFRIj5GQVE8L2E+Cis8L2xpPgorICAgIAorPC91bD4KKyAgCis8L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBjb250ZW50CisgICAgKy0tPgorPGRpdiBjbGFzcz0iY2xlYXJib3RoIj4mbmJzcDs8L2Rpdj4KKzwvZGl2PgorPGRpdiBpZD0iZm9vdGVyIj4KKzwhLS0rCisgICAgfHN0YXJ0IGJvdHRvbXN0cmlwCisgICAgKy0tPgorPGRpdiBjbGFzcz0ibGFzdG1vZGlmaWVkIj4KKzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48IS0tCitkb2N1bWVudC53cml0ZSgiTGFzdCBQdWJsaXNoZWQ6ICIgKyBkb2N1bWVudC5sYXN0TW9kaWZpZWQpOworLy8gIC0tPjwvc2NyaXB0PgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJjb3B5cmlnaHQiPgorICAgICAgICBDb3B5cmlnaHQgJmNvcHk7CisgICAgICAgICAyMDA4IDxhIGhyZWY9Imh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8iPlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi48L2E+Cis8L2Rpdj4KKzxkaXYgaWQ9ImxvZ29zIj48L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBib3R0b21zdHJpcAorICAgICstLT4KKzwvZGl2PgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvZG9jcy9pbmRleC5wZGYgYi9kb2NzL2luZGV4LnBkZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzVkMTA4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9pbmRleC5wZGYKQEAgLTAsMCArMSwxNTcgQEAKKyVQREYtMS4zCislqqusrQorNCAwIG9iagorPDwgL1R5cGUgL0luZm8KKy9Qcm9kdWNlciAoRk9QIDAuMjAuNSkgPj4KK2VuZG9iagorNSAwIG9iagorPDwgL0xlbmd0aCA4MTAgL0ZpbHRlciBbIC9BU0NJSTg1RGVjb2RlIC9GbGF0ZURlY29kZSBdCisgPj4KK3N0cmVhbQorR2F0PSpjI1Q6LShxZkdTM1tRWWIuWU5LNUJYYCxRU3NsKzkqMUBvc2FNN3AnI0QjJGBxb1tuZ19AQFdKYHM2c0ZePjhgZzhGZU5WXjhzR0kjdCxvaTM5Xi4mMyFhJlQkXXQ0cCs/WVxbIkA6P0U1ZFVdRW1YP11zYW1bJlliUUBKJG1bSGMkL1soVlEuN0E6aHJkc0AzaWhYQi8qVHIqMzEnVy5wM2hlJVMyIl5TJERCbTslKi9aNCU2WVhqdGMtV1UvcV1gR2ombEJzJkIyPUFiRj4/KT5CajVYbzZCZkhMNiYyMGMlRWB0LDFbJixPIyVaTWhQImYxPzRSTG1vW2NlQXFMKSp1Umt0IjtMJT1bKlZMdW4wYEMydGg+JGJgclEqal8wKUFyO2VeWkpwdExHM2NmTXImbylXU0JhImVyO1tndStXKyphXGJANEltXkldaFs4XSsmN25TOz41VClQM1tJYEgxVVM1OUVeX2hUMVlxanRPN0InNVw7IyIhWiQrb0Usbi85MjpKWUtwb0hLcyo1YEYuPl8+KSgzZTJTRT1BLVAuOWlVdC9kSlJyblxcaVpTJWdnPmI2RDhSQ2JvS108aGZCPTgqOStVYFZtKFFAVFBFJVZMb2ZndGwoJm45aCtOcFNGb185KjQnOV1yN1srKmM4WVlNMyVFLipqTmZUOWxsdUgoYSNhZCU7WyZOVjgnbGRJaCQrZzswQCRBQ1Uybl1mb1szX2s9PmspPiQkUk5uYkpUN3MmZlVJSVpXQzpBZExSYWE8NldyIypJRkpZSmYqImFrbDFab1hMVkIlOCVYWUtAWl5pcDYyWTZbXW1uKW9OTiswalVVciUjMUM0ZkFcOXRsTSxBJjJpTi10b2djbl9ePG5YPzAjUTYhQmUjWjZnN1lKbjBhYF8jNzFkQk9lL1c5LydzKnU7PSpLMDRUaVFYcVYoaE5qI2g6SE8zZyRVVHBLZVk9aE8qWCsiXU8icU4pM25ZSW1KOWRaJjk4N1lKbUEhYDNoSi4mb0VwIV5CKVwybGBTaExCUGhIbC9wWS5uLjVcMSwjOCFXYjpCfj4KK2VuZHN0cmVhbQorZW5kb2JqCis2IDAgb2JqCis8PCAvVHlwZSAvUGFnZQorL1BhcmVudCAxIDAgUgorL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXQorL1Jlc291cmNlcyAzIDAgUgorL0NvbnRlbnRzIDUgMCBSCisvQW5ub3RzIDcgMCBSCis+PgorZW5kb2JqCis3IDAgb2JqCitbCis4IDAgUgorOSAwIFIKKzEwIDAgUgorMTEgMCBSCisxMiAwIFIKK10KK2VuZG9iagorOCAwIG9iagorPDwgL1R5cGUgL0Fubm90CisvU3VidHlwZSAvTGluaworL1JlY3QgWyAzNzAuOTU2IDU3Mi42IDQyNS4zMDQgNTYwLjYgXQorL0MgWyAwIDAgMCBdCisvQm9yZGVyIFsgMCAwIDAgXQorL0EgPDwgL1VSSSAoaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlL21haWxpbmdfbGlzdHMuaHRtbCkKKy9TIC9VUkkgPj4KKy9IIC9JCis+PgorZW5kb2JqCis5IDAgb2JqCis8PCAvVHlwZSAvQW5ub3QKKy9TdWJ0eXBlIC9MaW5rCisvUmVjdCBbIDEwOC4wIDU1NS40IDE4MC45OTYgNTQzLjQgXQorL0MgWyAwIDAgMCBdCisvQm9yZGVyIFsgMCAwIDAgXQorL0EgPDwgL1VSSSAoYXBpL292ZXJ2aWV3LXN1bW1hcnkuaHRtbCNvdmVydmlld19kZXNjcmlwdGlvbikKKy9TIC9VUkkgPj4KKy9IIC9JCis+PgorZW5kb2JqCisxMCAwIG9iagorPDwgL1R5cGUgL0Fubm90CisvU3VidHlwZSAvTGluaworL1JlY3QgWyAxMDguMCA1NDIuMiAxNTQuOTkyIDUzMC4yIF0KKy9DIFsgMCAwIDAgXQorL0JvcmRlciBbIDAgMCAwIF0KKy9BIDw8IC9VUkkgKGFwaS9pbmRleC5odG1sKQorL1MgL1VSSSA+PgorL0ggL0kKKz4+CitlbmRvYmoKKzExIDAgb2JqCis8PCAvVHlwZSAvQW5ub3QKKy9TdWJ0eXBlIC9MaW5rCisvUmVjdCBbIDEwOC4wIDUyOS4wIDEzMi4wIDUxNy4wIF0KKy9DIFsgMCAwIDAgXQorL0JvcmRlciBbIDAgMCAwIF0KKy9BIDw8IC9VUkkgKGh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlKQorL1MgL1VSSSA+PgorL0ggL0kKKz4+CitlbmRvYmoKKzEyIDAgb2JqCis8PCAvVHlwZSAvQW5ub3QKKy9TdWJ0eXBlIC9MaW5rCisvUmVjdCBbIDEwOC4wIDUxNS44IDEzMi4wIDUwMy44IF0KKy9DIFsgMCAwIDAgXQorL0JvcmRlciBbIDAgMCAwIF0KKy9BIDw8IC9VUkkgKGh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlL0ZBUSkKKy9TIC9VUkkgPj4KKy9IIC9JCis+PgorZW5kb2JqCisxMyAwIG9iagorPDwgL1R5cGUgL0ZvbnQKKy9TdWJ0eXBlIC9UeXBlMQorL05hbWUgL0YzCisvQmFzZUZvbnQgL0hlbHZldGljYS1Cb2xkCisvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgorZW5kb2JqCisxNCAwIG9iagorPDwgL1R5cGUgL0ZvbnQKKy9TdWJ0eXBlIC9UeXBlMQorL05hbWUgL0Y1CisvQmFzZUZvbnQgL1RpbWVzLVJvbWFuCisvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgorZW5kb2JqCisxNSAwIG9iagorPDwgL1R5cGUgL0ZvbnQKKy9TdWJ0eXBlIC9UeXBlMQorL05hbWUgL0YxCisvQmFzZUZvbnQgL0hlbHZldGljYQorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMTYgMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GMgorL0Jhc2VGb250IC9IZWx2ZXRpY2EtT2JsaXF1ZQorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMSAwIG9iagorPDwgL1R5cGUgL1BhZ2VzCisvQ291bnQgMQorL0tpZHMgWzYgMCBSIF0gPj4KK2VuZG9iagorMiAwIG9iagorPDwgL1R5cGUgL0NhdGFsb2cKKy9QYWdlcyAxIDAgUgorID4+CitlbmRvYmoKKzMgMCBvYmoKKzw8IAorL0ZvbnQgPDwgL0YzIDEzIDAgUiAvRjUgMTQgMCBSIC9GMSAxNSAwIFIgL0YyIDE2IDAgUiA+PiAKKy9Qcm9jU2V0IFsgL1BERiAvSW1hZ2VDIC9UZXh0IF0gPj4gCitlbmRvYmoKK3hyZWYKKzAgMTcKKzAwMDAwMDAwMDAgNjU1MzUgZiAKKzAwMDAwMDI1MTAgMDAwMDAgbiAKKzAwMDAwMDI1NjggMDAwMDAgbiAKKzAwMDAwMDI2MTggMDAwMDAgbiAKKzAwMDAwMDAwMTUgMDAwMDAgbiAKKzAwMDAwMDAwNzEgMDAwMDAgbiAKKzAwMDAwMDA5NzIgMDAwMDAgbiAKKzAwMDAwMDEwOTIgMDAwMDAgbiAKKzAwMDAwMDExNDQgMDAwMDAgbiAKKzAwMDAwMDEzNDIgMDAwMDAgbiAKKzAwMDAwMDE1MzUgMDAwMDAgbiAKKzAwMDAwMDE2OTcgMDAwMDAgbiAKKzAwMDAwMDE4NzggMDAwMDAgbiAKKzAwMDAwMDIwNjMgMDAwMDAgbiAKKzAwMDAwMDIxNzYgMDAwMDAgbiAKKzAwMDAwMDIyODYgMDAwMDAgbiAKKzAwMDAwMDIzOTQgMDAwMDAgbiAKK3RyYWlsZXIKKzw8CisvU2l6ZSAxNworL1Jvb3QgMiAwIFIKKy9JbmZvIDQgMCBSCis+Pgorc3RhcnR4cmVmCisyNzMwCislJUVPRgpkaWZmIC0tZ2l0IGEvZG9jcy9saW5rbWFwLmh0bWwgYi9kb2NzL2xpbmttYXAuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZjJmNzg4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9saW5rbWFwLmh0bWwKQEAgLTAsMCArMSwyMzkgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9sb29zZS5kdGQiPgorPGh0bWw+Cis8aGVhZD4KKzxNRVRBIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKzxtZXRhIGNvbnRlbnQ9IkFwYWNoZSBGb3JyZXN0IiBuYW1lPSJHZW5lcmF0b3IiPgorPG1ldGEgbmFtZT0iRm9ycmVzdC12ZXJzaW9uIiBjb250ZW50PSIwLjgiPgorPG1ldGEgbmFtZT0iRm9ycmVzdC1za2luLW5hbWUiIGNvbnRlbnQ9InBlbHQiPgorPHRpdGxlPlNpdGUgTGlua21hcCBUYWJsZSBvZiBDb250ZW50czwvdGl0bGU+Cis8bGluayB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9iYXNpYy5jc3MiIHJlbD0ic3R5bGVzaGVldCI+Cis8bGluayBtZWRpYT0ic2NyZWVuIiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9zY3JlZW4uY3NzIiByZWw9InN0eWxlc2hlZXQiPgorPGxpbmsgbWVkaWE9InByaW50IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9wcmludC5jc3MiIHJlbD0ic3R5bGVzaGVldCI+Cis8bGluayB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0ic2tpbi9wcm9maWxlLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KKzxzY3JpcHQgc3JjPSJza2luL2dldEJsYW5rLmpzIiBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD48c2NyaXB0IHNyYz0ic2tpbi9nZXRNZW51LmpzIiBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD48c2NyaXB0IHNyYz0ic2tpbi9mb250c2l6ZS5qcyIgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+Cis8bGluayByZWw9InNob3J0Y3V0IGljb24iIGhyZWY9ImltYWdlcy9mYXZpY29uLmljbyI+Cis8L2hlYWQ+Cis8Ym9keSBvbmxvYWQ9ImluaXQoKSI+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+bmRlU2V0VGV4dFNpemUoKTs8L3NjcmlwdD4KKzxkaXYgaWQ9InRvcCI+Cis8IS0tKworICAgIHxicmVhZHRyYWlsCisgICAgKy0tPgorPGRpdiBjbGFzcz0iYnJlYWR0cmFpbCI+Cis8YSBocmVmPSJodHRwOi8vd3d3LmFwYWNoZS5vcmcvIj5BcGFjaGU8L2E+ICZndDsgPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnLyI+SGFkb29wPC9hPiAmZ3Q7IDxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS8iPkhCYXNlPC9hPjxzY3JpcHQgc3JjPSJza2luL2JyZWFkY3J1bWJzLmpzIiBsYW5ndWFnZT0iSmF2YVNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD4KKzwvZGl2PgorPCEtLSsKKyAgICB8aGVhZGVyCisgICAgKy0tPgorPGRpdiBjbGFzcz0iaGVhZGVyIj4KKzwhLS0rCisgICAgfHN0YXJ0IGdyb3VwIGxvZ28KKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJncm91cGxvZ28iPgorPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnLyI+PGltZyBjbGFzcz0ibG9nb0ltYWdlIiBhbHQ9IkhhZG9vcCIgc3JjPSJpbWFnZXMvaGFkb29wLWxvZ28uanBnIiB0aXRsZT0iQXBhY2hlIEhhZG9vcCI+PC9hPgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgZ3JvdXAgbG9nbworICAgICstLT4KKzwhLS0rCisgICAgfHN0YXJ0IFByb2plY3QgTG9nbworICAgICstLT4KKzxkaXYgY2xhc3M9InByb2plY3Rsb2dvIj4KKzxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS8iPjxpbWcgY2xhc3M9ImxvZ29JbWFnZSIgYWx0PSJIQmFzZSIgc3JjPSJpbWFnZXMvaGJhc2Vfc21hbGwuZ2lmIiB0aXRsZT0iVGhlIEhhZG9vcCBkYXRhYmFzZSI+PC9hPgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgUHJvamVjdCBMb2dvCisgICAgKy0tPgorPCEtLSsKKyAgICB8c3RhcnQgU2VhcmNoCisgICAgKy0tPgorPGRpdiBjbGFzcz0ic2VhcmNoYm94Ij4KKzxmb3JtIGFjdGlvbj0iaHR0cDovL3d3dy5nb29nbGUuY29tL3NlYXJjaCIgbWV0aG9kPSJnZXQiIGNsYXNzPSJyb3VuZHRvcHNtYWxsIj4KKzxpbnB1dCB2YWx1ZT0iaGFkb29wLmFwYWNoZS5vcmciIG5hbWU9InNpdGVzZWFyY2giIHR5cGU9ImhpZGRlbiI+PGlucHV0IG9uRm9jdXM9ImdldEJsYW5rICh0aGlzLCAnU2VhcmNoIHRoZSBzaXRlIHdpdGggZ29vZ2xlJyk7IiBzaXplPSIyNSIgbmFtZT0icSIgaWQ9InF1ZXJ5IiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iU2VhcmNoIHRoZSBzaXRlIHdpdGggZ29vZ2xlIj4mbmJzcDsgCisgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBuYW1lPSJTZWFyY2giIHZhbHVlPSJTZWFyY2giIHR5cGU9InN1Ym1pdCI+Cis8L2Zvcm0+Cis8L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBzZWFyY2gKKyAgICArLS0+Cis8IS0tKworICAgIHxzdGFydCBUYWJzCisgICAgKy0tPgorPHVsIGlkPSJ0YWJzIj4KKzxsaT4KKzxhIGNsYXNzPSJ1bnNlbGVjdGVkIiBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvIj5Qcm9qZWN0PC9hPgorPC9saT4KKzxsaT4KKzxhIGNsYXNzPSJ1bnNlbGVjdGVkIiBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZSI+V2lraTwvYT4KKzwvbGk+Cis8bGkgY2xhc3M9ImN1cnJlbnQiPgorPGEgY2xhc3M9InNlbGVjdGVkIiBocmVmPSJpbmRleC5odG1sIj5IQmFzZSBEb2N1bWVudGF0aW9uPC9hPgorPC9saT4KKzwvdWw+Cis8IS0tKworICAgIHxlbmQgVGFicworICAgICstLT4KKzwvZGl2PgorPC9kaXY+Cis8ZGl2IGlkPSJtYWluIj4KKzxkaXYgaWQ9InB1Ymxpc2hlZFN0cmlwIj4KKzwhLS0rCisgICAgfHN0YXJ0IFN1YnRhYnMKKyAgICArLS0+Cis8ZGl2IGlkPSJsZXZlbDJ0YWJzIj48L2Rpdj4KKzwhLS0rCisgICAgfGVuZCBFbmR0YWJzCisgICAgKy0tPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwhLS0KK2RvY3VtZW50LndyaXRlKCJMYXN0IFB1Ymxpc2hlZDogIiArIGRvY3VtZW50Lmxhc3RNb2RpZmllZCk7CisvLyAgLS0+PC9zY3JpcHQ+Cis8L2Rpdj4KKzwhLS0rCisgICAgfGJyZWFkdHJhaWwKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJicmVhZHRyYWlsIj4KKworICAgICAgICAgICAgICZuYnNwOworICAgICAgICAgICA8L2Rpdj4KKzwhLS0rCisgICAgfHN0YXJ0IE1lbnUsIG1haW5hcmVhCisgICAgKy0tPgorPCEtLSsKKyAgICB8c3RhcnQgTWVudQorICAgICstLT4KKzxkaXYgaWQ9Im1lbnUiPgorPGRpdiBvbmNsaWNrPSJTd2l0Y2hNZW51KCdtZW51XzEuMScsICdza2luLycpIiBpZD0ibWVudV8xLjFUaXRsZSIgY2xhc3M9Im1lbnV0aXRsZSI+RG9jdW1lbnRhdGlvbjwvZGl2PgorPGRpdiBpZD0ibWVudV8xLjEiIGNsYXNzPSJtZW51aXRlbWdyb3VwIj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9ImluZGV4Lmh0bWwiPk92ZXJ2aWV3PC9hPgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJhcGkvb3ZlcnZpZXctc3VtbWFyeS5odG1sI292ZXJ2aWV3X2Rlc2NyaXB0aW9uIj5HZXR0aW5nIFN0YXJ0ZWQ8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9ImFwaS9pbmRleC5odG1sIj5BUEkgRG9jczwvYT4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudWl0ZW0iPgorPGEgaHJlZj0ibWV0cmljcy5odG1sIj5IQmFzZSBNZXRyaWNzPC9hPgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZSI+V2lraTwvYT4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudWl0ZW0iPgorPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UvRkFRIj5GQVE8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS9tYWlsaW5nX2xpc3RzLmh0bWwiPk1haWxpbmcgTGlzdHM8L2E+Cis8L2Rpdj4KKzwvZGl2PgorPGRpdiBpZD0iY3JlZGl0Ij48L2Rpdj4KKzxkaXYgaWQ9InJvdW5kYm90dG9tIj4KKzxpbWcgc3R5bGU9ImRpc3BsYXk6IG5vbmUiIGNsYXNzPSJjb3JuZXIiIGhlaWdodD0iMTUiIHdpZHRoPSIxNSIgYWx0PSIiIHNyYz0ic2tpbi9pbWFnZXMvcmMtYi1sLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyI+PC9kaXY+Cis8IS0tKworICB8YWx0ZXJuYXRpdmUgY3JlZGl0cworICArLS0+Cis8ZGl2IGlkPSJjcmVkaXQyIj48L2Rpdj4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIE1lbnUKKyAgICArLS0+Cis8IS0tKworICAgIHxzdGFydCBjb250ZW50CisgICAgKy0tPgorPGRpdiBpZD0iY29udGVudCI+Cis8ZGl2IHRpdGxlPSJQb3J0YWJsZSBEb2N1bWVudCBGb3JtYXQiIGNsYXNzPSJwZGZsaW5rIj4KKzxhIGNsYXNzPSJkaWRhIiBocmVmPSJsaW5rbWFwLnBkZiI+PGltZyBhbHQ9IlBERiAtaWNvbiIgc3JjPSJza2luL2ltYWdlcy9wZGZkb2MuZ2lmIiBjbGFzcz0ic2tpbiI+PGJyPgorICAgICAgICBQREY8L2E+Cis8L2Rpdj4KKzxoMT5TaXRlIExpbmttYXAgVGFibGUgb2YgQ29udGVudHM8L2gxPgorPHA+CisgICAgICAgICAgVGhpcyBpcyBhIG1hcCBvZiB0aGUgY29tcGxldGUgc2l0ZSBhbmQgaXRzIHN0cnVjdHVyZS4KKyAgICAgICAgPC9wPgorPHVsPgorPGxpPgorPGE+SGFkb29wPC9hPiZuYnNwOyZuYnNwO19fX19fX19fX19fX19fX19fX18mbmJzcDsmbmJzcDs8ZW0+c2l0ZTwvZW0+Cis8L2xpPgorPHVsPgorCisgIAorPHVsPgorPGxpPgorPGE+RG9jdW1lbnRhdGlvbjwvYT4mbmJzcDsmbmJzcDtfX19fX19fX19fX19fX19fX19fJm5ic3A7Jm5ic3A7PGVtPmRvY3M8L2VtPgorPC9saT4KKzx1bD4gCisgICAgCis8dWw+Cis8bGk+Cis8YSBocmVmPSJpbmRleC5odG1sIj5PdmVydmlldzwvYT4mbmJzcDsmbmJzcDtfX19fX19fX19fX19fX19fX19fJm5ic3A7Jm5ic3A7PGVtPm92ZXJ2aWV3PC9lbT4KKzwvbGk+Cis8L3VsPgorICAgIAorPHVsPgorPGxpPgorPGEgaHJlZj0iYXBpL292ZXJ2aWV3LXN1bW1hcnkuaHRtbCNvdmVydmlld19kZXNjcmlwdGlvbiI+R2V0dGluZyBTdGFydGVkPC9hPiZuYnNwOyZuYnNwO19fX19fX19fX19fX19fX19fX18mbmJzcDsmbmJzcDs8ZW0+c3RhcnRlZDwvZW0+Cis8L2xpPgorPC91bD4KKyAgICAKKzx1bD4KKzxsaT4KKzxhIGhyZWY9ImFwaS9pbmRleC5odG1sIj5BUEkgRG9jczwvYT4mbmJzcDsmbmJzcDtfX19fX19fX19fX19fX19fX19fJm5ic3A7Jm5ic3A7PGVtPmFwaTwvZW0+Cis8L2xpPgorPC91bD4KKyAgICAKKzx1bD4KKzxsaT4KKzxhIGhyZWY9Im1ldHJpY3MuaHRtbCI+SEJhc2UgTWV0cmljczwvYT4mbmJzcDsmbmJzcDtfX19fX19fX19fX19fX19fX19fJm5ic3A7Jm5ic3A7PGVtPmFwaTwvZW0+Cis8L2xpPgorPC91bD4KKyAgICAKKzx1bD4KKzxsaT4KKzxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlIj5XaWtpPC9hPiZuYnNwOyZuYnNwO19fX19fX19fX19fX19fX19fX18mbmJzcDsmbmJzcDs8ZW0+d2lraTwvZW0+Cis8L2xpPgorPC91bD4KKyAgICAKKzx1bD4KKzxsaT4KKzxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlL0ZBUSI+RkFRPC9hPiZuYnNwOyZuYnNwO19fX19fX19fX19fX19fX19fX18mbmJzcDsmbmJzcDs8ZW0+ZmFxPC9lbT4KKzwvbGk+Cis8L3VsPgorICAgIAorPHVsPgorPGxpPgorPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlL21haWxpbmdfbGlzdHMuaHRtbCI+TWFpbGluZyBMaXN0czwvYT4mbmJzcDsmbmJzcDtfX19fX19fX19fX19fX19fX19fJm5ic3A7Jm5ic3A7PGVtPmxpc3RzPC9lbT4KKzwvbGk+Cis8L3VsPgorICAKKzwvdWw+Cis8L3VsPgorCisgIAorIAorCis8L3VsPgorPC91bD4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIGNvbnRlbnQKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJjbGVhcmJvdGgiPiZuYnNwOzwvZGl2PgorPC9kaXY+Cis8ZGl2IGlkPSJmb290ZXIiPgorPCEtLSsKKyAgICB8c3RhcnQgYm90dG9tc3RyaXAKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJsYXN0bW9kaWZpZWQiPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwhLS0KK2RvY3VtZW50LndyaXRlKCJMYXN0IFB1Ymxpc2hlZDogIiArIGRvY3VtZW50Lmxhc3RNb2RpZmllZCk7CisvLyAgLS0+PC9zY3JpcHQ+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9ImNvcHlyaWdodCI+CisgICAgICAgIENvcHlyaWdodCAmY29weTsKKyAgICAgICAgIDIwMDggPGEgaHJlZj0iaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLyI+VGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLjwvYT4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIGJvdHRvbXN0cmlwCisgICAgKy0tPgorPC9kaXY+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9kb2NzL2xpbmttYXAucGRmIGIvZG9jcy9saW5rbWFwLnBkZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Y2I5ZWU4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9saW5rbWFwLnBkZgpAQCAtMCwwICsxLDk0IEBACislUERGLTEuMworJaqrrK0KKzQgMCBvYmoKKzw8IC9UeXBlIC9JbmZvCisvUHJvZHVjZXIgKEZPUCAwLjIwLjUpID4+CitlbmRvYmoKKzUgMCBvYmoKKzw8IC9MZW5ndGggNjk1IC9GaWx0ZXIgWyAvQVNDSUk4NURlY29kZSAvRmxhdGVEZWNvZGUgXQorID4+CitzdHJlYW0KK0dhdFVxZDtJXF0nU2MpVCdPN0xPQVVqZzlRViJmalJwJ1ovL0czSkMuVj1rSWVNNCR0KVhacClsbUNYaURRNHRFJmU8Il9ydUsjOTlbX2tCMV4mSXUiT19SR2xzQ01OWVF1cEpibmwjTmM+ZV9MYUNDPTdfIWZaRSkwbDY4OEpGKjZVS15fXllKZi1oVXVIPU9YbTxNOj9nNiJbZGFUKWslbk0xLGM0IisvM1ZWbEInTEBhbUI5dDVORCdiUVQpPlJlJEwyUjMjY3JrTyVaXW0pYG9QLlomajM/KXJPJG9DXzo8J1c/OXNyKmVWTlBvRU5YKzM+IWdFRD1ySy5aYjYqXz9cZj45TSFGSTJCU2FML0llMFtxIipeJlJGJnEpXmtUQEAvPTkwQTVHSCRwaENXVEdTPGtfbk8oITlFJistUm9RZTVfQy9dXU1BRlhFNmg/OlhTVUdTczBYaF5TMXFzLSs1QDghcFdvV2thLk1mbDRvPWciOk1dTyoxIk5DT1Noa1chLD5kdSI4MVNRV1s1RkpsLVRkOFRGY1spTDciSS1wIi8jV1FzblpWQmtvIipZPTtyOG04R0lWOTRmJzU0OFZzXm81ZCtxQWBtOGBBQDFtTCooZDlcQV9vR3AvTThELkJyNEspbjgxL05jOmVbTVs5MGNqUSsiJEcnJnJMI1hacGZ0SE9WYTVeNyVkbyEiSD9GMi1DMy5CITJOPE9AXjE1UD5bTFtkXEs5cyNyWz9pVTsmV0BSIlhZWVFeSlAoTj5FJCViaWhdcERCWTQnPVRVPElEIlFuYXRJIypLUCdXM2ElX2xbUDEnLzwrRllPK15wWCZWT1ZzJWtiT0ozKnFOZU8oV2NWW1xFPilWS3UyJ20wc0g6YSw3XztYYHMwT1o+VChaUjchPjtJcUsmOCdFfj4KK2VuZHN0cmVhbQorZW5kb2JqCis2IDAgb2JqCis8PCAvVHlwZSAvUGFnZQorL1BhcmVudCAxIDAgUgorL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXQorL1Jlc291cmNlcyAzIDAgUgorL0NvbnRlbnRzIDUgMCBSCis+PgorZW5kb2JqCis3IDAgb2JqCis8PCAvVHlwZSAvRm9udAorL1N1YnR5cGUgL1R5cGUxCisvTmFtZSAvRjMKKy9CYXNlRm9udCAvSGVsdmV0aWNhLUJvbGQKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzggMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GNQorL0Jhc2VGb250IC9UaW1lcy1Sb21hbgorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorOSAwIG9iagorPDwgL1R5cGUgL0ZvbnQKKy9TdWJ0eXBlIC9UeXBlMQorL05hbWUgL0Y2CisvQmFzZUZvbnQgL1RpbWVzLUl0YWxpYworL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMTAgMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GMQorL0Jhc2VGb250IC9IZWx2ZXRpY2EKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzExIDAgb2JqCis8PCAvVHlwZSAvRm9udAorL1N1YnR5cGUgL1R5cGUxCisvTmFtZSAvRjIKKy9CYXNlRm9udCAvSGVsdmV0aWNhLU9ibGlxdWUKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzEgMCBvYmoKKzw8IC9UeXBlIC9QYWdlcworL0NvdW50IDEKKy9LaWRzIFs2IDAgUiBdID4+CitlbmRvYmoKKzIgMCBvYmoKKzw8IC9UeXBlIC9DYXRhbG9nCisvUGFnZXMgMSAwIFIKKyA+PgorZW5kb2JqCiszIDAgb2JqCis8PCAKKy9Gb250IDw8IC9GMyA3IDAgUiAvRjUgOCAwIFIgL0YxIDEwIDAgUiAvRjYgOSAwIFIgL0YyIDExIDAgUiA+PiAKKy9Qcm9jU2V0IFsgL1BERiAvSW1hZ2VDIC9UZXh0IF0gPj4gCitlbmRvYmoKK3hyZWYKKzAgMTIKKzAwMDAwMDAwMDAgNjU1MzUgZiAKKzAwMDAwMDE1MTggMDAwMDAgbiAKKzAwMDAwMDE1NzYgMDAwMDAgbiAKKzAwMDAwMDE2MjYgMDAwMDAgbiAKKzAwMDAwMDAwMTUgMDAwMDAgbiAKKzAwMDAwMDAwNzEgMDAwMDAgbiAKKzAwMDAwMDA4NTcgMDAwMDAgbiAKKzAwMDAwMDA5NjMgMDAwMDAgbiAKKzAwMDAwMDEwNzUgMDAwMDAgbiAKKzAwMDAwMDExODQgMDAwMDAgbiAKKzAwMDAwMDEyOTQgMDAwMDAgbiAKKzAwMDAwMDE0MDIgMDAwMDAgbiAKK3RyYWlsZXIKKzw8CisvU2l6ZSAxMgorL1Jvb3QgMiAwIFIKKy9JbmZvIDQgMCBSCis+Pgorc3RhcnR4cmVmCisxNzQ2CislJUVPRgpkaWZmIC0tZ2l0IGEvZG9jcy9tZXRyaWNzLmh0bWwgYi9kb2NzL21ldHJpY3MuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmVlOTEwCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9tZXRyaWNzLmh0bWwKQEAgLTAsMCArMSwyMjcgQEAKKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9sb29zZS5kdGQiPgorPGh0bWw+Cis8aGVhZD4KKzxNRVRBIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KKzxtZXRhIGNvbnRlbnQ9IkFwYWNoZSBGb3JyZXN0IiBuYW1lPSJHZW5lcmF0b3IiPgorPG1ldGEgbmFtZT0iRm9ycmVzdC12ZXJzaW9uIiBjb250ZW50PSIwLjgiPgorPG1ldGEgbmFtZT0iRm9ycmVzdC1za2luLW5hbWUiIGNvbnRlbnQ9InBlbHQiPgorPHRpdGxlPiAKKyAgICAgIEhCYXNlIE1ldHJpY3MKKyAgICA8L3RpdGxlPgorPGxpbmsgdHlwZT0idGV4dC9jc3MiIGhyZWY9InNraW4vYmFzaWMuY3NzIiByZWw9InN0eWxlc2hlZXQiPgorPGxpbmsgbWVkaWE9InNjcmVlbiIgdHlwZT0idGV4dC9jc3MiIGhyZWY9InNraW4vc2NyZWVuLmNzcyIgcmVsPSJzdHlsZXNoZWV0Ij4KKzxsaW5rIG1lZGlhPSJwcmludCIgdHlwZT0idGV4dC9jc3MiIGhyZWY9InNraW4vcHJpbnQuY3NzIiByZWw9InN0eWxlc2hlZXQiPgorPGxpbmsgdHlwZT0idGV4dC9jc3MiIGhyZWY9InNraW4vcHJvZmlsZS5jc3MiIHJlbD0ic3R5bGVzaGVldCI+Cis8c2NyaXB0IHNyYz0ic2tpbi9nZXRCbGFuay5qcyIgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9InNraW4vZ2V0TWVudS5qcyIgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9InNraW4vZm9udHNpemUuanMiIGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwvc2NyaXB0PgorPGxpbmsgcmVsPSJzaG9ydGN1dCBpY29uIiBocmVmPSJpbWFnZXMvZmF2aWNvbi5pY28iPgorPC9oZWFkPgorPGJvZHkgb25sb2FkPSJpbml0KCkiPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPm5kZVNldFRleHRTaXplKCk7PC9zY3JpcHQ+Cis8ZGl2IGlkPSJ0b3AiPgorPCEtLSsKKyAgICB8YnJlYWR0cmFpbAorICAgICstLT4KKzxkaXYgY2xhc3M9ImJyZWFkdHJhaWwiPgorPGEgaHJlZj0iaHR0cDovL3d3dy5hcGFjaGUub3JnLyI+QXBhY2hlPC9hPiAmZ3Q7IDxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy8iPkhhZG9vcDwvYT4gJmd0OyA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvIj5IQmFzZTwvYT48c2NyaXB0IHNyYz0ic2tpbi9icmVhZGNydW1icy5qcyIgbGFuZ3VhZ2U9IkphdmFTY3JpcHQiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+Cis8L2Rpdj4KKzwhLS0rCisgICAgfGhlYWRlcgorICAgICstLT4KKzxkaXYgY2xhc3M9ImhlYWRlciI+Cis8IS0tKworICAgIHxzdGFydCBncm91cCBsb2dvCisgICAgKy0tPgorPGRpdiBjbGFzcz0iZ3JvdXBsb2dvIj4KKzxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy8iPjxpbWcgY2xhc3M9ImxvZ29JbWFnZSIgYWx0PSJIYWRvb3AiIHNyYz0iaW1hZ2VzL2hhZG9vcC1sb2dvLmpwZyIgdGl0bGU9IkFwYWNoZSBIYWRvb3AiPjwvYT4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIGdyb3VwIGxvZ28KKyAgICArLS0+Cis8IS0tKworICAgIHxzdGFydCBQcm9qZWN0IExvZ28KKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJwcm9qZWN0bG9nbyI+Cis8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvIj48aW1nIGNsYXNzPSJsb2dvSW1hZ2UiIGFsdD0iSEJhc2UiIHNyYz0iaW1hZ2VzL2hiYXNlX3NtYWxsLmdpZiIgdGl0bGU9IlRoZSBIYWRvb3AgZGF0YWJhc2UiPjwvYT4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIFByb2plY3QgTG9nbworICAgICstLT4KKzwhLS0rCisgICAgfHN0YXJ0IFNlYXJjaAorICAgICstLT4KKzxkaXYgY2xhc3M9InNlYXJjaGJveCI+Cis8Zm9ybSBhY3Rpb249Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS9zZWFyY2giIG1ldGhvZD0iZ2V0IiBjbGFzcz0icm91bmR0b3BzbWFsbCI+Cis8aW5wdXQgdmFsdWU9ImhhZG9vcC5hcGFjaGUub3JnIiBuYW1lPSJzaXRlc2VhcmNoIiB0eXBlPSJoaWRkZW4iPjxpbnB1dCBvbkZvY3VzPSJnZXRCbGFuayAodGhpcywgJ1NlYXJjaCB0aGUgc2l0ZSB3aXRoIGdvb2dsZScpOyIgc2l6ZT0iMjUiIG5hbWU9InEiIGlkPSJxdWVyeSIgdHlwZT0idGV4dCIgdmFsdWU9IlNlYXJjaCB0aGUgc2l0ZSB3aXRoIGdvb2dsZSI+Jm5ic3A7IAorICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbmFtZT0iU2VhcmNoIiB2YWx1ZT0iU2VhcmNoIiB0eXBlPSJzdWJtaXQiPgorPC9mb3JtPgorPC9kaXY+Cis8IS0tKworICAgIHxlbmQgc2VhcmNoCisgICAgKy0tPgorPCEtLSsKKyAgICB8c3RhcnQgVGFicworICAgICstLT4KKzx1bCBpZD0idGFicyI+Cis8bGk+Cis8YSBjbGFzcz0idW5zZWxlY3RlZCIgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlLyI+UHJvamVjdDwvYT4KKzwvbGk+Cis8bGk+Cis8YSBjbGFzcz0idW5zZWxlY3RlZCIgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UiPldpa2k8L2E+Cis8L2xpPgorPGxpIGNsYXNzPSJjdXJyZW50Ij4KKzxhIGNsYXNzPSJzZWxlY3RlZCIgaHJlZj0iaW5kZXguaHRtbCI+SEJhc2UgRG9jdW1lbnRhdGlvbjwvYT4KKzwvbGk+Cis8L3VsPgorPCEtLSsKKyAgICB8ZW5kIFRhYnMKKyAgICArLS0+Cis8L2Rpdj4KKzwvZGl2PgorPGRpdiBpZD0ibWFpbiI+Cis8ZGl2IGlkPSJwdWJsaXNoZWRTdHJpcCI+Cis8IS0tKworICAgIHxzdGFydCBTdWJ0YWJzCisgICAgKy0tPgorPGRpdiBpZD0ibGV2ZWwydGFicyI+PC9kaXY+Cis8IS0tKworICAgIHxlbmQgRW5kdGFicworICAgICstLT4KKzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48IS0tCitkb2N1bWVudC53cml0ZSgiTGFzdCBQdWJsaXNoZWQ6ICIgKyBkb2N1bWVudC5sYXN0TW9kaWZpZWQpOworLy8gIC0tPjwvc2NyaXB0PgorPC9kaXY+Cis8IS0tKworICAgIHxicmVhZHRyYWlsCisgICAgKy0tPgorPGRpdiBjbGFzcz0iYnJlYWR0cmFpbCI+CisKKyAgICAgICAgICAgICAmbmJzcDsKKyAgICAgICAgICAgPC9kaXY+Cis8IS0tKworICAgIHxzdGFydCBNZW51LCBtYWluYXJlYQorICAgICstLT4KKzwhLS0rCisgICAgfHN0YXJ0IE1lbnUKKyAgICArLS0+Cis8ZGl2IGlkPSJtZW51Ij4KKzxkaXYgb25jbGljaz0iU3dpdGNoTWVudSgnbWVudV9zZWxlY3RlZF8xLjEnLCAnc2tpbi8nKSIgaWQ9Im1lbnVfc2VsZWN0ZWRfMS4xVGl0bGUiIGNsYXNzPSJtZW51dGl0bGUiIHN0eWxlPSJiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJ3NraW4vaW1hZ2VzL2NoYXB0ZXJfb3Blbi5naWYnKTsiPkRvY3VtZW50YXRpb248L2Rpdj4KKzxkaXYgaWQ9Im1lbnVfc2VsZWN0ZWRfMS4xIiBjbGFzcz0ic2VsZWN0ZWRtZW51aXRlbWdyb3VwIiBzdHlsZT0iZGlzcGxheTogYmxvY2s7Ij4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9ImluZGV4Lmh0bWwiPk92ZXJ2aWV3PC9hPgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJhcGkvb3ZlcnZpZXctc3VtbWFyeS5odG1sI292ZXJ2aWV3X2Rlc2NyaXB0aW9uIj5HZXR0aW5nIFN0YXJ0ZWQ8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9ImFwaS9pbmRleC5odG1sIj5BUEkgRG9jczwvYT4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudXBhZ2UiPgorPGRpdiBjbGFzcz0ibWVudXBhZ2V0aXRsZSI+SEJhc2UgTWV0cmljczwvZGl2PgorPC9kaXY+Cis8ZGl2IGNsYXNzPSJtZW51aXRlbSI+Cis8YSBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZSI+V2lraTwvYT4KKzwvZGl2PgorPGRpdiBjbGFzcz0ibWVudWl0ZW0iPgorPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UvRkFRIj5GQVE8L2E+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9Im1lbnVpdGVtIj4KKzxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS9tYWlsaW5nX2xpc3RzLmh0bWwiPk1haWxpbmcgTGlzdHM8L2E+Cis8L2Rpdj4KKzwvZGl2PgorPGRpdiBpZD0iY3JlZGl0Ij48L2Rpdj4KKzxkaXYgaWQ9InJvdW5kYm90dG9tIj4KKzxpbWcgc3R5bGU9ImRpc3BsYXk6IG5vbmUiIGNsYXNzPSJjb3JuZXIiIGhlaWdodD0iMTUiIHdpZHRoPSIxNSIgYWx0PSIiIHNyYz0ic2tpbi9pbWFnZXMvcmMtYi1sLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyI+PC9kaXY+Cis8IS0tKworICB8YWx0ZXJuYXRpdmUgY3JlZGl0cworICArLS0+Cis8ZGl2IGlkPSJjcmVkaXQyIj48L2Rpdj4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIE1lbnUKKyAgICArLS0+Cis8IS0tKworICAgIHxzdGFydCBjb250ZW50CisgICAgKy0tPgorPGRpdiBpZD0iY29udGVudCI+Cis8ZGl2IHRpdGxlPSJQb3J0YWJsZSBEb2N1bWVudCBGb3JtYXQiIGNsYXNzPSJwZGZsaW5rIj4KKzxhIGNsYXNzPSJkaWRhIiBocmVmPSJtZXRyaWNzLnBkZiI+PGltZyBhbHQ9IlBERiAtaWNvbiIgc3JjPSJza2luL2ltYWdlcy9wZGZkb2MuZ2lmIiBjbGFzcz0ic2tpbiI+PGJyPgorICAgICAgICBQREY8L2E+Cis8L2Rpdj4KKzxoMT4gCisgICAgICBIQmFzZSBNZXRyaWNzCisgICAgPC9oMT4KKzxkaXYgaWQ9Im1pbml0b2MtYXJlYSI+Cis8dWwgY2xhc3M9Im1pbml0b2MiPgorPGxpPgorPGEgaHJlZj0iI0ludHJvZHVjdGlvbiI+IEludHJvZHVjdGlvbiA8L2E+Cis8L2xpPgorPGxpPgorPGEgaHJlZj0iI0hPV1RPIj5IT1dUTzwvYT4KKzwvbGk+Cis8L3VsPgorPC9kaXY+CisgICAgCis8YSBuYW1lPSJOMTAwMEQiPjwvYT48YSBuYW1lPSJJbnRyb2R1Y3Rpb24iPjwvYT4KKzxoMiBjbGFzcz0iaDMiPiBJbnRyb2R1Y3Rpb24gPC9oMj4KKzxkaXYgY2xhc3M9InNlY3Rpb24iPgorPHA+CisgICAgICBIQmFzZSBlbWl0cyBIYWRvb3AgPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2NvcmUvZG9jcy9jdXJyZW50L2FwaS9vcmcvYXBhY2hlL2hhZG9vcC9tZXRyaWNzL3BhY2thZ2Utc3VtbWFyeS5odG1sIj5tZXRyaWNzPC9hPi4KKyAgICAgIDwvcD4KKzwvZGl2PgorICAgICAgCis8YSBuYW1lPSJOMTAwMUIiPjwvYT48YSBuYW1lPSJIT1dUTyI+PC9hPgorPGgyIGNsYXNzPSJoMyI+SE9XVE88L2gyPgorPGRpdiBjbGFzcz0ic2VjdGlvbiI+Cis8cD5GaXJzdCByZWFkIHVwIG9uIEhhZG9vcCA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9kb2NzL2N1cnJlbnQvYXBpL29yZy9hcGFjaGUvaGFkb29wL21ldHJpY3MvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm1ldHJpY3M8L2E+LgorICAgICAgSWYgeW91IGFyZSB1c2luZyBnYW5nbGlhLCB0aGUgPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvR2FuZ2xpYU1ldHJpY3MiPkdhbmdsaWFNZXRyaWNzPC9hPgorICAgICAgd2lraSBwYWdlIGlzIHVzZWZ1bCByZWFkLjwvcD4KKzxwPlRvIGhhdmUgSEJhc2UgZW1pdCBtZXRyaWNzLCBlZGl0IDxzcGFuIGNsYXNzPSJjb2RlZnJhZyI+JEhCQVNFX0hPTUUvY29uZi9oYWRvb3AtbWV0cmljcy5wcm9wZXJ0aWVzPC9zcGFuPgorICAgICAgYW5kIGVuYWJsZSBtZXRyaWMgJ2NvbnRleHRzJyBwZXIgcGx1Z2luLiAgQXMgb2YgdGhpcyB3cml0aW5nLCBoYWRvb3Agc3VwcG9ydHMKKyAgICAgIDxzdHJvbmc+ZmlsZTwvc3Ryb25nPiBhbmQgPHN0cm9uZz5nYW5nbGlhPC9zdHJvbmc+IHBsdWdpbnMuCisgICAgICBZZXMsIHRoZSBoYmFzZSBtZXRyaWNzIGZpbGVzIGlzIG5hbWVkIGhhZG9vcC1tZXRyaWNzIHJhdGhlciB0aGFuCisgICAgICA8ZW0+aGJhc2UtbWV0cmljczwvZW0+IGJlY2F1c2UgY3VycmVudGx5IGF0IGxlYXN0IHRoZSBoYWRvb3AgbWV0cmljcyBzeXN0ZW0gaGFzIHRoZQorICAgICAgcHJvcGVydGllcyBmaWxlbmFtZSBoYXJkY29kZWQuIFBlciBtZXRyaWNzIDxlbT5jb250ZXh0PC9lbT4sCisgICAgICBjb21tZW50IG91dCB0aGUgTnVsbENvbnRleHQgYW5kIGVuYWJsZSBvbmUgb3IgbW9yZSBwbHVnaW5zIGluc3RlYWQuCisgICAgICA8L3A+Cis8cD4KKyAgICAgIElmIHlvdSBlbmFibGUgdGhlIDxlbT5oYmFzZTwvZW0+IGNvbnRleHQsIG9uIHJlZ2lvbnNlcnZlcnMgeW91J2xsIHNlZSB0b3RhbCByZXF1ZXN0cyBzaW5jZSBsYXN0CisgICAgICBtZXRyaWMgZW1pc3Npb24sIGNvdW50IG9mIHJlZ2lvbnMgYW5kIHN0b3JlZmlsZXMgYXMgd2VsbCBhcyBhIGNvdW50IG9mIG1lbWNhY2hlIHNpemUuCisgICAgICBPbiB0aGUgbWFzdGVyLCB5b3UnbGwgc2VlIGEgY291bnQgb2YgdGhlIGNsdXN0ZXIncyByZXF1ZXN0cy4KKyAgICAgIDwvcD4KKzxwPgorICAgICAgRW5hYmxpbmcgdGhlIDxlbT5ycGM8L2VtPiBjb250ZXh0IGlzIGdvb2QgaWYgeW91IGFyZSBpbnRlcmVzdGVkIGluIHNlZWluZworICAgICAgbWV0cmljcyBvbiBlYWNoIGhiYXNlIHJwYyBtZXRob2QgaW52b2NhdGlvbiAoY291bnRzIGFuZCB0aW1lIHRha2VuKS4KKyAgICAgIDwvcD4KKzxwPgorICAgICAgVGhlIDxlbT5qdm08L2VtPiBjb250ZXh0IGlzCisgICAgICB1c2VmdWwgZm9yIGxvbmctdGVybSBzdGF0cyBvbiBydW5uaW5nIGhiYXNlIGp2bXMgLS0gbWVtb3J5IHVzZWQsIHRocmVhZCBjb3VudHMsIGV0Yy4KKyAgICAgIEFzIG9mIHRoaXMgd3JpdGluZywgaWYgbW9yZSB0aGFuIG9uZSBqdm0gaXMgcnVubmluZyBlbWl0dGluZyBtZXRyaWNzLCBhdCBsZWFzdAorICAgICAgaW4gZ2FuZ2xpYSwgdGhlIHN0YXRzIGFyZSBhZ2dyZWdhdGVkIHJhdGhlciB0aGFuIHJlcG9ydGVkIHBlciBpbnN0YW5jZS4KKyAgICAgIDwvcD4KKzwvZGl2PgorICAKKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIGNvbnRlbnQKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJjbGVhcmJvdGgiPiZuYnNwOzwvZGl2PgorPC9kaXY+Cis8ZGl2IGlkPSJmb290ZXIiPgorPCEtLSsKKyAgICB8c3RhcnQgYm90dG9tc3RyaXAKKyAgICArLS0+Cis8ZGl2IGNsYXNzPSJsYXN0bW9kaWZpZWQiPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwhLS0KK2RvY3VtZW50LndyaXRlKCJMYXN0IFB1Ymxpc2hlZDogIiArIGRvY3VtZW50Lmxhc3RNb2RpZmllZCk7CisvLyAgLS0+PC9zY3JpcHQ+Cis8L2Rpdj4KKzxkaXYgY2xhc3M9ImNvcHlyaWdodCI+CisgICAgICAgIENvcHlyaWdodCAmY29weTsKKyAgICAgICAgIDIwMDggPGEgaHJlZj0iaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLyI+VGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLjwvYT4KKzwvZGl2PgorPCEtLSsKKyAgICB8ZW5kIGJvdHRvbXN0cmlwCisgICAgKy0tPgorPC9kaXY+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9kb2NzL21ldHJpY3MucGRmIGIvZG9jcy9tZXRyaWNzLnBkZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjE3ZjBmCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9tZXRyaWNzLnBkZgpAQCAtMCwwICsxLDI0MCBAQAorJVBERi0xLjMKKyWqq6ytCis0IDAgb2JqCis8PCAvVHlwZSAvSW5mbworL1Byb2R1Y2VyIChGT1AgMC4yMC41KSA+PgorZW5kb2JqCis1IDAgb2JqCis8PCAvTGVuZ3RoIDM5NyAvRmlsdGVyIFsgL0FTQ0lJODVEZWNvZGUgL0ZsYXRlRGVjb2RlIF0KKyA+Pgorc3RyZWFtCitHYXVhOV1oWkkhJ1NVYHFgPyFFWU1nb2QtRkpPX20rSkItTk0jZUdbbEVsZ0s7QSdlYWdDcEpibUJVaTgxSDxGaDU1JlddTS4sIjciWXJMVlZJSj4pLTApND8hZE9fTykjTFFoamYjSSliVTolTVpVclF0JlI3bnVwSl0yL0ZtWmQsN2Rwb01UbStzLiVXM1gwVV47YXRwKGpQI2ZGL1BWVmltbmFzKCwraj5KJmZgK1NfcS5pNmlSLV5mOWUkNnNNPkQ8PWQ6NWxNSztDYyFqYmNGXTQnVG5NNzQyNWQhclpROWNfQEBrMzkoISRdYSE4KEZzQU1qXVhhUC1AR2ViNGBuMytRIigxMidkKnJNcjVMMjVydVhmN25NJzJXN1ZjUXByKD44amAmRz86KzZPTytNcitmME5MXkxvJVJkUmdUSGtuKEsxLFc4SF4+ImNcIiFSLixIbztVNVxiZDtuOE5wTkNLZWlZJE1mKzlHZkE5Q2s8TXRtTlFMMGdPQGxcIzR0LFZjRyYnfj4KK2VuZHN0cmVhbQorZW5kb2JqCis2IDAgb2JqCis8PCAvVHlwZSAvUGFnZQorL1BhcmVudCAxIDAgUgorL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXQorL1Jlc291cmNlcyAzIDAgUgorL0NvbnRlbnRzIDUgMCBSCisvQW5ub3RzIDcgMCBSCis+PgorZW5kb2JqCis3IDAgb2JqCitbCis4IDAgUgorMTAgMCBSCitdCitlbmRvYmoKKzggMCBvYmoKKzw8IC9UeXBlIC9Bbm5vdAorL1N1YnR5cGUgL0xpbmsKKy9SZWN0IFsgMTAyLjAgNTU5LjY2NiAxNjkuMzI4IDU0Ny42NjYgXQorL0MgWyAwIDAgMCBdCisvQm9yZGVyIFsgMCAwIDAgXQorL0EgOSAwIFIKKy9IIC9JCis+PgorZW5kb2JqCisxMCAwIG9iagorPDwgL1R5cGUgL0Fubm90CisvU3VidHlwZSAvTGluaworL1JlY3QgWyAxMDIuMCA1NDEuNDY2IDE1NC42NTIgNTI5LjQ2NiBdCisvQyBbIDAgMCAwIF0KKy9Cb3JkZXIgWyAwIDAgMCBdCisvQSAxMSAwIFIKKy9IIC9JCis+PgorZW5kb2JqCisxMiAwIG9iagorPDwgL0xlbmd0aCAxNzIwIC9GaWx0ZXIgWyAvQVNDSUk4NURlY29kZSAvRmxhdGVEZWNvZGUgXQorID4+CitzdHJlYW0KK0dhdG08PkFwO3EnUmxaXWlKMSVJOGY3alFiaUxRXmpqSGNVQ24kUWVXYHJKVm5JVzg/YmhBLjhyVWk8WUlFXUpgUSleKk0wdUxQTWhtbzBAYzBGalgrTyRTamckRGBMOFFVajFuO2leUUpTMl5bO1dkZ2RaUjxNWTFcdVsoXFMuUyxJcFowVGd0IyZeUSxPIiE0NSdQOV0lTzEhSlRSW0dEVWg9aipZIU9pR2NmMlkxV2tRO2pEIjs5bEZKXSQjaWhJYWdGMF91ImVFcDhsVz9laTxwbTpkUylccTAvXiI3KWhsLmJgaGlTWTM0O3Juc1csaj90YUlbQSZUZT5xbCM8P2Q7LWomczMqXW8uJz1kPi90Ky8/YGBbJFInIycmP2QyTztTL19EOylhW0BDRG1GbjowWmttVlJ0LF40NW9obzw9JVEjV1dWUCswY1JMIkJZQVxASXVIVlxoWSVkTjQ3cUsrM2BVT2FtVDslM3RfLGgjO1pDP15eUW4oMiVZY1loTGlDOkpwXV1ecWQ5SDxORGp0NHJkSEE1RiwxUlJYQks3KkM2ISI1VWozX19RbV5Gaj5fcSZCNmdFXW40bDpxcmo4VVJqOyRkVGhZJmlVT0BjWC1McFArZFpDXEJWQURCSWpQN0A9VGdtJG5XXW9zNUM6W0c5PENTSjYwSCRFPzApVWMsJzNHYEgtbWFkRUpvVmstaWpaZVJJUnBFXkopaj1vKU0oYkMvXElzcSE3bz5nZ0lWamtsKi85W0IrRDE4WDdlYiNOV0syYmh0b3IuU28xdShWdWNkaiRPVyJyblU1TlFxTltsTCgzalwjTVBsKkZOZ1M8MT03Pz5wK1JQTGpNTFRPYmAmaDYjSmttKiFhL1k6P1JxPnFbbm8+dTspRT5vc1FRV1xqLS1lIU85Jz5vcV9WbUJUdWdfVERJOmBqOTVbVW1CNzJeRk5uSWRbL1FXN1hRK0NyV0toSy9yZkFzPFUrOlhOZlpCMk0wRFhLI0BucGNQc01LOzVoZCMwcipANmZcWGQzRDUxNio1bjNeV2ZpYVJrclQ+OzVdJl4yKjhYayo8VWg9S2M6bmYzR11jOiVHIS0/NSQnL3ViLCE3P3RXXWsoZnJqUVNCTmBWVU81JkwhNFhxQnRiVT1UXGppO3BEPkhwXl84PXM5TD1AaVE8Mmg6Z3JfMm1zImQsaU1VYUguU2VqXW5nXl4sNWdmImM+L2VuZ1s9Oj9LXTtYWDhabU9WbXRCTmVxTDpHRW4jNUx0LFpFVVtIYGtaJVIyJFtmYDxQXicvIm9uJ0tbISowbTNcYFgtbnFeaTwmV0AnI3FqcmU7Zjk7QjszRmxVPy8iLlZHLGNYRWhWNjlTKlwoXXVtcjtIUT5wPCVoLWBiT2AlW2JxXmxVa0BHQjRGNyo2YTI7VHJvLD1wMllcUSdvbSJJUiI7azJQJHVALCxIKlkkKFF1KEojLytucE0+XzhZQFJWR0xFKCU8UDshRS8sZ2lEUWhBJkktWk9fTztlTFNRPCxXO2RLX0o9VlRUU01LKChIWTFAcS5SQWE4O0M2bG1AIzYoZD9FaDFzVnUuKWIkV1dEampBLlFHLmpqQWA6JzJhXG5pQ2FiYF0nIT0nM1NNXjZiRGEhMm9fOT5sKUtZMTVCM0kwc0gnWlJJQ1VQY1pYI0g4VmlOI29SXD02VXUpK1pQaTRkXjFoWV1yUm0oJUdVXGlkXS1lKjdeMnNjOi0ka2o4YzxuT3RBYiJtIjRKQkpDL1JpZGk1L28jKzc0aj9cP2hVRE1GJzNrY1pVQFFvMnIxJEtcMkVHXE9majZhMV9iJ0k8c3EtaFxnVCxcLTwsTl04OTJEUGIuKERoUTtfIic4Kls3JjFMTFEtKUhURT8/SGZKMkooUlw+N2JiOExnUUguUj5ZRU5jaEZBXEdbdTR1UmZvWlhpMlA3KDxgUGs5VFgrY0pqIWkmZWVgYj5iaDUuOWB1SVRKQU5YQkZRUXFwdC8uUkg/NkouLmBGTFA3Wy46UE5CZFIpJHVbJykzNipkPEokbTNjQ0NFWj0zVVlxUnMmLVdRa1JoM29IK3VaPD5FYmtMPkQ/ZUpQQF4nWWlMTmtNKilbXF10ciVuLSQ2TjdPaVBdMWFxIWpcNFJgS2JoUWw5TWwzZTVOaSZnNyhJNFBuSS5TSEM8ZXExLW4tPHI2R2lmNFxAZSMiQGY0J1dlXG5eYTZRYj9hZXA7cSp0QEtyajE/YyYqXk1ESWRtRmYhXCVcZmtxaGo4ZDNsRyI1cWpocnJ+PgorZW5kc3RyZWFtCitlbmRvYmoKKzEzIDAgb2JqCis8PCAvVHlwZSAvUGFnZQorL1BhcmVudCAxIDAgUgorL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXQorL1Jlc291cmNlcyAzIDAgUgorL0NvbnRlbnRzIDEyIDAgUgorL0Fubm90cyAxNCAwIFIKKz4+CitlbmRvYmoKKzE0IDAgb2JqCitbCisxNSAwIFIKKzE2IDAgUgorMTcgMCBSCitdCitlbmRvYmoKKzE1IDAgb2JqCis8PCAvVHlwZSAvQW5ub3QKKy9TdWJ0eXBlIC9MaW5rCisvUmVjdCBbIDE5NC45ODggNjI5LjY2NiAyMzAuMzE2IDYxNy42NjYgXQorL0MgWyAwIDAgMCBdCisvQm9yZGVyIFsgMCAwIDAgXQorL0EgPDwgL1VSSSAoaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2NvcmUvZG9jcy9jdXJyZW50L2FwaS9vcmcvYXBhY2hlL2hhZG9vcC9tZXRyaWNzL3BhY2thZ2Utc3VtbWFyeS5odG1sKQorL1MgL1VSSSA+PgorL0ggL0kKKz4+CitlbmRvYmoKKzE2IDAgb2JqCis8PCAvVHlwZSAvQW5ub3QKKy9TdWJ0eXBlIC9MaW5rCisvUmVjdCBbIDIwOS42NTIgNTc3LjMzMiAyNDQuOTggNTY1LjMzMiBdCisvQyBbIDAgMCAwIF0KKy9Cb3JkZXIgWyAwIDAgMCBdCisvQSA8PCAvVVJJIChodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9kb2NzL2N1cnJlbnQvYXBpL29yZy9hcGFjaGUvaGFkb29wL21ldHJpY3MvcGFja2FnZS1zdW1tYXJ5Lmh0bWwpCisvUyAvVVJJID4+CisvSCAvSQorPj4KK2VuZG9iagorMTcgMCBvYmoKKzw8IC9UeXBlIC9Bbm5vdAorL1N1YnR5cGUgL0xpbmsKKy9SZWN0IFsgMzg4LjYyIDU3Ny4zMzIgNDYzLjI3MiA1NjUuMzMyIF0KKy9DIFsgMCAwIDAgXQorL0JvcmRlciBbIDAgMCAwIF0KKy9BIDw8IC9VUkkgKGh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0dhbmdsaWFNZXRyaWNzKQorL1MgL1VSSSA+PgorL0ggL0kKKz4+CitlbmRvYmoKKzE5IDAgb2JqCis8PAorIC9UaXRsZSAoXDM3NlwzNzdcMFw2MVwwXDQwXDBcMTExXDBcMTU2XDBcMTY0XDBcMTYyXDBcMTU3XDBcMTQ0XDBcMTY1XDBcMTQzXDBcMTY0XDBcMTUxXDBcMTU3XDBcMTU2KQorIC9QYXJlbnQgMTggMCBSCisgL05leHQgMjAgMCBSCisgL0EgOSAwIFIKKz4+IGVuZG9iagorMjAgMCBvYmoKKzw8CisgL1RpdGxlIChcMzc2XDM3N1wwXDYyXDBcNDBcMFwxMTBcMFwxMTdcMFwxMjdcMFwxMjRcMFwxMTcpCisgL1BhcmVudCAxOCAwIFIKKyAvUHJldiAxOSAwIFIKKyAvQSAxMSAwIFIKKz4+IGVuZG9iagorMjEgMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GMworL0Jhc2VGb250IC9IZWx2ZXRpY2EtQm9sZAorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMjIgMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GNQorL0Jhc2VGb250IC9UaW1lcy1Sb21hbgorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMjMgMCBvYmoKKzw8IC9UeXBlIC9Gb250CisvU3VidHlwZSAvVHlwZTEKKy9OYW1lIC9GNgorL0Jhc2VGb250IC9UaW1lcy1JdGFsaWMKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzI0IDAgb2JqCis8PCAvVHlwZSAvRm9udAorL1N1YnR5cGUgL1R5cGUxCisvTmFtZSAvRjEKKy9CYXNlRm9udCAvSGVsdmV0aWNhCisvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgorZW5kb2JqCisyNSAwIG9iagorPDwgL1R5cGUgL0ZvbnQKKy9TdWJ0eXBlIC9UeXBlMQorL05hbWUgL0Y5CisvQmFzZUZvbnQgL0NvdXJpZXIKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzI2IDAgb2JqCis8PCAvVHlwZSAvRm9udAorL1N1YnR5cGUgL1R5cGUxCisvTmFtZSAvRjIKKy9CYXNlRm9udCAvSGVsdmV0aWNhLU9ibGlxdWUKKy9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CitlbmRvYmoKKzI3IDAgb2JqCis8PCAvVHlwZSAvRm9udAorL1N1YnR5cGUgL1R5cGUxCisvTmFtZSAvRjcKKy9CYXNlRm9udCAvVGltZXMtQm9sZAorL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KK2VuZG9iagorMSAwIG9iagorPDwgL1R5cGUgL1BhZ2VzCisvQ291bnQgMgorL0tpZHMgWzYgMCBSIDEzIDAgUiBdID4+CitlbmRvYmoKKzIgMCBvYmoKKzw8IC9UeXBlIC9DYXRhbG9nCisvUGFnZXMgMSAwIFIKKyAvT3V0bGluZXMgMTggMCBSCisgL1BhZ2VNb2RlIC9Vc2VPdXRsaW5lcworID4+CitlbmRvYmoKKzMgMCBvYmoKKzw8IAorL0ZvbnQgPDwgL0YzIDIxIDAgUiAvRjUgMjIgMCBSIC9GMSAyNCAwIFIgL0Y2IDIzIDAgUiAvRjkgMjUgMCBSIC9GMiAyNiAwIFIgL0Y3IDI3IDAgUiA+PiAKKy9Qcm9jU2V0IFsgL1BERiAvSW1hZ2VDIC9UZXh0IF0gPj4gCitlbmRvYmoKKzkgMCBvYmoKKzw8CisvUyAvR29UbworL0QgWzEzIDAgUiAvWFlaIDg1LjAgNjU5LjAgbnVsbF0KKz4+CitlbmRvYmoKKzExIDAgb2JqCis8PAorL1MgL0dvVG8KKy9EIFsxMyAwIFIgL1hZWiA4NS4wIDYwNi42NjYgbnVsbF0KKz4+CitlbmRvYmoKKzE4IDAgb2JqCis8PAorIC9GaXJzdCAxOSAwIFIKKyAvTGFzdCAyMCAwIFIKKz4+IGVuZG9iagoreHJlZgorMCAyOAorMDAwMDAwMDAwMCA2NTUzNSBmIAorMDAwMDAwNDcwOCAwMDAwMCBuIAorMDAwMDAwNDc3MyAwMDAwMCBuIAorMDAwMDAwNDg2NSAwMDAwMCBuIAorMDAwMDAwMDAxNSAwMDAwMCBuIAorMDAwMDAwMDA3MSAwMDAwMCBuIAorMDAwMDAwMDU1OSAwMDAwMCBuIAorMDAwMDAwMDY3OSAwMDAwMCBuIAorMDAwMDAwMDcxMSAwMDAwMCBuIAorMDAwMDAwNTAxMCAwMDAwMCBuIAorMDAwMDAwMDg0NiAwMDAwMCBuIAorMDAwMDAwNTA3MyAwMDAwMCBuIAorMDAwMDAwMDk4MyAwMDAwMCBuIAorMDAwMDAwMjc5NiAwMDAwMCBuIAorMDAwMDAwMjkxOSAwMDAwMCBuIAorMDAwMDAwMjk2MCAwMDAwMCBuIAorMDAwMDAwMzIwNyAwMDAwMCBuIAorMDAwMDAwMzQ1MyAwMDAwMCBuIAorMDAwMDAwNTEzOSAwMDAwMCBuIAorMDAwMDAwMzY1MCAwMDAwMCBuIAorMDAwMDAwMzgxMyAwMDAwMCBuIAorMDAwMDAwMzkzNSAwMDAwMCBuIAorMDAwMDAwNDA0OCAwMDAwMCBuIAorMDAwMDAwNDE1OCAwMDAwMCBuIAorMDAwMDAwNDI2OSAwMDAwMCBuIAorMDAwMDAwNDM3NyAwMDAwMCBuIAorMDAwMDAwNDQ4MyAwMDAwMCBuIAorMDAwMDAwNDU5OSAwMDAwMCBuIAordHJhaWxlcgorPDwKKy9TaXplIDI4CisvUm9vdCAyIDAgUgorL0luZm8gNCAwIFIKKz4+CitzdGFydHhyZWYKKzUxOTAKKyUlRU9GCmRpZmYgLS1naXQgYS9kb2NzL3NraW4vQ29tbW9uTWVzc2FnZXNfZGUueG1sIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2RlLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYzQ2MTE5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2RlLnhtbApAQCAtMCwwICsxLDIzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tCisgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8Y2F0YWxvZ3VlPgorICA8bWVzc2FnZSBrZXk9IkZvbnQgc2l6ZToiPlNjaHJpZnRncvZzc2U6PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9Ikxhc3QgUHVibGlzaGVkOiI+WnVsZXR6dCB2ZXL2ZmZlbnRsaWNodDo8L21lc3NhZ2U+CisgIDxtZXNzYWdlIGtleT0iU2VhcmNoIj5TdWNoZTo8L21lc3NhZ2U+CisgIDxtZXNzYWdlIGtleT0iU2VhcmNoIHRoZSBzaXRlIHdpdGgiPlN1Y2hlIGF1ZiBkZXIgU2VpdGUgbWl0PC9tZXNzYWdlPgorPC9jYXRhbG9ndWU+CmRpZmYgLS1naXQgYS9kb2NzL3NraW4vQ29tbW9uTWVzc2FnZXNfZW5fVVMueG1sIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2VuX1VTLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OGRmZTE0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2VuX1VTLnhtbApAQCAtMCwwICsxLDIzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tCisgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8Y2F0YWxvZ3VlPgorICA8bWVzc2FnZSAga2V5PSJGb250IHNpemU6Ij5Gb250IHNpemU6PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9Ikxhc3QgUHVibGlzaGVkOiI+TGFzdCBQdWJsaXNoZWQ6PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9IlNlYXJjaCI+U2VhcmNoPC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9IlNlYXJjaCB0aGUgc2l0ZSB3aXRoIj5TZWFyY2ggc2l0ZSB3aXRoPC9tZXNzYWdlPgorPC9jYXRhbG9ndWU+CmRpZmYgLS1naXQgYS9kb2NzL3NraW4vQ29tbW9uTWVzc2FnZXNfZXMueG1sIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2VzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2JlNjcxCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL0NvbW1vbk1lc3NhZ2VzX2VzLnhtbApAQCAtMCwwICsxLDIzIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tCisgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+Cis8Y2F0YWxvZ3VlPgorICA8bWVzc2FnZSBrZXk9IkZvbnQgc2l6ZToiPlRhbWHxbyBkZWwgdGV4dG86PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9Ikxhc3QgUHVibGlzaGVkOiI+RmVjaGEgZGUgcHVibGljYWNp8246PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9IlNlYXJjaCI+QnVzY2FyPC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9IlNlYXJjaCB0aGUgc2l0ZSB3aXRoIj5CdXNjYXIgZW48L21lc3NhZ2U+Cis8L2NhdGFsb2d1ZT4KZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9Db21tb25NZXNzYWdlc19mci54bWwgYi9kb2NzL3NraW4vQ29tbW9uTWVzc2FnZXNfZnIueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYyMjU2OWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vQ29tbW9uTWVzc2FnZXNfZnIueG1sCkBAIC0wLDAgKzEsMjMgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KKzwhLS0KKyAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKzxjYXRhbG9ndWU+CisgIDxtZXNzYWdlIGtleT0iRm9udCBzaXplOiI+VGFpbGxlIDo8L21lc3NhZ2U+CisgIDxtZXNzYWdlIGtleT0iTGFzdCBQdWJsaXNoZWQ6Ij5EZXJuaehyZSBwdWJsaWNhdGlvbiA6PC9tZXNzYWdlPgorICA8bWVzc2FnZSBrZXk9IlNlYXJjaCI+UmVjaGVyY2hlcjwvbWVzc2FnZT4KKyAgPG1lc3NhZ2Uga2V5PSJTZWFyY2ggdGhlIHNpdGUgd2l0aCI+UmVjaGVyY2hlciBzdXIgbGUgc2l0ZSBhdmVjPC9tZXNzYWdlPgorPC9jYXRhbG9ndWU+CmRpZmYgLS1naXQgYS9kb2NzL3NraW4vYmFzaWMuY3NzIGIvZG9jcy9za2luL2Jhc2ljLmNzcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjI0YzMyCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2Jhc2ljLmNzcwpAQCAtMCwwICsxLDE2NiBAQAorLyoKKyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqCisqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoKKyogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisvKioKKyAqIEdlbmVyYWwKKyAqLworCitpbWcgeyBib3JkZXI6IDA7IH0KKworI2NvbnRlbnQgdGFibGUgeworICBib3JkZXI6IDA7CisgIHdpZHRoOiAxMDAlOworfQorLypIYWNrIHRvIGdldCBJRSB0byByZW5kZXIgdGhlIHRhYmxlIGF0IDEwMCUqLworKiBodG1sICNjb250ZW50IHRhYmxlIHsgbWFyZ2luLWxlZnQ6IC0zcHg7IH0KKworI2NvbnRlbnQgdGgsCisjY29udGVudCB0ZCB7CisgIG1hcmdpbjogMDsKKyAgcGFkZGluZzogMDsKKyAgdmVydGljYWwtYWxpZ246IHRvcDsKK30KKworLmNsZWFyYm90aCB7CisgIGNsZWFyOiBib3RoOworfQorCisubm90ZSwgLndhcm5pbmcsIC5maXhtZSB7CisgIGJvcmRlcjogc29saWQgYmxhY2sgMXB4OworICBtYXJnaW46IDFlbSAzZW07Cit9CisKKy5ub3RlIC5sYWJlbCB7CisgIGJhY2tncm91bmQ6ICMzNjk7CisgIGNvbG9yOiB3aGl0ZTsKKyAgZm9udC13ZWlnaHQ6IGJvbGQ7CisgIHBhZGRpbmc6IDVweCAxMHB4OworfQorLm5vdGUgLmNvbnRlbnQgeworICBiYWNrZ3JvdW5kOiAjRjBGMEZGOworICBjb2xvcjogYmxhY2s7CisgIGxpbmUtaGVpZ2h0OiAxMjAlOworICBmb250LXNpemU6IDkwJTsKKyAgcGFkZGluZzogNXB4IDEwcHg7Cit9Cisud2FybmluZyAubGFiZWwgeworICBiYWNrZ3JvdW5kOiAjQzAwOworICBjb2xvcjogd2hpdGU7CisgIGZvbnQtd2VpZ2h0OiBib2xkOworICBwYWRkaW5nOiA1cHggMTBweDsKK30KKy53YXJuaW5nIC5jb250ZW50IHsKKyAgYmFja2dyb3VuZDogI0ZGRjBGMDsKKyAgY29sb3I6IGJsYWNrOworICBsaW5lLWhlaWdodDogMTIwJTsKKyAgZm9udC1zaXplOiA5MCU7CisgIHBhZGRpbmc6IDVweCAxMHB4OworfQorLmZpeG1lIC5sYWJlbCB7CisgIGJhY2tncm91bmQ6ICNDNkM2MDA7CisgIGNvbG9yOiBibGFjazsKKyAgZm9udC13ZWlnaHQ6IGJvbGQ7CisgIHBhZGRpbmc6IDVweCAxMHB4OworfQorLmZpeG1lIC5jb250ZW50IHsKKyAgcGFkZGluZzogNXB4IDEwcHg7Cit9CisKKy8qKgorICogVHlwb2dyYXBoeQorICovCisKK2JvZHkgeworICBmb250LWZhbWlseTogdmVyZGFuYSwgIlRyZWJ1Y2hldCBNUyIsIGFyaWFsLCBoZWx2ZXRpY2EsIHNhbnMtc2VyaWY7CisgIGZvbnQtc2l6ZTogMTAwJTsKK30KKworI2NvbnRlbnQgeworICBmb250LWZhbWlseTogR2VvcmdpYSwgUGFsYXRpbm8sIFRpbWVzLCBzZXJpZjsKKyAgZm9udC1zaXplOiA5NSU7Cit9CisjdGFicyB7CisgIGZvbnQtc2l6ZTogNzAlOworfQorI21lbnUgeworICBmb250LXNpemU6IDgwJTsKK30KKyNmb290ZXIgeworICBmb250LXNpemU6IDcwJTsKK30KKworaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7CisgIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgdmVyZGFuYSwgYXJpYWwsIGhlbHZldGljYSwgc2Fucy1zZXJpZjsKKyAgZm9udC13ZWlnaHQ6IGJvbGQ7CisgIG1hcmdpbi10b3A6IDFlbTsKKyAgbWFyZ2luLWJvdHRvbTogLjVlbTsKK30KKworaDEgeworICAgIG1hcmdpbi10b3A6IDA7CisgICAgbWFyZ2luLWJvdHRvbTogMWVtOworICBmb250LXNpemU6IDEuNGVtOworfQorI2NvbnRlbnQgaDEgeworICBmb250LXNpemU6IDE2MCU7CisgIG1hcmdpbi1ib3R0b206IC41ZW07Cit9CisjbWVudSBoMSB7CisgIG1hcmdpbjogMDsKKyAgcGFkZGluZzogMTBweDsKKyAgYmFja2dyb3VuZDogIzMzNjY5OTsKKyAgY29sb3I6IHdoaXRlOworfQoraDIgeyBmb250LXNpemU6IDEyMCU7IH0KK2gzIHsgZm9udC1zaXplOiAxMDAlOyB9CitoNCB7IGZvbnQtc2l6ZTogOTAlOyB9CitoNSB7IGZvbnQtc2l6ZTogODAlOyB9CitoNiB7IGZvbnQtc2l6ZTogNzUlOyB9CisKK3AgeworICBsaW5lLWhlaWdodDogMTIwJTsKKyAgdGV4dC1hbGlnbjogbGVmdDsKKyAgbWFyZ2luLXRvcDogLjVlbTsKKyAgbWFyZ2luLWJvdHRvbTogMWVtOworfQorCisjY29udGVudCBsaSwKKyNjb250ZW50IHRoLAorI2NvbnRlbnQgdGQsCisjY29udGVudCBsaSB1bCwKKyNjb250ZW50IGxpIG9seworICBtYXJnaW4tdG9wOiAuNWVtOworICBtYXJnaW4tYm90dG9tOiAuNWVtOworfQorCisKKyNjb250ZW50IGxpIGxpLAorI21pbml0b2MtYXJlYSBsaXsKKyAgbWFyZ2luLXRvcDogMGVtOworICBtYXJnaW4tYm90dG9tOiAwZW07Cit9CisKKyNjb250ZW50IC5hdHRyaWJ1dGlvbiB7CisgIHRleHQtYWxpZ246IHJpZ2h0OworICBmb250LXN0eWxlOiBpdGFsaWM7CisgIGZvbnQtc2l6ZTogODUlOworICBtYXJnaW4tdG9wOiAxZW07Cit9CisKKy5jb2RlZnJhZyB7CisgIGZvbnQtZmFtaWx5OiAiQ291cmllciBOZXciLCBDb3VyaWVyLCBtb25vc3BhY2U7CisgIGZvbnQtc2l6ZTogMTEwJTsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9kb2NzL3NraW4vYnJlYWRjcnVtYnMtb3B0aW1pemVkLmpzIGIvZG9jcy9za2luL2JyZWFkY3J1bWJzLW9wdGltaXplZC5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDc2MTJhCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2JyZWFkY3J1bWJzLW9wdGltaXplZC5qcwpAQCAtMCwwICsxLDkwIEBACisvKgorKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoKKyogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorKgorKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KK3ZhciBQUkVQUkVORF9DUlVNQlM9bmV3IEFycmF5KCk7Cit2YXIgbGluazE9IkBza2luY29uZmlnLnRyYWlsLmxpbmsxLm5hbWVAIjsKK3ZhciBsaW5rMj0iQHNraW5jb25maWcudHJhaWwubGluazIubmFtZUAiOwordmFyIGxpbmszPSJAc2tpbmNvbmZpZy50cmFpbC5saW5rMy5uYW1lQCI7CitpZighKGxpbmsxPT0iIikmJiFsaW5rMS5pbmRleE9mKCAiQCIgKSA9PSAwKXsKKyAgUFJFUFJFTkRfQ1JVTUJTLnB1c2goIG5ldyBBcnJheSggbGluazEsIEBza2luY29uZmlnLnRyYWlsLmxpbmsxLmhyZWZAICkgKTsgfQoraWYoIShsaW5rMj09IiIpJiYhbGluazIuaW5kZXhPZiggIkAiICkgPT0gMCl7CisgIFBSRVBSRU5EX0NSVU1CUy5wdXNoKCBuZXcgQXJyYXkoIGxpbmsyLCBAc2tpbmNvbmZpZy50cmFpbC5saW5rMi5ocmVmQCApICk7IH0KK2lmKCEobGluazM9PSIiKSYmIWxpbmszLmluZGV4T2YoICJAIiApID09IDApeworICBQUkVQUkVORF9DUlVNQlMucHVzaCggbmV3IEFycmF5KCBsaW5rMywgQHNraW5jb25maWcudHJhaWwubGluazMuaHJlZkAgKSApOyB9Cit2YXIgRElTUExBWV9TRVBBUkFUT1I9IiAmZ3Q7ICI7Cit2YXIgRElTUExBWV9QUkVQUkVORD0iICZndDsgIjsKK3ZhciBESVNQTEFZX1BPU1RQUkVORD0iOiI7Cit2YXIgQ1NTX0NMQVNTX0NSVU1CPSJicmVhZGNydW1iIjsKK3ZhciBDU1NfQ0xBU1NfVFJBSUw9ImJyZWFkY3J1bWJUcmFpbCI7Cit2YXIgQ1NTX0NMQVNTX1NFUEFSQVRPUj0iY3J1bWJTZXBhcmF0b3IiOwordmFyIEZJTEVfRVhURU5TSU9OUz1uZXcgQXJyYXkoICIuaHRtbCIsICIuaHRtIiwgIi5qc3AiLCAiLnBocCIsICIucGhwMyIsICIucGhwNCIgKTsKK3ZhciBQQVRIX1NFUEFSQVRPUj0iLyI7CisKK2Z1bmN0aW9uIHNjKHMpIHsKKwl2YXIgbD1zLnRvTG93ZXJDYXNlKCk7CisJcmV0dXJuIGwuc3Vic3RyKDAsMSkudG9VcHBlckNhc2UoKStsLnN1YnN0cigxKTsKK30KK2Z1bmN0aW9uIGdldGRpcnMoKSB7CisJdmFyIHQ9ZG9jdW1lbnQubG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoUEFUSF9TRVBBUkFUT1IpOworCXZhciBsYz10W3QubGVuZ3RoLTFdOworCWZvcih2YXIgaT0wO2kgPCBGSUxFX0VYVEVOU0lPTlMubGVuZ3RoO2krKykKKwl7CisJCWlmKGxjLmluZGV4T2YoRklMRV9FWFRFTlNJT05TW2ldKSkKKwkJCXJldHVybiB0LnNsaWNlKDEsdC5sZW5ndGgtMSk7IH0KKwlyZXR1cm4gdC5zbGljZSgxLHQubGVuZ3RoKTsKK30KK2Z1bmN0aW9uIGdldGNydW1icyggZCApCit7CisJdmFyIHByZSA9ICIvIjsKKwl2YXIgcG9zdCA9ICIvIjsKKwl2YXIgYyA9IG5ldyBBcnJheSgpOworCWlmKCBkICE9IG51bGwgKQorCXsKKwkJZm9yKHZhciBpPTA7aSA8IGQubGVuZ3RoO2krKykgeworCQkJcHJlKz1kW2ldK3Bvc3RmaXg7CisJCQljLnB1c2gobmV3IEFycmF5KGRbaV0scHJlKSk7IH0KKwl9CisJaWYoUFJFUFJFTkRfQ1JVTUJTLmxlbmd0aCA+IDAgKQorCQlyZXR1cm4gUFJFUFJFTkRfQ1JVTUJTLmNvbmNhdCggYyApOworCXJldHVybiBjOworfQorZnVuY3Rpb24gZ2V0dHJhaWwoIGMgKQoreworCXZhciBoPURJU1BMQVlfUFJFUFJFTkQ7CisJZm9yKHZhciBpPTA7aSA8IGMubGVuZ3RoO2krKykKKwl7CisJCWgrPSc8YSBocmVmPSInK2NbaV1bMV0rJyIgPicrc2MoY1tpXVswXSkrJzwvYT4nOworCQlpZihpIT0oYy5sZW5ndGgtMSkpCisJCQloKz1ESVNQTEFZX1NFUEFSQVRPUjsgfQorCXJldHVybiBoK0RJU1BMQVlfUE9TVFBSRU5EOworfQorCitmdW5jdGlvbiBnZXR0cmFpbFhIVE1MKCBjICkKK3sKKwl2YXIgaD0nPHNwYW4gY2xhc3M9IicrQ1NTX0NMQVNTX1RSQUlMKyciPicrRElTUExBWV9QUkVQUkVORDsKKwlmb3IodmFyIGk9MDtpIDwgYy5sZW5ndGg7aSsrKQorCXsKKwkJaCs9JzxhIGhyZWY9IicrY1tpXVsxXSsnIiBjbGFzcz0iJytDU1NfQ0xBU1NfQ1JVTUIrJyI+JytzYyhjW2ldWzBdKSsnPC9hPic7CisJCWlmKGkhPShjLmxlbmd0aC0xKSkKKwkJCWgrPSc8c3BhbiBjbGFzcz0iJytDU1NfQ0xBU1NfU0VQQVJBVE9SKyciPicrRElTUExBWV9TRVBBUkFUT1IrJzwvc3Bhbj4nOyB9CisJcmV0dXJuIGgrRElTUExBWV9QT1NUUFJFTkQrJzwvc3Bhbj4nOworfQorCitpZihkb2N1bWVudC5sb2NhdGlvbi5ocmVmLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigiaHR0cDovLyIpPT0tMSkKKwlkb2N1bWVudC53cml0ZShnZXR0cmFpbChnZXRjcnVtYnMoKSkpOworZWxzZQorCWRvY3VtZW50LndyaXRlKGdldHRyYWlsKGdldGNydW1icyhnZXRkaXJzKCkpKSk7CisKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9icmVhZGNydW1icy5qcyBiL2RvY3Mvc2tpbi9icmVhZGNydW1icy5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZWE4MGVjCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2JyZWFkY3J1bWJzLmpzCkBAIC0wLDAgKzEsMjM3IEBACisvKgorKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyogVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyoKKyogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorKgorKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKy8qKgorICogVGhpcyBzY3JpcHQsIHdoZW4gaW5jbHVkZWQgaW4gYSBodG1sIGZpbGUsIGJ1aWxkcyBhIG5lYXQgYnJlYWRjcnVtYiB0cmFpbAorICogYmFzZWQgb24gaXRzIHVybC4gVGhhdCBpcywgaWYgaXQgZG9lc24ndCBjb250YWlucyBidWdzIChJJ20gcmVsYXRpdmVseQorICogc3VyZSBpdCBkb2VzKS4KKyAqCisgKiBUeXBpY2FsIHVzYWdlOgorICogPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIGxhbmd1YWdlPSJKYXZhU2NyaXB0IiBzcmM9ImJyZWFkY3J1bWJzLmpzIj48L3NjcmlwdD4KKyAqLworCisvKioKKyAqIElFIDUgb24gTWFjIGRvZXNuJ3Qga25vdyBBcnJheS5wdXNoLgorICoKKyAqIEltcGxlbWVudCBpdCAtIGNvdXJ0ZXN5IHRvIGZyaXR6LgorICovCit2YXIgYWJjCT0gbmV3IEFycmF5KCk7CitpZiAoIWFiYy5wdXNoKSB7CisgIEFycmF5LnByb3RvdHlwZS5wdXNoCT0gZnVuY3Rpb24od2hhdCl7dGhpc1t0aGlzLmxlbmd0aF09d2hhdH0KK30KKworLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisJQ09OU1RBTlRTCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworLyoqCisgKiBUd28tZGltZW5zaW9uYWwgYXJyYXkgY29udGFpbmluZyBleHRyYSBjcnVtYnMgdG8gcGxhY2UgYXQgdGhlIGZyb250IG9mCisgKiB0aGUgdHJhaWwuIFNwZWNpZnkgZmlyc3QgdGhlIG5hbWUgb2YgdGhlIGNydW1iLCB0aGVuIHRoZSBVUkkgdGhhdCBiZWxvbmdzCisgKiB0byBpdC4gWW91J2xsIG5lZWQgdG8gbW9kaWZ5IHRoaXMgZm9yIGV2ZXJ5IGRvbWFpbiBvciBzdWJkb21haW4gd2hlcmUKKyAqIHlvdSB1c2UgdGhpcyBzY3JpcHQgKHlvdSBjYW4gbGVhdmUgaXQgYXMgYW4gZW1wdHkgYXJyYXkgaWYgeW91IHdpc2gpCisgKi8KK3ZhciBQUkVQUkVORF9DUlVNQlMgPSBuZXcgQXJyYXkoKTsKKwordmFyIGxpbmsxID0gIkBza2luY29uZmlnLnRyYWlsLmxpbmsxLm5hbWVAIjsKK3ZhciBsaW5rMiA9ICJAc2tpbmNvbmZpZy50cmFpbC5saW5rMi5uYW1lQCI7Cit2YXIgbGluazMgPSAiQHNraW5jb25maWcudHJhaWwubGluazMubmFtZUAiOworCit2YXIgaHJlZjEgPSAiQHNraW5jb25maWcudHJhaWwubGluazEuaHJlZkAiOwordmFyIGhyZWYyID0gIkBza2luY29uZmlnLnRyYWlsLmxpbmsyLmhyZWZAIjsKK3ZhciBocmVmMyA9ICJAc2tpbmNvbmZpZy50cmFpbC5saW5rMy5ocmVmQCI7CisKKyAgIGlmKCEobGluazE9PSIiKSYmIWxpbmsxLmluZGV4T2YoICJAIiApID09IDApeworICAgICBQUkVQUkVORF9DUlVNQlMucHVzaCggbmV3IEFycmF5KCBsaW5rMSwgaHJlZjEgKSApOworICAgfQorICAgaWYoIShsaW5rMj09IiIpJiYhbGluazIuaW5kZXhPZiggIkAiICkgPT0gMCl7CisgICAgIFBSRVBSRU5EX0NSVU1CUy5wdXNoKCBuZXcgQXJyYXkoIGxpbmsyLCBocmVmMiApICk7CisgICB9CisgICBpZighKGxpbmszPT0iIikmJiFsaW5rMy5pbmRleE9mKCAiQCIgKSA9PSAwKXsKKyAgICAgUFJFUFJFTkRfQ1JVTUJTLnB1c2goIG5ldyBBcnJheSggbGluazMsIGhyZWYzICkgKTsKKyAgIH0KKworLyoqCisgKiBTdHJpbmcgdG8gaW5jbHVkZSBiZXR3ZWVuIGNydW1iczoKKyAqLwordmFyIERJU1BMQVlfU0VQQVJBVE9SID0gIiAmZ3Q7ICI7CisvKioKKyAqIFN0cmluZyB0byBpbmNsdWRlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRyYWlsCisgKi8KK3ZhciBESVNQTEFZX1BSRVBSRU5EID0gIiAmZ3Q7ICI7CisvKioKKyAqIFN0cmluZyB0byBpbmNsdWRlIGF0IHRoZSBlbmQgb2YgdGhlIHRyYWlsCisgKi8KK3ZhciBESVNQTEFZX1BPU1RQUkVORCA9ICIiOworCisvKioKKyAqIENTUyBDbGFzcyB0byB1c2UgZm9yIGEgc2luZ2xlIGNydW1iOgorICovCit2YXIgQ1NTX0NMQVNTX0NSVU1CID0gImJyZWFkY3J1bWIiOworCisvKioKKyAqIENTUyBDbGFzcyB0byB1c2UgZm9yIHRoZSBjb21wbGV0ZSB0cmFpbDoKKyAqLwordmFyIENTU19DTEFTU19UUkFJTCA9ICJicmVhZGNydW1iVHJhaWwiOworCisvKioKKyAqIENTUyBDbGFzcyB0byB1c2UgZm9yIGNydW1iIHNlcGFyYXRvcjoKKyAqLwordmFyIENTU19DTEFTU19TRVBBUkFUT1IgPSAiY3J1bWJTZXBhcmF0b3IiOworCisvKioKKyAqIEFycmF5IG9mIHN0cmluZ3MgY29udGFpbmluZyBjb21tb24gZmlsZSBleHRlbnNpb25zLiBXZSB1c2UgdGhpcyB0bworICogZGV0ZXJtaW5lIHdoYXQgcGFydCBvZiB0aGUgdXJsIHRvIGlnbm9yZSAoaWYgaXQgY29udGFpbnMgb25lIG9mIHRoZQorICogc3RyaW5nIHNwZWNpZmllZCBoZXJlLCB3ZSBpZ25vcmUgaXQpLgorICovCit2YXIgRklMRV9FWFRFTlNJT05TID0gbmV3IEFycmF5KCAiLmh0bWwiLCAiLmh0bSIsICIuanNwIiwgIi5waHAiLCAiLnBocDMiLCAiLnBocDQiICk7CisKKy8qKgorICogU3RyaW5nIHRoYXQgc2VwYXJhdGVzIHBhcnRzIG9mIHRoZSBicmVhZGNydW1iIHRyYWlsIGZyb20gZWFjaCBvdGhlci4KKyAqIFdoZW4gdGhpcyBpcyBubyBsb25nZXIgYSBzbGFzaCwgSSdtIHN1cmUgSSdsbCBiZSBvbGQgYW5kIGdyZXkuCisgKi8KK3ZhciBQQVRIX1NFUEFSQVRPUiA9ICIvIjsKKworLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisJVVRJTElUWSBGVU5DVElPTlMKKyAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworLyoqCisgKiBDYXBpdGFsaXplIGZpcnN0IGxldHRlciBvZiB0aGUgcHJvdmlkZWQgc3RyaW5nIGFuZCByZXR1cm4gdGhlIG1vZGlmaWVkCisgKiBzdHJpbmcuCisgKi8KK2Z1bmN0aW9uIHNlbnRlbmNlQ2FzZSggc3RyaW5nICkKK3sgICAgICAgIHJldHVybiBzdHJpbmc7CisJLy92YXIgbG93ZXIgPSBzdHJpbmcudG9Mb3dlckNhc2UoKTsKKwkvL3JldHVybiBsb3dlci5zdWJzdHIoMCwxKS50b1VwcGVyQ2FzZSgpICsgbG93ZXIuc3Vic3RyKDEpOworfQorCisvKioKKyAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgbmFtZXMgb2YgYWxsIHRoZSBkaXJlY3RvcmllcyBpbiB0aGUKKyAqIGN1cnJlbnQgZG9jdW1lbnQgVVJMCisgKi8KK2Z1bmN0aW9uIGdldERpcmVjdG9yaWVzSW5VUkwoKQoreworCXZhciB0cmFpbCA9IGRvY3VtZW50LmxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KCBQQVRIX1NFUEFSQVRPUiApOworCisJLy8gY2hlY2sgd2hldGhlciBsYXN0IHNlY3Rpb24gaXMgYSBmaWxlIG9yIGEgZGlyZWN0b3J5CisJdmFyIGxhc3RjcnVtYiA9IHRyYWlsW3RyYWlsLmxlbmd0aC0xXTsKKwlmb3IoIHZhciBpID0gMDsgaSA8IEZJTEVfRVhURU5TSU9OUy5sZW5ndGg7IGkrKyApCisJeworCQlpZiggbGFzdGNydW1iLmluZGV4T2YoIEZJTEVfRVhURU5TSU9OU1tpXSApICkKKwkJeworCQkJLy8gaXQgaXMsIHJlbW92ZSBpdCBhbmQgc2VuZCByZXN1bHRzCisJCQlyZXR1cm4gdHJhaWwuc2xpY2UoIDEsIHRyYWlsLmxlbmd0aC0xICk7CisJCX0KKwl9CisKKwkvLyBpdCdzIG5vdDsgc2VuZCB0aGUgdHJhaWwgdW5tb2RpZmllZAorCXJldHVybiB0cmFpbC5zbGljZSggMSwgdHJhaWwubGVuZ3RoICk7Cit9CisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCUJSRUFEQ1JVTUIgRlVOQ1RJT05BTElUWQorICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCisvKioKKyAqIFJldHVybiBhIHR3by1kaW1lbnNpb25hbCBhcnJheSBkZXNjcmliaW5nIHRoZSBicmVhZGNydW1icyBiYXNlZCBvbiB0aGUKKyAqIGFycmF5IG9mIGRpcmVjdG9yaWVzIHBhc3NlZCBpbi4KKyAqLworZnVuY3Rpb24gZ2V0QnJlYWRjcnVtYnMoIGRpcnMgKQoreworCXZhciBwcmVmaXggPSAiLyI7CisJdmFyIHBvc3RmaXggPSAiLyI7CisKKwkvLyB0aGUgYXJyYXkgd2Ugd2lsbCByZXR1cm4KKwl2YXIgY3J1bWJzID0gbmV3IEFycmF5KCk7CisKKwlpZiggZGlycyAhPSBudWxsICkKKwl7CisJCWZvciggdmFyIGkgPSAwOyBpIDwgZGlycy5sZW5ndGg7IGkrKyApCisJCXsKKwkJCXByZWZpeCArPSBkaXJzW2ldICsgcG9zdGZpeDsKKwkJCWNydW1icy5wdXNoKCBuZXcgQXJyYXkoIGRpcnNbaV0sIHByZWZpeCApICk7CisJCX0KKwl9CisKKwkvLyBwcmVwcmVuZCB0aGUgUFJFUFJFTkRfQ1JVTUJTCisJaWYoUFJFUFJFTkRfQ1JVTUJTLmxlbmd0aCA+IDAgKQorCXsKKwkJcmV0dXJuIFBSRVBSRU5EX0NSVU1CUy5jb25jYXQoIGNydW1icyApOworCX0KKworCXJldHVybiBjcnVtYnM7Cit9CisKKy8qKgorICogUmV0dXJuIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBzaW1wbGUgdGV4dCBicmVhZGNydW1iIHRyYWlsIGJhc2VkIG9uIHRoZQorICogdHdvLWRpbWVuc2lvbmFsIGFycmF5IHBhc3NlZCBpbi4KKyAqLworZnVuY3Rpb24gZ2V0Q3J1bWJUcmFpbCggY3J1bWJzICkKK3sKKwl2YXIgeGh0bWwgPSBESVNQTEFZX1BSRVBSRU5EOworCisJZm9yKCB2YXIgaSA9IDA7IGkgPCBjcnVtYnMubGVuZ3RoOyBpKysgKQorCXsKKwkJeGh0bWwgKz0gJzxhIGhyZWY9IicgKyBjcnVtYnNbaV1bMV0gKyAnIiA+JzsKKwkJeGh0bWwgKz0gdW5lc2NhcGUoIGNydW1ic1tpXVswXSApICsgJzwvYT4nOworCQlpZiggaSAhPSAoY3J1bWJzLmxlbmd0aC0xKSApCisJCXsKKwkJCXhodG1sICs9IERJU1BMQVlfU0VQQVJBVE9SOworCQl9CisJfQorCisJeGh0bWwgKz0gRElTUExBWV9QT1NUUFJFTkQ7CisKKwlyZXR1cm4geGh0bWw7Cit9CisKKy8qKgorICogUmV0dXJuIGEgc3RyaW5nIGNvbnRhaW5pbmcgYW4gWEhUTUwgYnJlYWRjcnVtYiB0cmFpbCBiYXNlZCBvbiB0aGUKKyAqIHR3by1kaW1lbnNpb25hbCBhcnJheSBwYXNzZWQgaW4uCisgKi8KK2Z1bmN0aW9uIGdldENydW1iVHJhaWxYSFRNTCggY3J1bWJzICkKK3sKKwl2YXIgeGh0bWwgPSAnPHNwYW4gY2xhc3M9IicgKyBDU1NfQ0xBU1NfVFJBSUwgICsgJyI+JzsKKwl4aHRtbCArPSBESVNQTEFZX1BSRVBSRU5EOworCisJZm9yKCB2YXIgaSA9IDA7IGkgPCBjcnVtYnMubGVuZ3RoOyBpKysgKQorCXsKKwkJeGh0bWwgKz0gJzxhIGhyZWY9IicgKyBjcnVtYnNbaV1bMV0gKyAnIiBjbGFzcz0iJyArIENTU19DTEFTU19DUlVNQiArICciPic7CisJCXhodG1sICs9IHVuZXNjYXBlKCBjcnVtYnNbaV1bMF0gKSArICc8L2E+JzsKKwkJaWYoIGkgIT0gKGNydW1icy5sZW5ndGgtMSkgKQorCQl7CisJCQl4aHRtbCArPSAnPHNwYW4gY2xhc3M9IicgKyBDU1NfQ0xBU1NfU0VQQVJBVE9SICsgJyI+JyArIERJU1BMQVlfU0VQQVJBVE9SICsgJzwvc3Bhbj4nOworCQl9CisJfQorCisJeGh0bWwgKz0gRElTUExBWV9QT1NUUFJFTkQ7CisJeGh0bWwgKz0gJzwvc3Bhbj4nOworCisJcmV0dXJuIHhodG1sOworfQorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwlQUklOVCBCUkVBRENSVU1CIFRSQUlMCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworLy8gY2hlY2sgaWYgd2UncmUgbG9jYWw7IGlmIHNvLCBvbmx5IHByaW50IHRoZSBQUkVQUkVORF9DUlVNQlMKK2lmKCBkb2N1bWVudC5sb2NhdGlvbi5ocmVmLnRvTG93ZXJDYXNlKCkuaW5kZXhPZiggImh0dHA6Ly8iICkgPT0gLTEgKQoreworCWRvY3VtZW50LndyaXRlKCBnZXRDcnVtYlRyYWlsKCBnZXRCcmVhZGNydW1icygpICkgKTsKK30KK2Vsc2UKK3sKKwlkb2N1bWVudC53cml0ZSggZ2V0Q3J1bWJUcmFpbCggZ2V0QnJlYWRjcnVtYnMoIGdldERpcmVjdG9yaWVzSW5VUkwoKSApICkgKTsKK30KKwpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL2ZvbnRzaXplLmpzIGIvZG9jcy9za2luL2ZvbnRzaXplLmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExNzIyYmYKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vZm9udHNpemUuanMKQEAgLTAsMCArMSwxNjYgQEAKKy8qCisqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKgorKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworZnVuY3Rpb24gaW5pdCgpIAoreyAvL2VtYmVkZGVkIGluIHRoZSBkb2MKKyAgLy9uZGVTZXRUZXh0U2l6ZSgpOworfQorCitmdW5jdGlvbiBjaGVja0Jyb3dzZXIoKXsKKyAgaWYgKCFkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSl7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgZWxzZXsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworCitmdW5jdGlvbiBuZGVTZXRUZXh0U2l6ZShjaGdzaXplLHJzKSAKK3sKKyAgdmFyIHN0YXJ0U2l6ZTsKKyAgdmFyIG5ld1NpemU7CisKKyAgaWYgKCFjaGVja0Jyb3dzZXIpCisgIHsKKyAgICByZXR1cm47CisgIH0KKworICBzdGFydFNpemUgPSBwYXJzZUludChuZGVHZXREb2NUZXh0U2l6ZSgpKTsKKworICBpZiAoIXN0YXJ0U2l6ZSkKKyAgeworICAgIHN0YXJ0U2l6ZSA9IDE2OworICB9CisKKyAgc3dpdGNoIChjaGdzaXplKQorICB7CisgIGNhc2UgJ2luY3InOgorICAgIG5ld1NpemUgPSBzdGFydFNpemUgKyAyOworICAgIGJyZWFrOworCisgIGNhc2UgJ2RlY3InOgorICAgIG5ld1NpemUgPSBzdGFydFNpemUgLSAyOworICAgIGJyZWFrOworCisgIGNhc2UgJ3Jlc2V0JzoKKyAgICBpZiAocnMpIHtuZXdTaXplID0gcnM7fSBlbHNlIHtuZXdTaXplID0gMTY7fQorICAgIGJyZWFrOworCisgIGRlZmF1bHQ6CisgICAgdHJ5eworICAgICAgbmV3U2l6ZSA9IHBhcnNlSW50KG5kZVJlYWRDb29raWUoIm5kZS10ZXh0c2l6ZSIpKTsKKyAgICB9CisgICAgY2F0Y2goZSl7CisgICAgICBhbGVydChlKTsKKyAgICB9CisgICAgCisgICAgaWYgKCFuZXdTaXplIHx8IG5ld1NpemUgPT0gJ05hTicpCisgICAgeworICAgICAgbmV3U2l6ZSA9IHN0YXJ0U2l6ZTsKKyAgICB9CisgICAgYnJlYWs7CisKKyAgfQorCisgIGlmIChuZXdTaXplIDwgMTApIAorICB7CisgICAgbmV3U2l6ZSA9IDEwOworICB9CisKKyAgbmV3U2l6ZSArPSAncHgnOworCisgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdodG1sJylbMF0uc3R5bGUuZm9udFNpemUgPSBuZXdTaXplOworICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYm9keScpWzBdLnN0eWxlLmZvbnRTaXplID0gbmV3U2l6ZTsKKworICBuZGVDcmVhdGVDb29raWUoIm5kZS10ZXh0c2l6ZSIsIG5ld1NpemUsIDM2NSk7Cit9CisKK2Z1bmN0aW9uIG5kZUdldERvY1RleHRTaXplKCkgCit7CisgIGlmICghY2hlY2tCcm93c2VyKQorICB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICB2YXIgc2l6ZSA9IDA7CisgIHZhciBib2R5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXTsKKworICBpZiAoYm9keS5zdHlsZSAmJiBib2R5LnN0eWxlLmZvbnRTaXplKQorICB7CisgICAgc2l6ZSA9IGJvZHkuc3R5bGUuZm9udFNpemU7CisgIH0KKyAgZWxzZSBpZiAodHlwZW9mKGdldENvbXB1dGVkU3R5bGUpICE9ICd1bmRlZmluZWQnKQorICB7CisgICAgc2l6ZSA9IGdldENvbXB1dGVkU3R5bGUoYm9keSwnJykuZ2V0UHJvcGVydHlWYWx1ZSgnZm9udC1zaXplJyk7CisgIH0KKyAgZWxzZSBpZiAoYm9keS5jdXJyZW50U3R5bGUpCisgIHsKKyAgIHNpemUgPSBib2R5LmN1cnJlbnRTdHlsZS5mb250U2l6ZTsKKyAgfQorCisgIC8vZml4IElFIGJ1ZworICBpZiggaXNOYU4oc2l6ZSkpeworICAgIGlmKHNpemUuc3Vic3RyaW5nKHNpemUubGVuZ3RoLTEpPT0iJSIpeworICAgICAgcmV0dXJuCisgICAgfQorCisgIH0KKworICByZXR1cm4gc2l6ZTsKKworfQorCisKKworZnVuY3Rpb24gbmRlQ3JlYXRlQ29va2llKG5hbWUsdmFsdWUsZGF5cykgCit7CisgIHZhciBjb29raWUgPSBuYW1lICsgIj0iICsgdmFsdWUgKyAiOyI7CisKKyAgaWYgKGRheXMpIAorICB7CisgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOworICAgIGRhdGUuc2V0VGltZShkYXRlLmdldFRpbWUoKSsoZGF5cyoyNCo2MCo2MCoxMDAwKSk7CisgICAgY29va2llICs9ICIgZXhwaXJlcz0iICsgZGF0ZS50b0dNVFN0cmluZygpICsgIjsiOworICB9CisgIGNvb2tpZSArPSAiIHBhdGg9LyI7CisKKyAgZG9jdW1lbnQuY29va2llID0gY29va2llOworCit9CisKK2Z1bmN0aW9uIG5kZVJlYWRDb29raWUobmFtZSkgCit7CisgIHZhciBuYW1lRVEgPSBuYW1lICsgIj0iOworICB2YXIgY2EgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoJzsnKTsKKworIAorICBmb3IodmFyIGkgPSAwOyBpIDwgY2EubGVuZ3RoOyBpKyspIAorICB7CisgICAgdmFyIGMgPSBjYVtpXTsKKyAgICB3aGlsZSAoYy5jaGFyQXQoMCkgPT0gJyAnKSAKKyAgICB7CisgICAgICBjID0gYy5zdWJzdHJpbmcoMSwgYy5sZW5ndGgpOworICAgIH0KKworICAgIGN0ZXN0ID0gYy5zdWJzdHJpbmcoMCxuYW1lLmxlbmd0aCk7CisgCisgICAgaWYoY3Rlc3QgPT0gbmFtZSl7CisgICAgICByZXR1cm4gYy5zdWJzdHJpbmcobmFtZUVRLmxlbmd0aCxjLmxlbmd0aCk7CisgICAgfQorICB9CisgIHJldHVybiBudWxsOworfQpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL2dldEJsYW5rLmpzIGIvZG9jcy9za2luL2dldEJsYW5rLmpzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5OTc4YzAKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vZ2V0QmxhbmsuanMKQEAgLTAsMCArMSw0MCBAQAorLyoKKyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqCisqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoKKyogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisvKioKKyAqIGdldEJsYW5rIHNjcmlwdCAtIHdoZW4gaW5jbHVkZWQgaW4gYSBodG1sIGZpbGUgYW5kIGNhbGxlZCBmcm9tIGEgZm9ybSB0ZXh0IGZpZWxkLCB3aWxsIHNldCB0aGUgdmFsdWUgb2YgdGhpcyBmaWVsZCB0byAiIgorICogaWYgdGhlIHRleHQgdmFsdWUgaXMgc3RpbGwgdGhlIHN0YW5kYXJkIHZhbHVlLgorICogZ2V0UHJvbXB0IHNjcmlwdCAtIHdoZW4gaW5jbHVkZWQgaW4gYSBodG1sIGZpbGUgYW5kIGNhbGxlZCBmcm9tIGEgZm9ybSB0ZXh0IGZpZWxkLCB3aWxsIHNldCB0aGUgdmFsdWUgb2YgdGhpcyBmaWVsZCB0byB0aGUgcHJvbXB0CisgKiBpZiB0aGUgdGV4dCB2YWx1ZSBpcyBlbXB0eS4KKyAqCisgKiBUeXBpY2FsIHVzYWdlOgorICogPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIGxhbmd1YWdlPSJKYXZhU2NyaXB0IiBzcmM9ImdldEJsYW5rLmpzIj48L3NjcmlwdD4KKyAqIDxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0icXVlcnkiIHZhbHVlPSJTZWFyY2ggdGhlIHNpdGU6IiBvbkZvY3VzPSJnZXRCbGFuayAodGhpcywgJ1NlYXJjaCB0aGUgc2l0ZTonKTsiIG9uQmx1cj0iZ2V0QmxhbmsgKHRoaXMsICdTZWFyY2ggdGhlIHNpdGU6Jyk7Ii8+CisgKi8KKzwhLS0KK2Z1bmN0aW9uIGdldEJsYW5rIChmb3JtLCBzdGRWYWx1ZSl7CitpZiAoZm9ybS52YWx1ZSA9PSBzdGRWYWx1ZSl7CisJZm9ybS52YWx1ZSA9ICcnOworCX0KK3JldHVybiB0cnVlOworfQorZnVuY3Rpb24gZ2V0UHJvbXB0IChmb3JtLCBzdGRWYWx1ZSl7CitpZiAoZm9ybS52YWx1ZSA9PSAnJyl7CisJZm9ybS52YWx1ZSA9IHN0ZFZhbHVlOworCX0KK3JldHVybiB0cnVlOworfQorLy8tLT4KZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9nZXRNZW51LmpzIGIvZG9jcy9za2luL2dldE1lbnUuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE3YWFkNgotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9nZXRNZW51LmpzCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKgorKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworLyoqCisgKiBUaGlzIHNjcmlwdCwgd2hlbiBpbmNsdWRlZCBpbiBhIGh0bWwgZmlsZSwgY2FuIGJlIHVzZWQgdG8gbWFrZSBjb2xsYXBzaWJsZSBtZW51cworICoKKyAqIFR5cGljYWwgdXNhZ2U6CisgKiA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgbGFuZ3VhZ2U9IkphdmFTY3JpcHQiIHNyYz0ibWVudS5qcyI+PC9zY3JpcHQ+CisgKi8KKworaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKXsgCisgIGRvY3VtZW50LndyaXRlKCc8c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5tZW51aXRlbWdyb3Vwe2Rpc3BsYXk6IG5vbmU7fTwvc3R5bGU+JykKK30KKworCitmdW5jdGlvbiBTd2l0Y2hNZW51KG9iaiwgdGhlUGF0aCkKK3sKK3ZhciBvcGVuID0gJ3VybCgiJyt0aGVQYXRoICsgJ2ltYWdlcy9jaGFwdGVyX29wZW4uZ2lmIiknOwordmFyIGNsb3NlID0gJ3VybCgiJyt0aGVQYXRoICsgJ2ltYWdlcy9jaGFwdGVyLmdpZiIpJzsKKyAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQpICB7CisgICAgdmFyIGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob2JqKTsKKyAgICB2YXIgdGl0bGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvYmorJ1RpdGxlJyk7CisKKyAgICBpZihlbC5zdHlsZS5kaXNwbGF5ICE9ICJibG9jayIpeyAKKyAgICAgIHRpdGxlLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IG9wZW47CisgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKKyAgICB9ZWxzZXsKKyAgICAgIHRpdGxlLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IGNsb3NlOworICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKKyAgICB9CisgIH0vLyBlbmQgLSAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQpIAorfS8vZW5kIC0gZnVuY3Rpb24gU3dpdGNoTWVudShvYmopCmRpZmYgLS1naXQgYS9kb2NzL3NraW4vaW1hZ2VzL1JFQURNRS50eHQgYi9kb2NzL3NraW4vaW1hZ2VzL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTA5MzJmNAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvUkVBRE1FLnR4dApAQCAtMCwwICsxIEBACitUaGUgaW1hZ2VzIGluIHRoaXMgZGlyZWN0b3J5IGFyZSB1c2VkIGlmIHRoZSBjdXJyZW50IHNraW4gbGFja3MgdGhlbS4KZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvYWRkLmpwZyBiL2RvY3Mvc2tpbi9pbWFnZXMvYWRkLmpwZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNjgzMWVlCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9hZGQuanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvYnVpbHQtd2l0aC1mb3JyZXN0LWJ1dHRvbi5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL2J1aWx0LXdpdGgtZm9ycmVzdC1idXR0b24ucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhNzg3YWIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2J1aWx0LXdpdGgtZm9ycmVzdC1idXR0b24ucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvY2hhcHRlci5naWYgYi9kb2NzL3NraW4vaW1hZ2VzL2NoYXB0ZXIuZ2lmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzZDgyNDUKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2NoYXB0ZXIuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvY2hhcHRlcl9vcGVuLmdpZiBiL2RvY3Mvc2tpbi9pbWFnZXMvY2hhcHRlcl9vcGVuLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWNjZTE4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9jaGFwdGVyX29wZW4uZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvY3VycmVudC5naWYgYi9kb2NzL3NraW4vaW1hZ2VzL2N1cnJlbnQuZ2lmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkODJjMDgKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2N1cnJlbnQuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvZXJyb3IucG5nIGIvZG9jcy9za2luL2ltYWdlcy9lcnJvci5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRmZTA2ZQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvZXJyb3IucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvZXh0ZXJuYWwtbGluay5naWYgYi9kb2NzL3NraW4vaW1hZ2VzL2V4dGVybmFsLWxpbmsuZ2lmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmMmY3YjIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2V4dGVybmFsLWxpbmsuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvZml4LmpwZyBiL2RvY3Mvc2tpbi9pbWFnZXMvZml4LmpwZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDY4MjBiCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9maXguanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvZm9ycmVzdC1jcmVkaXQtbG9nby5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL2ZvcnJlc3QtY3JlZGl0LWxvZ28ucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNjNlNDIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2ZvcnJlc3QtY3JlZGl0LWxvZ28ucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvaGFjay5qcGcgYi9kb2NzL3NraW4vaW1hZ2VzL2hhY2suanBnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzOGQ1MGYKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2hhY2suanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvaGVhZGVyX3doaXRlX2xpbmUuZ2lmIGIvZG9jcy9za2luL2ltYWdlcy9oZWFkZXJfd2hpdGVfbGluZS5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY5Y2FlOAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvaGVhZGVyX3doaXRlX2xpbmUuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvaW5mby5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL2luZm8ucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlNTM0NDcKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL2luZm8ucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvaW5zdHJ1Y3Rpb25fYXJyb3cucG5nIGIvZG9jcy9za2luL2ltYWdlcy9pbnN0cnVjdGlvbl9hcnJvdy5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZiYzcyNAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvaW5zdHJ1Y3Rpb25fYXJyb3cucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvbGFiZWwuZ2lmIGIvZG9jcy9za2luL2ltYWdlcy9sYWJlbC5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzgzYTM4OQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvbGFiZWwuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcGFnZS5naWYgYi9kb2NzL3NraW4vaW1hZ2VzL3BhZ2UuZ2lmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExNDRkMzIKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3BhZ2UuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcGRmZG9jLmdpZiBiL2RvY3Mvc2tpbi9pbWFnZXMvcGRmZG9jLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzEzZWI1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9wZGZkb2MuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcG9kZG9jLnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcG9kZG9jLnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzkzZGY3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9wb2Rkb2MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcHJpbnRlci5naWYgYi9kb2NzL3NraW4vaW1hZ2VzL3ByaW50ZXIuZ2lmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4ZDBkNDEKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3ByaW50ZXIuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1sLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1sLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZGI0NjBhCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yYy1iLWwtMTUtMWJvZHktMm1lbnUtM21lbnUucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1yLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1yLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZWZmMjU0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yYy1iLXItMTUtMWJvZHktMm1lbnUtM21lbnUucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1yLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nIGIvZG9jcy9za2luL2ltYWdlcy9yYy1iLXItNS0xaGVhZGVyLTJ0YWItc2VsZWN0ZWQtM3RhYi1zZWxlY3RlZC5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE3NWYyNwotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtYi1yLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0yc2VhcmNoYm94LTNzZWFyY2hib3gucG5nIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LWwtNS0xaGVhZGVyLTJzZWFyY2hib3gtM3NlYXJjaGJveC5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTlmNDQ0MAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0yc2VhcmNoYm94LTNzZWFyY2hib3gucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LWwtNS0xaGVhZGVyLTJ0YWItc2VsZWN0ZWQtM3RhYi1zZWxlY3RlZC5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjFlMDE1YgotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0ydGFiLXVuc2VsZWN0ZWQtM3RhYi11bnNlbGVjdGVkLnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1sLTUtMWhlYWRlci0ydGFiLXVuc2VsZWN0ZWQtM3RhYi11bnNlbGVjdGVkLnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWY0NDQwCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LWwtNS0xaGVhZGVyLTJ0YWItdW5zZWxlY3RlZC0zdGFiLXVuc2VsZWN0ZWQucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOTM4OGI1Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LXItMTUtMWJvZHktMm1lbnUtM21lbnUucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0yc2VhcmNoYm94LTNzZWFyY2hib3gucG5nIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LXItNS0xaGVhZGVyLTJzZWFyY2hib3gtM3NlYXJjaGJveC5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQ0ZWQ3MwotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0yc2VhcmNoYm94LTNzZWFyY2hib3gucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LXItNS0xaGVhZGVyLTJ0YWItc2VsZWN0ZWQtM3RhYi1zZWxlY3RlZC5wbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzRkNGE4YwotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0ydGFiLXNlbGVjdGVkLTN0YWItc2VsZWN0ZWQucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0ydGFiLXVuc2VsZWN0ZWQtM3RhYi11bnNlbGVjdGVkLnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmMtdC1yLTUtMWhlYWRlci0ydGFiLXVuc2VsZWN0ZWQtM3RhYi11bnNlbGVjdGVkLnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDRlZDczCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yYy10LXItNS0xaGVhZGVyLTJ0YWItdW5zZWxlY3RlZC0zdGFiLXVuc2VsZWN0ZWQucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcmVtb3ZlLmpwZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcmVtb3ZlLmpwZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzliOWVmCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yZW1vdmUuanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvcnNzLnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvcnNzLnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDc5NmFjCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9yc3MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvc3BhY2VyLmdpZiBiL2RvY3Mvc2tpbi9pbWFnZXMvc3BhY2VyLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWQ0MmU4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy9zcGFjZXIuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvc3VjY2Vzcy5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL3N1Y2Nlc3MucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2ZmNmZWEKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3N1Y2Nlc3MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvdHh0ZG9jLnBuZyBiL2RvY3Mvc2tpbi9pbWFnZXMvdHh0ZG9jLnBuZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjhiMzc0Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy90eHRkb2MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvdXBkYXRlLmpwZyBiL2RvY3Mvc2tpbi9pbWFnZXMvdXBkYXRlLmpwZwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZWI5MjA3Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy91cGRhdGUuanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvdmFsaWQtaHRtbDQwMS5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL3ZhbGlkLWh0bWw0MDEucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4NTUyMTAKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3ZhbGlkLWh0bWw0MDEucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvdmNzcy5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL3Zjc3MucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliMmY1OTYKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3Zjc3MucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMvd2FybmluZy5wbmcgYi9kb2NzL3NraW4vaW1hZ2VzL3dhcm5pbmcucG5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4MWIyY2UKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vaW1hZ2VzL3dhcm5pbmcucG5nCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9pbWFnZXMveG1sZG9jLmdpZiBiL2RvY3Mvc2tpbi9pbWFnZXMveG1sZG9jLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTJkOWI5Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL2ltYWdlcy94bWxkb2MuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9tZW51LmpzIGIvZG9jcy9za2luL21lbnUuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZlYTQ3MQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9tZW51LmpzCkBAIC0wLDAgKzEsNDggQEAKKy8qCisqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKgorKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworLyoqCisgKiBUaGlzIHNjcmlwdCwgd2hlbiBpbmNsdWRlZCBpbiBhIGh0bWwgZmlsZSwgY2FuIGJlIHVzZWQgdG8gbWFrZSBjb2xsYXBzaWJsZSBtZW51cworICoKKyAqIFR5cGljYWwgdXNhZ2U6CisgKiA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgbGFuZ3VhZ2U9IkphdmFTY3JpcHQiIHNyYz0ibWVudS5qcyI+PC9zY3JpcHQ+CisgKi8KKworaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKXsgCisgIGRvY3VtZW50LndyaXRlKCc8c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5tZW51aXRlbWdyb3Vwe2Rpc3BsYXk6IG5vbmU7fTwvc3R5bGU+JykKK30KKworZnVuY3Rpb24gU3dpdGNoTWVudShvYmopCit7CisgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKSAgeworICAgIHZhciBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9iaik7CisgICAgdmFyIHRpdGxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob2JqKydUaXRsZScpOworCisgICAgaWYob2JqLmluZGV4T2YoIl9zZWxlY3RlZF8iKT09MCYmZWwuc3R5bGUuZGlzcGxheSA9PSAiIil7CisgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKKyAgICAgIHRpdGxlLmNsYXNzTmFtZSA9ICJwYWdlZ3JvdXBzZWxlY3RlZCI7CisgICAgfQorCisgICAgaWYoZWwuc3R5bGUuZGlzcGxheSAhPSAiYmxvY2siKXsKKyAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAiYmxvY2siOworICAgICAgdGl0bGUuY2xhc3NOYW1lID0gInBhZ2Vncm91cG9wZW4iOworICAgIH0KKyAgICBlbHNleworICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKKyAgICAgIHRpdGxlLmNsYXNzTmFtZSA9ICJwYWdlZ3JvdXAiOworICAgIH0KKyAgfS8vIGVuZCAtICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCkgCit9Ly9lbmQgLSBmdW5jdGlvbiBTd2l0Y2hNZW51KG9iaikKZGlmZiAtLWdpdCBhL2RvY3Mvc2tpbi9ub3RlLnR4dCBiL2RvY3Mvc2tpbi9ub3RlLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMzRjOGRiCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL25vdGUudHh0CkBAIC0wLDAgKzEsNTAgQEAKK05vdGVzIGZvciBkZXZlbG9wZXI6CisKKy0tTGVnZW5kLS0tLS0tLS0tLS0tLS0tLS0tLQorVE9ETyAtPiBibG9ja2VyCitET05FIC0+IGJsb2NrZXIKK1RvRG8gLT4gZW5oYW5jZW1lbnQgYnVnCitkb25lIC0+IGVuaGFuY2VtZW50IGJ1ZworCistLUlzc3Vlcy0tLS0tLS0tLS0tLS0tLS0tLS0KKy0gdGhlIGNvcm5lciBpbWFnZXMgc2hvdWxkIGJlIHJlbmRlcmVkIHRocm91Z2ggc3ZnIHdpdGggdGhlIGhlYWRlciBjb2xvci4KKy0+IERPTkUgCistPiBUb0RvOiBnZXQgcmlkIG9mIHRoZSBpbWFnZXMgYW5kIHVzZSBvbmx5IGRpdnMhCisKKy0gdGhlIG1lbnUgcG9pbnRzIHNob3VsZCBiZSBkaXNwbGF5ZWQgImJldHRlciIuIAorLT4gRE9ORQorLS0gVXNlIHRoZSBrcnlzYWxpcy1zaXRlIG1lbnUgYXBwcm9hY2ggZm9yIHRoZSBvdmVyYWxsIG1lbnUgZGlzcGxheS4KKy0+IERPTkUKKy0tIFVzZSB0aGUgb2xkIGxlbnlhIGlubmVybWVudSBhcHByb2NoIHRvIGZ1cnRoZXIgZW5oYW5jZSB0aGUgbWVudSAuCistPiBET05FCisKKy0gdGhlIGNvbnRlbnQgYXJlYSBuZWVkcyBzb21lIGF0dGVudGlvbi4KKy0+IERPTkUKKy0tIGludHJvZHVjZSB0aGUgaGVhZGluZyBzY2hlbWUgZnJvbSBrcnlzYWxpcyAoPGhlYWRpbmdzIHR5cGU9ImNsZWFufGJveHx1bmRlcmxpbmVkIi8+KQorLT4gRE9ORSAKKy0+IFRvRG86IG1ha2UgYm94IHdpdGggcm91bmQgY29ybmVycworLT4gZG9uZTogbWFrZSB1bmRlcmxpbmVkIHdpdGggdmFyaWFibGUgYm9yZGVyIGhlaWdodAorLT4gVG9EbzogbWFrZSB1bmRlcmxpbmUgd2l0aCBib3R0b20gcm91bmQgY29ybmVyCistLSBpbnRyb2R1Y2UgdGhlIHRvYyBmb3IgZWFjaCBodG1sLXBhZ2UKKy0+IERPTkUKKy0tIGludHJvZHVjZSB0aGUgZXh0ZXJuYWwtbGluay1pbWFnZXMuCistPiBET05FCisKKy0gdGhlIHB1Ymxpc2ggbm90ZSBzaG91bGQgYmUgd2hlcmUgbm93IG9ubHkgYSBib3JkZXIgaXMuIAorTGlrZSA8ZGl2IGlkPSJwdWJsaXNoZWQiLz4KKy0+IERPTkUKKywgYnV0IG1ha2UgaXQgY29uZmlndXJhYmxlLgorLT4gRE9ORQorLSBmb290ZXIgbmVlZHMgc29tZSBhdHRlbnRpb24KKy0+IERPTkUKKy0tIHRoZSBmb290ZXIgZG8gbm90IGhhdmUgdGhlIGNvbG9yIHByb2ZpbGUhIEVuYWJsZSBpdCEKKy0+IERPTkUKKy0tIHRoZSBmb290ZXIgc2hvdWxkIGFzIHdlbGwgY29udGFpbiBhIGZlZWRiYWNrIGxpbmsuIAorU2VlIGh0dHA6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9leWVicm93c2UvUmVhZE1zZz9saXN0TmFtZT1mb3JyZXN0LXVzZXJAeG1sLmFwYWNoZS5vcmcmbXNnTm89NzEKKy0+IERPTkUKKworLSBpbnRyb2R1Y2UgY3JlZGl0cyBhbHRlcm5hdGl2IGxvY2F0aW9uCistPiBET05FCisKKy0gYm9yZGVyIGZvciBwdWJsaXNoZWQgLyBicmVhZHRyYWlsIC8gbWVudSAvdGFiIGRpdnMgCistPiBUb0RvClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL3ByaW50LmNzcyBiL2RvY3Mvc2tpbi9wcmludC5jc3MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWFhOTkzMQotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9wcmludC5jc3MKQEAgLTAsMCArMSw1NCBAQAorLyoKKyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisqCisqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyoKKyogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCitib2R5IHsKKyAgZm9udC1mYW1pbHk6IEdlb3JnaWEsIFBhbGF0aW5vLCBzZXJpZjsKKyAgZm9udC1zaXplOiAxMnB0OworICBiYWNrZ3JvdW5kOiB3aGl0ZTsKK30KKworI3RhYnMsCisjbWVudSwKKyNjb250ZW50IC50b2MgeworICBkaXNwbGF5OiBub25lOworfQorCisjY29udGVudCB7CisgIHdpZHRoOiBhdXRvOworICBwYWRkaW5nOiAwOworICBmbG9hdDogbm9uZSAhaW1wb3J0YW50OworICBjb2xvcjogYmxhY2s7CisgIGJhY2tncm91bmQ6IGluaGVyaXQ7Cit9CisKK2E6bGluaywgYTp2aXNpdGVkIHsKKyAgY29sb3I6ICMzMzY2OTk7CisgIGJhY2tncm91bmQ6IGluaGVyaXQ7CisgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOworfQorCisjdG9wIC5sb2dvIHsKKyAgcGFkZGluZzogMDsKKyAgbWFyZ2luOiAwIDAgMmVtIDA7Cit9CisKKyNmb290ZXIgeworICBtYXJnaW4tdG9wOiA0ZW07Cit9CisKK2Fjcm9ueW0geworICBib3JkZXI6IDA7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL3Byb2ZpbGUuY3NzIGIvZG9jcy9za2luL3Byb2ZpbGUuY3NzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwZDNlYjQKLS0tIC9kZXYvbnVsbAorKysgYi9kb2NzL3NraW4vcHJvZmlsZS5jc3MKQEAgLTAsMCArMSwxNTggQEAKKworCisvKiA9PT09PT09PT09PT09PT09PT09PSBhdXJhbCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCisKK0BtZWRpYSBhdXJhbCB7CisgIGgxLCBoMiwgaDMsIGg0LCBoNSwgaDYgeyB2b2ljZS1mYW1pbHk6IHBhdWwsIG1hbGU7IHN0cmVzczogMjA7IHJpY2huZXNzOiA5MCB9CisgIGgxIHsgcGl0Y2g6IHgtbG93OyBwaXRjaC1yYW5nZTogOTAgfQorICBoMiB7IHBpdGNoOiB4LWxvdzsgcGl0Y2gtcmFuZ2U6IDgwIH0KKyAgaDMgeyBwaXRjaDogbG93OyBwaXRjaC1yYW5nZTogNzAgfQorICBoNCB7IHBpdGNoOiBtZWRpdW07IHBpdGNoLXJhbmdlOiA2MCB9CisgIGg1IHsgcGl0Y2g6IG1lZGl1bTsgcGl0Y2gtcmFuZ2U6IDUwIH0KKyAgaDYgeyBwaXRjaDogbWVkaXVtOyBwaXRjaC1yYW5nZTogNDAgfQorICBsaSwgZHQsIGRkIHsgcGl0Y2g6IG1lZGl1bTsgcmljaG5lc3M6IDYwIH0KKyAgZHQgeyBzdHJlc3M6IDgwIH0KKyAgcHJlLCBjb2RlLCB0dCB7IHBpdGNoOiBtZWRpdW07IHBpdGNoLXJhbmdlOiAwOyBzdHJlc3M6IDA7IHJpY2huZXNzOiA4MCB9CisgIGVtIHsgcGl0Y2g6IG1lZGl1bTsgcGl0Y2gtcmFuZ2U6IDYwOyBzdHJlc3M6IDYwOyByaWNobmVzczogNTAgfQorICBzdHJvbmcgeyBwaXRjaDogbWVkaXVtOyBwaXRjaC1yYW5nZTogNjA7IHN0cmVzczogOTA7IHJpY2huZXNzOiA5MCB9CisgIGRmbiB7IHBpdGNoOiBoaWdoOyBwaXRjaC1yYW5nZTogNjA7IHN0cmVzczogNjAgfQorICBzLCBzdHJpa2UgeyByaWNobmVzczogMCB9CisgIGkgeyBwaXRjaDogbWVkaXVtOyBwaXRjaC1yYW5nZTogNjA7IHN0cmVzczogNjA7IHJpY2huZXNzOiA1MCB9CisgIGIgeyBwaXRjaDogbWVkaXVtOyBwaXRjaC1yYW5nZTogNjA7IHN0cmVzczogOTA7IHJpY2huZXNzOiA5MCB9CisgIHUgeyByaWNobmVzczogMCB9CisgIAorICA6bGluayB7IHZvaWNlLWZhbWlseTogaGFycnksIG1hbGUgfQorICA6dmlzaXRlZCB7IHZvaWNlLWZhbWlseTogYmV0dHksIGZlbWFsZSB9CisgIDphY3RpdmUgeyB2b2ljZS1mYW1pbHk6IGJldHR5LCBmZW1hbGU7IHBpdGNoLXJhbmdlOiA4MDsgcGl0Y2g6IHgtaGlnaCB9Cit9CisgIAorYS5leHRlcm5hbCAgeworICBwYWRkaW5nOiAwIDIwcHggMHB4IDBweDsKKwlkaXNwbGF5OmlubGluZTsKKyAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKwliYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXIgcmlnaHQ7CisJYmFja2dyb3VuZC1pbWFnZTogdXJsKGltYWdlcy9leHRlcm5hbC1saW5rLmdpZik7Cit9CisgIAorI3RvcCAgICAgICAgICB7IGJhY2tncm91bmQtY29sb3I6ICNGRkZGRkY7fSAgCisgCisjdG9wIC5oZWFkZXIgLmN1cnJlbnQgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjNEM2QzhGO30gCisjdG9wIC5oZWFkZXIgLmN1cnJlbnQgYTpsaW5rIHsgIGNvbG9yOiAjZmZmZmZmOyAgfQorI3RvcCAuaGVhZGVyIC5jdXJyZW50IGE6dmlzaXRlZCB7IGNvbG9yOiAjZmZmZmZmOyB9CisjdG9wIC5oZWFkZXIgLmN1cnJlbnQgYTpob3ZlciB7IGNvbG9yOiAjZmZmZmZmOyB9CisgCisjdGFicyBsaSAgICAgIHsgYmFja2dyb3VuZC1jb2xvcjogI0U1RTREOSA7fSAKKyN0YWJzIGxpIGE6bGluayB7ICBjb2xvcjogIzAwMDAwMDsgIH0KKyN0YWJzIGxpIGE6dmlzaXRlZCB7IGNvbG9yOiAjMDAwMDAwOyB9CisjdGFicyBsaSBhOmhvdmVyIHsgY29sb3I6ICMwMDAwMDA7IH0KKworI2xldmVsMnRhYnMgYS5zZWxlY3RlZCAgICAgIHsgYmFja2dyb3VuZC1jb2xvcjogIzRDNkM4RiA7fSAKKyNsZXZlbDJ0YWJzIGE6bGluayB7ICBjb2xvcjogI2ZmZmZmZjsgIH0KKyNsZXZlbDJ0YWJzIGE6dmlzaXRlZCB7IGNvbG9yOiAjZmZmZmZmOyB9CisjbGV2ZWwydGFicyBhOmhvdmVyIHsgY29sb3I6ICNmZmZmZmY7IH0KKworI2xldmVsMnRhYnMgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFNEQ5O30KKyNsZXZlbDJ0YWJzIGEudW5zZWxlY3RlZDpsaW5rIHsgIGNvbG9yOiAjMDAwMDAwOyAgfQorI2xldmVsMnRhYnMgYS51bnNlbGVjdGVkOnZpc2l0ZWQgeyBjb2xvcjogIzAwMDAwMDsgfQorI2xldmVsMnRhYnMgYS51bnNlbGVjdGVkOmhvdmVyIHsgY29sb3I6ICMwMDAwMDA7IH0KKworLmhlYWRpbmcgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFNEQ5O30gCisKKy5ib3hlZCB7IGJhY2tncm91bmQtY29sb3I6ICNFNUU0RDk7fSAKKy51bmRlcmxpbmVkXzUgCXtib3JkZXItYm90dG9tOiBzb2xpZCA1cHggI0U1RTREOTt9CisudW5kZXJsaW5lZF8xMCAJe2JvcmRlci1ib3R0b206IHNvbGlkIDEwcHggI0U1RTREOTt9Cit0YWJsZSBjYXB0aW9uIHsgCitiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFNEQ5OyAKK2NvbG9yOiAjMDAwMDAwOworfQorICAgIAorI2ZlZWRiYWNrIHsKK2NvbG9yOiAjRkZGRkZGOworYmFja2dyb3VuZDogIzRDNkM4RjsKK3RleHQtYWxpZ246IGNlbnRlcjsKK30KKyNmZWVkYmFjayAjZmVlZGJhY2t0byB7Citjb2xvcjogI0ZGRkZGRjsKK30gICAKKworI3B1Ymxpc2hlZFN0cmlwIHsgCitjb2xvcjogI0ZGRkZGRjsKK2JhY2tncm91bmQ6ICM0QzZDOEY7IAorfQorCisjcHVibGlzaGVkU3RyaXAgeyAKK2NvbG9yOiAjMDAwMDAwOworYmFja2dyb3VuZDogI0U1RTREOTsgCit9CisKKyNtZW51IC5tZW51cGFnZXRpdGxlICB7IGJhY2tncm91bmQtY29sb3I6ICNDRkRDRUQ7CisgIGNvbG9yOiAjMDAwMDAwO30KKworI21lbnUgICAgICAgICAgIHsgYm9yZGVyLWNvbG9yOiAjOTk5OTk5O30KKyNtZW51IC5tZW51cGFnZXRpdGxlICB7IGJvcmRlci1jb2xvcjogIzk5OTk5OTt9CisjbWVudSAubWVudXBhZ2VpdGVtZ3JvdXAgIHsgYm9yZGVyLWNvbG9yOiAjOTk5OTk5O30KKworI21lbnUgICAgICB7IGJhY2tncm91bmQtY29sb3I6ICM0QzZDOEY7fSAKKyNtZW51ICB7ICBjb2xvcjogI2ZmZmZmZjt9IAorI21lbnUgYTpsaW5rIHsgIGNvbG9yOiAjZmZmZmZmO30gCisjbWVudSBhOnZpc2l0ZWQgeyAgY29sb3I6ICNmZmZmZmY7fSAKKyNtZW51IGE6aG92ZXIgeyAgCitiYWNrZ3JvdW5kLWNvbG9yOiAjNEM2QzhGOworY29sb3I6ICNmZmZmZmY7fSAKKworI21lbnUgaDEgeworY29sb3I6ICMwMDAwMDA7CitiYWNrZ3JvdW5kLWNvbG9yOiAjY2ZkY2VkOworfSAgIAorIAorI3RvcCAuc2VhcmNoYm94IHsgCitiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFNEQ5IDsKK2NvbG9yOiAjMDAwMDAwOyAKK30gCisgCisjbWVudSAubWVudXBhZ2VpdGVtZ3JvdXAgICAgIHsgCitiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFNEQ5OworfQorI21lbnUgLm1lbnVwYWdlaXRlbSB7Citjb2xvcjogIzAwMDAwMDsKK30gCisjbWVudSAubWVudXBhZ2VpdGVtIGE6bGluayB7ICBjb2xvcjogIzAwMDAwMDt9IAorI21lbnUgLm1lbnVwYWdlaXRlbSBhOnZpc2l0ZWQgeyAgY29sb3I6ICMwMDAwMDA7fSAKKyNtZW51IC5tZW51cGFnZWl0ZW0gYTpob3ZlciB7ICAKK2JhY2tncm91bmQtY29sb3I6ICNFNUU0RDk7Citjb2xvcjogIzAwMDAwMDsKK30KKworYm9keXsgCitiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmOworY29sb3I6ICMwMDAwMDA7Cit9IAorYTpsaW5rIHsgY29sb3I6IzAwMDBmZn0gCithOnZpc2l0ZWQgeyBjb2xvcjojMDA5OTk5fSAKK2E6aG92ZXIgeyBjb2xvcjojNjU4N2ZmfSAKKworIAorLkZvcnJlc3RUYWJsZSAgICAgIHsgYmFja2dyb3VuZC1jb2xvcjogI2NjYzt9IAorIAorLkZvcnJlc3RUYWJsZSB0ZCAgIHsgYmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjt9IAorIAorLmhpZ2hsaWdodCAgICAgICAgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZjAwO30gCisgCisuZml4bWUgICAgICAgIHsgYm9yZGVyLWNvbG9yOiAjYzYwO30gCisgCisubm90ZSAgICAgICAgIHsgYm9yZGVyLWNvbG9yOiAjMDY5O30gCisgCisud2FybmluZyAgICAgICAgIHsgYm9yZGVyLWNvbG9yOiAjOTAwO30gCisgCisuY29kZSAgICAgICAgIHsgYm9yZGVyLWNvbG9yOiAjYTViNmM2O30gCisgCisjZm9vdGVyICAgICAgIHsgYmFja2dyb3VuZC1jb2xvcjogI0U1RTREOTt9IAorLyogZXh0cmEtY3NzICovCisgICAgCisgICAgcC5xdW90ZSB7CisgICAgICBtYXJnaW4tbGVmdDogMmVtOworICAgICAgcGFkZGluZzogLjVlbTsKKyAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmMGYwZjA7CisgICAgICBmb250LWZhbWlseTogbW9ub3NwYWNlOworICAgIH0KKyAgClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL3Byb3RvdHlwZS5qcyBiL2RvY3Mvc2tpbi9wcm90b3R5cGUuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ3ZDkyMAotLS0gL2Rldi9udWxsCisrKyBiL2RvY3Mvc2tpbi9wcm90b3R5cGUuanMKQEAgLTAsMCArMSwxMjU3IEBACisvKiAgUHJvdG90eXBlIEphdmFTY3JpcHQgZnJhbWV3b3JrLCB2ZXJzaW9uIDEuNC4wX3ByZTQKKyAqICAoYykgMjAwNSBTYW0gU3RlcGhlbnNvbiA8c2FtQGNvbmlvLm5ldD4KKyAqCisgKiAgVEhJUyBGSUxFIElTIEFVVE9NQVRJQ0FMTFkgR0VORVJBVEVELiBXaGVuIHNlbmRpbmcgcGF0Y2hlcywgcGxlYXNlIGRpZmYKKyAqICBhZ2FpbnN0IHRoZSBzb3VyY2UgdHJlZSwgYXZhaWxhYmxlIGZyb20gdGhlIFByb3RvdHlwZSBkYXJjcyByZXBvc2l0b3J5LiAKKyAqCisgKiAgUHJvdG90eXBlIGlzIGZyZWVseSBkaXN0cmlidXRhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiBhbiBNSVQtc3R5bGUgbGljZW5zZS4KKyAqCisgKiAgRm9yIGRldGFpbHMsIHNlZSB0aGUgUHJvdG90eXBlIHdlYiBzaXRlOiBodHRwOi8vcHJvdG90eXBlLmNvbmlvLm5ldC8KKyAqCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKwordmFyIFByb3RvdHlwZSA9IHsKKyAgVmVyc2lvbjogJzEuNC4wX3ByZTQnLAorICAKKyAgZW1wdHlGdW5jdGlvbjogZnVuY3Rpb24oKSB7fSwKKyAgSzogZnVuY3Rpb24oeCkge3JldHVybiB4fQorfQorCit2YXIgQ2xhc3MgPSB7CisgIGNyZWF0ZTogZnVuY3Rpb24oKSB7CisgICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAKKyAgICAgIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOworICAgIH0KKyAgfQorfQorCit2YXIgQWJzdHJhY3QgPSBuZXcgT2JqZWN0KCk7CisKK09iamVjdC5leHRlbmQgPSBmdW5jdGlvbihkZXN0aW5hdGlvbiwgc291cmNlKSB7CisgIGZvciAocHJvcGVydHkgaW4gc291cmNlKSB7CisgICAgZGVzdGluYXRpb25bcHJvcGVydHldID0gc291cmNlW3Byb3BlcnR5XTsKKyAgfQorICByZXR1cm4gZGVzdGluYXRpb247Cit9CisKK0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24ob2JqZWN0KSB7CisgIHZhciBfX21ldGhvZCA9IHRoaXM7CisgIHJldHVybiBmdW5jdGlvbigpIHsKKyAgICByZXR1cm4gX19tZXRob2QuYXBwbHkob2JqZWN0LCBhcmd1bWVudHMpOworICB9Cit9CisKK0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kQXNFdmVudExpc3RlbmVyID0gZnVuY3Rpb24ob2JqZWN0KSB7CisgIHZhciBfX21ldGhvZCA9IHRoaXM7CisgIHJldHVybiBmdW5jdGlvbihldmVudCkgeworICAgIHJldHVybiBfX21ldGhvZC5jYWxsKG9iamVjdCwgZXZlbnQgfHwgd2luZG93LmV2ZW50KTsKKyAgfQorfQorCitOdW1iZXIucHJvdG90eXBlLnRvQ29sb3JQYXJ0ID0gZnVuY3Rpb24oKSB7CisgIHZhciBkaWdpdHMgPSB0aGlzLnRvU3RyaW5nKDE2KTsKKyAgaWYgKHRoaXMgPCAxNikgcmV0dXJuICcwJyArIGRpZ2l0czsKKyAgcmV0dXJuIGRpZ2l0czsKK30KKwordmFyIFRyeSA9IHsKKyAgdGhlc2U6IGZ1bmN0aW9uKCkgeworICAgIHZhciByZXR1cm5WYWx1ZTsKKworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICB2YXIgbGFtYmRhID0gYXJndW1lbnRzW2ldOworICAgICAgdHJ5IHsKKyAgICAgICAgcmV0dXJuVmFsdWUgPSBsYW1iZGEoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9IGNhdGNoIChlKSB7fQorICAgIH0KKworICAgIHJldHVybiByZXR1cm5WYWx1ZTsKKyAgfQorfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKwordmFyIFBlcmlvZGljYWxFeGVjdXRlciA9IENsYXNzLmNyZWF0ZSgpOworUGVyaW9kaWNhbEV4ZWN1dGVyLnByb3RvdHlwZSA9IHsKKyAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oY2FsbGJhY2ssIGZyZXF1ZW5jeSkgeworICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjazsKKyAgICB0aGlzLmZyZXF1ZW5jeSA9IGZyZXF1ZW5jeTsKKyAgICB0aGlzLmN1cnJlbnRseUV4ZWN1dGluZyA9IGZhbHNlOworCisgICAgdGhpcy5yZWdpc3RlckNhbGxiYWNrKCk7CisgIH0sCisKKyAgcmVnaXN0ZXJDYWxsYmFjazogZnVuY3Rpb24oKSB7CisgICAgc2V0SW50ZXJ2YWwodGhpcy5vblRpbWVyRXZlbnQuYmluZCh0aGlzKSwgdGhpcy5mcmVxdWVuY3kgKiAxMDAwKTsKKyAgfSwKKworICBvblRpbWVyRXZlbnQ6IGZ1bmN0aW9uKCkgeworICAgIGlmICghdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcpIHsKKyAgICAgIHRyeSB7IAorICAgICAgICB0aGlzLmN1cnJlbnRseUV4ZWN1dGluZyA9IHRydWU7CisgICAgICAgIHRoaXMuY2FsbGJhY2soKTsgCisgICAgICB9IGZpbmFsbHkgeyAKKyAgICAgICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKK2Z1bmN0aW9uICQoKSB7CisgIHZhciBlbGVtZW50cyA9IG5ldyBBcnJheSgpOworCisgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgdmFyIGVsZW1lbnQgPSBhcmd1bWVudHNbaV07CisgICAgaWYgKHR5cGVvZiBlbGVtZW50ID09ICdzdHJpbmcnKQorICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnQpOworCisgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkgCisgICAgICByZXR1cm4gZWxlbWVudDsKKworICAgIGVsZW1lbnRzLnB1c2goZWxlbWVudCk7CisgIH0KKworICByZXR1cm4gZWxlbWVudHM7Cit9CisKK2lmICghQXJyYXkucHJvdG90eXBlLnB1c2gpIHsKKyAgQXJyYXkucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbigpIHsKKwkJdmFyIHN0YXJ0TGVuZ3RoID0gdGhpcy5sZW5ndGg7CisJCWZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKQorICAgICAgdGhpc1tzdGFydExlbmd0aCArIGldID0gYXJndW1lbnRzW2ldOworCSAgcmV0dXJuIHRoaXMubGVuZ3RoOworICB9Cit9CisKK2lmICghRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5KSB7CisgIC8vIEJhc2VkIG9uIGNvZGUgZnJvbSBodHRwOi8vd3d3LnlvdW5ncHVwLm5ldC8KKyAgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24ob2JqZWN0LCBwYXJhbWV0ZXJzKSB7CisgICAgdmFyIHBhcmFtZXRlclN0cmluZ3MgPSBuZXcgQXJyYXkoKTsKKyAgICBpZiAoIW9iamVjdCkgICAgIG9iamVjdCA9IHdpbmRvdzsKKyAgICBpZiAoIXBhcmFtZXRlcnMpIHBhcmFtZXRlcnMgPSBuZXcgQXJyYXkoKTsKKyAgICAKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhcmFtZXRlcnMubGVuZ3RoOyBpKyspCisgICAgICBwYXJhbWV0ZXJTdHJpbmdzW2ldID0gJ3BhcmFtZXRlcnNbJyArIGkgKyAnXSc7CisgICAgCisgICAgb2JqZWN0Ll9fYXBwbHlfXyA9IHRoaXM7CisgICAgdmFyIHJlc3VsdCA9IGV2YWwoJ29iamVjdC5fX2FwcGx5X18oJyArIAorICAgICAgcGFyYW1ldGVyU3RyaW5ncy5qb2luKCcsICcpICsgJyknKTsKKyAgICBvYmplY3QuX19hcHBseV9fID0gbnVsbDsKKyAgICAKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK09iamVjdC5leHRlbmQoU3RyaW5nLnByb3RvdHlwZSwgeworICBzdHJpcFRhZ3M6IGZ1bmN0aW9uKCkgeworICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLzxcLz9bXj5dKz4vZ2ksICcnKTsKKyAgfSwKKworICBlc2NhcGVIVE1MOiBmdW5jdGlvbigpIHsKKyAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CisgICAgdmFyIHRleHQgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzKTsKKyAgICBkaXYuYXBwZW5kQ2hpbGQodGV4dCk7CisgICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7CisgIH0sCisKKyAgdW5lc2NhcGVIVE1MOiBmdW5jdGlvbigpIHsKKyAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CisgICAgZGl2LmlubmVySFRNTCA9IHRoaXMuc3RyaXBUYWdzKCk7CisgICAgcmV0dXJuIGRpdi5jaGlsZE5vZGVzWzBdLm5vZGVWYWx1ZTsKKyAgfSwKKyAgCisgIHBhcnNlUXVlcnk6IGZ1bmN0aW9uKCkgeworICAgIHZhciBzdHIgPSB0aGlzOworICAgIGlmIChzdHIuc3Vic3RyaW5nKDAsMSkgPT0gJz8nKSB7CisgICAgICBzdHIgPSB0aGlzLnN1YnN0cmluZygxKTsKKyAgICB9CisgICAgdmFyIHJlc3VsdCA9IHt9OworICAgIHZhciBwYWlycyA9IHN0ci5zcGxpdCgnJicpOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFpcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHZhciBwYWlyID0gcGFpcnNbaV0uc3BsaXQoJz0nKTsKKyAgICAgIHJlc3VsdFtwYWlyWzBdXSA9IHBhaXJbMV07CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30pOworCisKK3ZhciBfYnJlYWsgICAgPSBuZXcgT2JqZWN0KCk7Cit2YXIgX2NvbnRpbnVlID0gbmV3IE9iamVjdCgpOworCit2YXIgRW51bWVyYWJsZSA9IHsKKyAgZWFjaDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKKyAgICB2YXIgaW5kZXggPSAwOworICAgIHRyeSB7CisgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uKHZhbHVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaXRlcmF0b3IodmFsdWUsIGluZGV4KyspOworICAgICAgICB9IGNhdGNoIChlKSB7CisgICAgICAgICAgaWYgKGUgIT0gX2NvbnRpbnVlKSB0aHJvdyBlOworICAgICAgICB9CisgICAgICB9KTsKKyAgICB9IGNhdGNoIChlKSB7CisgICAgICBpZiAoZSAhPSBfYnJlYWspIHRocm93IGU7CisgICAgfQorICB9LAorICAKKyAgYWxsOiBmdW5jdGlvbihpdGVyYXRvcikgeworICAgIHZhciByZXN1bHQgPSB0cnVlOworICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKKyAgICAgIGlmICghKHJlc3VsdCAmPSAoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCkpKSAKKyAgICAgICAgdGhyb3cgX2JyZWFrOworICAgIH0pOworICAgIHJldHVybiByZXN1bHQ7CisgIH0sCisgIAorICBhbnk6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CisgICAgdmFyIHJlc3VsdCA9IHRydWU7CisgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgeworICAgICAgaWYgKHJlc3VsdCAmPSAoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCkpIAorICAgICAgICB0aHJvdyBfYnJlYWs7CisgICAgfSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSwKKyAgCisgIGNvbGxlY3Q6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CisgICAgdmFyIHJlc3VsdHMgPSBbXTsKKyAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CisgICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IodmFsdWUsIGluZGV4KSk7CisgICAgfSk7CisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0sCisgIAorICBkZXRlY3Q6IGZ1bmN0aW9uIChpdGVyYXRvcikgeworICAgIHZhciByZXN1bHQ7CisgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgeworICAgICAgaWYgKGl0ZXJhdG9yKHZhbHVlLCBpbmRleCkpIHsKKyAgICAgICAgcmVzdWx0ID0gdmFsdWU7CisgICAgICAgIHRocm93IF9icmVhazsKKyAgICAgIH0KKyAgICB9KTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9LAorICAKKyAgZmluZEFsbDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKKyAgICB2YXIgcmVzdWx0cyA9IFtdOworICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKKyAgICAgIGlmIChpdGVyYXRvcih2YWx1ZSwgaW5kZXgpKQorICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpOworICAgIH0pOworICAgIHJldHVybiByZXN1bHRzOworICB9LAorICAKKyAgZ3JlcDogZnVuY3Rpb24ocGF0dGVybiwgaXRlcmF0b3IpIHsKKyAgICB2YXIgcmVzdWx0cyA9IFtdOworICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKKyAgICAgIHZhciBzdHJpbmdWYWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7CisgICAgICBpZiAoc3RyaW5nVmFsdWUubWF0Y2gocGF0dGVybikpCisgICAgICAgIHJlc3VsdHMucHVzaCgoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCkpOworICAgIH0pCisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0sCisgIAorICBpbmNsdWRlOiBmdW5jdGlvbihvYmplY3QpIHsKKyAgICB2YXIgZm91bmQgPSBmYWxzZTsKKyAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUpIHsKKyAgICAgIGlmICh2YWx1ZSA9PSBvYmplY3QpIHsKKyAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICB0aHJvdyBfYnJlYWs7CisgICAgICB9CisgICAgfSk7CisgICAgcmV0dXJuIGZvdW5kOworICB9LAorICAKKyAgaW5qZWN0OiBmdW5jdGlvbihtZW1vLCBpdGVyYXRvcikgeworICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKKyAgICAgIG1lbW8gPSBpdGVyYXRvcihtZW1vLCB2YWx1ZSwgaW5kZXgpOworICAgIH0pOworICAgIHJldHVybiBtZW1vOworICB9LAorICAKKyAgaW52b2tlOiBmdW5jdGlvbihtZXRob2QpIHsKKyAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cykuc2xpY2UoMSk7CisgICAgcmV0dXJuIHRoaXMuY29sbGVjdChmdW5jdGlvbih2YWx1ZSkgeworICAgICAgcmV0dXJuIHZhbHVlW21ldGhvZF0uYXBwbHkodmFsdWUsIGFyZ3MpOworICAgIH0pOworICB9LAorICAKKyAgbWF4OiBmdW5jdGlvbihpdGVyYXRvcikgeworICAgIHZhciByZXN1bHQ7CisgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgeworICAgICAgdmFsdWUgPSAoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCk7CisgICAgICBpZiAodmFsdWUgPj0gKHJlc3VsdCB8fCB2YWx1ZSkpCisgICAgICAgIHJlc3VsdCA9IHZhbHVlOworICAgIH0pOworICAgIHJldHVybiByZXN1bHQ7CisgIH0sCisgIAorICBtaW46IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CisgICAgdmFyIHJlc3VsdDsKKyAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CisgICAgICB2YWx1ZSA9IChpdGVyYXRvciB8fCBQcm90b3R5cGUuSykodmFsdWUsIGluZGV4KTsKKyAgICAgIGlmICh2YWx1ZSA8PSAocmVzdWx0IHx8IHZhbHVlKSkKKyAgICAgICAgcmVzdWx0ID0gdmFsdWU7CisgICAgfSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSwKKyAgCisgIHBhcnRpdGlvbjogZnVuY3Rpb24oaXRlcmF0b3IpIHsKKyAgICB2YXIgdHJ1ZXMgPSBbXSwgZmFsc2VzID0gW107CisgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgeworICAgICAgKChpdGVyYXRvciB8fCBQcm90b3R5cGUuSykodmFsdWUsIGluZGV4KSA/IAorICAgICAgICB0cnVlcyA6IGZhbHNlcykucHVzaCh2YWx1ZSk7CisgICAgfSk7CisgICAgcmV0dXJuIFt0cnVlcywgZmFsc2VzXTsKKyAgfSwKKyAgCisgIHBsdWNrOiBmdW5jdGlvbihwcm9wZXJ0eSkgeworICAgIHZhciByZXN1bHRzID0gW107CisgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgeworICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlW3Byb3BlcnR5XSk7CisgICAgfSk7CisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0sCisgIAorICByZWplY3Q6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CisgICAgdmFyIHJlc3VsdHMgPSBbXTsKKyAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CisgICAgICBpZiAoIWl0ZXJhdG9yKHZhbHVlLCBpbmRleCkpCisgICAgICAgIHJlc3VsdHMucHVzaCh2YWx1ZSk7CisgICAgfSk7CisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0sCisgIAorICBzb3J0Qnk6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CisgICAgcmV0dXJuIHRoaXMuY29sbGVjdChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKKyAgICAgIHJldHVybiB7dmFsdWU6IHZhbHVlLCBjcml0ZXJpYTogaXRlcmF0b3IodmFsdWUsIGluZGV4KX07CisgICAgfSkuc29ydChmdW5jdGlvbihsZWZ0LCByaWdodCkgeworICAgICAgdmFyIGEgPSBsZWZ0LmNyaXRlcmlhLCBiID0gcmlnaHQuY3JpdGVyaWE7CisgICAgICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDA7CisgICAgfSkucGx1Y2soJ3ZhbHVlJyk7CisgIH0sCisgIAorICB0b0FycmF5OiBmdW5jdGlvbigpIHsKKyAgICByZXR1cm4gdGhpcy5jb2xsZWN0KFByb3RvdHlwZS5LKTsKKyAgfSwKKyAgCisgIHppcDogZnVuY3Rpb24oKSB7CisgICAgdmFyIGl0ZXJhdG9yID0gUHJvdG90eXBlLkssIGFyZ3MgPSAkQShhcmd1bWVudHMpOworICAgIGlmICh0eXBlb2YgYXJncy5sYXN0KCkgPT0gJ2Z1bmN0aW9uJykKKyAgICAgIGl0ZXJhdG9yID0gYXJncy5wb3AoKTsKKworICAgIHZhciBjb2xsZWN0aW9ucyA9IFt0aGlzXS5jb25jYXQoYXJncykubWFwKCRBKTsKKyAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CisgICAgICBpdGVyYXRvcih2YWx1ZSA9IGNvbGxlY3Rpb25zLnBsdWNrKGluZGV4KSk7CisgICAgICByZXR1cm4gdmFsdWU7CisgICAgfSk7CisgIH0KK30KKworT2JqZWN0LmV4dGVuZChFbnVtZXJhYmxlLCB7CisgIG1hcDogICAgIEVudW1lcmFibGUuY29sbGVjdCwKKyAgZmluZDogICAgRW51bWVyYWJsZS5kZXRlY3QsCisgIHNlbGVjdDogIEVudW1lcmFibGUuZmluZEFsbCwKKyAgbWVtYmVyOiAgRW51bWVyYWJsZS5pbmNsdWRlLAorICBlbnRyaWVzOiBFbnVtZXJhYmxlLnRvQXJyYXkKK30pOworCiskQSA9IEFycmF5LmZyb20gPSBmdW5jdGlvbihpdGVyYWJsZSkgeworICB2YXIgcmVzdWx0cyA9IFtdOworICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKQorICAgIHJlc3VsdHMucHVzaChpdGVyYWJsZVtpXSk7CisgIHJldHVybiByZXN1bHRzOworfQorCitPYmplY3QuZXh0ZW5kKEFycmF5LnByb3RvdHlwZSwgeworICBfZWFjaDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspCisgICAgICBpdGVyYXRvcih0aGlzW2ldKTsKKyAgfSwKKyAgCisgIGZpcnN0OiBmdW5jdGlvbigpIHsKKyAgICByZXR1cm4gdGhpc1swXTsKKyAgfSwKKyAgCisgIGxhc3Q6IGZ1bmN0aW9uKCkgeworICAgIHJldHVybiB0aGlzW3RoaXMubGVuZ3RoIC0gMV07CisgIH0KK30pOworCitPYmplY3QuZXh0ZW5kKEFycmF5LnByb3RvdHlwZSwgRW51bWVyYWJsZSk7CisKKwordmFyIEFqYXggPSB7CisgIGdldFRyYW5zcG9ydDogZnVuY3Rpb24oKSB7CisgICAgcmV0dXJuIFRyeS50aGVzZSgKKyAgICAgIGZ1bmN0aW9uKCkge3JldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAnKX0sCisgICAgICBmdW5jdGlvbigpIHtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyl9LAorICAgICAgZnVuY3Rpb24oKSB7cmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpfQorICAgICkgfHwgZmFsc2U7CisgIH0KK30KKworQWpheC5CYXNlID0gZnVuY3Rpb24oKSB7fTsKK0FqYXguQmFzZS5wcm90b3R5cGUgPSB7CisgIHNldE9wdGlvbnM6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKKyAgICB0aGlzLm9wdGlvbnMgPSB7CisgICAgICBtZXRob2Q6ICAgICAgICdwb3N0JywKKyAgICAgIGFzeW5jaHJvbm91czogdHJ1ZSwKKyAgICAgIHBhcmFtZXRlcnM6ICAgJycKKyAgICB9CisgICAgT2JqZWN0LmV4dGVuZCh0aGlzLm9wdGlvbnMsIG9wdGlvbnMgfHwge30pOworICB9LAorCisgIHJlc3BvbnNlSXNTdWNjZXNzOiBmdW5jdGlvbigpIHsKKyAgICByZXR1cm4gdGhpcy50cmFuc3BvcnQuc3RhdHVzID09IHVuZGVmaW5lZAorICAgICAgICB8fCB0aGlzLnRyYW5zcG9ydC5zdGF0dXMgPT0gMCAKKyAgICAgICAgfHwgKHRoaXMudHJhbnNwb3J0LnN0YXR1cyA+PSAyMDAgJiYgdGhpcy50cmFuc3BvcnQuc3RhdHVzIDwgMzAwKTsKKyAgfSwKKworICByZXNwb25zZUlzRmFpbHVyZTogZnVuY3Rpb24oKSB7CisgICAgcmV0dXJuICF0aGlzLnJlc3BvbnNlSXNTdWNjZXNzKCk7CisgIH0KK30KKworQWpheC5SZXF1ZXN0ID0gQ2xhc3MuY3JlYXRlKCk7CitBamF4LlJlcXVlc3QuRXZlbnRzID0gCisgIFsnVW5pbml0aWFsaXplZCcsICdMb2FkaW5nJywgJ0xvYWRlZCcsICdJbnRlcmFjdGl2ZScsICdDb21wbGV0ZSddOworCitBamF4LlJlcXVlc3QucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWpheC5CYXNlKCksIHsKKyAgaW5pdGlhbGl6ZTogZnVuY3Rpb24odXJsLCBvcHRpb25zKSB7CisgICAgdGhpcy50cmFuc3BvcnQgPSBBamF4LmdldFRyYW5zcG9ydCgpOworICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTsKKyAgICB0aGlzLnJlcXVlc3QodXJsKTsKKyAgfSwKKworICByZXF1ZXN0OiBmdW5jdGlvbih1cmwpIHsKKyAgICB2YXIgcGFyYW1ldGVycyA9IHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzIHx8ICcnOworICAgIGlmIChwYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHBhcmFtZXRlcnMgKz0gJyZfPSc7CisKKyAgICB0cnkgeworICAgICAgaWYgKHRoaXMub3B0aW9ucy5tZXRob2QgPT0gJ2dldCcpCisgICAgICAgIHVybCArPSAnPycgKyBwYXJhbWV0ZXJzOworCisgICAgICB0aGlzLnRyYW5zcG9ydC5vcGVuKHRoaXMub3B0aW9ucy5tZXRob2QsIHVybCwKKyAgICAgICAgdGhpcy5vcHRpb25zLmFzeW5jaHJvbm91cyk7CisKKyAgICAgIGlmICh0aGlzLm9wdGlvbnMuYXN5bmNocm9ub3VzKSB7CisgICAgICAgIHRoaXMudHJhbnNwb3J0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHRoaXMub25TdGF0ZUNoYW5nZS5iaW5kKHRoaXMpOworICAgICAgICBzZXRUaW1lb3V0KChmdW5jdGlvbigpIHt0aGlzLnJlc3BvbmRUb1JlYWR5U3RhdGUoMSl9KS5iaW5kKHRoaXMpLCAxMCk7CisgICAgICB9CisKKyAgICAgIHRoaXMuc2V0UmVxdWVzdEhlYWRlcnMoKTsKKworICAgICAgdmFyIGJvZHkgPSB0aGlzLm9wdGlvbnMucG9zdEJvZHkgPyB0aGlzLm9wdGlvbnMucG9zdEJvZHkgOiBwYXJhbWV0ZXJzOworICAgICAgdGhpcy50cmFuc3BvcnQuc2VuZCh0aGlzLm9wdGlvbnMubWV0aG9kID09ICdwb3N0JyA/IGJvZHkgOiBudWxsKTsKKworICAgIH0gY2F0Y2ggKGUpIHsKKyAgICB9CisgIH0sCisKKyAgc2V0UmVxdWVzdEhlYWRlcnM6IGZ1bmN0aW9uKCkgeworICAgIHZhciByZXF1ZXN0SGVhZGVycyA9IAorICAgICAgWydYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0JywKKyAgICAgICAnWC1Qcm90b3R5cGUtVmVyc2lvbicsIFByb3RvdHlwZS5WZXJzaW9uXTsKKworICAgIGlmICh0aGlzLm9wdGlvbnMubWV0aG9kID09ICdwb3N0JykgeworICAgICAgcmVxdWVzdEhlYWRlcnMucHVzaCgnQ29udGVudC10eXBlJywgCisgICAgICAgICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTsKKworICAgICAgLyogRm9yY2UgIkNvbm5lY3Rpb246IGNsb3NlIiBmb3IgTW96aWxsYSBicm93c2VycyB0byB3b3JrIGFyb3VuZAorICAgICAgICogYSBidWcgd2hlcmUgWE1MSHR0cFJlcWV1ZXN0IHNlbmRzIGFuIGluY29ycmVjdCBDb250ZW50LWxlbmd0aAorICAgICAgICogaGVhZGVyLiBTZWUgTW96aWxsYSBCdWd6aWxsYSAjMjQ2NjUxLiAKKyAgICAgICAqLworICAgICAgaWYgKHRoaXMudHJhbnNwb3J0Lm92ZXJyaWRlTWltZVR5cGUpCisgICAgICAgIHJlcXVlc3RIZWFkZXJzLnB1c2goJ0Nvbm5lY3Rpb24nLCAnY2xvc2UnKTsKKyAgICB9CisKKyAgICBpZiAodGhpcy5vcHRpb25zLnJlcXVlc3RIZWFkZXJzKQorICAgICAgcmVxdWVzdEhlYWRlcnMucHVzaC5hcHBseShyZXF1ZXN0SGVhZGVycywgdGhpcy5vcHRpb25zLnJlcXVlc3RIZWFkZXJzKTsKKworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVxdWVzdEhlYWRlcnMubGVuZ3RoOyBpICs9IDIpCisgICAgICB0aGlzLnRyYW5zcG9ydC5zZXRSZXF1ZXN0SGVhZGVyKHJlcXVlc3RIZWFkZXJzW2ldLCByZXF1ZXN0SGVhZGVyc1tpKzFdKTsKKyAgfSwKKworICBvblN0YXRlQ2hhbmdlOiBmdW5jdGlvbigpIHsKKyAgICB2YXIgcmVhZHlTdGF0ZSA9IHRoaXMudHJhbnNwb3J0LnJlYWR5U3RhdGU7CisgICAgaWYgKHJlYWR5U3RhdGUgIT0gMSkKKyAgICAgIHRoaXMucmVzcG9uZFRvUmVhZHlTdGF0ZSh0aGlzLnRyYW5zcG9ydC5yZWFkeVN0YXRlKTsKKyAgfSwKKworICByZXNwb25kVG9SZWFkeVN0YXRlOiBmdW5jdGlvbihyZWFkeVN0YXRlKSB7CisgICAgdmFyIGV2ZW50ID0gQWpheC5SZXF1ZXN0LkV2ZW50c1tyZWFkeVN0YXRlXTsKKworICAgIGlmIChldmVudCA9PSAnQ29tcGxldGUnKQorICAgICAgKHRoaXMub3B0aW9uc1snb24nICsgdGhpcy50cmFuc3BvcnQuc3RhdHVzXQorICAgICAgIHx8IHRoaXMub3B0aW9uc1snb24nICsgKHRoaXMucmVzcG9uc2VJc1N1Y2Nlc3MoKSA/ICdTdWNjZXNzJyA6ICdGYWlsdXJlJyldCisgICAgICAgfHwgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb24pKHRoaXMudHJhbnNwb3J0KTsKKworICAgICh0aGlzLm9wdGlvbnNbJ29uJyArIGV2ZW50XSB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbikodGhpcy50cmFuc3BvcnQpOworCisgICAgLyogQXZvaWQgbWVtb3J5IGxlYWsgaW4gTVNJRTogY2xlYW4gdXAgdGhlIG9uY29tcGxldGUgZXZlbnQgaGFuZGxlciAqLworICAgIGlmIChldmVudCA9PSAnQ29tcGxldGUnKQorICAgICAgdGhpcy50cmFuc3BvcnQub25yZWFkeXN0YXRlY2hhbmdlID0gUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247CisgIH0KK30pOworCitBamF4LlVwZGF0ZXIgPSBDbGFzcy5jcmVhdGUoKTsKK0FqYXguVXBkYXRlci5TY3JpcHRGcmFnbWVudCA9ICcoPzo8c2NyaXB0Lio/PikoKFxufC4pKj8pKD86PFwvc2NyaXB0PiknOworCitPYmplY3QuZXh0ZW5kKE9iamVjdC5leHRlbmQoQWpheC5VcGRhdGVyLnByb3RvdHlwZSwgQWpheC5SZXF1ZXN0LnByb3RvdHlwZSksIHsKKyAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oY29udGFpbmVyLCB1cmwsIG9wdGlvbnMpIHsKKyAgICB0aGlzLmNvbnRhaW5lcnMgPSB7CisgICAgICBzdWNjZXNzOiBjb250YWluZXIuc3VjY2VzcyA/ICQoY29udGFpbmVyLnN1Y2Nlc3MpIDogJChjb250YWluZXIpLAorICAgICAgZmFpbHVyZTogY29udGFpbmVyLmZhaWx1cmUgPyAkKGNvbnRhaW5lci5mYWlsdXJlKSA6CisgICAgICAgIChjb250YWluZXIuc3VjY2VzcyA/IG51bGwgOiAkKGNvbnRhaW5lcikpCisgICAgfQorCisgICAgdGhpcy50cmFuc3BvcnQgPSBBamF4LmdldFRyYW5zcG9ydCgpOworICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTsKKworICAgIHZhciBvbkNvbXBsZXRlID0gdGhpcy5vcHRpb25zLm9uQ29tcGxldGUgfHwgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247CisgICAgdGhpcy5vcHRpb25zLm9uQ29tcGxldGUgPSAoZnVuY3Rpb24oKSB7CisgICAgICB0aGlzLnVwZGF0ZUNvbnRlbnQoKTsKKyAgICAgIG9uQ29tcGxldGUodGhpcy50cmFuc3BvcnQpOworICAgIH0pLmJpbmQodGhpcyk7CisKKyAgICB0aGlzLnJlcXVlc3QodXJsKTsKKyAgfSwKKworICB1cGRhdGVDb250ZW50OiBmdW5jdGlvbigpIHsKKyAgICB2YXIgcmVjZWl2ZXIgPSB0aGlzLnJlc3BvbnNlSXNTdWNjZXNzKCkgPworICAgICAgdGhpcy5jb250YWluZXJzLnN1Y2Nlc3MgOiB0aGlzLmNvbnRhaW5lcnMuZmFpbHVyZTsKKworICAgIHZhciBtYXRjaCAgICA9IG5ldyBSZWdFeHAoQWpheC5VcGRhdGVyLlNjcmlwdEZyYWdtZW50LCAnaW1nJyk7CisgICAgdmFyIHJlc3BvbnNlID0gdGhpcy50cmFuc3BvcnQucmVzcG9uc2VUZXh0LnJlcGxhY2UobWF0Y2gsICcnKTsKKyAgICB2YXIgc2NyaXB0cyAgPSB0aGlzLnRyYW5zcG9ydC5yZXNwb25zZVRleHQubWF0Y2gobWF0Y2gpOworCisgICAgaWYgKHJlY2VpdmVyKSB7CisgICAgICBpZiAodGhpcy5vcHRpb25zLmluc2VydGlvbikgeworICAgICAgICBuZXcgdGhpcy5vcHRpb25zLmluc2VydGlvbihyZWNlaXZlciwgcmVzcG9uc2UpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVjZWl2ZXIuaW5uZXJIVE1MID0gcmVzcG9uc2U7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHRoaXMucmVzcG9uc2VJc1N1Y2Nlc3MoKSkgeworICAgICAgaWYgKHRoaXMub25Db21wbGV0ZSkKKyAgICAgICAgc2V0VGltZW91dCgoZnVuY3Rpb24oKSB7dGhpcy5vbkNvbXBsZXRlKAorICAgICAgICAgIHRoaXMudHJhbnNwb3J0KX0pLmJpbmQodGhpcyksIDEwKTsKKyAgICB9CisKKyAgICBpZiAodGhpcy5vcHRpb25zLmV2YWxTY3JpcHRzICYmIHNjcmlwdHMpIHsKKyAgICAgIG1hdGNoID0gbmV3IFJlZ0V4cChBamF4LlVwZGF0ZXIuU2NyaXB0RnJhZ21lbnQsICdpbScpOworICAgICAgc2V0VGltZW91dCgoZnVuY3Rpb24oKSB7CisgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2NyaXB0cy5sZW5ndGg7IGkrKykKKyAgICAgICAgICBldmFsKHNjcmlwdHNbaV0ubWF0Y2gobWF0Y2gpWzFdKTsKKyAgICAgIH0pLmJpbmQodGhpcyksIDEwKTsKKyAgICB9CisgIH0KK30pOworCitBamF4LlBlcmlvZGljYWxVcGRhdGVyID0gQ2xhc3MuY3JlYXRlKCk7CitBamF4LlBlcmlvZGljYWxVcGRhdGVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFqYXguQmFzZSgpLCB7CisgIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNvbnRhaW5lciwgdXJsLCBvcHRpb25zKSB7CisgICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpOworICAgIHRoaXMub25Db21wbGV0ZSA9IHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlOworCisgICAgdGhpcy5mcmVxdWVuY3kgPSAodGhpcy5vcHRpb25zLmZyZXF1ZW5jeSB8fCAyKTsKKyAgICB0aGlzLmRlY2F5ID0gMTsKKworICAgIHRoaXMudXBkYXRlciA9IHt9OworICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyOworICAgIHRoaXMudXJsID0gdXJsOworCisgICAgdGhpcy5zdGFydCgpOworICB9LAorCisgIHN0YXJ0OiBmdW5jdGlvbigpIHsKKyAgICB0aGlzLm9wdGlvbnMub25Db21wbGV0ZSA9IHRoaXMudXBkYXRlQ29tcGxldGUuYmluZCh0aGlzKTsKKyAgICB0aGlzLm9uVGltZXJFdmVudCgpOworICB9LAorCisgIHN0b3A6IGZ1bmN0aW9uKCkgeworICAgIHRoaXMudXBkYXRlci5vbkNvbXBsZXRlID0gdW5kZWZpbmVkOworICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTsKKyAgICAodGhpcy5vbkNvbXBsZXRlIHx8IEFqYXguZW1wdHlGdW5jdGlvbikuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKKyAgfSwKKworICB1cGRhdGVDb21wbGV0ZTogZnVuY3Rpb24ocmVxdWVzdCkgeworICAgIGlmICh0aGlzLm9wdGlvbnMuZGVjYXkpIHsKKyAgICAgIHRoaXMuZGVjYXkgPSAocmVxdWVzdC5yZXNwb25zZVRleHQgPT0gdGhpcy5sYXN0VGV4dCA/IAorICAgICAgICB0aGlzLmRlY2F5ICogdGhpcy5vcHRpb25zLmRlY2F5IDogMSk7CisKKyAgICAgIHRoaXMubGFzdFRleHQgPSByZXF1ZXN0LnJlc3BvbnNlVGV4dDsKKyAgICB9CisgICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQodGhpcy5vblRpbWVyRXZlbnQuYmluZCh0aGlzKSwgCisgICAgICB0aGlzLmRlY2F5ICogdGhpcy5mcmVxdWVuY3kgKiAxMDAwKTsKKyAgfSwKKworICBvblRpbWVyRXZlbnQ6IGZ1bmN0aW9uKCkgeworICAgIHRoaXMudXBkYXRlciA9IG5ldyBBamF4LlVwZGF0ZXIodGhpcy5jb250YWluZXIsIHRoaXMudXJsLCB0aGlzLm9wdGlvbnMpOworICB9Cit9KTsKKworZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IGZ1bmN0aW9uKGNsYXNzTmFtZSkgeworICB2YXIgY2hpbGRyZW4gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnKicpIHx8IGRvY3VtZW50LmFsbDsKKyAgdmFyIGVsZW1lbnRzID0gbmV3IEFycmF5KCk7CisgIAorICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CisgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07CisgICAgdmFyIGNsYXNzTmFtZXMgPSBjaGlsZC5jbGFzc05hbWUuc3BsaXQoJyAnKTsKKyAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNsYXNzTmFtZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgIGlmIChjbGFzc05hbWVzW2pdID09IGNsYXNzTmFtZSkgeworICAgICAgICBlbGVtZW50cy5wdXNoKGNoaWxkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisgIAorICByZXR1cm4gZWxlbWVudHM7Cit9CisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCitpZiAoIXdpbmRvdy5FbGVtZW50KSB7CisgIHZhciBFbGVtZW50ID0gbmV3IE9iamVjdCgpOworfQorCitPYmplY3QuZXh0ZW5kKEVsZW1lbnQsIHsKKyAgdG9nZ2xlOiBmdW5jdGlvbigpIHsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgdmFyIGVsZW1lbnQgPSAkKGFyZ3VtZW50c1tpXSk7CisgICAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAKKyAgICAgICAgKGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9PSAnbm9uZScgPyAnJyA6ICdub25lJyk7CisgICAgfQorICB9LAorCisgIGhpZGU6IGZ1bmN0aW9uKCkgeworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICB2YXIgZWxlbWVudCA9ICQoYXJndW1lbnRzW2ldKTsKKyAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKKyAgICB9CisgIH0sCisKKyAgc2hvdzogZnVuY3Rpb24oKSB7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHZhciBlbGVtZW50ID0gJChhcmd1bWVudHNbaV0pOworICAgICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJyc7CisgICAgfQorICB9LAorCisgIHJlbW92ZTogZnVuY3Rpb24oZWxlbWVudCkgeworICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOworICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTsKKyAgfSwKKyAgIAorICBnZXRIZWlnaHQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKKyAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKKyAgICByZXR1cm4gZWxlbWVudC5vZmZzZXRIZWlnaHQ7IAorICB9LAorCisgIGhhc0NsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CisgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CisgICAgaWYgKCFlbGVtZW50KQorICAgICAgcmV0dXJuOworICAgIHZhciBhID0gZWxlbWVudC5jbGFzc05hbWUuc3BsaXQoJyAnKTsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHsKKyAgICAgIGlmIChhW2ldID09IGNsYXNzTmFtZSkKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfSwKKworICBhZGRDbGFzc05hbWU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSkgeworICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOworICAgIEVsZW1lbnQucmVtb3ZlQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSk7CisgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gJyAnICsgY2xhc3NOYW1lOworICB9LAorCisgIHJlbW92ZUNsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CisgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CisgICAgaWYgKCFlbGVtZW50KQorICAgICAgcmV0dXJuOworICAgIHZhciBuZXdDbGFzc05hbWUgPSAnJzsKKyAgICB2YXIgYSA9IGVsZW1lbnQuY2xhc3NOYW1lLnNwbGl0KCcgJyk7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoYVtpXSAhPSBjbGFzc05hbWUpIHsKKyAgICAgICAgaWYgKGkgPiAwKQorICAgICAgICAgIG5ld0NsYXNzTmFtZSArPSAnICc7CisgICAgICAgIG5ld0NsYXNzTmFtZSArPSBhW2ldOworICAgICAgfQorICAgIH0KKyAgICBlbGVtZW50LmNsYXNzTmFtZSA9IG5ld0NsYXNzTmFtZTsKKyAgfSwKKyAgCisgIC8vIHJlbW92ZXMgd2hpdGVzcGFjZS1vbmx5IHRleHQgbm9kZSBjaGlsZHJlbgorICBjbGVhbldoaXRlc3BhY2U6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKKyAgICB2YXIgZWxlbWVudCA9ICQoZWxlbWVudCk7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHZhciBub2RlID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldOworICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMyAmJiAhL1xTLy50ZXN0KG5vZGUubm9kZVZhbHVlKSkgCisgICAgICAgIEVsZW1lbnQucmVtb3ZlKG5vZGUpOworICAgIH0KKyAgfQorfSk7CisKK3ZhciBUb2dnbGUgPSBuZXcgT2JqZWN0KCk7CitUb2dnbGUuZGlzcGxheSA9IEVsZW1lbnQudG9nZ2xlOworCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworQWJzdHJhY3QuSW5zZXJ0aW9uID0gZnVuY3Rpb24oYWRqYWNlbmN5KSB7CisgIHRoaXMuYWRqYWNlbmN5ID0gYWRqYWNlbmN5OworfQorCitBYnN0cmFjdC5JbnNlcnRpb24ucHJvdG90eXBlID0geworICBpbml0aWFsaXplOiBmdW5jdGlvbihlbGVtZW50LCBjb250ZW50KSB7CisgICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTsKKyAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50OworICAgIAorICAgIGlmICh0aGlzLmFkamFjZW5jeSAmJiB0aGlzLmVsZW1lbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKSB7CisgICAgICB0aGlzLmVsZW1lbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKHRoaXMuYWRqYWNlbmN5LCB0aGlzLmNvbnRlbnQpOworICAgIH0gZWxzZSB7CisgICAgICB0aGlzLnJhbmdlID0gdGhpcy5lbGVtZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTsKKyAgICAgIGlmICh0aGlzLmluaXRpYWxpemVSYW5nZSkgdGhpcy5pbml0aWFsaXplUmFuZ2UoKTsKKyAgICAgIHRoaXMuZnJhZ21lbnQgPSB0aGlzLnJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCh0aGlzLmNvbnRlbnQpOworICAgICAgdGhpcy5pbnNlcnRDb250ZW50KCk7CisgICAgfQorICB9Cit9CisKK3ZhciBJbnNlcnRpb24gPSBuZXcgT2JqZWN0KCk7CisKK0luc2VydGlvbi5CZWZvcmUgPSBDbGFzcy5jcmVhdGUoKTsKK0luc2VydGlvbi5CZWZvcmUucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuSW5zZXJ0aW9uKCdiZWZvcmVCZWdpbicpLCB7CisgIGluaXRpYWxpemVSYW5nZTogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5yYW5nZS5zZXRTdGFydEJlZm9yZSh0aGlzLmVsZW1lbnQpOworICB9LAorICAKKyAgaW5zZXJ0Q29udGVudDogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5lbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMuZnJhZ21lbnQsIHRoaXMuZWxlbWVudCk7CisgIH0KK30pOworCitJbnNlcnRpb24uVG9wID0gQ2xhc3MuY3JlYXRlKCk7CitJbnNlcnRpb24uVG9wLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0Lkluc2VydGlvbignYWZ0ZXJCZWdpbicpLCB7CisgIGluaXRpYWxpemVSYW5nZTogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5yYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGhpcy5lbGVtZW50KTsKKyAgICB0aGlzLnJhbmdlLmNvbGxhcHNlKHRydWUpOworICB9LAorICAKKyAgaW5zZXJ0Q29udGVudDogZnVuY3Rpb24oKSB7ICAKKyAgICB0aGlzLmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRoaXMuZnJhZ21lbnQsIHRoaXMuZWxlbWVudC5maXJzdENoaWxkKTsKKyAgfQorfSk7CisKK0luc2VydGlvbi5Cb3R0b20gPSBDbGFzcy5jcmVhdGUoKTsKK0luc2VydGlvbi5Cb3R0b20ucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuSW5zZXJ0aW9uKCdiZWZvcmVFbmQnKSwgeworICBpbml0aWFsaXplUmFuZ2U6IGZ1bmN0aW9uKCkgeworICAgIHRoaXMucmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRoaXMuZWxlbWVudCk7CisgICAgdGhpcy5yYW5nZS5jb2xsYXBzZSh0aGlzLmVsZW1lbnQpOworICB9LAorICAKKyAgaW5zZXJ0Q29udGVudDogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuZnJhZ21lbnQpOworICB9Cit9KTsKKworSW5zZXJ0aW9uLkFmdGVyID0gQ2xhc3MuY3JlYXRlKCk7CitJbnNlcnRpb24uQWZ0ZXIucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuSW5zZXJ0aW9uKCdhZnRlckVuZCcpLCB7CisgIGluaXRpYWxpemVSYW5nZTogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5yYW5nZS5zZXRTdGFydEFmdGVyKHRoaXMuZWxlbWVudCk7CisgIH0sCisgIAorICBpbnNlcnRDb250ZW50OiBmdW5jdGlvbigpIHsKKyAgICB0aGlzLmVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5mcmFnbWVudCwgCisgICAgICB0aGlzLmVsZW1lbnQubmV4dFNpYmxpbmcpOworICB9Cit9KTsKKwordmFyIEZpZWxkID0geworICBjbGVhcjogZnVuY3Rpb24oKSB7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspCisgICAgICAkKGFyZ3VtZW50c1tpXSkudmFsdWUgPSAnJzsKKyAgfSwKKworICBmb2N1czogZnVuY3Rpb24oZWxlbWVudCkgeworICAgICQoZWxlbWVudCkuZm9jdXMoKTsKKyAgfSwKKyAgCisgIHByZXNlbnQ6IGZ1bmN0aW9uKCkgeworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKQorICAgICAgaWYgKCQoYXJndW1lbnRzW2ldKS52YWx1ZSA9PSAnJykgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiB0cnVlOworICB9LAorICAKKyAgc2VsZWN0OiBmdW5jdGlvbihlbGVtZW50KSB7CisgICAgJChlbGVtZW50KS5zZWxlY3QoKTsKKyAgfSwKKyAgIAorICBhY3RpdmF0ZTogZnVuY3Rpb24oZWxlbWVudCkgeworICAgICQoZWxlbWVudCkuZm9jdXMoKTsKKyAgICAkKGVsZW1lbnQpLnNlbGVjdCgpOworICB9Cit9CisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCit2YXIgRm9ybSA9IHsKKyAgc2VyaWFsaXplOiBmdW5jdGlvbihmb3JtKSB7CisgICAgdmFyIGVsZW1lbnRzID0gRm9ybS5nZXRFbGVtZW50cygkKGZvcm0pKTsKKyAgICB2YXIgcXVlcnlDb21wb25lbnRzID0gbmV3IEFycmF5KCk7CisgICAgCisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgdmFyIHF1ZXJ5Q29tcG9uZW50ID0gRm9ybS5FbGVtZW50LnNlcmlhbGl6ZShlbGVtZW50c1tpXSk7CisgICAgICBpZiAocXVlcnlDb21wb25lbnQpCisgICAgICAgIHF1ZXJ5Q29tcG9uZW50cy5wdXNoKHF1ZXJ5Q29tcG9uZW50KTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHF1ZXJ5Q29tcG9uZW50cy5qb2luKCcmJyk7CisgIH0sCisgIAorICBnZXRFbGVtZW50czogZnVuY3Rpb24oZm9ybSkgeworICAgIHZhciBmb3JtID0gJChmb3JtKTsKKyAgICB2YXIgZWxlbWVudHMgPSBuZXcgQXJyYXkoKTsKKworICAgIGZvciAodGFnTmFtZSBpbiBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnMpIHsKKyAgICAgIHZhciB0YWdFbGVtZW50cyA9IGZvcm0uZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnTmFtZSk7CisgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRhZ0VsZW1lbnRzLmxlbmd0aDsgaisrKQorICAgICAgICBlbGVtZW50cy5wdXNoKHRhZ0VsZW1lbnRzW2pdKTsKKyAgICB9CisgICAgcmV0dXJuIGVsZW1lbnRzOworICB9LAorICAKKyAgZ2V0SW5wdXRzOiBmdW5jdGlvbihmb3JtLCB0eXBlTmFtZSwgbmFtZSkgeworICAgIHZhciBmb3JtID0gJChmb3JtKTsKKyAgICB2YXIgaW5wdXRzID0gZm9ybS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTsKKyAgICAKKyAgICBpZiAoIXR5cGVOYW1lICYmICFuYW1lKQorICAgICAgcmV0dXJuIGlucHV0czsKKyAgICAgIAorICAgIHZhciBtYXRjaGluZ0lucHV0cyA9IG5ldyBBcnJheSgpOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV07CisgICAgICBpZiAoKHR5cGVOYW1lICYmIGlucHV0LnR5cGUgIT0gdHlwZU5hbWUpIHx8CisgICAgICAgICAgKG5hbWUgJiYgaW5wdXQubmFtZSAhPSBuYW1lKSkgCisgICAgICAgIGNvbnRpbnVlOworICAgICAgbWF0Y2hpbmdJbnB1dHMucHVzaChpbnB1dCk7CisgICAgfQorCisgICAgcmV0dXJuIG1hdGNoaW5nSW5wdXRzOworICB9LAorCisgIGRpc2FibGU6IGZ1bmN0aW9uKGZvcm0pIHsKKyAgICB2YXIgZWxlbWVudHMgPSBGb3JtLmdldEVsZW1lbnRzKGZvcm0pOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNbaV07CisgICAgICBlbGVtZW50LmJsdXIoKTsKKyAgICAgIGVsZW1lbnQuZGlzYWJsZWQgPSAndHJ1ZSc7CisgICAgfQorICB9LAorCisgIGVuYWJsZTogZnVuY3Rpb24oZm9ybSkgeworICAgIHZhciBlbGVtZW50cyA9IEZvcm0uZ2V0RWxlbWVudHMoZm9ybSk7CisgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgeworICAgICAgdmFyIGVsZW1lbnQgPSBlbGVtZW50c1tpXTsKKyAgICAgIGVsZW1lbnQuZGlzYWJsZWQgPSAnJzsKKyAgICB9CisgIH0sCisKKyAgZm9jdXNGaXJzdEVsZW1lbnQ6IGZ1bmN0aW9uKGZvcm0pIHsKKyAgICB2YXIgZm9ybSA9ICQoZm9ybSk7CisgICAgdmFyIGVsZW1lbnRzID0gRm9ybS5nZXRFbGVtZW50cyhmb3JtKTsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRzW2ldOworICAgICAgaWYgKGVsZW1lbnQudHlwZSAhPSAnaGlkZGVuJyAmJiAhZWxlbWVudC5kaXNhYmxlZCkgeworICAgICAgICBGaWVsZC5hY3RpdmF0ZShlbGVtZW50KTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9LAorCisgIHJlc2V0OiBmdW5jdGlvbihmb3JtKSB7CisgICAgJChmb3JtKS5yZXNldCgpOworICB9Cit9CisKK0Zvcm0uRWxlbWVudCA9IHsKKyAgc2VyaWFsaXplOiBmdW5jdGlvbihlbGVtZW50KSB7CisgICAgdmFyIGVsZW1lbnQgPSAkKGVsZW1lbnQpOworICAgIHZhciBtZXRob2QgPSBlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKTsKKyAgICB2YXIgcGFyYW1ldGVyID0gRm9ybS5FbGVtZW50LlNlcmlhbGl6ZXJzW21ldGhvZF0oZWxlbWVudCk7CisgICAgCisgICAgaWYgKHBhcmFtZXRlcikKKyAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQocGFyYW1ldGVyWzBdKSArICc9JyArIAorICAgICAgICBlbmNvZGVVUklDb21wb25lbnQocGFyYW1ldGVyWzFdKTsgICAgICAgICAgICAgICAgICAgCisgIH0sCisgIAorICBnZXRWYWx1ZTogZnVuY3Rpb24oZWxlbWVudCkgeworICAgIHZhciBlbGVtZW50ID0gJChlbGVtZW50KTsKKyAgICB2YXIgbWV0aG9kID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7CisgICAgdmFyIHBhcmFtZXRlciA9IEZvcm0uRWxlbWVudC5TZXJpYWxpemVyc1ttZXRob2RdKGVsZW1lbnQpOworICAgIAorICAgIGlmIChwYXJhbWV0ZXIpIAorICAgICAgcmV0dXJuIHBhcmFtZXRlclsxXTsKKyAgfQorfQorCitGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnMgPSB7CisgIGlucHV0OiBmdW5jdGlvbihlbGVtZW50KSB7CisgICAgc3dpdGNoIChlbGVtZW50LnR5cGUudG9Mb3dlckNhc2UoKSkgeworICAgICAgY2FzZSAnc3VibWl0JzoKKyAgICAgIGNhc2UgJ2hpZGRlbic6CisgICAgICBjYXNlICdwYXNzd29yZCc6CisgICAgICBjYXNlICd0ZXh0JzoKKyAgICAgICAgcmV0dXJuIEZvcm0uRWxlbWVudC5TZXJpYWxpemVycy50ZXh0YXJlYShlbGVtZW50KTsKKyAgICAgIGNhc2UgJ2NoZWNrYm94JzogIAorICAgICAgY2FzZSAncmFkaW8nOgorICAgICAgICByZXR1cm4gRm9ybS5FbGVtZW50LlNlcmlhbGl6ZXJzLmlucHV0U2VsZWN0b3IoZWxlbWVudCk7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfSwKKworICBpbnB1dFNlbGVjdG9yOiBmdW5jdGlvbihlbGVtZW50KSB7CisgICAgaWYgKGVsZW1lbnQuY2hlY2tlZCkKKyAgICAgIHJldHVybiBbZWxlbWVudC5uYW1lLCBlbGVtZW50LnZhbHVlXTsKKyAgfSwKKworICB0ZXh0YXJlYTogZnVuY3Rpb24oZWxlbWVudCkgeworICAgIHJldHVybiBbZWxlbWVudC5uYW1lLCBlbGVtZW50LnZhbHVlXTsKKyAgfSwKKworICBzZWxlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKKyAgICB2YXIgdmFsdWUgPSAnJzsKKyAgICBpZiAoZWxlbWVudC50eXBlID09ICdzZWxlY3Qtb25lJykgeworICAgICAgdmFyIGluZGV4ID0gZWxlbWVudC5zZWxlY3RlZEluZGV4OworICAgICAgaWYgKGluZGV4ID49IDApCisgICAgICAgIHZhbHVlID0gZWxlbWVudC5vcHRpb25zW2luZGV4XS52YWx1ZSB8fCBlbGVtZW50Lm9wdGlvbnNbaW5kZXhdLnRleHQ7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhbHVlID0gbmV3IEFycmF5KCk7CisgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgdmFyIG9wdCA9IGVsZW1lbnQub3B0aW9uc1tpXTsKKyAgICAgICAgaWYgKG9wdC5zZWxlY3RlZCkKKyAgICAgICAgICB2YWx1ZS5wdXNoKG9wdC52YWx1ZSB8fCBvcHQudGV4dCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBbZWxlbWVudC5uYW1lLCB2YWx1ZV07CisgIH0KK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKK3ZhciAkRiA9IEZvcm0uRWxlbWVudC5nZXRWYWx1ZTsKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKK0Fic3RyYWN0LlRpbWVkT2JzZXJ2ZXIgPSBmdW5jdGlvbigpIHt9CitBYnN0cmFjdC5UaW1lZE9ic2VydmVyLnByb3RvdHlwZSA9IHsKKyAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCwgZnJlcXVlbmN5LCBjYWxsYmFjaykgeworICAgIHRoaXMuZnJlcXVlbmN5ID0gZnJlcXVlbmN5OworICAgIHRoaXMuZWxlbWVudCAgID0gJChlbGVtZW50KTsKKyAgICB0aGlzLmNhbGxiYWNrICA9IGNhbGxiYWNrOworICAgIAorICAgIHRoaXMubGFzdFZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpOworICAgIHRoaXMucmVnaXN0ZXJDYWxsYmFjaygpOworICB9LAorICAKKyAgcmVnaXN0ZXJDYWxsYmFjazogZnVuY3Rpb24oKSB7CisgICAgc2V0SW50ZXJ2YWwodGhpcy5vblRpbWVyRXZlbnQuYmluZCh0aGlzKSwgdGhpcy5mcmVxdWVuY3kgKiAxMDAwKTsKKyAgfSwKKyAgCisgIG9uVGltZXJFdmVudDogZnVuY3Rpb24oKSB7CisgICAgdmFyIHZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpOworICAgIGlmICh0aGlzLmxhc3RWYWx1ZSAhPSB2YWx1ZSkgeworICAgICAgdGhpcy5jYWxsYmFjayh0aGlzLmVsZW1lbnQsIHZhbHVlKTsKKyAgICAgIHRoaXMubGFzdFZhbHVlID0gdmFsdWU7CisgICAgfQorICB9Cit9CisKK0Zvcm0uRWxlbWVudC5PYnNlcnZlciA9IENsYXNzLmNyZWF0ZSgpOworRm9ybS5FbGVtZW50Lk9ic2VydmVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0LlRpbWVkT2JzZXJ2ZXIoKSwgeworICBnZXRWYWx1ZTogZnVuY3Rpb24oKSB7CisgICAgcmV0dXJuIEZvcm0uRWxlbWVudC5nZXRWYWx1ZSh0aGlzLmVsZW1lbnQpOworICB9Cit9KTsKKworRm9ybS5PYnNlcnZlciA9IENsYXNzLmNyZWF0ZSgpOworRm9ybS5PYnNlcnZlci5wcm90b3R5cGUgPSBPYmplY3QuZXh0ZW5kKG5ldyBBYnN0cmFjdC5UaW1lZE9ic2VydmVyKCksIHsKKyAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkgeworICAgIHJldHVybiBGb3JtLnNlcmlhbGl6ZSh0aGlzLmVsZW1lbnQpOworICB9Cit9KTsKKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKK0Fic3RyYWN0LkV2ZW50T2JzZXJ2ZXIgPSBmdW5jdGlvbigpIHt9CitBYnN0cmFjdC5FdmVudE9ic2VydmVyLnByb3RvdHlwZSA9IHsKKyAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCwgY2FsbGJhY2spIHsKKyAgICB0aGlzLmVsZW1lbnQgID0gJChlbGVtZW50KTsKKyAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7CisgICAgCisgICAgdGhpcy5sYXN0VmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7CisgICAgaWYgKHRoaXMuZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2Zvcm0nKQorICAgICAgdGhpcy5yZWdpc3RlckZvcm1DYWxsYmFja3MoKTsKKyAgICBlbHNlCisgICAgICB0aGlzLnJlZ2lzdGVyQ2FsbGJhY2sodGhpcy5lbGVtZW50KTsKKyAgfSwKKyAgCisgIG9uRWxlbWVudEV2ZW50OiBmdW5jdGlvbigpIHsKKyAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7CisgICAgaWYgKHRoaXMubGFzdFZhbHVlICE9IHZhbHVlKSB7CisgICAgICB0aGlzLmNhbGxiYWNrKHRoaXMuZWxlbWVudCwgdmFsdWUpOworICAgICAgdGhpcy5sYXN0VmFsdWUgPSB2YWx1ZTsKKyAgICB9CisgIH0sCisgIAorICByZWdpc3RlckZvcm1DYWxsYmFja3M6IGZ1bmN0aW9uKCkgeworICAgIHZhciBlbGVtZW50cyA9IEZvcm0uZ2V0RWxlbWVudHModGhpcy5lbGVtZW50KTsKKyAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKQorICAgICAgdGhpcy5yZWdpc3RlckNhbGxiYWNrKGVsZW1lbnRzW2ldKTsKKyAgfSwKKyAgCisgIHJlZ2lzdGVyQ2FsbGJhY2s6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKKyAgICBpZiAoZWxlbWVudC50eXBlKSB7CisgICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZS50b0xvd2VyQ2FzZSgpKSB7CisgICAgICAgIGNhc2UgJ2NoZWNrYm94JzogIAorICAgICAgICBjYXNlICdyYWRpbyc6CisgICAgICAgICAgZWxlbWVudC50YXJnZXQgPSB0aGlzOworICAgICAgICAgIGVsZW1lbnQucHJldl9vbmNsaWNrID0gZWxlbWVudC5vbmNsaWNrIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uOworICAgICAgICAgIGVsZW1lbnQub25jbGljayA9IGZ1bmN0aW9uKCkgeworICAgICAgICAgICAgdGhpcy5wcmV2X29uY2xpY2soKTsgCisgICAgICAgICAgICB0aGlzLnRhcmdldC5vbkVsZW1lbnRFdmVudCgpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAncGFzc3dvcmQnOgorICAgICAgICBjYXNlICd0ZXh0JzoKKyAgICAgICAgY2FzZSAndGV4dGFyZWEnOgorICAgICAgICBjYXNlICdzZWxlY3Qtb25lJzoKKyAgICAgICAgY2FzZSAnc2VsZWN0LW11bHRpcGxlJzoKKyAgICAgICAgICBlbGVtZW50LnRhcmdldCA9IHRoaXM7CisgICAgICAgICAgZWxlbWVudC5wcmV2X29uY2hhbmdlID0gZWxlbWVudC5vbmNoYW5nZSB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjsKKyAgICAgICAgICBlbGVtZW50Lm9uY2hhbmdlID0gZnVuY3Rpb24oKSB7CisgICAgICAgICAgICB0aGlzLnByZXZfb25jaGFuZ2UoKTsgCisgICAgICAgICAgICB0aGlzLnRhcmdldC5vbkVsZW1lbnRFdmVudCgpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9ICAgIAorICB9Cit9CisKK0Zvcm0uRWxlbWVudC5FdmVudE9ic2VydmVyID0gQ2xhc3MuY3JlYXRlKCk7CitGb3JtLkVsZW1lbnQuRXZlbnRPYnNlcnZlci5wcm90b3R5cGUgPSBPYmplY3QuZXh0ZW5kKG5ldyBBYnN0cmFjdC5FdmVudE9ic2VydmVyKCksIHsKKyAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkgeworICAgIHJldHVybiBGb3JtLkVsZW1lbnQuZ2V0VmFsdWUodGhpcy5lbGVtZW50KTsKKyAgfQorfSk7CisKK0Zvcm0uRXZlbnRPYnNlcnZlciA9IENsYXNzLmNyZWF0ZSgpOworRm9ybS5FdmVudE9ic2VydmVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0LkV2ZW50T2JzZXJ2ZXIoKSwgeworICBnZXRWYWx1ZTogZnVuY3Rpb24oKSB7CisgICAgcmV0dXJuIEZvcm0uc2VyaWFsaXplKHRoaXMuZWxlbWVudCk7CisgIH0KK30pOworCisKK2lmICghd2luZG93LkV2ZW50KSB7CisgIHZhciBFdmVudCA9IG5ldyBPYmplY3QoKTsKK30KKworT2JqZWN0LmV4dGVuZChFdmVudCwgeworICBLRVlfQkFDS1NQQUNFOiA4LAorICBLRVlfVEFCOiAgICAgICA5LAorICBLRVlfUkVUVVJOOiAgIDEzLAorICBLRVlfRVNDOiAgICAgIDI3LAorICBLRVlfTEVGVDogICAgIDM3LAorICBLRVlfVVA6ICAgICAgIDM4LAorICBLRVlfUklHSFQ6ICAgIDM5LAorICBLRVlfRE9XTjogICAgIDQwLAorICBLRVlfREVMRVRFOiAgIDQ2LAorCisgIGVsZW1lbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CisgICAgcmV0dXJuIGV2ZW50LnRhcmdldCB8fCBldmVudC5zcmNFbGVtZW50OworICB9LAorCisgIGlzTGVmdENsaWNrOiBmdW5jdGlvbihldmVudCkgeworICAgIHJldHVybiAoKChldmVudC53aGljaCkgJiYgKGV2ZW50LndoaWNoID09IDEpKSB8fAorICAgICAgICAgICAgKChldmVudC5idXR0b24pICYmIChldmVudC5idXR0b24gPT0gMSkpKTsKKyAgfSwKKworICBwb2ludGVyWDogZnVuY3Rpb24oZXZlbnQpIHsKKyAgICByZXR1cm4gZXZlbnQucGFnZVggfHwgKGV2ZW50LmNsaWVudFggKyAKKyAgICAgIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbExlZnQpKTsKKyAgfSwKKworICBwb2ludGVyWTogZnVuY3Rpb24oZXZlbnQpIHsKKyAgICByZXR1cm4gZXZlbnQucGFnZVkgfHwgKGV2ZW50LmNsaWVudFkgKyAKKyAgICAgIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wKSk7CisgIH0sCisKKyAgc3RvcDogZnVuY3Rpb24oZXZlbnQpIHsKKyAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHsgCisgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOyAKKyAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyAKKyAgICB9IGVsc2UgeworICAgICAgZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTsKKyAgICB9CisgIH0sCisKKyAgLy8gZmluZCB0aGUgZmlyc3Qgbm9kZSB3aXRoIHRoZSBnaXZlbiB0YWdOYW1lLCBzdGFydGluZyBmcm9tIHRoZQorICAvLyBub2RlIHRoZSBldmVudCB3YXMgdHJpZ2dlcmVkIG9uOyB0cmF2ZXJzZXMgdGhlIERPTSB1cHdhcmRzCisgIGZpbmRFbGVtZW50OiBmdW5jdGlvbihldmVudCwgdGFnTmFtZSkgeworICAgIHZhciBlbGVtZW50ID0gRXZlbnQuZWxlbWVudChldmVudCk7CisgICAgd2hpbGUgKGVsZW1lbnQucGFyZW50Tm9kZSAmJiAoIWVsZW1lbnQudGFnTmFtZSB8fAorICAgICAgICAoZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgIT0gdGFnTmFtZS50b1VwcGVyQ2FzZSgpKSkpCisgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlOworICAgIHJldHVybiBlbGVtZW50OworICB9LAorCisgIG9ic2VydmVyczogZmFsc2UsCisgIAorICBfb2JzZXJ2ZUFuZENhY2hlOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSkgeworICAgIGlmICghdGhpcy5vYnNlcnZlcnMpIHRoaXMub2JzZXJ2ZXJzID0gW107CisgICAgaWYgKGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikgeworICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChbZWxlbWVudCwgbmFtZSwgb2JzZXJ2ZXIsIHVzZUNhcHR1cmVdKTsKKyAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSk7CisgICAgfSBlbHNlIGlmIChlbGVtZW50LmF0dGFjaEV2ZW50KSB7CisgICAgICB0aGlzLm9ic2VydmVycy5wdXNoKFtlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZV0pOworICAgICAgZWxlbWVudC5hdHRhY2hFdmVudCgnb24nICsgbmFtZSwgb2JzZXJ2ZXIpOworICAgIH0KKyAgfSwKKyAgCisgIHVubG9hZENhY2hlOiBmdW5jdGlvbigpIHsKKyAgICBpZiAoIUV2ZW50Lm9ic2VydmVycykgcmV0dXJuOworICAgIGZvciAodmFyIGkgPSAwOyBpIDwgRXZlbnQub2JzZXJ2ZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICBFdmVudC5zdG9wT2JzZXJ2aW5nLmFwcGx5KHRoaXMsIEV2ZW50Lm9ic2VydmVyc1tpXSk7CisgICAgICBFdmVudC5vYnNlcnZlcnNbaV1bMF0gPSBudWxsOworICAgIH0KKyAgICBFdmVudC5vYnNlcnZlcnMgPSBmYWxzZTsKKyAgfSwKKworICBvYnNlcnZlOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSkgeworICAgIHZhciBlbGVtZW50ID0gJChlbGVtZW50KTsKKyAgICB1c2VDYXB0dXJlID0gdXNlQ2FwdHVyZSB8fCBmYWxzZTsKKyAgICAKKyAgICBpZiAobmFtZSA9PSAna2V5cHJlc3MnICYmCisgICAgICAgICgoL0tvbnF1ZXJvcnxTYWZhcml8S0hUTUwvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIAorICAgICAgICB8fCBlbGVtZW50LmF0dGFjaEV2ZW50KSkKKyAgICAgIG5hbWUgPSAna2V5ZG93bic7CisgICAgCisgICAgdGhpcy5fb2JzZXJ2ZUFuZENhY2hlKGVsZW1lbnQsIG5hbWUsIG9ic2VydmVyLCB1c2VDYXB0dXJlKTsKKyAgfSwKKworICBzdG9wT2JzZXJ2aW5nOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSkgeworICAgIHZhciBlbGVtZW50ID0gJChlbGVtZW50KTsKKyAgICB1c2VDYXB0dXJlID0gdXNlQ2FwdHVyZSB8fCBmYWxzZTsKKyAgICAKKyAgICBpZiAobmFtZSA9PSAna2V5cHJlc3MnICYmCisgICAgICAgICgoL0tvbnF1ZXJvcnxTYWZhcml8S0hUTUwvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIAorICAgICAgICB8fCBlbGVtZW50LmRldGFjaEV2ZW50KSkKKyAgICAgIG5hbWUgPSAna2V5ZG93bic7CisgICAgCisgICAgaWYgKGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgeworICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUsIG9ic2VydmVyLCB1c2VDYXB0dXJlKTsKKyAgICB9IGVsc2UgaWYgKGVsZW1lbnQuZGV0YWNoRXZlbnQpIHsKKyAgICAgIGVsZW1lbnQuZGV0YWNoRXZlbnQoJ29uJyArIG5hbWUsIG9ic2VydmVyKTsKKyAgICB9CisgIH0KK30pOworCisvKiBwcmV2ZW50IG1lbW9yeSBsZWFrcyBpbiBJRSAqLworRXZlbnQub2JzZXJ2ZSh3aW5kb3csICd1bmxvYWQnLCBFdmVudC51bmxvYWRDYWNoZSwgZmFsc2UpOworCit2YXIgUG9zaXRpb24gPSB7CisKKyAgLy8gc2V0IHRvIHRydWUgaWYgbmVlZGVkLCB3YXJuaW5nOiBmaXJlZm94IHBlcmZvcm1hbmNlIHByb2JsZW1zCisgIC8vIE5PVCBuZWVlZGVkIGZvciBwYWdlIHNjcm9sbGluZywgb25seSBpZiBkcmFnZ2FibGUgY29udGFpbmVkIGluCisgIC8vIHNjcm9sbGFibGUgZWxlbWVudHMKKyAgaW5jbHVkZVNjcm9sbE9mZnNldHM6IGZhbHNlLCAKKworICAvLyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyB3aXRoaW5JbmNsdWRpbmdTY3JvbGxvZmZzZXQsIGV2ZXJ5IHRpbWUgdGhlCisgIC8vIHBhZ2UgaXMgc2Nyb2xsZWQKKyAgcHJlcGFyZTogZnVuY3Rpb24oKSB7CisgICAgdGhpcy5kZWx0YVggPSAgd2luZG93LnBhZ2VYT2Zmc2V0IAorICAgICAgICAgICAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IAorICAgICAgICAgICAgICAgIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdCAKKyAgICAgICAgICAgICAgICB8fCAwOworICAgIHRoaXMuZGVsdGFZID0gIHdpbmRvdy5wYWdlWU9mZnNldCAKKyAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIAorICAgICAgICAgICAgICAgIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wIAorICAgICAgICAgICAgICAgIHx8IDA7CisgIH0sCisKKyAgcmVhbE9mZnNldDogZnVuY3Rpb24oZWxlbWVudCkgeworICAgIHZhciB2YWx1ZVQgPSAwLCB2YWx1ZUwgPSAwOworICAgIGRvIHsKKyAgICAgIHZhbHVlVCArPSBlbGVtZW50LnNjcm9sbFRvcCAgfHwgMDsKKyAgICAgIHZhbHVlTCArPSBlbGVtZW50LnNjcm9sbExlZnQgfHwgMDsgCisgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlOworICAgIH0gd2hpbGUgKGVsZW1lbnQpOworICAgIHJldHVybiBbdmFsdWVMLCB2YWx1ZVRdOworICB9LAorCisgIGN1bXVsYXRpdmVPZmZzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKKyAgICB2YXIgdmFsdWVUID0gMCwgdmFsdWVMID0gMDsKKyAgICBkbyB7CisgICAgICB2YWx1ZVQgKz0gZWxlbWVudC5vZmZzZXRUb3AgIHx8IDA7CisgICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7CisgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7CisgICAgfSB3aGlsZSAoZWxlbWVudCk7CisgICAgcmV0dXJuIFt2YWx1ZUwsIHZhbHVlVF07CisgIH0sCisKKyAgLy8gY2FjaGVzIHgveSBjb29yZGluYXRlIHBhaXIgdG8gdXNlIHdpdGggb3ZlcmxhcAorICB3aXRoaW46IGZ1bmN0aW9uKGVsZW1lbnQsIHgsIHkpIHsKKyAgICBpZiAodGhpcy5pbmNsdWRlU2Nyb2xsT2Zmc2V0cykKKyAgICAgIHJldHVybiB0aGlzLndpdGhpbkluY2x1ZGluZ1Njcm9sbG9mZnNldHMoZWxlbWVudCwgeCwgeSk7CisgICAgdGhpcy54Y29tcCA9IHg7CisgICAgdGhpcy55Y29tcCA9IHk7CisgICAgdGhpcy5vZmZzZXQgPSB0aGlzLmN1bXVsYXRpdmVPZmZzZXQoZWxlbWVudCk7CisKKyAgICByZXR1cm4gKHkgPj0gdGhpcy5vZmZzZXRbMV0gJiYKKyAgICAgICAgICAgIHkgPCAgdGhpcy5vZmZzZXRbMV0gKyBlbGVtZW50Lm9mZnNldEhlaWdodCAmJgorICAgICAgICAgICAgeCA+PSB0aGlzLm9mZnNldFswXSAmJiAKKyAgICAgICAgICAgIHggPCAgdGhpcy5vZmZzZXRbMF0gKyBlbGVtZW50Lm9mZnNldFdpZHRoKTsKKyAgfSwKKworICB3aXRoaW5JbmNsdWRpbmdTY3JvbGxvZmZzZXRzOiBmdW5jdGlvbihlbGVtZW50LCB4LCB5KSB7CisgICAgdmFyIG9mZnNldGNhY2hlID0gdGhpcy5yZWFsT2Zmc2V0KGVsZW1lbnQpOworCisgICAgdGhpcy54Y29tcCA9IHggKyBvZmZzZXRjYWNoZVswXSAtIHRoaXMuZGVsdGFYOworICAgIHRoaXMueWNvbXAgPSB5ICsgb2Zmc2V0Y2FjaGVbMV0gLSB0aGlzLmRlbHRhWTsKKyAgICB0aGlzLm9mZnNldCA9IHRoaXMuY3VtdWxhdGl2ZU9mZnNldChlbGVtZW50KTsKKworICAgIHJldHVybiAodGhpcy55Y29tcCA+PSB0aGlzLm9mZnNldFsxXSAmJgorICAgICAgICAgICAgdGhpcy55Y29tcCA8ICB0aGlzLm9mZnNldFsxXSArIGVsZW1lbnQub2Zmc2V0SGVpZ2h0ICYmCisgICAgICAgICAgICB0aGlzLnhjb21wID49IHRoaXMub2Zmc2V0WzBdICYmIAorICAgICAgICAgICAgdGhpcy54Y29tcCA8ICB0aGlzLm9mZnNldFswXSArIGVsZW1lbnQub2Zmc2V0V2lkdGgpOworICB9LAorCisgIC8vIHdpdGhpbiBtdXN0IGJlIGNhbGxlZCBkaXJlY3RseSBiZWZvcmUKKyAgb3ZlcmxhcDogZnVuY3Rpb24obW9kZSwgZWxlbWVudCkgeyAgCisgICAgaWYgKCFtb2RlKSByZXR1cm4gMDsgIAorICAgIGlmIChtb2RlID09ICd2ZXJ0aWNhbCcpIAorICAgICAgcmV0dXJuICgodGhpcy5vZmZzZXRbMV0gKyBlbGVtZW50Lm9mZnNldEhlaWdodCkgLSB0aGlzLnljb21wKSAvIAorICAgICAgICBlbGVtZW50Lm9mZnNldEhlaWdodDsKKyAgICBpZiAobW9kZSA9PSAnaG9yaXpvbnRhbCcpCisgICAgICByZXR1cm4gKCh0aGlzLm9mZnNldFswXSArIGVsZW1lbnQub2Zmc2V0V2lkdGgpIC0gdGhpcy54Y29tcCkgLyAKKyAgICAgICAgZWxlbWVudC5vZmZzZXRXaWR0aDsKKyAgfSwKKworICBjbG9uZTogZnVuY3Rpb24oc291cmNlLCB0YXJnZXQpIHsKKyAgICBzb3VyY2UgPSAkKHNvdXJjZSk7CisgICAgdGFyZ2V0ID0gJCh0YXJnZXQpOworICAgIHRhcmdldC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7CisgICAgdmFyIG9mZnNldHMgPSB0aGlzLmN1bXVsYXRpdmVPZmZzZXQoc291cmNlKTsKKyAgICB0YXJnZXQuc3R5bGUudG9wICAgID0gb2Zmc2V0c1sxXSArICdweCc7CisgICAgdGFyZ2V0LnN0eWxlLmxlZnQgICA9IG9mZnNldHNbMF0gKyAncHgnOworICAgIHRhcmdldC5zdHlsZS53aWR0aCAgPSBzb3VyY2Uub2Zmc2V0V2lkdGggKyAncHgnOworICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBzb3VyY2Uub2Zmc2V0SGVpZ2h0ICsgJ3B4JzsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvZG9jcy9za2luL3NjcmVlbi5jc3MgYi9kb2NzL3NraW4vc2NyZWVuLmNzcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjA4NGY4Ci0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9za2luL3NjcmVlbi5jc3MKQEAgLTAsMCArMSw1ODcgQEAKKy8qCisqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyogdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorKiB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorKgorKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisqCisqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworYm9keSB7ICBtYXJnaW46IDBweCAwcHggMHB4IDBweDsgZm9udC1mYW1pbHk6IFZlcmRhbmEsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsgfQorCitoMSAgICAgeyBmb250LXNpemUgOiAxNjAlOyBtYXJnaW46IDBweCAwcHggMHB4IDBweDsgIHBhZGRpbmc6IDBweDsgfQoraDIgICAgIHsgZm9udC1zaXplIDogMTQwJTsgbWFyZ2luOiAxZW0gMHB4IDAuOGVtIDBweDsgcGFkZGluZzogMHB4OyBmb250LXdlaWdodCA6IGJvbGQ7fQoraDMgICAgIHsgZm9udC1zaXplIDogMTMwJTsgbWFyZ2luOiAwLjhlbSAwcHggMHB4IDBweDsgcGFkZGluZzogMHB4OyBmb250LXdlaWdodCA6IGJvbGQ7IH0KKy5oMyB7IG1hcmdpbjogMjJweCAwcHggM3B4IDBweDsgfQoraDQgICAgIHsgZm9udC1zaXplIDogMTIwJTsgbWFyZ2luOiAwLjdlbSAwcHggMHB4IDBweDsgcGFkZGluZzogMHB4OyBmb250LXdlaWdodCA6IG5vcm1hbDsgdGV4dC1hbGlnbjogbGVmdDsgfQorLmg0IHsgbWFyZ2luOiAxOHB4IDBweCAwcHggMHB4OyB9CitoNC5mYXEgeyBmb250LXNpemUgOiAxMjAlOyBtYXJnaW46IDE4cHggMHB4IDBweCAwcHg7IHBhZGRpbmc6IDBweDsgZm9udC13ZWlnaHQgOiBib2xkOyAgIHRleHQtYWxpZ246IGxlZnQ7IH0KK2g1ICAgICB7IGZvbnQtc2l6ZSA6IDEwMCU7IG1hcmdpbjogMTRweCAwcHggMHB4IDBweDsgcGFkZGluZzogMHB4OyBmb250LXdlaWdodCA6IG5vcm1hbDsgdGV4dC1hbGlnbjogbGVmdDsgfQorCisvKioKKyogdGFibGUKKyovCit0YWJsZSAudGl0bGUgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwOyB9CisuRm9ycmVzdFRhYmxlICAgICAgICAgeworICAgIGNvbG9yOiAjZmZmZmZmOworICAgIGJhY2tncm91bmQtY29sb3I6ICM3MDk5QzU7CisgICAgd2lkdGg6IDEwMCU7CisgICAgZm9udC1zaXplIDogMTAwJTsKKyAgICBlbXB0eS1jZWxsczogc2hvdzsKK30KK3RhYmxlIGNhcHRpb24geworICAgIHBhZGRpbmctbGVmdDogNXB4OworICAgIGNvbG9yOiB3aGl0ZTsKKyAgICB0ZXh0LWFsaWduOiBsZWZ0OworICAgIGZvbnQtd2VpZ2h0OiBib2xkOworICAgIGJhY2tncm91bmQtY29sb3I6ICMwMDAwMDA7Cit9CisuRm9ycmVzdFRhYmxlIHRkIHsKKyAgICBjb2xvcjogYmxhY2s7CisgICAgYmFja2dyb3VuZC1jb2xvcjogI2YwZjBmZjsKK30KKy5Gb3JyZXN0VGFibGUgdGggeyB0ZXh0LWFsaWduOiBjZW50ZXI7IH0KKy8qKgorICogUGFnZSBIZWFkZXIKKyAqLworCisjdG9wIHsKKyAgICBwb3NpdGlvbjogcmVsYXRpdmU7CisgICAgZmxvYXQ6IGxlZnQ7CisgICAgd2lkdGg6IDEwMCU7CisgICAgYmFja2dyb3VuZDogIzI5NDU2MzsgLyogaWYgeW91IHdhbnQgYSBiYWNrZ3JvdW5kIGluIHRoZSBoZWFkZXIsIHB1dCBpdCBoZXJlICovCit9CisKKyN0b3AgLmJyZWFkdHJhaWwgeworICAgIGJhY2tncm91bmQ6ICNDRkRDRUQ7CisgICAgY29sb3I6IGJsYWNrOworICAgIGJvcmRlci1ib3R0b206IHNvbGlkIDFweCB3aGl0ZTsKKyAgICBwYWRkaW5nOiAzcHggMTBweDsKKyAgICBmb250LXNpemU6IDc1JTsKK30KKyN0b3AgLmJyZWFkdHJhaWwgYSB7IGNvbG9yOiBibGFjazsgfQorCisjdG9wIC5oZWFkZXIgeworICAgIGZsb2F0OiBsZWZ0OworICAgIHdpZHRoOiAxMDAlOworICAgIGJhY2tncm91bmQ6IHVybCgiaW1hZ2VzL2hlYWRlcl93aGl0ZV9saW5lLmdpZiIpIHJlcGVhdC14IGJvdHRvbTsKK30KKworI3RvcCAuZ3JvdXBsb2dvIHsKKyAgICBwYWRkaW5nOiA3cHggMCAxMHB4IDEwcHg7CisgICAgZmxvYXQ6IGxlZnQ7CisgICAgdGV4dC1hbGlnbjogbGVmdDsKK30KKyN0b3AgLnByb2plY3Rsb2dvIHsKKyAgICBwYWRkaW5nOiA3cHggMCAxMHB4IDEwcHg7CisgICAgZmxvYXQ6IGxlZnQ7CisgICAgd2lkdGg6IDMzJTsKKyAgICB0ZXh0LWFsaWduOiByaWdodDsKK30KKyN0b3AgLnByb2plY3Rsb2dvQTEgeworICAgIHBhZGRpbmc6IDdweCAwIDEwcHggMTBweDsKKyAgICBmbG9hdDogcmlnaHQ7Cit9CitodG1sPmJvZHkgI3RvcCAuc2VhcmNoYm94IHsKKyAgICBib3R0b206IDBweDsKK30KKyN0b3AgLnNlYXJjaGJveCB7CisgICAgcG9zaXRpb246IGFic29sdXRlOworICAgIHJpZ2h0OiAxMHB4OworICAgIGhlaWdodDogNDJweDsKKyAgICBmb250LXNpemU6IDcwJTsKKyAgICB3aGl0ZS1zcGFjZTogbm93cmFwOworICAgIHRleHQtYWxpZ246IHJpZ2h0OworICAgIGNvbG9yOiB3aGl0ZTsKKyAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwOworICAgIHotaW5kZXg6MDsKKyAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoaW1hZ2VzL3JjLXQtbC01LTFoZWFkZXItMnNlYXJjaGJveC0zc2VhcmNoYm94LnBuZyk7CisgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKyAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiB0b3AgbGVmdDsKKyAgICBib3R0b206IC0xcHg7IC8qIGNvbXBlbnNhdGUgZm9yIElFIHJlbmRlcmluZyBpc3N1ZSAqLworfQorCisjdG9wIC5zZWFyY2hib3ggZm9ybSB7CisgICAgcGFkZGluZzogNXB4IDEwcHg7CisgICAgbWFyZ2luOiAwOworfQorI3RvcCAuc2VhcmNoYm94IHAgeworICAgIHBhZGRpbmc6IDAgMCAycHggMDsKKyAgICBtYXJnaW46IDA7Cit9CisjdG9wIC5zZWFyY2hib3ggaW5wdXQgeworICAgIGZvbnQtc2l6ZTogMTAwJTsKK30KKworI3RhYnMgeworICAgIGNsZWFyOiBib3RoOworICAgIHBhZGRpbmctbGVmdDogMTBweDsKKyAgICBtYXJnaW46IDA7CisgICAgbGlzdC1zdHlsZTogbm9uZTsKK30KKy8qICAgIGJhY2tncm91bmQ6ICNDRkRDRUQgdXJsKCJpbWFnZXMvdGFiLXJpZ2h0LmdpZiIpIG5vLXJlcGVhdCByaWdodCB0b3A7Ki8KKyN0YWJzIGxpIHsKKyAgICBmbG9hdDogbGVmdDsKKyAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoaW1hZ2VzL3JjLXQtci01LTFoZWFkZXItMnRhYi11bnNlbGVjdGVkLTN0YWItdW5zZWxlY3RlZC5wbmcpOworICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogdG9wIHJpZ2h0OworICAgIGJhY2tncm91bmQtY29sb3I6ICMwMDAwMDA7CisgICAgbWFyZ2luOiAwIDNweCAwIDA7CisgICAgcGFkZGluZzogMDsKK30KKworLypiYWNrZ3JvdW5kOiB1cmwoImltYWdlcy90YWItbGVmdC5naWYiKSBuby1yZXBlYXQgbGVmdCB0b3A7Ki8KKyN0YWJzIGxpIGEgeworICAgIGZsb2F0OiBsZWZ0OworICAgIGRpc3BsYXk6IGJsb2NrOworICAgIGZvbnQtZmFtaWx5OiB2ZXJkYW5hLCBhcmlhbCwgc2Fucy1zZXJpZjsKKyAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7CisgICAgY29sb3I6IGJsYWNrOworICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7CisgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKGltYWdlcy9yYy10LWwtNS0xaGVhZGVyLTJ0YWItdW5zZWxlY3RlZC0zdGFiLXVuc2VsZWN0ZWQucG5nKTsKKyAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0OworICAgIGJhY2tncm91bmQtcG9zaXRpb246IHRvcCBsZWZ0OworICAgIHBhZGRpbmc6IDVweCAxNXB4IDRweDsKKyAgICB3aWR0aDogLjFlbTsgLyogSUUvV2luIGZpeCAqLworfQorCisjdGFicyBsaSBhOmhvdmVyIHsKKyAgIAorICAgIGN1cnNvcjogcG9pbnRlcjsKKyAgICB0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lOworfQorCisjdGFicyA+IGxpIGEgeyB3aWR0aDogYXV0bzsgfSAvKiBSZXN0IG9mIElFL1dpbiBmaXggKi8KKworLyogQ29tbWVudGVkIEJhY2tzbGFzaCBIYWNrIGhpZGVzIHJ1bGUgZnJvbSBJRTUtTWFjIFwqLworI3RhYnMgYSB7IGZsb2F0OiBub25lOyB9CisvKiBFbmQgSUU1LU1hYyBoYWNrICovCisKKyN0b3AgLmhlYWRlciAuY3VycmVudCB7CisgICAgYmFja2dyb3VuZC1jb2xvcjogIzRDNkM4RjsKKyAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoaW1hZ2VzL3JjLXQtci01LTFoZWFkZXItMnRhYi1zZWxlY3RlZC0zdGFiLXNlbGVjdGVkLnBuZyk7CisgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKyAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiB0b3AgcmlnaHQ7Cit9CisjdG9wIC5oZWFkZXIgLmN1cnJlbnQgYSB7CisgICAgZm9udC13ZWlnaHQ6IGJvbGQ7CisgICAgcGFkZGluZy1ib3R0b206IDVweDsKKyAgICBjb2xvcjogd2hpdGU7CisgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKGltYWdlcy9yYy10LWwtNS0xaGVhZGVyLTJ0YWItc2VsZWN0ZWQtM3RhYi1zZWxlY3RlZC5wbmcpOworICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogdG9wIGxlZnQ7Cit9CisjcHVibGlzaGVkU3RyaXAgeworICAgIHBhZGRpbmctcmlnaHQ6IDEwcHg7CisgICAgcGFkZGluZy1sZWZ0OiAyMHB4OworICAgIHBhZGRpbmctdG9wOiAzcHg7CisgICAgcGFkZGluZy1ib3R0b206M3B4OworICAgIGNvbG9yOiAjZmZmZmZmOworICAgIGZvbnQtc2l6ZSA6IDYwJTsKKyAgICBmb250LXdlaWdodDogYm9sZDsKKyAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNEM2QzhGOworICAgIHRleHQtYWxpZ246cmlnaHQ7Cit9CisKKyNsZXZlbDJ0YWJzIHsKK21hcmdpbjogMDsKK2Zsb2F0OmxlZnQ7Citwb3NpdGlvbjpyZWxhdGl2ZTsKKworfQorCisKKworI2xldmVsMnRhYnMgIGE6aG92ZXIgeworICAgCisgICAgY3Vyc29yOiBwb2ludGVyOworICAgIHRleHQtZGVjb3JhdGlvbjp1bmRlcmxpbmU7CisgICAgCit9CisKKyNsZXZlbDJ0YWJzICBheworICAgCisgICAgY3Vyc29yOiBwb2ludGVyOworICAgIHRleHQtZGVjb3JhdGlvbjpub25lOworICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgnaW1hZ2VzL2NoYXB0ZXIuZ2lmJyk7CisgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKyAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXIgbGVmdDsKKyAgICBwYWRkaW5nLWxlZnQ6IDZweDsKKyAgICBtYXJnaW4tbGVmdDogNnB4OworfQorCisvKgorKiAgICBib3JkZXItdG9wOiBzb2xpZCAjNEM2QzhGIDE1cHg7CisqLworI21haW4geworICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKKyAgICBiYWNrZ3JvdW5kOiB3aGl0ZTsKKyAgICBjbGVhcjpib3RoOworfQorI21haW4gLmJyZWFkdHJhaWwgeworICAgIGNsZWFyOmJvdGg7CisgICAgcG9zaXRpb246IHJlbGF0aXZlOworICAgIGJhY2tncm91bmQ6ICNDRkRDRUQ7CisgICAgY29sb3I6IGJsYWNrOworICAgIGJvcmRlci1ib3R0b206IHNvbGlkIDFweCBibGFjazsKKyAgICBib3JkZXItdG9wOiBzb2xpZCAxcHggYmxhY2s7CisgICAgcGFkZGluZzogMHB4IDE4MHB4OworICAgIGZvbnQtc2l6ZTogNzUlOworICAgIHotaW5kZXg6MTA7Cit9CisvKioKKyogUm91bmQgY29ybmVyCisqLworI3JvdW5kdG9wIHsKKyAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoaW1hZ2VzL3JjLXQtci0xNS0xYm9keS0ybWVudS0zbWVudS5wbmcpOworICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogdG9wIHJpZ2h0OworfQorCisjcm91bmRib3R0b20geworICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybChpbWFnZXMvcmMtYi1yLTE1LTFib2R5LTJtZW51LTNtZW51LnBuZyk7CisgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKyAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiB0b3AgcmlnaHQ7Cit9CisKK2ltZy5jb3JuZXIgeworICAgd2lkdGg6IDE1cHg7CisgICBoZWlnaHQ6IDE1cHg7CisgICBib3JkZXI6IG5vbmU7CisgICBkaXNwbGF5OiBibG9jayAhaW1wb3J0YW50OworfQorCisucm91bmR0b3BzbWFsbCB7CisgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKGltYWdlcy9yYy10LXItNS0xaGVhZGVyLTJzZWFyY2hib3gtM3NlYXJjaGJveC5wbmcpOworICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogdG9wIHJpZ2h0OworfQorCisjcm91bmRib3R0b21zbWFsbCB7CisgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKGltYWdlcy9yYy1iLXItNS0xaGVhZGVyLTJ0YWItc2VsZWN0ZWQtM3RhYi1zZWxlY3RlZC5wbmcpOworICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogdG9wIHJpZ2h0OworfQorCitpbWcuY29ybmVyc21hbGwgeworICAgd2lkdGg6IDVweDsKKyAgIGhlaWdodDogNXB4OworICAgYm9yZGVyOiBub25lOworICAgZGlzcGxheTogYmxvY2sgIWltcG9ydGFudDsKK30KKy8qKgorICogU2lkZSBtZW51CisgKi8KKyNtZW51IGEgeyAgZm9udC13ZWlnaHQ6IG5vcm1hbDsgdGV4dC1kZWNvcmF0aW9uOiBub25lO30KKyNtZW51IGE6dmlzaXRlZCB7ICBmb250LXdlaWdodDogbm9ybWFsOyB9CisjbWVudSBhOmFjdGl2ZSB7ICBmb250LXdlaWdodDogbm9ybWFsOyB9CisjbWVudSBhOmhvdmVyIHsgIGZvbnQtd2VpZ2h0OiBub3JtYWw7ICB0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30KKworI21lbnVhcmVhIHsgd2lkdGg6MTBlbTt9CisjbWVudSB7CisgICAgcG9zaXRpb246IHJlbGF0aXZlOworICAgIGZsb2F0OiBsZWZ0OworICAgIHdpZHRoOiAxNjBweDsKKyAgICBwYWRkaW5nLXRvcDogMHB4OworICAgIHRvcDotMThweDsKKyAgICBsZWZ0OjEwcHg7CisgICAgei1pbmRleDogMjA7CisgICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5MDsKKyAgICBmb250LXNpemUgOiA3MCU7CisgICAgCit9CisKKy5tZW51dGl0bGUgeworICAgICAgICBjdXJzb3I6cG9pbnRlcjsKKyAgICAgICAgcGFkZGluZzogM3B4IDEycHg7CisgICAgICAgIG1hcmdpbi1sZWZ0OiAxMHB4OworICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJ2ltYWdlcy9jaGFwdGVyLmdpZicpOworICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0OworICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXIgbGVmdDsKKyAgICAgICAgZm9udC13ZWlnaHQgOiBib2xkOworCisgICAgICAgIAorfQorCisubWVudXRpdGxlOmhvdmVye3RleHQtZGVjb3JhdGlvbjp1bmRlcmxpbmU7Y3Vyc29yOiBwb2ludGVyO30KKworI21lbnUgLm1lbnVpdGVtZ3JvdXAgeworICAgICAgICBtYXJnaW46IDBweCAwcHggNnB4IDhweDsKKyAgICAgICAgcGFkZGluZzogMHB4OworICAgICAgICBmb250LXdlaWdodCA6IGJvbGQ7IH0KKworI21lbnUgLnNlbGVjdGVkbWVudWl0ZW1ncm91cHsKKyAgICAgICAgbWFyZ2luOiAwcHggMHB4IDBweCA4cHg7CisgICAgICAgIHBhZGRpbmc6IDBweDsKKyAgICAgICAgZm9udC13ZWlnaHQgOiBub3JtYWw7IAorICAgICAgIAorICAgICAgICB9CisKKyNtZW51IC5tZW51aXRlbSB7CisgICAgICAgIHBhZGRpbmc6IDJweCAwcHggMXB4IDEzcHg7CisgICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgnaW1hZ2VzL3BhZ2UuZ2lmJyk7CisgICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7CisgICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciBsZWZ0OworICAgICAgICBmb250LXdlaWdodCA6IG5vcm1hbDsKKyAgICAgICAgbWFyZ2luLWxlZnQ6IDEwcHg7Cit9CisKKyNtZW51IC5tZW51cGFnZSB7CisgICAgICAgIG1hcmdpbjogMnB4IDBweCAxcHggMTBweDsKKyAgICAgICAgcGFkZGluZzogMHB4IDNweCAwcHggMTJweDsKKyAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCdpbWFnZXMvcGFnZS5naWYnKTsKKyAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsKKyAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyIGxlZnQ7CisgICAgICAgIGZvbnQtc3R5bGUgOiBub3JtYWw7Cit9CisjbWVudSAubWVudXBhZ2V0aXRsZSB7CisgICAgICAgIHBhZGRpbmc6IDBweCAwcHggMHB4IDFweDsKKyAgICAgICAgZm9udC1zdHlsZSA6IG5vcm1hbDsKKyAgICAgICAgYm9yZGVyLXN0eWxlOiBzb2xpZDsKKyAgICAgICAgYm9yZGVyLXdpZHRoOiAxcHg7CisgICAgICAgIG1hcmdpbi1yaWdodDogMTBweDsKKyAgICAgICAgIAorfQorI21lbnUgLm1lbnVwYWdlaXRlbWdyb3VwIHsKKyAgICAgICAgcGFkZGluZzogM3B4IDBweCA0cHggNnB4OworICAgICAgICBmb250LXN0eWxlIDogbm9ybWFsOworICAgICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgOworICAgICAgICBib3JkZXItbGVmdDogMXB4IHNvbGlkIDsKKyAgICAgICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgOworICAgICAgICBtYXJnaW4tcmlnaHQ6IDEwcHg7Cit9CisjbWVudSAubWVudXBhZ2VpdGVtIHsKKyAgICAgICAgZm9udC1zdHlsZSA6IG5vcm1hbDsKKyAgICAgICAgZm9udC13ZWlnaHQgOiBub3JtYWw7CisgICAgICAgIGJvcmRlci13aWR0aDogMHB4OworICAgICAgICBmb250LXNpemUgOiA5MCU7Cit9CisjbWVudSAjY3JlZGl0IHsKKyAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cit9CisjbWVudSAjY3JlZGl0MiB7CisgICAgdGV4dC1hbGlnbjogY2VudGVyOworICAgIHBhZGRpbmc6IDNweCAzcHggM3B4IDNweDsKKyAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmOworfQorI21lbnUgLnNlYXJjaGJveCB7CisgICAgdGV4dC1hbGlnbjogY2VudGVyOworfQorI21lbnUgLnNlYXJjaGJveCBmb3JtIHsKKyAgICBwYWRkaW5nOiAzcHggM3B4OworICAgIG1hcmdpbjogMDsKK30KKyNtZW51IC5zZWFyY2hib3ggaW5wdXQgeworICAgIGZvbnQtc2l6ZTogMTAwJTsKK30KKworI2NvbnRlbnQgeworICAgIHBhZGRpbmc6IDIwcHggMjBweCAyMHB4IDE4MHB4OworICAgIG1hcmdpbjogMDsKKyAgICBmb250IDogc21hbGwgVmVyZGFuYSwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmOworICAgIGZvbnQtc2l6ZSA6IDgwJTsKK30KKworI2NvbnRlbnQgdWwgeworICAgIG1hcmdpbjogMDsKKyAgICBwYWRkaW5nOiAwIDI1cHg7Cit9CisjY29udGVudCBsaSB7CisgICAgcGFkZGluZzogMCA1cHg7Cit9CisjZmVlZGJhY2sgeworICAgIGNvbG9yOiBibGFjazsKKyAgICBiYWNrZ3JvdW5kOiAjQ0ZEQ0VEOworICAgIHRleHQtYWxpZ246Y2VudGVyOworICAgIG1hcmdpbi10b3A6IDVweDsKK30KKyNmZWVkYmFjayAjZmVlZGJhY2t0byB7CisgICAgZm9udC1zaXplOiA5MCU7CisgICAgY29sb3I6IGJsYWNrOworfQorI2Zvb3RlciB7CisgICAgY2xlYXI6IGJvdGg7CisgICAgcG9zaXRpb246IHJlbGF0aXZlOyAvKiBJRSBidWdmaXggKGh0dHA6Ly93d3cuZHJhY29zLmNvLnVrL3dlYi9jc3MvaWU2ZmxvYXRidWcvKSAqLworICAgIHdpZHRoOiAxMDAlOworICAgIGJhY2tncm91bmQ6ICNDRkRDRUQ7CisgICAgYm9yZGVyLXRvcDogc29saWQgMXB4ICM0QzZDOEY7CisgICAgY29sb3I6IGJsYWNrOworfQorI2Zvb3RlciAuY29weXJpZ2h0IHsKKyAgICBwb3NpdGlvbjogcmVsYXRpdmU7IC8qIElFIGJ1Z2ZpeCBjb250J2QgKi8KKyAgICBwYWRkaW5nOiA1cHg7CisgICAgbWFyZ2luOiAwOworICAgIHdpZHRoOiA0NSU7Cit9CisjZm9vdGVyIC5sYXN0bW9kaWZpZWQgeworICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsgLyogSUUgYnVnZml4IGNvbnQnZCAqLworICAgIGZsb2F0OiByaWdodDsKKyAgICB3aWR0aDogNDUlOworICAgIHBhZGRpbmc6IDVweDsKKyAgICBtYXJnaW46IDA7CisgICAgdGV4dC1hbGlnbjogcmlnaHQ7Cit9CisjZm9vdGVyIGEgeyBjb2xvcjogd2hpdGU7IH0KKworI2Zvb3RlciAjbG9nb3MgeworICAgIHRleHQtYWxpZ246IGxlZnQ7Cit9CisKKworLyoqCisgKiBNaXNjIFN0eWxlcworICovCisKK2Fjcm9ueW0geyBjdXJzb3I6IGhlbHA7IH0KKy5ib3hlZCAgICAgIHsgYmFja2dyb3VuZC1jb2xvcjogI2E1YjZjNjt9CisudW5kZXJsaW5lZF81ICAgICB7Ym9yZGVyLWJvdHRvbTogc29saWQgNXB4ICM0QzZDOEY7fQorLnVuZGVybGluZWRfMTAgICAgIHtib3JkZXItYm90dG9tOiBzb2xpZCAxMHB4ICM0QzZDOEY7fQorLyogPT09PT09PT09PT09PT09PT09PT0gc25haWwgdHJhaWwgPT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworCisudHJhaWwgeworICBwb3NpdGlvbjogcmVsYXRpdmU7IC8qIElFIGJ1Z2ZpeCBjb250J2QgKi8KKyAgZm9udC1zaXplOiA3MCU7CisgIHRleHQtYWxpZ246IHJpZ2h0OworICBmbG9hdDogcmlnaHQ7CisgIG1hcmdpbjogLTEwcHggNXB4IDBweCA1cHg7CisgIHBhZGRpbmc6IDA7Cit9CisKKyNtb3RkLWFyZWEgeworICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsgLyogSUUgYnVnZml4IGNvbnQnZCAqLworICAgIGZsb2F0OiByaWdodDsKKyAgICB3aWR0aDogMzUlOworICAgIGJhY2tncm91bmQtY29sb3I6ICNmMGYwZmY7CisgICAgYm9yZGVyLXRvcDogc29saWQgMXB4ICM0QzZDOEY7CisgICAgYm9yZGVyLWJvdHRvbTogc29saWQgMXB4ICM0QzZDOEY7CisgICAgbWFyZ2luLWJvdHRvbTogMTVweDsKKyAgICBtYXJnaW4tbGVmdDogMTVweDsKKyAgICBtYXJnaW4tcmlnaHQ6IDEwJTsKKyAgICBwYWRkaW5nLWJvdHRvbTogNXB4OworICAgIHBhZGRpbmctdG9wOiA1cHg7Cit9CisKKyNtaW5pdG9jLWFyZWEgeworICAgIGJvcmRlci10b3A6IHNvbGlkIDFweCAjNEM2QzhGOworICAgIGJvcmRlci1ib3R0b206IHNvbGlkIDFweCAjNEM2QzhGOworICAgIG1hcmdpbjogMTVweCAxMCUgNXB4IDE1cHg7CisgICAvKiBtYXJnaW4tYm90dG9tOiAxNXB4OworICAgIG1hcmdpbi1sZWZ0OiAxNXB4OworICAgIG1hcmdpbi1yaWdodDogMTAlOyovCisgICAgcGFkZGluZy1ib3R0b206IDdweDsKKyAgICBwYWRkaW5nLXRvcDogNXB4OworfQorLm1pbml0b2MgeworICAgIGxpc3Qtc3R5bGUtaW1hZ2U6IHVybCgnaW1hZ2VzL2N1cnJlbnQuZ2lmJyk7CisgICAgZm9udC13ZWlnaHQ6IG5vcm1hbDsKK30KKworbGkgcCB7CisgICAgbWFyZ2luOiAwOworICAgIHBhZGRpbmc6IDA7Cit9CisKKy5wZGZsaW5rIHsKKyAgICBwb3NpdGlvbjogcmVsYXRpdmU7IC8qIElFIGJ1Z2ZpeCBjb250J2QgKi8KKyAgICBmbG9hdDogcmlnaHQ7CisgICAgbWFyZ2luOiAwcHggNXB4OworICAgIHBhZGRpbmc6IDA7Cit9CisucGRmbGluayBiciB7CisgICAgbWFyZ2luLXRvcDogLTEwcHg7CisgICAgcGFkZGluZy1sZWZ0OiAxcHg7Cit9CisucGRmbGluayBhIHsKKyAgICBkaXNwbGF5OiBibG9jazsKKyAgICBmb250LXNpemU6IDcwJTsKKyAgICB0ZXh0LWFsaWduOiBjZW50ZXI7CisgICAgbWFyZ2luOiAwOworICAgIHBhZGRpbmc6IDA7Cit9CisKKy5wZGZsaW5rIGltZyB7CisgICAgZGlzcGxheTogYmxvY2s7CisgICAgaGVpZ2h0OiAxNnB4OworICAgIHdpZHRoOiAxNnB4OworfQorLnhtbGxpbmsgeworICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsgLyogSUUgYnVnZml4IGNvbnQnZCAqLworICAgIGZsb2F0OiByaWdodDsKKyAgICBtYXJnaW46IDBweCA1cHg7CisgICAgcGFkZGluZzogMDsKK30KKy54bWxsaW5rIGJyIHsKKyAgICBtYXJnaW4tdG9wOiAtMTBweDsKKyAgICBwYWRkaW5nLWxlZnQ6IDFweDsKK30KKy54bWxsaW5rIGEgeworICAgIGRpc3BsYXk6IGJsb2NrOworICAgIGZvbnQtc2l6ZTogNzAlOworICAgIHRleHQtYWxpZ246IGNlbnRlcjsKKyAgICBtYXJnaW46IDA7CisgICAgcGFkZGluZzogMDsKK30KKworLnhtbGxpbmsgaW1nIHsKKyAgICBkaXNwbGF5OiBibG9jazsKKyAgICBoZWlnaHQ6IDE2cHg7CisgICAgd2lkdGg6IDE2cHg7Cit9CisucG9kbGluayB7CisgICAgcG9zaXRpb246IHJlbGF0aXZlOyAvKiBJRSBidWdmaXggY29udCdkICovCisgICAgZmxvYXQ6IHJpZ2h0OworICAgIG1hcmdpbjogMHB4IDVweDsKKyAgICBwYWRkaW5nOiAwOworfQorLnBvZGxpbmsgYnIgeworICAgIG1hcmdpbi10b3A6IC0xMHB4OworICAgIHBhZGRpbmctbGVmdDogMXB4OworfQorLnBvZGxpbmsgYSB7CisgICAgZGlzcGxheTogYmxvY2s7CisgICAgZm9udC1zaXplOiA3MCU7CisgICAgdGV4dC1hbGlnbjogY2VudGVyOworICAgIG1hcmdpbjogMDsKKyAgICBwYWRkaW5nOiAwOworfQorCisucG9kbGluayBpbWcgeworICAgIGRpc3BsYXk6IGJsb2NrOworICAgIGhlaWdodDogMTZweDsKKyAgICB3aWR0aDogMTZweDsKK30KKworLnByaW50bGluayB7CisgICAgcG9zaXRpb246IHJlbGF0aXZlOyAvKiBJRSBidWdmaXggY29udCdkICovCisgICAgZmxvYXQ6IHJpZ2h0OworfQorLnByaW50bGluayBiciB7CisgICAgbWFyZ2luLXRvcDogLTEwcHg7CisgICAgcGFkZGluZy1sZWZ0OiAxcHg7Cit9CisucHJpbnRsaW5rIGEgeworICAgIGRpc3BsYXk6IGJsb2NrOworICAgIGZvbnQtc2l6ZTogNzAlOworICAgIHRleHQtYWxpZ246IGNlbnRlcjsKKyAgICBtYXJnaW46IDA7CisgICAgcGFkZGluZzogMDsKK30KKy5wcmludGxpbmsgaW1nIHsKKyAgICBkaXNwbGF5OiBibG9jazsKKyAgICBoZWlnaHQ6IDE2cHg7CisgICAgd2lkdGg6IDE2cHg7Cit9CisKK3AuaW5zdHJ1Y3Rpb24geworICBkaXNwbGF5OiBsaXN0LWl0ZW07CisgIGxpc3Qtc3R5bGUtaW1hZ2U6IHVybCgnLi4vaW1hZ2VzL2luc3RydWN0aW9uX2Fycm93LnBuZycpOworICBsaXN0LXN0eWxlLXBvc2l0aW9uOiBvdXRzaWRlOworICBtYXJnaW4tbGVmdDogMmVtOworfSAKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9saWIvQWdpbGVKU09OLTIuMC5qYXIgYi9saWIvQWdpbGVKU09OLTIuMC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA2MTYxYQotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9BZ2lsZUpTT04tMi4wLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1jbGktMi4wLVNOQVBTSE9ULmphciBiL2xpYi9jb21tb25zLWNsaS0yLjAtU05BUFNIT1QuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiMWQ1MTAKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvY29tbW9ucy1jbGktMi4wLVNOQVBTSE9ULmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1lbC1mcm9tLWpldHR5LTUuMS40LmphciBiL2xpYi9jb21tb25zLWVsLWZyb20tamV0dHktNS4xLjQuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwOGVkNzkKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvY29tbW9ucy1lbC1mcm9tLWpldHR5LTUuMS40LmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1odHRwY2xpZW50LTMuMC4xLmphciBiL2xpYi9jb21tb25zLWh0dHBjbGllbnQtMy4wLjEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmYzc3N2MKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvY29tbW9ucy1odHRwY2xpZW50LTMuMC4xLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1sb2dnaW5nLTEuMC40LmphciBiL2xpYi9jb21tb25zLWxvZ2dpbmctMS4wLjQuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3M2E4MGYKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvY29tbW9ucy1sb2dnaW5nLTEuMC40LmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1sb2dnaW5nLWFwaS0xLjAuNC5qYXIgYi9saWIvY29tbW9ucy1sb2dnaW5nLWFwaS0xLjAuNC5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWRlOWExMwotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9jb21tb25zLWxvZ2dpbmctYXBpLTEuMC40LmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvY29tbW9ucy1tYXRoLTEuMS5qYXIgYi9saWIvY29tbW9ucy1tYXRoLTEuMS5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg4ODgxMwotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9jb21tb25zLW1hdGgtMS4xLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvaGFkb29wLTAuMTguMy1jb3JlLmphciBiL2xpYi9oYWRvb3AtMC4xOC4zLWNvcmUuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxOTFhNjgKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvaGFkb29wLTAuMTguMy1jb3JlLmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvaGFkb29wLTAuMTguMy10ZXN0LmphciBiL2xpYi9oYWRvb3AtMC4xOC4zLXRlc3QuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmNTdmYjUKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvaGFkb29wLTAuMTguMy10ZXN0LmphcgpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9saWIvamV0dHktNS4xLjQuTElDRU5TRS50eHQgYi9saWIvamV0dHktNS4xLjQuTElDRU5TRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDY0NTY5NQotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9qZXR0eS01LjEuNC5MSUNFTlNFLnR4dApAQCAtMCwwICsxLDIwMiBAQAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKworICAgQVBQRU5ESVg6IEhvdyB0byBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLgorCisgICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZworICAgICAgYm9pbGVycGxhdGUgbm90aWNlLCB3aXRoIHRoZSBmaWVsZHMgZW5jbG9zZWQgYnkgYnJhY2tldHMgIltdIgorICAgICAgcmVwbGFjZWQgd2l0aCB5b3VyIG93biBpZGVudGlmeWluZyBpbmZvcm1hdGlvbi4gKERvbid0IGluY2x1ZGUKKyAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCisgICAgICBjb21tZW50IHN5bnRheCBmb3IgdGhlIGZpbGUgZm9ybWF0LiBXZSBhbHNvIHJlY29tbWVuZCB0aGF0IGEKKyAgICAgIGZpbGUgb3IgY2xhc3MgbmFtZSBhbmQgZGVzY3JpcHRpb24gb2YgcHVycG9zZSBiZSBpbmNsdWRlZCBvbiB0aGUKKyAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgorICAgICAgaWRlbnRpZmljYXRpb24gd2l0aGluIHRoaXJkLXBhcnR5IGFyY2hpdmVzLgorCisgICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KZGlmZiAtLWdpdCBhL2xpYi9qZXR0eS01LjEuNC5qYXIgYi9saWIvamV0dHktNS4xLjQuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjYmQ5OWUKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvamV0dHktNS4xLjQuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9qcnVieS1jb21wbGV0ZS0xLjIuMC5qYXIgYi9saWIvanJ1YnktY29tcGxldGUtMS4yLjAuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAyZTQ0N2QKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanJ1YnktY29tcGxldGUtMS4yLjAuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9qcnVieS1jb21wbGV0ZS1MSUNFTlNFLnR4dCBiL2xpYi9qcnVieS1jb21wbGV0ZS1MSUNFTlNFLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGU2YzA1Ci0tLSAvZGV2L251bGwKKysrIGIvbGliL2pydWJ5LWNvbXBsZXRlLUxJQ0VOU0UudHh0CkBAIC0wLDAgKzEsODYgQEAKK0NvbW1vbiBQdWJsaWMgTGljZW5zZSAtIHYgMS4wCisKK1RIRSBBQ0NPTVBBTllJTkcgUFJPR1JBTSBJUyBQUk9WSURFRCBVTkRFUiBUSEUgVEVSTVMgT0YgVEhJUyBDT01NT04gUFVCTElDIExJQ0VOU0UgKCJBR1JFRU1FTlQiKS4gQU5ZIFVTRSwgUkVQUk9EVUNUSU9OIE9SIERJU1RSSUJVVElPTiBPRiBUSEUgUFJPR1JBTSBDT05TVElUVVRFUyBSRUNJUElFTlQnUyBBQ0NFUFRBTkNFIE9GIFRISVMgQUdSRUVNRU5ULgorCisxLiBERUZJTklUSU9OUworCisiQ29udHJpYnV0aW9uIiBtZWFuczoKKworICAgICAgYSkgaW4gdGhlIGNhc2Ugb2YgdGhlIGluaXRpYWwgQ29udHJpYnV0b3IsIHRoZSBpbml0aWFsIGNvZGUgYW5kIGRvY3VtZW50YXRpb24gZGlzdHJpYnV0ZWQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQsIGFuZAorICAgICAgYikgaW4gdGhlIGNhc2Ugb2YgZWFjaCBzdWJzZXF1ZW50IENvbnRyaWJ1dG9yOgorCisgICAgICBpKSBjaGFuZ2VzIHRvIHRoZSBQcm9ncmFtLCBhbmQKKworICAgICAgaWkpIGFkZGl0aW9ucyB0byB0aGUgUHJvZ3JhbTsKKworICAgICAgd2hlcmUgc3VjaCBjaGFuZ2VzIGFuZC9vciBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gb3JpZ2luYXRlIGZyb20gYW5kIGFyZSBkaXN0cmlidXRlZCBieSB0aGF0IHBhcnRpY3VsYXIgQ29udHJpYnV0b3IuIEEgQ29udHJpYnV0aW9uICdvcmlnaW5hdGVzJyBmcm9tIGEgQ29udHJpYnV0b3IgaWYgaXQgd2FzIGFkZGVkIHRvIHRoZSBQcm9ncmFtIGJ5IHN1Y2ggQ29udHJpYnV0b3IgaXRzZWxmIG9yIGFueW9uZSBhY3Rpbmcgb24gc3VjaCBDb250cmlidXRvcidzIGJlaGFsZi4gQ29udHJpYnV0aW9ucyBkbyBub3QgaW5jbHVkZSBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW0gd2hpY2g6IChpKSBhcmUgc2VwYXJhdGUgbW9kdWxlcyBvZiBzb2Z0d2FyZSBkaXN0cmlidXRlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBQcm9ncmFtIHVuZGVyIHRoZWlyIG93biBsaWNlbnNlIGFncmVlbWVudCwgYW5kIChpaSkgYXJlIG5vdCBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBQcm9ncmFtLiAKKworIkNvbnRyaWJ1dG9yIiBtZWFucyBhbnkgcGVyc29uIG9yIGVudGl0eSB0aGF0IGRpc3RyaWJ1dGVzIHRoZSBQcm9ncmFtLgorCisiTGljZW5zZWQgUGF0ZW50cyAiIG1lYW4gcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlIGJ5IGEgQ29udHJpYnV0b3Igd2hpY2ggYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGUgdXNlIG9yIHNhbGUgb2YgaXRzIENvbnRyaWJ1dGlvbiBhbG9uZSBvciB3aGVuIGNvbWJpbmVkIHdpdGggdGhlIFByb2dyYW0uCisKKyJQcm9ncmFtIiBtZWFucyB0aGUgQ29udHJpYnV0aW9ucyBkaXN0cmlidXRlZCBpbiBhY2NvcmRhbmNlIHdpdGggdGhpcyBBZ3JlZW1lbnQuCisKKyJSZWNpcGllbnQiIG1lYW5zIGFueW9uZSB3aG8gcmVjZWl2ZXMgdGhlIFByb2dyYW0gdW5kZXIgdGhpcyBBZ3JlZW1lbnQsIGluY2x1ZGluZyBhbGwgQ29udHJpYnV0b3JzLgorCisyLiBHUkFOVCBPRiBSSUdIVFMKKworICAgICAgYSkgU3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyBSZWNpcGllbnQgYSBub24tZXhjbHVzaXZlLCB3b3JsZHdpZGUsIHJveWFsdHktZnJlZSBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgZGVyaXZhdGl2ZSB3b3JrcyBvZiwgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgZGlzdHJpYnV0ZSBhbmQgc3VibGljZW5zZSB0aGUgQ29udHJpYnV0aW9uIG9mIHN1Y2ggQ29udHJpYnV0b3IsIGlmIGFueSwgYW5kIHN1Y2ggZGVyaXZhdGl2ZSB3b3JrcywgaW4gc291cmNlIGNvZGUgYW5kIG9iamVjdCBjb2RlIGZvcm0uCisKKyAgICAgIGIpIFN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgUmVjaXBpZW50IGEgbm9uLWV4Y2x1c2l2ZSwgd29ybGR3aWRlLCByb3lhbHR5LWZyZWUgcGF0ZW50IGxpY2Vuc2UgdW5kZXIgTGljZW5zZWQgUGF0ZW50cyB0byBtYWtlLCB1c2UsIHNlbGwsIG9mZmVyIHRvIHNlbGwsIGltcG9ydCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBDb250cmlidXRpb24gb2Ygc3VjaCBDb250cmlidXRvciwgaWYgYW55LCBpbiBzb3VyY2UgY29kZSBhbmQgb2JqZWN0IGNvZGUgZm9ybS4gVGhpcyBwYXRlbnQgbGljZW5zZSBzaGFsbCBhcHBseSB0byB0aGUgY29tYmluYXRpb24gb2YgdGhlIENvbnRyaWJ1dGlvbiBhbmQgdGhlIFByb2dyYW0gaWYsIGF0IHRoZSB0aW1lIHRoZSBDb250cmlidXRpb24gaXMgYWRkZWQgYnkgdGhlIENvbnRyaWJ1dG9yLCBzdWNoIGFkZGl0aW9uIG9mIHRoZSBDb250cmlidXRpb24gY2F1c2VzIHN1Y2ggY29tYmluYXRpb24gdG8gYmUgY292ZXJlZCBieSB0aGUgTGljZW5zZWQgUGF0ZW50cy4gVGhlIHBhdGVudCBsaWNlbnNlIHNoYWxsIG5vdCBhcHBseSB0byBhbnkgb3RoZXIgY29tYmluYXRpb25zIHdoaWNoIGluY2x1ZGUgdGhlIENvbnRyaWJ1dGlvbi4gTm8gaGFyZHdhcmUgcGVyIHNlIGlzIGxpY2Vuc2VkIGhlcmV1bmRlci4gCisKKyAgICAgIGMpIFJlY2lwaWVudCB1bmRlcnN0YW5kcyB0aGF0IGFsdGhvdWdoIGVhY2ggQ29udHJpYnV0b3IgZ3JhbnRzIHRoZSBsaWNlbnNlcyB0byBpdHMgQ29udHJpYnV0aW9ucyBzZXQgZm9ydGggaGVyZWluLCBubyBhc3N1cmFuY2VzIGFyZSBwcm92aWRlZCBieSBhbnkgQ29udHJpYnV0b3IgdGhhdCB0aGUgUHJvZ3JhbSBkb2VzIG5vdCBpbmZyaW5nZSB0aGUgcGF0ZW50IG9yIG90aGVyIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb2YgYW55IG90aGVyIGVudGl0eS4gRWFjaCBDb250cmlidXRvciBkaXNjbGFpbXMgYW55IGxpYWJpbGl0eSB0byBSZWNpcGllbnQgZm9yIGNsYWltcyBicm91Z2h0IGJ5IGFueSBvdGhlciBlbnRpdHkgYmFzZWQgb24gaW5mcmluZ2VtZW50IG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3Igb3RoZXJ3aXNlLiBBcyBhIGNvbmRpdGlvbiB0byBleGVyY2lzaW5nIHRoZSByaWdodHMgYW5kIGxpY2Vuc2VzIGdyYW50ZWQgaGVyZXVuZGVyLCBlYWNoIFJlY2lwaWVudCBoZXJlYnkgYXNzdW1lcyBzb2xlIHJlc3BvbnNpYmlsaXR5IHRvIHNlY3VyZSBhbnkgb3RoZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBuZWVkZWQsIGlmIGFueS4gRm9yIGV4YW1wbGUsIGlmIGEgdGhpcmQgcGFydHkgcGF0ZW50IGxpY2Vuc2UgaXMgcmVxdWlyZWQgdG8gYWxsb3cgUmVjaXBpZW50IHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0sIGl0IGlzIFJlY2lwaWVudCdzIHJlc3BvbnNpYmlsaXR5IHRvIGFjcXVpcmUgdGhhdCBsaWNlbnNlIGJlZm9yZSBkaXN0cmlidXRpbmcgdGhlIFByb2dyYW0uCisKKyAgICAgIGQpIEVhY2ggQ29udHJpYnV0b3IgcmVwcmVzZW50cyB0aGF0IHRvIGl0cyBrbm93bGVkZ2UgaXQgaGFzIHN1ZmZpY2llbnQgY29weXJpZ2h0IHJpZ2h0cyBpbiBpdHMgQ29udHJpYnV0aW9uLCBpZiBhbnksIHRvIGdyYW50IHRoZSBjb3B5cmlnaHQgbGljZW5zZSBzZXQgZm9ydGggaW4gdGhpcyBBZ3JlZW1lbnQuIAorCiszLiBSRVFVSVJFTUVOVFMKKworQSBDb250cmlidXRvciBtYXkgY2hvb3NlIHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gaW4gb2JqZWN0IGNvZGUgZm9ybSB1bmRlciBpdHMgb3duIGxpY2Vuc2UgYWdyZWVtZW50LCBwcm92aWRlZCB0aGF0OgorCisgICAgICBhKSBpdCBjb21wbGllcyB3aXRoIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGlzIEFncmVlbWVudDsgYW5kCisKKyAgICAgIGIpIGl0cyBsaWNlbnNlIGFncmVlbWVudDoKKworICAgICAgaSkgZWZmZWN0aXZlbHkgZGlzY2xhaW1zIG9uIGJlaGFsZiBvZiBhbGwgQ29udHJpYnV0b3JzIGFsbCB3YXJyYW50aWVzIGFuZCBjb25kaXRpb25zLCBleHByZXNzIGFuZCBpbXBsaWVkLCBpbmNsdWRpbmcgd2FycmFudGllcyBvciBjb25kaXRpb25zIG9mIHRpdGxlIGFuZCBub24taW5mcmluZ2VtZW50LCBhbmQgaW1wbGllZCB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBmaXRuZXNzIGZvciBhIHBhcnRpY3VsYXIgcHVycG9zZTsgCisKKyAgICAgIGlpKSBlZmZlY3RpdmVseSBleGNsdWRlcyBvbiBiZWhhbGYgb2YgYWxsIENvbnRyaWJ1dG9ycyBhbGwgbGlhYmlsaXR5IGZvciBkYW1hZ2VzLCBpbmNsdWRpbmcgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwgaW5jaWRlbnRhbCBhbmQgY29uc2VxdWVudGlhbCBkYW1hZ2VzLCBzdWNoIGFzIGxvc3QgcHJvZml0czsgCisKKyAgICAgIGlpaSkgc3RhdGVzIHRoYXQgYW55IHByb3Zpc2lvbnMgd2hpY2ggZGlmZmVyIGZyb20gdGhpcyBBZ3JlZW1lbnQgYXJlIG9mZmVyZWQgYnkgdGhhdCBDb250cmlidXRvciBhbG9uZSBhbmQgbm90IGJ5IGFueSBvdGhlciBwYXJ0eTsgYW5kCisKKyAgICAgIGl2KSBzdGF0ZXMgdGhhdCBzb3VyY2UgY29kZSBmb3IgdGhlIFByb2dyYW0gaXMgYXZhaWxhYmxlIGZyb20gc3VjaCBDb250cmlidXRvciwgYW5kIGluZm9ybXMgbGljZW5zZWVzIGhvdyB0byBvYnRhaW4gaXQgaW4gYSByZWFzb25hYmxlIG1hbm5lciBvbiBvciB0aHJvdWdoIGEgbWVkaXVtIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGV4Y2hhbmdlLiAKKworV2hlbiB0aGUgUHJvZ3JhbSBpcyBtYWRlIGF2YWlsYWJsZSBpbiBzb3VyY2UgY29kZSBmb3JtOgorCisgICAgICBhKSBpdCBtdXN0IGJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoaXMgQWdyZWVtZW50OyBhbmQgCisKKyAgICAgIGIpIGEgY29weSBvZiB0aGlzIEFncmVlbWVudCBtdXN0IGJlIGluY2x1ZGVkIHdpdGggZWFjaCBjb3B5IG9mIHRoZSBQcm9ncmFtLiAKKworQ29udHJpYnV0b3JzIG1heSBub3QgcmVtb3ZlIG9yIGFsdGVyIGFueSBjb3B5cmlnaHQgbm90aWNlcyBjb250YWluZWQgd2l0aGluIHRoZSBQcm9ncmFtLgorCitFYWNoIENvbnRyaWJ1dG9yIG11c3QgaWRlbnRpZnkgaXRzZWxmIGFzIHRoZSBvcmlnaW5hdG9yIG9mIGl0cyBDb250cmlidXRpb24sIGlmIGFueSwgaW4gYSBtYW5uZXIgdGhhdCByZWFzb25hYmx5IGFsbG93cyBzdWJzZXF1ZW50IFJlY2lwaWVudHMgdG8gaWRlbnRpZnkgdGhlIG9yaWdpbmF0b3Igb2YgdGhlIENvbnRyaWJ1dGlvbi4KKworNC4gQ09NTUVSQ0lBTCBESVNUUklCVVRJT04KKworQ29tbWVyY2lhbCBkaXN0cmlidXRvcnMgb2Ygc29mdHdhcmUgbWF5IGFjY2VwdCBjZXJ0YWluIHJlc3BvbnNpYmlsaXRpZXMgd2l0aCByZXNwZWN0IHRvIGVuZCB1c2VycywgYnVzaW5lc3MgcGFydG5lcnMgYW5kIHRoZSBsaWtlLiBXaGlsZSB0aGlzIGxpY2Vuc2UgaXMgaW50ZW5kZWQgdG8gZmFjaWxpdGF0ZSB0aGUgY29tbWVyY2lhbCB1c2Ugb2YgdGhlIFByb2dyYW0sIHRoZSBDb250cmlidXRvciB3aG8gaW5jbHVkZXMgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsIHByb2R1Y3Qgb2ZmZXJpbmcgc2hvdWxkIGRvIHNvIGluIGEgbWFubmVyIHdoaWNoIGRvZXMgbm90IGNyZWF0ZSBwb3RlbnRpYWwgbGlhYmlsaXR5IGZvciBvdGhlciBDb250cmlidXRvcnMuIFRoZXJlZm9yZSwgaWYgYSBDb250cmlidXRvciBpbmNsdWRlcyB0aGUgUHJvZ3JhbSBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZywgc3VjaCBDb250cmlidXRvciAoIkNvbW1lcmNpYWwgQ29udHJpYnV0b3IiKSBoZXJlYnkgYWdyZWVzIHRvIGRlZmVuZCBhbmQgaW5kZW1uaWZ5IGV2ZXJ5IG90aGVyIENvbnRyaWJ1dG9yICgiSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IiKSBhZ2FpbnN0IGFueSBsb3NzZXMsIGRhbWFnZXMgYW5kIGNvc3RzIChjb2xsZWN0aXZlbHkgIkxvc3NlcyIpIGFyaXNpbmcgZnJvbSBjbGFpbXMsIGxhd3N1aXRzIGFuZCBvdGhlciBsZWdhbCBhY3Rpb25zIGJyb3VnaHQgYnkgYSB0aGlyZCBwYXJ0eSBhZ2FpbnN0IHRoZSBJbmRlbW5pZmllZCBDb250cmlidXRvciB0byB0aGUgZXh0ZW50IGNhdXNlZCBieSB0aGUgYWN0cyBvciBvbWlzc2lvbnMgb2Ygc3VjaCBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluIGNvbm5lY3Rpb24gd2l0aCBpdHMgZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9ncmFtIGluIGEgY29tbWVyY2lhbCBwcm9kdWN0IG9mZmVyaW5nLiBUaGUgb2JsaWdhdGlvbnMgaW4gdGhpcyBzZWN0aW9uIGRvIG5vdCBhcHBseSB0byBhbnkgY2xhaW1zIG9yIExvc3NlcyByZWxhdGluZyB0byBhbnkgYWN0dWFsIG9yIGFsbGVnZWQgaW50ZWxsZWN0dWFsIHByb3BlcnR5IGluZnJpbmdlbWVudC4gSW4gb3JkZXIgdG8gcXVhbGlmeSwgYW4gSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IgbXVzdDogYSkgcHJvbXB0bHkgbm90aWZ5IHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIGluIHdyaXRpbmcgb2Ygc3VjaCBjbGFpbSwgYW5kIGIpIGFsbG93IHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHRvIGNvbnRyb2wsIGFuZCBjb29wZXJhdGUgd2l0aCB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciBpbiwgdGhlIGRlZmVuc2UgYW5kIGFueSByZWxhdGVkIHNldHRsZW1lbnQgbmVnb3RpYXRpb25zLiBUaGUgSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IgbWF5IHBhcnRpY2lwYXRlIGluIGFueSBzdWNoIGNsYWltIGF0IGl0cyBvd24gZXhwZW5zZS4KKworRm9yIGV4YW1wbGUsIGEgQ29udHJpYnV0b3IgbWlnaHQgaW5jbHVkZSB0aGUgUHJvZ3JhbSBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZywgUHJvZHVjdCBYLiBUaGF0IENvbnRyaWJ1dG9yIGlzIHRoZW4gYSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yLiBJZiB0aGF0IENvbW1lcmNpYWwgQ29udHJpYnV0b3IgdGhlbiBtYWtlcyBwZXJmb3JtYW5jZSBjbGFpbXMsIG9yIG9mZmVycyB3YXJyYW50aWVzIHJlbGF0ZWQgdG8gUHJvZHVjdCBYLCB0aG9zZSBwZXJmb3JtYW5jZSBjbGFpbXMgYW5kIHdhcnJhbnRpZXMgYXJlIHN1Y2ggQ29tbWVyY2lhbCBDb250cmlidXRvcidzIHJlc3BvbnNpYmlsaXR5IGFsb25lLiBVbmRlciB0aGlzIHNlY3Rpb24sIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHdvdWxkIGhhdmUgdG8gZGVmZW5kIGNsYWltcyBhZ2FpbnN0IHRoZSBvdGhlciBDb250cmlidXRvcnMgcmVsYXRlZCB0byB0aG9zZSBwZXJmb3JtYW5jZSBjbGFpbXMgYW5kIHdhcnJhbnRpZXMsIGFuZCBpZiBhIGNvdXJ0IHJlcXVpcmVzIGFueSBvdGhlciBDb250cmlidXRvciB0byBwYXkgYW55IGRhbWFnZXMgYXMgYSByZXN1bHQsIHRoZSBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIG11c3QgcGF5IHRob3NlIGRhbWFnZXMuCisKKzUuIE5PIFdBUlJBTlRZCisKK0VYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBUSEUgUFJPR1JBTSBJUyBQUk9WSURFRCBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgTk9OLUlORlJJTkdFTUVOVCwgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBFYWNoIFJlY2lwaWVudCBpcyBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZSBhcHByb3ByaWF0ZW5lc3Mgb2YgdXNpbmcgYW5kIGRpc3RyaWJ1dGluZyB0aGUgUHJvZ3JhbSBhbmQgYXNzdW1lcyBhbGwgcmlza3MgYXNzb2NpYXRlZCB3aXRoIGl0cyBleGVyY2lzZSBvZiByaWdodHMgdW5kZXIgdGhpcyBBZ3JlZW1lbnQsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIHJpc2tzIGFuZCBjb3N0cyBvZiBwcm9ncmFtIGVycm9ycywgY29tcGxpYW5jZSB3aXRoIGFwcGxpY2FibGUgbGF3cywgZGFtYWdlIHRvIG9yIGxvc3Mgb2YgZGF0YSwgcHJvZ3JhbXMgb3IgZXF1aXBtZW50LCBhbmQgdW5hdmFpbGFiaWxpdHkgb3IgaW50ZXJydXB0aW9uIG9mIG9wZXJhdGlvbnMuCisKKzYuIERJU0NMQUlNRVIgT0YgTElBQklMSVRZCisKK0VYQ0VQVCBBUyBFWFBSRVNTTFkgU0VUIEZPUlRIIElOIFRISVMgQUdSRUVNRU5ULCBORUlUSEVSIFJFQ0lQSUVOVCBOT1IgQU5ZIENPTlRSSUJVVE9SUyBTSEFMTCBIQVZFIEFOWSBMSUFCSUxJVFkgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBMT1NUIFBST0ZJVFMpLCBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9SIERJU1RSSUJVVElPTiBPRiBUSEUgUFJPR1JBTSBPUiBUSEUgRVhFUkNJU0UgT0YgQU5ZIFJJR0hUUyBHUkFOVEVEIEhFUkVVTkRFUiwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRVMuCisKKzcuIEdFTkVSQUwKKworSWYgYW55IHByb3Zpc2lvbiBvZiB0aGlzIEFncmVlbWVudCBpcyBpbnZhbGlkIG9yIHVuZW5mb3JjZWFibGUgdW5kZXIgYXBwbGljYWJsZSBsYXcsIGl0IHNoYWxsIG5vdCBhZmZlY3QgdGhlIHZhbGlkaXR5IG9yIGVuZm9yY2VhYmlsaXR5IG9mIHRoZSByZW1haW5kZXIgb2YgdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBhbmQgd2l0aG91dCBmdXJ0aGVyIGFjdGlvbiBieSB0aGUgcGFydGllcyBoZXJldG8sIHN1Y2ggcHJvdmlzaW9uIHNoYWxsIGJlIHJlZm9ybWVkIHRvIHRoZSBtaW5pbXVtIGV4dGVudCBuZWNlc3NhcnkgdG8gbWFrZSBzdWNoIHByb3Zpc2lvbiB2YWxpZCBhbmQgZW5mb3JjZWFibGUuCisKK0lmIFJlY2lwaWVudCBpbnN0aXR1dGVzIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYSBDb250cmlidXRvciB3aXRoIHJlc3BlY3QgdG8gYSBwYXRlbnQgYXBwbGljYWJsZSB0byBzb2Z0d2FyZSAoaW5jbHVkaW5nIGEgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCksIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcyBncmFudGVkIGJ5IHRoYXQgQ29udHJpYnV0b3IgdG8gc3VjaCBSZWNpcGllbnQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgc2hhbGwgdGVybWluYXRlIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4gSW4gYWRkaXRpb24sIGlmIFJlY2lwaWVudCBpbnN0aXR1dGVzIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgUHJvZ3JhbSBpdHNlbGYgKGV4Y2x1ZGluZyBjb21iaW5hdGlvbnMgb2YgdGhlIFByb2dyYW0gd2l0aCBvdGhlciBzb2Z0d2FyZSBvciBoYXJkd2FyZSkgaW5mcmluZ2VzIHN1Y2ggUmVjaXBpZW50J3MgcGF0ZW50KHMpLCB0aGVuIHN1Y2ggUmVjaXBpZW50J3MgcmlnaHRzIGdyYW50ZWQgdW5kZXIgU2VjdGlvbiAyKGIpIHNoYWxsIHRlcm1pbmF0ZSBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKK0FsbCBSZWNpcGllbnQncyByaWdodHMgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgc2hhbGwgdGVybWluYXRlIGlmIGl0IGZhaWxzIHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgbWF0ZXJpYWwgdGVybXMgb3IgY29uZGl0aW9ucyBvZiB0aGlzIEFncmVlbWVudCBhbmQgZG9lcyBub3QgY3VyZSBzdWNoIGZhaWx1cmUgaW4gYSByZWFzb25hYmxlIHBlcmlvZCBvZiB0aW1lIGFmdGVyIGJlY29taW5nIGF3YXJlIG9mIHN1Y2ggbm9uY29tcGxpYW5jZS4gSWYgYWxsIFJlY2lwaWVudCdzIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCB0ZXJtaW5hdGUsIFJlY2lwaWVudCBhZ3JlZXMgdG8gY2Vhc2UgdXNlIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0gYXMgc29vbiBhcyByZWFzb25hYmx5IHByYWN0aWNhYmxlLiBIb3dldmVyLCBSZWNpcGllbnQncyBvYmxpZ2F0aW9ucyB1bmRlciB0aGlzIEFncmVlbWVudCBhbmQgYW55IGxpY2Vuc2VzIGdyYW50ZWQgYnkgUmVjaXBpZW50IHJlbGF0aW5nIHRvIHRoZSBQcm9ncmFtIHNoYWxsIGNvbnRpbnVlIGFuZCBzdXJ2aXZlLgorCitFdmVyeW9uZSBpcyBwZXJtaXR0ZWQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGJ1dCBpbiBvcmRlciB0byBhdm9pZCBpbmNvbnNpc3RlbmN5IHRoZSBBZ3JlZW1lbnQgaXMgY29weXJpZ2h0ZWQgYW5kIG1heSBvbmx5IGJlIG1vZGlmaWVkIGluIHRoZSBmb2xsb3dpbmcgbWFubmVyLiBUaGUgQWdyZWVtZW50IFN0ZXdhcmQgcmVzZXJ2ZXMgdGhlIHJpZ2h0IHRvIHB1Ymxpc2ggbmV3IHZlcnNpb25zIChpbmNsdWRpbmcgcmV2aXNpb25zKSBvZiB0aGlzIEFncmVlbWVudCBmcm9tIHRpbWUgdG8gdGltZS4gTm8gb25lIG90aGVyIHRoYW4gdGhlIEFncmVlbWVudCBTdGV3YXJkIGhhcyB0aGUgcmlnaHQgdG8gbW9kaWZ5IHRoaXMgQWdyZWVtZW50LiBJQk0gaXMgdGhlIGluaXRpYWwgQWdyZWVtZW50IFN0ZXdhcmQuIElCTSBtYXkgYXNzaWduIHRoZSByZXNwb25zaWJpbGl0eSB0byBzZXJ2ZSBhcyB0aGUgQWdyZWVtZW50IFN0ZXdhcmQgdG8gYSBzdWl0YWJsZSBzZXBhcmF0ZSBlbnRpdHkuIEVhY2ggbmV3IHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB3aWxsIGJlIGdpdmVuIGEgZGlzdGluZ3Vpc2hpbmcgdmVyc2lvbiBudW1iZXIuIFRoZSBQcm9ncmFtIChpbmNsdWRpbmcgQ29udHJpYnV0aW9ucykgbWF5IGFsd2F5cyBiZSBkaXN0cmlidXRlZCBzdWJqZWN0IHRvIHRoZSB2ZXJzaW9uIG9mIHRoZSBBZ3JlZW1lbnQgdW5kZXIgd2hpY2ggaXQgd2FzIHJlY2VpdmVkLiBJbiBhZGRpdGlvbiwgYWZ0ZXIgYSBuZXcgdmVyc2lvbiBvZiB0aGUgQWdyZWVtZW50IGlzIHB1Ymxpc2hlZCwgQ29udHJpYnV0b3IgbWF5IGVsZWN0IHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKGluY2x1ZGluZyBpdHMgQ29udHJpYnV0aW9ucykgdW5kZXIgdGhlIG5ldyB2ZXJzaW9uLiBFeGNlcHQgYXMgZXhwcmVzc2x5IHN0YXRlZCBpbiBTZWN0aW9ucyAyKGEpIGFuZCAyKGIpIGFib3ZlLCBSZWNpcGllbnQgcmVjZWl2ZXMgbm8gcmlnaHRzIG9yIGxpY2Vuc2VzIHRvIHRoZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkgb2YgYW55IENvbnRyaWJ1dG9yIHVuZGVyIHRoaXMgQWdyZWVtZW50LCB3aGV0aGVyIGV4cHJlc3NseSwgYnkgaW1wbGljYXRpb24sIGVzdG9wcGVsIG9yIG90aGVyd2lzZS4gQWxsIHJpZ2h0cyBpbiB0aGUgUHJvZ3JhbSBub3QgZXhwcmVzc2x5IGdyYW50ZWQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgYXJlIHJlc2VydmVkLgorCitUaGlzIEFncmVlbWVudCBpcyBnb3Zlcm5lZCBieSB0aGUgbGF3cyBvZiB0aGUgU3RhdGUgb2YgTmV3IFlvcmsgYW5kIHRoZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkgbGF3cyBvZiB0aGUgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhLiBObyBwYXJ0eSB0byB0aGlzIEFncmVlbWVudCB3aWxsIGJyaW5nIGEgbGVnYWwgYWN0aW9uIHVuZGVyIHRoaXMgQWdyZWVtZW50IG1vcmUgdGhhbiBvbmUgeWVhciBhZnRlciB0aGUgY2F1c2Ugb2YgYWN0aW9uIGFyb3NlLiBFYWNoIHBhcnR5IHdhaXZlcyBpdHMgcmlnaHRzIHRvIGEganVyeSB0cmlhbCBpbiBhbnkgcmVzdWx0aW5nIGxpdGlnYXRpb24uIApkaWZmIC0tZ2l0IGEvbGliL2p1bml0LTMuOC4xLkxJQ0VOU0UudHh0IGIvbGliL2p1bml0LTMuOC4xLkxJQ0VOU0UudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3MzVhNzEKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanVuaXQtMy44LjEuTElDRU5TRS50eHQKQEAgLTAsMCArMSwxMDAgQEAKK0NvbW1vbiBQdWJsaWMgTGljZW5zZSBWZXJzaW9uIDEuMAorCitUSEUgQUNDT01QQU5ZSU5HIFBST0dSQU0gSVMgUFJPVklERUQgVU5ERVIgVEhFIFRFUk1TIE9GIFRISVMgQ09NTU9OIFBVQkxJQyBMSUNFTlNFICgiQUdSRUVNRU5UIikuIEFOWSBVU0UsIFJFUFJPRFVDVElPTiBPUiBESVNUUklCVVRJT04gT0YgVEhFIFBST0dSQU0gQ09OU1RJVFVURVMgUkVDSVBJRU5UJ1MgQUNDRVBUQU5DRSBPRiBUSElTIEFHUkVFTUVOVC4KKworMS4gREVGSU5JVElPTlMKKworIkNvbnRyaWJ1dGlvbiIgbWVhbnM6CisKKyAgICBhKSBpbiB0aGUgY2FzZSBvZiB0aGUgaW5pdGlhbCBDb250cmlidXRvciwgdGhlIGluaXRpYWwgY29kZSBhbmQgZG9jdW1lbnRhdGlvbiBkaXN0cmlidXRlZCB1bmRlciB0aGlzIEFncmVlbWVudCwgYW5kCisKKyAgICBiKSBpbiB0aGUgY2FzZSBvZiBlYWNoIHN1YnNlcXVlbnQgQ29udHJpYnV0b3I6CisKKyAgICBpKSBjaGFuZ2VzIHRvIHRoZSBQcm9ncmFtLCBhbmQKKworICAgIGlpKSBhZGRpdGlvbnMgdG8gdGhlIFByb2dyYW07CisKKyAgICB3aGVyZSBzdWNoIGNoYW5nZXMgYW5kL29yIGFkZGl0aW9ucyB0byB0aGUgUHJvZ3JhbSBvcmlnaW5hdGUgZnJvbSBhbmQgYXJlIGRpc3RyaWJ1dGVkIGJ5IHRoYXQgcGFydGljdWxhciBDb250cmlidXRvci4gQSBDb250cmlidXRpb24gJ29yaWdpbmF0ZXMnIGZyb20gYSBDb250cmlidXRvciBpZiBpdCB3YXMgYWRkZWQgdG8gdGhlIFByb2dyYW0gYnkgc3VjaCBDb250cmlidXRvciBpdHNlbGYgb3IgYW55b25lIGFjdGluZyBvbiBzdWNoIENvbnRyaWJ1dG9yJ3MgYmVoYWxmLiBDb250cmlidXRpb25zIGRvIG5vdCBpbmNsdWRlIGFkZGl0aW9ucyB0byB0aGUgUHJvZ3JhbSB3aGljaDogKGkpIGFyZSBzZXBhcmF0ZSBtb2R1bGVzIG9mIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIFByb2dyYW0gdW5kZXIgdGhlaXIgb3duIGxpY2Vuc2UgYWdyZWVtZW50LCBhbmQgKGlpKSBhcmUgbm90IGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFByb2dyYW0uCisKKyJDb250cmlidXRvciIgbWVhbnMgYW55IHBlcnNvbiBvciBlbnRpdHkgdGhhdCBkaXN0cmlidXRlcyB0aGUgUHJvZ3JhbS4KKworIkxpY2Vuc2VkIFBhdGVudHMgIiBtZWFuIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZSBieSBhIENvbnRyaWJ1dG9yIHdoaWNoIGFyZSBuZWNlc3NhcmlseSBpbmZyaW5nZWQgYnkgdGhlIHVzZSBvciBzYWxlIG9mIGl0cyBDb250cmlidXRpb24gYWxvbmUgb3Igd2hlbiBjb21iaW5lZCB3aXRoIHRoZSBQcm9ncmFtLgorCisiUHJvZ3JhbSIgbWVhbnMgdGhlIENvbnRyaWJ1dGlvbnMgZGlzdHJpYnV0ZWQgaW4gYWNjb3JkYW5jZSB3aXRoIHRoaXMgQWdyZWVtZW50LgorCisiUmVjaXBpZW50IiBtZWFucyBhbnlvbmUgd2hvIHJlY2VpdmVzIHRoZSBQcm9ncmFtIHVuZGVyIHRoaXMgQWdyZWVtZW50LCBpbmNsdWRpbmcgYWxsIENvbnRyaWJ1dG9ycy4KKworMi4gR1JBTlQgT0YgUklHSFRTCisKKyAgICBhKSBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZiB0aGlzIEFncmVlbWVudCwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIFJlY2lwaWVudCBhIG5vbi1leGNsdXNpdmUsIHdvcmxkd2lkZSwgcm95YWx0eS1mcmVlIGNvcHlyaWdodCBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBkZXJpdmF0aXZlIHdvcmtzIG9mLCBwdWJsaWNseSBkaXNwbGF5LCBwdWJsaWNseSBwZXJmb3JtLCBkaXN0cmlidXRlIGFuZCBzdWJsaWNlbnNlIHRoZSBDb250cmlidXRpb24gb2Ygc3VjaCBDb250cmlidXRvciwgaWYgYW55LCBhbmQgc3VjaCBkZXJpdmF0aXZlIHdvcmtzLCBpbiBzb3VyY2UgY29kZSBhbmQgb2JqZWN0IGNvZGUgZm9ybS4KKworICAgIGIpIFN1YmplY3QgdG8gdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgUmVjaXBpZW50IGEgbm9uLWV4Y2x1c2l2ZSwgd29ybGR3aWRlLCByb3lhbHR5LWZyZWUgcGF0ZW50IGxpY2Vuc2UgdW5kZXIgTGljZW5zZWQgUGF0ZW50cyB0byBtYWtlLCB1c2UsIHNlbGwsIG9mZmVyIHRvIHNlbGwsIGltcG9ydCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBDb250cmlidXRpb24gb2Ygc3VjaCBDb250cmlidXRvciwgaWYgYW55LCBpbiBzb3VyY2UgY29kZSBhbmQgb2JqZWN0IGNvZGUgZm9ybS4gVGhpcyBwYXRlbnQgbGljZW5zZSBzaGFsbCBhcHBseSB0byB0aGUgY29tYmluYXRpb24gb2YgdGhlIENvbnRyaWJ1dGlvbiBhbmQgdGhlIFByb2dyYW0gaWYsIGF0IHRoZSB0aW1lIHRoZSBDb250cmlidXRpb24gaXMgYWRkZWQgYnkgdGhlIENvbnRyaWJ1dG9yLCBzdWNoIGFkZGl0aW9uIG9mIHRoZSBDb250cmlidXRpb24gY2F1c2VzIHN1Y2ggY29tYmluYXRpb24gdG8gYmUgY292ZXJlZCBieSB0aGUgTGljZW5zZWQgUGF0ZW50cy4gVGhlIHBhdGVudCBsaWNlbnNlIHNoYWxsIG5vdCBhcHBseSB0byBhbnkgb3RoZXIgY29tYmluYXRpb25zIHdoaWNoIGluY2x1ZGUgdGhlIENvbnRyaWJ1dGlvbi4gTm8gaGFyZHdhcmUgcGVyIHNlIGlzIGxpY2Vuc2VkIGhlcmV1bmRlci4KKworICAgIGMpIFJlY2lwaWVudCB1bmRlcnN0YW5kcyB0aGF0IGFsdGhvdWdoIGVhY2ggQ29udHJpYnV0b3IgZ3JhbnRzIHRoZSBsaWNlbnNlcyB0byBpdHMgQ29udHJpYnV0aW9ucyBzZXQgZm9ydGggaGVyZWluLCBubyBhc3N1cmFuY2VzIGFyZSBwcm92aWRlZCBieSBhbnkgQ29udHJpYnV0b3IgdGhhdCB0aGUgUHJvZ3JhbSBkb2VzIG5vdCBpbmZyaW5nZSB0aGUgcGF0ZW50IG9yIG90aGVyIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb2YgYW55IG90aGVyIGVudGl0eS4gRWFjaCBDb250cmlidXRvciBkaXNjbGFpbXMgYW55IGxpYWJpbGl0eSB0byBSZWNpcGllbnQgZm9yIGNsYWltcyBicm91Z2h0IGJ5IGFueSBvdGhlciBlbnRpdHkgYmFzZWQgb24gaW5mcmluZ2VtZW50IG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3Igb3RoZXJ3aXNlLiBBcyBhIGNvbmRpdGlvbiB0byBleGVyY2lzaW5nIHRoZSByaWdodHMgYW5kIGxpY2Vuc2VzIGdyYW50ZWQgaGVyZXVuZGVyLCBlYWNoIFJlY2lwaWVudCBoZXJlYnkgYXNzdW1lcyBzb2xlIHJlc3BvbnNpYmlsaXR5IHRvIHNlY3VyZSBhbnkgb3RoZXIgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBuZWVkZWQsIGlmIGFueS4gRm9yIGV4YW1wbGUsIGlmIGEgdGhpcmQgcGFydHkgcGF0ZW50IGxpY2Vuc2UgaXMgcmVxdWlyZWQgdG8gYWxsb3cgUmVjaXBpZW50IHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0sIGl0IGlzIFJlY2lwaWVudCdzIHJlc3BvbnNpYmlsaXR5IHRvIGFjcXVpcmUgdGhhdCBsaWNlbnNlIGJlZm9yZSBkaXN0cmlidXRpbmcgdGhlIFByb2dyYW0uCisKKyAgICBkKSBFYWNoIENvbnRyaWJ1dG9yIHJlcHJlc2VudHMgdGhhdCB0byBpdHMga25vd2xlZGdlIGl0IGhhcyBzdWZmaWNpZW50IGNvcHlyaWdodCByaWdodHMgaW4gaXRzIENvbnRyaWJ1dGlvbiwgaWYgYW55LCB0byBncmFudCB0aGUgY29weXJpZ2h0IGxpY2Vuc2Ugc2V0IGZvcnRoIGluIHRoaXMgQWdyZWVtZW50LgorCiszLiBSRVFVSVJFTUVOVFMKKworQSBDb250cmlidXRvciBtYXkgY2hvb3NlIHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gaW4gb2JqZWN0IGNvZGUgZm9ybSB1bmRlciBpdHMgb3duIGxpY2Vuc2UgYWdyZWVtZW50LCBwcm92aWRlZCB0aGF0OgorCisgICAgYSkgaXQgY29tcGxpZXMgd2l0aCB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhpcyBBZ3JlZW1lbnQ7IGFuZAorCisgICAgYikgaXRzIGxpY2Vuc2UgYWdyZWVtZW50OgorCisgICAgaSkgZWZmZWN0aXZlbHkgZGlzY2xhaW1zIG9uIGJlaGFsZiBvZiBhbGwgQ29udHJpYnV0b3JzIGFsbCB3YXJyYW50aWVzIGFuZCBjb25kaXRpb25zLCBleHByZXNzIGFuZCBpbXBsaWVkLCBpbmNsdWRpbmcgd2FycmFudGllcyBvciBjb25kaXRpb25zIG9mIHRpdGxlIGFuZCBub24taW5mcmluZ2VtZW50LCBhbmQgaW1wbGllZCB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMgb2YgbWVyY2hhbnRhYmlsaXR5IGFuZCBmaXRuZXNzIGZvciBhIHBhcnRpY3VsYXIgcHVycG9zZTsKKworICAgIGlpKSBlZmZlY3RpdmVseSBleGNsdWRlcyBvbiBiZWhhbGYgb2YgYWxsIENudHJpYnV0b3JzIGFsbCBsaWFiaWxpdHkgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLCBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMsIHN1Y2ggYXMgbG9zdCBwcm9maXRzOworCisgICAgaWlpKSBzdGF0ZXMgdGhhdCBhbnkgcHJvdmlzaW9ucyB3aGljaCBkaWZmZXIgZnJvbSB0aGlzIEFncmVlbWVudCBhcmUgb2ZmZXJlZCBieSB0aGF0IENvbnRyaWJ1dG9yIGFsb25lIGFuZCBub3QgYnkgYW55IG90aGVyIHBhcnR5OyBhbmQKKworICAgIGl2KSBzdGF0ZXMgdGhhdCBzb3VyY2UgY29kZSBmb3IgdGhlIFByb2dyYW0gaXMgYXZhaWxhYmxlIGZyb20gc3VjaCBDb250cmlidXRvciwgYW5kIGluZm9ybXMgbGljZW5zZWVzIGhvdyB0byBvYnRhaW4gaXQgaW4gYSByZWFzb25hYmxlIG1hbm5lciBvbiBvciB0aHJvdWdoIGEgbWVkaXVtIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGV4Y2hhbmdlLiAKKworV2hlbiB0aGUgUHJvZ3JhbSBpcyBtYWRlIGF2YWlsYWJsZSBpbiBzb3VyY2UgY29kZSBmb3JtOgorCisgICAgYSkgaXQgbXVzdCBiZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGlzIEFncmVlbWVudDsgYW5kCisKKyAgICBiKSBhIGNvcHkgb2YgdGhpcyBBZ3JlZW1lbnQgbXVzdCBiZSBpbmNsdWRlZCB3aXRoIGVhY2ggY29weSBvZiB0aGUgUHJvZ3JhbS4gCisKK0NvbnRyaWJ1dG9ycyBtYXkgbm90IHJlbW92ZSBvciBhbHRlciBhbnkgY29weXJpZ2h0IG5vdGljZXMgY29udGFpbmVkIHdpdGhpbiB0aGUgUHJvZ3JhbS4KKworRWFjaCBDb250cmlidXRvciBtdXN0IGlkZW50aWZ5IGl0c2VsZiBhcyB0aGUgb3JpZ2luYXRvciBvZiBpdHMgQ29udHJpYnV0aW9uLCBpZiBhbnksIGluIGEgbWFubmVyIHRoYXQgcmVhc29uYWJseSBhbGxvd3Mgc3Vic2VxdWVudCBSZWNpcGllbnRzIHRvIGlkZW50aWZ5IHRoZSBvcmlnaW5hdG9yIG9mIHRoZSBDb250cmlidXRpb24uCisKKzQuIENPTU1FUkNJQUwgRElTVFJJQlVUSU9OCisKK0NvbW1lcmNpYWwgZGlzdHJpYnV0b3JzIG9mIHNvZnR3YXJlIG1heSBhY2NlcHQgY2VydGFpbiByZXNwb25zaWJpbGl0aWVzIHdpdGggcmVzcGVjdCB0byBlbmQgdXNlcnMsIGJ1c2luZXNzIHBhcnRuZXJzIGFuZCB0aGUgbGlrZS4gV2hpbGUgdGhpcyBsaWNlbnNlIGlzIGludGVuZGVkIHRvIGZhY2lsaXRhdGUgdGhlIGNvbW1lcmNpYWwgdXNlIG9mIHRoZSBQcm9ncmFtLCB0aGUgQ29udHJpYnV0b3Igd2hvIGluY2x1ZGVzIHRoZSBQcm9ncmFtIGluIGEgY29tbWVyY2lhbCBwcm9kdWN0IG9mZmVyaW5nIHNob3VsZCBkbyBzbyBpbiBhIG1hbm5lciB3aGljaCBkb2VzIG5vdCBjcmVhdGUgcG90ZW50aWFsIGxpYWJpbGl0eSBmb3Igb3RoZXIgQ29udHJpYnV0b3JzLiBUaGVyZWZvcmUsIGlmIGEgQ29udHJpYnV0b3IgaW5jbHVkZXMgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsIHByb2R1Y3Qgb2ZmZXJpbmcsIHN1Y2ggQ29udHJpYnV0b3IgKCJDb21tZXJjaWFsIENvbnRyaWJ1dG9yIikgaGVyZWJ5IGFncmVlcyB0byBkZWZlbmQgYW5kIGluZGVtbmlmeSBldmVyeSBvdGhlciBDb250cmlidXRvciAoIkluZGVtbmlmaWVkIENvbnRyaWJ1dG9yIikgYWdhaW5zdCBhbnkgbG9zc2VzLCBkYW1hZ2VzIGFuZCBjb3N0cyAoY29sbGVjdGl2ZWx5ICJMb3NzZXMiKSBhcmlzaW5nIGZyb20gY2xhaW1zLCBsYXdzdWl0cyBhbmQgb3RoZXIgbGVnYWwgYWN0aW9ucyBicm91Z2h0IGJ5IGEgdGhpcmQgcGFydHkgYWdhaW5zdCB0aGUgSW5kZW1uaWZpZWQgQ29udHJpYnV0b3IgdG8gdGhlIGV4dGVudCBjYXVzZWQgYnkgdGhlIGFjdHMgb3Igb21pc3Npb25zIG9mIHN1Y2ggQ29tbWVyY2lhbCBDb250cmlidXRvciBpbiBjb25uZWN0aW9uIHdpdGggaXRzIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBpbiBhIGNvbW1lcmNpYWwgcHJvZHVjdCBvZmZlcmluZy4gVGhlIG9ibGlnYXRpb25zIGluIHRoaXMgc2VjdGlvbiBkbyBub3QgYXBwbHkgdG8gYW55IGNsYWltcyBvciBMb3NzZXMgcmVsYXRpbmcgdG8gYW55IGFjdHVhbCBvciBhbGxlZ2VkIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBpbmZyaW5nZW1lbnQuIEluIG9yZGVyIHRvIHF1YWxpZnksIGFuIEluZGVtbmlmaWVkIENvbnRyaWJ1dG9yIG11c3Q6IGEpIHByb21wdGx5IG5vdGlmeSB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciBpbiB3cml0aW5nIG9mIHN1Y2ggY2xhaW0sIGFuZCBiKSBhbGxvdyB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciB0byBjb250cm9sLCBhbmQgY29vcGVyYXRlIHdpdGggdGhlIENvbW1lcmNpYWwgQ29udHJpYnV0b3IgaW4sIHRoZSBkZWZlbnNlIGFuZCBhbnkgcmVsYXRlZCBzZXR0bGVtZW50IG5lZ290aWF0aW9ucy4gVGhlIEluZGVtbmlmaWVkIENvbnRyaWJ1dG9yIG1heSBwYXJ0aWNpcGF0ZSBpbiBhbnkgc3VjaCBjbGFpbSBhdCBpdHMgb3duIGV4cGVuc2UuCisKK0ZvciBleGFtcGxlLCBhIENvbnRyaWJ1dG9yIG1pZ2h0IGluY2x1ZGUgdGhlIFByb2dyYW0gaW4gYSBjb21tZXJjaWFsIHByb2R1Y3Qgb2ZmZXJpbmcsIFByb2R1Y3QgWC4gVGhhdCBDb250cmlidXRvciBpcyB0aGVuIGEgQ29tbWVyY2lhbCBDb250cmlidXRvci4gSWYgdGhhdCBDb21tZXJjaWFsIENvbnRyaWJ1dG9yIHRoZW4gbWFrZXMgcGVyZm9ybWFuY2UgY2xhaW1zLCBvciBvZmZlcnMgd2FycmFudGllcyByZWxhdGVkIHRvIFByb2R1Y3QgWCwgdGhvc2UgcGVyZm9ybWFuY2UgY2xhaW1zIGFuZCB3YXJyYW50aWVzIGFyZSBzdWNoIENvbW1lcmNpYWwgQ29udHJpYnV0b3IncyByZXNwb25zaWJpbGl0eSBhbG9uZS4gVW5kZXIgdGhpcyBzZWN0aW9uLCB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciB3b3VsZCBoYXZlIHRvIGRlZmVuZCBjbGFpbXMgYWdhaW5zdCB0aGUgb3RoZXIgQ29udHJpYnV0b3JzIHJlbGF0ZWQgdG8gdGhvc2UgcGVyZm9ybWFuY2UgY2xhaW1zIGFuZCB3YXJyYW50aWVzLCBhbmQgaWYgYSBjb3VydCByZXF1aXJlcyBhbnkgb3RoZXIgQ29udHJpYnV0b3IgdG8gcGF5IGFueSBkYW1hZ2VzIGFzIGEgcmVzdWx0LCB0aGUgQ29tbWVyY2lhbCBDb250cmlidXRvciBtdXN0IHBheSB0aG9zZSBkYW1hZ2VzLgorCis1LiBOTyBXQVJSQU5UWQorCitFWENFUFQgQVMgRVhQUkVTU0xZIFNFVCBGT1JUSCBJTiBUSElTIEFHUkVFTUVOVCwgVEhFIFBST0dSQU0gSVMgUFJPVklERUQgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gRWFjaCBSZWNpcGllbnQgaXMgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIGFuZCBkaXN0cmlidXRpbmcgdGhlIFByb2dyYW0gYW5kIGFzc3VtZXMgYWxsIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBpdHMgZXhlcmNpc2Ugb2YgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50LCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHRoZSByaXNrcyBhbmQgY29zdHMgb2YgcHJvZ3JhbSBlcnJvcnMsIGNvbXBsaWFuY2Ugd2l0aCBhcHBsaWNhYmxlIGxhd3MsIGRhbWFnZSB0byBvciBsb3NzIG9mIGRhdGEsIHByb2dyYW1zIG9yIGVxdWlwbWVudCwgYW5kIHVuYXZhaWxhYmlsaXR5IG9yIGludGVycnVwdGlvbiBvZiBvcGVyYXRpb25zLgorCis2LiBESVNDTEFJTUVSIE9GIExJQUJJTElUWQorCitFWENFUFQgQVMgRVhQUkVTU0xZIFNFVCBGT1JUSCBJTiBUSElTIEFHUkVFTUVOVCwgTkVJVEhFUiBSRUNJUElFTlQgTk9SIEFOWSBDT05UUklCVVRPUlMgU0hBTEwgSEFWRSBBTlkgTElBQklMSVRZIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gTE9TVCBQUiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9SIERJU1RSSUJVVElPTiBPRiBUSEUgUFJPR1JBTSBPUiBUSEUgRVhFUkNJU0UgT0YgQU5ZIFJJR0hUUyBHUkFOVEVEIEhFUkVVTkRFUiwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRVMuCisKKzcuIEdFTkVSQUwKKworSWYgYW55IHByb3Zpc2lvbiBvZiB0aGlzIEFncmVlbWVudCBpcyBpbnZhbGlkIG9yIHVuZW5mb3JjZWFibGUgdW5kZXIgYXBwbGljYWJsZSBsYXcsIGl0IHNoYWxsIG5vdCBhZmZlY3QgdGhlIHZhbGlkaXR5IG9yIGVuZm9yY2VhYmlsaXR5IG9mIHRoZSByZW1haW5kZXIgb2YgdGhlIHRlcm1zIG9mIHRoaXMgQWdyZWVtZW50LCBhbmQgd2l0aG91dCBmdXJ0aGVyIGFjdGlvbiBieSB0aGUgcGFydGllcyBoZXJldG8sIHN1Y2ggcHJvdmlzaW9uIHNoYWxsIGJlIHJlZm9ybWVkIHRvIHRoZSBtaW5pbXVtIGV4dGVudCBuZWNlc3NhcnkgdG8gbWFrZSBzdWNoIHByb3Zpc2lvbiB2YWxpZCBhbmQgZW5mb3JjZWFibGUuCisKK0lmIFJlY2lwaWVudCBpbnN0aXR1dGVzIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYSBDb250cmlidXRvciB3aXRoIHJlc3BlY3QgdG8gYSBwYXRlbnQgYXBwbGljYWJsZSB0byBzb2Z0d2FyZSAoaW5jbHVkaW5nIGEgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCksIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcyBncmFudGVkIGJ5IHRoYXQgQ29udHJpYnV0b3IgdG8gc3VjaCBSZWNpcGllbnQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgc2hhbGwgdGVybWluYXRlIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4gSW4gYWRkaXRpb24sIGlmIFJlY2lwaWVudCBpbnN0aXR1dGVzIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgUHJvZ3JhbSBpdHNlbGYgKGV4Y2x1ZGluZyBjb21iaW5hdGlvbnMgb2YgdGhlIFByb2dyYW0gd2l0aCBvdGhlciBzb2Z0d2FyZSBvciBoYXJkd2FyZSkgaW5mcmluZ2VzIHN1Y2ggUmVjaXBpZW50J3MgcGF0ZW50KHMpLCB0aGVuIHN1Y2ggUmVjaXBpZW50J3MgcmlnaHRzIGdyYW50ZWQgdW5kZXIgU2VjdGlvbiAyKGIpIHNoYWxsIHRlcm1pbmF0ZSBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKK0FsbCBSZWNpcGllbnQncyByaWdodHMgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgc2hhbGwgdGVybWluYXRlIGlmIGl0IGZhaWxzIHRvIGNvbXBseSB3aXRoIGFueSBvZiB0aGUgbWF0ZXJpYWwgdGVybXMgb3IgY29uZGl0aW9ucyBvZiB0aGlzIEFncmVlbWVudCBhbmQgZG9lcyBub3QgY3VyZSBzdWNoIGZhaWx1cmUgaW4gYSByZWFzb25hYmxlIHBlcmlvZCBvZiB0aW1lIGFmdGVyIGJlY29taW5nIGF3YXJlIG9mIHN1Y2ggbm9uY29tcGxpYW5jZS4gSWYgYWxsIFJlY2lwaWVudCdzIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCB0ZXJtaW5hdGUsIFJlY2lwaWVudCBhZ3JlZXMgdG8gY2Vhc2UgdXNlIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0gYXMgc29vbiBhcyByZWFzb25hYmx5IHByYWN0aWNhYmxlLiBIb3dldmVyLCBSZWNpcGllbnQncyBvYmxpZ2F0aW9ucyB1bmRlciB0aGlzIEFncmVlbWVudCBhbmQgYW55IGxpY2Vuc2VzIGdyYW50ZWQgYnkgUmVjaXBpZW50IHJlbGF0aW5nIHRvIHRoZSBQcm9ncmFtIHNoYWxsIGNvbnRpbnVlIGFuZCBzdXJ2aXZlLgorCitFdmVyeW9uZSBpcyBwZXJtaXR0ZWQgdG8gY29weSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGJ1dCBpbiBvcmRlciB0byBhdm9pZCBpbmNvbnNpc3RlbmN5IHRoZSBBZ3JlZW1lbnQgaXMgY29weXJpZ2h0ZWQgYW5kIG1heSBvbmx5IGJlIG1vZGlmaWVkIGluIHRoZSBmb2xsb3dpbmcgbWFubmVyLiBUaGUgQWdyZWVtZW50IFN0ZXdhcmQgcmVzZXJ2ZXMgdGhlIHJpZ2h0IHRvIHB1Ymxpc2ggbmV3IHZlcnNpb25zIChpbmNsdWRpbmcgcmV2aXNpb25zKSBvZiB0aGlzIEFncmVlbWVudCBmcm9tIHRpbWUgdG8gdGltZS4gTm8gb25lIG90aGVyIHRoYW4gdGhlIEFncmVlbWVudCBTdGV3YXJkIGhhcyB0aGUgcmlnaHQgdG8gbW9kaWZ5IHRoaXMgQWdyZWVtZW50LiBJQk0gaXMgdGhlIGluaXRpYWwgQWdyZWVtZW50IFN0ZXdhcmQuIElCTSBtYXkgYXNzaWduIHRoZSByZXNwb25zaWJpbGl0eSB0byBzZXJ2ZSBhcyB0aGUgQWdyZWVtZW50IFN0ZXdhcmQgdG8gYSBzdWl0YWJsZSBzZXBhcmF0ZSBlbnRpdHkuIEVhY2ggbmV3IHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB3aWxsIGJlIGdpdmVuIGEgZGlzdGluZ3Vpc2hpbmcgdmVyc2lvbiBudW1iZXIuIFRoZSBQcm9ncmFtIChpbmNsdWRpbmcgQ29udHJpYnV0aW9ucykgbWF5IGFsd2F5cyBiZSBkaXN0cmlidXRlZCBzdWJqZWN0IHRvIHRoZSB2ZXJzaW9uIG9mIHRoZSBBZ3JlZW1lbnQgdW5kZXIgd2hpY2ggaXQgd2FzIHJlY2VpdmVkLiBJbiBhZGRpdGlvbiwgYWZ0ZXIgYSBuZXcgdmVyc2lvbiBvZiB0aGUgQWdyZWVtZW50IGlzIHB1Ymxpc2hlZCwgQ29udHJpYnV0b3IgbWF5IGVsZWN0IHRvIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gKGluY2x1ZGluZyBpdHMgQ29udHJpYnV0aW9ucykgdW5kZXIgdGhlIG5ldyB2ZXJzaW9uLiBFeGNlcHQgYXMgZXhwcmVzc2x5IHN0YXRlZCBpbiBTZWN0aW9ucyAyKGEpIGFuZCAyKGIpIGFib3ZlLCBSZWNpcGllbnQgcmVjZWl2ZXMgbm8gcmlnaHRzIG9yIGxpY2Vuc2VzIHRvIHRoZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkgb2YgYW55IENvbnRyaWJ1dG9yIHVuZGVyIHRoaXMgQWdyZWVtZW50LCB3aGV0aGVyIGV4cHJlc3NseSwgYnkgaW1wbGljYXRpb24sIGVzdG9wcGVsIG9yIG90aGVyd2lzZS4gQWxsIHJpZ2h0cyBpbiB0aGUgUHJvZ3JhbSBub3QgZXhwcmVzc2x5IGdyYW50ZWQgdW5kZXIgdGhpcyBBZ3JlZW1lbnQgYXJlIHJlc2VydmVkLgorCitUaGlzIEFncmVlbWVudCBpcyBnb3Zlcm5lZCBieSB0aGUgbGF3cyBvZiB0aGUgU3RhdGUgb2YgTmV3IFlvcmsgYW5kIHRoZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkgbGF3cyBvZiB0aGUgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhLiBObyBwYXJ0eSB0byB0aGlzIEFncmVlbWVudCB3aWxsIGJyaW5nIGEgbGVnYWwgYWN0aW9uIHVuZGVyIHRoaXMgQWdyZWVtZW50IG1vcmUgdGhhbiBvbmUgeWVhciBhZnRlciB0aGUgY2F1c2Ugb2YgYWN0aW9uIGFyb3NlLiBFYWNoIHBhcnR5IHdhaXZlcyBpdHMgcmlnaHRzIHRvIGEganVyeSB0cmlhbCBpbiBhbnkgcmVzdWx0aW5nIGxpdGlnYXRpb24uCitPRklUUyksIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT1IgRElTVFJJQlVUSU9OIE9GIFRIRSBQUk9HUkFNIE9SIFRIRSBFWEVSQ0lTRSBPRiBBTlkgUklHSFRTIEdSQU5URUQgSEVSRVVOREVSLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFUy4KKworNy4gR0VORVJBTAorCitJZiBhbnkgcHJvdmlzaW9uIG9mIHRoaXMgQWdyZWVtZW50IGlzIGludmFsaWQgb3IgdW5lbmZvcmNlYWJsZSB1bmRlciBhcHBsaWNhYmxlIGxhdywgaXQgc2hhbGwgbm90IGFmZmVjdCB0aGUgdmFsaWRpdHkgb3IgZW5mb3JjZWFiaWxpdHkgb2YgdGhlIHJlbWFpbmRlciBvZiB0aGUgdGVybXMgb2YgdGhpcyBBZ3JlZW1lbnQsIGFuZCB3aXRob3V0IGZ1cnRoZXIgYWN0aW9uIGJ5IHRoZSBwYXJ0aWVzIGhlcmV0bywgc3VjaCBwcm92aXNpb24gc2hhbGwgYmUgcmVmb3JtZWQgdG8gdGhlIG1pbmltdW0gZXh0ZW50IG5lY2Vzc2FyeSB0byBtYWtlIHN1Y2ggcHJvdmlzaW9uIHZhbGlkIGFuZCBlbmZvcmNlYWJsZS4KKworSWYgUmVjaXBpZW50IGluc3RpdHV0ZXMgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhIENvbnRyaWJ1dG9yIHdpdGggcmVzcGVjdCB0byBhIHBhdGVudCBhcHBsaWNhYmxlIHRvIHNvZnR3YXJlIChpbmNsdWRpbmcgYSBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzIGdyYW50ZWQgYnkgdGhhdCBDb250cmlidXRvciB0byBzdWNoIFJlY2lwaWVudCB1bmRlciB0aGlzIEFncmVlbWVudCBzaGFsbCB0ZXJtaW5hdGUgYXMgb2YgdGhlIGRhdGUgc3VjaCBsaXRpZ2F0aW9uIGlzIGZpbGVkLiBJbiBhZGRpdGlvbiwgaWYgUmVjaXBpZW50IGluc3RpdHV0ZXMgcGF0ZW50IGxpdGlnYXRpb24gYWdhaW5zdCBhbnkgZW50aXR5IChpbmNsdWRpbmcgYSBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBQcm9ncmFtIGl0c2VsZiAoZXhjbHVkaW5nIGNvbWJpbmF0aW9ucyBvZiB0aGUgUHJvZ3JhbSB3aXRoIG90aGVyIHNvZnR3YXJlIG9yIGhhcmR3YXJlKSBpbmZyaW5nZXMgc3VjaCBSZWNpcGllbnQncyBwYXRlbnQocyksIHRoZW4gc3VjaCBSZWNpcGllbnQncyByaWdodHMgZ3JhbnRlZCB1bmRlciBTZWN0aW9uIDIoYikgc2hhbGwgdGVybWluYXRlIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4KKworQWxsIFJlY2lwaWVudCdzIHJpZ2h0cyB1bmRlciB0aGlzIEFncmVlbWVudCBzaGFsbCB0ZXJtaW5hdGUgaWYgaXQgZmFpbHMgdG8gY29tcGx5IHdpdGggYW55IG9mIHRoZSBtYXRlcmlhbCB0ZXJtcyBvciBjb25kaXRpb25zIG9mIHRoaXMgQWdyZWVtZW50IGFuZCBkb2VzIG5vdCBjdXJlIHN1Y2ggZmFpbHVyZSBpbiBhIHJlYXNvbmFibGUgcGVyaW9kIG9mIHRpbWUgYWZ0ZXIgYmVjb21pbmcgYXdhcmUgb2Ygc3VjaCBub25jb21wbGlhbmNlLiBJZiBhbGwgUmVjaXBpZW50J3MgcmlnaHRzIHVuZGVyIHRoaXMgQWdyZWVtZW50IHRlcm1pbmF0ZSwgUmVjaXBpZW50IGFncmVlcyB0byBjZWFzZSB1c2UgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZ3JhbSBhcyBzb29uIGFzIHJlYXNvbmFibHkgcHJhY3RpY2FibGUuIEhvd2V2ZXIsIFJlY2lwaWVudCdzIG9ibGlnYXRpb25zIHVuZGVyIHRoaXMgQWdyZWVtZW50IGFuZCBhbnkgbGljZW5zZXMgZ3JhbnRlZCBieSBSZWNpcGllbnQgcmVsYXRpbmcgdG8gdGhlIFByb2dyYW0gc2hhbGwgY29udGludWUgYW5kIHN1cnZpdmUuCisKK0V2ZXJ5b25lIGlzIHBlcm1pdHRlZCB0byBjb3B5IGFuZCBkaXN0cmlidXRlIGNvcGllcyBvZiB0aGlzIEFncmVlbWVudCwgYnV0IGluIG9yZGVyIHRvIGF2b2lkIGluY29uc2lzdGVuY3kgdGhlIEFncmVlbWVudCBpcyBjb3B5cmlnaHRlZCBhbmQgbWF5IG9ubHkgYmUgbW9kaWZpZWQgaW4gdGhlIGZvbGxvd2luZyBtYW5uZXIuIFRoZSBBZ3JlZW1lbnQgU3Rld2FyZCByZXNlcnZlcyB0aGUgcmlnaHQgdG8gcHVibGlzaCBuZXcgdmVyc2lvbnMgKGluY2x1ZGluZyByZXZpc2lvbnMpIG9mIHRoaXMgQWdyZWVtZW50IGZyb20gdGltZSB0byB0aW1lLiBObyBvbmUgb3RoZXIgdGhhbiB0aGUgQWdyZWVtZW50IFN0ZXdhcmQgaGFzIHRoZSByaWdodCB0byBtb2RpZnkgdGhpcyBBZ3JlZW1lbnQuIElCTSBpcyB0aGUgaW5pdGlhbCBBZ3JlZW1lbnQgU3Rld2FyZC4gSUJNIG1heSBhc3NpZ24gdGhlIHJlc3BvbnNpYmlsaXR5IHRvIHNlcnZlIGFzIHRoZSBBZ3JlZW1lbnQgU3Rld2FyZCB0byBhIHN1aXRhYmxlIHNlcGFyYXRlIGVudGl0eS4gRWFjaCBuZXcgdmVyc2lvbiBvZiB0aGUgQWdyZWVtZW50IHdpbGwgYmUgZ2l2ZW4gYSBkaXN0aW5ndWlzaGluZyB2ZXJzaW9uIG51bWJlci4gVGhlIFByb2dyYW0gKGluY2x1ZGluZyBDb250cmlidXRpb25zKSBtYXkgYWx3YXlzIGJlIGRpc3RyaWJ1dGVkIHN1YmplY3QgdG8gdGhlIHZlcnNpb24gb2YgdGhlIEFncmVlbWVudCB1bmRlciB3aGljaCBpdCB3YXMgcmVjZWl2ZWQuIEluIGFkZGl0aW9uLCBhZnRlciBhIG5ldyB2ZXJzaW9uIG9mIHRoZSBBZ3JlZW1lbnQgaXMgcHVibGlzaGVkLCBDb250cmlidXRvciBtYXkgZWxlY3QgdG8gZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSAoaW5jbHVkaW5nIGl0cyBDb250cmlidXRpb25zKSB1bmRlciB0aGUgbmV3IHZlcnNpb24uIEV4Y2VwdCBhcyBleHByZXNzbHkgc3RhdGVkIGluIFNlY3Rpb25zIDIoYSkgYW5kIDIoYikgYWJvdmUsIFJlY2lwaWVudCByZWNlaXZlcyBubyByaWdodHMgb3IgbGljZW5zZXMgdG8gdGhlIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBvZiBhbnkgQ29udHJpYnV0b3IgdW5kZXIgdGhpcyBBZ3JlZW1lbnQsIHdoZXRoZXIgZXhwcmVzc2x5LCBieSBpbXBsaWNhdGlvbiwgZXN0b3BwZWwgb3Igb3RoZXJ3aXNlLiBBbGwgcmlnaHRzIGluIHRoZSBQcm9ncmFtIG5vdCBleHByZXNzbHkgZ3JhbnRlZCB1bmRlciB0aGlzIEFncmVlbWVudCBhcmUgcmVzZXJ2ZWQuCisKK1RoaXMgQWdyZWVtZW50IGlzIGdvdmVybmVkIGJ5IHRoZSBsYXdzIG9mIHRoZSBTdGF0ZSBvZiBOZXcgWW9yayBhbmQgdGhlIGludGVsbGVjdHVhbCBwcm9wZXJ0eSBsYXdzIG9mIHRoZSBVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EuIE5vIHBhcnR5IHRvIHRoaXMgQWdyZWVtZW50IHdpbGwgYnJpbmcgYSBsZWdhbCBhY3Rpb24gdW5kZXIgdGhpcyBBZ3JlZW1lbnQgbW9yZSB0aGFuIG9uZSB5ZWFyIGFmdGVyIHRoZSBjYXVzZSBvZiBhY3Rpb24gYXJvc2UuIEVhY2ggcGFydHkgd2FpdmVzIGl0cyByaWdodHMgdG8gYSBqdXJ5IHRyaWFsIGluIGFueSByZXN1bHRpbmcgbGl0aWdhdGlvbi4KZGlmZiAtLWdpdCBhL2xpYi9qdW5pdC0zLjguMS5qYXIgYi9saWIvanVuaXQtMy44LjEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3NGQ3MWUKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanVuaXQtMy44LjEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9saWJ0aHJpZnQtcjc3MTU4Ny5qYXIgYi9saWIvbGlidGhyaWZ0LXI3NzE1ODcuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5ODhkYTcKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvbGlidGhyaWZ0LXI3NzE1ODcuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9sb2c0ai0xLjIuMTUuamFyIGIvbGliL2xvZzRqLTEuMi4xNS5qYXIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzkzMGE2YQotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9sb2c0ai0xLjIuMTUuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9sdWNlbmUtY29yZS0yLjIuMC5qYXIgYi9saWIvbHVjZW5lLWNvcmUtMi4yLjAuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0Njk0ODEKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvbHVjZW5lLWNvcmUtMi4yLjAuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi9zZXJ2bGV0LWFwaS5qYXIgYi9saWIvc2VydmxldC1hcGkuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ZGFiMzAKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvc2VydmxldC1hcGkuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi94bWxlbmMtMC41Mi5qYXIgYi9saWIveG1sZW5jLTAuNTIuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjNTY4YjQKLS0tIC9kZXYvbnVsbAorKysgYi9saWIveG1sZW5jLTAuNTIuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL2xpYi96b29rZWVwZXItMy4xLjAtaGJhc2UtMTI0MS5qYXIgYi9saWIvem9va2VlcGVyLTMuMS4wLWhiYXNlLTEyNDEuamFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxZTJhYWQKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvem9va2VlcGVyLTMuMS4wLWhiYXNlLTEyNDEuamFyCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL2ZvcnJlc3QucHJvcGVydGllcyBiL3NyYy9kb2NzL2ZvcnJlc3QucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNGViYzUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3MvZm9ycmVzdC5wcm9wZXJ0aWVzCkBAIC0wLDAgKzEsMTA0IEBACisjIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKKyMjIyMjIyMjIyMjIyMjCisjIFByb3BlcnRpZXMgdXNlZCBieSBmb3JyZXN0LmJ1aWxkLnhtbCBmb3IgYnVpbGRpbmcgdGhlIHdlYnNpdGUKKyMgVGhlc2UgYXJlIHRoZSBkZWZhdWx0cywgdW4tY29tbWVudCB0aGVtIGlmIHlvdSBuZWVkIHRvIGNoYW5nZSB0aGVtLgorIyMjIyMjIyMjIyMjIyMKKworIyBQcmludHMgb3V0IGEgc3VtbWFyeSBvZiBGb3JyZXN0IHNldHRpbmdzIGZvciB0aGlzIHByb2plY3QKKyNmb3JyZXN0LmVjaG89dHJ1ZSAKKworIyBQcm9qZWN0IG5hbWUgKHVzZWQgdG8gbmFtZSAud2FyIGZpbGUpCisjcHJvamVjdC5uYW1lPW15LXByb2plY3QKKworIyBTcGVjaWZpZXMgbmFtZSBvZiBGb3JyZXN0IHNraW4gdG8gdXNlCisjcHJvamVjdC5za2luPXRpZ3JpcworI3Byb2plY3Quc2tpbj1wZWx0CisKKyMgY29tbWEgc2VwYXJhdGVkIGxpc3QsIGZpbGU6Ly8gaXMgc3VwcG9ydGVkCisjZm9ycmVzdC5za2lucy5kZXNjcmlwdG9ycz1odHRwOi8vZm9ycmVzdC5hcGFjaGUub3JnL3NraW5zL3NraW5zLnhtbCxmaWxlOi8vL2M6L215c2tpbnMvc2tpbnMueG1sCisKKyMjIyMjIyMjIyMjIyMjCisjIGJlaGF2aW91cmFsIHByb3BlcnRpZXMKKyNwcm9qZWN0Lm1lbnUtc2NoZW1lPXRhYl9hdHRyaWJ1dGVzCisjcHJvamVjdC5tZW51LXNjaGVtZT1kaXJlY3RvcmllcworCisjIyMjIyMjIyMjIyMjIworIyBsYXlvdXQgcHJvcGVydGllcworCisjIFByb3BlcnRpZXMgdGhhdCBjYW4gYmUgc2V0IHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGxvY2F0aW9ucworIworIyBQYXJlbnQgcHJvcGVydGllcyBtdXN0IGJlIHNldC4gVGhpcyB1c3VhbGx5IG1lYW5zIHVuY29tbWVudGluZworIyBwcm9qZWN0LmNvbnRlbnQtZGlyIGlmIGFueSBvdGhlciBwcm9wZXJ0eSB1c2luZyBpdCBpcyB1bmNvbW1lbnRlZAorCisjcHJvamVjdC5zdGF0dXM9c3RhdHVzLnhtbAorI3Byb2plY3QuY29udGVudC1kaXI9c3JjL2RvY3VtZW50YXRpb24KKyNwcm9qZWN0LnJhdy1jb250ZW50LWRpcj0ke3Byb2plY3QuY29udGVudC1kaXJ9L2NvbnRlbnQKKyNwcm9qZWN0LmNvbmYtZGlyPSR7cHJvamVjdC5jb250ZW50LWRpcn0vY29uZgorI3Byb2plY3Quc2l0ZW1hcC1kaXI9JHtwcm9qZWN0LmNvbnRlbnQtZGlyfQorI3Byb2plY3QueGRvY3MtZGlyPSR7cHJvamVjdC5jb250ZW50LWRpcn0vY29udGVudC94ZG9jcworI3Byb2plY3QucmVzb3VyY2VzLWRpcj0ke3Byb2plY3QuY29udGVudC1kaXJ9L3Jlc291cmNlcworI3Byb2plY3Quc3R5bGVzaGVldHMtZGlyPSR7cHJvamVjdC5yZXNvdXJjZXMtZGlyfS9zdHlsZXNoZWV0cworI3Byb2plY3QuaW1hZ2VzLWRpcj0ke3Byb2plY3QucmVzb3VyY2VzLWRpcn0vaW1hZ2VzCisjcHJvamVjdC5zY2hlbWEtZGlyPSR7cHJvamVjdC5yZXNvdXJjZXMtZGlyfS9zY2hlbWEKKyNwcm9qZWN0LnNraW5zLWRpcj0ke3Byb2plY3QuY29udGVudC1kaXJ9L3NraW5zCisjcHJvamVjdC5za2luY29uZj0ke3Byb2plY3QuY29udGVudC1kaXJ9L3NraW5jb25mLnhtbAorI3Byb2plY3QubGliLWRpcj0ke3Byb2plY3QuY29udGVudC1kaXJ9L2xpYgorI3Byb2plY3QuY2xhc3Nlcy1kaXI9JHtwcm9qZWN0LmNvbnRlbnQtZGlyfS9jbGFzc2VzCisjcHJvamVjdC50cmFuc2xhdGlvbnMtZGlyPSR7cHJvamVjdC5jb250ZW50LWRpcn0vdHJhbnNsYXRpb25zCisKKyMjIyMjIyMjIyMjIyMjCisjIHZhbGlkYXRpb24gcHJvcGVydGllcworCisjIFRoaXMgc2V0IG9mIHByb3BlcnRpZXMgZGV0ZXJtaW5lIGlmIHZhbGlkYXRpb24gaXMgcGVyZm9ybWVkCisjIFZhbHVlcyBhcmUgaW5oZXJpdGVkIHVubGVzcyBvdmVycmlkZGVuLgorIyBlLmcuIGlmIGZvcnJlc3QudmFsaWRhdGU9ZmFsc2UgdGhlbiBhbGwgb3RoZXJzIGFyZSBmYWxzZSB1bmxlc3Mgc2V0IHRvIHRydWUuCisjZm9ycmVzdC52YWxpZGF0ZT10cnVlCisjZm9ycmVzdC52YWxpZGF0ZS54ZG9jcz0ke2ZvcnJlc3QudmFsaWRhdGV9CisjZm9ycmVzdC52YWxpZGF0ZS5za2luY29uZj0ke2ZvcnJlc3QudmFsaWRhdGV9CisjZm9ycmVzdC52YWxpZGF0ZS5zaXRlbWFwPSR7Zm9ycmVzdC52YWxpZGF0ZX0KKyNmb3JyZXN0LnZhbGlkYXRlLnN0eWxlc2hlZXRzPSR7Zm9ycmVzdC52YWxpZGF0ZX0KKyNmb3JyZXN0LnZhbGlkYXRlLnNraW5zPSR7Zm9ycmVzdC52YWxpZGF0ZX0KKyNmb3JyZXN0LnZhbGlkYXRlLnNraW5zLnN0eWxlc2hlZXRzPSR7Zm9ycmVzdC52YWxpZGF0ZS5za2luc30KKworIyAqLmZhaWxvbmVycm9yPSh0cnVlfGZhbHNlKSAtIHN0b3Agd2hlbiBhbiBYTUwgZmlsZSBpcyBpbnZhbGlkCisjZm9ycmVzdC52YWxpZGF0ZS5mYWlsb25lcnJvcj10cnVlCisKKyMgKi5leGNsdWRlcz0ocGF0dGVybikgLSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBwYXRoIHBhdHRlcm5zIHRvIG5vdCB2YWxpZGF0ZQorIyBlLmcuCisjZm9ycmVzdC52YWxpZGF0ZS54ZG9jcy5leGNsdWRlcz1zYW1wbGVzL3N1YmRpci8qKiwgc2FtcGxlcy9mYXEueG1sCisjZm9ycmVzdC52YWxpZGF0ZS54ZG9jcy5leGNsdWRlcz0KKworCisjIyMjIyMjIyMjIyMjIworIyBHZW5lcmFsIEZvcnJlc3QgcHJvcGVydGllcworCisjIFRoZSBVUkwgdG8gc3RhcnQgY3Jhd2xpbmcgZnJvbQorI3Byb2plY3Quc3RhcnQtdXJpPWxpbmttYXAuaHRtbAorIyBTZXQgbG9nZ2luZyBsZXZlbCBmb3IgbWVzc2FnZXMgcHJpbnRlZCB0byB0aGUgY29uc29sZQorIyAoREVCVUcsIElORk8sIFdBUk4sIEVSUk9SLCBGQVRBTF9FUlJPUikKKyNwcm9qZWN0LmRlYnVnbGV2ZWw9RVJST1IKKyMgTWF4IG1lbW9yeSB0byBhbGxvY2F0ZSB0byBKYXZhCisjZm9ycmVzdC5tYXhtZW1vcnk9NjRtCisjIEFueSBvdGhlciBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgSlZNLiBGb3IgZXhhbXBsZSwgdG8gcnVuIG9uIGFuIFgtbGVzcworIyBzZXJ2ZXIsIHNldCB0byAtRGphdmEuYXd0LmhlYWRsZXNzPXRydWUKKyNmb3JyZXN0Lmp2bWFyZ3M9CisjIFRoZSBidWd0cmFja2luZyBVUkwgLSB0aGUgaXNzdWUgbnVtYmVyIHdpbGwgYmUgYXBwZW5kZWQKKyNwcm9qZWN0LmJ1Z3RyYWNraW5nLXVybD1odHRwOi8vaXNzdWVzLmFwYWNoZS5vcmcvYnVnemlsbGEvc2hvd19idWcuY2dpP2lkPQorI3Byb2plY3QuYnVndHJhY2tpbmctdXJsPWh0dHA6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS8KKyMgVGhlIGlzc3VlcyBsaXN0IGFzIHJzcworI3Byb2plY3QuaXNzdWVzLXJzcy11cmw9CisjSTE4biBQcm9wZXJ0eSBvbmx5IHdvcmtzIGZvciB0aGUgImZvcnJlc3QgcnVuIiB0YXJnZXQuCisjcHJvamVjdC5pMThuPXRydWUKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL1JFQURNRS50eHQgYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9SRUFETUUudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliYzI2MWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9SRUFETUUudHh0CkBAIC0wLDAgKzEsNyBAQAorVGhpcyBpcyB0aGUgYmFzZSBkb2N1bWVudGF0aW9uIGRpcmVjdG9yeS4KKworc2tpbmNvbmYueG1sICAgICAjIFRoaXMgZmlsZSBjdXN0b21pemVzIEZvcnJlc3QgZm9yIHlvdXIgcHJvamVjdC4gSW4gaXQsIHlvdQorICAgICAgICAgICAgICAgICAjIHRlbGwgZm9ycmVzdCB0aGUgcHJvamVjdCBuYW1lLCBsb2dvLCBjb3B5cmlnaHQgaW5mbywgZXRjCisKK3NpdGVtYXAueG1hcCAgICAgIyBPcHRpb25hbC4gVGhpcyBzaXRlbWFwIGlzIGNvbnN1bHRlZCBiZWZvcmUgYWxsIGNvcmUgc2l0ZW1hcHMuCisgICAgICAgICAgICAgICAgICMgU2VlIGh0dHA6Ly9mb3JyZXN0LmFwYWNoZS5vcmcvZG9jcy9wcm9qZWN0LXNpdGVtYXAuaHRtbApkaWZmIC0tZ2l0IGEvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY2xhc3Nlcy9DYXRhbG9nTWFuYWdlci5wcm9wZXJ0aWVzIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY2xhc3Nlcy9DYXRhbG9nTWFuYWdlci5wcm9wZXJ0aWVzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjMDYwYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9jbGFzc2VzL0NhdGFsb2dNYW5hZ2VyLnByb3BlcnRpZXMKQEAgLTAsMCArMSwzNyBAQAorIyBDb3B5cmlnaHQgMjAwMi0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisjPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyMgQ2F0YWxvZ01hbmFnZXIucHJvcGVydGllcworIworIyBUaGlzIGlzIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMgZmlsZSBmb3IgQXBhY2hlIEZvcnJlc3QuCisjIFRoaXMgZmFjaWxpdGF0ZXMgbG9jYWwgY29uZmlndXJhdGlvbiBvZiBhcHBsaWNhdGlvbi1zcGVjaWZpYyBjYXRhbG9ncy4KKyMKKyMgU2VlIHRoZSBBcGFjaGUgRm9ycmVzdCBkb2N1bWVudGF0aW9uOgorIyBodHRwOi8vZm9ycmVzdC5hcGFjaGUub3JnL2RvY3MveW91ci1wcm9qZWN0Lmh0bWwKKyMgaHR0cDovL2ZvcnJlc3QuYXBhY2hlLm9yZy9kb2NzL3ZhbGlkYXRpb24uaHRtbAorCisjIHZlcmJvc2l0eSAuLi4gbGV2ZWwgb2YgbWVzc2FnZXMgZm9yIHN0YXR1cy9kZWJ1ZworIyBTZWUgZm9ycmVzdC9zcmMvY29yZS9jb250ZXh0L1dFQi1JTkYvY29jb29uLnhjb25mCisKKyMgY2F0YWxvZ3MgLi4uIGxpc3Qgb2YgYWRkaXRpb25hbCBjYXRhbG9ncyB0byBsb2FkCisjICAoTm90ZSB0aGF0IEFwYWNoZSBGb3JyZXN0IHdpbGwgYXV0b21hdGljYWxseSBsb2FkIGl0cyBvd24gZGVmYXVsdCBjYXRhbG9nCisjICBmcm9tIHNyYy9jb3JlL2NvbnRleHQvcmVzb3VyY2VzL3NjaGVtYS9jYXRhbG9nLnhjYXQpCisjIHVzZSBmdWxsIHBhdGhuYW1lcworIyBwYXRobmFtZSBzZXBhcmF0b3IgaXMgYWx3YXlzIHNlbWktY29sb24gKDspIHJlZ2FyZGxlc3Mgb2Ygb3BlcmF0aW5nIHN5c3RlbQorIyBkaXJlY3Rvcnkgc2VwYXJhdG9yIGlzIGFsd2F5cyBzbGFzaCAoLykgcmVnYXJkbGVzcyBvZiBvcGVyYXRpbmcgc3lzdGVtCisjCisjY2F0YWxvZ3M9L2hvbWUvbWUvZm9ycmVzdC9teS1zaXRlL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9zY2hlbWEvY2F0YWxvZy54Y2F0CitjYXRhbG9ncz0KKwpkaWZmIC0tZ2l0IGEvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy9pbmRleC54bWwgYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9jb250ZW50L3hkb2NzL2luZGV4LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjI1YTg5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy9pbmRleC54bWwKQEAgLTAsMCArMSw0MCBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCisgIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisKKyAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCFET0NUWVBFIGRvY3VtZW50IFBVQkxJQyAiLS8vQVBBQ0hFLy9EVEQgRG9jdW1lbnRhdGlvbiBWMi4wLy9FTiIgImh0dHA6Ly9mb3JyZXN0LmFwYWNoZS5vcmcvZHRkL2RvY3VtZW50LXYyMC5kdGQiPgorCis8ZG9jdW1lbnQ+CisgIAorICA8aGVhZGVyPgorICAgIDx0aXRsZT5IQmFzZSBEb2N1bWVudGF0aW9uPC90aXRsZT4KKyAgPC9oZWFkZXI+CisgIAorICA8Ym9keT4KKyAgICA8cD4KKyAgICBUaGUgZm9sbG93aW5nIGRvY3VtZW50cyBwcm92aWRlIGNvbmNlcHRzIGFuZCBwcm9jZWR1cmVzIHRoYXQgd2lsbCBoZWxwIHlvdSAKKyAgICBnZXQgc3RhcnRlZCB1c2luZyBIQmFzZS4gSWYgeW91IGhhdmUgbW9yZSBxdWVzdGlvbnMsIHlvdSBjYW4gYXNrIHRoZSAKKyAgICA8YSBocmVmPSJleHQ6bGlzdHMiPm1haWxpbmcgbGlzdDwvYT4gb3IgYnJvd3NlIHRoZSBhcmNoaXZlcy4KKyAgICA8L3A+CisgICAgPHVsPgorICAgICAgPGxpPjxhIGhyZWY9ImV4dDphcGkvc3RhcnRlZCI+R2V0dGluZyBTdGFydGVkPC9hPjwvbGk+CisgICAgICA8bGk+PGEgaHJlZj0iZXh0OmFwaS9pbmRleCI+QVBJIERvY3M8L2E+PC9saT4KKyAgICAgIDxsaT48YSBocmVmPSJleHQ6d2lraSI+V2lraTwvYT48L2xpPgorICAgICAgPGxpPjxhIGhyZWY9ImV4dDpmYXEiPkZBUTwvYT48L2xpPgorICAgIDwvdWw+CisgIDwvYm9keT4KKyAgCis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy9tZXRyaWNzLnhtbCBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL2NvbnRlbnQveGRvY3MvbWV0cmljcy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFhY2FlOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL2NvbnRlbnQveGRvY3MvbWV0cmljcy54bWwKQEAgLTAsMCArMSw2NyBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCisgIENvcHlyaWdodCAyMDAyLTIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisKKyAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCFET0NUWVBFIGRvY3VtZW50IFBVQkxJQyAiLS8vQVBBQ0hFLy9EVEQgRG9jdW1lbnRhdGlvbiBWMi4wLy9FTiIKKyAgICAgICAgICAiaHR0cDovL2ZvcnJlc3QuYXBhY2hlLm9yZy9kdGQvZG9jdW1lbnQtdjIwLmR0ZCI+CisKKworPGRvY3VtZW50PgorCisgIDxoZWFkZXI+CisgICAgPHRpdGxlPiAKKyAgICAgIEhCYXNlIE1ldHJpY3MKKyAgICA8L3RpdGxlPgorICA8L2hlYWRlcj4KKworICA8Ym9keT4KKyAgICA8c2VjdGlvbj4KKyAgICAgIDx0aXRsZT4gSW50cm9kdWN0aW9uIDwvdGl0bGU+CisgICAgICA8cD4KKyAgICAgIEhCYXNlIGVtaXRzIEhhZG9vcCA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9kb2NzL2N1cnJlbnQvYXBpL29yZy9hcGFjaGUvaGFkb29wL21ldHJpY3MvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm1ldHJpY3M8L2E+LgorICAgICAgPC9wPgorICAgICAgPC9zZWN0aW9uPgorICAgICAgPHNlY3Rpb24+CisgICAgICAgIDx0aXRsZT5IT1dUTzwvdGl0bGU+CisgICAgICA8cD5GaXJzdCByZWFkIHVwIG9uIEhhZG9vcCA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9kb2NzL2N1cnJlbnQvYXBpL29yZy9hcGFjaGUvaGFkb29wL21ldHJpY3MvcGFja2FnZS1zdW1tYXJ5Lmh0bWwiPm1ldHJpY3M8L2E+LgorICAgICAgSWYgeW91IGFyZSB1c2luZyBnYW5nbGlhLCB0aGUgPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvR2FuZ2xpYU1ldHJpY3MiPkdhbmdsaWFNZXRyaWNzPC9hPgorICAgICAgd2lraSBwYWdlIGlzIHVzZWZ1bCByZWFkLjwvcD4KKyAgICAgIDxwPlRvIGhhdmUgSEJhc2UgZW1pdCBtZXRyaWNzLCBlZGl0IDxjb2RlPiRIQkFTRV9IT01FL2NvbmYvaGFkb29wLW1ldHJpY3MucHJvcGVydGllczwvY29kZT4KKyAgICAgIGFuZCBlbmFibGUgbWV0cmljICdjb250ZXh0cycgcGVyIHBsdWdpbi4gIEFzIG9mIHRoaXMgd3JpdGluZywgaGFkb29wIHN1cHBvcnRzCisgICAgICA8c3Ryb25nPmZpbGU8L3N0cm9uZz4gYW5kIDxzdHJvbmc+Z2FuZ2xpYTwvc3Ryb25nPiBwbHVnaW5zLgorICAgICAgWWVzLCB0aGUgaGJhc2UgbWV0cmljcyBmaWxlcyBpcyBuYW1lZCBoYWRvb3AtbWV0cmljcyByYXRoZXIgdGhhbgorICAgICAgPGVtPmhiYXNlLW1ldHJpY3M8L2VtPiBiZWNhdXNlIGN1cnJlbnRseSBhdCBsZWFzdCB0aGUgaGFkb29wIG1ldHJpY3Mgc3lzdGVtIGhhcyB0aGUKKyAgICAgIHByb3BlcnRpZXMgZmlsZW5hbWUgaGFyZGNvZGVkLiBQZXIgbWV0cmljcyA8ZW0+Y29udGV4dDwvZW0+LAorICAgICAgY29tbWVudCBvdXQgdGhlIE51bGxDb250ZXh0IGFuZCBlbmFibGUgb25lIG9yIG1vcmUgcGx1Z2lucyBpbnN0ZWFkLgorICAgICAgPC9wPgorICAgICAgPHA+CisgICAgICBJZiB5b3UgZW5hYmxlIHRoZSA8ZW0+aGJhc2U8L2VtPiBjb250ZXh0LCBvbiByZWdpb25zZXJ2ZXJzIHlvdSdsbCBzZWUgdG90YWwgcmVxdWVzdHMgc2luY2UgbGFzdAorICAgICAgbWV0cmljIGVtaXNzaW9uLCBjb3VudCBvZiByZWdpb25zIGFuZCBzdG9yZWZpbGVzIGFzIHdlbGwgYXMgYSBjb3VudCBvZiBtZW1jYWNoZSBzaXplLgorICAgICAgT24gdGhlIG1hc3RlciwgeW91J2xsIHNlZSBhIGNvdW50IG9mIHRoZSBjbHVzdGVyJ3MgcmVxdWVzdHMuCisgICAgICA8L3A+CisgICAgICA8cD4KKyAgICAgIEVuYWJsaW5nIHRoZSA8ZW0+cnBjPC9lbT4gY29udGV4dCBpcyBnb29kIGlmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBzZWVpbmcKKyAgICAgIG1ldHJpY3Mgb24gZWFjaCBoYmFzZSBycGMgbWV0aG9kIGludm9jYXRpb24gKGNvdW50cyBhbmQgdGltZSB0YWtlbikuCisgICAgICA8L3A+CisgICAgICA8cD4KKyAgICAgIFRoZSA8ZW0+anZtPC9lbT4gY29udGV4dCBpcworICAgICAgdXNlZnVsIGZvciBsb25nLXRlcm0gc3RhdHMgb24gcnVubmluZyBoYmFzZSBqdm1zIC0tIG1lbW9yeSB1c2VkLCB0aHJlYWQgY291bnRzLCBldGMuCisgICAgICBBcyBvZiB0aGlzIHdyaXRpbmcsIGlmIG1vcmUgdGhhbiBvbmUganZtIGlzIHJ1bm5pbmcgZW1pdHRpbmcgbWV0cmljcywgYXQgbGVhc3QKKyAgICAgIGluIGdhbmdsaWEsIHRoZSBzdGF0cyBhcmUgYWdncmVnYXRlZCByYXRoZXIgdGhhbiByZXBvcnRlZCBwZXIgaW5zdGFuY2UuCisgICAgICA8L3A+CisgICAgPC9zZWN0aW9uPgorICA8L2JvZHk+Cis8L2RvY3VtZW50PgpkaWZmIC0tZ2l0IGEvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy9zaXRlLnhtbCBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL2NvbnRlbnQveGRvY3Mvc2l0ZS54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMyMjE4MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL2NvbnRlbnQveGRvY3Mvc2l0ZS54bWwKQEAgLTAsMCArMSw3MiBAQAorPD94bWwgdmVyc2lvbj0iMS4wIj8+Cis8IS0tCisgIENvcHlyaWdodCAyMDAyLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisKKyAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPCEtLQorRm9ycmVzdCBzaXRlLnhtbAorCitUaGlzIGZpbGUgY29udGFpbnMgYW4gb3V0bGluZSBvZiB0aGUgc2l0ZSdzIGluZm9ybWF0aW9uIGNvbnRlbnQuICBJdCBpcyB1c2VkIHRvOgorLSBHZW5lcmF0ZSB0aGUgd2Vic2l0ZSBtZW51cyAodGhvdWdoIHRoZXNlIGNhbiBiZSBvdmVycmlkZGVuIC0gc2VlIGRvY3MpCistIFByb3ZpZGUgc2VtYW50aWMsIGxvY2F0aW9uLWluZGVwZW5kZW50IGFsaWFzZXMgZm9yIGludGVybmFsICdzaXRlOicgVVJJcywgZWcKKzxsaW5rIGhyZWY9InNpdGU6Y2hhbmdlcyI+IGxpbmtzIHRvIGNoYW5nZXMuaHRtbCAob3IgLi4vY2hhbmdlcy5odG1sIGlmIGluCisgIHN1YmRpcikuCistIFByb3ZpZGUgYWxpYXNlcyBmb3IgZXh0ZXJuYWwgVVJMcyBpbiB0aGUgZXh0ZXJuYWwtcmVmcyBzZWN0aW9uLiAgRWcsIDxsaW5rCisgIGhyZWY9ImV4dDpjb2Nvb24iPiBsaW5rcyB0byBodHRwOi8veG1sLmFwYWNoZS5vcmcvY29jb29uLworCitTZWUgaHR0cDovL2ZvcnJlc3QuYXBhY2hlLm9yZy9kb2NzL2xpbmtpbmcuaHRtbCBmb3IgbW9yZSBpbmZvLgorLS0+CisKKzxzaXRlIGxhYmVsPSJIYWRvb3AiIGhyZWY9IiIgeG1sbnM9Imh0dHA6Ly9hcGFjaGUub3JnL2ZvcnJlc3QvbGlua21hcC8xLjAiPgorCisgIDxkb2NzIGxhYmVsPSJEb2N1bWVudGF0aW9uIj4gCisgICAgPG92ZXJ2aWV3ICBsYWJlbD0iT3ZlcnZpZXciICAgICAgICAgICBocmVmPSJpbmRleC5odG1sIiAvPgorICAgIDxzdGFydGVkICAgbGFiZWw9IkdldHRpbmcgU3RhcnRlZCIgICAgaHJlZj0iZXh0OmFwaS9zdGFydGVkIiAvPgorICAgIDxhcGkgICAgICAgbGFiZWw9IkFQSSBEb2NzIiAgICAgICAgICAgaHJlZj0iZXh0OmFwaS9pbmRleCIgLz4KKyAgICA8YXBpICAgICAgIGxhYmVsPSJIQmFzZSBNZXRyaWNzIiAgICAgIGhyZWY9Im1ldHJpY3MuaHRtbCIgLz4KKyAgICA8d2lraSAgICAgIGxhYmVsPSJXaWtpIiAgICAgICAgICAgICAgIGhyZWY9ImV4dDp3aWtpIiAvPgorICAgIDxmYXEgICAgICAgbGFiZWw9IkZBUSIgICAgICAgICAgICAgICAgaHJlZj0iZXh0OmZhcSIgLz4KKyAgICA8bGlzdHMgICAgIGxhYmVsPSJNYWlsaW5nIExpc3RzIiAgICAgIGhyZWY9ImV4dDpsaXN0cyIgLz4KKyAgPC9kb2NzPgorCisgIDxleHRlcm5hbC1yZWZzPgorICAgIDxzaXRlICAgICAgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlLyIvPgorICAgIDxsaXN0cyAgICAgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlL21haWxpbmdfbGlzdHMuaHRtbCIvPgorICAgIDxyZWxlYXNlcyAgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlL3JlbGVhc2VzLmh0bWwiPgorICAgICAgPGRvd25sb2FkIGhyZWY9IiNEb3dubG9hZCIgLz4KKyAgICA8L3JlbGVhc2VzPgorICAgIDxqaXJhICAgICAgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlL2lzc3VlX3RyYWNraW5nLmh0bWwiLz4KKyAgICA8d2lraSAgICAgIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlIiAvPgorICAgIDxmYXEgICAgICAgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UvRkFRIiAvPgorICAgIDx6bGliICAgICAgaHJlZj0iaHR0cDovL3d3dy56bGliLm5ldC8iIC8+CisgICAgPGx6byAgICAgICBocmVmPSJodHRwOi8vd3d3Lm9iZXJodW1lci5jb20vb3BlbnNvdXJjZS9sem8vIiAvPgorICAgIDxnemlwICAgICAgaHJlZj0iaHR0cDovL3d3dy5nemlwLm9yZy8iIC8+CisgICAgPGN5Z3dpbiAgICBocmVmPSJodHRwOi8vd3d3LmN5Z3dpbi5jb20vIiAvPgorICAgIDxvc3ggICAgICAgaHJlZj0iaHR0cDovL3d3dy5hcHBsZS5jb20vbWFjb3N4IiAvPgorICAgIDxhcGkgaHJlZj0iYXBpLyI+CisgICAgICA8c3RhcnRlZCBocmVmPSJvdmVydmlldy1zdW1tYXJ5Lmh0bWwjb3ZlcnZpZXdfZGVzY3JpcHRpb24iIC8+CisgICAgICA8aW5kZXggaHJlZj0iaW5kZXguaHRtbCIgLz4KKyAgICAgIDxvcmcgaHJlZj0ib3JnLyI+CisgICAgICAgIDxhcGFjaGUgaHJlZj0iYXBhY2hlLyI+CisgICAgICAgICAgPGhhZG9vcCBocmVmPSJoYWRvb3AvIj4KKyAgICAgICAgICAgIDxoYmFzZSBocmVmPSJoYmFzZS8iPgorICAgICAgICAgICAgPC9oYmFzZT4KKyAgICAgICAgICA8L2hhZG9vcD4KKyAgICAgICAgPC9hcGFjaGU+CisgICAgICA8L29yZz4KKyAgICA8L2FwaT4KKyAgPC9leHRlcm5hbC1yZWZzPgorIAorPC9zaXRlPgpkaWZmIC0tZ2l0IGEvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy90YWJzLnhtbCBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL2NvbnRlbnQveGRvY3MvdGFicy54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWM2Y2NiNGIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vY29udGVudC94ZG9jcy90YWJzLnhtbApAQCAtMCwwICsxLDM2IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKyAgQ29weXJpZ2h0IDIwMDItMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKworICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8IURPQ1RZUEUgdGFicyBQVUJMSUMgIi0vL0FQQUNIRS8vRFREIENvY29vbiBEb2N1bWVudGF0aW9uIFRhYiBWMS4wLy9FTiIgCisgICAgICAgICAgImh0dHA6Ly9mb3JyZXN0LmFwYWNoZS5vcmcvZHRkL3RhYi1jb2Nvb24tdjEwLmR0ZCI+CisKKzx0YWJzIHNvZnR3YXJlPSJIQmFzZSIKKyAgICAgIHRpdGxlPSJIQmFzZSIKKyAgICAgIGNvcHlyaWdodD0iVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIgorICAgICAgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgorCisgIDwhLS0gVGhlIHJ1bGVzIGFyZToKKyAgICBAZGlyIHdpbGwgYWx3YXlzIGhhdmUgL2luZGV4Lmh0bWwgYWRkZWQuCisgICAgQGhyZWYgaXMgbm90IG1vZGlmaWVkIHVubGVzcyBpdCBpcyByb290LXJlbGF0aXZlIGFuZCBvYnZpb3VzbHkgc3BlY2lmaWVzIGEKKyAgICBkaXJlY3RvcnkgKGVuZHMgaW4gJy8nKSwgaW4gd2hpY2ggY2FzZSAvaW5kZXguaHRtbCB3aWxsIGJlIGFkZGVkCisgIC0tPgorCisgIDx0YWIgbGFiZWw9IlByb2plY3QiIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy9oYmFzZS8iIC8+CisgIDx0YWIgbGFiZWw9Ildpa2kiIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlIiAvPgorICA8dGFiIGxhYmVsPSJIQmFzZSBEb2N1bWVudGF0aW9uIiBkaXI9IiIgLz4gIAorICAKKzwvdGFicz4KZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvYXJjaGl0ZWN0dXJlLmdpZiBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvYXJjaGl0ZWN0dXJlLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDg0YTIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vcmVzb3VyY2VzL2ltYWdlcy9hcmNoaXRlY3R1cmUuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvZmF2aWNvbi5pY28gYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9yZXNvdXJjZXMvaW1hZ2VzL2Zhdmljb24uaWNvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MWJjZjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZG9jcy9zcmMvZG9jdW1lbnRhdGlvbi9yZXNvdXJjZXMvaW1hZ2VzL2Zhdmljb24uaWNvCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGFkb29wLWxvZ28uanBnIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vcmVzb3VyY2VzL2ltYWdlcy9oYWRvb3AtbG9nby5qcGcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODA5NTI1ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGFkb29wLWxvZ28uanBnCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGJhc2VfbG9nb19tZWQuZ2lmIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vcmVzb3VyY2VzL2ltYWdlcy9oYmFzZV9sb2dvX21lZC5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzZkM2UzYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGJhc2VfbG9nb19tZWQuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGJhc2Vfc21hbGwuZ2lmIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vcmVzb3VyY2VzL2ltYWdlcy9oYmFzZV9zbWFsbC5naWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI3NTc2NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3Jlc291cmNlcy9pbWFnZXMvaGJhc2Vfc21hbGwuZ2lmCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3NraW5jb25mLnhtbCBiL3NyYy9kb2NzL3NyYy9kb2N1bWVudGF0aW9uL3NraW5jb25mLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMzFlZDMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3Mvc3JjL2RvY3VtZW50YXRpb24vc2tpbmNvbmYueG1sCkBAIC0wLDAgKzEsMzQ1IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKyAgQ29weXJpZ2h0IDIwMDItMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKworICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8IS0tCitTa2luIGNvbmZpZ3VyYXRpb24gZmlsZS4gVGhpcyBmaWxlIGNvbnRhaW5zIGRldGFpbHMgb2YgeW91ciBwcm9qZWN0LAord2hpY2ggd2lsbCBiZSB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUgY2hvc2VuIEZvcnJlc3Qgc2tpbi4KKy0tPgorCis8IURPQ1RZUEUgc2tpbmNvbmZpZyBQVUJMSUMgIi0vL0FQQUNIRS8vRFREIFNraW4gQ29uZmlndXJhdGlvbiBWMC42LTMvL0VOIiAiaHR0cDovL2ZvcnJlc3QuYXBhY2hlLm9yZy9kdGQvc2tpbmNvbmZpZy12MDYtMy5kdGQiPgorPHNraW5jb25maWc+CisgIDwhLS0gVG8gZW5hYmxlIGx1Y2VuZSBzZWFyY2ggYWRkIHByb3ZpZGVyPSJsdWNlbmUiIChkZWZhdWx0IGlzIGdvb2dsZSkuCisgICAgQWRkIGJveC1sb2NhdGlvbj0iYWx0IiB0byBtb3ZlIHRoZSBzZWFyY2ggYm94IHRvIGFuIGFsdGVybmF0ZSBsb2NhdGlvbgorICAgIChpZiB0aGUgc2tpbiBzdXBwb3J0cyBpdCkgYW5kIGJveC1sb2NhdGlvbj0iYWxsIiB0byBzaG93IGl0IGluIGFsbAorICAgIGF2YWlsYWJsZSBsb2NhdGlvbnMgb24gdGhlIHBhZ2UuICBSZW1vdmUgdGhlIDxzZWFyY2g+IGVsZW1lbnQgdG8gc2hvdworICAgIG5vIHNlYXJjaCBib3guIEBkb21haW4gd2lsbCBlbmFibGUgc2l0ZXNlYXJjaCBmb3IgdGhlIHNwZWNpZmljIGRvbWFpbiB3aXRoIGdvb2dsZS4KKyAgICBJbiBvdGhlciB3b3JkcyBnb29nbGUgd2lsbCBzZWFyY2ggdGhlIEBkb21haW4gZm9yIHRoZSBxdWVyeSBzdHJpbmcuCisKKyAgLS0+CisgIDxzZWFyY2ggbmFtZT0iSEJhc2UiIGRvbWFpbj0iaGFkb29wLmFwYWNoZS5vcmciIHByb3ZpZGVyPSJnb29nbGUiLz4KKworICA8IS0tIERpc2FibGUgdGhlIHByaW50IGxpbms/IElmIGVuYWJsZWQsIGludmFsaWQgSFRNTCA0LjAuMSAtLT4KKyAgPGRpc2FibGUtcHJpbnQtbGluaz50cnVlPC9kaXNhYmxlLXByaW50LWxpbms+ICAKKyAgPCEtLSBEaXNhYmxlIHRoZSBQREYgbGluaz8gLS0+CisgIDxkaXNhYmxlLXBkZi1saW5rPmZhbHNlPC9kaXNhYmxlLXBkZi1saW5rPgorICA8IS0tIERpc2FibGUgdGhlIFBPRCBsaW5rPyAtLT4KKyAgPGRpc2FibGUtcG9kLWxpbms+dHJ1ZTwvZGlzYWJsZS1wb2QtbGluaz4KKyAgPCEtLSBEaXNhYmxlIHRoZSBUZXh0IGxpbms/IEZJWE1FOiBOT1QgWUVUIElNUExFTUVORVRFRC4gLS0+CisgIDxkaXNhYmxlLXR4dC1saW5rPnRydWU8L2Rpc2FibGUtdHh0LWxpbms+CisgIDwhLS0gRGlzYWJsZSB0aGUgeG1sIHNvdXJjZSBsaW5rPyAtLT4KKyAgPCEtLSBUaGUgeG1sIHNvdXJjZSBsaW5rIG1ha2VzIGl0IHBvc3NpYmxlIHRvIGFjY2VzcyB0aGUgeG1sIHJlbmRpdGlvbgorICAgIG9mIHRoZSBzb3VyY2UgZnJpbSB0aGUgaHRtbCBwYWdlLCBhbmQgdG8gaGF2ZSBpdCBnZW5lcmF0ZWQgc3RhdGljYWxseS4KKyAgICBUaGlzIGNhbiBiZSB1c2VkIHRvIGVuYWJsZSBvdGhlciBzaXRlcyBhbmQgc2VydmljZXMgdG8gcmV1c2UgdGhlCisgICAgeG1sIGZvcm1hdCBmb3IgdGhlaXIgdXNlcy4gS2VlcCB0aGlzIGRpc2FibGVkIGlmIHlvdSBkb24ndCB3YW50IG90aGVyCisgICAgc2l0ZXMgdG8gZWFzaWx5IHJldXNlIHlvdXIgcGFnZXMuLS0+CisgIDxkaXNhYmxlLXhtbC1saW5rPnRydWU8L2Rpc2FibGUteG1sLWxpbms+CisKKyAgPCEtLSBEaXNhYmxlIG5hdmlnYXRpb24gaWNvbnMgb24gYWxsIGV4dGVybmFsIGxpbmtzPyAtLT4KKyAgPGRpc2FibGUtZXh0ZXJuYWwtbGluay1pbWFnZT50cnVlPC9kaXNhYmxlLWV4dGVybmFsLWxpbmstaW1hZ2U+CisKKyAgPCEtLSBEaXNhYmxlIHczYyBjb21wbGlhbmNlIGxpbmtzPyAKKyAgICBVc2UgZS5nLiBhbGlnbj0iY2VudGVyIiB0byBtb3ZlIHRoZSBjb21wbGlhbmNlIGxpbmtzIGxvZ29zIHRvIAorICAgIGFuIGFsdGVybmF0ZSBsb2NhdGlvbiBkZWZhdWx0IGlzIGxlZnQuCisgICAgKGlmIHRoZSBza2luIHN1cHBvcnRzIGl0KSAtLT4KKyAgPGRpc2FibGUtY29tcGxpYW5jZS1saW5rcz50cnVlPC9kaXNhYmxlLWNvbXBsaWFuY2UtbGlua3M+CisKKyAgPCEtLSBSZW5kZXIgbWFpbHRvOiBsaW5rcyB1bnJlY29nbmlzYWJsZSBieSBzcGFtIGhhcnZlc3RlcnM/IC0tPgorICA8b2JmdXNjYXRlLW1haWwtbGlua3M+ZmFsc2U8L29iZnVzY2F0ZS1tYWlsLWxpbmtzPgorCisgIDwhLS0gRGlzYWJsZSB0aGUgamF2YXNjcmlwdCBmYWNpbGl0eSB0byBjaGFuZ2UgdGhlIGZvbnQgc2l6ZSAtLT4KKyAgPGRpc2FibGUtZm9udC1zY3JpcHQ+dHJ1ZTwvZGlzYWJsZS1mb250LXNjcmlwdD4KKworICA8IS0tIHByb2plY3QgbG9nbyAtLT4KKyAgPHByb2plY3QtbmFtZT5IQmFzZTwvcHJvamVjdC1uYW1lPgorICA8cHJvamVjdC1kZXNjcmlwdGlvbj5UaGUgSGFkb29wIGRhdGFiYXNlPC9wcm9qZWN0LWRlc2NyaXB0aW9uPgorICA8cHJvamVjdC11cmw+aHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2hiYXNlLzwvcHJvamVjdC11cmw+CisgIDxwcm9qZWN0LWxvZ28+aW1hZ2VzL2hiYXNlX3NtYWxsLmdpZjwvcHJvamVjdC1sb2dvPgorCisgIDwhLS0gZ3JvdXAgbG9nbyAtLT4KKyAgPGdyb3VwLW5hbWU+SGFkb29wPC9ncm91cC1uYW1lPgorICA8Z3JvdXAtZGVzY3JpcHRpb24+QXBhY2hlIEhhZG9vcDwvZ3JvdXAtZGVzY3JpcHRpb24+CisgIDxncm91cC11cmw+aHR0cDovL2hhZG9vcC5hcGFjaGUub3JnLzwvZ3JvdXAtdXJsPgorICA8Z3JvdXAtbG9nbz5pbWFnZXMvaGFkb29wLWxvZ28uanBnPC9ncm91cC1sb2dvPgorCisgIDwhLS0gb3B0aW9uYWwgaG9zdCBsb2dvIChlLmcuIHNvdXJjZWZvcmdlIGxvZ28pCisgICAgICAgZGVmYXVsdCBza2luOiByZW5kZXJzIGl0IGF0IHRoZSBib3R0b20tbGVmdCBjb3JuZXIgLS0+CisgIDxob3N0LXVybD48L2hvc3QtdXJsPgorICA8aG9zdC1sb2dvPjwvaG9zdC1sb2dvPgorCisgIDwhLS0gcmVsYXRpdmUgdXJsIG9mIGEgZmF2aWNvbiBmaWxlLCBub3JtYWxseSBmYXZpY29uLmljbyAtLT4KKyAgPGZhdmljb24tdXJsPmltYWdlcy9mYXZpY29uLmljbzwvZmF2aWNvbi11cmw+CisKKyAgPCEtLSBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIHRvIGNvbnN0cnVjdCBhIGNvcHlyaWdodCBzdGF0ZW1lbnQgLS0+CisgIDx5ZWFyPjIwMDg8L3llYXI+CisgIDx2ZW5kb3I+VGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLjwvdmVuZG9yPgorICA8Y29weXJpZ2h0LWxpbms+aHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLzwvY29weXJpZ2h0LWxpbms+CisKKyAgPCEtLSBTb21lIHNraW5zIHVzZSB0aGlzIHRvIGZvcm0gYSAnYnJlYWRjcnVtYiB0cmFpbCcgb2YgbGlua3MuCisgICAgVXNlIGxvY2F0aW9uPSJhbHQiIHRvIG1vdmUgdGhlIHRyYWlsIHRvIGFuIGFsdGVybmF0ZSBsb2NhdGlvbgorICAgIChpZiB0aGUgc2tpbiBzdXBwb3J0cyBpdCkuCisJICBPbWl0IHRoZSBsb2NhdGlvbiBhdHRyaWJ1dGUgdG8gZGlzcGxheSB0aGUgdHJhaWwgaW4gdGhlIGRlZmF1bHQgbG9jYXRpb24uCisJICBVc2UgbG9jYXRpb249Im5vbmUiIHRvIG5vdCBkaXNwbGF5IHRoZSB0cmFpbCAoaWYgdGhlIHNraW4gc3VwcG9ydHMgaXQpLgorICAgIEZvciBzb21lIHNraW5zIGp1c3Qgc2V0IHRoZSBhdHRyaWJ1dGVzIHRvIGJsYW5rLgorICAtLT4KKyAgPHRyYWlsPgorICAgIDxsaW5rMSBuYW1lPSJBcGFjaGUiIGhyZWY9Imh0dHA6Ly93d3cuYXBhY2hlLm9yZy8iLz4KKyAgICA8bGluazIgbmFtZT0iSGFkb29wIiBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvIi8+CisgICAgPGxpbmszIG5hbWU9IkhCYXNlIiBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvaGJhc2UvIi8+CisgIDwvdHJhaWw+CisKKyAgPCEtLSBDb25maWd1cmUgdGhlIFRPQywgaS5lLiB0aGUgVGFibGUgb2YgQ29udGVudHMuCisgIEBtYXgtZGVwdGgKKyAgIGhvdyBtYW55ICJzZWN0aW9uIiBsZXZlbHMgbmVlZCB0byBiZSBpbmNsdWRlZCBpbiB0aGUKKyAgIGdlbmVyYXRlZCBUYWJsZSBvZiBDb250ZW50cyAoVE9DKS4gCisgIEBtaW4tc2VjdGlvbnMKKyAgIE1pbmltdW0gcmVxdWlyZWQgdG8gY3JlYXRlIGEgVE9DLgorICBAbG9jYXRpb24gKCJwYWdlIiwibWVudSIsInBhZ2UsbWVudSIsICJub25lIikKKyAgIFdoZXJlIHRvIHNob3cgdGhlIFRPQy4KKyAgLS0+CisgIDx0b2MgbWF4LWRlcHRoPSIyIiBtaW4tc2VjdGlvbnM9IjEiIGxvY2F0aW9uPSJwYWdlIi8+CisKKyAgPCEtLSBIZWFkaW5nIHR5cGVzIGNhbiBiZSBjbGVhbnx1bmRlcmxpbmVkfGJveGVkICAtLT4KKyAgPGhlYWRpbmdzIHR5cGU9ImNsZWFuIi8+CisgIAorICA8IS0tIFRoZSBvcHRpb25hbCBmZWVkYmFjayBlbGVtZW50IHdpbGwgYmUgdXNlZCB0byBjb25zdHJ1Y3QgYQorICAgIGZlZWRiYWNrIGxpbmsgaW4gdGhlIGZvb3RlciB3aXRoIHRoZSBwYWdlIHBhdGhuYW1lIGFwcGVuZGVkOgorICAgIDxhIGhyZWY9IkBocmVmIj57QHRvfTwvYT4KKyAgPGZlZWRiYWNrIHRvPSJ3ZWJtYXN0ZXJAZm9vLmNvbSIKKyAgICBocmVmPSJtYWlsdG86d2VibWFzdGVyQGZvby5jb20/c3ViamVjdD1GZWVkYmFjayYjMTYwOyIgPgorICAgIFNlbmQgZmVlZGJhY2sgYWJvdXQgdGhlIHdlYnNpdGUgdG86CisgIDwvZmVlZGJhY2s+CisgICAgLS0+CisgIDwhLS0KKyAgICBleHRyYS1jc3MgLSBoZXJlIHlvdSBjYW4gZGVmaW5lIGN1c3RvbSBjc3MtZWxlbWVudHMgdGhhdCBhcmUgCisgICAgYS4gb3ZlcnJpZGluZyB0aGUgZmFsbGJhY2sgZWxlbWVudHMgb3IgCisgICAgYi4gYWRkaW5nIHRoZSBjc3MgZGVmaW5pdGlvbiBmcm9tIG5ldyBlbGVtZW50cyB0aGF0IHlvdSBtYXkgaGF2ZSAKKyAgICAgICB1c2VkIGluIHlvdXIgZG9jdW1lbnRhdGlvbi4KKyAgICAtLT4KKyAgPGV4dHJhLWNzcz4KKyAgICA8IS0tRXhhbXBsZSBvZiBiLiAKKyAgICAgICAgVG8gZGVmaW5lIHRoZSBjc3MgZGVmaW5pdGlvbiBvZiBhIG5ldyBlbGVtZW50IHRoYXQgeW91IG1heSBoYXZlIHVzZWQKKyAgICAgICAgaW4gdGhlIGNsYXNzIGF0dHJpYnV0ZSBvZiBhIDxwPiBub2RlLiAKKyAgICAgICAgZS5nLiA8cCBjbGFzcz0icXVvdGUiLz4KKyAgICAtLT4KKyAgICBwLnF1b3RlIHsKKyAgICAgIG1hcmdpbi1sZWZ0OiAyZW07CisgICAgICBwYWRkaW5nOiAuNWVtOworICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2YwZjBmMDsKKyAgICAgIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CisgICAgfQorICA8L2V4dHJhLWNzcz4KKworICA8Y29sb3JzPgorICA8IS0tIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBmb3IgdGhlIGdlbmVyYXRlZCBDU1MgZmlsZXMuIC0tPgorCisgIDwhLS0gS3J5c2FsaXMgLS0+Cis8IS0tCisgICAgPGNvbG9yIG5hbWU9ImhlYWRlciIgICAgdmFsdWU9IiNGRkZGRkYiLz4KKworICAgIDxjb2xvciBuYW1lPSJ0YWItc2VsZWN0ZWQiIHZhbHVlPSIjYTViNmM2IiBsaW5rPSIjMDAwMDAwIiB2bGluaz0iIzAwMDAwMCIgaGxpbms9IiMwMDAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0idGFiLXVuc2VsZWN0ZWQiIHZhbHVlPSIjRjdGN0Y3IiAgbGluaz0iIzAwMDAwMCIgdmxpbms9IiMwMDAwMDAiIGhsaW5rPSIjMDAwMDAwIi8+CisgICAgPGNvbG9yIG5hbWU9InN1YnRhYi1zZWxlY3RlZCIgdmFsdWU9IiNhNWI2YzYiICBsaW5rPSIjMDAwMDAwIiB2bGluaz0iIzAwMDAwMCIgaGxpbms9IiMwMDAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3VidGFiLXVuc2VsZWN0ZWQiIHZhbHVlPSIjYTViNmM2IiAgbGluaz0iIzAwMDAwMCIgdmxpbms9IiMwMDAwMDAiIGhsaW5rPSIjMDAwMDAwIi8+CisKKyAgICA8Y29sb3IgbmFtZT0iaGVhZGluZyIgdmFsdWU9IiNhNWI2YzYiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3ViaGVhZGluZyIgdmFsdWU9IiNDRkRDRUQiLz4KKyAgICAgICAgCisgICAgPGNvbG9yIG5hbWU9Im5hdnN0cmlwIiB2YWx1ZT0iI0NGRENFRCIgZm9udD0iIzAwMDAwMCIgbGluaz0iIzAwMDAwMCIgdmxpbms9IiMwMDAwMDAiIGhsaW5rPSIjMDAwMDAwIi8+CisgICAgPGNvbG9yIG5hbWU9InRvb2xib3giIHZhbHVlPSIjYTViNmM2Ii8+CisgICAgPGNvbG9yIG5hbWU9ImJvcmRlciIgdmFsdWU9IiNhNWI2YzYiLz4KKyAgICAgICAgCisgICAgPGNvbG9yIG5hbWU9Im1lbnUiIHZhbHVlPSIjRjdGN0Y3IiBsaW5rPSIjMDAwMDAwIiB2bGluaz0iIzAwMDAwMCIgaGxpbms9IiMwMDAwMDAiLz4gICAgCisgICAgPGNvbG9yIG5hbWU9ImRpYWxvZyIgdmFsdWU9IiNGN0Y3RjciLz4KKyAgICAgICAgICAgIAorICAgIDxjb2xvciBuYW1lPSJib2R5IiAgICB2YWx1ZT0iI2ZmZmZmZiIgbGluaz0iIzBGMzY2MCIgdmxpbms9IiMwMDk5OTkiIGhsaW5rPSIjMDAwMDY2Ii8+CisgICAgCisgICAgPGNvbG9yIG5hbWU9InRhYmxlIiB2YWx1ZT0iI2E1YjZjNiIvPiAgICAKKyAgICA8Y29sb3IgbmFtZT0idGFibGUtY2VsbCIgdmFsdWU9IiNmZmZmZmYiLz4gICAgCisgICAgPGNvbG9yIG5hbWU9ImhpZ2hsaWdodCIgdmFsdWU9IiNmZmZmMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0iZml4bWUiIHZhbHVlPSIjY2M2NjAwIi8+CisgICAgPGNvbG9yIG5hbWU9Im5vdGUiIHZhbHVlPSIjMDA2Njk5Ii8+CisgICAgPGNvbG9yIG5hbWU9Indhcm5pbmciIHZhbHVlPSIjOTkwMDAwIi8+CisgICAgPGNvbG9yIG5hbWU9ImNvZGUiIHZhbHVlPSIjYTViNmM2Ii8+CisgICAgICAgIAorICAgIDxjb2xvciBuYW1lPSJmb290ZXIiIHZhbHVlPSIjYTViNmM2Ii8+CistLT4KKyAgCisgIDwhLS0gRm9ycmVzdCAtLT4KKzwhLS0KKyAgICA8Y29sb3IgbmFtZT0iaGVhZGVyIiAgICB2YWx1ZT0iIzI5NDU2MyIvPgorCisgICAgPGNvbG9yIG5hbWU9InRhYi1zZWxlY3RlZCIgdmFsdWU9IiM0YTZkOGMiIGxpbms9IiMwRjM2NjAiIHZsaW5rPSIjMEYzNjYwIiBobGluaz0iIzAwMDA2NiIvPgorICAgIDxjb2xvciBuYW1lPSJ0YWItdW5zZWxlY3RlZCIgdmFsdWU9IiNiNWM3ZTciIGxpbms9IiMwRjM2NjAiIHZsaW5rPSIjMEYzNjYwIiBobGluaz0iIzAwMDA2NiIvPgorICAgIDxjb2xvciBuYW1lPSJzdWJ0YWItc2VsZWN0ZWQiIHZhbHVlPSIjNGE2ZDhjIiBsaW5rPSIjMEYzNjYwIiB2bGluaz0iIzBGMzY2MCIgaGxpbms9IiMwMDAwNjYiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3VidGFiLXVuc2VsZWN0ZWQiIHZhbHVlPSIjNGE2ZDhjIiBsaW5rPSIjMEYzNjYwIiB2bGluaz0iIzBGMzY2MCIgaGxpbms9IiMwMDAwNjYiLz4KKworICAgIDxjb2xvciBuYW1lPSJoZWFkaW5nIiB2YWx1ZT0iIzI5NDU2MyIvPgorICAgIDxjb2xvciBuYW1lPSJzdWJoZWFkaW5nIiB2YWx1ZT0iIzRhNmQ4YyIvPgorICAgICAgICAKKyAgICA8Y29sb3IgbmFtZT0ibmF2c3RyaXAiIHZhbHVlPSIjY2VkZmVmIiBmb250PSIjMEYzNjYwIiBsaW5rPSIjMEYzNjYwIiB2bGluaz0iIzBGMzY2MCIgaGxpbms9IiMwMDAwNjYiLz4KKyAgICA8Y29sb3IgbmFtZT0idG9vbGJveCIgdmFsdWU9IiM0YTZkOGMiLz4KKyAgICA8Y29sb3IgbmFtZT0iYm9yZGVyIiB2YWx1ZT0iIzI5NDU2MyIvPgorICAgIAorICAgIDxjb2xvciBuYW1lPSJtZW51IiB2YWx1ZT0iIzRhNmQ4YyIgZm9udD0iI2NlZGZlZiIgbGluaz0iI2ZmZmZmZiIgdmxpbms9IiNmZmZmZmYiIGhsaW5rPSIjZmZjZjAwIi8+ICAgIAorICAgIDxjb2xvciBuYW1lPSJkaWFsb2ciIHZhbHVlPSIjNGE2ZDhjIi8+CisgICAgICAgICAgICAKKyAgICA8Y29sb3IgbmFtZT0iYm9keSIgdmFsdWU9IiNmZmZmZmYiICBsaW5rPSIjMEYzNjYwIiB2bGluaz0iIzAwOTk5OSIgaGxpbms9IiMwMDAwNjYiLz4KKyAgICAKKyAgICA8Y29sb3IgbmFtZT0idGFibGUiIHZhbHVlPSIjNzA5OUM1Ii8+ICAgIAorICAgIDxjb2xvciBuYW1lPSJ0YWJsZS1jZWxsIiB2YWx1ZT0iI2YwZjBmZiIvPiAgICAKKyAgICA8Y29sb3IgbmFtZT0iaGlnaGxpZ2h0IiB2YWx1ZT0iI2ZmZmYwMCIvPgorICAgIDxjb2xvciBuYW1lPSJmaXhtZSIgdmFsdWU9IiNjYzY2MDAiLz4KKyAgICA8Y29sb3IgbmFtZT0ibm90ZSIgdmFsdWU9IiMwMDY2OTkiLz4KKyAgICA8Y29sb3IgbmFtZT0id2FybmluZyIgdmFsdWU9IiM5OTAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0iY29kZSIgdmFsdWU9IiNDRkRDRUQiLz4KKyAgICAgICAgCisgICAgPGNvbG9yIG5hbWU9ImZvb3RlciIgdmFsdWU9IiNjZWRmZWYiLz4KKy0tPgorCisgIDwhLS0gQ29sbGFibmV0IC0tPiAKKzwhLS0KKyAgICA8Y29sb3IgbmFtZT0iaGVhZGVyIiAgICB2YWx1ZT0iIzAwMzM2NiIvPgorCisgICAgPGNvbG9yIG5hbWU9InRhYi1zZWxlY3RlZCIgdmFsdWU9IiNkZGRkZGQiIGxpbms9IiM1NTU1NTUiIHZsaW5rPSIjNTU1NTU1IiBobGluaz0iIzU1NTU1NSIvPgorICAgIDxjb2xvciBuYW1lPSJ0YWItdW5zZWxlY3RlZCIgdmFsdWU9IiM5OTk5OTkiIGxpbms9IiNmZmZmZmYiIHZsaW5rPSIjZmZmZmZmIiBobGluaz0iI2ZmZmZmZiIvPgorICAgIDxjb2xvciBuYW1lPSJzdWJ0YWItc2VsZWN0ZWQiIHZhbHVlPSIjY2NjY2NjIiBsaW5rPSIjMDAwMDAwIiB2bGluaz0iIzAwMDAwMCIgaGxpbms9IiMwMDAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3VidGFiLXVuc2VsZWN0ZWQiIHZhbHVlPSIjY2NjY2NjIiBsaW5rPSIjNTU1NTU1IiB2bGluaz0iIzU1NTU1NSIgaGxpbms9IiM1NTU1NTUiLz4KKworICAgIDxjb2xvciBuYW1lPSJoZWFkaW5nIiB2YWx1ZT0iIzAwMzM2NiIvPgorICAgIDxjb2xvciBuYW1lPSJzdWJoZWFkaW5nIiB2YWx1ZT0iIzg4ODg4OCIvPgorICAgIAorICAgIDxjb2xvciBuYW1lPSJuYXZzdHJpcCIgdmFsdWU9IiNkZGRkZGQiIGZvbnQ9IiM1NTU1NTUiLz4KKyAgICA8Y29sb3IgbmFtZT0idG9vbGJveCIgdmFsdWU9IiNkZGRkZGQiIGZvbnQ9IiM1NTU1NTUiLz4KKyAgICA8Y29sb3IgbmFtZT0iYm9yZGVyIiB2YWx1ZT0iIzk5OTk5OSIvPgorICAgIAorICAgIDxjb2xvciBuYW1lPSJtZW51IiB2YWx1ZT0iI2ZmZmZmZiIvPiAgICAKKyAgICA8Y29sb3IgbmFtZT0iZGlhbG9nIiB2YWx1ZT0iI2VlZWVlZSIvPgorICAgICAgICAgICAgCisgICAgPGNvbG9yIG5hbWU9ImJvZHkiICAgICAgdmFsdWU9IiNmZmZmZmYiLz4KKyAgICAKKyAgICA8Y29sb3IgbmFtZT0idGFibGUiIHZhbHVlPSIjY2NjIi8+ICAgIAorICAgIDxjb2xvciBuYW1lPSJ0YWJsZS1jZWxsIiB2YWx1ZT0iI2ZmZmZmZiIvPiAgIAorICAgIDxjb2xvciBuYW1lPSJoaWdobGlnaHQiIHZhbHVlPSIjZmZmZjAwIi8+CisgICAgPGNvbG9yIG5hbWU9ImZpeG1lIiB2YWx1ZT0iI2NjNjYwMCIvPgorICAgIDxjb2xvciBuYW1lPSJub3RlIiB2YWx1ZT0iIzAwNjY5OSIvPgorICAgIDxjb2xvciBuYW1lPSJ3YXJuaW5nIiB2YWx1ZT0iIzk5MDAwMCIvPgorICAgIDxjb2xvciBuYW1lPSJjb2RlIiB2YWx1ZT0iIzAwMzM2NiIvPgorICAgICAgICAKKyAgICA8Y29sb3IgbmFtZT0iZm9vdGVyIiB2YWx1ZT0iI2ZmZmZmZiIvPgorLS0+CisgPCEtLSBMZW55YSB1c2luZyBwZWx0LS0+Cis8IS0tCisgICAgPGNvbG9yIG5hbWU9ImhlYWRlciIgdmFsdWU9IiNmZmZmZmYiLz4KKworICAgIDxjb2xvciBuYW1lPSJ0YWItc2VsZWN0ZWQiIHZhbHVlPSIjNEM2QzhGIiBsaW5rPSIjZmZmZmZmIiB2bGluaz0iI2ZmZmZmZiIgaGxpbms9IiNmZmZmZmYiLz4KKyAgICA8Y29sb3IgbmFtZT0idGFiLXVuc2VsZWN0ZWQiIHZhbHVlPSIjRTVFNEQ5IiBsaW5rPSIjMDAwMDAwIiB2bGluaz0iIzAwMDAwMCIgaGxpbms9IiMwMDAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3VidGFiLXNlbGVjdGVkIiB2YWx1ZT0iIzAwMDAwMCIgbGluaz0iIzAwMDAwMCIgdmxpbms9IiMwMDAwMDAiIGhsaW5rPSIjMDAwMDAwIi8+CisgICAgPGNvbG9yIG5hbWU9InN1YnRhYi11bnNlbGVjdGVkIiB2YWx1ZT0iI0U1RTREOSIgbGluaz0iIzAwMDAwMCIgdmxpbms9IiMwMDAwMDAiIGhsaW5rPSIjMDAwMDAwIi8+CisKKyAgICA8Y29sb3IgbmFtZT0iaGVhZGluZyIgdmFsdWU9IiNFNUU0RDkiLz4KKyAgICA8Y29sb3IgbmFtZT0ic3ViaGVhZGluZyIgdmFsdWU9IiMwMDAwMDAiLz4KKyAgICA8Y29sb3IgbmFtZT0icHVibGlzaGVkIiB2YWx1ZT0iIzRDNkM4RiIgZm9udD0iI0ZGRkZGRiIvPgorICAgIDxjb2xvciBuYW1lPSJmZWVkYmFjayIgdmFsdWU9IiM0QzZDOEYiIGZvbnQ9IiNGRkZGRkYiIGFsaWduPSJjZW50ZXIiLz4KKyAgICA8Y29sb3IgbmFtZT0ibmF2c3RyaXAiIHZhbHVlPSIjRTVFNEQ5IiBmb250PSIjMDAwMDAwIi8+CisKKyAgICA8Y29sb3IgbmFtZT0idG9vbGJveCIgdmFsdWU9IiNDRkRDRUQiIGZvbnQ9IiMwMDAwMDAiLz4KKworICAgIDxjb2xvciBuYW1lPSJib3JkZXIiIHZhbHVlPSIjOTk5OTk5Ii8+CisgICAgPGNvbG9yIG5hbWU9Im1lbnUiIHZhbHVlPSIjNEM2QzhGIiBmb250PSIjZmZmZmZmIiBsaW5rPSIjZmZmZmZmIiB2bGluaz0iI2ZmZmZmZiIgaGxpbms9IiNmZmZmZmYiIGN1cnJlbnQ9IiNGRkNDMzMiIC8+ICAgIAorICAgIDxjb2xvciBuYW1lPSJtZW51aGVhZGluZyIgdmFsdWU9IiNjZmRjZWQiIGZvbnQ9IiMwMDAwMDAiIC8+CisgICAgPGNvbG9yIG5hbWU9InNlYXJjaGJveCIgdmFsdWU9IiNFNUU0RDkiIGZvbnQ9IiMwMDAwMDAiLz4KKyAgICAKKyAgICA8Y29sb3IgbmFtZT0iZGlhbG9nIiB2YWx1ZT0iI0NGRENFRCIvPgorICAgIDxjb2xvciBuYW1lPSJib2R5IiB2YWx1ZT0iI2ZmZmZmZiIgLz4gICAgICAgICAgICAKKyAgICAKKyAgICA8Y29sb3IgbmFtZT0idGFibGUiIHZhbHVlPSIjY2NjIi8+ICAgIAorICAgIDxjb2xvciBuYW1lPSJ0YWJsZS1jZWxsIiB2YWx1ZT0iI2ZmZmZmZiIvPiAgIAorICAgIDxjb2xvciBuYW1lPSJoaWdobGlnaHQiIHZhbHVlPSIjZmZmZjAwIi8+CisgICAgPGNvbG9yIG5hbWU9ImZpeG1lIiB2YWx1ZT0iI2NjNjYwMCIvPgorICAgIDxjb2xvciBuYW1lPSJub3RlIiB2YWx1ZT0iIzAwNjY5OSIvPgorICAgIDxjb2xvciBuYW1lPSJ3YXJuaW5nIiB2YWx1ZT0iIzk5MDAwMCIvPgorICAgIDxjb2xvciBuYW1lPSJjb2RlIiB2YWx1ZT0iIzAwMzM2NiIvPgorICAgICAgICAKKyAgICA8Y29sb3IgbmFtZT0iZm9vdGVyIiB2YWx1ZT0iI0U1RTREOSIvPgorLS0+CisgIDwvY29sb3JzPgorIAorICA8IS0tIFNldHRpbmdzIHNwZWNpZmljIHRvIFBERiBvdXRwdXQuIC0tPgorICA8cGRmPgorICAgIDwhLS0gCisgICAgICAgU3VwcG9ydGVkIHBhZ2Ugc2l6ZXMgYXJlIGEwLCBhMSwgYTIsIGEzLCBhNCwgYTUsIGV4ZWN1dGl2ZSwKKyAgICAgICBmb2xpbywgbGVnYWwsIGxlZGdlciwgbGV0dGVyLCBxdWFydG8sIHRhYmxvaWQgKGRlZmF1bHQgbGV0dGVyKS4KKyAgICAgICBTdXBwb3J0ZWQgcGFnZSBvcmllbnRhdGlvbnMgYXJlIHBvcnRyYWl0LCBsYW5kc2NhcGUgKGRlZmF1bHQKKyAgICAgICBwb3J0cmFpdCkuCisgICAgICAgU3VwcG9ydGVkIHRleHQgYWxpZ25tZW50cyBhcmUgbGVmdCwgcmlnaHQsIGp1c3RpZnkgKGRlZmF1bHQgbGVmdCkuCisgICAgLS0+CisgICAgPHBhZ2Ugc2l6ZT0ibGV0dGVyIiBvcmllbnRhdGlvbj0icG9ydHJhaXQiIHRleHQtYWxpZ249ImxlZnQiLz4KKworICAgIDwhLS0KKyAgICAgICBNYXJnaW5zIGNhbiBiZSBzcGVjaWZpZWQgZm9yIHRvcCwgYm90dG9tLCBpbm5lciwgYW5kIG91dGVyCisgICAgICAgZWRnZXMuIElmIGRvdWJsZS1zaWRlZD0iZmFsc2UiLCB0aGUgaW5uZXIgZWRnZSBpcyBhbHdheXMgbGVmdAorICAgICAgIGFuZCB0aGUgb3V0ZXIgaXMgYWx3YXlzIHJpZ2h0LiBJZiBkb3VibGUtc2lkZWQ9InRydWUiLCB0aGUKKyAgICAgICBpbm5lciBlZGdlIHdpbGwgYmUgbGVmdCBvbiBvZGQgcGFnZXMsIHJpZ2h0IG9uIGV2ZW4gcGFnZXMsCisgICAgICAgdGhlIG91dGVyIGVkZ2UgdmljZSB2ZXJzYS4KKyAgICAgICBTcGVjaWZpZWQgYmVsb3cgYXJlIHRoZSBkZWZhdWx0IHNldHRpbmdzLgorICAgIC0tPgorICAgIDxtYXJnaW5zIGRvdWJsZS1zaWRlZD0iZmFsc2UiPgorICAgICAgPHRvcD4xaW48L3RvcD4KKyAgICAgIDxib3R0b20+MWluPC9ib3R0b20+CisgICAgICA8aW5uZXI+MS4yNWluPC9pbm5lcj4KKyAgICAgIDxvdXRlcj4xaW48L291dGVyPgorICAgIDwvbWFyZ2lucz4KKworICAgIDwhLS0KKyAgICAgIFByaW50IHRoZSBVUkwgdGV4dCBuZXh0IHRvIGFsbCBsaW5rcyBnb2luZyBvdXRzaWRlIHRoZSBmaWxlCisgICAgLS0+CisgICAgPHNob3ctZXh0ZXJuYWwtdXJscz5mYWxzZTwvc2hvdy1leHRlcm5hbC11cmxzPgorCisgICAgPCEtLQorICAgICAgRGlzYWJsZSB0aGUgY29weXJpZ2h0IGZvb3RlciBvbiBlYWNoIHBhZ2Ugb2YgdGhlIFBERi4KKyAgICAgIEEgZm9vdGVyIGlzIGNvbXBvc2VkIGZvciBlYWNoIHBhZ2UuIEJ5IGRlZmF1bHQsIGEgImNyZWRpdCIgd2l0aCByb2xlPXBkZgorICAgICAgd2lsbCBiZSB1c2VkLCBhcyBleHBsYWluZWQgYmVsb3cuIE90aGVyd2lzZSBhIGNvcHlyaWdodCBzdGF0ZW1lbnQKKyAgICAgIHdpbGwgYmUgZ2VuZXJhdGVkLiBUaGlzIGxhdHRlciBjYW4gYmUgZGlzYWJsZWQuCisgICAgLS0+CisgICAgPGRpc2FibGUtY29weXJpZ2h0LWZvb3Rlcj5mYWxzZTwvZGlzYWJsZS1jb3B5cmlnaHQtZm9vdGVyPgorICA8L3BkZj4KKworICA8IS0tIENyZWRpdHMgYXJlIHR5cGljYWxseSByZW5kZXJlZCBhcyBhIHNldCBvZiBzbWFsbCBjbGlja2FibGUKKyAgICBpbWFnZXMgaW4gdGhlIHBhZ2UgZm9vdGVyLgorICAgIFVzZSBib3gtbG9jYXRpb249ImFsdCIgdG8gbW92ZSB0aGUgY3JlZGl0IHRvIGFuIGFsdGVybmF0ZSBsb2NhdGlvbgorICAgIChpZiB0aGUgc2tpbiBzdXBwb3J0cyBpdCkuIAorICAtLT4KKyAgPGNyZWRpdHM+CisgICAgPGNyZWRpdCBib3gtbG9jYXRpb249ImFsdCI+CisgICAgICA8bmFtZT5CdWlsdCB3aXRoIEFwYWNoZSBGb3JyZXN0PC9uYW1lPgorICAgICAgPHVybD5odHRwOi8vZm9ycmVzdC5hcGFjaGUub3JnLzwvdXJsPgorICAgICAgPGltYWdlPmltYWdlcy9idWlsdC13aXRoLWZvcnJlc3QtYnV0dG9uLnBuZzwvaW1hZ2U+CisgICAgICA8d2lkdGg+ODg8L3dpZHRoPgorICAgICAgPGhlaWdodD4zMTwvaGVpZ2h0PgorICAgIDwvY3JlZGl0PgorICAgIDwhLS0gQSBjcmVkaXQgd2l0aCBAcm9sZT0icGRmIiB3aWxsIGJlIHVzZWQgdG8gY29tcG9zZSBhIGZvb3RlcgorICAgICBmb3IgZWFjaCBwYWdlIGluIHRoZSBQREYsIHVzaW5nIGVpdGhlciAibmFtZSIgb3IgInVybCIgb3IgYm90aC4KKyAgICAtLT4KKyAgICA8IS0tCisgICAgPGNyZWRpdCByb2xlPSJwZGYiPgorICAgICAgPG5hbWU+QnVpbHQgd2l0aCBBcGFjaGUgRm9ycmVzdDwvbmFtZT4KKyAgICAgIDx1cmw+aHR0cDovL2ZvcnJlc3QuYXBhY2hlLm9yZy88L3VybD4KKyAgICA8L2NyZWRpdD4KKyAgICAtLT4KKyAgPC9jcmVkaXRzPgorCis8L3NraW5jb25maWc+CmRpZmYgLS1naXQgYS9zcmMvZG9jcy9zdGF0dXMueG1sIGIvc3JjL2RvY3Mvc3RhdHVzLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYWMzZmRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2RvY3Mvc3RhdHVzLnhtbApAQCAtMCwwICsxLDc0IEBACis8P3htbCB2ZXJzaW9uPSIxLjAiPz4KKzwhLS0KKyAgQ29weXJpZ2h0IDIwMDItMjAwNCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKworICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorPHN0YXR1cz4KKworICA8ZGV2ZWxvcGVycz4KKyAgICA8cGVyc29uIG5hbWU9IkpvZSBCbG9nZ3MiICAgICAgZW1haWw9ImpvZUBqb2VzY29tcGFueS5vcmciICAgICAgaWQ9IkpCIiAvPgorICAgIDwhLS0gQWRkIG1vcmUgcGVvcGxlIGhlcmUgLS0+CisgIDwvZGV2ZWxvcGVycz4KKworICA8Y2hhbmdlcz4KKyAgICA8IS0tIEFkZCBuZXcgcmVsZWFzZXMgaGVyZSAtLT4KKyAgICA8cmVsZWFzZSB2ZXJzaW9uPSIwLjEiIGRhdGU9InVucmVsZWFzZWQiPgorICAgICAgPCEtLSBTb21lIGFjdGlvbiB0eXBlcyBoYXZlIGFzc29jaWF0ZWQgaW1hZ2VzLiBCeSBkZWZhdWx0LCBpbWFnZXMgYXJlCisgICAgICBkZWZpbmVkIGZvciAnYWRkJywgJ2ZpeCcsICdyZW1vdmUnLCAndXBkYXRlJyBhbmQgJ2hhY2snLiBJZiB5b3UgYWRkCisgICAgICBzcmMvZG9jdW1lbnRhdGlvbi9yZXNvdXJjZXMvaW1hZ2VzLzxmb28+LmpwZyBpbWFnZXMsIHRoZXNlIHdpbGwKKyAgICAgIGF1dG9tYXRpY2FsbHkgYmUgdXNlZCBmb3IgZW50cmllcyBvZiB0eXBlIDxmb28+LiAtLT4KKworICAgICAgPGFjdGlvbiBkZXY9IkpCIiB0eXBlPSJhZGQiIGNvbnRleHQ9ImFkbWluIj4KKyAgICAgICAgSW5pdGlhbCBJbXBvcnQKKyAgICAgIDwvYWN0aW9uPgorICAgICAgPCEtLSBTYW1wbGUgYWN0aW9uOgorICAgICAgPGFjdGlvbiBkZXY9IkpCIiB0eXBlPSJmaXgiIGR1ZS10bz0iSm9lIENvbnRyaWJ1dG9yIgorICAgICAgICAgIGR1ZS10by1lbWFpbD0iam9lY0BhcGFjaGUub3JnIiBmaXhlcy1idWc9IjEyMyI+CisgICAgICAgICAgRml4ZWQgYSBidWcgaW4gdGhlIEZvbyBjbGFzcy4KKyAgICAgICAgPC9hY3Rpb24+CisgICAgICAgIC0tPgorICAgIDwvcmVsZWFzZT4KKyAgPC9jaGFuZ2VzPgorCisgIDx0b2RvPgorICAgIDxhY3Rpb25zIHByaW9yaXR5PSJoaWdoIj4KKyAgICAgIDxhY3Rpb24gY29udGV4dD0iZG9jcyIgZGV2PSJKQiI+CisgICAgICAgIEN1c3RvbWl6ZSB0aGlzIHRlbXBsYXRlIHByb2plY3Qgd2l0aCB5b3VyIHByb2plY3QncyBkZXRhaWxzLiAgVGhpcworICAgICAgICBUT0RPIGxpc3QgaXMgZ2VuZXJhdGVkIGZyb20gJ3N0YXR1cy54bWwnLgorICAgICAgPC9hY3Rpb24+CisgICAgICA8YWN0aW9uIGNvbnRleHQ9ImRvY3MiIGRldj0iSkIiPgorICAgICAgICBBZGQgbG90cyBvZiBjb250ZW50LiAgWE1MIGNvbnRlbnQgZ29lcyBpbgorICAgICAgICA8Y29kZT5zcmMvZG9jdW1lbnRhdGlvbi9jb250ZW50L3hkb2NzPC9jb2RlPiwgb3Igd2hlcmV2ZXIgdGhlCisgICAgICAgIDxjb2RlPiR7cHJvamVjdC54ZG9jcy1kaXJ9PC9jb2RlPiBwcm9wZXJ0eSAoc2V0IGluCisgICAgICAgIDxjb2RlPmZvcnJlc3QucHJvcGVydGllczwvY29kZT4pIHBvaW50cy4KKyAgICAgIDwvYWN0aW9uPgorICAgICAgPGFjdGlvbiBjb250ZXh0PSJmZWVkYmFjayIgZGV2PSJKQiI+CisgICAgICAgIE1haWwgPGxpbmsKKyAgICAgICAgICBocmVmPSJtYWlsdG86Zm9ycmVzdC1kZXZAeG1sLmFwYWNoZS5vcmciPmZvcnJlc3QtZGV2QHhtbC5hcGFjaGUub3JnPC9saW5rPgorICAgICAgICB3aXRoIGZlZWRiYWNrLgorICAgICAgPC9hY3Rpb24+CisgICAgPC9hY3Rpb25zPgorICAgIDwhLS0gQWRkIHRvZG8gaXRlbXMuIEBjb250ZXh0IGlzIGFuIGFyYml0cmFyeSBzdHJpbmcuIEVnOgorICAgIDxhY3Rpb25zIHByaW9yaXR5PSJoaWdoIj4KKyAgICAgIDxhY3Rpb24gY29udGV4dD0iY29kZSIgZGV2PSJTTiI+CisgICAgICA8L2FjdGlvbj4KKyAgICA8L2FjdGlvbnM+CisgICAgPGFjdGlvbnMgcHJpb3JpdHk9Im1lZGl1bSI+CisgICAgICA8YWN0aW9uIGNvbnRleHQ9ImRvY3MiIGRldj0ib3BlbiI+CisgICAgICA8L2FjdGlvbj4KKyAgICA8L2FjdGlvbnM+CisgICAgLS0+CisgIDwvdG9kbz4KKworPC9zdGF0dXM+CmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvUkVBTUUudHh0IGIvc3JjL2V4YW1wbGVzL1JFQU1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OWNmZjA2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL1JFQU1FLnR4dApAQCAtMCwwICsxLDIgQEAKK0V4YW1wbGUgY29kZS4gIEluY2x1ZGVzIHRocmlmdCBjbGllbnRzIGFuZCB1cGxvYWRlciBleGFtcGxlcyBpbmNsdWRpbmcKK2Egc2NyaXB0IHRvIHJlcGxpY2F0ZSBhIHBvc3RncmVzIGRhdGFiYXNlIGluIGhiYXNlIGJ5IFRpbSBTZWxsLgpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL21hcHJlZC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvU2FtcGxlVXBsb2FkZXIuamF2YSBiL3NyYy9leGFtcGxlcy9tYXByZWQvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1NhbXBsZVVwbG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhlNDg5NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9leGFtcGxlcy9tYXByZWQvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1NhbXBsZVVwbG9hZGVyLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlTWFwV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQuVGFibGVNYXBSZWR1Y2VVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZC5UYWJsZVJlZHVjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLkxvbmdXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlSW5wdXRGb3JtYXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNsaWVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ29uZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuTWFwUmVkdWNlQmFzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuTWFwcGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5PdXRwdXRDb2xsZWN0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlJlcG9ydGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVG9vbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlRvb2xSdW5uZXI7CisKKy8qCisgKiBTYW1wbGUgdXBsb2FkZXIuCisgKiAKKyAqIFRoaXMgaXMgRVhBTVBMRSBjb2RlLiAgWW91IHdpbGwgbmVlZCB0byBjaGFuZ2UgaXQgdG8gd29yayBmb3IgeW91ciBjb250ZXh0LgorICogCisgKiBVc2VzIFRhYmxlUmVkdWNlIHRvIHB1dCB0aGUgZGF0YSBpbnRvIGhiYXNlLiBDaGFuZ2UgdGhlIElucHV0Rm9ybWF0IHRvIHN1aXQKKyAqIHlvdXIgZGF0YS4gVXNlIHRoZSBtYXAgdG8gbWFzc2FnZSB0aGUgaW5wdXQgc28gaXQgZml0cyBoYmFzZS4gIEN1cnJlbnRseSBpdHMKKyAqIGp1c3QgYSBwYXNzLXRocm91Z2ggbWFwLiAgSW4gdGhlIHJlZHVjZSwgeW91IG5lZWQgdG8gb3V0cHV0IGEgcm93IGFuZCBhCisgKiBtYXAgb2YgY29sdW1ucyB0byBjZWxscy4gIENoYW5nZSBtYXAgYW5kIHJlZHVjZSB0byBzdWl0IHlvdXIgaW5wdXQuCisgKiAKKyAqIDxwPlRoZSBiZWxvdyBpcyB3aXJlZCB1cCB0byBoYW5kbGUgYW4gaW5wdXQgd2hvc2UgZm9ybWF0IGlzIGEgdGV4dCBmaWxlCisgKiB3aGljaCBoYXMgYSBsaW5lIGZvcm1hdCBhcyBmb2xsb3c6CisgKiA8cHJlPgorICogcm93IGNvbHVtbm5hbWUgY29sdW1uZGF0YQorICogPC9wcmU+CisgKiAKKyAqIDxwPlRoZSB0YWJsZSBhbmQgY29sdW1uZmFtaWx5IHdlJ3JlIHRvIGluc2VydCBpbnRvIG11c3QgcHJlZXhpc3QuCisgKiAKKyAqIDxwPkRvIHRoZSBmb2xsb3dpbmcgdG8gc3RhcnQgdGhlIE1SIGpvYjoKKyAqIDxwcmU+CisgKiAuL2Jpbi9oYWRvb3Agb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlNhbXBsZVVwbG9hZGVyIC90bXAvaW5wdXQudHh0IFRBQkxFX05BTUUKKyAqIDwvcHJlPgorICogCisgKiA8cD5UaGlzIGNvZGUgd2FzIHdyaXR0ZW4gYWdhaW5zdCBoYmFzZSAwLjEgYnJhbmNoLgorICovCitwdWJsaWMgY2xhc3MgU2FtcGxlVXBsb2FkZXIgZXh0ZW5kcyBNYXBSZWR1Y2VCYXNlCitpbXBsZW1lbnRzIE1hcHBlcjxMb25nV3JpdGFibGUsIFRleHQsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgYnl0ZSBbXT4+LAorICAgIFRvb2wgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRSA9ICJTYW1wbGVVcGxvYWRlciI7CisgIHByaXZhdGUgQ29uZmlndXJhdGlvbiBjb25mOworCisgIHB1YmxpYyBKb2JDb25mIGNyZWF0ZVN1Ym1pdHRhYmxlSm9iKFN0cmluZ1tdIGFyZ3MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSm9iQ29uZiBjID0gbmV3IEpvYkNvbmYoZ2V0Q29uZigpLCBTYW1wbGVVcGxvYWRlci5jbGFzcyk7CisgICAgYy5zZXRKb2JOYW1lKE5BTUUpOworICAgIEZpbGVJbnB1dEZvcm1hdC5zZXRJbnB1dFBhdGhzKGMsIG5ldyBQYXRoKGFyZ3NbMF0pKTsKKyAgICBjLnNldE1hcHBlckNsYXNzKHRoaXMuZ2V0Q2xhc3MoKSk7CisgICAgYy5zZXRNYXBPdXRwdXRLZXlDbGFzcyhJbW11dGFibGVCeXRlc1dyaXRhYmxlLmNsYXNzKTsKKyAgICBjLnNldE1hcE91dHB1dFZhbHVlQ2xhc3MoSGJhc2VNYXBXcml0YWJsZS5jbGFzcyk7CisgICAgYy5zZXRSZWR1Y2VyQ2xhc3MoVGFibGVVcGxvYWRlci5jbGFzcyk7CisgICAgVGFibGVNYXBSZWR1Y2VVdGlsLmluaXRUYWJsZVJlZHVjZUpvYihhcmdzWzFdLCBUYWJsZVVwbG9hZGVyLmNsYXNzLCBjKTsKKyAgICByZXR1cm4gYzsKKyAgfSAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgIHB1YmxpYyB2b2lkIG1hcChMb25nV3JpdGFibGUgaywgVGV4dCB2LAorICAgICAgT3V0cHV0Q29sbGVjdG9yPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgYnl0ZSBbXT4+IG91dHB1dCwKKyAgICAgIFJlcG9ydGVyIHIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgIC8vIExpbmVzIGFyZSBzcGFjZS1kZWxpbWl0ZWQ7IGZpcnN0IGl0ZW0gaXMgcm93LCBuZXh0IHRoZSBjb2x1bW5uYW1lIGFuZAorICAgICAvLyB0aGVuIHRoZSB0aGlyZCB0aGUgY2VsbCB2YWx1ZS4KKyAgICBTdHJpbmcgdG1wID0gdi50b1N0cmluZygpOworICAgIGlmICh0bXAubGVuZ3RoKCkgPT0gMCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBTdHJpbmcgW10gc3BsaXRzID0gdi50b1N0cmluZygpLnNwbGl0KCIgIik7CisgICAgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBieXRlIFtdPiBtdyA9CisgICAgICBuZXcgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBieXRlIFtdPigpOworICAgIG13LnB1dChCeXRlcy50b0J5dGVzKHNwbGl0c1sxXSksIEJ5dGVzLnRvQnl0ZXMoc3BsaXRzWzJdKSk7CisgICAgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKHNwbGl0c1swXSk7CisgICAgci5zZXRTdGF0dXMoIk1hcCBlbWl0dGluZyAiICsgc3BsaXRzWzBdICsgIiBmb3IgcmVjb3JkICIgKyBrLnRvU3RyaW5nKCkpOworICAgIG91dHB1dC5jb2xsZWN0KG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKHJvdyksIG13KTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVGFibGVVcGxvYWRlciBleHRlbmRzIE1hcFJlZHVjZUJhc2UKKyAgaW1wbGVtZW50cyBUYWJsZVJlZHVjZTxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBIYmFzZU1hcFdyaXRhYmxlPGJ5dGUgW10sIGJ5dGUgW10+PiB7CisgICAgcHVibGljIHZvaWQgcmVkdWNlKEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgaywgSXRlcmF0b3I8SGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBieXRlIFtdPj4gdiwKKyAgICAgICAgT3V0cHV0Q29sbGVjdG9yPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEJhdGNoVXBkYXRlPiBvdXRwdXQsCisgICAgICAgIFJlcG9ydGVyIHIpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHdoaWxlICh2Lmhhc05leHQoKSkgeworICAgICAgICByLnNldFN0YXR1cygiUmVkdWNlciBjb21taXR0aW5nICIgKyBrKTsKKyAgICAgICAgQmF0Y2hVcGRhdGUgYnUgPSBuZXcgQmF0Y2hVcGRhdGUoay5nZXQoKSk7CisgICAgICAgIHdoaWxlICh2Lmhhc05leHQoKSkgeworICAgICAgICAgIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgYnl0ZSBbXT4gaG13ID0gdi5uZXh0KCk7CisgICAgICAgICAgZm9yIChFbnRyeTxieXRlIFtdLCBieXRlIFtdPiBlOiBobXcuZW50cnlTZXQoKSkgeworICAgICAgICAgICAgYnUucHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG91dHB1dC5jb2xsZWN0KGssIGJ1KTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBzdGF0aWMgaW50IHByaW50VXNhZ2UoKSB7CisgICAgU3lzdGVtLm91dC5wcmludGxuKE5BTUUgKyAiIDxpbnB1dD4gPHRhYmxlX25hbWU+Iik7CisgICAgcmV0dXJuIC0xOworICB9IAorCisgIHB1YmxpYyBpbnQgcnVuKEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKSBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIGV4YWN0bHkgMiBwYXJhbWV0ZXJzIGxlZnQuCisgICAgaWYgKGFyZ3MubGVuZ3RoICE9IDIpIHsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRVJST1I6IFdyb25nIG51bWJlciBvZiBwYXJhbWV0ZXJzOiAiICsKKyAgICAgICAgYXJncy5sZW5ndGggKyAiIGluc3RlYWQgb2YgMi4iKTsKKyAgICAgIHJldHVybiBwcmludFVzYWdlKCk7CisgICAgfQorICAgIEpvYkNsaWVudC5ydW5Kb2IoY3JlYXRlU3VibWl0dGFibGVKb2IoYXJncykpOworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIENvbmZpZ3VyYXRpb24gZ2V0Q29uZigpIHsKKyAgICByZXR1cm4gdGhpcy5jb25mOworICB9IAorCisgIHB1YmxpYyB2b2lkIHNldENvbmYoZmluYWwgQ29uZmlndXJhdGlvbiBjKSB7CisgICAgdGhpcy5jb25mID0gYzsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIGludCBlcnJDb2RlID0gVG9vbFJ1bm5lci5ydW4obmV3IENvbmZpZ3VyYXRpb24oKSwgbmV3IFNhbXBsZVVwbG9hZGVyKCksCisgICAgICBhcmdzKTsKKyAgICBTeXN0ZW0uZXhpdChlcnJDb2RlKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy90aHJpZnQvRGVtb0NsaWVudC5jcHAgYi9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjMTk3MmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQuY3BwCkBAIC0wLDAgKzEsMzAwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworLyoKKyAqIEluc3RydWN0aW9uczoKKyAqIDEuIFJ1biBUaHJpZnQgdG8gZ2VuZXJhdGUgdGhlIGNwcCBtb2R1bGUgSEJhc2UKKyAqICAgIHRocmlmdCAtLWdlbiBjcHAgLi4vLi4vLi4vc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L0hiYXNlLnRocmlmdAorICogMi4gRXhlY3V0ZSB7bWFrZX0uCisgKiAzLiBFeGVjdXRlIHsuL0RlbW9DbGllbnR9LgorICovIAorCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2luY2x1ZGUgPHBvbGwuaD4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorCisjaW5jbHVkZSA8cHJvdG9jb2wvVEJpbmFyeVByb3RvY29sLmg+CisjaW5jbHVkZSA8dHJhbnNwb3J0L1RTb2NrZXQuaD4KKyNpbmNsdWRlIDx0cmFuc3BvcnQvVFRyYW5zcG9ydFV0aWxzLmg+CisKKyNpbmNsdWRlICJIYmFzZS5oIgorCit1c2luZyBuYW1lc3BhY2UgZmFjZWJvb2s6OnRocmlmdDsKK3VzaW5nIG5hbWVzcGFjZSBmYWNlYm9vazo6dGhyaWZ0Ojpwcm90b2NvbDsKK3VzaW5nIG5hbWVzcGFjZSBmYWNlYm9vazo6dGhyaWZ0Ojp0cmFuc3BvcnQ7CisKK3VzaW5nIG5hbWVzcGFjZSBhcGFjaGU6OmhhZG9vcDo6aGJhc2U6OnRocmlmdDsKKwordHlwZWRlZiBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gU3RyVmVjOwordHlwZWRlZiBzdGQ6Om1hcDxzdGQ6OnN0cmluZyxzdGQ6OnN0cmluZz4gU3RyTWFwOwordHlwZWRlZiBzdGQ6OnZlY3RvcjxDb2x1bW5EZXNjcmlwdG9yPiBDb2xWZWM7Cit0eXBlZGVmIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLENvbHVtbkRlc2NyaXB0b3I+IENvbE1hcDsKK3R5cGVkZWYgc3RkOjp2ZWN0b3I8VENlbGw+IENlbGxWZWM7Cit0eXBlZGVmIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLFRDZWxsPiBDZWxsTWFwOworCisKK3N0YXRpYyB2b2lkCitwcmludFJvdyhjb25zdCBUUm93UmVzdWx0ICZyb3dSZXN1bHQpCit7CisgIHN0ZDo6Y291dCA8PCAicm93OiAiIDw8IHJvd1Jlc3VsdC5yb3cgPDwgIiwgY29sczogIjsKKyAgZm9yIChDZWxsTWFwOjpjb25zdF9pdGVyYXRvciBpdCA9IHJvd1Jlc3VsdC5jb2x1bW5zLmJlZ2luKCk7IAorICAgICAgaXQgIT0gcm93UmVzdWx0LmNvbHVtbnMuZW5kKCk7ICsraXQpIHsKKyAgICBzdGQ6OmNvdXQgPDwgaXQtPmZpcnN0IDw8ICIgPT4gIiA8PCBpdC0+c2Vjb25kLnZhbHVlIDw8ICI7ICI7CisgIH0KKyAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKK30KKworc3RhdGljIHZvaWQKK3ByaW50VmVyc2lvbnMoY29uc3Qgc3RkOjpzdHJpbmcgJnJvdywgY29uc3QgQ2VsbFZlYyAmdmVyc2lvbnMpCit7CisgIHN0ZDo6Y291dCA8PCAicm93OiAiIDw8IHJvdyA8PCAiLCB2YWx1ZXM6ICI7CisgIGZvciAoQ2VsbFZlYzo6Y29uc3RfaXRlcmF0b3IgaXQgPSB2ZXJzaW9ucy5iZWdpbigpOyBpdCAhPSB2ZXJzaW9ucy5lbmQoKTsgKytpdCkgeworICAgIHN0ZDo6Y291dCA8PCAoKml0KS52YWx1ZSA8PCAiOyAiOworICB9CisgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cit9CisKK2ludCAKK21haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSAKK3sKKyAgYm9vc3Q6OnNoYXJlZF9wdHI8VFRyYW5zcG9ydD4gc29ja2V0KG5ldyBUU29ja2V0KCJsb2NhbGhvc3QiLCA5MDkwKSk7CisgIGJvb3N0OjpzaGFyZWRfcHRyPFRUcmFuc3BvcnQ+IHRyYW5zcG9ydChuZXcgVEJ1ZmZlcmVkVHJhbnNwb3J0KHNvY2tldCkpOworICBib29zdDo6c2hhcmVkX3B0cjxUUHJvdG9jb2w+IHByb3RvY29sKG5ldyBUQmluYXJ5UHJvdG9jb2wodHJhbnNwb3J0KSk7CisgIEhiYXNlQ2xpZW50IGNsaWVudChwcm90b2NvbCk7CisKKyAgdHJ5IHsKKyAgICB0cmFuc3BvcnQtPm9wZW4oKTsKKworICAgIHN0ZDo6c3RyaW5nIHQoImRlbW9fdGFibGUiKTsKKworICAgIC8vCisgICAgLy8gU2NhbiBhbGwgdGFibGVzLCBsb29rIGZvciB0aGUgZGVtbyB0YWJsZSBhbmQgZGVsZXRlIGl0LgorICAgIC8vCisgICAgc3RkOjpjb3V0IDw8ICJzY2FubmluZyB0YWJsZXMuLi4iIDw8IHN0ZDo6ZW5kbDsKKyAgICBTdHJWZWMgdGFibGVzOworICAgIGNsaWVudC5nZXRUYWJsZU5hbWVzKHRhYmxlcyk7CisgICAgZm9yIChTdHJWZWM6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gdGFibGVzLmJlZ2luKCk7IGl0ICE9IHRhYmxlcy5lbmQoKTsgKytpdCkgeworICAgICAgc3RkOjpjb3V0IDw8ICIgIGZvdW5kOiAiIDw8ICppdCA8PCBzdGQ6OmVuZGw7CisgICAgICBpZiAodCA9PSAqaXQpIHsKKyAgICAgICAgaWYgKGNsaWVudC5pc1RhYmxlRW5hYmxlZCgqaXQpKSB7CisgICAgICAgICAgc3RkOjpjb3V0IDw8ICIgICAgZGlzYWJsaW5nIHRhYmxlOiAiIDw8ICppdCA8PCBzdGQ6OmVuZGw7CisgICAgICAgICAgY2xpZW50LmRpc2FibGVUYWJsZSgqaXQpOworICAgICAgICB9CisgICAgICAgIHN0ZDo6Y291dCA8PCAiICAgIGRlbGV0aW5nIHRhYmxlOiAiIDw8ICppdCA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGNsaWVudC5kZWxldGVUYWJsZSgqaXQpOworICAgICAgfQorICAgIH0KKworICAgIC8vCisgICAgLy8gQ3JlYXRlIHRoZSBkZW1vIHRhYmxlIHdpdGggdHdvIGNvbHVtbiBmYW1pbGllcywgZW50cnk6IGFuZCB1bnVzZWQ6CisgICAgLy8KKyAgICBDb2xWZWMgY29sdW1uczsKKyAgICBjb2x1bW5zLnB1c2hfYmFjayhDb2x1bW5EZXNjcmlwdG9yKCkpOworICAgIGNvbHVtbnMuYmFjaygpLm5hbWUgPSAiZW50cnk6IjsKKyAgICBjb2x1bW5zLmJhY2soKS5tYXhWZXJzaW9ucyA9IDEwOworICAgIGNvbHVtbnMucHVzaF9iYWNrKENvbHVtbkRlc2NyaXB0b3IoKSk7CisgICAgY29sdW1ucy5iYWNrKCkubmFtZSA9ICJ1bnVzZWQ6IjsKKworICAgIHN0ZDo6Y291dCA8PCAiY3JlYXRpbmcgdGFibGU6ICIgPDwgdCA8PCBzdGQ6OmVuZGw7CisgICAgdHJ5IHsKKyAgICAgIGNsaWVudC5jcmVhdGVUYWJsZSh0LCBjb2x1bW5zKTsKKyAgICB9IGNhdGNoIChBbHJlYWR5RXhpc3RzICZhZSkgeworICAgICAgc3RkOjpjb3V0IDw8ICJXQVJOOiAiIDw8IGFlLm1lc3NhZ2UgPDwgc3RkOjplbmRsOworICAgIH0KKworICAgIENvbE1hcCBjb2x1bW5NYXA7CisgICAgY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKGNvbHVtbk1hcCwgdCk7CisgICAgc3RkOjpjb3V0IDw8ICJjb2x1bW4gZmFtaWxpZXMgaW4gIiA8PCB0IDw8ICI6ICIgPDwgc3RkOjplbmRsOworICAgIGZvciAoQ29sTWFwOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbHVtbk1hcC5iZWdpbigpOyBpdCAhPSBjb2x1bW5NYXAuZW5kKCk7ICsraXQpIHsKKyAgICAgIHN0ZDo6Y291dCA8PCAiICBjb2x1bW46ICIgPDwgaXQtPnNlY29uZC5uYW1lIDw8ICIsIG1heFZlcjogIiA8PCBpdC0+c2Vjb25kLm1heFZlcnNpb25zIDw8IHN0ZDo6ZW5kbDsKKyAgICB9CisKKyAgICAvLworICAgIC8vIFRlc3QgVVRGLTggaGFuZGxpbmcKKyAgICAvLworICAgIHN0ZDo6c3RyaW5nIGludmFsaWQoImZvby1ceGZjXHhhMVx4YTFceGExXHhhMVx4YTEiKTsKKyAgICBzdGQ6OnN0cmluZyB2YWxpZCgiZm9vLVx4RTdceDk0XHg5Rlx4RTNceDgzXHg5M1x4RTNceDgzXHhCQ1x4RTNceDgzXHhBQiIpOworCisgICAgLy8gbm9uLXV0ZjggaXMgZmluZSBmb3IgZGF0YQorICAgIHN0ZDo6dmVjdG9yPE11dGF0aW9uPiBtdXRhdGlvbnM7CisgICAgbXV0YXRpb25zLnB1c2hfYmFjayhNdXRhdGlvbigpKTsKKyAgICBtdXRhdGlvbnMuYmFjaygpLmNvbHVtbiA9ICJlbnRyeTpmb28iOworICAgIG11dGF0aW9ucy5iYWNrKCkudmFsdWUgPSBpbnZhbGlkOworICAgIGNsaWVudC5tdXRhdGVSb3codCwgImZvbyIsIG11dGF0aW9ucyk7CisKKyAgICAvLyB0cnkgZW1wdHkgc3RyaW5ncworICAgIG11dGF0aW9ucy5jbGVhcigpOworICAgIG11dGF0aW9ucy5wdXNoX2JhY2soTXV0YXRpb24oKSk7CisgICAgbXV0YXRpb25zLmJhY2soKS5jb2x1bW4gPSAiZW50cnk6IjsKKyAgICBtdXRhdGlvbnMuYmFjaygpLnZhbHVlID0gIiI7CisgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCAiIiwgbXV0YXRpb25zKTsKKworICAgIC8vIHRoaXMgcm93IG5hbWUgaXMgdmFsaWQgdXRmOAorICAgIG11dGF0aW9ucy5jbGVhcigpOworICAgIG11dGF0aW9ucy5wdXNoX2JhY2soTXV0YXRpb24oKSk7CisgICAgbXV0YXRpb25zLmJhY2soKS5jb2x1bW4gPSAiZW50cnk6Zm9vIjsKKyAgICBtdXRhdGlvbnMuYmFjaygpLnZhbHVlID0gdmFsaWQ7CisgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCB2YWxpZCwgbXV0YXRpb25zKTsKKworICAgIC8vIG5vbi11dGY4IGlzIG5vdCBhbGxvd2VkIGluIHJvdyBuYW1lcworICAgIHRyeSB7CisgICAgICBtdXRhdGlvbnMuY2xlYXIoKTsKKyAgICAgIG11dGF0aW9ucy5wdXNoX2JhY2soTXV0YXRpb24oKSk7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLmNvbHVtbiA9ICJlbnRyeTpmb28iOworICAgICAgbXV0YXRpb25zLmJhY2soKS52YWx1ZSA9IGludmFsaWQ7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIGludmFsaWQsIG11dGF0aW9ucyk7CisgICAgICBzdGQ6OmNvdXQgPDwgIkZBVEFMOiBzaG91bGRuJ3QgZ2V0IGhlcmUhIiA8PCBzdGQ6OmVuZGw7CisgICAgICBleGl0KC0xKTsKKyAgICB9IGNhdGNoIChJT0Vycm9yIGUpIHsKKyAgICAgIHN0ZDo6Y291dCA8PCAiZXhwZWN0ZWQgZXJyb3I6ICIgPDwgZS5tZXNzYWdlIDw8IHN0ZDo6ZW5kbDsKKyAgICB9CisKKyAgICAvLyBSdW4gYSBzY2FubmVyIG9uIHRoZSByb3dzIHdlIGp1c3QgY3JlYXRlZAorICAgIFN0clZlYyBjb2x1bW5OYW1lczsKKyAgICBjb2x1bW5OYW1lcy5wdXNoX2JhY2soImVudHJ5OiIpOworCisgICAgc3RkOjpjb3V0IDw8ICJTdGFydGluZyBzY2FubmVyLi4uIiA8PCBzdGQ6OmVuZGw7CisgICAgaW50IHNjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW4odCwgIiIsIGNvbHVtbk5hbWVzKTsKKyAgICB0cnkgeworICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgVFJvd1Jlc3VsdCB2YWx1ZTsKKyAgICAgICAgY2xpZW50LnNjYW5uZXJHZXQodmFsdWUsIHNjYW5uZXIpOworICAgICAgICBwcmludFJvdyh2YWx1ZSk7CisgICAgICB9CisgICAgfSBjYXRjaCAoTm90Rm91bmQgJm5mKSB7CisgICAgICBjbGllbnQuc2Nhbm5lckNsb3NlKHNjYW5uZXIpOworICAgICAgc3RkOjpjb3V0IDw8ICJTY2FubmVyIGZpbmlzaGVkIiA8PCBzdGQ6OmVuZGw7CisgICAgfQorCisgICAgLy8KKyAgICAvLyBSdW4gc29tZSBvcGVyYXRpb25zIG9uIGEgYnVuY2ggb2Ygcm93cy4KKyAgICAvLworICAgIGZvciAoaW50IGkgPSAxMDA7IGkgPj0gMDsgLS1pKSB7CisgICAgICAvLyBmb3JtYXQgcm93IGtleXMgYXMgIjAwMDAwIiB0byAiMDAxMDAiCisgICAgICBjaGFyIGJ1ZlszMl07CisgICAgICBzcHJpbnRmKGJ1ZiwgIiUwLjVkIiwgaSk7CisgICAgICBzdGQ6OnN0cmluZyByb3coYnVmKTsKKyAgICAgIAorICAgICAgVFJvd1Jlc3VsdCByb3dSZXN1bHQ7CisKKyAgICAgIG11dGF0aW9ucy5jbGVhcigpOworICAgICAgbXV0YXRpb25zLnB1c2hfYmFjayhNdXRhdGlvbigpKTsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkuY29sdW1uID0gInVudXNlZDoiOworICAgICAgbXV0YXRpb25zLmJhY2soKS52YWx1ZSA9ICJERUxFVEVfTUUiOworICAgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucyk7CisgICAgICBjbGllbnQuZ2V0Um93KHJvd1Jlc3VsdCwgdCwgcm93KTsKKyAgICAgIHByaW50Um93KHJvd1Jlc3VsdCk7CisgICAgICBjbGllbnQuZGVsZXRlQWxsUm93KHQsIHJvdyk7CisKKyAgICAgIG11dGF0aW9ucy5jbGVhcigpOworICAgICAgbXV0YXRpb25zLnB1c2hfYmFjayhNdXRhdGlvbigpKTsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkuY29sdW1uID0gImVudHJ5Om51bSI7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLnZhbHVlID0gIjAiOworICAgICAgbXV0YXRpb25zLnB1c2hfYmFjayhNdXRhdGlvbigpKTsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkuY29sdW1uID0gImVudHJ5OmZvbyI7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLnZhbHVlID0gIkZPTyI7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKTsKKyAgICAgIGNsaWVudC5nZXRSb3cocm93UmVzdWx0LCB0LCByb3cpOworICAgICAgcHJpbnRSb3cocm93UmVzdWx0KTsKKworICAgICAgLy8gc2xlZXAgdG8gZm9yY2UgbGF0ZXIgdGltZXN0YW1wIAorICAgICAgcG9sbCgwLCAwLCA1MCk7CisKKyAgICAgIG11dGF0aW9ucy5jbGVhcigpOworICAgICAgbXV0YXRpb25zLnB1c2hfYmFjayhNdXRhdGlvbigpKTsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkuY29sdW1uID0gImVudHJ5OmZvbyI7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLmlzRGVsZXRlID0gdHJ1ZTsKKyAgICAgIG11dGF0aW9ucy5wdXNoX2JhY2soTXV0YXRpb24oKSk7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLmNvbHVtbiA9ICJlbnRyeTpudW0iOworICAgICAgbXV0YXRpb25zLmJhY2soKS52YWx1ZSA9ICItMSI7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKTsKKyAgICAgIGNsaWVudC5nZXRSb3cocm93UmVzdWx0LCB0LCByb3cpOworICAgICAgcHJpbnRSb3cocm93UmVzdWx0KTsKKworICAgICAgbXV0YXRpb25zLmNsZWFyKCk7CisgICAgICBtdXRhdGlvbnMucHVzaF9iYWNrKE11dGF0aW9uKCkpOworICAgICAgbXV0YXRpb25zLmJhY2soKS5jb2x1bW4gPSAiZW50cnk6bnVtIjsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkudmFsdWUgPSBib29zdDo6bGV4aWNhbF9jYXN0PHN0ZDo6c3RyaW5nPihpKTsKKyAgICAgIG11dGF0aW9ucy5wdXNoX2JhY2soTXV0YXRpb24oKSk7CisgICAgICBtdXRhdGlvbnMuYmFjaygpLmNvbHVtbiA9ICJlbnRyeTpzcXIiOworICAgICAgbXV0YXRpb25zLmJhY2soKS52YWx1ZSA9IGJvb3N0OjpsZXhpY2FsX2Nhc3Q8c3RkOjpzdHJpbmc+KGkqaSk7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKTsKKyAgICAgIGNsaWVudC5nZXRSb3cocm93UmVzdWx0LCB0LCByb3cpOworICAgICAgcHJpbnRSb3cocm93UmVzdWx0KTsKKworICAgICAgbXV0YXRpb25zLmNsZWFyKCk7CisgICAgICBtdXRhdGlvbnMucHVzaF9iYWNrKE11dGF0aW9uKCkpOworICAgICAgbXV0YXRpb25zLmJhY2soKS5jb2x1bW4gPSAiZW50cnk6bnVtIjsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkudmFsdWUgPSAiLTk5OSI7CisgICAgICBtdXRhdGlvbnMucHVzaF9iYWNrKE11dGF0aW9uKCkpOworICAgICAgbXV0YXRpb25zLmJhY2soKS5jb2x1bW4gPSAiZW50cnk6c3FyIjsKKyAgICAgIG11dGF0aW9ucy5iYWNrKCkuaXNEZWxldGUgPSB0cnVlOworICAgICAgY2xpZW50Lm11dGF0ZVJvd1RzKHQsIHJvdywgbXV0YXRpb25zLCAxKTsgLy8gc2hvdWxkbid0IG92ZXJyaWRlIGxhdGVzdAorICAgICAgY2xpZW50LmdldFJvdyhyb3dSZXN1bHQsIHQsIHJvdyk7CisgICAgICBwcmludFJvdyhyb3dSZXN1bHQpOworCisgICAgICBDZWxsVmVjIHZlcnNpb25zOworICAgICAgY2xpZW50LmdldFZlcih2ZXJzaW9ucywgdCwgcm93LCAiZW50cnk6bnVtIiwgMTApOworICAgICAgcHJpbnRWZXJzaW9ucyhyb3csIHZlcnNpb25zKTsKKyAgICAgIGFzc2VydCh2ZXJzaW9ucy5zaXplKCkgPT0gNCk7CisgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOworCisgICAgICB0cnkgeworICAgICAgICBUQ2VsbCB2YWx1ZTsKKyAgICAgICAgY2xpZW50LmdldCh2YWx1ZSwgdCwgcm93LCAiZW50cnk6Zm9vIik7CisgICAgICAgIHN0ZDo6Y291dCA8PCAiRkFUQUw6IHNob3VsZG4ndCBnZXQgaGVyZSEiIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgZXhpdCgtMSk7CisgICAgICB9IGNhdGNoIChOb3RGb3VuZCAmbmYpIHsKKyAgICAgICAgLy8gYmxhbmsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBzY2FuIGFsbCByb3dzL2NvbHVtbnMKKworICAgIGNvbHVtbk5hbWVzLmNsZWFyKCk7CisgICAgY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKGNvbHVtbk1hcCwgdCk7CisgICAgZm9yIChDb2xNYXA6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sdW1uTWFwLmJlZ2luKCk7IGl0ICE9IGNvbHVtbk1hcC5lbmQoKTsgKytpdCkgeworICAgICAgc3RkOjpjb3V0IDw8ICJjb2x1bW4gd2l0aCBuYW1lOiAiICsgaXQtPnNlY29uZC5uYW1lIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIGNvbHVtbk5hbWVzLnB1c2hfYmFjayhpdC0+c2Vjb25kLm5hbWUgKyAiOiIpOworICAgIH0KKworICAgIHN0ZDo6Y291dCA8PCAiU3RhcnRpbmcgc2Nhbm5lci4uLiIgPDwgc3RkOjplbmRsOworICAgIHNjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW5XaXRoU3RvcCh0LCAiMDAwMjAiLCAiMDAwNDAiLCBjb2x1bW5OYW1lcyk7CisgICAgdHJ5IHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIFRSb3dSZXN1bHQgdmFsdWU7CisgICAgICAgIGNsaWVudC5zY2FubmVyR2V0KHZhbHVlLCBzY2FubmVyKTsKKyAgICAgICAgcHJpbnRSb3codmFsdWUpOworICAgICAgfQorICAgIH0gY2F0Y2ggKE5vdEZvdW5kICZuZikgeworICAgICAgY2xpZW50LnNjYW5uZXJDbG9zZShzY2FubmVyKTsKKyAgICAgIHN0ZDo6Y291dCA8PCAiU2Nhbm5lciBmaW5pc2hlZCIgPDwgc3RkOjplbmRsOworICAgIH0KKworICAgIHRyYW5zcG9ydC0+Y2xvc2UoKTsKKyAgfSAKKyAgY2F0Y2ggKFRFeGNlcHRpb24gJnR4KSB7CisgICAgcHJpbnRmKCJFUlJPUjogJXNcbiIsIHR4LndoYXQoKSk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL3RocmlmdC9EZW1vQ2xpZW50LmphdmEgYi9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzU2MmUzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9EZW1vQ2xpZW50LmphdmEKQEAgLTAsMCArMSwzMzEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQ7CisKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RGVjb2RlcjsKK2ltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5BbHJlYWR5RXhpc3RzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLkhiYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuSU9FcnJvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLklsbGVnYWxBcmd1bWVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLk11dGF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuTm90Rm91bmQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5UQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLlRSb3dSZXN1bHQ7CisKK2ltcG9ydCBjb20uZmFjZWJvb2sudGhyaWZ0LlRFeGNlcHRpb247CitpbXBvcnQgY29tLmZhY2Vib29rLnRocmlmdC5wcm90b2NvbC5UQmluYXJ5UHJvdG9jb2w7CitpbXBvcnQgY29tLmZhY2Vib29rLnRocmlmdC5wcm90b2NvbC5UUHJvdG9jb2w7CitpbXBvcnQgY29tLmZhY2Vib29rLnRocmlmdC50cmFuc3BvcnQuVFNvY2tldDsKK2ltcG9ydCBjb20uZmFjZWJvb2sudGhyaWZ0LnRyYW5zcG9ydC5UVHJhbnNwb3J0OworCisvKgorICogSW5zdHJ1Y3Rpb25zOgorICogMS4gUnVuIFRocmlmdCB0byBnZW5lcmF0ZSB0aGUgamF2YSBtb2R1bGUgSEJhc2UKKyAqICAgIHRocmlmdCAtLWdlbiBqYXZhIC4uLy4uLy4uL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9IYmFzZS50aHJpZnQKKyAqIDIuIEFjcXVpcmUgYSBqYXIgb2YgY29tcGlsZWQgVGhyaWZ0IGphdmEgY2xhc3Nlcy4gIEFzIG9mIHRoaXMgd3JpdGluZywgSEJhc2Ugc2hpcHMgCisgKiAgICB3aXRoIHRoaXMgamFyIChsaWJ0aHJpZnQtW1ZFUlNJT05dLmphcikuICBJZiB0aGlzIGphciBpcyBub3QgcHJlc2VudCwgb3IgaXQgaXMgCisgKiAgICBvdXQtb2YtZGF0ZSB3aXRoIHlvdXIgY3VycmVudCB2ZXJzaW9uIG9mIHRocmlmdCwgeW91IGNhbiBjb21waWxlIHRoZSBqYXIgCisgKiAgICB5b3Vyc2VsZiBieSBleGVjdXRpbmcge2FudH0gaW4geyRUSFJJRlRfSE9NRX0vbGliL2phdmEuCisgKiAzLiBDb21waWxlIGFuZCBleGVjdXRlIHRoaXMgZmlsZSB3aXRoIGJvdGggdGhlIGxpYnRocmlmdCBqYXIgYW5kIHRoZSBnZW4tamF2YS8gCisgKiAgICBkaXJlY3RvcnkgaW4gdGhlIGNsYXNzcGF0aC4gIFRoaXMgY2FuIGJlIGRvbmUgb24gdGhlIGNvbW1hbmQtbGluZSB3aXRoIHRoZSAKKyAqICAgIGZvbGxvd2luZyBsaW5lczogKGZyb20gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoaXMgZmlsZSBhbmQgZ2VuLWphdmEvKQorICogICAgCisgKiAgICBqYXZhYyAtY3AgL3BhdGgvdG8vbGlidGhyaWZ0L2phci5qYXI6Z2VuLWphdmEvIERlbW9DbGllbnQuamF2YQorICogICAgbXYgRGVtb0NsaWVudC5jbGFzcyBnZW4tamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvCisgKiAgICBqYXZhIC1jcCAvcGF0aC90by9saWJ0aHJpZnQvamFyLmphcjpnZW4tamF2YS8gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LkRlbW9DbGllbnQKKyAqIAorICovCitwdWJsaWMgY2xhc3MgRGVtb0NsaWVudCB7CisgIAorICBwcm90ZWN0ZWQgaW50IHBvcnQgPSA5MDkwOworICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gbnVsbDsKKworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSAKKyAgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24sIE5vdEZvdW5kLCBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnQsIEFscmVhZHlFeGlzdHMgeworICAgIERlbW9DbGllbnQgY2xpZW50ID0gbmV3IERlbW9DbGllbnQoKTsKKyAgICBjbGllbnQucnVuKCk7CisgIH0KKworICBEZW1vQ2xpZW50KCkgeworICAgIGRlY29kZXIgPSBDaGFyc2V0LmZvck5hbWUoIlVURi04IikubmV3RGVjb2RlcigpOworICB9CisgIAorICAvLyBIZWxwZXIgdG8gdHJhbnNsYXRlIGJ5dGVbXSdzIHRvIFVURjggc3RyaW5ncworICBwcml2YXRlIFN0cmluZyB1dGY4KGJ5dGVbXSBidWYpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIGRlY29kZXIuZGVjb2RlKEJ5dGVCdWZmZXIud3JhcChidWYpKS50b1N0cmluZygpOworICAgIH0gY2F0Y2ggKENoYXJhY3RlckNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICByZXR1cm4gIltJTlZBTElEIFVURi04XSI7CisgICAgfQorICB9CisgIAorICAvLyBIZWxwZXIgdG8gdHJhbnNsYXRlIHN0cmluZ3MgdG8gVVRGOCBieXRlcworICBwcml2YXRlIGJ5dGVbXSBieXRlcyhTdHJpbmcgcykgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gcy5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBydW4oKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbiwgTm90Rm91bmQsIElsbGVnYWxBcmd1bWVudCwKKyAgICAgIEFscmVhZHlFeGlzdHMgeworICAgIAorICAgIFRUcmFuc3BvcnQgdHJhbnNwb3J0ID0gbmV3IFRTb2NrZXQoImxvY2FsaG9zdCIsIHBvcnQpOworICAgIFRQcm90b2NvbCBwcm90b2NvbCA9IG5ldyBUQmluYXJ5UHJvdG9jb2wodHJhbnNwb3J0LCB0cnVlLCB0cnVlKTsKKyAgICBIYmFzZS5DbGllbnQgY2xpZW50ID0gbmV3IEhiYXNlLkNsaWVudChwcm90b2NvbCk7CisKKyAgICB0cmFuc3BvcnQub3BlbigpOworCisgICAgYnl0ZVtdIHQgPSBieXRlcygiZGVtb190YWJsZSIpOworICAgIAorICAgIC8vCisgICAgLy8gU2NhbiBhbGwgdGFibGVzLCBsb29rIGZvciB0aGUgZGVtbyB0YWJsZSBhbmQgZGVsZXRlIGl0LgorICAgIC8vCisgICAgU3lzdGVtLm91dC5wcmludGxuKCJzY2FubmluZyB0YWJsZXMuLi4iKTsKKyAgICBmb3IgKGJ5dGVbXSBuYW1lIDogY2xpZW50LmdldFRhYmxlTmFtZXMoKSkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIGZvdW5kOiAiICsgdXRmOChuYW1lKSk7CisgICAgICBpZiAodXRmOChuYW1lKS5lcXVhbHModXRmOCh0KSkpIHsKKyAgICAgICAgaWYgKGNsaWVudC5pc1RhYmxlRW5hYmxlZChuYW1lKSkgeworICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICAgIGRpc2FibGluZyB0YWJsZTogIiArIHV0ZjgobmFtZSkpOworICAgICAgICAgIGNsaWVudC5kaXNhYmxlVGFibGUobmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgICAgZGVsZXRpbmcgdGFibGU6ICIgKyB1dGY4KG5hbWUpKTsgCisgICAgICAgIGNsaWVudC5kZWxldGVUYWJsZShuYW1lKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLy8KKyAgICAvLyBDcmVhdGUgdGhlIGRlbW8gdGFibGUgd2l0aCB0d28gY29sdW1uIGZhbWlsaWVzLCBlbnRyeTogYW5kIHVudXNlZDoKKyAgICAvLworICAgIEFycmF5TGlzdDxDb2x1bW5EZXNjcmlwdG9yPiBjb2x1bW5zID0gbmV3IEFycmF5TGlzdDxDb2x1bW5EZXNjcmlwdG9yPigpOworICAgIENvbHVtbkRlc2NyaXB0b3IgY29sID0gbnVsbDsKKyAgICBjb2wgPSBuZXcgQ29sdW1uRGVzY3JpcHRvcigpOworICAgIGNvbC5uYW1lID0gYnl0ZXMoImVudHJ5OiIpOworICAgIGNvbC5tYXhWZXJzaW9ucyA9IDEwOworICAgIGNvbHVtbnMuYWRkKGNvbCk7CisgICAgY29sID0gbmV3IENvbHVtbkRlc2NyaXB0b3IoKTsKKyAgICBjb2wubmFtZSA9IGJ5dGVzKCJ1bnVzZWQ6Iik7CisgICAgY29sdW1ucy5hZGQoY29sKTsKKworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY3JlYXRpbmcgdGFibGU6ICIgKyB1dGY4KHQpKTsKKyAgICB0cnkgeworICAgICAgY2xpZW50LmNyZWF0ZVRhYmxlKHQsIGNvbHVtbnMpOworICAgIH0gY2F0Y2ggKEFscmVhZHlFeGlzdHMgYWUpIHsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiV0FSTjogIiArIGFlLm1lc3NhZ2UpOworICAgIH0KKyAgICAKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oImNvbHVtbiBmYW1pbGllcyBpbiAiICsgdXRmOCh0KSArICI6ICIpOworICAgIE1hcDxieXRlW10sIENvbHVtbkRlc2NyaXB0b3I+IGNvbHVtbk1hcCA9IGNsaWVudC5nZXRDb2x1bW5EZXNjcmlwdG9ycyh0KTsKKyAgICBmb3IgKENvbHVtbkRlc2NyaXB0b3IgY29sMiA6IGNvbHVtbk1hcC52YWx1ZXMoKSkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIgIGNvbHVtbjogIiArIHV0ZjgoY29sMi5uYW1lKSArICIsIG1heFZlcjogIiArIEludGVnZXIudG9TdHJpbmcoY29sMi5tYXhWZXJzaW9ucykpOworICAgIH0KKyAgICAKKyAgICAvLworICAgIC8vIFRlc3QgVVRGLTggaGFuZGxpbmcKKyAgICAvLworICAgIGJ5dGVbXSBpbnZhbGlkID0geyAoYnl0ZSkgJ2YnLCAoYnl0ZSkgJ28nLCAoYnl0ZSkgJ28nLCAoYnl0ZSkgJy0nLCAoYnl0ZSkgMHhmYywgKGJ5dGUpIDB4YTEsIChieXRlKSAweGExLCAoYnl0ZSkgMHhhMSwgKGJ5dGUpIDB4YTEgfTsKKyAgICBieXRlW10gdmFsaWQgPSB7IChieXRlKSAnZicsIChieXRlKSAnbycsIChieXRlKSAnbycsIChieXRlKSAnLScsIChieXRlKSAweEU3LCAoYnl0ZSkgMHg5NCwgKGJ5dGUpIDB4OUYsIChieXRlKSAweEUzLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4OTMsIChieXRlKSAweEUzLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4QkMsIChieXRlKSAweEUzLCAoYnl0ZSkgMHg4MywgKGJ5dGUpIDB4QUJ9OworCisgICAgQXJyYXlMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnM7CisgICAgLy8gbm9uLXV0ZjggaXMgZmluZSBmb3IgZGF0YQorICAgIG11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KCk7CisgICAgbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGJ5dGVzKCJlbnRyeTpmb28iKSwgaW52YWxpZCkpOworICAgIGNsaWVudC5tdXRhdGVSb3codCwgYnl0ZXMoImZvbyIpLCBtdXRhdGlvbnMpOworCisgICAgLy8gdHJ5IGVtcHR5IHN0cmluZ3MKKyAgICBtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgIG11dGF0aW9ucy5hZGQobmV3IE11dGF0aW9uKGZhbHNlLCBieXRlcygiZW50cnk6IiksIGJ5dGVzKCIiKSkpOworICAgIGNsaWVudC5tdXRhdGVSb3codCwgYnl0ZXMoIiIpLCBtdXRhdGlvbnMpOworCisgICAgLy8gdGhpcyByb3cgbmFtZSBpcyB2YWxpZCB1dGY4CisgICAgbXV0YXRpb25zID0gbmV3IEFycmF5TGlzdDxNdXRhdGlvbj4oKTsKKyAgICBtdXRhdGlvbnMuYWRkKG5ldyBNdXRhdGlvbihmYWxzZSwgYnl0ZXMoImVudHJ5OmZvbyIpLCB2YWxpZCkpOworICAgIGNsaWVudC5tdXRhdGVSb3codCwgdmFsaWQsIG11dGF0aW9ucyk7CisgICAgCisgICAgLy8gbm9uLXV0ZjggaXMgbm90IGFsbG93ZWQgaW4gcm93IG5hbWVzCisgICAgdHJ5IHsKKyAgICAgIG11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KCk7CisgICAgICBtdXRhdGlvbnMuYWRkKG5ldyBNdXRhdGlvbihmYWxzZSwgYnl0ZXMoImVudHJ5OmZvbyIpLCBpbnZhbGlkKSk7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIGludmFsaWQsIG11dGF0aW9ucyk7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZBVEFMOiBzaG91bGRuJ3QgZ2V0IGhlcmUiKTsKKyAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICB9IGNhdGNoIChJT0Vycm9yIGUpIHsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZXhwZWN0ZWQgZXJyb3I6ICIgKyBlLm1lc3NhZ2UpOworICAgIH0KKyAgICAKKyAgICAvLyBSdW4gYSBzY2FubmVyIG9uIHRoZSByb3dzIHdlIGp1c3QgY3JlYXRlZAorICAgIEFycmF5TGlzdDxieXRlW10+IGNvbHVtbk5hbWVzID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgY29sdW1uTmFtZXMuYWRkKGJ5dGVzKCJlbnRyeToiKSk7CisgICAgCisgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGFydGluZyBzY2FubmVyLi4uIik7CisgICAgaW50IHNjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW4odCwgYnl0ZXMoIiIpLCBjb2x1bW5OYW1lcyk7CisgICAgdHJ5IHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIFRSb3dSZXN1bHQgZW50cnkgPSBjbGllbnQuc2Nhbm5lckdldChzY2FubmVyKTsKKyAgICAgICAgcHJpbnRSb3coZW50cnkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKE5vdEZvdW5kIG5mKSB7CisgICAgICBjbGllbnQuc2Nhbm5lckNsb3NlKHNjYW5uZXIpOworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTY2FubmVyIGZpbmlzaGVkIik7CisgICAgfQorICAgIAorICAgIC8vCisgICAgLy8gUnVuIHNvbWUgb3BlcmF0aW9ucyBvbiBhIGJ1bmNoIG9mIHJvd3MKKyAgICAvLworICAgIGZvciAoaW50IGkgPSAxMDA7IGkgPj0gMDsgLS1pKSB7CisgICAgICAvLyBmb3JtYXQgcm93IGtleXMgYXMgIjAwMDAwIiB0byAiMDAxMDAiCisgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKKyAgICAgIG5mLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKDUpOworICAgICAgbmYuc2V0R3JvdXBpbmdVc2VkKGZhbHNlKTsKKyAgICAgIGJ5dGVbXSByb3cgPSBieXRlcyhuZi5mb3JtYXQoaSkpOworICAgICAgCisgICAgICBtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgICAgbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGJ5dGVzKCJ1bnVzZWQ6IiksIGJ5dGVzKCJERUxFVEVfTUUiKSkpOworICAgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucyk7CisgICAgICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpOworICAgICAgY2xpZW50LmRlbGV0ZUFsbFJvdyh0LCByb3cpOworCisgICAgICBtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgICAgbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGJ5dGVzKCJlbnRyeTpudW0iKSwgYnl0ZXMoIjAiKSkpOworICAgICAgbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGJ5dGVzKCJlbnRyeTpmb28iKSwgYnl0ZXMoIkZPTyIpKSk7CisgICAgICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKTsKKyAgICAgIHByaW50Um93KGNsaWVudC5nZXRSb3codCwgcm93KSk7CisKKyAgICAgIE11dGF0aW9uIG0gPSBudWxsOworICAgICAgbXV0YXRpb25zID0gbmV3IEFycmF5TGlzdDxNdXRhdGlvbj4oKTsKKyAgICAgIG0gPSBuZXcgTXV0YXRpb24oKTsKKyAgICAgIG0uY29sdW1uID0gYnl0ZXMoImVudHJ5OmZvbyIpOworICAgICAgbS5pc0RlbGV0ZSA9IHRydWU7CisgICAgICBtdXRhdGlvbnMuYWRkKG0pOworICAgICAgbSA9IG5ldyBNdXRhdGlvbigpOworICAgICAgbS5jb2x1bW4gPSBieXRlcygiZW50cnk6bnVtIik7CisgICAgICBtLnZhbHVlID0gYnl0ZXMoIi0xIik7CisgICAgICBtdXRhdGlvbnMuYWRkKG0pOworICAgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucyk7CisgICAgICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpOworICAgICAgCisgICAgICBtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgICAgbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGJ5dGVzKCJlbnRyeTpudW0iKSwgYnl0ZXMoSW50ZWdlci50b1N0cmluZyhpKSkpKTsKKyAgICAgIG11dGF0aW9ucy5hZGQobmV3IE11dGF0aW9uKGZhbHNlLCBieXRlcygiZW50cnk6c3FyIiksIGJ5dGVzKEludGVnZXIudG9TdHJpbmcoaSAqIGkpKSkpOworICAgICAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucyk7CisgICAgICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpOworCisgICAgICAvLyBzbGVlcCB0byBmb3JjZSBsYXRlciB0aW1lc3RhbXAgCisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoNTApOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBuby1vcAorICAgICAgfQorICAgICAgCisgICAgICBtdXRhdGlvbnMuY2xlYXIoKTsKKyAgICAgIG0gPSBuZXcgTXV0YXRpb24oKTsKKyAgICAgIG0uY29sdW1uID0gYnl0ZXMoImVudHJ5Om51bSIpOworICAgICAgbS52YWx1ZSA9IGJ5dGVzKCItOTk5Iik7CisgICAgICBtdXRhdGlvbnMuYWRkKG0pOworICAgICAgbSA9IG5ldyBNdXRhdGlvbigpOworICAgICAgbS5jb2x1bW4gPSBieXRlcygiZW50cnk6c3FyIik7CisgICAgICBtLmlzRGVsZXRlID0gdHJ1ZTsKKyAgICAgIGNsaWVudC5tdXRhdGVSb3dUcyh0LCByb3csIG11dGF0aW9ucywgMSk7IC8vIHNob3VsZG4ndCBvdmVycmlkZSBsYXRlc3QKKyAgICAgIHByaW50Um93KGNsaWVudC5nZXRSb3codCwgcm93KSk7CisKKyAgICAgIExpc3Q8VENlbGw+IHZlcnNpb25zID0gY2xpZW50LmdldFZlcih0LCByb3csIGJ5dGVzKCJlbnRyeTpudW0iKSwgMTApOworICAgICAgcHJpbnRWZXJzaW9ucyhyb3csIHZlcnNpb25zKTsKKyAgICAgIGlmICh2ZXJzaW9ucy5zaXplKCkgIT0gNCkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZBVEFMOiB3cm9uZyAjIG9mIHZlcnNpb25zIik7CisgICAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgICAgY2xpZW50LmdldCh0LCByb3csIGJ5dGVzKCJlbnRyeTpmb28iKSk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRkFUQUw6IHNob3VsZG4ndCBnZXQgaGVyZSIpOworICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7CisgICAgICB9IGNhdGNoIChOb3RGb3VuZCBuZjIpIHsKKyAgICAgICAgLy8gYmxhbmsKKyAgICAgIH0KKworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKyAgICB9CisgICAgCisgICAgLy8gc2NhbiBhbGwgcm93cy9jb2x1bW5OYW1lcworICAgIAorICAgIGNvbHVtbk5hbWVzLmNsZWFyKCk7CisgICAgZm9yIChDb2x1bW5EZXNjcmlwdG9yIGNvbDIgOiBjbGllbnQuZ2V0Q29sdW1uRGVzY3JpcHRvcnModCkudmFsdWVzKCkpIHsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY29sdW1uIHdpdGggbmFtZTogIiArIG5ldyBTdHJpbmcoY29sMi5uYW1lKSk7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oY29sMi50b1N0cmluZygpKTsKKyAgICAgIGNvbHVtbk5hbWVzLmFkZCgodXRmOChjb2wyLm5hbWUpICsgIjoiKS5nZXRCeXRlcygpKTsKKyAgICB9CisgICAgCisgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGFydGluZyBzY2FubmVyLi4uIik7CisgICAgc2Nhbm5lciA9IGNsaWVudC5zY2FubmVyT3BlbldpdGhTdG9wKHQsIGJ5dGVzKCIwMDAyMCIpLCBieXRlcygiMDAwNDAiKSwKKyAgICAgICAgY29sdW1uTmFtZXMpOworICAgIHRyeSB7CisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICBUUm93UmVzdWx0IGVudHJ5ID0gY2xpZW50LnNjYW5uZXJHZXQoc2Nhbm5lcik7CisgICAgICAgIHByaW50Um93KGVudHJ5KTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChOb3RGb3VuZCBuZikgeworICAgICAgY2xpZW50LnNjYW5uZXJDbG9zZShzY2FubmVyKTsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU2Nhbm5lciBmaW5pc2hlZCIpOworICAgIH0KKyAgICAKKyAgICB0cmFuc3BvcnQuY2xvc2UoKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBmaW5hbCB2b2lkIHByaW50VmVyc2lvbnMoYnl0ZVtdIHJvdywgTGlzdDxUQ2VsbD4gdmVyc2lvbnMpIHsKKyAgICBTdHJpbmdCdWlsZGVyIHJvd1N0ciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgZm9yIChUQ2VsbCBjZWxsIDogdmVyc2lvbnMpIHsKKyAgICAgIHJvd1N0ci5hcHBlbmQodXRmOChjZWxsLnZhbHVlKSk7CisgICAgICByb3dTdHIuYXBwZW5kKCI7ICIpOworICAgIH0KKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oInJvdzogIiArIHV0Zjgocm93KSArICIsIHZhbHVlczogIiArIHJvd1N0cik7CisgIH0KKyAgCisgIHByaXZhdGUgZmluYWwgdm9pZCBwcmludFJvdyhUUm93UmVzdWx0IHJvd1Jlc3VsdCkgeworICAgIC8vIGNvcHkgdmFsdWVzIGludG8gYSBUcmVlTWFwIHRvIGdldCB0aGVtIGluIHNvcnRlZCBvcmRlcgorICAgIAorICAgIFRyZWVNYXA8U3RyaW5nLFRDZWxsPiBzb3J0ZWQgPSBuZXcgVHJlZU1hcDxTdHJpbmcsVENlbGw+KCk7CisgICAgZm9yIChNYXAuRW50cnk8Ynl0ZVtdLCBUQ2VsbD4gY29sdW1uIDogcm93UmVzdWx0LmNvbHVtbnMuZW50cnlTZXQoKSkgeworICAgICAgc29ydGVkLnB1dCh1dGY4KGNvbHVtbi5nZXRLZXkoKSksIGNvbHVtbi5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgCisgICAgU3RyaW5nQnVpbGRlciByb3dTdHIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIGZvciAoU29ydGVkTWFwLkVudHJ5PFN0cmluZywgVENlbGw+IGVudHJ5IDogc29ydGVkLmVudHJ5U2V0KCkpIHsKKyAgICAgIHJvd1N0ci5hcHBlbmQoZW50cnkuZ2V0S2V5KCkpOworICAgICAgcm93U3RyLmFwcGVuZCgiID0+ICIpOworICAgICAgcm93U3RyLmFwcGVuZCh1dGY4KGVudHJ5LmdldFZhbHVlKCkudmFsdWUpKTsKKyAgICAgIHJvd1N0ci5hcHBlbmQoIjsgIik7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigicm93OiAiICsgdXRmOChyb3dSZXN1bHQucm93KSArICIsIGNvbHM6ICIgKyByb3dTdHIpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQucGhwIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9EZW1vQ2xpZW50LnBocApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWVhNTUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9EZW1vQ2xpZW50LnBocApAQCAtMCwwICsxLDI3NyBAQAorPD9waHAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqIAorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCisjIEluc3RydWN0aW9uczoKKyMgMS4gUnVuIFRocmlmdCB0byBnZW5lcmF0ZSB0aGUgcGhwIG1vZHVsZSBIQmFzZQorIyAgICB0aHJpZnQgLXBocCAuLi8uLi8uLi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvSGJhc2UudGhyaWZ0IAorIyAyLiBNb2RpZnkgdGhlIGltcG9ydCBzdHJpbmcgYmVsb3cgdG8gcG9pbnQgdG8geyRUSFJJRlRfSE9NRX0vbGliL3BocC9zcmMuCisjIDMuIEV4ZWN1dGUge3BocCBEZW1vQ2xpZW50LnBocH0uICBOb3RlIHRoYXQgeW91IG11c3QgdXNlIHBocDUgb3IgaGlnaGVyLgorIyA0LiBTZWUgeyRUSFJJRlRfSE9NRX0vbGliL3BocC9SRUFETUUgZm9yIGFkZGl0aW9uYWwgaGVscC4KKworIyBDaGFuZ2UgdGhpcyB0byBtYXRjaCB5b3VyIHRocmlmdCByb290CiskR0xPQkFMU1snVEhSSUZUX1JPT1QnXSA9ICcvVXNlcnMvaXJ1YmluL1RocmlmdC90aHJpZnQtMjAwODA0MTFwMS9saWIvcGhwL3NyYyc7CisKK3JlcXVpcmVfb25jZSggJEdMT0JBTFNbJ1RIUklGVF9ST09UJ10uJy9UaHJpZnQucGhwJyApOworCityZXF1aXJlX29uY2UoICRHTE9CQUxTWydUSFJJRlRfUk9PVCddLicvdHJhbnNwb3J0L1RTb2NrZXQucGhwJyApOworcmVxdWlyZV9vbmNlKCAkR0xPQkFMU1snVEhSSUZUX1JPT1QnXS4nL3RyYW5zcG9ydC9UQnVmZmVyZWRUcmFuc3BvcnQucGhwJyApOworcmVxdWlyZV9vbmNlKCAkR0xPQkFMU1snVEhSSUZUX1JPT1QnXS4nL3Byb3RvY29sL1RCaW5hcnlQcm90b2NvbC5waHAnICk7CisKKyMgQWNjb3JkaW5nIHRvIHRoZSB0aHJpZnQgZG9jdW1lbnRhdGlvbiwgY29tcGlsZWQgUEhQIHRocmlmdCBsaWJyYXJpZXMgc2hvdWxkCisjIHJlc2lkZSB1bmRlciB0aGUgVEhSSUZUX1JPT1QvcGFja2FnZXMgZGlyZWN0b3J5LiAgSWYgdGhlc2UgY29tcGlsZWQgbGlicmFyaWVzIAorIyBhcmUgbm90IHByZXNlbnQgaW4gdGhpcyBkaXJlY3RvcnksIG1vdmUgdGhlbSB0aGVyZSBmcm9tIGdlbi1waHAvLiAgCityZXF1aXJlX29uY2UoICRHTE9CQUxTWydUSFJJRlRfUk9PVCddLicvcGFja2FnZXMvSGJhc2UvSGJhc2UucGhwJyApOworCitmdW5jdGlvbiBwcmludFJvdyggJHJvd3Jlc3VsdCApIHsKKyAgZWNobyggInJvdzogeyRyb3dyZXN1bHQtPnJvd30sIGNvbHM6IFxuIiApOworICAkdmFsdWVzID0gJHJvd3Jlc3VsdC0+Y29sdW1uczsKKyAgYXNvcnQoICR2YWx1ZXMgKTsKKyAgZm9yZWFjaCAoICR2YWx1ZXMgYXMgJGs9PiR2ICkgeworICAgIGVjaG8oICIgIHska30gPT4geyR2LT52YWx1ZX1cbiIgKTsKKyAgfQorfQorCiskc29ja2V0ID0gbmV3IFRTb2NrZXQoICdsb2NhbGhvc3QnLCA5MDkwICk7Ciskc29ja2V0LT5zZXRTZW5kVGltZW91dCggMTAwMDAgKTsgLy8gVGVuIHNlY29uZHMgKHRvbyBsb25nIGZvciBwcm9kdWN0aW9uLCBidXQgdGhpcyBpcyBqdXN0IGEgZGVtbyA7KQorJHNvY2tldC0+c2V0UmVjdlRpbWVvdXQoIDIwMDAwICk7IC8vIFR3ZW50eSBzZWNvbmRzCiskdHJhbnNwb3J0ID0gbmV3IFRCdWZmZXJlZFRyYW5zcG9ydCggJHNvY2tldCApOworJHByb3RvY29sID0gbmV3IFRCaW5hcnlQcm90b2NvbCggJHRyYW5zcG9ydCApOworJGNsaWVudCA9IG5ldyBIYmFzZUNsaWVudCggJHByb3RvY29sICk7CisKKyR0cmFuc3BvcnQtPm9wZW4oKTsKKworJHQgPSAnZGVtb190YWJsZSc7CisKKz8+PGh0bWw+Cis8aGVhZD4KKzx0aXRsZT5EZW1vQ2xpZW50PC90aXRsZT4KKzwvaGVhZD4KKzxib2R5PgorPHByZT4KKzw/cGhwCisKKyMKKyMgU2NhbiBhbGwgdGFibGVzLCBsb29rIGZvciB0aGUgZGVtbyB0YWJsZSBhbmQgZGVsZXRlIGl0LgorIworZWNobyggInNjYW5uaW5nIHRhYmxlcy4uLlxuIiApOworJHRhYmxlcyA9ICRjbGllbnQtPmdldFRhYmxlTmFtZXMoKTsKK3NvcnQoICR0YWJsZXMgKTsKK2ZvcmVhY2ggKCAkdGFibGVzIGFzICRuYW1lICkgeworICBlY2hvKCAiICBmb3VuZDogeyRuYW1lfVxuIiApOworICBpZiAoICRuYW1lID09ICR0ICkgeworICAgIGlmICgkY2xpZW50LT5pc1RhYmxlRW5hYmxlZCggJG5hbWUgKSkgeworICAgICAgZWNobyggIiAgICBkaXNhYmxpbmcgdGFibGU6IHskbmFtZX1cbiIpOworICAgICAgJGNsaWVudC0+ZGlzYWJsZVRhYmxlKCAkbmFtZSApOworICAgIH0KKyAgICBlY2hvKCAiICAgIGRlbGV0aW5nIHRhYmxlOiB7JG5hbWV9XG4iICk7CisgICAgJGNsaWVudC0+ZGVsZXRlVGFibGUoICRuYW1lICk7CisgIH0KK30KKworIworIyBDcmVhdGUgdGhlIGRlbW8gdGFibGUgd2l0aCB0d28gY29sdW1uIGZhbWlsaWVzLCBlbnRyeTogYW5kIHVudXNlZDoKKyMKKyRjb2x1bW5zID0gYXJyYXkoCisgIG5ldyBDb2x1bW5EZXNjcmlwdG9yKCBhcnJheSgKKyAgICAnbmFtZScgPT4gJ2VudHJ5OicsCisgICAgJ21heFZlcnNpb25zJyA9PiAxMAorICApICksCisgIG5ldyBDb2x1bW5EZXNjcmlwdG9yKCBhcnJheSgKKyAgICAnbmFtZScgPT4gJ3VudXNlZDonCisgICkgKQorKTsKKworZWNobyggImNyZWF0aW5nIHRhYmxlOiB7JHR9XG4iICk7Cit0cnkgeworICAkY2xpZW50LT5jcmVhdGVUYWJsZSggJHQsICRjb2x1bW5zICk7Cit9IGNhdGNoICggQWxyZWFkeUV4aXN0cyAkYWUgKSB7CisgIGVjaG8oICJXQVJOOiB7JGFlLT5tZXNzYWdlfVxuIiApOworfQorCitlY2hvKCAiY29sdW1uIGZhbWlsaWVzIGluIHskdH06XG4iICk7CiskZGVzY3JpcHRvcnMgPSAkY2xpZW50LT5nZXRDb2x1bW5EZXNjcmlwdG9ycyggJHQgKTsKK2Fzb3J0KCAkZGVzY3JpcHRvcnMgKTsKK2ZvcmVhY2ggKCAkZGVzY3JpcHRvcnMgYXMgJGNvbCApIHsKKyAgZWNobyggIiAgY29sdW1uOiB7JGNvbC0+bmFtZX0sIG1heFZlcjogeyRjb2wtPm1heFZlcnNpb25zfVxuIiApOworfQorCisjCisjIFRlc3QgVVRGLTggaGFuZGxpbmcKKyMKKyRpbnZhbGlkID0gImZvby1ceGZjXHhhMVx4YTFceGExXHhhMVx4YTEiOworJHZhbGlkID0gImZvby1ceEU3XHg5NFx4OUZceEUzXHg4M1x4OTNceEUzXHg4M1x4QkNceEUzXHg4M1x4QUIiOworCisjIG5vbi11dGY4IGlzIGZpbmUgZm9yIGRhdGEKKyRtdXRhdGlvbnMgPSBhcnJheSgKKyAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAnY29sdW1uJyA9PiAnZW50cnk6Zm9vJywKKyAgICAndmFsdWUnID0+ICRpbnZhbGlkCisgICkgKSwKKyk7CiskY2xpZW50LT5tdXRhdGVSb3coICR0LCAiZm9vIiwgJG11dGF0aW9ucyApOworCisjIHRyeSBlbXB0eSBzdHJpbmdzCiskbXV0YXRpb25zID0gYXJyYXkoCisgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgJ2NvbHVtbicgPT4gJ2VudHJ5OicsCisgICAgJ3ZhbHVlJyA9PiAiIgorICApICksCispOworJGNsaWVudC0+bXV0YXRlUm93KCAkdCwgIiIsICRtdXRhdGlvbnMgKTsKKworIyB0aGlzIHJvdyBuYW1lIGlzIHZhbGlkIHV0ZjgKKyRtdXRhdGlvbnMgPSBhcnJheSgKKyAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAnY29sdW1uJyA9PiAnZW50cnk6Zm9vJywKKyAgICAndmFsdWUnID0+ICR2YWxpZAorICApICksCispOworJGNsaWVudC0+bXV0YXRlUm93KCAkdCwgJHZhbGlkLCAkbXV0YXRpb25zICk7CisKKyMgbm9uLXV0ZjggaXMgbm90IGFsbG93ZWQgaW4gcm93IG5hbWVzCit0cnkgeworICAkbXV0YXRpb25zID0gYXJyYXkoCisgICAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAgICdjb2x1bW4nID0+ICdlbnRyeTpmb28nLAorICAgICAgJ3ZhbHVlJyA9PiAkaW52YWxpZAorICAgICkgKSwKKyAgKTsKKyAgJGNsaWVudC0+bXV0YXRlUm93KCAkdCwgJGludmFsaWQsICRtdXRhdGlvbnMgKTsKKyAgdGhyb3cgbmV3IEV4Y2VwdGlvbiggInNob3VsZG4ndCBnZXQgaGVyZSEiICk7Cit9IGNhdGNoICggSU9FcnJvciAkZSApIHsKKyAgZWNobyggImV4cGVjdGVkIGVycm9yOiB7JGUtPm1lc3NhZ2V9XG4iICk7Cit9CisKKyMgUnVuIGEgc2Nhbm5lciBvbiB0aGUgcm93cyB3ZSBqdXN0IGNyZWF0ZWQKK2VjaG8oICJTdGFydGluZyBzY2FubmVyLi4uXG4iICk7Ciskc2Nhbm5lciA9ICRjbGllbnQtPnNjYW5uZXJPcGVuKCAkdCwgIiIsIGFycmF5KCAiZW50cnk6IiApICk7Cit0cnkgeworICB3aGlsZSAodHJ1ZSkgcHJpbnRSb3coICRjbGllbnQtPnNjYW5uZXJHZXQoICRzY2FubmVyICkgKTsKK30gY2F0Y2ggKCBOb3RGb3VuZCAkbmYgKSB7CisgICRjbGllbnQtPnNjYW5uZXJDbG9zZSggJHNjYW5uZXIgKTsKKyAgZWNobyggIlNjYW5uZXIgZmluaXNoZWRcbiIgKTsKK30KKworIworIyBSdW4gc29tZSBvcGVyYXRpb25zIG9uIGEgYnVuY2ggb2Ygcm93cy4KKyMKK2ZvciAoJGU9MTAwOyAkZT49MDsgJGUtLSkgeworCisgICMgZm9ybWF0IHJvdyBrZXlzIGFzICIwMDAwMCIgdG8gIjAwMTAwIgorICAkcm93ID0gc3RyX3BhZCggJGUsIDUsICcwJywgU1RSX1BBRF9MRUZUICk7CisKKyAgJG11dGF0aW9ucyA9IGFycmF5KAorICAgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgICAnY29sdW1uJyA9PiAndW51c2VkOicsCisgICAgICAndmFsdWUnID0+ICJERUxFVEVfTUUiCisgICAgKSApLAorICApOworICAkY2xpZW50LT5tdXRhdGVSb3coICR0LCAkcm93LCAkbXV0YXRpb25zKTsKKyAgcHJpbnRSb3coICRjbGllbnQtPmdldFJvdyggJHQsICRyb3cgKSk7CisgICRjbGllbnQtPmRlbGV0ZUFsbFJvdyggJHQsICRyb3cgKTsKKworICAkbXV0YXRpb25zID0gYXJyYXkoCisgICAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAgICdjb2x1bW4nID0+ICdlbnRyeTpudW0nLAorICAgICAgJ3ZhbHVlJyA9PiAiMCIKKyAgICApICksCisgICAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAgICdjb2x1bW4nID0+ICdlbnRyeTpmb28nLAorICAgICAgJ3ZhbHVlJyA9PiAiRk9PIgorICAgICkgKSwKKyAgKTsKKyAgJGNsaWVudC0+bXV0YXRlUm93KCAkdCwgJHJvdywgJG11dGF0aW9ucyApOworICBwcmludFJvdyggJGNsaWVudC0+Z2V0Um93KCAkdCwgJHJvdyApKTsKKworICAkbXV0YXRpb25zID0gYXJyYXkoCisgICAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAgICdjb2x1bW4nID0+ICdlbnRyeTpmb28nLAorICAgICAgJ2lzRGVsZXRlJyA9PiAxCisgICAgKSApLAorICAgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgICAnY29sdW1uJyA9PiAnZW50cnk6bnVtJywKKyAgICAgICd2YWx1ZScgPT4gJy0xJworICAgICkgKSwKKyAgKTsKKyAgJGNsaWVudC0+bXV0YXRlUm93KCAkdCwgJHJvdywgJG11dGF0aW9ucyApOworICBwcmludFJvdyggJGNsaWVudC0+Z2V0Um93KCAkdCwgJHJvdyApICk7CisKKyAgJG11dGF0aW9ucyA9IGFycmF5KAorICAgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgICAnY29sdW1uJyA9PiAiZW50cnk6bnVtIiwKKyAgICAgICd2YWx1ZScgPT4gJGUKKyAgICApICksCisgICAgbmV3IE11dGF0aW9uKCBhcnJheSgKKyAgICAgICdjb2x1bW4nID0+ICJlbnRyeTpzcXIiLAorICAgICAgJ3ZhbHVlJyA9PiAkZSAqICRlCisgICAgKSApLAorICApOworICAkY2xpZW50LT5tdXRhdGVSb3coICR0LCAkcm93LCAkbXV0YXRpb25zICk7CisgIHByaW50Um93KCAkY2xpZW50LT5nZXRSb3coICR0LCAkcm93ICkpOworICAKKyAgJG11dGF0aW9ucyA9IGFycmF5KAorICAgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgICAnY29sdW1uJyA9PiAnZW50cnk6bnVtJywKKyAgICAgICd2YWx1ZScgPT4gJy05OTknCisgICAgKSApLAorICAgIG5ldyBNdXRhdGlvbiggYXJyYXkoCisgICAgICAnY29sdW1uJyA9PiAnZW50cnk6c3FyJywKKyAgICAgICdpc0RlbGV0ZScgPT4gMQorICAgICkgKSwKKyAgKTsKKyAgJGNsaWVudC0+bXV0YXRlUm93VHMoICR0LCAkcm93LCAkbXV0YXRpb25zLCAxICk7ICMgc2hvdWxkbid0IG92ZXJyaWRlIGxhdGVzdAorICBwcmludFJvdyggJGNsaWVudC0+Z2V0Um93KCAkdCwgJHJvdyApICk7CisKKyAgJHZlcnNpb25zID0gJGNsaWVudC0+Z2V0VmVyKCAkdCwgJHJvdywgImVudHJ5Om51bSIsIDEwICk7CisgIGVjaG8oICJyb3c6IHskcm93fSwgdmFsdWVzOiBcbiIgKTsKKyAgZm9yZWFjaCAoICR2ZXJzaW9ucyBhcyAkdiApIGVjaG8oICIgIHskdi0+dmFsdWV9O1xuIiApOworICAKKyAgdHJ5IHsKKyAgICAkY2xpZW50LT5nZXQoICR0LCAkcm93LCAiZW50cnk6Zm9vIik7CisgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbiAoICJzaG91bGRuJ3QgZ2V0IGhlcmUhICIgKTsKKyAgfSBjYXRjaCAoIE5vdEZvdW5kICRuZiApIHsKKyAgICAjIGJsYW5rCisgIH0KKworfQorCiskY29sdW1ucyA9IGFycmF5KCk7Citmb3JlYWNoICggJGNsaWVudC0+Z2V0Q29sdW1uRGVzY3JpcHRvcnMoJHQpIGFzICRjb2w9PiRkZXNjICkgeworICBlY2hvKCJjb2x1bW4gd2l0aCBuYW1lOiB7JGRlc2MtPm5hbWV9XG4iKTsKKyAgJGNvbHVtbnNbXSA9ICRkZXNjLT5uYW1lLiI6IjsKK30KKworZWNobyggIlN0YXJ0aW5nIHNjYW5uZXIuLi5cbiIgKTsKKyRzY2FubmVyID0gJGNsaWVudC0+c2Nhbm5lck9wZW5XaXRoU3RvcCggJHQsICIwMDAyMCIsICIwMDA0MCIsICRjb2x1bW5zICk7Cit0cnkgeworICB3aGlsZSAodHJ1ZSkgcHJpbnRSb3coICRjbGllbnQtPnNjYW5uZXJHZXQoICRzY2FubmVyICkgKTsKK30gY2F0Y2ggKCBOb3RGb3VuZCAkbmYgKSB7CisgICRjbGllbnQtPnNjYW5uZXJDbG9zZSggJHNjYW5uZXIgKTsKKyAgZWNobyggIlNjYW5uZXIgZmluaXNoZWRcbiIgKTsKK30KKyAgCiskdHJhbnNwb3J0LT5jbG9zZSgpOworCis/PgorPC9wcmU+Cis8L2JvZHk+Cis8L2h0bWw+CisKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy90aHJpZnQvRGVtb0NsaWVudC5weSBiL3NyYy9leGFtcGxlcy90aHJpZnQvRGVtb0NsaWVudC5weQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi4wZmIyMmI2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9EZW1vQ2xpZW50LnB5CkBAIC0wLDAgKzEsMjEzIEBACisjIS91c3IvYmluL3B5dGhvbgorJycnQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgCisgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAKKyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKycnJyAKKyMgSW5zdHJ1Y3Rpb25zOgorIyAxLiBSdW4gVGhyaWZ0IHRvIGdlbmVyYXRlIHRoZSBweXRob24gbW9kdWxlIEhCYXNlCisjICAgIHRocmlmdCAtLWdlbiBweSAuLi8uLi8uLi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvSGJhc2UudGhyaWZ0IAorIyAyLiBDcmVhdGUgYSBkaXJlY3Rvcnkgb2YgeW91ciBjaG9vc2luZyB0aGF0IGNvbnRhaW5zOgorIyAgICAgYS4gVGhpcyBmaWxlIChEZW1vQ2xpZW50LnB5KS4KKyMgICAgIGIuIFRoZSBkaXJlY3RvcnkgZ2VuLXB5L2hiYXNlIChnZW5lcmF0ZWQgYnkgaW5zdHJ1Y3Rpb24gc3RlcCAxKS4KKyMgICAgIGMuIFRoZSBkaXJlY3RvcnkgeyRUSFJJRlRfSE9NRX0vbGliL3B5L2J1aWxkL2xpYi57WU9VUl9TWVNURU19L3RocmlmdC4KKyMgICAgT3IsIG1vZGlmeSB0aGUgaW1wb3J0IHN0YXRlbWVudHMgYmVsb3cgc3VjaCB0aGF0IHRoaXMgZmlsZSBjYW4gYWNjZXNzIHRoZSAKKyMgICAgZGlyZWN0b3JpZXMgZnJvbSBzdGVwcyAzYiBhbmQgM2MuCisjIDMuIEV4ZWN1dGUge3B5dGhvbiBEZW1vQ2xpZW50LnB5fS4KKworaW1wb3J0IHN5cworaW1wb3J0IHRpbWUKKworZnJvbSB0aHJpZnQgaW1wb3J0IFRocmlmdAorZnJvbSB0aHJpZnQudHJhbnNwb3J0IGltcG9ydCBUU29ja2V0LCBUVHJhbnNwb3J0Citmcm9tIHRocmlmdC5wcm90b2NvbCBpbXBvcnQgVEJpbmFyeVByb3RvY29sCitmcm9tIGhiYXNlIGltcG9ydCB0dHlwZXMKK2Zyb20gaGJhc2UuSGJhc2UgaW1wb3J0IENsaWVudCwgQ29sdW1uRGVzY3JpcHRvciwgTXV0YXRpb24KKworZGVmIHByaW50VmVyc2lvbnMocm93LCB2ZXJzaW9ucyk6CisgIHByaW50ICJyb3c6ICIgKyByb3cgKyAiLCB2YWx1ZXM6ICIsCisgIGZvciBjZWxsIGluIHZlcnNpb25zOgorICAgIHByaW50IGNlbGwudmFsdWUgKyAiOyAiLAorICBwcmludAorCitkZWYgcHJpbnRSb3coZW50cnkpOgorICBwcmludCAicm93OiAiICsgZW50cnkucm93ICsgIiwgY29sczoiLAorICBmb3IgayBpbiBzb3J0ZWQoZW50cnkuY29sdW1ucyk6CisgICAgcHJpbnQgayArICIgPT4gIiArIGVudHJ5LmNvbHVtbnNba10udmFsdWUsCisgIHByaW50CisKKyMgTWFrZSBzb2NrZXQKK3RyYW5zcG9ydCA9IFRTb2NrZXQuVFNvY2tldCgnbG9jYWxob3N0JywgOTA5MCkKKworIyBCdWZmZXJpbmcgaXMgY3JpdGljYWwuIFJhdyBzb2NrZXRzIGFyZSB2ZXJ5IHNsb3cKK3RyYW5zcG9ydCA9IFRUcmFuc3BvcnQuVEJ1ZmZlcmVkVHJhbnNwb3J0KHRyYW5zcG9ydCkKKworIyBXcmFwIGluIGEgcHJvdG9jb2wKK3Byb3RvY29sID0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbCh0cmFuc3BvcnQpCisKKyMgQ3JlYXRlIGEgY2xpZW50IHRvIHVzZSB0aGUgcHJvdG9jb2wgZW5jb2RlcgorY2xpZW50ID0gQ2xpZW50KHByb3RvY29sKQorCisjIENvbm5lY3QhCit0cmFuc3BvcnQub3BlbigpCisKK3QgPSAiZGVtb190YWJsZSIKKworIworIyBTY2FuIGFsbCB0YWJsZXMsIGxvb2sgZm9yIHRoZSBkZW1vIHRhYmxlIGFuZCBkZWxldGUgaXQuCisjCitwcmludCAic2Nhbm5pbmcgdGFibGVzLi4uIgorZm9yIHRhYmxlIGluIGNsaWVudC5nZXRUYWJsZU5hbWVzKCk6CisgIHByaW50ICIgIGZvdW5kOiAlcyIgJSh0YWJsZSkKKyAgaWYgdGFibGUgPT0gdDoKKyAgICBpZiBjbGllbnQuaXNUYWJsZUVuYWJsZWQodGFibGUpOgorICAgICAgcHJpbnQgIiAgICBkaXNhYmxpbmcgdGFibGU6ICVzIiAgJSh0KQorICAgICAgY2xpZW50LmRpc2FibGVUYWJsZSh0YWJsZSkKKyAgICBwcmludCAiICAgIGRlbGV0aW5nIHRhYmxlOiAlcyIgICUodCkKKyAgICBjbGllbnQuZGVsZXRlVGFibGUodGFibGUpCisKK2NvbHVtbnMgPSBbXQorY29sID0gQ29sdW1uRGVzY3JpcHRvcigpCitjb2wubmFtZSA9ICdlbnRyeTonCitjb2wubWF4VmVyc2lvbnMgPSAxMAorY29sdW1ucy5hcHBlbmQoY29sKQorY29sID0gQ29sdW1uRGVzY3JpcHRvcigpCitjb2wubmFtZSA9ICd1bnVzZWQ6JworY29sdW1ucy5hcHBlbmQoY29sKQorCit0cnk6CisgIHByaW50ICJjcmVhdGluZyB0YWJsZTogJXMiICUodCkKKyAgY2xpZW50LmNyZWF0ZVRhYmxlKHQsIGNvbHVtbnMpCitleGNlcHQgQWxyZWFkeUV4aXN0cywgYWU6CisgIHByaW50ICJXQVJOOiAiICsgYWUubWVzc2FnZQorCitjb2xzID0gY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKHQpCitwcmludCAiY29sdW1uIGZhbWlsaWVzIGluICVzIiAlKHQpCitmb3IgY29sX25hbWUgaW4gY29scy5rZXlzKCk6CisgIGNvbCA9IGNvbHNbY29sX25hbWVdCisgIHByaW50ICIgIGNvbHVtbjogJXMsIG1heFZlcjogJWQiICUgKGNvbC5uYW1lLCBjb2wubWF4VmVyc2lvbnMpCisjCisjIFRlc3QgVVRGLTggaGFuZGxpbmcKKyMKK2ludmFsaWQgPSAiZm9vLVx4ZmNceGExXHhhMVx4YTFceGExXHhhMSIKK3ZhbGlkID0gImZvby1ceEU3XHg5NFx4OUZceEUzXHg4M1x4OTNceEUzXHg4M1x4QkNceEUzXHg4M1x4QUIiOworCisjIG5vbi11dGY4IGlzIGZpbmUgZm9yIGRhdGEKK211dGF0aW9ucyA9IFtNdXRhdGlvbih7ImNvbHVtbiI6ImVudHJ5OmZvbyIsICJ2YWx1ZSI6aW52YWxpZH0pXQorY2xpZW50Lm11dGF0ZVJvdyh0LCAiZm9vIiwgbXV0YXRpb25zKQorCisjIHRyeSBlbXB0eSBzdHJpbmdzCittdXRhdGlvbnMgPSBbTXV0YXRpb24oeyJjb2x1bW4iOiJlbnRyeToiLCAidmFsdWUiOiIifSldCitjbGllbnQubXV0YXRlUm93KHQsICIiLCBtdXRhdGlvbnMpCisKKyMgdGhpcyByb3cgbmFtZSBpcyB2YWxpZCB1dGY4CittdXRhdGlvbnMgPSBbTXV0YXRpb24oeyJjb2x1bW4iOiJlbnRyeTpmb28iLCAidmFsdWUiOnZhbGlkfSldCitjbGllbnQubXV0YXRlUm93KHQsIHZhbGlkLCBtdXRhdGlvbnMpCisKKyMgbm9uLXV0ZjggaXMgbm90IGFsbG93ZWQgaW4gcm93IG5hbWVzCit0cnk6CisgIG11dGF0aW9ucyA9IFtNdXRhdGlvbih7ImNvbHVtbiI6ImVudHJ5OmZvbyIsICJ2YWx1ZSI6aW52YWxpZH0pXQorICBjbGllbnQubXV0YXRlUm93KHQsIGludmFsaWQsIG11dGF0aW9ucykKK2V4Y2VwdCB0dHlwZXMuSU9FcnJvciwgZToKKyAgcHJpbnQgJ2V4cGVjdGVkIGV4Y2VwdGlvbjogJXMnICUoZS5tZXNzYWdlKQorCisjIFJ1biBhIHNjYW5uZXIgb24gdGhlIHJvd3Mgd2UganVzdCBjcmVhdGVkCitwcmludCAiU3RhcnRpbmcgc2Nhbm5lci4uLiIKK3NjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW4odCwgIiIsIFsiZW50cnk6Il0pCit0cnk6CisgIHdoaWxlIDE6CisgICAgcHJpbnRSb3coY2xpZW50LnNjYW5uZXJHZXQoc2Nhbm5lcikpCitleGNlcHQgdHR5cGVzLk5vdEZvdW5kLCBlOgorICBwcmludCAiU2Nhbm5lciBmaW5pc2hlZCIKKworIworIyBSdW4gc29tZSBvcGVyYXRpb25zIG9uIGEgYnVuY2ggb2Ygcm93cy4KKyMKK2ZvciBlIGluIHJhbmdlKDEwMCwgMCwgLTEpOgorICAgICMgZm9ybWF0IHJvdyBrZXlzIGFzICIwMDAwMCIgdG8gIjAwMTAwIgorICByb3cgPSAiJTAuNWQiICUgKGUpCisKKyAgbXV0YXRpb25zID0gW011dGF0aW9uKHsiY29sdW1uIjoidW51c2VkOiIsICJ2YWx1ZSI6IkRFTEVURV9NRSJ9KV0KKyAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucykKKyAgcHJpbnRSb3coY2xpZW50LmdldFJvdyh0LCByb3cpKQorICBjbGllbnQuZGVsZXRlQWxsUm93KHQsIHJvdykKKworICBtdXRhdGlvbnMgPSBbTXV0YXRpb24oeyJjb2x1bW4iOiJlbnRyeTpudW0iLCAidmFsdWUiOiIwIn0pLAorICAgICAgICAgICAgICAgTXV0YXRpb24oeyJjb2x1bW4iOiJlbnRyeTpmb28iLCAidmFsdWUiOiJGT08ifSldCisgIGNsaWVudC5tdXRhdGVSb3codCwgcm93LCBtdXRhdGlvbnMpCisgIHByaW50Um93KGNsaWVudC5nZXRSb3codCwgcm93KSk7CisKKyAgbXV0YXRpb25zID0gW10KKyAgbSA9IE11dGF0aW9uKCkKKyAgbS5jb2x1bW4gPSAiZW50cnk6Zm9vIgorICBtLmlzRGVsZXRlID0gMQorICBtdXRhdGlvbnMuYXBwZW5kKG0pCisgIG0gPSBNdXRhdGlvbigpCisgIG0uY29sdW1uID0gImVudHJ5Om51bSIKKyAgbS52YWx1ZSA9ICItMSIKKyAgbXV0YXRpb25zLmFwcGVuZChtKQorICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKQorICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpCisKKyAgbXV0YXRpb25zID0gW011dGF0aW9uKHsiY29sdW1uIjoiZW50cnk6bnVtIiwgInZhbHVlIjpzdHIoZSl9KSwKKyAgICAgICAgICAgICAgIE11dGF0aW9uKHsiY29sdW1uIjoiZW50cnk6c3FyIiwgInZhbHVlIjpzdHIoZSplKX0pXQorICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKQorICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpOworCisgIHRpbWUuc2xlZXAoMC4wNSkKKworICBtdXRhdGlvbnMgPSBbXQorICBtID0gTXV0YXRpb24oKQorICBtLmNvbHVtbiA9ICJlbnRyeTpudW0iCisgIG0udmFsdWUgPSAiLTk5OSIKKyAgbXV0YXRpb25zLmFwcGVuZChtKQorICBtID0gTXV0YXRpb24oKQorICBtLmNvbHVtbiA9ICJlbnRyeTpzcXIiCisgIG0uaXNEZWxldGUgPSAxCisgIG11dGF0aW9ucy5hcHBlbmQobSkKKyAgY2xpZW50Lm11dGF0ZVJvd1RzKHQsIHJvdywgbXV0YXRpb25zLCAxKSAjIHNob3VsZG4ndCBvdmVycmlkZSBsYXRlc3QKKyAgcHJpbnRSb3coY2xpZW50LmdldFJvdyh0LCByb3cpKQorCisgIHZlcnNpb25zID0gY2xpZW50LmdldFZlcih0LCByb3csICJlbnRyeTpudW0iLCAxMCkKKyAgcHJpbnRWZXJzaW9ucyhyb3csIHZlcnNpb25zKQorICBpZiBsZW4odmVyc2lvbnMpICE9IDQ6CisgICAgcHJpbnQoIkZBVEFMOiB3cm9uZyAjIG9mIHZlcnNpb25zIikKKyAgICBzeXMuZXhpdCgtMSkKKworICB0cnk6CisgICAgY2xpZW50LmdldCh0LCByb3csICJlbnRyeTpmb28iKQorICAgIHJhaXNlICJzaG91bGRuJ3QgZ2V0IGhlcmUhIgorICBleGNlcHQgdHR5cGVzLk5vdEZvdW5kLCBlOgorCXBhc3MKKworICBwcmludAorCitjb2x1bW5OYW1lcyA9IFtdCitmb3IgKGNvbCwgZGVzYykgaW4gY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKHQpLml0ZW1zKCk6CisgIHByaW50ICJjb2x1bW4gd2l0aCBuYW1lOiAiK2Rlc2MubmFtZQorICBwcmludCBkZXNjCisgIGNvbHVtbk5hbWVzLmFwcGVuZChkZXNjLm5hbWUrIjoiKQorCitwcmludCAiU3RhcnRpbmcgc2Nhbm5lci4uLiIKK3NjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW5XaXRoU3RvcCh0LCAiMDAwMjAiLCAiMDAwNDAiLCBjb2x1bW5OYW1lcykKK3RyeToKKyAgd2hpbGUgMToKKyAgICBwcmludFJvdyhjbGllbnQuc2Nhbm5lckdldChzY2FubmVyKSkKK2V4Y2VwdCB0dHlwZXMuTm90Rm91bmQ6CisgIGNsaWVudC5zY2FubmVyQ2xvc2Uoc2Nhbm5lcikKKyAgcHJpbnQgIlNjYW5uZXIgZmluaXNoZWQiCisKK3RyYW5zcG9ydC5jbG9zZSgpCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQucmIgYi9zcmMvZXhhbXBsZXMvdGhyaWZ0L0RlbW9DbGllbnQucmIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODRmODgxOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9leGFtcGxlcy90aHJpZnQvRGVtb0NsaWVudC5yYgpAQCAtMCwwICsxLDI0NSBAQAorIyEvdXNyL2Jpbi9ydWJ5CisKKyMgQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisjCisjIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisjIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisjIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorIyAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisjIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisjIEluc3RydWN0aW9uczogCisjIDEuIFJ1biBUaHJpZnQgdG8gZ2VuZXJhdGUgdGhlIHJ1YnkgbW9kdWxlIEhCYXNlCisjICAgIHRocmlmdCAtLWdlbiByYiAuLi8uLi8uLi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvSGJhc2UudGhyaWZ0IAorIyAyLiBNb2RpZnkgdGhlIGltcG9ydCBzdHJpbmcgYmVsb3cgdG8gcG9pbnQgdG8geyRUSFJJRlRfSE9NRX0vbGliL3JiL2xpYi4KKyMgMy4gRXhlY3V0ZSB7cnVieSBEZW1vQ2xpZW50LnJifS4KKworIyBZb3Ugd2lsbCBuZWVkIHRvIG1vZGlmeSB0aGlzIGltcG9ydCBzdHJpbmc6CiskOi5wdXNoKCd+L1RocmlmdC90aHJpZnQtMjAwODA0MTFwMS9saWIvcmIvbGliJykKKyQ6LnB1c2goJy4vZ2VuLXJiJykKKworcmVxdWlyZSAndGhyaWZ0L3RyYW5zcG9ydC90c29ja2V0JworcmVxdWlyZSAndGhyaWZ0L3Byb3RvY29sL3RiaW5hcnlwcm90b2NvbCcKKworcmVxdWlyZSAnSGJhc2UnCisKK2RlZiBwcmludFJvdyhyb3dyZXN1bHQpCisgIHByaW50ICJyb3c6ICN7cm93cmVzdWx0LnJvd30sIGNvbHM6ICIKKyAgcm93cmVzdWx0LmNvbHVtbnMuc29ydC5lYWNoIGRvIHxrLHZ8CisgICAgcHJpbnQgIiN7a30gPT4gI3t2LnZhbHVlfTsgIgorICBlbmQKKyAgcHV0cyAiIgorZW5kCisKK3RyYW5zcG9ydCA9IFRCdWZmZXJlZFRyYW5zcG9ydC5uZXcoVFNvY2tldC5uZXcoImxvY2FsaG9zdCIsIDkwOTApKQorcHJvdG9jb2wgPSBUQmluYXJ5UHJvdG9jb2wubmV3KHRyYW5zcG9ydCkKK2NsaWVudCA9IEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpIYmFzZTo6Q2xpZW50Lm5ldyhwcm90b2NvbCkKKwordHJhbnNwb3J0Lm9wZW4oKQorCit0ID0gImRlbW9fdGFibGUiCisKKyMKKyMgU2NhbiBhbGwgdGFibGVzLCBsb29rIGZvciB0aGUgZGVtbyB0YWJsZSBhbmQgZGVsZXRlIGl0LgorIworcHV0cyAic2Nhbm5pbmcgdGFibGVzLi4uIgorY2xpZW50LmdldFRhYmxlTmFtZXMoKS5zb3J0LmVhY2ggZG8gfG5hbWV8CisgIHB1dHMgIiAgZm91bmQ6ICN7bmFtZX0iCisgIGlmIChuYW1lID09IHQpCisgICAgaWYgKGNsaWVudC5pc1RhYmxlRW5hYmxlZChuYW1lKSkKKyAgICAgIHB1dHMgIiAgICBkaXNhYmxpbmcgdGFibGU6ICN7bmFtZX0iCisgICAgICBjbGllbnQuZGlzYWJsZVRhYmxlKG5hbWUpCisgICAgZW5kCisgICAgcHV0cyAiICAgIGRlbGV0aW5nIHRhYmxlOiAje25hbWV9IiAKKyAgICBjbGllbnQuZGVsZXRlVGFibGUobmFtZSkKKyAgZW5kCitlbmQKKworIworIyBDcmVhdGUgdGhlIGRlbW8gdGFibGUgd2l0aCB0d28gY29sdW1uIGZhbWlsaWVzLCBlbnRyeTogYW5kIHVudXNlZDoKKyMKK2NvbHVtbnMgPSBbXQorY29sID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6OkNvbHVtbkRlc2NyaXB0b3IubmV3Citjb2wubmFtZSA9ICJlbnRyeToiCitjb2wubWF4VmVyc2lvbnMgPSAxMAorY29sdW1ucyA8PCBjb2w7Citjb2wgPSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6Q29sdW1uRGVzY3JpcHRvci5uZXcKK2NvbC5uYW1lID0gInVudXNlZDoiCitjb2x1bW5zIDw8IGNvbDsKKworcHV0cyAiY3JlYXRpbmcgdGFibGU6ICN7dH0iCitiZWdpbgorICBjbGllbnQuY3JlYXRlVGFibGUodCwgY29sdW1ucykKK3Jlc2N1ZSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6QWxyZWFkeUV4aXN0cyA9PiBhZQorICBwdXRzICJXQVJOOiAje2FlLm1lc3NhZ2V9IgorZW5kCisKK3B1dHMgImNvbHVtbiBmYW1pbGllcyBpbiAje3R9OiAiCitjbGllbnQuZ2V0Q29sdW1uRGVzY3JpcHRvcnModCkuc29ydC5lYWNoIGRvIHxrZXksIGNvbHwKKyAgcHV0cyAiICBjb2x1bW46ICN7Y29sLm5hbWV9LCBtYXhWZXI6ICN7Y29sLm1heFZlcnNpb25zfSIKK2VuZAorCisjCisjIFRlc3QgVVRGLTggaGFuZGxpbmcKKyMKK2ludmFsaWQgPSAiZm9vLVx4ZmNceGExXHhhMVx4YTFceGExXHhhMSIKK3ZhbGlkID0gImZvby1ceEU3XHg5NFx4OUZceEUzXHg4M1x4OTNceEUzXHg4M1x4QkNceEUzXHg4M1x4QUIiOworCisjIG5vbi11dGY4IGlzIGZpbmUgZm9yIGRhdGEKK211dGF0aW9ucyA9IFtdCittID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworbS5jb2x1bW4gPSAiZW50cnk6Zm9vIgorbS52YWx1ZSA9IGludmFsaWQKK211dGF0aW9ucyA8PCBtCitjbGllbnQubXV0YXRlUm93KHQsICJmb28iLCBtdXRhdGlvbnMpCisKKyMgdHJ5IGVtcHR5IHN0cmluZ3MKK211dGF0aW9ucyA9IFtdCittID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworbS5jb2x1bW4gPSAiZW50cnk6IgorbS52YWx1ZSA9ICIiCittdXRhdGlvbnMgPDwgbQorY2xpZW50Lm11dGF0ZVJvdyh0LCAiIiwgbXV0YXRpb25zKQorCisjIHRoaXMgcm93IG5hbWUgaXMgdmFsaWQgdXRmOAorbXV0YXRpb25zID0gW10KK20gPSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6TXV0YXRpb24ubmV3CittLmNvbHVtbiA9ICJlbnRyeTpmb28iCittLnZhbHVlID0gdmFsaWQKK211dGF0aW9ucyA8PCBtCitjbGllbnQubXV0YXRlUm93KHQsIHZhbGlkLCBtdXRhdGlvbnMpCisKKyMgbm9uLXV0ZjggaXMgbm90IGFsbG93ZWQgaW4gcm93IG5hbWVzCitiZWdpbgorICBtdXRhdGlvbnMgPSBbXQorICBtID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworICBtLmNvbHVtbiA9ICJlbnRyeTpmb28iCisgIG0udmFsdWUgPSBpbnZhbGlkCisgIG11dGF0aW9ucyA8PCBtCisgIGNsaWVudC5tdXRhdGVSb3codCwgaW52YWxpZCwgbXV0YXRpb25zKQorICByYWlzZSAic2hvdWxkbid0IGdldCBoZXJlISIKK3Jlc2N1ZSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6SU9FcnJvciA9PiBlCisgIHB1dHMgImV4cGVjdGVkIGVycm9yOiAje2UubWVzc2FnZX0iCitlbmQKKworIyBSdW4gYSBzY2FubmVyIG9uIHRoZSByb3dzIHdlIGp1c3QgY3JlYXRlZAorcHV0cyAiU3RhcnRpbmcgc2Nhbm5lci4uLiIKK3NjYW5uZXIgPSBjbGllbnQuc2Nhbm5lck9wZW4odCwgIiIsIFsiZW50cnk6Il0pCitiZWdpbgorICB3aGlsZSAodHJ1ZSkgCisgICAgcHJpbnRSb3coY2xpZW50LnNjYW5uZXJHZXQoc2Nhbm5lcikpCisgIGVuZAorcmVzY3VlIEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpOb3RGb3VuZCA9PiBuZgorICBjbGllbnQuc2Nhbm5lckNsb3NlKHNjYW5uZXIpCisgIHB1dHMgIlNjYW5uZXIgZmluaXNoZWQiCitlbmQKKworIworIyBSdW4gc29tZSBvcGVyYXRpb25zIG9uIGEgYnVuY2ggb2Ygcm93cy4KKyMKKygwLi4xMDApLnRvX2EucmV2ZXJzZS5lYWNoIGRvIHxlfAorICAjIGZvcm1hdCByb3cga2V5cyBhcyAiMDAwMDAiIHRvICIwMDEwMCIKKyAgcm93ID0gZm9ybWF0KCIlMC41ZCIsIGUpCisKKyAgbXV0YXRpb25zID0gW10KKyAgbSA9IEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpNdXRhdGlvbi5uZXcKKyAgbS5jb2x1bW4gPSAidW51c2VkOiIKKyAgbS52YWx1ZSA9ICJERUxFVEVfTUUiCisgIG11dGF0aW9ucyA8PCBtCisgIGNsaWVudC5tdXRhdGVSb3codCwgcm93LCBtdXRhdGlvbnMpCisgIHByaW50Um93KGNsaWVudC5nZXRSb3codCwgcm93KSkKKyAgY2xpZW50LmRlbGV0ZUFsbFJvdyh0LCByb3cpCisKKyAgbXV0YXRpb25zID0gW10KKyAgbSA9IEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpNdXRhdGlvbi5uZXcKKyAgbS5jb2x1bW4gPSAiZW50cnk6bnVtIgorICBtLnZhbHVlID0gIjAiCisgIG11dGF0aW9ucyA8PCBtCisgIG0gPSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6TXV0YXRpb24ubmV3CisgIG0uY29sdW1uID0gImVudHJ5OmZvbyIKKyAgbS52YWx1ZSA9ICJGT08iCisgIG11dGF0aW9ucyA8PCBtCisgIGNsaWVudC5tdXRhdGVSb3codCwgcm93LCBtdXRhdGlvbnMpCisgIHByaW50Um93KGNsaWVudC5nZXRSb3codCwgcm93KSkKKworICBtdXRhdGlvbnMgPSBbXQorICBtID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworICBtLmNvbHVtbiA9ICJlbnRyeTpmb28iCisgIG0uaXNEZWxldGUgPSAxCisgIG11dGF0aW9ucyA8PCBtCisgIG0gPSBBcGFjaGU6OkhhZG9vcDo6SGJhc2U6OlRocmlmdDo6TXV0YXRpb24ubmV3CisgIG0uY29sdW1uID0gImVudHJ5Om51bSIKKyAgbS52YWx1ZSA9ICItMSIKKyAgbXV0YXRpb25zIDw8IG0KKyAgY2xpZW50Lm11dGF0ZVJvdyh0LCByb3csIG11dGF0aW9ucykKKyAgcHJpbnRSb3coY2xpZW50LmdldFJvdyh0LCByb3cpKTsKKworICBtdXRhdGlvbnMgPSBbXQorICBtID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworICBtLmNvbHVtbiA9ICJlbnRyeTpudW0iCisgIG0udmFsdWUgPSBlLnRvX3MKKyAgbXV0YXRpb25zIDw8IG0KKyAgbSA9IEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpNdXRhdGlvbi5uZXcKKyAgbS5jb2x1bW4gPSAiZW50cnk6c3FyIgorICBtLnZhbHVlID0gKGUqZSkudG9fcworICBtdXRhdGlvbnMgPDwgbQorICBjbGllbnQubXV0YXRlUm93KHQsIHJvdywgbXV0YXRpb25zKQorICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpCisgIAorICBtdXRhdGlvbnMgPSBbXQorICBtID0gQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok11dGF0aW9uLm5ldworICBtLmNvbHVtbiA9ICJlbnRyeTpudW0iCisgIG0udmFsdWUgPSAiLTk5OSIKKyAgbXV0YXRpb25zIDw8IG0KKyAgbSA9IEFwYWNoZTo6SGFkb29wOjpIYmFzZTo6VGhyaWZ0OjpNdXRhdGlvbi5uZXcKKyAgbS5jb2x1bW4gPSAiZW50cnk6c3FyIgorICBtLmlzRGVsZXRlID0gMQorICBtdXRhdGlvbnMgPDwgbQorICBjbGllbnQubXV0YXRlUm93VHModCwgcm93LCBtdXRhdGlvbnMsIDEpICMgc2hvdWxkbid0IG92ZXJyaWRlIGxhdGVzdAorICBwcmludFJvdyhjbGllbnQuZ2V0Um93KHQsIHJvdykpOworCisgIHZlcnNpb25zID0gY2xpZW50LmdldFZlcih0LCByb3csICJlbnRyeTpudW0iLCAxMCkKKyAgcHJpbnQgInJvdzogI3tyb3d9LCB2YWx1ZXM6ICIKKyAgdmVyc2lvbnMuZWFjaCBkbyB8dnwKKyAgICBwcmludCAiI3t2LnZhbHVlfTsgIgorICBlbmQKKyAgcHV0cyAiIiAgICAKKyAgCisgIGJlZ2luCisgICAgY2xpZW50LmdldCh0LCByb3csICJlbnRyeTpmb28iKQorICAgIHJhaXNlICJzaG91bGRuJ3QgZ2V0IGhlcmUhIgorICByZXNjdWUgQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok5vdEZvdW5kID0+IG5mCisgICAgIyBibGFuaworICBlbmQKKworICBwdXRzICIiCitlbmQgCisKK2NvbHVtbnMgPSBbXQorY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKHQpLmVhY2ggZG8gfGNvbCwgZGVzY3wKKyAgcHV0cyAiY29sdW1uIHdpdGggbmFtZTogI3tkZXNjLm5hbWV9IgorICBjb2x1bW5zIDw8IGRlc2MubmFtZSArICI6IgorZW5kCisKK3B1dHMgIlN0YXJ0aW5nIHNjYW5uZXIuLi4iCitzY2FubmVyID0gY2xpZW50LnNjYW5uZXJPcGVuV2l0aFN0b3AodCwgIjAwMDIwIiwgIjAwMDQwIiwgY29sdW1ucykKK2JlZ2luCisgIHdoaWxlICh0cnVlKSAKKyAgICBwcmludFJvdyhjbGllbnQuc2Nhbm5lckdldChzY2FubmVyKSkKKyAgZW5kCityZXNjdWUgQXBhY2hlOjpIYWRvb3A6OkhiYXNlOjpUaHJpZnQ6Ok5vdEZvdW5kID0+IG5mCisgIGNsaWVudC5zY2FubmVyQ2xvc2Uoc2Nhbm5lcikKKyAgcHV0cyAiU2Nhbm5lciBmaW5pc2hlZCIKK2VuZAorICAKK3RyYW5zcG9ydC5jbG9zZSgpCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdGhyaWZ0L01ha2VmaWxlIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9NYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OTFhMWU5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9NYWtlZmlsZQpAQCAtMCwwICsxLDM1IEBACisjIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorIworIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisjIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorIyByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKworIyBNYWtlZmlsZSBmb3IgQysrIEhiYXNlIFRocmlmdCBEZW1vQ2xpZW50CisjIE5PVEU6IHJ1biAndGhyaWZ0IC1jcHAgSGJhc2UudGhyaWZ0JyBmaXJzdAorCitUSFJJRlRfRElSID0gL3Vzci9sb2NhbC9pbmNsdWRlL3RocmlmdAorTElCX0RJUiA9IC91c3IvbG9jYWwvbGliCisKK0dFTl9TUkMgPSAuL2dlbi1jcHAvSGJhc2UuY3BwIFwKKwkgIC4vZ2VuLWNwcC9IYmFzZV90eXBlcy5jcHAgXAorCSAgLi9nZW4tY3BwL0hiYXNlX2NvbnN0YW50cy5jcHAKKworZGVmYXVsdDogRGVtb0NsaWVudAorCitEZW1vQ2xpZW50OiBEZW1vQ2xpZW50LmNwcAorCWcrKyAtbyBEZW1vQ2xpZW50IC1JJHtUSFJJRlRfRElSfSAgLUkuL2dlbi1jcHAgLUwke0xJQl9ESVJ9IC1sdGhyaWZ0IERlbW9DbGllbnQuY3BwICR7R0VOX1NSQ30KKworY2xlYW46CisJcm0gLXJmIERlbW9DbGllbnQKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy90aHJpZnQvUkVBRE1FLnR4dCBiL3NyYy9leGFtcGxlcy90aHJpZnQvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzQyZjhkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3RocmlmdC9SRUFETUUudHh0CkBAIC0wLDAgKzEsMTYgQEAKK0hiYXNlIFRocmlmdCBDbGllbnQgRXhhbXBsZXMKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW5jbHVkZWQgaW4gdGhpcyBkaXJlY3RvcnkgYXJlIHNhbXBsZSBjbGllbnRzIG9mIHRoZSBIQmFzZSBUaHJpZnRTZXJ2ZXIuICBUaGV5CithbGwgcGVyZm9ybSB0aGUgc2FtZSBhY3Rpb25zIGJ1dCBhcmUgaW1wbGVtZW50ZWQgaW4gQysrLCBKYXZhLCBSdWJ5LCBQSFAsIGFuZAorUHl0aG9uIHJlc3BlY3RpdmVseS4KKworVG8gcnVuL2NvbXBpbGUgdGhpcyBjbGllbnRzLCB5b3Ugd2lsbCBmaXJzdCBuZWVkIHRvIGluc3RhbGwgdGhlIHRocmlmdCBwYWNrYWdlCisoZnJvbSBodHRwOi8vZGV2ZWxvcGVycy5mYWNlYm9vay5jb20vdGhyaWZ0LykgYW5kIHRoZW4gcnVuIHRocmlmdCB0byBnZW5lcmF0ZQordGhlIGxhbmd1YWdlIGZpbGVzOgorCit0aHJpZnQgLS1nZW4gY3BwIC0tZ2VuIGphdmEgLS1nZW4gcmIgLS1nZW4gcHkgLXBocCBcCisgICAgLi4vLi4vLi4vc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L0hiYXNlLnRocmlmdAorCitTZWUgdGhlIGluZGl2aWR1YWwgRGVtb0NsaWVudCB0ZXN0IGZpbGVzIGZvciBtb3JlIHNwZWNpZmljIGluc3RydWN0aW9ucyBvbiAKK3J1bm5pbmcgZWFjaCB0ZXN0LgpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IQmFzZUNvbm5lY3Rpb24ucHkgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hCYXNlQ29ubmVjdGlvbi5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODAwNmIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IQmFzZUNvbm5lY3Rpb24ucHkKQEAgLTAsMCArMSwzOSBAQAoraW1wb3J0IHN5cywgb3MKKworZnJvbSBIYmFzZS50dHlwZXMgaW1wb3J0ICoKK2Zyb20gSGJhc2UgaW1wb3J0IEhiYXNlCisKK2Zyb20gdGhyaWZ0IGltcG9ydCBUaHJpZnQKK2Zyb20gdGhyaWZ0LnRyYW5zcG9ydCBpbXBvcnQgVFNvY2tldCwgVFRyYW5zcG9ydAorZnJvbSB0aHJpZnQucHJvdG9jb2wgaW1wb3J0IFRCaW5hcnlQcm90b2NvbAorCitjbGFzcyBIQmFzZUNvbm5lY3Rpb246CisgIGRlZiBfX2luaXRfXyhzZWxmLCBob3N0bmFtZSwgcG9ydCk6CisgICAgIyBNYWtlIHNvY2tldAorICAgIHNlbGYudHJhbnNwb3J0ID0gVFNvY2tldC5UU29ja2V0KGhvc3RuYW1lLCBwb3J0KQorICAgICMgQnVmZmVyaW5nIGlzIGNyaXRpY2FsLiBSYXcgc29ja2V0cyBhcmUgdmVyeSBzbG93CisgICAgc2VsZi50cmFuc3BvcnQgPSBUVHJhbnNwb3J0LlRCdWZmZXJlZFRyYW5zcG9ydChzZWxmLnRyYW5zcG9ydCkKKyAgICAjIFdyYXAgaW4gYSBwcm90b2NvbAorICAgIHNlbGYucHJvdG9jb2wgPSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sKHNlbGYudHJhbnNwb3J0KQorICAgICMgQ3JlYXRlIGEgY2xpZW50IHRvIHVzZSB0aGUgcHJvdG9jb2wgZW5jb2RlcgorICAgIHNlbGYuY2xpZW50ID0gSGJhc2UuQ2xpZW50KHNlbGYucHJvdG9jb2wpCisgCisgIGRlZiBjb25uZWN0KHNlbGYpOiAgCisgICAgc2VsZi50cmFuc3BvcnQub3BlbigpCisgICAKKyAgZGVmIGRpc2Nvbm5lY3Qoc2VsZik6CisgICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKQorICAgIAorICBkZWYgdmFsaWRhdGVfY29sdW1uX2Rlc2NyaXB0b3JzKHNlbGYsIHRhYmxlX25hbWUsIGNvbHVtbl9kZXNjcmlwdG9ycyk6CisgICAgaGJhc2VfZmFtaWxpZXMgPSBzZWxmLmNsaWVudC5nZXRDb2x1bW5EZXNjcmlwdG9ycyh0YWJsZV9uYW1lKQorICAgIGZvciBjb2xfZGVzYyBpbiBjb2x1bW5fZGVzY3JpcHRvcnM6CisgICAgICBmYW1pbHksIGNvbHVtbiA9IGNvbF9kZXNjLnNwbGl0KCI6IikKKyAgICAgIGlmIG5vdCBmYW1pbHkgaW4gaGJhc2VfZmFtaWxpZXM6CisgICAgICAgIHJhaXNlIEV4Y2VwdGlvbigiSW52YWxpZCBjb2x1bW4gZGVzY3JpcHRvciBcIiVzXCIgZm9yIGhiYXNlIHRhYmxlIFwiJXNcIiIgJSAoY29sX2Rlc2MsdGFibGVfbmFtZSkpCisgICAgICAKKyAgZGVmIHZhbGlkYXRlX3RhYmxlX25hbWUoc2VsZiwgdGFibGVfbmFtZSk6CisgICAgaWYgbm90IHRhYmxlX25hbWUgaW4gc2VsZi5jbGllbnQuZ2V0VGFibGVOYW1lcygpOgorICAgICAgcmFpc2UgRXhjZXB0aW9uKCJoYmFzZSB0YWJsZSAnJXMnIG5vdCBmb3VuZC4iICUgKHRhYmxlX25hbWUpKQorICAgIAorICAKKyAgClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IQmFzZUNvbnN1bWVyLnB5IGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IQmFzZUNvbnN1bWVyLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3NWYzMzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hCYXNlQ29uc3VtZXIucHkKQEAgLTAsMCArMSw5MCBAQAoraW1wb3J0IHN5cywgb3MsIHBncSwgc2t5dG9vbHMsIENvbmZpZ1BhcnNlcgorCitmcm9tIHRocmlmdCBpbXBvcnQgVGhyaWZ0Citmcm9tIHRocmlmdC50cmFuc3BvcnQgaW1wb3J0IFRTb2NrZXQsIFRUcmFuc3BvcnQKK2Zyb20gdGhyaWZ0LnByb3RvY29sIGltcG9ydCBUQmluYXJ5UHJvdG9jb2wKKworZnJvbSBIQmFzZUNvbm5lY3Rpb24gaW1wb3J0ICoKK2ltcG9ydCB0YWJsZW1hcHBpbmcKKworSU5TRVJUID0gJ0knCitVUERBVEUgPSAnVScKK0RFTEVURSA9ICdEJworCitjbGFzcyBIQmFzZUNvbnN1bWVyKHBncS5Db25zdW1lcik6CisgICIiIkhCYXNlQ29uc3VtZXIgaXMgYSBwZ3EuQ29uc3VtZXIgdGhhdCBzZW5kcyBwcm9jZXNzZWQgZXZlbnRzIHRvIGhiYXNlIGFzIG11dGF0aW9ucy4iIiIKKyAgCisgIGRlZiBfX2luaXRfXyhzZWxmLCBzZXJ2aWNlX25hbWUsIGFyZ3MpOgorICAgIHBncS5Db25zdW1lci5fX2luaXRfXyhzZWxmLCBzZXJ2aWNlX25hbWUsICJwb3N0Z3Jlc3FsX2RiIiwgYXJncykKKyAgICAKKyAgICBjb25maWdfZmlsZSA9IHNlbGYuYXJnc1swXQorICAgIGlmIGxlbihzZWxmLmFyZ3MpIDwgMjoKKyAgICAgIHByaW50ICJuZWVkIHRhYmxlIG5hbWVzIgorICAgICAgc3lzLmV4aXQoMSkKKyAgICBlbHNlOgorICAgICAgc2VsZi50YWJsZV9uYW1lcyA9IHNlbGYuYXJnc1sxOl0KKyAgICAgIAorICAgICNqdXN0IHRvIGNoZWNrIHRoaXMgb3B0aW9uIGV4aXN0cworICAgIHNlbGYuY2YuZ2V0KCJwb3N0Z3Jlc3FsX2RiIikKKyAgICAKKyAgICBzZWxmLm1heF9iYXRjaF9zaXplID0gaW50KHNlbGYuY2YuZ2V0KCJtYXhfYmF0Y2hfc2l6ZSIsICIxMDAwMCIpKQorICAgIHNlbGYuaGJhc2VfaG9zdG5hbWUgPSBzZWxmLmNmLmdldCgiaGJhc2VfaG9zdG5hbWUiLCAibG9jYWxob3N0IikKKyAgICBzZWxmLmhiYXNlX3BvcnQgPSBpbnQoc2VsZi5jZi5nZXQoImhiYXNlX3BvcnQiLCAiOTA5MCIpKQorICAgIHNlbGYucm93X2xpbWl0ID0gaW50KHNlbGYuY2YuZ2V0KCJib290c3RyYXBfcm93X2xpbWl0IiwgMCkpCisgICAgc2VsZi50YWJsZV9tYXBwaW5ncyA9IHRhYmxlbWFwcGluZy5sb2FkX3RhYmxlX21hcHBpbmdzKGNvbmZpZ19maWxlLCBzZWxmLnRhYmxlX25hbWVzKQorICAKKyAgZGVmIHByb2Nlc3NfYmF0Y2goc2VsZiwgc291cmNlX2RiLCBiYXRjaF9pZCwgZXZlbnRfbGlzdCk6CisgICAgdHJ5OgorICAgICAgc2VsZi5sb2cuZGVidWcoInByb2Nlc3NpbmcgYmF0Y2ggJXMiICUgKGJhdGNoX2lkKSkKKyAgICAgIGhiYXNlID0gSEJhc2VDb25uZWN0aW9uKHNlbGYuaGJhc2VfaG9zdG5hbWUsIHNlbGYuaGJhc2VfcG9ydCkKKyAgICAgIHRyeToKKyAgICAgICAgc2VsZi5sb2cuZGVidWcoIkNvbm5lY3RpbmcgdG8gSEJhc2UiKQorICAgICAgICBoYmFzZS5jb25uZWN0KCkKKyAgICAgICAgICAgICAgCisgICAgICAgIGkgPSAwTAorICAgICAgICBmb3IgZXZlbnQgaW4gZXZlbnRfbGlzdDoKKyAgICAgICAgICBpID0gaSsxCisgICAgICAgICAgc2VsZi5wcm9jZXNzX2V2ZW50KGV2ZW50LCBoYmFzZSkKKyAgICAgICAgcHJpbnQgIiVpIGV2ZW50cyBwcm9jZXNzZWQiICUgKGkpCisgICAgICAgIAorICAgICAgZXhjZXB0IEV4Y2VwdGlvbiwgZToKKyAgICAgICAgI3NlbGYubG9nLmluZm8oZSkKKyAgICAgICAgc3lzLmV4aXQoZSkKKyAgICAgIAorICAgIGZpbmFsbHk6CisgICAgICBoYmFzZS5kaXNjb25uZWN0KCkKKyAgCisgIGRlZiBwcm9jZXNzX2V2ZW50KHNlbGYsIGV2ZW50LCBoYmFzZSk6CisgICAgaWYgZXZlbnQuZXZfZXh0cmExIGluIHNlbGYudGFibGVfbWFwcGluZ3M6CisgICAgICB0YWJsZV9tYXBwaW5nID0gc2VsZi50YWJsZV9tYXBwaW5nc1tldmVudC5ldl9leHRyYTFdCisgICAgZWxzZToKKyAgICAgIHNlbGYubG9nLmluZm8oInRhYmxlIG5hbWUgbm90IGZvdW5kIGluIGNvbmZpZywgc2tpcHBpbmcgZXZlbnQiKQorICAgICAgcmV0dXJuCisgICAgI2hiYXNlLnZhbGlkYXRlX3RhYmxlX25hbWUodGFibGVfbWFwcGluZy5oYmFzZV90YWJsZV9uYW1lKQorICAgICNoYmFzZS52YWxpZGF0ZV9jb2x1bW5fZGVzY3JpcHRvcnModGFibGVfbWFwcGluZy5oYmFzZV90YWJsZV9uYW1lLCB0YWJsZV9tYXBwaW5nLmhiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycykKKyAgICBldmVudF9kYXRhID0gc2t5dG9vbHMuZGJfdXJsZGVjb2RlKGV2ZW50LmRhdGEpCisgICAgZXZlbnRfdHlwZSA9IGV2ZW50LnR5cGUuc3BsaXQoJzonKVswXQorICAgIAorICAgIGJhdGNoID0gQmF0Y2hNdXRhdGlvbigpCisgICAgYmF0Y2gucm93ID0gdGFibGVfbWFwcGluZy5oYmFzZV9yb3dfcHJlZml4ICsgc3RyKGV2ZW50X2RhdGFbdGFibGVfbWFwcGluZy5wc3FsX2tleV9jb2x1bW5dKQorICAgICAgICAKKyAgICBiYXRjaC5tdXRhdGlvbnMgPSBbXQorICAgIGZvciBwc3FsX2NvbHVtbiwgaGJhc2VfY29sdW1uIGluIHppcCh0YWJsZV9tYXBwaW5nLnBzcWxfY29sdW1ucywgdGFibGVfbWFwcGluZy5oYmFzZV9jb2x1bW5fZGVzY3JpcHRvcnMpOgorICAgICAgaWYgZXZlbnRfdHlwZSA9PSBJTlNFUlQgb3IgZXZlbnRfdHlwZSA9PSBVUERBVEU6CisgICAgICAgIG0gPSBNdXRhdGlvbigpCisgICAgICAgIG0uY29sdW1uID0gaGJhc2VfY29sdW1uCisgICAgICAgIG0udmFsdWUgPSBzdHIoZXZlbnRfZGF0YVtwc3FsX2NvbHVtbl0pCisgICAgICBlbGlmIGV2ZW50X3R5cGUgPT0gREVMRVRFOgorICAgICAgICAjIGRlbGV0ZSB0aGlzIGNvbHVtbiBlbnRyeQorICAgICAgICBtID0gTXV0YXRpb24oKQorICAgICAgICBtLmlzRGVsZXRlID0gVHJ1ZQorICAgICAgICBtLmNvbHVtbiA9IGhiYXNlX2NvbHVtbgorICAgICAgZWxzZToKKyAgICAgICAgcmFpc2UgRXhjZXB0aW9uKCJJbnZhbGlkIGV2ZW50IHR5cGU6ICVzLCBldmVudCBkYXRhIHdhczogJXMiICUgKGV2ZW50X3R5cGUsIHN0cihldmVudF9kYXRhKSkpCisgICAgICBiYXRjaC5tdXRhdGlvbnMuYXBwZW5kKG0pCisgICAgaGJhc2UuY2xpZW50Lm11dGF0ZVJvdyh0YWJsZV9tYXBwaW5nLmhiYXNlX3RhYmxlX25hbWUsIGJhdGNoLnJvdywgYmF0Y2gubXV0YXRpb25zKQorICAgIGV2ZW50LnRhZ19kb25lKCkKKyAgICAKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIHNjcmlwdCA9IEhCYXNlQ29uc3VtZXIoIkhCYXNlUmVwbGljIixzeXMuYXJndlsxOl0pCisgIHNjcmlwdC5zdGFydCgpCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL0hiYXNlLXJlbW90ZSBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvSGJhc2UvSGJhc2UtcmVtb3RlCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjJlYzllOTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL0hiYXNlLXJlbW90ZQpAQCAtMCwwICsxLDI0NyBAQAorIyEvdXNyL2Jpbi9lbnYgcHl0aG9uCisjCisjIEF1dG9nZW5lcmF0ZWQgYnkgVGhyaWZ0CisjCisjIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyMKKworaW1wb3J0IHN5cworaW1wb3J0IHBwcmludAorZnJvbSB1cmxwYXJzZSBpbXBvcnQgdXJscGFyc2UKK2Zyb20gdGhyaWZ0LnRyYW5zcG9ydCBpbXBvcnQgVFRyYW5zcG9ydAorZnJvbSB0aHJpZnQudHJhbnNwb3J0IGltcG9ydCBUU29ja2V0Citmcm9tIHRocmlmdC50cmFuc3BvcnQgaW1wb3J0IFRIdHRwQ2xpZW50Citmcm9tIHRocmlmdC5wcm90b2NvbCBpbXBvcnQgVEJpbmFyeVByb3RvY29sCisKK2ltcG9ydCBIYmFzZQorZnJvbSB0dHlwZXMgaW1wb3J0ICoKKworaWYgbGVuKHN5cy5hcmd2KSA8PSAxIG9yIHN5cy5hcmd2WzFdID09ICctLWhlbHAnOgorICBwcmludCAnJworICBwcmludCAnVXNhZ2U6ICcgKyBzeXMuYXJndlswXSArICcgWy1oIGhvc3Q6cG9ydF0gWy11IHVybF0gWy1mW3JhbWVkXV0gZnVuY3Rpb24gW2FyZzEgW2FyZzIuLi5dXScKKyAgcHJpbnQgJycKKyAgcHJpbnQgJ0Z1bmN0aW9uczonCisgIHByaW50ICcgICBnZXRUYWJsZU5hbWVzKCknCisgIHByaW50ICcgICBnZXRDb2x1bW5EZXNjcmlwdG9ycyhUZXh0IHRhYmxlTmFtZSknCisgIHByaW50ICcgICBnZXRUYWJsZVJlZ2lvbnMoVGV4dCB0YWJsZU5hbWUpJworICBwcmludCAnICB2b2lkIGNyZWF0ZVRhYmxlKFRleHQgdGFibGVOYW1lLCAgY29sdW1uRmFtaWxpZXMpJworICBwcmludCAnICB2b2lkIGRlbGV0ZVRhYmxlKFRleHQgdGFibGVOYW1lKScKKyAgcHJpbnQgJyAgQnl0ZXMgZ2V0KFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgVGV4dCBjb2x1bW4pJworICBwcmludCAnICAgZ2V0VmVyKFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgVGV4dCBjb2x1bW4sIGkzMiBudW1WZXJzaW9ucyknCisgIHByaW50ICcgICBnZXRWZXJUcyhUZXh0IHRhYmxlTmFtZSwgVGV4dCByb3csIFRleHQgY29sdW1uLCBpNjQgdGltZXN0YW1wLCBpMzIgbnVtVmVyc2lvbnMpJworICBwcmludCAnICAgZ2V0Um93KFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdyknCisgIHByaW50ICcgICBnZXRSb3dUcyhUZXh0IHRhYmxlTmFtZSwgVGV4dCByb3csIGk2NCB0aW1lc3RhbXApJworICBwcmludCAnICB2b2lkIHB1dChUZXh0IHRhYmxlTmFtZSwgVGV4dCByb3csIFRleHQgY29sdW1uLCBCeXRlcyB2YWx1ZSknCisgIHByaW50ICcgIHZvaWQgbXV0YXRlUm93KFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgIG11dGF0aW9ucyknCisgIHByaW50ICcgIHZvaWQgbXV0YXRlUm93VHMoVGV4dCB0YWJsZU5hbWUsIFRleHQgcm93LCAgbXV0YXRpb25zLCBpNjQgdGltZXN0YW1wKScKKyAgcHJpbnQgJyAgdm9pZCBtdXRhdGVSb3dzKFRleHQgdGFibGVOYW1lLCAgcm93QmF0Y2hlcyknCisgIHByaW50ICcgIHZvaWQgbXV0YXRlUm93c1RzKFRleHQgdGFibGVOYW1lLCAgcm93QmF0Y2hlcywgaTY0IHRpbWVzdGFtcCknCisgIHByaW50ICcgIHZvaWQgZGVsZXRlQWxsKFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgVGV4dCBjb2x1bW4pJworICBwcmludCAnICB2b2lkIGRlbGV0ZUFsbFRzKFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgVGV4dCBjb2x1bW4sIGk2NCB0aW1lc3RhbXApJworICBwcmludCAnICB2b2lkIGRlbGV0ZUFsbFJvdyhUZXh0IHRhYmxlTmFtZSwgVGV4dCByb3cpJworICBwcmludCAnICB2b2lkIGRlbGV0ZUFsbFJvd1RzKFRleHQgdGFibGVOYW1lLCBUZXh0IHJvdywgaTY0IHRpbWVzdGFtcCknCisgIHByaW50ICcgIFNjYW5uZXJJRCBzY2FubmVyT3BlbihUZXh0IHRhYmxlTmFtZSwgVGV4dCBzdGFydFJvdywgIGNvbHVtbnMpJworICBwcmludCAnICBTY2FubmVySUQgc2Nhbm5lck9wZW5XaXRoU3RvcChUZXh0IHRhYmxlTmFtZSwgVGV4dCBzdGFydFJvdywgVGV4dCBzdG9wUm93LCAgY29sdW1ucyknCisgIHByaW50ICcgIFNjYW5uZXJJRCBzY2FubmVyT3BlblRzKFRleHQgdGFibGVOYW1lLCBUZXh0IHN0YXJ0Um93LCAgY29sdW1ucywgaTY0IHRpbWVzdGFtcCknCisgIHByaW50ICcgIFNjYW5uZXJJRCBzY2FubmVyT3BlbldpdGhTdG9wVHMoVGV4dCB0YWJsZU5hbWUsIFRleHQgc3RhcnRSb3csIFRleHQgc3RvcFJvdywgIGNvbHVtbnMsIGk2NCB0aW1lc3RhbXApJworICBwcmludCAnICBTY2FuRW50cnkgc2Nhbm5lckdldChTY2FubmVySUQgaWQpJworICBwcmludCAnICB2b2lkIHNjYW5uZXJDbG9zZShTY2FubmVySUQgaWQpJworICBwcmludCAnJworICBzeXMuZXhpdCgwKQorCitwcCA9IHBwcmludC5QcmV0dHlQcmludGVyKGluZGVudCA9IDIpCitob3N0ID0gJ2xvY2FsaG9zdCcKK3BvcnQgPSA5MDkwCit1cmkgPSAnJworZnJhbWVkID0gRmFsc2UKK2h0dHAgPSBGYWxzZQorYXJnaSA9IDEKKworaWYgc3lzLmFyZ3ZbYXJnaV0gPT0gJy1oJzoKKyAgcGFydHMgPSBzeXMuYXJndlthcmdpKzFdLnNwbGl0KCc6JykgCisgIGhvc3QgPSBwYXJ0c1swXQorICBwb3J0ID0gaW50KHBhcnRzWzFdKQorICBhcmdpICs9IDIKKworaWYgc3lzLmFyZ3ZbYXJnaV0gPT0gJy11JzoKKyAgdXJsID0gdXJscGFyc2Uoc3lzLmFyZ3ZbYXJnaSsxXSkKKyAgcGFydHMgPSB1cmxbMV0uc3BsaXQoJzonKSAKKyAgaG9zdCA9IHBhcnRzWzBdCisgIGlmIGxlbihwYXJ0cykgPiAxOgorICAgIHBvcnQgPSBpbnQocGFydHNbMV0pCisgIGVsc2U6CisgICAgcG9ydCA9IDgwCisgIHVyaSA9IHVybFsyXQorICBodHRwID0gVHJ1ZQorICBhcmdpICs9IDIKKworaWYgc3lzLmFyZ3ZbYXJnaV0gPT0gJy1mJyBvciBzeXMuYXJndlthcmdpXSA9PSAnLWZyYW1lZCc6CisgIGZyYW1lZCA9IFRydWUKKyAgYXJnaSArPSAxCisKK2NtZCA9IHN5cy5hcmd2W2FyZ2ldCithcmdzID0gc3lzLmFyZ3ZbYXJnaSsxOl0KKworaWYgaHR0cDoKKyAgdHJhbnNwb3J0ID0gVEh0dHBDbGllbnQuVEh0dHBDbGllbnQoaG9zdCwgcG9ydCwgdXJpKQorZWxzZToKKyAgc29ja2V0ID0gVFNvY2tldC5UU29ja2V0KGhvc3QsIHBvcnQpCisgIGlmIGZyYW1lZDoKKyAgICB0cmFuc3BvcnQgPSBUVHJhbnNwb3J0LlRGcmFtZWRUcmFuc3BvcnQoc29ja2V0KQorICBlbHNlOgorICAgIHRyYW5zcG9ydCA9IFRUcmFuc3BvcnQuVEJ1ZmZlcmVkVHJhbnNwb3J0KHNvY2tldCkKK3Byb3RvY29sID0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbCh0cmFuc3BvcnQpCitjbGllbnQgPSBIYmFzZS5DbGllbnQocHJvdG9jb2wpCit0cmFuc3BvcnQub3BlbigpCisKK2lmIGNtZCA9PSAnZ2V0VGFibGVOYW1lcyc6CisgIGlmIGxlbihhcmdzKSAhPSAwOgorICAgIHByaW50ICdnZXRUYWJsZU5hbWVzIHJlcXVpcmVzIDAgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmdldFRhYmxlTmFtZXMoKSkKKworZWxpZiBjbWQgPT0gJ2dldENvbHVtbkRlc2NyaXB0b3JzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDE6CisgICAgcHJpbnQgJ2dldENvbHVtbkRlc2NyaXB0b3JzIHJlcXVpcmVzIDEgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmdldENvbHVtbkRlc2NyaXB0b3JzKGV2YWwoYXJnc1swXSksKSkKKworZWxpZiBjbWQgPT0gJ2dldFRhYmxlUmVnaW9ucyc6CisgIGlmIGxlbihhcmdzKSAhPSAxOgorICAgIHByaW50ICdnZXRUYWJsZVJlZ2lvbnMgcmVxdWlyZXMgMSBhcmdzJworICAgIHN5cy5leGl0KDEpCisgIHBwLnBwcmludChjbGllbnQuZ2V0VGFibGVSZWdpb25zKGV2YWwoYXJnc1swXSksKSkKKworZWxpZiBjbWQgPT0gJ2NyZWF0ZVRhYmxlJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDI6CisgICAgcHJpbnQgJ2NyZWF0ZVRhYmxlIHJlcXVpcmVzIDIgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmNyZWF0ZVRhYmxlKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSwpKQorCitlbGlmIGNtZCA9PSAnZGVsZXRlVGFibGUnOgorICBpZiBsZW4oYXJncykgIT0gMToKKyAgICBwcmludCAnZGVsZXRlVGFibGUgcmVxdWlyZXMgMSBhcmdzJworICAgIHN5cy5leGl0KDEpCisgIHBwLnBwcmludChjbGllbnQuZGVsZXRlVGFibGUoZXZhbChhcmdzWzBdKSwpKQorCitlbGlmIGNtZCA9PSAnZ2V0JzoKKyAgaWYgbGVuKGFyZ3MpICE9IDM6CisgICAgcHJpbnQgJ2dldCByZXF1aXJlcyAzIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5nZXQoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksKSkKKworZWxpZiBjbWQgPT0gJ2dldFZlcic6CisgIGlmIGxlbihhcmdzKSAhPSA0OgorICAgIHByaW50ICdnZXRWZXIgcmVxdWlyZXMgNCBhcmdzJworICAgIHN5cy5leGl0KDEpCisgIHBwLnBwcmludChjbGllbnQuZ2V0VmVyKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSxldmFsKGFyZ3NbMl0pLGV2YWwoYXJnc1szXSksKSkKKworZWxpZiBjbWQgPT0gJ2dldFZlclRzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDU6CisgICAgcHJpbnQgJ2dldFZlclRzIHJlcXVpcmVzIDUgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmdldFZlclRzKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSxldmFsKGFyZ3NbMl0pLGV2YWwoYXJnc1szXSksZXZhbChhcmdzWzRdKSwpKQorCitlbGlmIGNtZCA9PSAnZ2V0Um93JzoKKyAgaWYgbGVuKGFyZ3MpICE9IDI6CisgICAgcHJpbnQgJ2dldFJvdyByZXF1aXJlcyAyIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5nZXRSb3coZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLCkpCisKK2VsaWYgY21kID09ICdnZXRSb3dUcyc6CisgIGlmIGxlbihhcmdzKSAhPSAzOgorICAgIHByaW50ICdnZXRSb3dUcyByZXF1aXJlcyAzIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5nZXRSb3dUcyhldmFsKGFyZ3NbMF0pLGV2YWwoYXJnc1sxXSksZXZhbChhcmdzWzJdKSwpKQorCitlbGlmIGNtZCA9PSAncHV0JzoKKyAgaWYgbGVuKGFyZ3MpICE9IDQ6CisgICAgcHJpbnQgJ3B1dCByZXF1aXJlcyA0IGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5wdXQoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksZXZhbChhcmdzWzNdKSwpKQorCitlbGlmIGNtZCA9PSAnbXV0YXRlUm93JzoKKyAgaWYgbGVuKGFyZ3MpICE9IDM6CisgICAgcHJpbnQgJ211dGF0ZVJvdyByZXF1aXJlcyAzIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5tdXRhdGVSb3coZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksKSkKKworZWxpZiBjbWQgPT0gJ211dGF0ZVJvd1RzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDQ6CisgICAgcHJpbnQgJ211dGF0ZVJvd1RzIHJlcXVpcmVzIDQgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50Lm11dGF0ZVJvd1RzKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSxldmFsKGFyZ3NbMl0pLGV2YWwoYXJnc1szXSksKSkKKworZWxpZiBjbWQgPT0gJ211dGF0ZVJvd3MnOgorICBpZiBsZW4oYXJncykgIT0gMjoKKyAgICBwcmludCAnbXV0YXRlUm93cyByZXF1aXJlcyAyIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5tdXRhdGVSb3dzKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSwpKQorCitlbGlmIGNtZCA9PSAnbXV0YXRlUm93c1RzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDM6CisgICAgcHJpbnQgJ211dGF0ZVJvd3NUcyByZXF1aXJlcyAzIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5tdXRhdGVSb3dzVHMoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksKSkKKworZWxpZiBjbWQgPT0gJ2RlbGV0ZUFsbCc6CisgIGlmIGxlbihhcmdzKSAhPSAzOgorICAgIHByaW50ICdkZWxldGVBbGwgcmVxdWlyZXMgMyBhcmdzJworICAgIHN5cy5leGl0KDEpCisgIHBwLnBwcmludChjbGllbnQuZGVsZXRlQWxsKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSxldmFsKGFyZ3NbMl0pLCkpCisKK2VsaWYgY21kID09ICdkZWxldGVBbGxUcyc6CisgIGlmIGxlbihhcmdzKSAhPSA0OgorICAgIHByaW50ICdkZWxldGVBbGxUcyByZXF1aXJlcyA0IGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5kZWxldGVBbGxUcyhldmFsKGFyZ3NbMF0pLGV2YWwoYXJnc1sxXSksZXZhbChhcmdzWzJdKSxldmFsKGFyZ3NbM10pLCkpCisKK2VsaWYgY21kID09ICdkZWxldGVBbGxSb3cnOgorICBpZiBsZW4oYXJncykgIT0gMjoKKyAgICBwcmludCAnZGVsZXRlQWxsUm93IHJlcXVpcmVzIDIgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmRlbGV0ZUFsbFJvdyhldmFsKGFyZ3NbMF0pLGV2YWwoYXJnc1sxXSksKSkKKworZWxpZiBjbWQgPT0gJ2RlbGV0ZUFsbFJvd1RzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDM6CisgICAgcHJpbnQgJ2RlbGV0ZUFsbFJvd1RzIHJlcXVpcmVzIDMgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LmRlbGV0ZUFsbFJvd1RzKGV2YWwoYXJnc1swXSksZXZhbChhcmdzWzFdKSxldmFsKGFyZ3NbMl0pLCkpCisKK2VsaWYgY21kID09ICdzY2FubmVyT3Blbic6CisgIGlmIGxlbihhcmdzKSAhPSAzOgorICAgIHByaW50ICdzY2FubmVyT3BlbiByZXF1aXJlcyAzIGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5zY2FubmVyT3BlbihldmFsKGFyZ3NbMF0pLGV2YWwoYXJnc1sxXSksZXZhbChhcmdzWzJdKSwpKQorCitlbGlmIGNtZCA9PSAnc2Nhbm5lck9wZW5XaXRoU3RvcCc6CisgIGlmIGxlbihhcmdzKSAhPSA0OgorICAgIHByaW50ICdzY2FubmVyT3BlbldpdGhTdG9wIHJlcXVpcmVzIDQgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LnNjYW5uZXJPcGVuV2l0aFN0b3AoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksZXZhbChhcmdzWzNdKSwpKQorCitlbGlmIGNtZCA9PSAnc2Nhbm5lck9wZW5Ucyc6CisgIGlmIGxlbihhcmdzKSAhPSA0OgorICAgIHByaW50ICdzY2FubmVyT3BlblRzIHJlcXVpcmVzIDQgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LnNjYW5uZXJPcGVuVHMoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksZXZhbChhcmdzWzNdKSwpKQorCitlbGlmIGNtZCA9PSAnc2Nhbm5lck9wZW5XaXRoU3RvcFRzJzoKKyAgaWYgbGVuKGFyZ3MpICE9IDU6CisgICAgcHJpbnQgJ3NjYW5uZXJPcGVuV2l0aFN0b3BUcyByZXF1aXJlcyA1IGFyZ3MnCisgICAgc3lzLmV4aXQoMSkKKyAgcHAucHByaW50KGNsaWVudC5zY2FubmVyT3BlbldpdGhTdG9wVHMoZXZhbChhcmdzWzBdKSxldmFsKGFyZ3NbMV0pLGV2YWwoYXJnc1syXSksZXZhbChhcmdzWzNdKSxldmFsKGFyZ3NbNF0pLCkpCisKK2VsaWYgY21kID09ICdzY2FubmVyR2V0JzoKKyAgaWYgbGVuKGFyZ3MpICE9IDE6CisgICAgcHJpbnQgJ3NjYW5uZXJHZXQgcmVxdWlyZXMgMSBhcmdzJworICAgIHN5cy5leGl0KDEpCisgIHBwLnBwcmludChjbGllbnQuc2Nhbm5lckdldChldmFsKGFyZ3NbMF0pLCkpCisKK2VsaWYgY21kID09ICdzY2FubmVyQ2xvc2UnOgorICBpZiBsZW4oYXJncykgIT0gMToKKyAgICBwcmludCAnc2Nhbm5lckNsb3NlIHJlcXVpcmVzIDEgYXJncycKKyAgICBzeXMuZXhpdCgxKQorICBwcC5wcHJpbnQoY2xpZW50LnNjYW5uZXJDbG9zZShldmFsKGFyZ3NbMF0pLCkpCisKK3RyYW5zcG9ydC5jbG9zZSgpCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL0hiYXNlLnB5IGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IYmFzZS9IYmFzZS5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wY2U4NDJmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IYmFzZS9IYmFzZS5weQpAQCAtMCwwICsxLDUxNTMgQEAKKyMKKyMgQXV0b2dlbmVyYXRlZCBieSBUaHJpZnQKKyMKKyMgRE8gTk9UIEVESVQgVU5MRVNTIFlPVSBBUkUgU1VSRSBUSEFUIFlPVSBLTk9XIFdIQVQgWU9VIEFSRSBET0lORworIworCitmcm9tIHRocmlmdC5UaHJpZnQgaW1wb3J0ICoKK2Zyb20gdHR5cGVzIGltcG9ydCAqCitmcm9tIHRocmlmdC5UaHJpZnQgaW1wb3J0IFRQcm9jZXNzb3IKK2Zyb20gdGhyaWZ0LnRyYW5zcG9ydCBpbXBvcnQgVFRyYW5zcG9ydAorZnJvbSB0aHJpZnQucHJvdG9jb2wgaW1wb3J0IFRCaW5hcnlQcm90b2NvbAordHJ5OgorICBmcm9tIHRocmlmdC5wcm90b2NvbCBpbXBvcnQgZmFzdGJpbmFyeQorZXhjZXB0OgorICBmYXN0YmluYXJ5ID0gTm9uZQorCisKK2NsYXNzIElmYWNlOgorICBkZWYgZ2V0VGFibGVOYW1lcyhzZWxmLCApOgorICAgIHBhc3MKKworICBkZWYgZ2V0Q29sdW1uRGVzY3JpcHRvcnMoc2VsZiwgdGFibGVOYW1lKToKKyAgICBwYXNzCisKKyAgZGVmIGdldFRhYmxlUmVnaW9ucyhzZWxmLCB0YWJsZU5hbWUpOgorICAgIHBhc3MKKworICBkZWYgY3JlYXRlVGFibGUoc2VsZiwgdGFibGVOYW1lLCBjb2x1bW5GYW1pbGllcyk6CisgICAgcGFzcworCisgIGRlZiBkZWxldGVUYWJsZShzZWxmLCB0YWJsZU5hbWUpOgorICAgIHBhc3MKKworICBkZWYgZ2V0KHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4pOgorICAgIHBhc3MKKworICBkZWYgZ2V0VmVyKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIG51bVZlcnNpb25zKToKKyAgICBwYXNzCisKKyAgZGVmIGdldFZlclRzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOgorICAgIHBhc3MKKworICBkZWYgZ2V0Um93KHNlbGYsIHRhYmxlTmFtZSwgcm93KToKKyAgICBwYXNzCisKKyAgZGVmIGdldFJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCB0aW1lc3RhbXApOgorICAgIHBhc3MKKworICBkZWYgcHV0KHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHZhbHVlKToKKyAgICBwYXNzCisKKyAgZGVmIG11dGF0ZVJvdyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgbXV0YXRpb25zKToKKyAgICBwYXNzCisKKyAgZGVmIG11dGF0ZVJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBtdXRhdGlvbnMsIHRpbWVzdGFtcCk6CisgICAgcGFzcworCisgIGRlZiBtdXRhdGVSb3dzKHNlbGYsIHRhYmxlTmFtZSwgcm93QmF0Y2hlcyk6CisgICAgcGFzcworCisgIGRlZiBtdXRhdGVSb3dzVHMoc2VsZiwgdGFibGVOYW1lLCByb3dCYXRjaGVzLCB0aW1lc3RhbXApOgorICAgIHBhc3MKKworICBkZWYgZGVsZXRlQWxsKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4pOgorICAgIHBhc3MKKworICBkZWYgZGVsZXRlQWxsVHMoc2VsZiwgdGFibGVOYW1lLCByb3csIGNvbHVtbiwgdGltZXN0YW1wKToKKyAgICBwYXNzCisKKyAgZGVmIGRlbGV0ZUFsbFJvdyhzZWxmLCB0YWJsZU5hbWUsIHJvdyk6CisgICAgcGFzcworCisgIGRlZiBkZWxldGVBbGxSb3dUcyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgdGltZXN0YW1wKToKKyAgICBwYXNzCisKKyAgZGVmIHNjYW5uZXJPcGVuKHNlbGYsIHRhYmxlTmFtZSwgc3RhcnRSb3csIGNvbHVtbnMpOgorICAgIHBhc3MKKworICBkZWYgc2Nhbm5lck9wZW5XaXRoU3RvcChzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zKToKKyAgICBwYXNzCisKKyAgZGVmIHNjYW5uZXJPcGVuVHMoc2VsZiwgdGFibGVOYW1lLCBzdGFydFJvdywgY29sdW1ucywgdGltZXN0YW1wKToKKyAgICBwYXNzCisKKyAgZGVmIHNjYW5uZXJPcGVuV2l0aFN0b3BUcyhzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zLCB0aW1lc3RhbXApOgorICAgIHBhc3MKKworICBkZWYgc2Nhbm5lckdldChzZWxmLCBpZCk6CisgICAgcGFzcworCisgIGRlZiBzY2FubmVyQ2xvc2Uoc2VsZiwgaWQpOgorICAgIHBhc3MKKworCitjbGFzcyBDbGllbnQoSWZhY2UpOgorICBkZWYgX19pbml0X18oc2VsZiwgaXByb3QsIG9wcm90PU5vbmUpOgorICAgIHNlbGYuX2lwcm90ID0gc2VsZi5fb3Byb3QgPSBpcHJvdAorICAgIGlmIG9wcm90ICE9IE5vbmU6CisgICAgICBzZWxmLl9vcHJvdCA9IG9wcm90CisgICAgc2VsZi5fc2VxaWQgPSAwCisKKyAgZGVmIGdldFRhYmxlTmFtZXMoc2VsZiwgKToKKyAgICBzZWxmLnNlbmRfZ2V0VGFibGVOYW1lcygpCisgICAgcmV0dXJuIHNlbGYucmVjdl9nZXRUYWJsZU5hbWVzKCkKKworICBkZWYgc2VuZF9nZXRUYWJsZU5hbWVzKHNlbGYsICk6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ2dldFRhYmxlTmFtZXMnLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VsZi5fc2VxaWQpCisgICAgYXJncyA9IGdldFRhYmxlTmFtZXNfYXJncygpCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9nZXRUYWJsZU5hbWVzKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBnZXRUYWJsZU5hbWVzX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5zdWNjZXNzICE9IE5vbmU6CisgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRUYWJsZU5hbWVzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgZ2V0Q29sdW1uRGVzY3JpcHRvcnMoc2VsZiwgdGFibGVOYW1lKToKKyAgICBzZWxmLnNlbmRfZ2V0Q29sdW1uRGVzY3JpcHRvcnModGFibGVOYW1lKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0Q29sdW1uRGVzY3JpcHRvcnMoKQorCisgIGRlZiBzZW5kX2dldENvbHVtbkRlc2NyaXB0b3JzKHNlbGYsIHRhYmxlTmFtZSk6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ2dldENvbHVtbkRlc2NyaXB0b3JzJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfZ2V0Q29sdW1uRGVzY3JpcHRvcnMoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5zdWNjZXNzICE9IE5vbmU6CisgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRDb2x1bW5EZXNjcmlwdG9ycyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisKKyAgZGVmIGdldFRhYmxlUmVnaW9ucyhzZWxmLCB0YWJsZU5hbWUpOgorICAgIHNlbGYuc2VuZF9nZXRUYWJsZVJlZ2lvbnModGFibGVOYW1lKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0VGFibGVSZWdpb25zKCkKKworICBkZWYgc2VuZF9nZXRUYWJsZVJlZ2lvbnMoc2VsZiwgdGFibGVOYW1lKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZ2V0VGFibGVSZWdpb25zJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBnZXRUYWJsZVJlZ2lvbnNfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X2dldFRhYmxlUmVnaW9ucyhzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5zdWNjZXNzICE9IE5vbmU6CisgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRUYWJsZVJlZ2lvbnMgZmFpbGVkOiB1bmtub3duIHJlc3VsdCIpOworCisgIGRlZiBjcmVhdGVUYWJsZShzZWxmLCB0YWJsZU5hbWUsIGNvbHVtbkZhbWlsaWVzKToKKyAgICBzZWxmLnNlbmRfY3JlYXRlVGFibGUodGFibGVOYW1lLCBjb2x1bW5GYW1pbGllcykKKyAgICBzZWxmLnJlY3ZfY3JlYXRlVGFibGUoKQorCisgIGRlZiBzZW5kX2NyZWF0ZVRhYmxlKHNlbGYsIHRhYmxlTmFtZSwgY29sdW1uRmFtaWxpZXMpOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdjcmVhdGVUYWJsZScsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gY3JlYXRlVGFibGVfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLmNvbHVtbkZhbWlsaWVzID0gY29sdW1uRmFtaWxpZXMKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X2NyZWF0ZVRhYmxlKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBjcmVhdGVUYWJsZV9yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIGlmIHJlc3VsdC5pYSAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlhCisgICAgaWYgcmVzdWx0LmV4aXN0ICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuZXhpc3QKKyAgICByZXR1cm4KKworICBkZWYgZGVsZXRlVGFibGUoc2VsZiwgdGFibGVOYW1lKToKKyAgICBzZWxmLnNlbmRfZGVsZXRlVGFibGUodGFibGVOYW1lKQorICAgIHNlbGYucmVjdl9kZWxldGVUYWJsZSgpCisKKyAgZGVmIHNlbmRfZGVsZXRlVGFibGUoc2VsZiwgdGFibGVOYW1lKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZGVsZXRlVGFibGUnLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VsZi5fc2VxaWQpCisgICAgYXJncyA9IGRlbGV0ZVRhYmxlX2FyZ3MoKQorICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9kZWxldGVUYWJsZShzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gZGVsZXRlVGFibGVfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICBpZiByZXN1bHQubmYgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5uZgorICAgIHJldHVybgorCisgIGRlZiBnZXQoc2VsZiwgdGFibGVOYW1lLCByb3csIGNvbHVtbik6CisgICAgc2VsZi5zZW5kX2dldCh0YWJsZU5hbWUsIHJvdywgY29sdW1uKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0KCkKKworICBkZWYgc2VuZF9nZXQoc2VsZiwgdGFibGVOYW1lLCByb3csIGNvbHVtbik6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ2dldCcsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gZ2V0X2FyZ3MoKQorICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lCisgICAgYXJncy5yb3cgPSByb3cKKyAgICBhcmdzLmNvbHVtbiA9IGNvbHVtbgorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfZ2V0KHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBnZXRfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzcworICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgaWYgcmVzdWx0Lm5mICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQubmYKKyAgICByYWlzZSBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAiZ2V0IGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgZ2V0VmVyKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIG51bVZlcnNpb25zKToKKyAgICBzZWxmLnNlbmRfZ2V0VmVyKHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIG51bVZlcnNpb25zKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0VmVyKCkKKworICBkZWYgc2VuZF9nZXRWZXIoc2VsZiwgdGFibGVOYW1lLCByb3csIGNvbHVtbiwgbnVtVmVyc2lvbnMpOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdnZXRWZXInLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VsZi5fc2VxaWQpCisgICAgYXJncyA9IGdldFZlcl9hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Mucm93ID0gcm93CisgICAgYXJncy5jb2x1bW4gPSBjb2x1bW4KKyAgICBhcmdzLm51bVZlcnNpb25zID0gbnVtVmVyc2lvbnMKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X2dldFZlcihzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gZ2V0VmVyX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5zdWNjZXNzICE9IE5vbmU6CisgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIGlmIHJlc3VsdC5uZiAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0Lm5mCisgICAgcmFpc2UgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgImdldFZlciBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisKKyAgZGVmIGdldFZlclRzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOgorICAgIHNlbGYuc2VuZF9nZXRWZXJUcyh0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB0aW1lc3RhbXAsIG51bVZlcnNpb25zKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0VmVyVHMoKQorCisgIGRlZiBzZW5kX2dldFZlclRzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdnZXRWZXJUcycsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gZ2V0VmVyVHNfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3MuY29sdW1uID0gY29sdW1uCisgICAgYXJncy50aW1lc3RhbXAgPSB0aW1lc3RhbXAKKyAgICBhcmdzLm51bVZlcnNpb25zID0gbnVtVmVyc2lvbnMKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X2dldFZlclRzKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBnZXRWZXJUc19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuc3VjY2VzcyAhPSBOb25lOgorICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICBpZiByZXN1bHQubmYgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5uZgorICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRWZXJUcyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisKKyAgZGVmIGdldFJvdyhzZWxmLCB0YWJsZU5hbWUsIHJvdyk6CisgICAgc2VsZi5zZW5kX2dldFJvdyh0YWJsZU5hbWUsIHJvdykKKyAgICByZXR1cm4gc2VsZi5yZWN2X2dldFJvdygpCisKKyAgZGVmIHNlbmRfZ2V0Um93KHNlbGYsIHRhYmxlTmFtZSwgcm93KToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZ2V0Um93JywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBnZXRSb3dfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfZ2V0Um93KHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBnZXRSb3dfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzcworICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgcmFpc2UgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgImdldFJvdyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisKKyAgZGVmIGdldFJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCB0aW1lc3RhbXApOgorICAgIHNlbGYuc2VuZF9nZXRSb3dUcyh0YWJsZU5hbWUsIHJvdywgdGltZXN0YW1wKQorICAgIHJldHVybiBzZWxmLnJlY3ZfZ2V0Um93VHMoKQorCisgIGRlZiBzZW5kX2dldFJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCB0aW1lc3RhbXApOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdnZXRSb3dUcycsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gZ2V0Um93VHNfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9nZXRSb3dUcyhzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gZ2V0Um93VHNfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzcworICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgcmFpc2UgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgImdldFJvd1RzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgcHV0KHNlbGYsIHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHZhbHVlKToKKyAgICBzZWxmLnNlbmRfcHV0KHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHZhbHVlKQorICAgIHNlbGYucmVjdl9wdXQoKQorCisgIGRlZiBzZW5kX3B1dChzZWxmLCB0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB2YWx1ZSk6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ3B1dCcsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gcHV0X2FyZ3MoKQorICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lCisgICAgYXJncy5yb3cgPSByb3cKKyAgICBhcmdzLmNvbHVtbiA9IGNvbHVtbgorICAgIGFyZ3MudmFsdWUgPSB2YWx1ZQorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfcHV0KHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBwdXRfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICBpZiByZXN1bHQuaWEgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pYQorICAgIHJldHVybgorCisgIGRlZiBtdXRhdGVSb3coc2VsZiwgdGFibGVOYW1lLCByb3csIG11dGF0aW9ucyk6CisgICAgc2VsZi5zZW5kX211dGF0ZVJvdyh0YWJsZU5hbWUsIHJvdywgbXV0YXRpb25zKQorICAgIHNlbGYucmVjdl9tdXRhdGVSb3coKQorCisgIGRlZiBzZW5kX211dGF0ZVJvdyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgbXV0YXRpb25zKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignbXV0YXRlUm93JywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBtdXRhdGVSb3dfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3MubXV0YXRpb25zID0gbXV0YXRpb25zCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9tdXRhdGVSb3coc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IG11dGF0ZVJvd19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIGlmIHJlc3VsdC5pYSAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlhCisgICAgcmV0dXJuCisKKyAgZGVmIG11dGF0ZVJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBtdXRhdGlvbnMsIHRpbWVzdGFtcCk6CisgICAgc2VsZi5zZW5kX211dGF0ZVJvd1RzKHRhYmxlTmFtZSwgcm93LCBtdXRhdGlvbnMsIHRpbWVzdGFtcCkKKyAgICBzZWxmLnJlY3ZfbXV0YXRlUm93VHMoKQorCisgIGRlZiBzZW5kX211dGF0ZVJvd1RzKHNlbGYsIHRhYmxlTmFtZSwgcm93LCBtdXRhdGlvbnMsIHRpbWVzdGFtcCk6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ211dGF0ZVJvd1RzJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBtdXRhdGVSb3dUc19hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Mucm93ID0gcm93CisgICAgYXJncy5tdXRhdGlvbnMgPSBtdXRhdGlvbnMKKyAgICBhcmdzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfbXV0YXRlUm93VHMoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IG11dGF0ZVJvd1RzX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgaWYgcmVzdWx0LmlhICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaWEKKyAgICByZXR1cm4KKworICBkZWYgbXV0YXRlUm93cyhzZWxmLCB0YWJsZU5hbWUsIHJvd0JhdGNoZXMpOgorICAgIHNlbGYuc2VuZF9tdXRhdGVSb3dzKHRhYmxlTmFtZSwgcm93QmF0Y2hlcykKKyAgICBzZWxmLnJlY3ZfbXV0YXRlUm93cygpCisKKyAgZGVmIHNlbmRfbXV0YXRlUm93cyhzZWxmLCB0YWJsZU5hbWUsIHJvd0JhdGNoZXMpOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdtdXRhdGVSb3dzJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBtdXRhdGVSb3dzX2FyZ3MoKQorICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lCisgICAgYXJncy5yb3dCYXRjaGVzID0gcm93QmF0Y2hlcworICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfbXV0YXRlUm93cyhzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gbXV0YXRlUm93c19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIGlmIHJlc3VsdC5pYSAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlhCisgICAgcmV0dXJuCisKKyAgZGVmIG11dGF0ZVJvd3NUcyhzZWxmLCB0YWJsZU5hbWUsIHJvd0JhdGNoZXMsIHRpbWVzdGFtcCk6CisgICAgc2VsZi5zZW5kX211dGF0ZVJvd3NUcyh0YWJsZU5hbWUsIHJvd0JhdGNoZXMsIHRpbWVzdGFtcCkKKyAgICBzZWxmLnJlY3ZfbXV0YXRlUm93c1RzKCkKKworICBkZWYgc2VuZF9tdXRhdGVSb3dzVHMoc2VsZiwgdGFibGVOYW1lLCByb3dCYXRjaGVzLCB0aW1lc3RhbXApOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdtdXRhdGVSb3dzVHMnLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VsZi5fc2VxaWQpCisgICAgYXJncyA9IG11dGF0ZVJvd3NUc19hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Mucm93QmF0Y2hlcyA9IHJvd0JhdGNoZXMKKyAgICBhcmdzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfbXV0YXRlUm93c1RzKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBtdXRhdGVSb3dzVHNfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICBpZiByZXN1bHQuaWEgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pYQorICAgIHJldHVybgorCisgIGRlZiBkZWxldGVBbGwoc2VsZiwgdGFibGVOYW1lLCByb3csIGNvbHVtbik6CisgICAgc2VsZi5zZW5kX2RlbGV0ZUFsbCh0YWJsZU5hbWUsIHJvdywgY29sdW1uKQorICAgIHNlbGYucmVjdl9kZWxldGVBbGwoKQorCisgIGRlZiBzZW5kX2RlbGV0ZUFsbChzZWxmLCB0YWJsZU5hbWUsIHJvdywgY29sdW1uKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZGVsZXRlQWxsJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBkZWxldGVBbGxfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3MuY29sdW1uID0gY29sdW1uCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9kZWxldGVBbGwoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IGRlbGV0ZUFsbF9yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJldHVybgorCisgIGRlZiBkZWxldGVBbGxUcyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB0aW1lc3RhbXApOgorICAgIHNlbGYuc2VuZF9kZWxldGVBbGxUcyh0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB0aW1lc3RhbXApCisgICAgc2VsZi5yZWN2X2RlbGV0ZUFsbFRzKCkKKworICBkZWYgc2VuZF9kZWxldGVBbGxUcyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB0aW1lc3RhbXApOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdkZWxldGVBbGxUcycsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gZGVsZXRlQWxsVHNfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3MuY29sdW1uID0gY29sdW1uCisgICAgYXJncy50aW1lc3RhbXAgPSB0aW1lc3RhbXAKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X2RlbGV0ZUFsbFRzKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBkZWxldGVBbGxUc19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJldHVybgorCisgIGRlZiBkZWxldGVBbGxSb3coc2VsZiwgdGFibGVOYW1lLCByb3cpOgorICAgIHNlbGYuc2VuZF9kZWxldGVBbGxSb3codGFibGVOYW1lLCByb3cpCisgICAgc2VsZi5yZWN2X2RlbGV0ZUFsbFJvdygpCisKKyAgZGVmIHNlbmRfZGVsZXRlQWxsUm93KHNlbGYsIHRhYmxlTmFtZSwgcm93KToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZGVsZXRlQWxsUm93JywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBkZWxldGVBbGxSb3dfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnJvdyA9IHJvdworICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfZGVsZXRlQWxsUm93KHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBkZWxldGVBbGxSb3dfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICByZXR1cm4KKworICBkZWYgZGVsZXRlQWxsUm93VHMoc2VsZiwgdGFibGVOYW1lLCByb3csIHRpbWVzdGFtcCk6CisgICAgc2VsZi5zZW5kX2RlbGV0ZUFsbFJvd1RzKHRhYmxlTmFtZSwgcm93LCB0aW1lc3RhbXApCisgICAgc2VsZi5yZWN2X2RlbGV0ZUFsbFJvd1RzKCkKKworICBkZWYgc2VuZF9kZWxldGVBbGxSb3dUcyhzZWxmLCB0YWJsZU5hbWUsIHJvdywgdGltZXN0YW1wKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignZGVsZXRlQWxsUm93VHMnLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VsZi5fc2VxaWQpCisgICAgYXJncyA9IGRlbGV0ZUFsbFJvd1RzX2FyZ3MoKQorICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lCisgICAgYXJncy5yb3cgPSByb3cKKyAgICBhcmdzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3ZfZGVsZXRlQWxsUm93VHMoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgcmV0dXJuCisKKyAgZGVmIHNjYW5uZXJPcGVuKHNlbGYsIHRhYmxlTmFtZSwgc3RhcnRSb3csIGNvbHVtbnMpOgorICAgIHNlbGYuc2VuZF9zY2FubmVyT3Blbih0YWJsZU5hbWUsIHN0YXJ0Um93LCBjb2x1bW5zKQorICAgIHJldHVybiBzZWxmLnJlY3Zfc2Nhbm5lck9wZW4oKQorCisgIGRlZiBzZW5kX3NjYW5uZXJPcGVuKHNlbGYsIHRhYmxlTmFtZSwgc3RhcnRSb3csIGNvbHVtbnMpOgorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUJlZ2luKCdzY2FubmVyT3BlbicsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gc2Nhbm5lck9wZW5fYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnN0YXJ0Um93ID0gc3RhcnRSb3cKKyAgICBhcmdzLmNvbHVtbnMgPSBjb2x1bW5zCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9zY2FubmVyT3BlbihzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gc2Nhbm5lck9wZW5fcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzcworICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgcmFpc2UgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgInNjYW5uZXJPcGVuIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgc2Nhbm5lck9wZW5XaXRoU3RvcChzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zKToKKyAgICBzZWxmLnNlbmRfc2Nhbm5lck9wZW5XaXRoU3RvcCh0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zKQorICAgIHJldHVybiBzZWxmLnJlY3Zfc2Nhbm5lck9wZW5XaXRoU3RvcCgpCisKKyAgZGVmIHNlbmRfc2Nhbm5lck9wZW5XaXRoU3RvcChzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignc2Nhbm5lck9wZW5XaXRoU3RvcCcsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Muc3RhcnRSb3cgPSBzdGFydFJvdworICAgIGFyZ3Muc3RvcFJvdyA9IHN0b3BSb3cKKyAgICBhcmdzLmNvbHVtbnMgPSBjb2x1bW5zCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9zY2FubmVyT3BlbldpdGhTdG9wKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBzY2FubmVyT3BlbldpdGhTdG9wX3Jlc3VsdCgpCisgICAgcmVzdWx0LnJlYWQoc2VsZi5faXByb3QpCisgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIGlmIHJlc3VsdC5zdWNjZXNzICE9IE5vbmU6CisgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MKKyAgICBpZiByZXN1bHQuaW8gIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pbworICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJzY2FubmVyT3BlbldpdGhTdG9wIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgc2Nhbm5lck9wZW5UcyhzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBjb2x1bW5zLCB0aW1lc3RhbXApOgorICAgIHNlbGYuc2VuZF9zY2FubmVyT3BlblRzKHRhYmxlTmFtZSwgc3RhcnRSb3csIGNvbHVtbnMsIHRpbWVzdGFtcCkKKyAgICByZXR1cm4gc2VsZi5yZWN2X3NjYW5uZXJPcGVuVHMoKQorCisgIGRlZiBzZW5kX3NjYW5uZXJPcGVuVHMoc2VsZiwgdGFibGVOYW1lLCBzdGFydFJvdywgY29sdW1ucywgdGltZXN0YW1wKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignc2Nhbm5lck9wZW5UcycsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gc2Nhbm5lck9wZW5Uc19hcmdzKCkKKyAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZQorICAgIGFyZ3Muc3RhcnRSb3cgPSBzdGFydFJvdworICAgIGFyZ3MuY29sdW1ucyA9IGNvbHVtbnMKKyAgICBhcmdzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3Zfc2Nhbm5lck9wZW5UcyhzZWxmLCApOgorICAgIChmbmFtZSwgbXR5cGUsIHJzZXFpZCkgPSBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCkKKyAgICBpZiBtdHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OOgorICAgICAgeCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbigpCisgICAgICB4LnJlYWQoc2VsZi5faXByb3QpCisgICAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgICByYWlzZSB4CisgICAgcmVzdWx0ID0gc2Nhbm5lck9wZW5Uc19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuc3VjY2VzcyAhPSBOb25lOgorICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICByYWlzZSBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAic2Nhbm5lck9wZW5UcyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisKKyAgZGVmIHNjYW5uZXJPcGVuV2l0aFN0b3BUcyhzZWxmLCB0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zLCB0aW1lc3RhbXApOgorICAgIHNlbGYuc2VuZF9zY2FubmVyT3BlbldpdGhTdG9wVHModGFibGVOYW1lLCBzdGFydFJvdywgc3RvcFJvdywgY29sdW1ucywgdGltZXN0YW1wKQorICAgIHJldHVybiBzZWxmLnJlY3Zfc2Nhbm5lck9wZW5XaXRoU3RvcFRzKCkKKworICBkZWYgc2VuZF9zY2FubmVyT3BlbldpdGhTdG9wVHMoc2VsZiwgdGFibGVOYW1lLCBzdGFydFJvdywgc3RvcFJvdywgY29sdW1ucywgdGltZXN0YW1wKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignc2Nhbm5lck9wZW5XaXRoU3RvcFRzJywgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlbGYuX3NlcWlkKQorICAgIGFyZ3MgPSBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncygpCisgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWUKKyAgICBhcmdzLnN0YXJ0Um93ID0gc3RhcnRSb3cKKyAgICBhcmdzLnN0b3BSb3cgPSBzdG9wUm93CisgICAgYXJncy5jb2x1bW5zID0gY29sdW1ucworICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wCisgICAgYXJncy53cml0ZShzZWxmLl9vcHJvdCkKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIHNlbGYuX29wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcmVjdl9zY2FubmVyT3BlbldpdGhTdG9wVHMoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IHNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQoKQorICAgIHJlc3VsdC5yZWFkKHNlbGYuX2lwcm90KQorICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICBpZiByZXN1bHQuc3VjY2VzcyAhPSBOb25lOgorICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICByYWlzZSBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAic2Nhbm5lck9wZW5XaXRoU3RvcFRzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgc2Nhbm5lckdldChzZWxmLCBpZCk6CisgICAgc2VsZi5zZW5kX3NjYW5uZXJHZXQoaWQpCisgICAgcmV0dXJuIHNlbGYucmVjdl9zY2FubmVyR2V0KCkKKworICBkZWYgc2VuZF9zY2FubmVyR2V0KHNlbGYsIGlkKToKKyAgICBzZWxmLl9vcHJvdC53cml0ZU1lc3NhZ2VCZWdpbignc2Nhbm5lckdldCcsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gc2Nhbm5lckdldF9hcmdzKCkKKyAgICBhcmdzLmlkID0gaWQKKyAgICBhcmdzLndyaXRlKHNlbGYuX29wcm90KQorICAgIHNlbGYuX29wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgc2VsZi5fb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiByZWN2X3NjYW5uZXJHZXQoc2VsZiwgKToKKyAgICAoZm5hbWUsIG10eXBlLCByc2VxaWQpID0gc2VsZi5faXByb3QucmVhZE1lc3NhZ2VCZWdpbigpCisgICAgaWYgbXR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTjoKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oKQorICAgICAgeC5yZWFkKHNlbGYuX2lwcm90KQorICAgICAgc2VsZi5faXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgICAgcmFpc2UgeAorICAgIHJlc3VsdCA9IHNjYW5uZXJHZXRfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzcworICAgIGlmIHJlc3VsdC5pbyAhPSBOb25lOgorICAgICAgcmFpc2UgcmVzdWx0LmlvCisgICAgaWYgcmVzdWx0LmlhICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaWEKKyAgICBpZiByZXN1bHQubmYgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5uZgorICAgIHJhaXNlIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJzY2FubmVyR2V0IGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKworICBkZWYgc2Nhbm5lckNsb3NlKHNlbGYsIGlkKToKKyAgICBzZWxmLnNlbmRfc2Nhbm5lckNsb3NlKGlkKQorICAgIHNlbGYucmVjdl9zY2FubmVyQ2xvc2UoKQorCisgIGRlZiBzZW5kX3NjYW5uZXJDbG9zZShzZWxmLCBpZCk6CisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oJ3NjYW5uZXJDbG9zZScsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZWxmLl9zZXFpZCkKKyAgICBhcmdzID0gc2Nhbm5lckNsb3NlX2FyZ3MoKQorICAgIGFyZ3MuaWQgPSBpZAorICAgIGFyZ3Mud3JpdGUoc2VsZi5fb3Byb3QpCisgICAgc2VsZi5fb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBzZWxmLl9vcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHJlY3Zfc2Nhbm5lckNsb3NlKHNlbGYsICk6CisgICAgKGZuYW1lLCBtdHlwZSwgcnNlcWlkKSA9IHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG10eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT046CisgICAgICB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uKCkKKyAgICAgIHgucmVhZChzZWxmLl9pcHJvdCkKKyAgICAgIHNlbGYuX2lwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHJhaXNlIHgKKyAgICByZXN1bHQgPSBzY2FubmVyQ2xvc2VfcmVzdWx0KCkKKyAgICByZXN1bHQucmVhZChzZWxmLl9pcHJvdCkKKyAgICBzZWxmLl9pcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgaWYgcmVzdWx0LmlvICE9IE5vbmU6CisgICAgICByYWlzZSByZXN1bHQuaW8KKyAgICBpZiByZXN1bHQuaWEgIT0gTm9uZToKKyAgICAgIHJhaXNlIHJlc3VsdC5pYQorICAgIHJldHVybgorCisKK2NsYXNzIFByb2Nlc3NvcihJZmFjZSwgVFByb2Nlc3Nvcik6CisgIGRlZiBfX2luaXRfXyhzZWxmLCBoYW5kbGVyKToKKyAgICBzZWxmLl9oYW5kbGVyID0gaGFuZGxlcgorICAgIHNlbGYuX3Byb2Nlc3NNYXAgPSB7fQorICAgIHNlbGYuX3Byb2Nlc3NNYXBbImdldFRhYmxlTmFtZXMiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX2dldFRhYmxlTmFtZXMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJnZXRDb2x1bW5EZXNjcmlwdG9ycyJdID0gUHJvY2Vzc29yLnByb2Nlc3NfZ2V0Q29sdW1uRGVzY3JpcHRvcnMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJnZXRUYWJsZVJlZ2lvbnMiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX2dldFRhYmxlUmVnaW9ucworICAgIHNlbGYuX3Byb2Nlc3NNYXBbImNyZWF0ZVRhYmxlIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19jcmVhdGVUYWJsZQorICAgIHNlbGYuX3Byb2Nlc3NNYXBbImRlbGV0ZVRhYmxlIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19kZWxldGVUYWJsZQorICAgIHNlbGYuX3Byb2Nlc3NNYXBbImdldCJdID0gUHJvY2Vzc29yLnByb2Nlc3NfZ2V0CisgICAgc2VsZi5fcHJvY2Vzc01hcFsiZ2V0VmVyIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19nZXRWZXIKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJnZXRWZXJUcyJdID0gUHJvY2Vzc29yLnByb2Nlc3NfZ2V0VmVyVHMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJnZXRSb3ciXSA9IFByb2Nlc3Nvci5wcm9jZXNzX2dldFJvdworICAgIHNlbGYuX3Byb2Nlc3NNYXBbImdldFJvd1RzIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19nZXRSb3dUcworICAgIHNlbGYuX3Byb2Nlc3NNYXBbInB1dCJdID0gUHJvY2Vzc29yLnByb2Nlc3NfcHV0CisgICAgc2VsZi5fcHJvY2Vzc01hcFsibXV0YXRlUm93Il0gPSBQcm9jZXNzb3IucHJvY2Vzc19tdXRhdGVSb3cKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJtdXRhdGVSb3dUcyJdID0gUHJvY2Vzc29yLnByb2Nlc3NfbXV0YXRlUm93VHMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJtdXRhdGVSb3dzIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19tdXRhdGVSb3dzCisgICAgc2VsZi5fcHJvY2Vzc01hcFsibXV0YXRlUm93c1RzIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19tdXRhdGVSb3dzVHMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJkZWxldGVBbGwiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX2RlbGV0ZUFsbAorICAgIHNlbGYuX3Byb2Nlc3NNYXBbImRlbGV0ZUFsbFRzIl0gPSBQcm9jZXNzb3IucHJvY2Vzc19kZWxldGVBbGxUcworICAgIHNlbGYuX3Byb2Nlc3NNYXBbImRlbGV0ZUFsbFJvdyJdID0gUHJvY2Vzc29yLnByb2Nlc3NfZGVsZXRlQWxsUm93CisgICAgc2VsZi5fcHJvY2Vzc01hcFsiZGVsZXRlQWxsUm93VHMiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX2RlbGV0ZUFsbFJvd1RzCisgICAgc2VsZi5fcHJvY2Vzc01hcFsic2Nhbm5lck9wZW4iXSA9IFByb2Nlc3Nvci5wcm9jZXNzX3NjYW5uZXJPcGVuCisgICAgc2VsZi5fcHJvY2Vzc01hcFsic2Nhbm5lck9wZW5XaXRoU3RvcCJdID0gUHJvY2Vzc29yLnByb2Nlc3Nfc2Nhbm5lck9wZW5XaXRoU3RvcAorICAgIHNlbGYuX3Byb2Nlc3NNYXBbInNjYW5uZXJPcGVuVHMiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX3NjYW5uZXJPcGVuVHMKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJzY2FubmVyT3BlbldpdGhTdG9wVHMiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX3NjYW5uZXJPcGVuV2l0aFN0b3BUcworICAgIHNlbGYuX3Byb2Nlc3NNYXBbInNjYW5uZXJHZXQiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX3NjYW5uZXJHZXQKKyAgICBzZWxmLl9wcm9jZXNzTWFwWyJzY2FubmVyQ2xvc2UiXSA9IFByb2Nlc3Nvci5wcm9jZXNzX3NjYW5uZXJDbG9zZQorCisgIGRlZiBwcm9jZXNzKHNlbGYsIGlwcm90LCBvcHJvdCk6CisgICAgKG5hbWUsIHR5cGUsIHNlcWlkKSA9IGlwcm90LnJlYWRNZXNzYWdlQmVnaW4oKQorICAgIGlmIG5hbWUgbm90IGluIHNlbGYuX3Byb2Nlc3NNYXA6CisgICAgICBpcHJvdC5za2lwKFRUeXBlLlNUUlVDVCkKKyAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICAgIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLlVOS05PV05fTUVUSE9ELCAnVW5rbm93biBmdW5jdGlvbiAlcycgJSAobmFtZSkpCisgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuYW1lLCBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OLCBzZXFpZCkKKyAgICAgIHgud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgICAgb3Byb3QudHJhbnMuZmx1c2goKQorICAgICAgcmV0dXJuCisgICAgZWxzZToKKyAgICAgIHNlbGYuX3Byb2Nlc3NNYXBbbmFtZV0oc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCkKKyAgICByZXR1cm4gVHJ1ZQorCisgIGRlZiBwcm9jZXNzX2dldFRhYmxlTmFtZXMoc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCk6CisgICAgYXJncyA9IGdldFRhYmxlTmFtZXNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBnZXRUYWJsZU5hbWVzX3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBzZWxmLl9oYW5kbGVyLmdldFRhYmxlTmFtZXMoKQorICAgIGV4Y2VwdCBJT0Vycm9yLCBpbzoKKyAgICAgIHJlc3VsdC5pbyA9IGlvCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oImdldFRhYmxlTmFtZXMiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19nZXRDb2x1bW5EZXNjcmlwdG9ycyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHJlc3VsdC5zdWNjZXNzID0gc2VsZi5faGFuZGxlci5nZXRDb2x1bW5EZXNjcmlwdG9ycyhhcmdzLnRhYmxlTmFtZSkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXRDb2x1bW5EZXNjcmlwdG9ycyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX2dldFRhYmxlUmVnaW9ucyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZ2V0VGFibGVSZWdpb25zX2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBzZWxmLl9oYW5kbGVyLmdldFRhYmxlUmVnaW9ucyhhcmdzLnRhYmxlTmFtZSkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXRUYWJsZVJlZ2lvbnMiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19jcmVhdGVUYWJsZShzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gY3JlYXRlVGFibGVfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBjcmVhdGVUYWJsZV9yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIuY3JlYXRlVGFibGUoYXJncy50YWJsZU5hbWUsIGFyZ3MuY29sdW1uRmFtaWxpZXMpCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBleGNlcHQgSWxsZWdhbEFyZ3VtZW50LCBpYToKKyAgICAgIHJlc3VsdC5pYSA9IGlhCisgICAgZXhjZXB0IEFscmVhZHlFeGlzdHMsIGV4aXN0OgorICAgICAgcmVzdWx0LmV4aXN0ID0gZXhpc3QKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigiY3JlYXRlVGFibGUiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19kZWxldGVUYWJsZShzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZGVsZXRlVGFibGVfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBkZWxldGVUYWJsZV9yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIuZGVsZXRlVGFibGUoYXJncy50YWJsZU5hbWUpCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBleGNlcHQgTm90Rm91bmQsIG5mOgorICAgICAgcmVzdWx0Lm5mID0gbmYKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigiZGVsZXRlVGFibGUiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19nZXQoc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCk6CisgICAgYXJncyA9IGdldF9hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IGdldF9yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHJlc3VsdC5zdWNjZXNzID0gc2VsZi5faGFuZGxlci5nZXQoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbikKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIGV4Y2VwdCBOb3RGb3VuZCwgbmY6CisgICAgICByZXN1bHQubmYgPSBuZgorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXQiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19nZXRWZXIoc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCk6CisgICAgYXJncyA9IGdldFZlcl9hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IGdldFZlcl9yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHJlc3VsdC5zdWNjZXNzID0gc2VsZi5faGFuZGxlci5nZXRWZXIoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbiwgYXJncy5udW1WZXJzaW9ucykKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIGV4Y2VwdCBOb3RGb3VuZCwgbmY6CisgICAgICByZXN1bHQubmYgPSBuZgorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXRWZXIiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19nZXRWZXJUcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZ2V0VmVyVHNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBnZXRWZXJUc19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHJlc3VsdC5zdWNjZXNzID0gc2VsZi5faGFuZGxlci5nZXRWZXJUcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1uLCBhcmdzLnRpbWVzdGFtcCwgYXJncy5udW1WZXJzaW9ucykKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIGV4Y2VwdCBOb3RGb3VuZCwgbmY6CisgICAgICByZXN1bHQubmYgPSBuZgorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXRWZXJUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX2dldFJvdyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZ2V0Um93X2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gZ2V0Um93X3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBzZWxmLl9oYW5kbGVyLmdldFJvdyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3cpCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigiZ2V0Um93IiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3NfZ2V0Um93VHMoc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCk6CisgICAgYXJncyA9IGdldFJvd1RzX2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gZ2V0Um93VHNfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICByZXN1bHQuc3VjY2VzcyA9IHNlbGYuX2hhbmRsZXIuZ2V0Um93VHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLnRpbWVzdGFtcCkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJnZXRSb3dUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX3B1dChzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gcHV0X2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gcHV0X3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgc2VsZi5faGFuZGxlci5wdXQoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbiwgYXJncy52YWx1ZSkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIGV4Y2VwdCBJbGxlZ2FsQXJndW1lbnQsIGlhOgorICAgICAgcmVzdWx0LmlhID0gaWEKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigicHV0IiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3NfbXV0YXRlUm93KHNlbGYsIHNlcWlkLCBpcHJvdCwgb3Byb3QpOgorICAgIGFyZ3MgPSBtdXRhdGVSb3dfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBtdXRhdGVSb3dfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICBzZWxmLl9oYW5kbGVyLm11dGF0ZVJvdyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MubXV0YXRpb25zKQorICAgIGV4Y2VwdCBJT0Vycm9yLCBpbzoKKyAgICAgIHJlc3VsdC5pbyA9IGlvCisgICAgZXhjZXB0IElsbGVnYWxBcmd1bWVudCwgaWE6CisgICAgICByZXN1bHQuaWEgPSBpYQorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJtdXRhdGVSb3ciLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19tdXRhdGVSb3dUcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gbXV0YXRlUm93VHNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBtdXRhdGVSb3dUc19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIubXV0YXRlUm93VHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLm11dGF0aW9ucywgYXJncy50aW1lc3RhbXApCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBleGNlcHQgSWxsZWdhbEFyZ3VtZW50LCBpYToKKyAgICAgIHJlc3VsdC5pYSA9IGlhCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oIm11dGF0ZVJvd1RzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3NfbXV0YXRlUm93cyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gbXV0YXRlUm93c19hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IG11dGF0ZVJvd3NfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICBzZWxmLl9oYW5kbGVyLm11dGF0ZVJvd3MoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93QmF0Y2hlcykKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIGV4Y2VwdCBJbGxlZ2FsQXJndW1lbnQsIGlhOgorICAgICAgcmVzdWx0LmlhID0gaWEKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigibXV0YXRlUm93cyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX211dGF0ZVJvd3NUcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gbXV0YXRlUm93c1RzX2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gbXV0YXRlUm93c1RzX3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgc2VsZi5faGFuZGxlci5tdXRhdGVSb3dzVHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93QmF0Y2hlcywgYXJncy50aW1lc3RhbXApCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBleGNlcHQgSWxsZWdhbEFyZ3VtZW50LCBpYToKKyAgICAgIHJlc3VsdC5pYSA9IGlhCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4oIm11dGF0ZVJvd3NUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX2RlbGV0ZUFsbChzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZGVsZXRlQWxsX2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gZGVsZXRlQWxsX3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgc2VsZi5faGFuZGxlci5kZWxldGVBbGwoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbikKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJkZWxldGVBbGwiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19kZWxldGVBbGxUcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZGVsZXRlQWxsVHNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBkZWxldGVBbGxUc19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIuZGVsZXRlQWxsVHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbiwgYXJncy50aW1lc3RhbXApCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigiZGVsZXRlQWxsVHMiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19kZWxldGVBbGxSb3coc2VsZiwgc2VxaWQsIGlwcm90LCBvcHJvdCk6CisgICAgYXJncyA9IGRlbGV0ZUFsbFJvd19hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IGRlbGV0ZUFsbFJvd19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIuZGVsZXRlQWxsUm93KGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdykKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJkZWxldGVBbGxSb3ciLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19kZWxldGVBbGxSb3dUcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gZGVsZXRlQWxsUm93VHNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBkZWxldGVBbGxSb3dUc19yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHNlbGYuX2hhbmRsZXIuZGVsZXRlQWxsUm93VHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLnRpbWVzdGFtcCkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJkZWxldGVBbGxSb3dUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpCisgICAgcmVzdWx0LndyaXRlKG9wcm90KQorICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpCisgICAgb3Byb3QudHJhbnMuZmx1c2goKQorCisgIGRlZiBwcm9jZXNzX3NjYW5uZXJPcGVuKHNlbGYsIHNlcWlkLCBpcHJvdCwgb3Byb3QpOgorICAgIGFyZ3MgPSBzY2FubmVyT3Blbl9hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IHNjYW5uZXJPcGVuX3Jlc3VsdCgpCisgICAgdHJ5OgorICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBzZWxmLl9oYW5kbGVyLnNjYW5uZXJPcGVuKGFyZ3MudGFibGVOYW1lLCBhcmdzLnN0YXJ0Um93LCBhcmdzLmNvbHVtbnMpCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigic2Nhbm5lck9wZW4iLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworICBkZWYgcHJvY2Vzc19zY2FubmVyT3BlbldpdGhTdG9wKHNlbGYsIHNlcWlkLCBpcHJvdCwgb3Byb3QpOgorICAgIGFyZ3MgPSBzY2FubmVyT3BlbldpdGhTdG9wX2FyZ3MoKQorICAgIGFyZ3MucmVhZChpcHJvdCkKKyAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpCisgICAgcmVzdWx0ID0gc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQoKQorICAgIHRyeToKKyAgICAgIHJlc3VsdC5zdWNjZXNzID0gc2VsZi5faGFuZGxlci5zY2FubmVyT3BlbldpdGhTdG9wKGFyZ3MudGFibGVOYW1lLCBhcmdzLnN0YXJ0Um93LCBhcmdzLnN0b3BSb3csIGFyZ3MuY29sdW1ucykKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJzY2FubmVyT3BlbldpdGhTdG9wIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3Nfc2Nhbm5lck9wZW5UcyhzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gc2Nhbm5lck9wZW5Uc19hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IHNjYW5uZXJPcGVuVHNfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICByZXN1bHQuc3VjY2VzcyA9IHNlbGYuX2hhbmRsZXIuc2Nhbm5lck9wZW5UcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5zdGFydFJvdywgYXJncy5jb2x1bW5zLCBhcmdzLnRpbWVzdGFtcCkKKyAgICBleGNlcHQgSU9FcnJvciwgaW86CisgICAgICByZXN1bHQuaW8gPSBpbworICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJzY2FubmVyT3BlblRzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3Nfc2Nhbm5lck9wZW5XaXRoU3RvcFRzKHNlbGYsIHNlcWlkLCBpcHJvdCwgb3Byb3QpOgorICAgIGFyZ3MgPSBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICByZXN1bHQuc3VjY2VzcyA9IHNlbGYuX2hhbmRsZXIuc2Nhbm5lck9wZW5XaXRoU3RvcFRzKGFyZ3MudGFibGVOYW1lLCBhcmdzLnN0YXJ0Um93LCBhcmdzLnN0b3BSb3csIGFyZ3MuY29sdW1ucywgYXJncy50aW1lc3RhbXApCisgICAgZXhjZXB0IElPRXJyb3IsIGlvOgorICAgICAgcmVzdWx0LmlvID0gaW8KKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbigic2Nhbm5lck9wZW5XaXRoU3RvcFRzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3Nfc2Nhbm5lckdldChzZWxmLCBzZXFpZCwgaXByb3QsIG9wcm90KToKKyAgICBhcmdzID0gc2Nhbm5lckdldF9hcmdzKCkKKyAgICBhcmdzLnJlYWQoaXByb3QpCisgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKQorICAgIHJlc3VsdCA9IHNjYW5uZXJHZXRfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICByZXN1bHQuc3VjY2VzcyA9IHNlbGYuX2hhbmRsZXIuc2Nhbm5lckdldChhcmdzLmlkKQorICAgIGV4Y2VwdCBJT0Vycm9yLCBpbzoKKyAgICAgIHJlc3VsdC5pbyA9IGlvCisgICAgZXhjZXB0IElsbGVnYWxBcmd1bWVudCwgaWE6CisgICAgICByZXN1bHQuaWEgPSBpYQorICAgIGV4Y2VwdCBOb3RGb3VuZCwgbmY6CisgICAgICByZXN1bHQubmYgPSBuZgorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJzY2FubmVyR2V0IiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkKKyAgICByZXN1bHQud3JpdGUob3Byb3QpCisgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCkKKyAgICBvcHJvdC50cmFucy5mbHVzaCgpCisKKyAgZGVmIHByb2Nlc3Nfc2Nhbm5lckNsb3NlKHNlbGYsIHNlcWlkLCBpcHJvdCwgb3Byb3QpOgorICAgIGFyZ3MgPSBzY2FubmVyQ2xvc2VfYXJncygpCisgICAgYXJncy5yZWFkKGlwcm90KQorICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCkKKyAgICByZXN1bHQgPSBzY2FubmVyQ2xvc2VfcmVzdWx0KCkKKyAgICB0cnk6CisgICAgICBzZWxmLl9oYW5kbGVyLnNjYW5uZXJDbG9zZShhcmdzLmlkKQorICAgIGV4Y2VwdCBJT0Vycm9yLCBpbzoKKyAgICAgIHJlc3VsdC5pbyA9IGlvCisgICAgZXhjZXB0IElsbGVnYWxBcmd1bWVudCwgaWE6CisgICAgICByZXN1bHQuaWEgPSBpYQorICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKCJzY2FubmVyQ2xvc2UiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKQorICAgIHJlc3VsdC53cml0ZShvcHJvdCkKKyAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKQorICAgIG9wcm90LnRyYW5zLmZsdXNoKCkKKworCisjIEhFTFBFUiBGVU5DVElPTlMgQU5EIFNUUlVDVFVSRVMKKworY2xhc3MgZ2V0VGFibGVOYW1lc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgcGFzcworCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldFRhYmxlTmFtZXNfYXJncycpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZ2V0VGFibGVOYW1lc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLkxJU1QsICdzdWNjZXNzJywgKFRUeXBlLlNUUklORyxOb25lKSwgTm9uZSwgKSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuc3VjY2VzcyA9IE5vbmUKKyAgICBzZWxmLmlvID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnc3VjY2VzcycgaW4gZDoKKyAgICAgICAgc2VsZi5zdWNjZXNzID0gZFsnc3VjY2VzcyddCisgICAgICBpZiAnaW8nIGluIGQ6CisgICAgICAgIHNlbGYuaW8gPSBkWydpbyddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDA6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkxJU1Q6CisgICAgICAgICAgc2VsZi5zdWNjZXNzID0gW10KKyAgICAgICAgICAoX2V0eXBlMTksIF9zaXplMTYpID0gaXByb3QucmVhZExpc3RCZWdpbigpCisgICAgICAgICAgZm9yIF9pMjAgaW4geHJhbmdlKF9zaXplMTYpOgorICAgICAgICAgICAgX2VsZW0yMSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIHNlbGYuc3VjY2Vzcy5hcHBlbmQoX2VsZW0yMSkKKyAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdnZXRUYWJsZU5hbWVzX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5MSVNULCAwKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5zdWNjZXNzKSkKKyAgICAgIGZvciBpdGVyMjIgaW4gc2VsZi5zdWNjZXNzOgorICAgICAgICBvcHJvdC53cml0ZVN0cmluZyhpdGVyMjIpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLk1BUCwgJ3N1Y2Nlc3MnLCAoVFR5cGUuU1RSSU5HLE5vbmUsVFR5cGUuU1RSVUNULChDb2x1bW5EZXNjcmlwdG9yLCBDb2x1bW5EZXNjcmlwdG9yLnRocmlmdF9zcGVjKSksIE5vbmUsICksICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnN1Y2Nlc3MgPSBOb25lCisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5NQVA6CisgICAgICAgICAgc2VsZi5zdWNjZXNzID0ge30KKyAgICAgICAgICAoX2t0eXBlMjQsIF92dHlwZTI1LCBfc2l6ZTIzICkgPSBpcHJvdC5yZWFkTWFwQmVnaW4oKSAKKyAgICAgICAgICBmb3IgX2kyNyBpbiB4cmFuZ2UoX3NpemUyMyk6CisgICAgICAgICAgICBfa2V5MjggPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgICBfdmFsMjkgPSBDb2x1bW5EZXNjcmlwdG9yKCkKKyAgICAgICAgICAgIF92YWwyOS5yZWFkKGlwcm90KQorICAgICAgICAgICAgc2VsZi5zdWNjZXNzW19rZXkyOF0gPSBfdmFsMjkKKyAgICAgICAgICBpcHJvdC5yZWFkTWFwRW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5NQVAsIDApCisgICAgICBvcHJvdC53cml0ZU1hcEJlZ2luKFRUeXBlLlNUUklORywgVFR5cGUuU1RSVUNULCBsZW4oc2VsZi5zdWNjZXNzKSkKKyAgICAgIGZvciBraXRlcjMwLHZpdGVyMzEgaW4gc2VsZi5zdWNjZXNzLml0ZW1zKCk6CisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKGtpdGVyMzApCisgICAgICAgIHZpdGVyMzEud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZU1hcEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGdldFRhYmxlUmVnaW9uc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZ2V0VGFibGVSZWdpb25zX2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZ2V0VGFibGVSZWdpb25zX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICAoMCwgVFR5cGUuTElTVCwgJ3N1Y2Nlc3MnLCAoVFR5cGUuU1RSVUNULChSZWdpb25EZXNjcmlwdG9yLCBSZWdpb25EZXNjcmlwdG9yLnRocmlmdF9zcGVjKSksIE5vbmUsICksICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnN1Y2Nlc3MgPSBOb25lCisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IFtdCisgICAgICAgICAgKF9ldHlwZTM1LCBfc2l6ZTMyKSA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKQorICAgICAgICAgIGZvciBfaTM2IGluIHhyYW5nZShfc2l6ZTMyKToKKyAgICAgICAgICAgIF9lbGVtMzcgPSBSZWdpb25EZXNjcmlwdG9yKCkKKyAgICAgICAgICAgIF9lbGVtMzcucmVhZChpcHJvdCkKKyAgICAgICAgICAgIHNlbGYuc3VjY2Vzcy5hcHBlbmQoX2VsZW0zNykKKyAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdnZXRUYWJsZVJlZ2lvbnNfcmVzdWx0JykKKyAgICBpZiBzZWxmLnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignc3VjY2VzcycsIFRUeXBlLkxJU1QsIDApCisgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihUVHlwZS5TVFJVQ1QsIGxlbihzZWxmLnN1Y2Nlc3MpKQorICAgICAgZm9yIGl0ZXIzOCBpbiBzZWxmLnN1Y2Nlc3M6CisgICAgICAgIGl0ZXIzOC53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGNyZWF0ZVRhYmxlX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5MSVNULCAnY29sdW1uRmFtaWxpZXMnLCAoVFR5cGUuU1RSVUNULChDb2x1bW5EZXNjcmlwdG9yLCBDb2x1bW5EZXNjcmlwdG9yLnRocmlmdF9zcGVjKSksIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5jb2x1bW5GYW1pbGllcyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ2NvbHVtbkZhbWlsaWVzJyBpbiBkOgorICAgICAgICBzZWxmLmNvbHVtbkZhbWlsaWVzID0gZFsnY29sdW1uRmFtaWxpZXMnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkxJU1Q6CisgICAgICAgICAgc2VsZi5jb2x1bW5GYW1pbGllcyA9IFtdCisgICAgICAgICAgKF9ldHlwZTQyLCBfc2l6ZTM5KSA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKQorICAgICAgICAgIGZvciBfaTQzIGluIHhyYW5nZShfc2l6ZTM5KToKKyAgICAgICAgICAgIF9lbGVtNDQgPSBDb2x1bW5EZXNjcmlwdG9yKCkKKyAgICAgICAgICAgIF9lbGVtNDQucmVhZChpcHJvdCkKKyAgICAgICAgICAgIHNlbGYuY29sdW1uRmFtaWxpZXMuYXBwZW5kKF9lbGVtNDQpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdjcmVhdGVUYWJsZV9hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1uRmFtaWxpZXMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignY29sdW1uRmFtaWxpZXMnLCBUVHlwZS5MSVNULCAyKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSVUNULCBsZW4oc2VsZi5jb2x1bW5GYW1pbGllcykpCisgICAgICBmb3IgaXRlcjQ1IGluIHNlbGYuY29sdW1uRmFtaWxpZXM6CisgICAgICAgIGl0ZXI0NS53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBjcmVhdGVUYWJsZV9yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSVUNULCAnaWEnLCAoSWxsZWdhbEFyZ3VtZW50LCBJbGxlZ2FsQXJndW1lbnQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuU1RSVUNULCAnZXhpc3QnLCAoQWxyZWFkeUV4aXN0cywgQWxyZWFkeUV4aXN0cy50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMworICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBzZWxmLmlhID0gTm9uZQorICAgIHNlbGYuZXhpc3QgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKyAgICAgIGlmICdpYScgaW4gZDoKKyAgICAgICAgc2VsZi5pYSA9IGRbJ2lhJ10KKyAgICAgIGlmICdleGlzdCcgaW4gZDoKKyAgICAgICAgc2VsZi5leGlzdCA9IGRbJ2V4aXN0J10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlhID0gSWxsZWdhbEFyZ3VtZW50KCkKKyAgICAgICAgICBzZWxmLmlhLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDM6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmV4aXN0ID0gQWxyZWFkeUV4aXN0cygpCisgICAgICAgICAgc2VsZi5leGlzdC5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdjcmVhdGVUYWJsZV9yZXN1bHQnKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pYSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpYScsIFRUeXBlLlNUUlVDVCwgMikKKyAgICAgIHNlbGYuaWEud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmV4aXN0ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2V4aXN0JywgVFR5cGUuU1RSVUNULCAzKQorICAgICAgc2VsZi5leGlzdC53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGRlbGV0ZVRhYmxlX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdkZWxldGVUYWJsZV9hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGRlbGV0ZVRhYmxlX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJVQ1QsICduZicsIChOb3RGb3VuZCwgTm90Rm91bmQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuaW8gPSBOb25lCisgICAgc2VsZi5uZiA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ25mJyBpbiBkOgorICAgICAgICBzZWxmLm5mID0gZFsnbmYnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYubmYgPSBOb3RGb3VuZCgpCisgICAgICAgICAgc2VsZi5uZi5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdkZWxldGVUYWJsZV9yZXN1bHQnKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5uZiAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCduZicsIFRUeXBlLlNUUlVDVCwgMikKKyAgICAgIHNlbGYubmYud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3JvdycsIE5vbmUsIE5vbmUsICksICMgMgorICAgICgzLCBUVHlwZS5TVFJJTkcsICdjb2x1bW4nLCBOb25lLCBOb25lLCApLCAjIDMKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIHNlbGYucm93ID0gTm9uZQorICAgIHNlbGYuY29sdW1uID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisgICAgICBpZiAncm93JyBpbiBkOgorICAgICAgICBzZWxmLnJvdyA9IGRbJ3JvdyddCisgICAgICBpZiAnY29sdW1uJyBpbiBkOgorICAgICAgICBzZWxmLmNvbHVtbiA9IGRbJ2NvbHVtbiddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYucm93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5jb2x1bW4gPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldF9hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYucm93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3JvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYucm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5jb2x1bW4gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignY29sdW1uJywgVFR5cGUuU1RSSU5HLCAzKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5jb2x1bW4pCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRfcmVzdWx0OgorCisgIHRocmlmdF9zcGVjID0gKAorICAgICgwLCBUVHlwZS5TVFJJTkcsICdzdWNjZXNzJywgTm9uZSwgTm9uZSwgKSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSVUNULCAnbmYnLCAoTm90Rm91bmQsIE5vdEZvdW5kLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAyCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnN1Y2Nlc3MgPSBOb25lCisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBzZWxmLm5mID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnc3VjY2VzcycgaW4gZDoKKyAgICAgICAgc2VsZi5zdWNjZXNzID0gZFsnc3VjY2VzcyddCisgICAgICBpZiAnaW8nIGluIGQ6CisgICAgICAgIHNlbGYuaW8gPSBkWydpbyddCisgICAgICBpZiAnbmYnIGluIGQ6CisgICAgICAgIHNlbGYubmYgPSBkWyduZiddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDA6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5uZiA9IE5vdEZvdW5kKCkKKyAgICAgICAgICBzZWxmLm5mLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldF9yZXN1bHQnKQorICAgIGlmIHNlbGYuc3VjY2VzcyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdWNjZXNzJywgVFR5cGUuU1RSSU5HLCAwKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5zdWNjZXNzKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLm5mICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ25mJywgVFR5cGUuU1RSVUNULCAyKQorICAgICAgc2VsZi5uZi53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGdldFZlcl9hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSSU5HLCAncm93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ2NvbHVtbicsIE5vbmUsIE5vbmUsICksICMgMworICAgICg0LCBUVHlwZS5JMzIsICdudW1WZXJzaW9ucycsIE5vbmUsIE5vbmUsICksICMgNAorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgc2VsZi5jb2x1bW4gPSBOb25lCisgICAgc2VsZi5udW1WZXJzaW9ucyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ2NvbHVtbicgaW4gZDoKKyAgICAgICAgc2VsZi5jb2x1bW4gPSBkWydjb2x1bW4nXQorICAgICAgaWYgJ251bVZlcnNpb25zJyBpbiBkOgorICAgICAgICBzZWxmLm51bVZlcnNpb25zID0gZFsnbnVtVmVyc2lvbnMnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuY29sdW1uID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA0OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5JMzI6CisgICAgICAgICAgc2VsZi5udW1WZXJzaW9ucyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZ2V0VmVyX2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5yb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93JywgVFR5cGUuU1RSSU5HLCAyKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5yb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmNvbHVtbiAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdjb2x1bW4nLCBUVHlwZS5TVFJJTkcsIDMpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLmNvbHVtbikKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYubnVtVmVyc2lvbnMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignbnVtVmVyc2lvbnMnLCBUVHlwZS5JMzIsIDQpCisgICAgICBvcHJvdC53cml0ZUkzMihzZWxmLm51bVZlcnNpb25zKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZ2V0VmVyX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICAoMCwgVFR5cGUuTElTVCwgJ3N1Y2Nlc3MnLCAoVFR5cGUuU1RSSU5HLE5vbmUpLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJVQ1QsICduZicsIChOb3RGb3VuZCwgTm90Rm91bmQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuc3VjY2VzcyA9IE5vbmUKKyAgICBzZWxmLmlvID0gTm9uZQorICAgIHNlbGYubmYgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdzdWNjZXNzJyBpbiBkOgorICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBkWydzdWNjZXNzJ10KKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKyAgICAgIGlmICduZicgaW4gZDoKKyAgICAgICAgc2VsZi5uZiA9IGRbJ25mJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTElTVDoKKyAgICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBbXQorICAgICAgICAgIChfZXR5cGU0OSwgX3NpemU0NikgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCkKKyAgICAgICAgICBmb3IgX2k1MCBpbiB4cmFuZ2UoX3NpemU0Nik6CisgICAgICAgICAgICBfZWxlbTUxID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICAgICAgc2VsZi5zdWNjZXNzLmFwcGVuZChfZWxlbTUxKQorICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLm5mID0gTm90Rm91bmQoKQorICAgICAgICAgIHNlbGYubmYucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZ2V0VmVyX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5MSVNULCAwKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5zdWNjZXNzKSkKKyAgICAgIGZvciBpdGVyNTIgaW4gc2VsZi5zdWNjZXNzOgorICAgICAgICBvcHJvdC53cml0ZVN0cmluZyhpdGVyNTIpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLm5mICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ25mJywgVFR5cGUuU1RSVUNULCAyKQorICAgICAgc2VsZi5uZi53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGdldFZlclRzX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuU1RSSU5HLCAnY29sdW1uJywgTm9uZSwgTm9uZSwgKSwgIyAzCisgICAgKDQsIFRUeXBlLkk2NCwgJ3RpbWVzdGFtcCcsIE5vbmUsIE5vbmUsICksICMgNAorICAgICg1LCBUVHlwZS5JMzIsICdudW1WZXJzaW9ucycsIE5vbmUsIE5vbmUsICksICMgNQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgc2VsZi5jb2x1bW4gPSBOb25lCisgICAgc2VsZi50aW1lc3RhbXAgPSBOb25lCisgICAgc2VsZi5udW1WZXJzaW9ucyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ2NvbHVtbicgaW4gZDoKKyAgICAgICAgc2VsZi5jb2x1bW4gPSBkWydjb2x1bW4nXQorICAgICAgaWYgJ3RpbWVzdGFtcCcgaW4gZDoKKyAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBkWyd0aW1lc3RhbXAnXQorICAgICAgaWYgJ251bVZlcnNpb25zJyBpbiBkOgorICAgICAgICBzZWxmLm51bVZlcnNpb25zID0gZFsnbnVtVmVyc2lvbnMnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuY29sdW1uID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA0OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5JNjQ6CisgICAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDU6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLm51bVZlcnNpb25zID0gaXByb3QucmVhZEkzMigpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdnZXRWZXJUc19hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYucm93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3JvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYucm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5jb2x1bW4gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignY29sdW1uJywgVFR5cGUuU1RSSU5HLCAzKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5jb2x1bW4pCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnRpbWVzdGFtcCAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0aW1lc3RhbXAnLCBUVHlwZS5JNjQsIDQpCisgICAgICBvcHJvdC53cml0ZUk2NChzZWxmLnRpbWVzdGFtcCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYubnVtVmVyc2lvbnMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignbnVtVmVyc2lvbnMnLCBUVHlwZS5JMzIsIDUpCisgICAgICBvcHJvdC53cml0ZUkzMihzZWxmLm51bVZlcnNpb25zKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZ2V0VmVyVHNfcmVzdWx0OgorCisgIHRocmlmdF9zcGVjID0gKAorICAgICgwLCBUVHlwZS5MSVNULCAnc3VjY2VzcycsIChUVHlwZS5TVFJJTkcsTm9uZSksIE5vbmUsICksICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUlVDVCwgJ25mJywgKE5vdEZvdW5kLCBOb3RGb3VuZC50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdWNjZXNzID0gTm9uZQorICAgIHNlbGYuaW8gPSBOb25lCisgICAgc2VsZi5uZiA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ25mJyBpbiBkOgorICAgICAgICBzZWxmLm5mID0gZFsnbmYnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IFtdCisgICAgICAgICAgKF9ldHlwZTU2LCBfc2l6ZTUzKSA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKQorICAgICAgICAgIGZvciBfaTU3IGluIHhyYW5nZShfc2l6ZTUzKToKKyAgICAgICAgICAgIF9lbGVtNTggPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgICBzZWxmLnN1Y2Nlc3MuYXBwZW5kKF9lbGVtNTgpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYubmYgPSBOb3RGb3VuZCgpCisgICAgICAgICAgc2VsZi5uZi5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdnZXRWZXJUc19yZXN1bHQnKQorICAgIGlmIHNlbGYuc3VjY2VzcyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdWNjZXNzJywgVFR5cGUuTElTVCwgMCkKKyAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKFRUeXBlLlNUUklORywgbGVuKHNlbGYuc3VjY2VzcykpCisgICAgICBmb3IgaXRlcjU5IGluIHNlbGYuc3VjY2VzczoKKyAgICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoaXRlcjU5KQorICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5uZiAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCduZicsIFRUeXBlLlNUUlVDVCwgMikKKyAgICAgIHNlbGYubmYud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRSb3dfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3JvdycsIE5vbmUsIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKyAgICAgIGlmICdyb3cnIGluIGQ6CisgICAgICAgIHNlbGYucm93ID0gZFsncm93J10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5yb3cgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldFJvd19hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYucm93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3JvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYucm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZ2V0Um93X3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICAoMCwgVFR5cGUuTUFQLCAnc3VjY2VzcycsIChUVHlwZS5TVFJJTkcsTm9uZSxUVHlwZS5TVFJJTkcsTm9uZSksIE5vbmUsICksICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnN1Y2Nlc3MgPSBOb25lCisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5NQVA6CisgICAgICAgICAgc2VsZi5zdWNjZXNzID0ge30KKyAgICAgICAgICAoX2t0eXBlNjEsIF92dHlwZTYyLCBfc2l6ZTYwICkgPSBpcHJvdC5yZWFkTWFwQmVnaW4oKSAKKyAgICAgICAgICBmb3IgX2k2NCBpbiB4cmFuZ2UoX3NpemU2MCk6CisgICAgICAgICAgICBfa2V5NjUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgICBfdmFsNjYgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgICBzZWxmLnN1Y2Nlc3NbX2tleTY1XSA9IF92YWw2NgorICAgICAgICAgIGlwcm90LnJlYWRNYXBFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZ2V0Um93X3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5NQVAsIDApCisgICAgICBvcHJvdC53cml0ZU1hcEJlZ2luKFRUeXBlLlNUUklORywgVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5zdWNjZXNzKSkKKyAgICAgIGZvciBraXRlcjY3LHZpdGVyNjggaW4gc2VsZi5zdWNjZXNzLml0ZW1zKCk6CisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKGtpdGVyNjcpCisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKHZpdGVyNjgpCisgICAgICBvcHJvdC53cml0ZU1hcEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIGdldFJvd1RzX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuSTY0LCAndGltZXN0YW1wJywgTm9uZSwgTm9uZSwgKSwgIyAzCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnJvdyA9IE5vbmUKKyAgICBzZWxmLnRpbWVzdGFtcCA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ3RpbWVzdGFtcCcgaW4gZDoKKyAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBkWyd0aW1lc3RhbXAnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTY0OgorICAgICAgICAgIHNlbGYudGltZXN0YW1wID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdnZXRSb3dUc19hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYucm93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3JvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYucm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi50aW1lc3RhbXAgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGltZXN0YW1wJywgVFR5cGUuSTY0LCAzKQorICAgICAgb3Byb3Qud3JpdGVJNjQoc2VsZi50aW1lc3RhbXApCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBnZXRSb3dUc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLk1BUCwgJ3N1Y2Nlc3MnLCAoVFR5cGUuU1RSSU5HLE5vbmUsVFR5cGUuU1RSSU5HLE5vbmUpLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdWNjZXNzID0gTm9uZQorICAgIHNlbGYuaW8gPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdzdWNjZXNzJyBpbiBkOgorICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBkWydzdWNjZXNzJ10KKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTUFQOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IHt9CisgICAgICAgICAgKF9rdHlwZTcwLCBfdnR5cGU3MSwgX3NpemU2OSApID0gaXByb3QucmVhZE1hcEJlZ2luKCkgCisgICAgICAgICAgZm9yIF9pNzMgaW4geHJhbmdlKF9zaXplNjkpOgorICAgICAgICAgICAgX2tleTc0ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICAgICAgX3ZhbDc1ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICAgICAgc2VsZi5zdWNjZXNzW19rZXk3NF0gPSBfdmFsNzUKKyAgICAgICAgICBpcHJvdC5yZWFkTWFwRW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2dldFJvd1RzX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5NQVAsIDApCisgICAgICBvcHJvdC53cml0ZU1hcEJlZ2luKFRUeXBlLlNUUklORywgVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5zdWNjZXNzKSkKKyAgICAgIGZvciBraXRlcjc2LHZpdGVyNzcgaW4gc2VsZi5zdWNjZXNzLml0ZW1zKCk6CisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKGtpdGVyNzYpCisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKHZpdGVyNzcpCisgICAgICBvcHJvdC53cml0ZU1hcEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIHB1dF9hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSSU5HLCAncm93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ2NvbHVtbicsIE5vbmUsIE5vbmUsICksICMgMworICAgICg0LCBUVHlwZS5TVFJJTkcsICd2YWx1ZScsIE5vbmUsIE5vbmUsICksICMgNAorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgc2VsZi5jb2x1bW4gPSBOb25lCisgICAgc2VsZi52YWx1ZSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ2NvbHVtbicgaW4gZDoKKyAgICAgICAgc2VsZi5jb2x1bW4gPSBkWydjb2x1bW4nXQorICAgICAgaWYgJ3ZhbHVlJyBpbiBkOgorICAgICAgICBzZWxmLnZhbHVlID0gZFsndmFsdWUnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuY29sdW1uID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA0OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi52YWx1ZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbigncHV0X2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5yb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93JywgVFR5cGUuU1RSSU5HLCAyKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5yb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmNvbHVtbiAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdjb2x1bW4nLCBUVHlwZS5TVFJJTkcsIDMpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLmNvbHVtbikKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYudmFsdWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndmFsdWUnLCBUVHlwZS5TVFJJTkcsIDQpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnZhbHVlKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgcHV0X3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJVQ1QsICdpYScsIChJbGxlZ2FsQXJndW1lbnQsIElsbGVnYWxBcmd1bWVudC50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBzZWxmLmlhID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnaW8nIGluIGQ6CisgICAgICAgIHNlbGYuaW8gPSBkWydpbyddCisgICAgICBpZiAnaWEnIGluIGQ6CisgICAgICAgIHNlbGYuaWEgPSBkWydpYSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pYSA9IElsbGVnYWxBcmd1bWVudCgpCisgICAgICAgICAgc2VsZi5pYS5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdwdXRfcmVzdWx0JykKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaWEgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaWEnLCBUVHlwZS5TVFJVQ1QsIDIpCisgICAgICBzZWxmLmlhLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgbXV0YXRlUm93X2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuTElTVCwgJ211dGF0aW9ucycsIChUVHlwZS5TVFJVQ1QsKE11dGF0aW9uLCBNdXRhdGlvbi50aHJpZnRfc3BlYykpLCBOb25lLCApLCAjIDMKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIHNlbGYucm93ID0gTm9uZQorICAgIHNlbGYubXV0YXRpb25zID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisgICAgICBpZiAncm93JyBpbiBkOgorICAgICAgICBzZWxmLnJvdyA9IGRbJ3JvdyddCisgICAgICBpZiAnbXV0YXRpb25zJyBpbiBkOgorICAgICAgICBzZWxmLm11dGF0aW9ucyA9IGRbJ211dGF0aW9ucyddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYucm93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYubXV0YXRpb25zID0gW10KKyAgICAgICAgICAoX2V0eXBlODEsIF9zaXplNzgpID0gaXByb3QucmVhZExpc3RCZWdpbigpCisgICAgICAgICAgZm9yIF9pODIgaW4geHJhbmdlKF9zaXplNzgpOgorICAgICAgICAgICAgX2VsZW04MyA9IE11dGF0aW9uKCkKKyAgICAgICAgICAgIF9lbGVtODMucmVhZChpcHJvdCkKKyAgICAgICAgICAgIHNlbGYubXV0YXRpb25zLmFwcGVuZChfZWxlbTgzKQorICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignbXV0YXRlUm93X2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5yb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93JywgVFR5cGUuU1RSSU5HLCAyKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5yb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLm11dGF0aW9ucyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtdXRhdGlvbnMnLCBUVHlwZS5MSVNULCAzKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSVUNULCBsZW4oc2VsZi5tdXRhdGlvbnMpKQorICAgICAgZm9yIGl0ZXI4NCBpbiBzZWxmLm11dGF0aW9uczoKKyAgICAgICAgaXRlcjg0LndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIG11dGF0ZVJvd19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSVUNULCAnaWEnLCAoSWxsZWdhbEFyZ3VtZW50LCBJbGxlZ2FsQXJndW1lbnQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuaW8gPSBOb25lCisgICAgc2VsZi5pYSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ2lhJyBpbiBkOgorICAgICAgICBzZWxmLmlhID0gZFsnaWEnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaWEgPSBJbGxlZ2FsQXJndW1lbnQoKQorICAgICAgICAgIHNlbGYuaWEucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignbXV0YXRlUm93X3Jlc3VsdCcpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlhICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lhJywgVFR5cGUuU1RSVUNULCAyKQorICAgICAgc2VsZi5pYS53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIG11dGF0ZVJvd1RzX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuTElTVCwgJ211dGF0aW9ucycsIChUVHlwZS5TVFJVQ1QsKE11dGF0aW9uLCBNdXRhdGlvbi50aHJpZnRfc3BlYykpLCBOb25lLCApLCAjIDMKKyAgICAoNCwgVFR5cGUuSTY0LCAndGltZXN0YW1wJywgTm9uZSwgTm9uZSwgKSwgIyA0CisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnJvdyA9IE5vbmUKKyAgICBzZWxmLm11dGF0aW9ucyA9IE5vbmUKKyAgICBzZWxmLnRpbWVzdGFtcCA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ211dGF0aW9ucycgaW4gZDoKKyAgICAgICAgc2VsZi5tdXRhdGlvbnMgPSBkWydtdXRhdGlvbnMnXQorICAgICAgaWYgJ3RpbWVzdGFtcCcgaW4gZDoKKyAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBkWyd0aW1lc3RhbXAnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTElTVDoKKyAgICAgICAgICBzZWxmLm11dGF0aW9ucyA9IFtdCisgICAgICAgICAgKF9ldHlwZTg4LCBfc2l6ZTg1KSA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKQorICAgICAgICAgIGZvciBfaTg5IGluIHhyYW5nZShfc2l6ZTg1KToKKyAgICAgICAgICAgIF9lbGVtOTAgPSBNdXRhdGlvbigpCisgICAgICAgICAgICBfZWxlbTkwLnJlYWQoaXByb3QpCisgICAgICAgICAgICBzZWxmLm11dGF0aW9ucy5hcHBlbmQoX2VsZW05MCkKKyAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDQ6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkk2NDoKKyAgICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignbXV0YXRlUm93VHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdyb3cnLCBUVHlwZS5TVFJJTkcsIDIpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYubXV0YXRpb25zICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ211dGF0aW9ucycsIFRUeXBlLkxJU1QsIDMpCisgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihUVHlwZS5TVFJVQ1QsIGxlbihzZWxmLm11dGF0aW9ucykpCisgICAgICBmb3IgaXRlcjkxIGluIHNlbGYubXV0YXRpb25zOgorICAgICAgICBpdGVyOTEud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi50aW1lc3RhbXAgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGltZXN0YW1wJywgVFR5cGUuSTY0LCA0KQorICAgICAgb3Byb3Qud3JpdGVJNjQoc2VsZi50aW1lc3RhbXApCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBtdXRhdGVSb3dUc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSVUNULCAnaWEnLCAoSWxsZWdhbEFyZ3VtZW50LCBJbGxlZ2FsQXJndW1lbnQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuaW8gPSBOb25lCisgICAgc2VsZi5pYSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ2lhJyBpbiBkOgorICAgICAgICBzZWxmLmlhID0gZFsnaWEnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaWEgPSBJbGxlZ2FsQXJndW1lbnQoKQorICAgICAgICAgIHNlbGYuaWEucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignbXV0YXRlUm93VHNfcmVzdWx0JykKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaWEgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaWEnLCBUVHlwZS5TVFJVQ1QsIDIpCisgICAgICBzZWxmLmlhLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgbXV0YXRlUm93c19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuTElTVCwgJ3Jvd0JhdGNoZXMnLCAoVFR5cGUuU1RSVUNULChCYXRjaE11dGF0aW9uLCBCYXRjaE11dGF0aW9uLnRocmlmdF9zcGVjKSksIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3dCYXRjaGVzID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisgICAgICBpZiAncm93QmF0Y2hlcycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3dCYXRjaGVzID0gZFsncm93QmF0Y2hlcyddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTElTVDoKKyAgICAgICAgICBzZWxmLnJvd0JhdGNoZXMgPSBbXQorICAgICAgICAgIChfZXR5cGU5NSwgX3NpemU5MikgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCkKKyAgICAgICAgICBmb3IgX2k5NiBpbiB4cmFuZ2UoX3NpemU5Mik6CisgICAgICAgICAgICBfZWxlbTk3ID0gQmF0Y2hNdXRhdGlvbigpCisgICAgICAgICAgICBfZWxlbTk3LnJlYWQoaXByb3QpCisgICAgICAgICAgICBzZWxmLnJvd0JhdGNoZXMuYXBwZW5kKF9lbGVtOTcpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdtdXRhdGVSb3dzX2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5yb3dCYXRjaGVzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3Jvd0JhdGNoZXMnLCBUVHlwZS5MSVNULCAyKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSVUNULCBsZW4oc2VsZi5yb3dCYXRjaGVzKSkKKyAgICAgIGZvciBpdGVyOTggaW4gc2VsZi5yb3dCYXRjaGVzOgorICAgICAgICBpdGVyOTgud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgbXV0YXRlUm93c19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSVUNULCAnaWEnLCAoSWxsZWdhbEFyZ3VtZW50LCBJbGxlZ2FsQXJndW1lbnQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuaW8gPSBOb25lCisgICAgc2VsZi5pYSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ2lhJyBpbiBkOgorICAgICAgICBzZWxmLmlhID0gZFsnaWEnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaWEgPSBJbGxlZ2FsQXJndW1lbnQoKQorICAgICAgICAgIHNlbGYuaWEucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignbXV0YXRlUm93c19yZXN1bHQnKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pYSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpYScsIFRUeXBlLlNUUlVDVCwgMikKKyAgICAgIHNlbGYuaWEud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBtdXRhdGVSb3dzVHNfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLkxJU1QsICdyb3dCYXRjaGVzJywgKFRUeXBlLlNUUlVDVCwoQmF0Y2hNdXRhdGlvbiwgQmF0Y2hNdXRhdGlvbi50aHJpZnRfc3BlYykpLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuSTY0LCAndGltZXN0YW1wJywgTm9uZSwgTm9uZSwgKSwgIyAzCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnJvd0JhdGNoZXMgPSBOb25lCisgICAgc2VsZi50aW1lc3RhbXAgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKyAgICAgIGlmICdyb3dCYXRjaGVzJyBpbiBkOgorICAgICAgICBzZWxmLnJvd0JhdGNoZXMgPSBkWydyb3dCYXRjaGVzJ10KKyAgICAgIGlmICd0aW1lc3RhbXAnIGluIGQ6CisgICAgICAgIHNlbGYudGltZXN0YW1wID0gZFsndGltZXN0YW1wJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYucm93QmF0Y2hlcyA9IFtdCisgICAgICAgICAgKF9ldHlwZTEwMiwgX3NpemU5OSkgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCkKKyAgICAgICAgICBmb3IgX2kxMDMgaW4geHJhbmdlKF9zaXplOTkpOgorICAgICAgICAgICAgX2VsZW0xMDQgPSBCYXRjaE11dGF0aW9uKCkKKyAgICAgICAgICAgIF9lbGVtMTA0LnJlYWQoaXByb3QpCisgICAgICAgICAgICBzZWxmLnJvd0JhdGNoZXMuYXBwZW5kKF9lbGVtMTA0KQorICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTY0OgorICAgICAgICAgIHNlbGYudGltZXN0YW1wID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdtdXRhdGVSb3dzVHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnJvd0JhdGNoZXMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93QmF0Y2hlcycsIFRUeXBlLkxJU1QsIDIpCisgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihUVHlwZS5TVFJVQ1QsIGxlbihzZWxmLnJvd0JhdGNoZXMpKQorICAgICAgZm9yIGl0ZXIxMDUgaW4gc2VsZi5yb3dCYXRjaGVzOgorICAgICAgICBpdGVyMTA1LndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYudGltZXN0YW1wICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RpbWVzdGFtcCcsIFRUeXBlLkk2NCwgMykKKyAgICAgIG9wcm90LndyaXRlSTY0KHNlbGYudGltZXN0YW1wKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgbXV0YXRlUm93c1RzX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJVQ1QsICdpYScsIChJbGxlZ2FsQXJndW1lbnQsIElsbGVnYWxBcmd1bWVudC50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBzZWxmLmlhID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnaW8nIGluIGQ6CisgICAgICAgIHNlbGYuaW8gPSBkWydpbyddCisgICAgICBpZiAnaWEnIGluIGQ6CisgICAgICAgIHNlbGYuaWEgPSBkWydpYSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pYSA9IElsbGVnYWxBcmd1bWVudCgpCisgICAgICAgICAgc2VsZi5pYS5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdtdXRhdGVSb3dzVHNfcmVzdWx0JykKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaWEgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaWEnLCBUVHlwZS5TVFJVQ1QsIDIpCisgICAgICBzZWxmLmlhLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZGVsZXRlQWxsX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3RhYmxlTmFtZScsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuU1RSSU5HLCAnY29sdW1uJywgTm9uZSwgTm9uZSwgKSwgIyAzCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnJvdyA9IE5vbmUKKyAgICBzZWxmLmNvbHVtbiA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3JvdycgaW4gZDoKKyAgICAgICAgc2VsZi5yb3cgPSBkWydyb3cnXQorICAgICAgaWYgJ2NvbHVtbicgaW4gZDoKKyAgICAgICAgc2VsZi5jb2x1bW4gPSBkWydjb2x1bW4nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuY29sdW1uID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdkZWxldGVBbGxfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdyb3cnLCBUVHlwZS5TVFJJTkcsIDIpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1uICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbHVtbicsIFRUeXBlLlNUUklORywgMykKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuY29sdW1uKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZGVsZXRlQWxsX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZGVsZXRlQWxsX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBkZWxldGVBbGxUc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSSU5HLCAncm93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ2NvbHVtbicsIE5vbmUsIE5vbmUsICksICMgMworICAgICg0LCBUVHlwZS5JNjQsICd0aW1lc3RhbXAnLCBOb25lLCBOb25lLCApLCAjIDQKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIHNlbGYucm93ID0gTm9uZQorICAgIHNlbGYuY29sdW1uID0gTm9uZQorICAgIHNlbGYudGltZXN0YW1wID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAndGFibGVOYW1lJyBpbiBkOgorICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGRbJ3RhYmxlTmFtZSddCisgICAgICBpZiAncm93JyBpbiBkOgorICAgICAgICBzZWxmLnJvdyA9IGRbJ3JvdyddCisgICAgICBpZiAnY29sdW1uJyBpbiBkOgorICAgICAgICBzZWxmLmNvbHVtbiA9IGRbJ2NvbHVtbiddCisgICAgICBpZiAndGltZXN0YW1wJyBpbiBkOgorICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IGRbJ3RpbWVzdGFtcCddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYucm93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5jb2x1bW4gPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDQ6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkk2NDoKKyAgICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZGVsZXRlQWxsVHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdyb3cnLCBUVHlwZS5TVFJJTkcsIDIpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1uICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbHVtbicsIFRUeXBlLlNUUklORywgMykKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuY29sdW1uKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi50aW1lc3RhbXAgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGltZXN0YW1wJywgVFR5cGUuSTY0LCA0KQorICAgICAgb3Byb3Qud3JpdGVJNjQoc2VsZi50aW1lc3RhbXApCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBkZWxldGVBbGxUc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUlVDVCwgJ2lvJywgKElPRXJyb3IsIElPRXJyb3IudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDEKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuaW8gPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2RlbGV0ZUFsbFRzX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBkZWxldGVBbGxSb3dfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3JvdycsIE5vbmUsIE5vbmUsICksICMgMgorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKyAgICAgIGlmICdyb3cnIGluIGQ6CisgICAgICAgIHNlbGYucm93ID0gZFsncm93J10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5yb3cgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ2RlbGV0ZUFsbFJvd19hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYucm93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3JvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYucm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZGVsZXRlQWxsUm93X3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZGVsZXRlQWxsUm93X3Jlc3VsdCcpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBkZWxldGVBbGxSb3dUc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSSU5HLCAncm93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLkk2NCwgJ3RpbWVzdGFtcCcsIE5vbmUsIE5vbmUsICksICMgMworICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi50YWJsZU5hbWUgPSBOb25lCisgICAgc2VsZi5yb3cgPSBOb25lCisgICAgc2VsZi50aW1lc3RhbXAgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKyAgICAgIGlmICdyb3cnIGluIGQ6CisgICAgICAgIHNlbGYucm93ID0gZFsncm93J10KKyAgICAgIGlmICd0aW1lc3RhbXAnIGluIGQ6CisgICAgICAgIHNlbGYudGltZXN0YW1wID0gZFsndGltZXN0YW1wJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5yb3cgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDM6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkk2NDoKKyAgICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignZGVsZXRlQWxsUm93VHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdyb3cnLCBUVHlwZS5TVFJJTkcsIDIpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYudGltZXN0YW1wICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RpbWVzdGFtcCcsIFRUeXBlLkk2NCwgMykKKyAgICAgIG9wcm90LndyaXRlSTY0KHNlbGYudGltZXN0YW1wKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgZGVsZXRlQWxsUm93VHNfcmVzdWx0OgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLmlvID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnaW8nIGluIGQ6CisgICAgICAgIHNlbGYuaW8gPSBkWydpbyddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlvID0gSU9FcnJvcigpCisgICAgICAgICAgc2VsZi5pby5yZWFkKGlwcm90KQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdkZWxldGVBbGxSb3dUc19yZXN1bHQnKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3Mgc2Nhbm5lck9wZW5fYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3N0YXJ0Um93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLkxJU1QsICdjb2x1bW5zJywgKFRUeXBlLlNUUklORyxOb25lKSwgTm9uZSwgKSwgIyAzCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnN0YXJ0Um93ID0gTm9uZQorICAgIHNlbGYuY29sdW1ucyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3N0YXJ0Um93JyBpbiBkOgorICAgICAgICBzZWxmLnN0YXJ0Um93ID0gZFsnc3RhcnRSb3cnXQorICAgICAgaWYgJ2NvbHVtbnMnIGluIGQ6CisgICAgICAgIHNlbGYuY29sdW1ucyA9IGRbJ2NvbHVtbnMnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnN0YXJ0Um93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYuY29sdW1ucyA9IFtdCisgICAgICAgICAgKF9ldHlwZTEwOSwgX3NpemUxMDYpID0gaXByb3QucmVhZExpc3RCZWdpbigpCisgICAgICAgICAgZm9yIF9pMTEwIGluIHhyYW5nZShfc2l6ZTEwNik6CisgICAgICAgICAgICBfZWxlbTExMSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIHNlbGYuY29sdW1ucy5hcHBlbmQoX2VsZW0xMTEpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdzY2FubmVyT3Blbl9hcmdzJykKKyAgICBpZiBzZWxmLnRhYmxlTmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0YWJsZU5hbWUnLCBUVHlwZS5TVFJJTkcsIDEpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnRhYmxlTmFtZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuc3RhcnRSb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignc3RhcnRSb3cnLCBUVHlwZS5TVFJJTkcsIDIpCisgICAgICBvcHJvdC53cml0ZVN0cmluZyhzZWxmLnN0YXJ0Um93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5jb2x1bW5zICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbHVtbnMnLCBUVHlwZS5MSVNULCAzKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5jb2x1bW5zKSkKKyAgICAgIGZvciBpdGVyMTEyIGluIHNlbGYuY29sdW1uczoKKyAgICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoaXRlcjExMikKKyAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBzY2FubmVyT3Blbl9yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLkkzMiwgJ3N1Y2Nlc3MnLCBOb25lLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdWNjZXNzID0gTm9uZQorICAgIHNlbGYuaW8gPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdzdWNjZXNzJyBpbiBkOgorICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBkWydzdWNjZXNzJ10KKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTMyOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ3NjYW5uZXJPcGVuX3Jlc3VsdCcpCisgICAgaWYgc2VsZi5zdWNjZXNzICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N1Y2Nlc3MnLCBUVHlwZS5JMzIsIDApCisgICAgICBvcHJvdC53cml0ZUkzMihzZWxmLnN1Y2Nlc3MpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlvICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lvJywgVFR5cGUuU1RSVUNULCAxKQorICAgICAgc2VsZi5pby53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3N0YXJ0Um93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ3N0b3BSb3cnLCBOb25lLCBOb25lLCApLCAjIDMKKyAgICAoNCwgVFR5cGUuTElTVCwgJ2NvbHVtbnMnLCAoVFR5cGUuU1RSSU5HLE5vbmUpLCBOb25lLCApLCAjIDQKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYudGFibGVOYW1lID0gTm9uZQorICAgIHNlbGYuc3RhcnRSb3cgPSBOb25lCisgICAgc2VsZi5zdG9wUm93ID0gTm9uZQorICAgIHNlbGYuY29sdW1ucyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3N0YXJ0Um93JyBpbiBkOgorICAgICAgICBzZWxmLnN0YXJ0Um93ID0gZFsnc3RhcnRSb3cnXQorICAgICAgaWYgJ3N0b3BSb3cnIGluIGQ6CisgICAgICAgIHNlbGYuc3RvcFJvdyA9IGRbJ3N0b3BSb3cnXQorICAgICAgaWYgJ2NvbHVtbnMnIGluIGQ6CisgICAgICAgIHNlbGYuY29sdW1ucyA9IGRbJ2NvbHVtbnMnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnN0YXJ0Um93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5zdG9wUm93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA0OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYuY29sdW1ucyA9IFtdCisgICAgICAgICAgKF9ldHlwZTExNiwgX3NpemUxMTMpID0gaXByb3QucmVhZExpc3RCZWdpbigpCisgICAgICAgICAgZm9yIF9pMTE3IGluIHhyYW5nZShfc2l6ZTExMyk6CisgICAgICAgICAgICBfZWxlbTExOCA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIHNlbGYuY29sdW1ucy5hcHBlbmQoX2VsZW0xMTgpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdzY2FubmVyT3BlbldpdGhTdG9wX2FyZ3MnKQorICAgIGlmIHNlbGYudGFibGVOYW1lICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3RhYmxlTmFtZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudGFibGVOYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5zdGFydFJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdGFydFJvdycsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuc3RhcnRSb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnN0b3BSb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignc3RvcFJvdycsIFRUeXBlLlNUUklORywgMykKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuc3RvcFJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1ucyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdjb2x1bW5zJywgVFR5cGUuTElTVCwgNCkKKyAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKFRUeXBlLlNUUklORywgbGVuKHNlbGYuY29sdW1ucykpCisgICAgICBmb3IgaXRlcjExOSBpbiBzZWxmLmNvbHVtbnM6CisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKGl0ZXIxMTkpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3Mgc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLkkzMiwgJ3N1Y2Nlc3MnLCBOb25lLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdWNjZXNzID0gTm9uZQorICAgIHNlbGYuaW8gPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdzdWNjZXNzJyBpbiBkOgorICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBkWydzdWNjZXNzJ10KKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTMyOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ3NjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0JykKKyAgICBpZiBzZWxmLnN1Y2Nlc3MgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignc3VjY2VzcycsIFRUeXBlLkkzMiwgMCkKKyAgICAgIG9wcm90LndyaXRlSTMyKHNlbGYuc3VjY2VzcykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3Mgc2Nhbm5lck9wZW5Uc19hcmdzOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICd0YWJsZU5hbWUnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuU1RSSU5HLCAnc3RhcnRSb3cnLCBOb25lLCBOb25lLCApLCAjIDIKKyAgICAoMywgVFR5cGUuTElTVCwgJ2NvbHVtbnMnLCAoVFR5cGUuU1RSSU5HLE5vbmUpLCBOb25lLCApLCAjIDMKKyAgICAoNCwgVFR5cGUuSTY0LCAndGltZXN0YW1wJywgTm9uZSwgTm9uZSwgKSwgIyA0CisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnN0YXJ0Um93ID0gTm9uZQorICAgIHNlbGYuY29sdW1ucyA9IE5vbmUKKyAgICBzZWxmLnRpbWVzdGFtcCA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3RhYmxlTmFtZScgaW4gZDoKKyAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBkWyd0YWJsZU5hbWUnXQorICAgICAgaWYgJ3N0YXJ0Um93JyBpbiBkOgorICAgICAgICBzZWxmLnN0YXJ0Um93ID0gZFsnc3RhcnRSb3cnXQorICAgICAgaWYgJ2NvbHVtbnMnIGluIGQ6CisgICAgICAgIHNlbGYuY29sdW1ucyA9IGRbJ2NvbHVtbnMnXQorICAgICAgaWYgJ3RpbWVzdGFtcCcgaW4gZDoKKyAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBkWyd0aW1lc3RhbXAnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi50YWJsZU5hbWUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnN0YXJ0Um93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAzOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5MSVNUOgorICAgICAgICAgIHNlbGYuY29sdW1ucyA9IFtdCisgICAgICAgICAgKF9ldHlwZTEyMywgX3NpemUxMjApID0gaXByb3QucmVhZExpc3RCZWdpbigpCisgICAgICAgICAgZm9yIF9pMTI0IGluIHhyYW5nZShfc2l6ZTEyMCk6CisgICAgICAgICAgICBfZWxlbTEyNSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIHNlbGYuY29sdW1ucy5hcHBlbmQoX2VsZW0xMjUpCisgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKQorICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA0OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5JNjQ6CisgICAgICAgICAgc2VsZi50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ3NjYW5uZXJPcGVuVHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnN0YXJ0Um93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N0YXJ0Um93JywgVFR5cGUuU1RSSU5HLCAyKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5zdGFydFJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1ucyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdjb2x1bW5zJywgVFR5cGUuTElTVCwgMykKKyAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKFRUeXBlLlNUUklORywgbGVuKHNlbGYuY29sdW1ucykpCisgICAgICBmb3IgaXRlcjEyNiBpbiBzZWxmLmNvbHVtbnM6CisgICAgICAgIG9wcm90LndyaXRlU3RyaW5nKGl0ZXIxMjYpCisgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi50aW1lc3RhbXAgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGltZXN0YW1wJywgVFR5cGUuSTY0LCA0KQorICAgICAgb3Byb3Qud3JpdGVJNjQoc2VsZi50aW1lc3RhbXApCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBzY2FubmVyT3BlblRzX3Jlc3VsdDoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICAoMCwgVFR5cGUuSTMyLCAnc3VjY2VzcycsIE5vbmUsIE5vbmUsICksICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnN1Y2Nlc3MgPSBOb25lCisgICAgc2VsZi5pbyA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5JMzI6CisgICAgICAgICAgc2VsZi5zdWNjZXNzID0gaXByb3QucmVhZEkzMigpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5pbyA9IElPRXJyb3IoKQorICAgICAgICAgIHNlbGYuaW8ucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignc2Nhbm5lck9wZW5Uc19yZXN1bHQnKQorICAgIGlmIHNlbGYuc3VjY2VzcyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdWNjZXNzJywgVFR5cGUuSTMyLCAwKQorICAgICAgb3Byb3Qud3JpdGVJMzIoc2VsZi5zdWNjZXNzKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJnczoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAndGFibGVOYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ3N0YXJ0Um93JywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ3N0b3BSb3cnLCBOb25lLCBOb25lLCApLCAjIDMKKyAgICAoNCwgVFR5cGUuTElTVCwgJ2NvbHVtbnMnLCAoVFR5cGUuU1RSSU5HLE5vbmUpLCBOb25lLCApLCAjIDQKKyAgICAoNSwgVFR5cGUuSTY0LCAndGltZXN0YW1wJywgTm9uZSwgTm9uZSwgKSwgIyA1CisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnRhYmxlTmFtZSA9IE5vbmUKKyAgICBzZWxmLnN0YXJ0Um93ID0gTm9uZQorICAgIHNlbGYuc3RvcFJvdyA9IE5vbmUKKyAgICBzZWxmLmNvbHVtbnMgPSBOb25lCisgICAgc2VsZi50aW1lc3RhbXAgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICd0YWJsZU5hbWUnIGluIGQ6CisgICAgICAgIHNlbGYudGFibGVOYW1lID0gZFsndGFibGVOYW1lJ10KKyAgICAgIGlmICdzdGFydFJvdycgaW4gZDoKKyAgICAgICAgc2VsZi5zdGFydFJvdyA9IGRbJ3N0YXJ0Um93J10KKyAgICAgIGlmICdzdG9wUm93JyBpbiBkOgorICAgICAgICBzZWxmLnN0b3BSb3cgPSBkWydzdG9wUm93J10KKyAgICAgIGlmICdjb2x1bW5zJyBpbiBkOgorICAgICAgICBzZWxmLmNvbHVtbnMgPSBkWydjb2x1bW5zJ10KKyAgICAgIGlmICd0aW1lc3RhbXAnIGluIGQ6CisgICAgICAgIHNlbGYudGltZXN0YW1wID0gZFsndGltZXN0YW1wJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYudGFibGVOYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5zdGFydFJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuc3RvcFJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gNDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTElTVDoKKyAgICAgICAgICBzZWxmLmNvbHVtbnMgPSBbXQorICAgICAgICAgIChfZXR5cGUxMzAsIF9zaXplMTI3KSA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKQorICAgICAgICAgIGZvciBfaTEzMSBpbiB4cmFuZ2UoX3NpemUxMjcpOgorICAgICAgICAgICAgX2VsZW0xMzIgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgICBzZWxmLmNvbHVtbnMuYXBwZW5kKF9lbGVtMTMyKQorICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gNToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTY0OgorICAgICAgICAgIHNlbGYudGltZXN0YW1wID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncycpCisgICAgaWYgc2VsZi50YWJsZU5hbWUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGFibGVOYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi50YWJsZU5hbWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnN0YXJ0Um93ICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ3N0YXJ0Um93JywgVFR5cGUuU1RSSU5HLCAyKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5zdGFydFJvdykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuc3RvcFJvdyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdG9wUm93JywgVFR5cGUuU1RSSU5HLCAzKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5zdG9wUm93KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5jb2x1bW5zICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbHVtbnMnLCBUVHlwZS5MSVNULCA0KQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSSU5HLCBsZW4oc2VsZi5jb2x1bW5zKSkKKyAgICAgIGZvciBpdGVyMTMzIGluIHNlbGYuY29sdW1uczoKKyAgICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoaXRlcjEzMykKKyAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnRpbWVzdGFtcCAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd0aW1lc3RhbXAnLCBUVHlwZS5JNjQsIDUpCisgICAgICBvcHJvdC53cml0ZUk2NChzZWxmLnRpbWVzdGFtcCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLkkzMiwgJ3N1Y2Nlc3MnLCBOb25lLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdWNjZXNzID0gTm9uZQorICAgIHNlbGYuaW8gPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdzdWNjZXNzJyBpbiBkOgorICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBkWydzdWNjZXNzJ10KKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMDoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTMyOgorICAgICAgICAgIHNlbGYuc3VjY2VzcyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ3NjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQnKQorICAgIGlmIHNlbGYuc3VjY2VzcyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdWNjZXNzJywgVFR5cGUuSTMyLCAwKQorICAgICAgb3Byb3Qud3JpdGVJMzIoc2VsZi5zdWNjZXNzKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBzY2FubmVyR2V0X2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLkkzMiwgJ2lkJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLmlkID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnaWQnIGluIGQ6CisgICAgICAgIHNlbGYuaWQgPSBkWydpZCddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLmlkID0gaXByb3QucmVhZEkzMigpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdzY2FubmVyR2V0X2FyZ3MnKQorICAgIGlmIHNlbGYuaWQgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaWQnLCBUVHlwZS5JMzIsIDEpCisgICAgICBvcHJvdC53cml0ZUkzMihzZWxmLmlkKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3Mgc2Nhbm5lckdldF9yZXN1bHQ6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgKDAsIFRUeXBlLlNUUlVDVCwgJ3N1Y2Nlc3MnLCAoU2NhbkVudHJ5LCBTY2FuRW50cnkudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSVUNULCAnaW8nLCAoSU9FcnJvciwgSU9FcnJvci50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5TVFJVQ1QsICdpYScsIChJbGxlZ2FsQXJndW1lbnQsIElsbGVnYWxBcmd1bWVudC50aHJpZnRfc3BlYyksIE5vbmUsICksICMgMgorICAgICgzLCBUVHlwZS5TVFJVQ1QsICduZicsIChOb3RGb3VuZCwgTm90Rm91bmQudGhyaWZ0X3NwZWMpLCBOb25lLCApLCAjIDMKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYuc3VjY2VzcyA9IE5vbmUKKyAgICBzZWxmLmlvID0gTm9uZQorICAgIHNlbGYuaWEgPSBOb25lCisgICAgc2VsZi5uZiA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N1Y2Nlc3MnIGluIGQ6CisgICAgICAgIHNlbGYuc3VjY2VzcyA9IGRbJ3N1Y2Nlc3MnXQorICAgICAgaWYgJ2lvJyBpbiBkOgorICAgICAgICBzZWxmLmlvID0gZFsnaW8nXQorICAgICAgaWYgJ2lhJyBpbiBkOgorICAgICAgICBzZWxmLmlhID0gZFsnaWEnXQorICAgICAgaWYgJ25mJyBpbiBkOgorICAgICAgICBzZWxmLm5mID0gZFsnbmYnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAwOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJVQ1Q6CisgICAgICAgICAgc2VsZi5zdWNjZXNzID0gU2NhbkVudHJ5KCkKKyAgICAgICAgICBzZWxmLnN1Y2Nlc3MucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlhID0gSWxsZWdhbEFyZ3VtZW50KCkKKyAgICAgICAgICBzZWxmLmlhLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDM6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLm5mID0gTm90Rm91bmQoKQorICAgICAgICAgIHNlbGYubmYucmVhZChpcHJvdCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignc2Nhbm5lckdldF9yZXN1bHQnKQorICAgIGlmIHNlbGYuc3VjY2VzcyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdWNjZXNzJywgVFR5cGUuU1RSVUNULCAwKQorICAgICAgc2VsZi5zdWNjZXNzLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pbyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpbycsIFRUeXBlLlNUUlVDVCwgMSkKKyAgICAgIHNlbGYuaW8ud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmlhICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2lhJywgVFR5cGUuU1RSVUNULCAyKQorICAgICAgc2VsZi5pYS53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYubmYgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignbmYnLCBUVHlwZS5TVFJVQ1QsIDMpCisgICAgICBzZWxmLm5mLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3Mgc2Nhbm5lckNsb3NlX2FyZ3M6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLkkzMiwgJ2lkJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLmlkID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnaWQnIGluIGQ6CisgICAgICAgIHNlbGYuaWQgPSBkWydpZCddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLmlkID0gaXByb3QucmVhZEkzMigpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdzY2FubmVyQ2xvc2VfYXJncycpCisgICAgaWYgc2VsZi5pZCAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpZCcsIFRUeXBlLkkzMiwgMSkKKyAgICAgIG9wcm90LndyaXRlSTMyKHNlbGYuaWQpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBzY2FubmVyQ2xvc2VfcmVzdWx0OgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJVQ1QsICdpbycsIChJT0Vycm9yLCBJT0Vycm9yLnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUlVDVCwgJ2lhJywgKElsbGVnYWxBcmd1bWVudCwgSWxsZWdhbEFyZ3VtZW50LnRocmlmdF9zcGVjKSwgTm9uZSwgKSwgIyAyCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLmlvID0gTm9uZQorICAgIHNlbGYuaWEgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdpbycgaW4gZDoKKyAgICAgICAgc2VsZi5pbyA9IGRbJ2lvJ10KKyAgICAgIGlmICdpYScgaW4gZDoKKyAgICAgICAgc2VsZi5pYSA9IGRbJ2lhJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSVUNUOgorICAgICAgICAgIHNlbGYuaW8gPSBJT0Vycm9yKCkKKyAgICAgICAgICBzZWxmLmlvLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDI6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUlVDVDoKKyAgICAgICAgICBzZWxmLmlhID0gSWxsZWdhbEFyZ3VtZW50KCkKKyAgICAgICAgICBzZWxmLmlhLnJlYWQoaXByb3QpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ3NjYW5uZXJDbG9zZV9yZXN1bHQnKQorICAgIGlmIHNlbGYuaW8gIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW8nLCBUVHlwZS5TVFJVQ1QsIDEpCisgICAgICBzZWxmLmlvLndyaXRlKG9wcm90KQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5pYSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpYScsIFRUeXBlLlNUUlVDVCwgMikKKyAgICAgIHNlbGYuaWEud3JpdGUob3Byb3QpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCisKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvSGJhc2UvX19pbml0X18ucHkgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL19faW5pdF9fLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMxZGMxNWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL19faW5pdF9fLnB5CkBAIC0wLDAgKzEgQEAKK19fYWxsX18gPSBbJ3R0eXBlcycsICdjb25zdGFudHMnLCAnSGJhc2UnXQpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IYmFzZS9jb25zdGFudHMucHkgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL2NvbnN0YW50cy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjE3ZWMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9IYmFzZS9jb25zdGFudHMucHkKQEAgLTAsMCArMSw5IEBACisjCisjIEF1dG9nZW5lcmF0ZWQgYnkgVGhyaWZ0CisjCisjIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyMKKworZnJvbSB0aHJpZnQuVGhyaWZ0IGltcG9ydCAqCitmcm9tIHR0eXBlcyBpbXBvcnQgKgorCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL3R0eXBlcy5weSBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvSGJhc2UvdHR5cGVzLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2ZGY4MDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL0hiYXNlL3R0eXBlcy5weQpAQCAtMCwwICsxLDcwOCBAQAorIworIyBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorIworIyBETyBOT1QgRURJVCBVTkxFU1MgWU9VIEFSRSBTVVJFIFRIQVQgWU9VIEtOT1cgV0hBVCBZT1UgQVJFIERPSU5HCisjCisKK2Zyb20gdGhyaWZ0LlRocmlmdCBpbXBvcnQgKgorCitmcm9tIHRocmlmdC50cmFuc3BvcnQgaW1wb3J0IFRUcmFuc3BvcnQKK2Zyb20gdGhyaWZ0LnByb3RvY29sIGltcG9ydCBUQmluYXJ5UHJvdG9jb2wKK3RyeToKKyAgZnJvbSB0aHJpZnQucHJvdG9jb2wgaW1wb3J0IGZhc3RiaW5hcnkKK2V4Y2VwdDoKKyAgZmFzdGJpbmFyeSA9IE5vbmUKKworCitjbGFzcyBDb2x1bW5EZXNjcmlwdG9yOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICduYW1lJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLkkzMiwgJ21heFZlcnNpb25zJywgTm9uZSwgTm9uZSwgKSwgIyAyCisgICAgKDMsIFRUeXBlLlNUUklORywgJ2NvbXByZXNzaW9uJywgTm9uZSwgTm9uZSwgKSwgIyAzCisgICAgKDQsIFRUeXBlLkJPT0wsICdpbk1lbW9yeScsIE5vbmUsIE5vbmUsICksICMgNAorICAgICg1LCBUVHlwZS5JMzIsICdtYXhWYWx1ZUxlbmd0aCcsIE5vbmUsIE5vbmUsICksICMgNQorICAgICg2LCBUVHlwZS5TVFJJTkcsICdibG9vbUZpbHRlclR5cGUnLCBOb25lLCBOb25lLCApLCAjIDYKKyAgICAoNywgVFR5cGUuSTMyLCAnYmxvb21GaWx0ZXJWZWN0b3JTaXplJywgTm9uZSwgTm9uZSwgKSwgIyA3CisgICAgKDgsIFRUeXBlLkkzMiwgJ2Jsb29tRmlsdGVyTmJIYXNoZXMnLCBOb25lLCBOb25lLCApLCAjIDgKKyAgICAoOSwgVFR5cGUuQk9PTCwgJ2Jsb2NrQ2FjaGVFbmFibGVkJywgTm9uZSwgTm9uZSwgKSwgIyA5CisgICAgKDEwLCBUVHlwZS5JMzIsICd0aW1lVG9MaXZlJywgTm9uZSwgTm9uZSwgKSwgIyAxMAorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5uYW1lID0gTm9uZQorICAgIHNlbGYubWF4VmVyc2lvbnMgPSAzCisgICAgc2VsZi5jb21wcmVzc2lvbiA9ICdOT05FJworICAgIHNlbGYuaW5NZW1vcnkgPSBGYWxzZQorICAgIHNlbGYubWF4VmFsdWVMZW5ndGggPSAyMTQ3NDgzNjQ3CisgICAgc2VsZi5ibG9vbUZpbHRlclR5cGUgPSAnTk9ORScKKyAgICBzZWxmLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IDAKKyAgICBzZWxmLmJsb29tRmlsdGVyTmJIYXNoZXMgPSAwCisgICAgc2VsZi5ibG9ja0NhY2hlRW5hYmxlZCA9IEZhbHNlCisgICAgc2VsZi50aW1lVG9MaXZlID0gLTEKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ25hbWUnIGluIGQ6CisgICAgICAgIHNlbGYubmFtZSA9IGRbJ25hbWUnXQorICAgICAgaWYgJ21heFZlcnNpb25zJyBpbiBkOgorICAgICAgICBzZWxmLm1heFZlcnNpb25zID0gZFsnbWF4VmVyc2lvbnMnXQorICAgICAgaWYgJ2NvbXByZXNzaW9uJyBpbiBkOgorICAgICAgICBzZWxmLmNvbXByZXNzaW9uID0gZFsnY29tcHJlc3Npb24nXQorICAgICAgaWYgJ2luTWVtb3J5JyBpbiBkOgorICAgICAgICBzZWxmLmluTWVtb3J5ID0gZFsnaW5NZW1vcnknXQorICAgICAgaWYgJ21heFZhbHVlTGVuZ3RoJyBpbiBkOgorICAgICAgICBzZWxmLm1heFZhbHVlTGVuZ3RoID0gZFsnbWF4VmFsdWVMZW5ndGgnXQorICAgICAgaWYgJ2Jsb29tRmlsdGVyVHlwZScgaW4gZDoKKyAgICAgICAgc2VsZi5ibG9vbUZpbHRlclR5cGUgPSBkWydibG9vbUZpbHRlclR5cGUnXQorICAgICAgaWYgJ2Jsb29tRmlsdGVyVmVjdG9yU2l6ZScgaW4gZDoKKyAgICAgICAgc2VsZi5ibG9vbUZpbHRlclZlY3RvclNpemUgPSBkWydibG9vbUZpbHRlclZlY3RvclNpemUnXQorICAgICAgaWYgJ2Jsb29tRmlsdGVyTmJIYXNoZXMnIGluIGQ6CisgICAgICAgIHNlbGYuYmxvb21GaWx0ZXJOYkhhc2hlcyA9IGRbJ2Jsb29tRmlsdGVyTmJIYXNoZXMnXQorICAgICAgaWYgJ2Jsb2NrQ2FjaGVFbmFibGVkJyBpbiBkOgorICAgICAgICBzZWxmLmJsb2NrQ2FjaGVFbmFibGVkID0gZFsnYmxvY2tDYWNoZUVuYWJsZWQnXQorICAgICAgaWYgJ3RpbWVUb0xpdmUnIGluIGQ6CisgICAgICAgIHNlbGYudGltZVRvTGl2ZSA9IGRbJ3RpbWVUb0xpdmUnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5uYW1lID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5JMzI6CisgICAgICAgICAgc2VsZi5tYXhWZXJzaW9ucyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMzoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYuY29tcHJlc3Npb24gPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDQ6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkJPT0w6CisgICAgICAgICAgc2VsZi5pbk1lbW9yeSA9IGlwcm90LnJlYWRCb29sKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDU6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLm1heFZhbHVlTGVuZ3RoID0gaXByb3QucmVhZEkzMigpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSA2OgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5ibG9vbUZpbHRlclR5cGUgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDc6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gODoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuSTMyOgorICAgICAgICAgIHNlbGYuYmxvb21GaWx0ZXJOYkhhc2hlcyA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gOToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuQk9PTDoKKyAgICAgICAgICBzZWxmLmJsb2NrQ2FjaGVFbmFibGVkID0gaXByb3QucmVhZEJvb2woKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMTA6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLkkzMjoKKyAgICAgICAgICBzZWxmLnRpbWVUb0xpdmUgPSBpcHJvdC5yZWFkSTMyKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ0NvbHVtbkRlc2NyaXB0b3InKQorICAgIGlmIHNlbGYubmFtZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCduYW1lJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5uYW1lKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5tYXhWZXJzaW9ucyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtYXhWZXJzaW9ucycsIFRUeXBlLkkzMiwgMikKKyAgICAgIG9wcm90LndyaXRlSTMyKHNlbGYubWF4VmVyc2lvbnMpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmNvbXByZXNzaW9uICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbXByZXNzaW9uJywgVFR5cGUuU1RSSU5HLCAzKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5jb21wcmVzc2lvbikKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuaW5NZW1vcnkgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignaW5NZW1vcnknLCBUVHlwZS5CT09MLCA0KQorICAgICAgb3Byb3Qud3JpdGVCb29sKHNlbGYuaW5NZW1vcnkpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLm1heFZhbHVlTGVuZ3RoICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ21heFZhbHVlTGVuZ3RoJywgVFR5cGUuSTMyLCA1KQorICAgICAgb3Byb3Qud3JpdGVJMzIoc2VsZi5tYXhWYWx1ZUxlbmd0aCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuYmxvb21GaWx0ZXJUeXBlICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2Jsb29tRmlsdGVyVHlwZScsIFRUeXBlLlNUUklORywgNikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuYmxvb21GaWx0ZXJUeXBlKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi5ibG9vbUZpbHRlclZlY3RvclNpemUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignYmxvb21GaWx0ZXJWZWN0b3JTaXplJywgVFR5cGUuSTMyLCA3KQorICAgICAgb3Byb3Qud3JpdGVJMzIoc2VsZi5ibG9vbUZpbHRlclZlY3RvclNpemUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmJsb29tRmlsdGVyTmJIYXNoZXMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignYmxvb21GaWx0ZXJOYkhhc2hlcycsIFRUeXBlLkkzMiwgOCkKKyAgICAgIG9wcm90LndyaXRlSTMyKHNlbGYuYmxvb21GaWx0ZXJOYkhhc2hlcykKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuYmxvY2tDYWNoZUVuYWJsZWQgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignYmxvY2tDYWNoZUVuYWJsZWQnLCBUVHlwZS5CT09MLCA5KQorICAgICAgb3Byb3Qud3JpdGVCb29sKHNlbGYuYmxvY2tDYWNoZUVuYWJsZWQpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLnRpbWVUb0xpdmUgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigndGltZVRvTGl2ZScsIFRUeXBlLkkzMiwgMTApCisgICAgICBvcHJvdC53cml0ZUkzMihzZWxmLnRpbWVUb0xpdmUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBSZWdpb25EZXNjcmlwdG9yOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICdzdGFydEtleScsIE5vbmUsIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5zdGFydEtleSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ3N0YXJ0S2V5JyBpbiBkOgorICAgICAgICBzZWxmLnN0YXJ0S2V5ID0gZFsnc3RhcnRLZXknXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5zdGFydEtleSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignUmVnaW9uRGVzY3JpcHRvcicpCisgICAgaWYgc2VsZi5zdGFydEtleSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdzdGFydEtleScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuc3RhcnRLZXkpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBNdXRhdGlvbjoKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuQk9PTCwgJ2lzRGVsZXRlJywgTm9uZSwgTm9uZSwgKSwgIyAxCisgICAgKDIsIFRUeXBlLlNUUklORywgJ2NvbHVtbicsIE5vbmUsIE5vbmUsICksICMgMgorICAgICgzLCBUVHlwZS5TVFJJTkcsICd2YWx1ZScsIE5vbmUsIE5vbmUsICksICMgMworICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5pc0RlbGV0ZSA9IEZhbHNlCisgICAgc2VsZi5jb2x1bW4gPSBOb25lCisgICAgc2VsZi52YWx1ZSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ2lzRGVsZXRlJyBpbiBkOgorICAgICAgICBzZWxmLmlzRGVsZXRlID0gZFsnaXNEZWxldGUnXQorICAgICAgaWYgJ2NvbHVtbicgaW4gZDoKKyAgICAgICAgc2VsZi5jb2x1bW4gPSBkWydjb2x1bW4nXQorICAgICAgaWYgJ3ZhbHVlJyBpbiBkOgorICAgICAgICBzZWxmLnZhbHVlID0gZFsndmFsdWUnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5CT09MOgorICAgICAgICAgIHNlbGYuaXNEZWxldGUgPSBpcHJvdC5yZWFkQm9vbCgpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5jb2x1bW4gPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsaWYgZmlkID09IDM6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnZhbHVlID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdNdXRhdGlvbicpCisgICAgaWYgc2VsZi5pc0RlbGV0ZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdpc0RlbGV0ZScsIFRUeXBlLkJPT0wsIDEpCisgICAgICBvcHJvdC53cml0ZUJvb2woc2VsZi5pc0RlbGV0ZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIGlmIHNlbGYuY29sdW1uICE9IE5vbmU6CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oJ2NvbHVtbicsIFRUeXBlLlNUUklORywgMikKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYuY29sdW1uKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgaWYgc2VsZi52YWx1ZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCd2YWx1ZScsIFRUeXBlLlNUUklORywgMykKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYudmFsdWUpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBCYXRjaE11dGF0aW9uOgorCisgIHRocmlmdF9zcGVjID0gKAorICAgIE5vbmUsICMgMAorICAgICgxLCBUVHlwZS5TVFJJTkcsICdyb3cnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgICAoMiwgVFR5cGUuTElTVCwgJ211dGF0aW9ucycsIChUVHlwZS5TVFJVQ1QsKE11dGF0aW9uLCBNdXRhdGlvbi50aHJpZnRfc3BlYykpLCBOb25lLCApLCAjIDIKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYucm93ID0gTm9uZQorICAgIHNlbGYubXV0YXRpb25zID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAncm93JyBpbiBkOgorICAgICAgICBzZWxmLnJvdyA9IGRbJ3JvdyddCisgICAgICBpZiAnbXV0YXRpb25zJyBpbiBkOgorICAgICAgICBzZWxmLm11dGF0aW9ucyA9IGRbJ211dGF0aW9ucyddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLnJvdyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxpZiBmaWQgPT0gMjoKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuTElTVDoKKyAgICAgICAgICBzZWxmLm11dGF0aW9ucyA9IFtdCisgICAgICAgICAgKF9ldHlwZTMsIF9zaXplMCkgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCkKKyAgICAgICAgICBmb3IgX2k0IGluIHhyYW5nZShfc2l6ZTApOgorICAgICAgICAgICAgX2VsZW01ID0gTXV0YXRpb24oKQorICAgICAgICAgICAgX2VsZW01LnJlYWQoaXByb3QpCisgICAgICAgICAgICBzZWxmLm11dGF0aW9ucy5hcHBlbmQoX2VsZW01KQorICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgZWxzZToKKyAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpCisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpCisKKyAgZGVmIHdyaXRlKHNlbGYsIG9wcm90KToKKyAgICBpZiBvcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgb3Byb3QudHJhbnMud3JpdGUoZmFzdGJpbmFyeS5lbmNvZGVfYmluYXJ5KHNlbGYsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpKQorICAgICAgcmV0dXJuCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbignQmF0Y2hNdXRhdGlvbicpCisgICAgaWYgc2VsZi5yb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93JywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5yb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLm11dGF0aW9ucyAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtdXRhdGlvbnMnLCBUVHlwZS5MSVNULCAyKQorICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4oVFR5cGUuU1RSVUNULCBsZW4oc2VsZi5tdXRhdGlvbnMpKQorICAgICAgZm9yIGl0ZXI2IGluIHNlbGYubXV0YXRpb25zOgorICAgICAgICBpdGVyNi53cml0ZShvcHJvdCkKKyAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKQorCisgIGRlZiBfX3N0cl9fKHNlbGYpOiAKKyAgICByZXR1cm4gc3RyKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fcmVwcl9fKHNlbGYpOiAKKyAgICByZXR1cm4gcmVwcihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBpc2luc3RhbmNlKG90aGVyLCBzZWxmLl9fY2xhc3NfXykgYW5kIHNlbGYuX19kaWN0X18gPT0gb3RoZXIuX19kaWN0X18KKworICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gbm90IChzZWxmID09IG90aGVyKQorCitjbGFzcyBTY2FuRW50cnk6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ3JvdycsIE5vbmUsIE5vbmUsICksICMgMQorICAgICgyLCBUVHlwZS5NQVAsICdjb2x1bW5zJywgKFRUeXBlLlNUUklORyxOb25lLFRUeXBlLlNUUklORyxOb25lKSwgTm9uZSwgKSwgIyAyCisgICkKKworICBkZWYgX19pbml0X18oc2VsZiwgZD1Ob25lKToKKyAgICBzZWxmLnJvdyA9IE5vbmUKKyAgICBzZWxmLmNvbHVtbnMgPSBOb25lCisgICAgaWYgaXNpbnN0YW5jZShkLCBkaWN0KToKKyAgICAgIGlmICdyb3cnIGluIGQ6CisgICAgICAgIHNlbGYucm93ID0gZFsncm93J10KKyAgICAgIGlmICdjb2x1bW5zJyBpbiBkOgorICAgICAgICBzZWxmLmNvbHVtbnMgPSBkWydjb2x1bW5zJ10KKworICBkZWYgcmVhZChzZWxmLCBpcHJvdCk6CisgICAgaWYgaXByb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgaXNpbnN0YW5jZShpcHJvdC50cmFucywgVFRyYW5zcG9ydC5DUmVhZGFibGVUcmFuc3BvcnQpIGFuZCBzZWxmLnRocmlmdF9zcGVjIGlzIG5vdCBOb25lIGFuZCBmYXN0YmluYXJ5IGlzIG5vdCBOb25lOgorICAgICAgZmFzdGJpbmFyeS5kZWNvZGVfYmluYXJ5KHNlbGYsIGlwcm90LnRyYW5zLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKQorICAgICAgcmV0dXJuCisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCkKKyAgICB3aGlsZSBUcnVlOgorICAgICAgKGZuYW1lLCBmdHlwZSwgZmlkKSA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUT1A6CisgICAgICAgIGJyZWFrCisgICAgICBpZiBmaWQgPT0gMToKKyAgICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RSSU5HOgorICAgICAgICAgIHNlbGYucm93ID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbGlmIGZpZCA9PSAyOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5NQVA6CisgICAgICAgICAgc2VsZi5jb2x1bW5zID0ge30KKyAgICAgICAgICAoX2t0eXBlOCwgX3Z0eXBlOSwgX3NpemU3ICkgPSBpcHJvdC5yZWFkTWFwQmVnaW4oKSAKKyAgICAgICAgICBmb3IgX2kxMSBpbiB4cmFuZ2UoX3NpemU3KToKKyAgICAgICAgICAgIF9rZXkxMiA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIF92YWwxMyA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICAgIHNlbGYuY29sdW1uc1tfa2V5MTJdID0gX3ZhbDEzCisgICAgICAgICAgaXByb3QucmVhZE1hcEVuZCgpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ1NjYW5FbnRyeScpCisgICAgaWYgc2VsZi5yb3cgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbigncm93JywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5yb3cpCisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCkKKyAgICBpZiBzZWxmLmNvbHVtbnMgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignY29sdW1ucycsIFRUeXBlLk1BUCwgMikKKyAgICAgIG9wcm90LndyaXRlTWFwQmVnaW4oVFR5cGUuU1RSSU5HLCBUVHlwZS5TVFJJTkcsIGxlbihzZWxmLmNvbHVtbnMpKQorICAgICAgZm9yIGtpdGVyMTQsdml0ZXIxNSBpbiBzZWxmLmNvbHVtbnMuaXRlbXMoKToKKyAgICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoa2l0ZXIxNCkKKyAgICAgICAgb3Byb3Qud3JpdGVTdHJpbmcodml0ZXIxNSkKKyAgICAgIG9wcm90LndyaXRlTWFwRW5kKCkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIElPRXJyb3IoRXhjZXB0aW9uKToKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAnbWVzc2FnZScsIE5vbmUsIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5tZXNzYWdlID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnbWVzc2FnZScgaW4gZDoKKyAgICAgICAgc2VsZi5tZXNzYWdlID0gZFsnbWVzc2FnZSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLm1lc3NhZ2UgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ0lPRXJyb3InKQorICAgIGlmIHNlbGYubWVzc2FnZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtZXNzYWdlJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5tZXNzYWdlKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgSWxsZWdhbEFyZ3VtZW50KEV4Y2VwdGlvbik6CisKKyAgdGhyaWZ0X3NwZWMgPSAoCisgICAgTm9uZSwgIyAwCisgICAgKDEsIFRUeXBlLlNUUklORywgJ21lc3NhZ2UnLCBOb25lLCBOb25lLCApLCAjIDEKKyAgKQorCisgIGRlZiBfX2luaXRfXyhzZWxmLCBkPU5vbmUpOgorICAgIHNlbGYubWVzc2FnZSA9IE5vbmUKKyAgICBpZiBpc2luc3RhbmNlKGQsIGRpY3QpOgorICAgICAgaWYgJ21lc3NhZ2UnIGluIGQ6CisgICAgICAgIHNlbGYubWVzc2FnZSA9IGRbJ21lc3NhZ2UnXQorCisgIGRlZiByZWFkKHNlbGYsIGlwcm90KToKKyAgICBpZiBpcHJvdC5fX2NsYXNzX18gPT0gVEJpbmFyeVByb3RvY29sLlRCaW5hcnlQcm90b2NvbEFjY2VsZXJhdGVkIGFuZCBpc2luc3RhbmNlKGlwcm90LnRyYW5zLCBUVHJhbnNwb3J0LkNSZWFkYWJsZVRyYW5zcG9ydCkgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBmYXN0YmluYXJ5LmRlY29kZV9iaW5hcnkoc2VsZiwgaXByb3QudHJhbnMsIChzZWxmLl9fY2xhc3NfXywgc2VsZi50aHJpZnRfc3BlYykpCisgICAgICByZXR1cm4KKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKQorICAgIHdoaWxlIFRydWU6CisgICAgICAoZm5hbWUsIGZ0eXBlLCBmaWQpID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKQorICAgICAgaWYgZnR5cGUgPT0gVFR5cGUuU1RPUDoKKyAgICAgICAgYnJlYWsKKyAgICAgIGlmIGZpZCA9PSAxOgorICAgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVFJJTkc6CisgICAgICAgICAgc2VsZi5tZXNzYWdlID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICBlbHNlOgorICAgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBlbHNlOgorICAgICAgICBpcHJvdC5za2lwKGZ0eXBlKQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCkKKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCkKKworICBkZWYgd3JpdGUoc2VsZiwgb3Byb3QpOgorICAgIGlmIG9wcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIHNlbGYudGhyaWZ0X3NwZWMgaXMgbm90IE5vbmUgYW5kIGZhc3RiaW5hcnkgaXMgbm90IE5vbmU6CisgICAgICBvcHJvdC50cmFucy53cml0ZShmYXN0YmluYXJ5LmVuY29kZV9iaW5hcnkoc2VsZiwgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkpCisgICAgICByZXR1cm4KKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKCdJbGxlZ2FsQXJndW1lbnQnKQorICAgIGlmIHNlbGYubWVzc2FnZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtZXNzYWdlJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5tZXNzYWdlKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKworY2xhc3MgTm90Rm91bmQoRXhjZXB0aW9uKToKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAnbWVzc2FnZScsIE5vbmUsIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5tZXNzYWdlID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnbWVzc2FnZScgaW4gZDoKKyAgICAgICAgc2VsZi5tZXNzYWdlID0gZFsnbWVzc2FnZSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLm1lc3NhZ2UgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ05vdEZvdW5kJykKKyAgICBpZiBzZWxmLm1lc3NhZ2UgIT0gTm9uZToKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbignbWVzc2FnZScsIFRUeXBlLlNUUklORywgMSkKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHNlbGYubWVzc2FnZSkKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCkKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpCisKKyAgZGVmIF9fc3RyX18oc2VsZik6IAorICAgIHJldHVybiBzdHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19yZXByX18oc2VsZik6IAorICAgIHJldHVybiByZXByKHNlbGYuX19kaWN0X18pCisKKyAgZGVmIF9fZXFfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIGlzaW5zdGFuY2Uob3RoZXIsIHNlbGYuX19jbGFzc19fKSBhbmQgc2VsZi5fX2RpY3RfXyA9PSBvdGhlci5fX2RpY3RfXworCisgIGRlZiBfX25lX18oc2VsZiwgb3RoZXIpOgorICAgIHJldHVybiBub3QgKHNlbGYgPT0gb3RoZXIpCisKK2NsYXNzIEFscmVhZHlFeGlzdHMoRXhjZXB0aW9uKToKKworICB0aHJpZnRfc3BlYyA9ICgKKyAgICBOb25lLCAjIDAKKyAgICAoMSwgVFR5cGUuU1RSSU5HLCAnbWVzc2FnZScsIE5vbmUsIE5vbmUsICksICMgMQorICApCisKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGQ9Tm9uZSk6CisgICAgc2VsZi5tZXNzYWdlID0gTm9uZQorICAgIGlmIGlzaW5zdGFuY2UoZCwgZGljdCk6CisgICAgICBpZiAnbWVzc2FnZScgaW4gZDoKKyAgICAgICAgc2VsZi5tZXNzYWdlID0gZFsnbWVzc2FnZSddCisKKyAgZGVmIHJlYWQoc2VsZiwgaXByb3QpOgorICAgIGlmIGlwcm90Ll9fY2xhc3NfXyA9PSBUQmluYXJ5UHJvdG9jb2wuVEJpbmFyeVByb3RvY29sQWNjZWxlcmF0ZWQgYW5kIGlzaW5zdGFuY2UoaXByb3QudHJhbnMsIFRUcmFuc3BvcnQuQ1JlYWRhYmxlVHJhbnNwb3J0KSBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIGZhc3RiaW5hcnkuZGVjb2RlX2JpbmFyeShzZWxmLCBpcHJvdC50cmFucywgKHNlbGYuX19jbGFzc19fLCBzZWxmLnRocmlmdF9zcGVjKSkKKyAgICAgIHJldHVybgorICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgIChmbmFtZSwgZnR5cGUsIGZpZCkgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpCisgICAgICBpZiBmdHlwZSA9PSBUVHlwZS5TVE9QOgorICAgICAgICBicmVhaworICAgICAgaWYgZmlkID09IDE6CisgICAgICAgIGlmIGZ0eXBlID09IFRUeXBlLlNUUklORzoKKyAgICAgICAgICBzZWxmLm1lc3NhZ2UgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgIGVsc2U6CisgICAgICAgICAgaXByb3Quc2tpcChmdHlwZSkKKyAgICAgIGVsc2U6CisgICAgICAgIGlwcm90LnNraXAoZnR5cGUpCisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKQorCisgIGRlZiB3cml0ZShzZWxmLCBvcHJvdCk6CisgICAgaWYgb3Byb3QuX19jbGFzc19fID09IFRCaW5hcnlQcm90b2NvbC5UQmluYXJ5UHJvdG9jb2xBY2NlbGVyYXRlZCBhbmQgc2VsZi50aHJpZnRfc3BlYyBpcyBub3QgTm9uZSBhbmQgZmFzdGJpbmFyeSBpcyBub3QgTm9uZToKKyAgICAgIG9wcm90LnRyYW5zLndyaXRlKGZhc3RiaW5hcnkuZW5jb2RlX2JpbmFyeShzZWxmLCAoc2VsZi5fX2NsYXNzX18sIHNlbGYudGhyaWZ0X3NwZWMpKSkKKyAgICAgIHJldHVybgorICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oJ0FscmVhZHlFeGlzdHMnKQorICAgIGlmIHNlbGYubWVzc2FnZSAhPSBOb25lOgorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKCdtZXNzYWdlJywgVFR5cGUuU1RSSU5HLCAxKQorICAgICAgb3Byb3Qud3JpdGVTdHJpbmcoc2VsZi5tZXNzYWdlKQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpCisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKQorICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCkKKworICBkZWYgX19zdHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHN0cihzZWxmLl9fZGljdF9fKQorCisgIGRlZiBfX3JlcHJfXyhzZWxmKTogCisgICAgcmV0dXJuIHJlcHIoc2VsZi5fX2RpY3RfXykKKworICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1cm4gaXNpbnN0YW5jZShvdGhlciwgc2VsZi5fX2NsYXNzX18pIGFuZCBzZWxmLl9fZGljdF9fID09IG90aGVyLl9fZGljdF9fCisKKyAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CisgICAgcmV0dXJuIG5vdCAoc2VsZiA9PSBvdGhlcikKKwpkaWZmIC0tZ2l0IGEvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9SRUFETUUgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL1JFQURNRQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Y2ZhYjE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9SRUFETUUKQEAgLTAsMCArMSwxMDcgQEAKK2hicmVwIGlzIGEgdG9vbCBmb3IgcmVwbGljYXRpbmcgZGF0YSBmcm9tIHBvc3RncmVzcWwgdGFibGVzIHRvIGhiYXNlIHRhYmxlcy4KKworRGVwZW5kYW5jaWVzOgorIC0gcHl0aG9uIDIuNAorIC0gaGJhc2UgMC4yLjAKKyAtIHNreXRvb2xzIDIuMS43CisgLSBwb3N0Z3Jlc3FsCisgCitJdCBoYXMgdHdvIG1haW4gZnVuY3Rpb25zLgorIC0gYm9vdHN0cmFwLCB3aGljaCBib290c3RyYXBzIGFsbCB0aGUgZGF0YSBmcm9tIHNwZWNpZmllZCBjb2x1bW5zIG9mIGEgdGFibGUKKyAtIHBsYXksIHdoaWNoIHByb2Nlc3NlcyBpbmNvbWluZyBpbnNlcnQsIHVwZGF0ZSBhbmQgZGVsZXRlIGV2ZW50cyBhbmQgYXBwbGllcyB0aGVtIHRvIGhiYXNlLgorCitFeGFtcGxlIHVzYWdlOgoraW5zdGFsbCB0cmlnZ2VyczoKKyAgLi9oYnJlcC5weSBoYnJlcC5pbmkgaW5zdGFsbCBzY2hlbWExLnRhYmxlMSBzY2hlbWEyLnRhYmxlMgorbm93IHRoYXQgZnV0dXJlIHVwZGF0ZXMgYXJlIHF1ZXVpbmcsIGJvb3RzdHJhcCB0aGUgdGFibGVzLgorICAuL2hicmVwLnB5IGhicmVwLmluaSBib290c3RyYXAgc2NoZW1hMS50YWJsZTEgc2NoZW1hMi50YWJsZTIKK3N0YXJ0IHBncSB0aWNrZXIKKyAgcGdxYWRtLnB5IHBncS5pbmkgdGlja2VyCitwbGF5IG91ciBxdWV1ZSBjb25zdW1lcgorICAuL2hicmVwLnB5IGhicmVwLmluaSBwbGF5IHNjaGVtYTEudGFibGUxIHNjaGVtYTIudGFibGUyCisKKworTW9yZSBkZXRhaWxzIGZvbGxvdy4KKworCitBbGwgZnVuY3Rpb25zIHJlcXVpcmUgYW4gaW5pIGZpbGUgKHNheSBoYnJlcC5pbmkpIHdpdGggYSBIQmFzZVJlcGxpYyBzZWN0aW9uLCBhbmQgYSBzZWN0aW9uIGZvciBlYWNoIHBvc3RncmVzcWwgdGFibGUgeW91IHdpc2ggdG8gcmVwbGljYXRlIGNvbnRhaW5pbmcgdGhlIHRhYmxlIG1hcHBpbmcuIE5vdGUgdGhlIHRhYmxlIG1hcHBpbmcgc2VjdGlvbiBuYW1lcyBzaG91bGQgbWF0Y2ggdGhlIG5hbWUgb2YgdGhlIHBvc3RncmVzcWwgdGFibGUuCisKK2VnLiBpbmkgZmlsZToKKyMjIyMjIyMjIyMjIyMjIyMjIyMjCitbSEJhc2VSZXBsaWNdCitqb2JfbmFtZSA9IGhiYXNlX3JlcGxpY19qb2IKK2xvZ2ZpbGUgPSAlKGpvYl9uYW1lKXMubG9nCitwaWRmaWxlID0gJShqb2JfbmFtZSlzLnBpZAorcG9zdGdyZXNxbF9kYiA9IGRibmFtZT1zb3VyY2VfZGF0YWJhc2UgdXNlcj1kYnVzZXIKK3BncV9xdWV1ZV9uYW1lID0gaGJhc2VfcmVwbGljX3F1ZXVlCitoYmFzZV9ob3N0bmFtZSA9IGxvY2FsaG9zdAoraGJhc2VfcG9ydCA9IDkwOTAKKyMgSWYgb21pdHRlZCwgZGVmYXVsdCBpcyAxMDAwMAorbWF4X2JhdGNoX3NpemUgPSAxMDAwMAorIyBmaWxlIHRvIHVzZSB3aGVuIGNvcHlpbmcgYSB0YWJsZSwgaWYgb21pdHRlZCBhIHNlbGVjdCBjb2x1bW5zIHdpbGwgYmUgZG9uZSBpbnN0ZWFkLgorYm9vdHN0cmFwX3RtcGZpbGUgPSB0YWJsZWR1bXAuZGF0CisKKyMgRm9yIGVhY2ggdGFibGUgbWFwcGluZywgdGhlcmUgbXVzdCBiZSB0aGUgc2FtZSBudW1iZXIgcHNxbF9jb2x1bW5zIGFzIGhiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycworW3B1YmxpYy51c2Vyc10KK3BzcWxfc2NoZW1hID0gcHVibGljCitwc3FsX3RhYmxlX25hbWUgPSB1c2VycworcHNxbF9rZXlfY29sdW1uID0gdXNlcl9pZAorcHNxbF9jb2x1bW5zID0gZG9iCitoYmFzZV90YWJsZV9uYW1lID0gc3R1ZmYKK2hiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycyA9IHVzZXJzOmRvYgoraGJhc2Vfcm93X3ByZWZpeCA9IHVzZXJfaWQ6CisjIyMjIyMjIyMjIyMjIyMjIyMjIworCitCb290c3RyYXBwaW5nOgorVG8gYm9vdHN0cmFwIHRoZSBwdWJsaWMudXNlcnMgdGFibGUgZnJvbSBwb3N0Z3Jlc3FsIHRvIGhiYXNlLCAKKworICAuL2hicmVwLnB5IGhicmVwLmluaSBib290c3RyYXAgcHVibGljLnVzZXJzCisgIAoreW91IGNhbiBzcGVjaWZ5IG11bHRpcGxlIHRhYmxlcyBhcyBhcmd1bWVudHMuCisgCisgCitQbGF5OgorVGhpcyBtb2RlIHVzZXMgcGdxIGZyb20gdGhlIHNreXRvb2xzIHBhY2thZ2UgdG8gY3JlYXRlIGFuZCBtYW5hZ2UgZXZlbnQgcXVldWVzIG9uIHBvc3RncmVzcWwuCitZb3UgbmVlZCB0byBoYXZlIHBncSBpbnN0YWxsZWQgb24gdGhlIGRhdGFiYXNlIHlvdSBhcmUgcmVwbGljYXRpbmcuCisKK1dpdGggYSBwZ3EuaW5pIGZpbGUgbGlrZSB0aGlzOgorIyMjIyMjIyMjIyMjIyMjIyMjIyMKK1twZ3FhZG1dCitqb2JfbmFtZSA9IHNvdXJjZWRiX3RpY2tlcgorZGIgPSBkYm5hbWU9c291cmNlX2RhdGFiYXNlIHVzZXI9ZGJ1c2VyCisjIGhvdyBvZnRlbiB0byBydW4gbWFpbnRlbmFuY2UgW21pbnV0ZXNdCittYWludF9kZWxheV9taW4gPSAxCisjIGhvdyBvZnRlbiB0byBjaGVjayBmb3IgYWN0aXZpdHkgW3NlY3NdCitsb29wX2RlbGF5ID0gMC4yCitsb2dmaWxlID0gJShqb2JfbmFtZSlzLmxvZworcGlkZmlsZSA9ICUoam9iX25hbWUpcy5waWQKK3VzZV9za3lsb2cgPSAwCisjIyMjIyMjIyMjIyMjIyMjIyMjIworCitZb3UgaW5zdGFsbCBwZ3Egb24gdGhlIGRhdGFiYXNlIGJ5LCAKKworICBwZ3FhZG0ucHkgcGdxLmluaSBpbnN0YWxsCisKK05leHQgeW91IGluc3RhbGwgaGJyZXAuCisKKyAgaGJyZXAucHkgaGJyZXAuaW5pIGluc3RhbGwgcHVibGljLnVzZXJzCisgIAorVGhpcyBjcmVhdGVzIGEgcXVldWUgdXNpbmcgcGdxLCB3aGljaCBpbiB0aGlzIGNhc2Ugd2lsbCBiZSBjYWxsZWQgaGJhc2VfcmVwbGljX3F1ZXVlLiBJdCBhbHNvIHJlZ2lzdGVycyB0aGUgaGJyZXAgY29uc3VtZXIgKGNhbGxlZCBIQmFzZVJlcGxpYykgd2l0aCB0aGF0IHF1ZXVlLiBUaGVuIGZpbmFsbHkgaXQgY3JlYXRlcyB0cmlnZ2VycyBvbiBlYWNoIHRhYmxlIHNwZWNpZmllZCB0byBhZGQgYW4gZXZlbnQgZm9yIGVhY2ggaW5zZXJ0LCB1cGRhdGUgb3IgZGVsZXRlLgorCitTdGFydCB0aGUgcGdxIGV2ZW50IHRpY2tlciwKKworICBwZ3FhZG0ucHkgcGdxLmluaSB0aWNrZXIKKworRmluYWxseSwgcnVuIHRoZSBoYnJlcGxpYyBjb25zdW1lcgorICAuL2hicmVwLnB5IGhicmVwLmluaSBwbGF5IHB1YmxpYy51c2VycworICAKK05vdyBhbnkgaW5zZXJ0cywgdXBkYXRlcyBvciBkZWxldGVzIG9uIHRoZSBwb3N0Z3Jlc3FsIHVzZXJzIHRhYmxlIHdpbGwgYmUgcHJvY2Vzc2VkIGFuZCBzZW50IHRvIHRoZSAKK2hiYXNlIHRhYmxlLgorCisKK3VuaW5zdGFsbDoKK1lvdSBjYW4gcmVtb3ZlIHRoZSB0cmlnZ2VycyBmcm9tIGEgdGFibGUgYnkKKyAgLi9oYnJlcC5weSBoYnJlcC5pbmkgdW5pbnN0YWxsIHB1YmxpYy51c2VycworICAKKyAgCisKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvX19pbml0X18ucHkgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL19faW5pdF9fLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL19faW5pdF9fLnB5CmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL2Jvb3RzdHJhcC5weSBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvYm9vdHN0cmFwLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2NWE2NmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL2Jvb3RzdHJhcC5weQpAQCAtMCwwICsxLDE5MCBAQAoraW1wb3J0IHN5cywgb3MKKworaW1wb3J0IHBncSwgcGdxLnByb2R1Y2VyCitpbXBvcnQgc2t5dG9vbHMKKworZnJvbSBIQmFzZUNvbm5lY3Rpb24gaW1wb3J0ICoKK2ltcG9ydCB0YWJsZW1hcHBpbmcKKworY2xhc3MgSEJhc2VCb290c3RyYXAoc2t5dG9vbHMuREJTY3JpcHQpOgorICAiIiJCb290c3RyYXBwaW5nIHNjcmlwdCBmb3IgbG9hZGluZyBjb2x1bW5zIGZyb20gYSB0YWJsZSBpbiBwb3N0Z3Jlc3FsIHRvIGhiYXNlLiIiIgorICAKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHNlcnZpY2VfbmFtZSwgYXJncyk6CisgICAgIyBUaGlzIHdpbGwgcHJvY2VzcyBhbnkgb3B0aW9ucyBlZyAtayAtdiAtZAorICAgIHNreXRvb2xzLkRCU2NyaXB0Ll9faW5pdF9fKHNlbGYsIHNlcnZpY2VfbmFtZSwgYXJncykKKyAgICAKKyAgICBjb25maWdfZmlsZSA9IHNlbGYuYXJnc1swXQorICAgIGlmIGxlbihzZWxmLmFyZ3MpIDwgMjoKKyAgICAgIHByaW50ICJuZWVkIHRhYmxlIG5hbWVzIgorICAgICAgc3lzLmV4aXQoMSkKKyAgICBlbHNlOgorICAgICAgc2VsZi50YWJsZV9uYW1lcyA9IHNlbGYuYXJnc1sxOl0KKyAgICAKKyAgICAjanVzdCB0byBjaGVjayB0aGlzIG9wdGlvbiBleGlzdHMKKyAgICBzZWxmLmNmLmdldCgicG9zdGdyZXNxbF9kYiIpCisgICAgCisgICAgc2VsZi5tYXhfYmF0Y2hfc2l6ZSA9IGludChzZWxmLmNmLmdldCgibWF4X2JhdGNoX3NpemUiLCAiMTAwMDAiKSkKKyAgICBzZWxmLmhiYXNlX2hvc3RuYW1lID0gc2VsZi5jZi5nZXQoImhiYXNlX2hvc3RuYW1lIiwgImxvY2FsaG9zdCIpCisgICAgc2VsZi5oYmFzZV9wb3J0ID0gaW50KHNlbGYuY2YuZ2V0KCJoYmFzZV9wb3J0IiwgIjkwOTAiKSkKKyAgICBzZWxmLnRhYmxlX21hcHBpbmdzID0gdGFibGVtYXBwaW5nLmxvYWRfdGFibGVfbWFwcGluZ3MoY29uZmlnX2ZpbGUsIHNlbGYudGFibGVfbmFtZXMpCisgIAorICBkZWYgc3RhcnR1cChzZWxmKToKKyAgICAjIG1ha2Ugc3VyZSB0aGUgc2NyaXB0IGxvb3BzIG9ubHkgb25jZS4KKyAgICBzZWxmLnNldF9zaW5nbGVfbG9vcCgxKQorICAgIHNlbGYubG9nLmluZm8oIlN0YXJ0aW5nICIgKyBzZWxmLmpvYl9uYW1lKQorICAgIAorICBkZWYgd29yayhzZWxmKToKKyAgICBmb3IgdCBpbiBzZWxmLnRhYmxlX25hbWVzOgorICAgICAgc2VsZi5ib290c3RyYXBfdGFibGUodCkKKyAgICAgIAorICBkZWYgYm9vdHN0cmFwX3RhYmxlKHNlbGYsIHRhYmxlX25hbWUpOgorICAgIHRyeToKKyAgICAgIHNlbGYubG9nLmluZm8oIkJvb3RzdHJhcHBpbmcgdGFibGUgJXMiICUgdGFibGVfbmFtZSkKKyAgICAgIGhiYXNlID0gSEJhc2VDb25uZWN0aW9uKHNlbGYuaGJhc2VfaG9zdG5hbWUsIHNlbGYuaGJhc2VfcG9ydCkKKyAgICAgIHRyeToKKyAgICAgICAgdGFibGVfbWFwcGluZyA9IHNlbGYudGFibGVfbWFwcGluZ3NbdGFibGVfbmFtZV0KKyAgICAgIAorICAgICAgICBzZWxmLmxvZy5kZWJ1ZygiQ29ubmVjdGluZyB0byBIQmFzZSIpCisgICAgICAgIGhiYXNlLmNvbm5lY3QoKQorICAgICAgICAKKyAgICAgICAgIyBGZXRjaCBwb3N0Z3Jlc3FsIGN1cnNvcgorICAgICAgICBzZWxmLmxvZy5kZWJ1ZygiR2V0dGluZyBwb3N0Z3Jlc3FsIGN1cnNvciIpCisgICAgICAgIGRiID0gc2VsZi5nZXRfZGF0YWJhc2UoInBvc3RncmVzcWxfZGIiKQorICAgICAgICBjdXJzID0gZGIuY3Vyc29yKCkKKyAgICAgICAgCisgICAgICAgIGhiYXNlLnZhbGlkYXRlX3RhYmxlX25hbWUodGFibGVfbWFwcGluZy5oYmFzZV90YWJsZV9uYW1lKQorICAgICAgICBoYmFzZS52YWxpZGF0ZV9jb2x1bW5fZGVzY3JpcHRvcnModGFibGVfbWFwcGluZy5oYmFzZV90YWJsZV9uYW1lLCB0YWJsZV9tYXBwaW5nLmhiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycykKKyAgICAgICAgCisgICAgICAgIHRyeToKKyAgICAgICAgICBkdW1wX2ZpbGUgPSBzZWxmLmNmLmdldCgiYm9vdHN0cmFwX3RtcGZpbGUiKQorICAgICAgICBleGNlcHQ6CisgICAgICAgICAgZHVtcF9maWxlID0gTm9uZQorICAgICAgICAKKyAgICAgICAgaWYgZHVtcF9maWxlICE9IE5vbmU6CisgICAgICAgICAgcm93X3NvdXJjZSA9IENvcGllZFJvd3Moc2VsZi5sb2csIGN1cnMsIGR1bXBfZmlsZSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICByb3dfc291cmNlID0gU2VsZWN0ZWRSb3dzKHNlbGYubG9nLCBjdXJzKQorICAgICAgICAKKyAgICAgICAgdGFibGVfbmFtZSA9IHRhYmxlX21hcHBpbmcucHNxbF9zY2hlbWErIi4iK3RhYmxlX21hcHBpbmcucHNxbF90YWJsZV9uYW1lCisgICAgICAgICMgd2UgYXJlIGNhcmVmdWwgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGZpcnN0IGNvbHVtbiB3aWxsIGJlIHRoZSBrZXkuCisgICAgICAgIGNvbHVtbl9saXN0ID0gW3RhYmxlX21hcHBpbmcucHNxbF9rZXlfY29sdW1uXSArIHRhYmxlX21hcHBpbmcucHNxbF9jb2x1bW5zCisgICAgICAgIAorICAgICAgICAjIExvYWQgdGhlIHJvd3MgZWl0aGVyIHZpYSBhIHNlbGVjdCBvciB2aWEgYSB0YWJsZSBjb3B5IHRvIGZpbGUuIAorICAgICAgICAjIEVpdGhlciB3YXksIGl0IGRvZXMgbm90IGxvYWQgaXQgYWxsIGludG8gbWVtb3J5LiAKKyAgICAgICAgIyBjb3B5IGlzIGZhc3RlciwgYnV0IG1heSBpbmNvcnJlY3RseSBoYW5kbGUgZGF0YSB3aXRoIHRhYnMgaW4gaXQuCisgICAgICAgIHJvd19zb3VyY2UubG9hZF9yb3dzKHRhYmxlX25hbWUsIGNvbHVtbl9saXN0KQorICAgICAgICAKKyAgICAgICAgIyBtYXggbnVtYmVyIG9mIHJvd3MgdG8gZmV0Y2ggYXQgb25jZQorICAgICAgICBiYXRjaF9zaXplID0gc2VsZi5tYXhfYmF0Y2hfc2l6ZQorICAgICAgICB0b3RhbF9yb3dzID0gMEwKKyAgICAgICAgICAKKyAgICAgICAgc2VsZi5sb2cuZGVidWcoIlN0YXJ0aW5nIHB1dHMgdG8gaGJhc2UiKQorICAgICAgICByb3dzID0gcm93X3NvdXJjZS5nZXRfcm93cyhiYXRjaF9zaXplKQorICAgICAgICB3aGlsZSByb3dzICE9IFtdOgorICAgICAgICAgIGJhdGNoZXMgPSBbXQorICAgICAgICAgIGZvciByb3cgaW4gcm93czoKKyAgICAgICAgICAgIGJhdGNoZXMuYXBwZW5kKHNlbGYuY3JlYXRlUm93QmF0Y2godGFibGVfbWFwcGluZywgcm93KSkKKyAgICAgICAgICAKKyAgICAgICAgICBoYmFzZS5jbGllbnQubXV0YXRlUm93cyh0YWJsZV9tYXBwaW5nLmhiYXNlX3RhYmxlX25hbWUsIGJhdGNoZXMpCisgICAgICAgICAgdG90YWxfcm93cyA9IHRvdGFsX3Jvd3MgKyBsZW4oYmF0Y2hlcykKKyAgICAgICAgICBzZWxmLmxvZy5kZWJ1ZygidG90YWwgcm93cyBwdXQgPSAlZCIgJSAodG90YWxfcm93cykpCisgICAgICAgICAgIyBnZXQgbmV4dCBiYXRjaCBvZiByb3dzCisgICAgICAgICAgcm93cyA9IHJvd19zb3VyY2UuZ2V0X3Jvd3MoYmF0Y2hfc2l6ZSkKKyAgICAgICAgICAKKyAgICAgICAgc2VsZi5sb2cuaW5mbygidG90YWwgcm93cyBwdXQgPSAlZCIgJSAodG90YWxfcm93cykpCisgICAgICAgIHNlbGYubG9nLmluZm8oIkJvb3RzdHJhcHBpbmcgdGFibGUgJXMgY29tcGxldGUiICUgdGFibGVfbmFtZSkKKyAgICAgICAgCisgICAgICAgIAorICAgICAgZXhjZXB0IEV4Y2VwdGlvbiwgZToKKyAgICAgICAgI3NlbGYubG9nLmluZm8oZSkKKyAgICAgICAgc3lzLmV4aXQoZSkKKyAgICAgIAorICAgIGZpbmFsbHk6CisgICAgICBoYmFzZS5kaXNjb25uZWN0KCkKKyAgCisgIGRlZiBjcmVhdGVSb3dCYXRjaChzZWxmLCB0YWJsZV9tYXBwaW5nLCByb3cpOgorICAgIGJhdGNoID0gQmF0Y2hNdXRhdGlvbigpCisgICAgYmF0Y2gucm93ID0gdGFibGVfbWFwcGluZy5oYmFzZV9yb3dfcHJlZml4ICsgc3RyKHJvd1swXSkKKyAgICBiYXRjaC5tdXRhdGlvbnMgPSBbXQorICAgIGZvciBjb2x1bW4sIHZhbHVlIGluIHppcCh0YWJsZV9tYXBwaW5nLmhiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycywgcm93WzE6XSk6CisgICAgICBpZiB2YWx1ZSAhPSAnTlVMTCcgYW5kICB2YWx1ZSAhPSBOb25lOgorICAgICAgICBtID0gTXV0YXRpb24oKQorICAgICAgICBtLmNvbHVtbiA9IGNvbHVtbgorICAgICAgICBtLnZhbHVlID0gc3RyKHZhbHVlKQorICAgICAgICBiYXRjaC5tdXRhdGlvbnMuYXBwZW5kKG0pCisgICAgcmV0dXJuIGJhdGNoCisgIAorICAKKyMjIEhlbHBlciBjbGFzc2VzIHRvIGZldGNoIHJvd3MgZnJvbSBhIHNlbGVjdCwgb3IgZnJvbSBhIHRhYmxlIGR1bXBlZCBieSBjb3B5CisgIAorY2xhc3MgUm93U291cmNlOgorICAiIiIgQmFzZSBjbGFzcyBmb3IgZmV0Y2hpbmcgcm93cyBmcm9tIHNvbWV3aGVyZS4gIiIiCisgIAorICBkZWYgX19pbml0X18oc2VsZiwgbG9nKToKKyAgICBzZWxmLmxvZyA9IGxvZworICAgIAorICBkZWYgbWFrZV9jb2x1bW5fc3RyKHNlbGYsIGNvbHVtbl9saXN0KToKKyAgICBpID0gMAorICAgIHdoaWxlIGkgPCBsZW4oY29sdW1uX2xpc3QpOgorICAgICAgY29sdW1uX2xpc3RbaV0gPSAnIiVzIicgJSBjb2x1bW5fbGlzdFtpXQorICAgICAgaSArPSAxCisgICAgcmV0dXJuICIsIi5qb2luKGNvbHVtbl9saXN0KQorICAKKyAgIAorY2xhc3MgQ29waWVkUm93cyhSb3dTb3VyY2UpOgorICAiIiIgCisgIENsYXNzIGZvciBmZXRjaGluZyByb3dzIGZyb20gYSBwb3N0Z3Jlc3FsIGRhdGFiYXNlLAorICByb3dzIGFyZSBkdW1wZWQgdG8gYSBjb3BpZWQgdG8gYSBmaWxlIGZpcnN0CisgICIiIgorICBkZWYgX19pbml0X18oc2VsZiwgbG9nLCBjdXJzLCBkdW1wX2ZpbGUpOgorICAgIFJvd1NvdXJjZS5fX2luaXRfXyhzZWxmLCBsb2cpCisgICAgc2VsZi5kdW1wX2ZpbGUgPSBkdW1wX2ZpbGUKKyAgICAjIFNldCBEQkFQSS0yLjAgY3Vyc29yCisgICAgc2VsZi5jdXJzID0gY3VycworICAgIAorICBkZWYgbG9hZF9yb3dzKHNlbGYsIHRhYmxlX25hbWUsIGNvbHVtbl9saXN0KToKKyAgICBjb2x1bW5zID0gc2VsZi5tYWtlX2NvbHVtbl9zdHIoY29sdW1uX2xpc3QpCisgICAgc2VsZi5sb2cuZGVidWcoInN0YXJ0aW5nIGR1bXAgdG8gZmlsZTolcy4gdGFibGU6JXMuIGNvbHVtbnM6JXMiICUgKHNlbGYuZHVtcF9maWxlLCB0YWJsZV9uYW1lLCBjb2x1bW5zKSkKKyAgICBkdW1wX291dCA9IG9wZW4oc2VsZi5kdW1wX2ZpbGUsICd3JykKKyAgICBzZWxmLmN1cnMuY29weV90byhkdW1wX291dCwgdGFibGVfbmFtZSArICIoJXMpIiAlIGNvbHVtbnMsICdcdCcsICdOVUxMJykKKyAgICBkdW1wX291dC5jbG9zZSgpCisgICAgc2VsZi5sb2cuZGVidWcoInRhYmxlICVzIGR1bXAgY29tcGxldGUiICUgdGFibGVfbmFtZSkKKyAgICAKKyAgICBzZWxmLmR1bXBfaW4gPSBvcGVuKHNlbGYuZHVtcF9maWxlLCAncicpCisgICAgCisgIGRlZiBnZXRfcm93cyhzZWxmLCBub19vZl9yb3dzKToKKyAgICByb3dzID0gW10KKyAgICBpZiBub3Qgc2VsZi5kdW1wX2luLmNsb3NlZDoKKyAgICAgIGZvciBsaW5lIGluIHNlbGYuZHVtcF9pbjoKKyAgICAgICAgcm93cy5hcHBlbmQobGluZS5zcGxpdCgpKSAgICAgIAorICAgICAgICBpZiBsZW4ocm93cykgPj0gbm9fb2Zfcm93czoKKyAgICAgICAgICBicmVhaworICAgICAgaWYgcm93cyA9PSBbXToKKyAgICAgICAgc2VsZi5kdW1wX2luLmNsb3NlKCkKKyAgICByZXR1cm4gcm93cworCisKK2NsYXNzIFNlbGVjdGVkUm93cyhSb3dTb3VyY2UpOgorICAiIiIgCisgIENsYXNzIGZvciBmZXRjaGluZyByb3dzIGZyb20gYSBwb3N0Z3Jlc3FsIGRhdGFiYXNlLAorICByb3dzIGFyZSBmZXRjaGVkIHZpYSBhIHNlbGVjdCBvbiB0aGUgZW50aXJlIHRhYmxlLgorICAiIiIKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGxvZywgY3Vycyk6CisgICAgUm93U291cmNlLl9faW5pdF9fKHNlbGYsIGxvZykKKyAgICAjIFNldCBEQkFQSS0yLjAgY3Vyc29yCisgICAgc2VsZi5jdXJzID0gY3VycworICAgIAorICBkZWYgbG9hZF9yb3dzKHNlbGYsIHRhYmxlX25hbWUsIGNvbHVtbl9saXN0KToKKyAgICBjb2x1bW5zID0gc2VsZi5tYWtlX2NvbHVtbl9zdHIoY29sdW1uX2xpc3QpCisgICAgcSA9ICJTRUxFQ1QgJXMgRlJPTSAlcyIgJSAoY29sdW1ucyx0YWJsZV9uYW1lKQorICAgIHNlbGYubG9nLmRlYnVnKCJFeGVjdXRpbmcgcXVlcnkgJXMiICUgcSkKKyAgICBzZWxmLmN1cnMuZXhlY3V0ZShxKQorICAgIHNlbGYubG9nLmRlYnVnKCJxdWVyeSBmaW5pc2hlZCIpCisgICAgCisgIGRlZiBnZXRfcm93cyhzZWxmLCBub19vZl9yb3dzKToKKyAgICByZXR1cm4gc2VsZi5jdXJzLmZldGNobWFueShub19vZl9yb3dzKQorICAgIAorCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBib290c3RyYXAgPSBIQmFzZUJvb3RzdHJhcCgiSEJhc2VSZXBsaWMiLHN5cy5hcmd2WzE6XSkKKyAgYm9vdHN0cmFwLnN0YXJ0KCkKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvaGJyZXAuaW5pIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9oYnJlcC5pbmkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDgzOTg5NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvaGJyZXAuaW5pCkBAIC0wLDAgKzEsMjIgQEAKK1tIQmFzZVJlcGxpY10KK2pvYl9uYW1lID0gaGJhc2VfcmVwbGljX2pvYgorbG9nZmlsZSA9ICUoam9iX25hbWUpcy5sb2cKK3BpZGZpbGUgPSAlKGpvYl9uYW1lKXMucGlkCitwb3N0Z3Jlc3FsX2RiID0gZGJuYW1lPXNvdXJjZV9kYXRhYmFzZSB1c2VyPWRidXNlcgorcGdxX3F1ZXVlX25hbWUgPSBoYmFzZV9yZXBsaWNfcXVldWUKK2hiYXNlX2hvc3RuYW1lID0gbG9jYWxob3N0CitoYmFzZV9wb3J0ID0gOTA5MAorIyBJZiBvbWl0dGVkLCBkZWZhdWx0IGlzIDEwMDAwCittYXhfYmF0Y2hfc2l6ZSA9IDEwMDAwCisjIGZpbGUgdG8gdXNlIHdoZW4gY29weWluZyBhIHRhYmxlLCBpZiBvbWl0dGVkIGEgc2VsZWN0IGNvbHVtbnMgd2lsbCBiZSBkb25lIGluc3RlYWQuCitib290c3RyYXBfdG1wZmlsZSA9IHRhYmxlZHVtcC5kYXQKKworIyBGb3IgZWFjaCB0YWJsZSBtYXBwaW5nLCB0aGVyZSBtdXN0IGJlIHRoZSBzYW1lIG51bWJlciBwc3FsX2NvbHVtbnMgYXMgaGJhc2VfY29sdW1uX2Rlc2NyaXB0b3JzCitbcHVibGljLnVzZXJzXQorcHNxbF9zY2hlbWEgPSBwdWJsaWMKK3BzcWxfdGFibGVfbmFtZSA9IHVzZXJzCitwc3FsX2tleV9jb2x1bW4gPSB1c2VyX2lkCitwc3FsX2NvbHVtbnMgPSBkb2IKK2hiYXNlX3RhYmxlX25hbWUgPSBzdHVmZgoraGJhc2VfY29sdW1uX2Rlc2NyaXB0b3JzID0gdXNlcnM6ZG9iCitoYmFzZV9yb3dfcHJlZml4ID0gdXNlcl9pZDoKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvaGJyZXAucHkgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL2hicmVwLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjY2NTM4N2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL2hicmVwLnB5CkBAIC0wLDAgKzEsMTI2IEBACisjIS91c3IvYmluL2VudiBweXRob24KK2ltcG9ydCBzeXMsIG9zCisKK2ltcG9ydCBwZ3EsIHBncS5wcm9kdWNlcgoraW1wb3J0IHNreXRvb2xzLCBza3l0b29scy5fcHlxdW90aW5nCisKK2Zyb20gYm9vdHN0cmFwIGltcG9ydCBIQmFzZUJvb3RzdHJhcAorZnJvbSBIQmFzZUNvbnN1bWVyIGltcG9ydCBIQmFzZUNvbnN1bWVyCisKK2NvbW1hbmRfdXNhZ2UgPSAiIiIKKyVwcm9nIFtvcHRpb25zXSBpbmlmaWxlIGNvbW1hbmQgW3RhYmxlbmFtZXNdCisKK2NvbW1hbmRzOgorICBwbGF5ICAgICAgICAgIFJ1biBldmVudCBjb25zdW1lciB0byB1cGRhdGUgc3BlY2lmaWVkIHRhYmxlcyB3aXRoIGhiYXNlLgorICBib290c3RyYXAgICAgIEJvb3RzdHJhcCBzcGVjaWZpZWQgdGFibGVzIGFyZ3MgaW50byBoYmFzZS4KKyAgaW5zdGFsbCAgICAgICBTZXR1cCB0aGUgcGdxIHF1ZXVlLCBhbmQgaW5zdGFsbCB0cmlnZ2VyIG9uIGVhY2ggdGFibGUuCisgIHVuaW5zdGFsbCAgICAgUmVtb3ZlIHRoZSB0cmlnZ2VycyBmcm9tIGVhY2ggc3BlY2lmaWVkIHRhYmxlLgorIiIiCisKK2NsYXNzIEhCYXNlUmVwbGljKHNreXRvb2xzLkRCU2NyaXB0KToKKyAgZGVmIF9faW5pdF9fKHNlbGYsIHNlcnZpY2VfbmFtZSwgYXJncyk6CisgICAgdHJ5OgorICAgICAgc2VsZi5ydW5fc2NyaXB0ID0gMAorICAgICAgCisgICAgICAjIFRoaXMgd2lsbCBwcm9jZXNzIGFueSBvcHRpb25zIGVnIC1rIC12IC1kCisgICAgICBza3l0b29scy5EQlNjcmlwdC5fX2luaXRfXyhzZWxmLCBzZXJ2aWNlX25hbWUsIGFyZ3MpCisgICAgICAKKyAgICAgIHNlbGYuY29uZmlnX2ZpbGUgPSBzZWxmLmFyZ3NbMF0KKyAgICAgIAorICAgICAgaWYgbGVuKHNlbGYuYXJncykgPCAyOgorICAgICAgICBzZWxmLnByaW50X3VzYWdlKCkKKyAgICAgICAgcHJpbnQgIm5lZWQgY29tbWFuZCIKKyAgICAgICAgc3lzLmV4aXQoMCkKKyAgICAgIGNtZCA9IHNlbGYuYXJnc1sxXQorICAgICAgICAKKyAgICAgIGlmIG5vdCBjbWQgaW4gWyJwbGF5IiwiYm9vdHN0cmFwIiwiaW5zdGFsbCIsICJ1bmluc3RhbGwiXToKKyAgICAgICAgc2VsZi5wcmludF91c2FnZSgpCisgICAgICAgIHByaW50ICJ1bmtub3duIGNvbW1hbmQiCisgICAgICAgIHN5cy5leGl0KDApCisgICAgICAgIAorICAgICAgaWYgbGVuKHNlbGYuYXJncykgPCAzOgorICAgICAgICBzZWxmLnByaW50X3VzYWdlKCkKKyAgICAgICAgcHJpbnQgIm5lZWQgdGFibGUgbmFtZXMiCisgICAgICAgIHN5cy5leGl0KDApCisgICAgICBlbHNlOgorICAgICAgICBzZWxmLnRhYmxlX25hbWVzID0gc2VsZi5hcmdzWzI6XQorICAgICAgCisgICAgICBpZiBjbWQgPT0gInBsYXkiOgorICAgICAgICBzZWxmLnJ1bl9zY3JpcHQgPSBIQmFzZUNvbnN1bWVyKHNlcnZpY2VfbmFtZSwgW3NlbGYuY29uZmlnX2ZpbGVdICsgc2VsZi50YWJsZV9uYW1lcykKKyAgICAgIGVsaWYgY21kID09ICJib290c3RyYXAiOgorICAgICAgICBzZWxmLnJ1bl9zY3JpcHQgPSBIQmFzZUJvb3RzdHJhcChzZXJ2aWNlX25hbWUsIFtzZWxmLmNvbmZpZ19maWxlXSArIHNlbGYudGFibGVfbmFtZXMpCisgICAgICBlbGlmIGNtZCA9PSAiaW5zdGFsbCI6CisgICAgICAgIHNlbGYud29yayA9IHNlbGYuZG9faW5zdGFsbAorICAgICAgZWxpZiBjbWQgPT0gInVuaW5zdGFsbCI6CisgICAgICAgIHNlbGYud29yayA9IHNlbGYuZG9fdW5pbnN0YWxsCisgICAgICAgIAorICAgIGV4Y2VwdCBFeGNlcHRpb24sIGU6CisgICAgICBzeXMuZXhpdChlKQorICAKKyAgZGVmIHByaW50X3VzYWdlKHNlbGYpOgorICAgIHByaW50ICJVc2FnZTogIiArIGNvbW1hbmRfdXNhZ2UKKyAgICAKKyAgZGVmIGluaXRfb3B0cGFyc2Uoc2VsZiwgcGFyc2VyPU5vbmUpOgorICAgIHAgPSBza3l0b29scy5EQlNjcmlwdC5pbml0X29wdHBhcnNlKHNlbGYsIHBhcnNlcikKKyAgICBwLnNldF91c2FnZShjb21tYW5kX3VzYWdlLnN0cmlwKCkpCisgICAgcmV0dXJuIHAKKworICBkZWYgc3RhcnQoc2VsZik6CisgICAgaWYgc2VsZi5ydW5fc2NyaXB0OgorICAgICAgc2VsZi5ydW5fc2NyaXB0LnN0YXJ0KCkKKyAgICBlbHNlOgorICAgICAgc2t5dG9vbHMuREJTY3JpcHQuc3RhcnQoc2VsZikKKyAgICAgIAorICBkZWYgc3RhcnR1cChzZWxmKToKKyAgICAjIG1ha2Ugc3VyZSB0aGUgc2NyaXB0IGxvb3BzIG9ubHkgb25jZS4KKyAgICBzZWxmLnNldF9zaW5nbGVfbG9vcCgxKQorICAgIAorICBkZWYgZG9faW5zdGFsbChzZWxmKToKKyAgICB0cnk6CisgICAgICBxdWV1ZV9uYW1lID0gc2VsZi5jZi5nZXQoInBncV9xdWV1ZV9uYW1lIikKKyAgICAgIGNvbnN1bWVyID0gc2VsZi5qb2JfbmFtZQorICAgICAgCisgICAgICBzZWxmLmxvZy5pbmZvKCdDcmVhdGluZyBxdWV1ZTogJXMnICUgcXVldWVfbmFtZSkKKyAgICAgIHNlbGYuZXhlY19zcWwoInNlbGVjdCBwZ3EuY3JlYXRlX3F1ZXVlKCVzKSIsIFtxdWV1ZV9uYW1lXSkKKyAgCisgICAgICBzZWxmLmxvZy5pbmZvKCdSZWdpc3RlcmluZyBjb25zdW1lciAlcyBvbiBxdWV1ZSAlcycgJSAoY29uc3VtZXIsIHF1ZXVlX25hbWUpKQorICAgICAgc2VsZi5leGVjX3NxbCgic2VsZWN0IHBncS5yZWdpc3Rlcl9jb25zdW1lciglcywgJXMpIiwgW3F1ZXVlX25hbWUsIGNvbnN1bWVyXSkKKyAgCisgICAgICBmb3IgdGFibGVfbmFtZSBpbiBzZWxmLnRhYmxlX25hbWVzOgorICAgICAgICBzZWxmLmxvZy5pbmZvKCdDcmVhdGluZyB0cmlnZ2VyIGhiYXNlX3JlcGxpYyBvbiB0YWJsZSAlcycgJSAodGFibGVfbmFtZSkpCisgICAgICAgIHEgPSAiIiIKKyAgICAgICAgQ1JFQVRFIFRSSUdHRVIgaGJhc2VfcmVwbGljCisgICAgICAgICAgQUZURVIgSU5TRVJUIE9SIFVQREFURSBPUiBERUxFVEUKKyAgICAgICAgICBPTiAlcworICAgICAgICAgIEZPUiBFQUNIIFJPVworICAgICAgICAgIEVYRUNVVEUgUFJPQ0VEVVJFIHBncS5sb2d1dHJpZ2EoJyVzJykiIiIKKyAgICAgICAgc2VsZi5leGVjX3NxbChxICUgKHRhYmxlX25hbWUsIHF1ZXVlX25hbWUpLCBbXSkKKyAgICBleGNlcHQgRXhjZXB0aW9uLCBlOgorICAgICAgc3lzLmV4aXQoZSkKKyAgICAgIAorICBkZWYgZG9fdW5pbnN0YWxsKHNlbGYpOgorICAgIHRyeToKKyAgICAgIHF1ZXVlX25hbWUgPSBzZWxmLmNmLmdldCgicGdxX3F1ZXVlX25hbWUiKQorICAgICAgY29uc3VtZXIgPSAiSEJhc2VSZXBsaWMiCisgICAgICAKKyAgICAgICNzZWxmLmxvZy5pbmZvKCdVbnJlZ2lzdGVyaW5nIGNvbnN1bWVyICVzIG9uIHF1ZXVlICVzJyAlIChjb25zdW1lciwgcXVldWVfbmFtZSkpCisgICAgICAjc2VsZi5leGVjX3NxbCgic2VsZWN0IHBncS51bnJlZ2lzdGVyX2NvbnN1bWVyKCVzLCAlcykiLCBbcXVldWVfbmFtZSwgY29uc3VtZXJdKQorICAKKyAgICAgIGZvciB0YWJsZV9uYW1lIGluIHNlbGYudGFibGVfbmFtZXM6CisgICAgICAgIHNlbGYubG9nLmluZm8oJ0Ryb3BwaW5nIHRyaWdnZXIgaGJhc2VfcmVwbGljIG9uIHRhYmxlICVzJyAlICh0YWJsZV9uYW1lKSkKKyAgICAgICAgcSA9ICJEUk9QIFRSSUdHRVIgaGJhc2VfcmVwbGljIE9OICVzIiAlIHRhYmxlX25hbWUKKyAgICAgICAgc2VsZi5leGVjX3NxbChxLCBbXSkKKyAgICAgICAgCisgICAgZXhjZXB0IEV4Y2VwdGlvbiwgZToKKyAgICAgIHN5cy5leGl0KGUpCisgICAgCisgIGRlZiBleGVjX3NxbChzZWxmLCBxLCBhcmdzKToKKyAgICBzZWxmLmxvZy5kZWJ1ZyhxKQorICAgIGRiID0gc2VsZi5nZXRfZGF0YWJhc2UoJ3Bvc3RncmVzcWxfZGInKQorICAgIGN1cnMgPSBkYi5jdXJzb3IoKQorICAgIGN1cnMuZXhlY3V0ZShxLCBhcmdzKQorICAgIGRiLmNvbW1pdCgpCisgICAgCitpZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgorICBzY3JpcHQgPSBIQmFzZVJlcGxpYygiSEJhc2VSZXBsaWMiLHN5cy5hcmd2WzE6XSkKKyAgc2NyaXB0LnN0YXJ0KCkKZGlmZiAtLWdpdCBhL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvcGdxLmluaSBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvcGdxLmluaQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMTFiNWRkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2V4YW1wbGVzL3VwbG9hZGVycy9oYnJlcC9wZ3EuaW5pCkBAIC0wLDAgKzEsMTAgQEAKK1twZ3FhZG1dCitqb2JfbmFtZSA9IHNvdXJjZWRiX3RpY2tlcgorZGIgPSBkYm5hbWU9c291cmNlX2RhdGFiYXNlIHVzZXI9ZGJ1c2VyCisjIGhvdyBvZnRlbiB0byBydW4gbWFpbnRlbmFuY2UgW21pbnV0ZXNdCittYWludF9kZWxheV9taW4gPSAxCisjIGhvdyBvZnRlbiB0byBjaGVjayBmb3IgYWN0aXZpdHkgW3NlY3NdCitsb29wX2RlbGF5ID0gMC4yCitsb2dmaWxlID0gJShqb2JfbmFtZSlzLmxvZworcGlkZmlsZSA9ICUoam9iX25hbWUpcy5waWQKK3VzZV9za3lsb2cgPSAwCmRpZmYgLS1naXQgYS9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL3RhYmxlbWFwcGluZy5weSBiL3NyYy9leGFtcGxlcy91cGxvYWRlcnMvaGJyZXAvdGFibGVtYXBwaW5nLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4NWNiZmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZXhhbXBsZXMvdXBsb2FkZXJzL2hicmVwL3RhYmxlbWFwcGluZy5weQpAQCAtMCwwICsxLDMzIEBACitpbXBvcnQgc3lzLCBvcworZnJvbSBza3l0b29scy5jb25maWcgaW1wb3J0ICoKKworUFNRTF9TQ0hFTUEgPSAicHNxbF9zY2hlbWEiCitQU1FMX1RBQkxFTkFNRSA9ICJwc3FsX3RhYmxlX25hbWUiCitQU1FMX0tFWUNPTCA9ICJwc3FsX2tleV9jb2x1bW4iCitQU1FMX0NPTFVNTlMgPSAicHNxbF9jb2x1bW5zIgorSEJBU0VfVEFCTEVOQU1FID0gImhiYXNlX3RhYmxlX25hbWUiCitIQkFTRV9DT0xVTU5ERVNDUyA9ICJoYmFzZV9jb2x1bW5fZGVzY3JpcHRvcnMiCitIQkFTRV9ST1dQUkVGSVggPSAiaGJhc2Vfcm93X3ByZWZpeCIKKworZGVmIGxvYWRfdGFibGVfbWFwcGluZ3MoY29uZmlnX2ZpbGUsIHRhYmxlX25hbWVzKToKKyAgdGFibGVfbWFwcGluZ3MgPSB7fQorICBmb3IgdGFibGVfbmFtZSBpbiB0YWJsZV9uYW1lczoKKyAgICBjb25mID0gQ29uZmlnKHRhYmxlX25hbWUsIGNvbmZpZ19maWxlKQorICAgIHRhYmxlX21hcHBpbmdzW3RhYmxlX25hbWVdID0gUFNxbEhCYXNlVGFibGVNYXBwaW5nKGNvbmYpCisgIHJldHVybiB0YWJsZV9tYXBwaW5ncworICAKK2NsYXNzIFBTcWxIQmFzZVRhYmxlTWFwcGluZzoKKyAgIyBjb25mIGNhbiBiZSBhbnl0aGluZyB3aXRoIGEgZ2V0IGZ1bmN0aW9uIGVnLCBhIGRpY3Rpb25hcnkKKyAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbmYpOgorICAgIHNlbGYucHNxbF9zY2hlbWEgPSBjb25mLmdldChQU1FMX1NDSEVNQSkKKyAgICBzZWxmLnBzcWxfdGFibGVfbmFtZSA9IGNvbmYuZ2V0KFBTUUxfVEFCTEVOQU1FKQorICAgIHNlbGYucHNxbF9rZXlfY29sdW1uID0gY29uZi5nZXQoUFNRTF9LRVlDT0wpCisgICAgc2VsZi5wc3FsX2NvbHVtbnMgPSBjb25mLmdldChQU1FMX0NPTFVNTlMpLnNwbGl0KCkKKyAgICBzZWxmLmhiYXNlX3RhYmxlX25hbWUgPSBjb25mLmdldChIQkFTRV9UQUJMRU5BTUUpCisgICAgc2VsZi5oYmFzZV9jb2x1bW5fZGVzY3JpcHRvcnMgPSBjb25mLmdldChIQkFTRV9DT0xVTU5ERVNDUykuc3BsaXQoKQorICAgIHNlbGYuaGJhc2Vfcm93X3ByZWZpeCA9IGNvbmYuZ2V0KEhCQVNFX1JPV1BSRUZJWCkKKyAgICAKKyAgICBpZiBsZW4oc2VsZi5wc3FsX2NvbHVtbnMpICE9IGxlbihzZWxmLmhiYXNlX2NvbHVtbl9kZXNjcmlwdG9ycyk6CisgICAgICByYWlzZSBFeGNlcHRpb24oInBzcWxfY29sdW1ucyBhbmQgaGJhc2VfY29sdW1uX2Rlc2NyaXB0b3JzIG11c3QgaGF2ZSBzYW1lIGxlbmd0aCIpCisgICAgCisgIApkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvQ2hvcmUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0Nob3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZhOTdkNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0Nob3JlLmphdmEKQEAgLTAsMCArMSwxMDYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5TbGVlcGVyOworCisvKioKKyAqIENob3JlIGlzIGEgdGFzayBwZXJmb3JtZWQgb24gYSBwZXJpb2QgaW4gaGJhc2UuICBUaGUgY2hvcmUgaXMgcnVuIGluIGl0cyBvd24KKyAqIHRocmVhZC4gVGhpcyBiYXNlIGFic3RyYWN0IGNsYXNzIHByb3ZpZGVzIHdoaWxlIGxvb3AgYW5kIHNsZWVwaW5nIGZhY2lsaXR5LgorICogSWYgYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbiwgdGhlIHRocmVhZHMgZXhpdCBpcyBsb2dnZWQuCisgKiBJbXBsZW1lbnRlcnMganVzdCBuZWVkIHRvIGFkZCBjaGVja2luZyBpZiB0aGVyZSBpcyB3b3JrIHRvIGJlIGRvbmUgYW5kIGlmCisgKiBzbywgZG8gaXQuICBJdHMgdGhlIGJhc2Ugb2YgbW9zdCBvZiB0aGUgY2hvcmUgdGhyZWFkcyBpbiBoYmFzZS4KKyAqIAorICogRG9uJ3Qgc3ViY2xhc3MgQ2hvcmUgaWYgdGhlIHRhc2sgcmVsaWVzIG9uIGJlaW5nIHdva2VuIHVwIGZvciBzb21ldGhpbmcgdG8KKyAqIGRvLCBzdWNoIGFzIGFuIGVudHJ5IGJlaW5nIGFkZGVkIHRvIGEgcXVldWUsIGV0Yy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIENob3JlIGV4dGVuZHMgVGhyZWFkIHsKKyAgcHJpdmF0ZSBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpKTsKKyAgcHJpdmF0ZSBmaW5hbCBTbGVlcGVyIHNsZWVwZXI7CisgIHByb3RlY3RlZCB2b2xhdGlsZSBBdG9taWNCb29sZWFuIHN0b3A7CisgIAorICAvKioKKyAgICogQHBhcmFtIHAgUGVyaW9kIGF0IHdoaWNoIHdlIHNob3VsZCBydW4uICBXaWxsIGJlIGFkanVzdGVkIGFwcHJvcHJpYXRlbHkKKyAgICogc2hvdWxkIHdlIGZpbmQgd29yayBhbmQgaXQgdGFrZXMgdGltZSB0byBjb21wbGV0ZS4KKyAgICogQHBhcmFtIHMgV2hlbiB0aGlzIGZsYWcgaXMgc2V0IHRvIHRydWUsIHRoaXMgdGhyZWFkIHdpbGwgY2xlYW51cCBhbmQgZXhpdAorICAgKiBjbGVhbmx5LgorICAgKi8KKyAgcHVibGljIENob3JlKGZpbmFsIGludCBwLCBmaW5hbCBBdG9taWNCb29sZWFuIHMpIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuc2xlZXBlciA9IG5ldyBTbGVlcGVyKHAsIHMpOworICAgIHRoaXMuc3RvcCA9IHM7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkI3J1bigpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcnVuKCkgeworICAgIHRyeSB7CisgICAgICBib29sZWFuIGluaXRpYWxDaG9yZUNvbXBsZXRlID0gZmFsc2U7CisgICAgICB3aGlsZSAoIXRoaXMuc3RvcC5nZXQoKSkgeworICAgICAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmICghaW5pdGlhbENob3JlQ29tcGxldGUpIHsKKyAgICAgICAgICAgIGluaXRpYWxDaG9yZUNvbXBsZXRlID0gaW5pdGlhbENob3JlKCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGNob3JlKCk7CisgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiQ2F1Z2h0IGV4Y2VwdGlvbiIsIGUpOworICAgICAgICAgIGlmICh0aGlzLnN0b3AuZ2V0KCkpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLnNsZWVwZXIuc2xlZXAoc3RhcnRUaW1lKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgTE9HLmZhdGFsKCJDYXVnaHQgZXJyb3IuIFN0YXJ0aW5nIHNodXRkb3duLiIsIHQpOworICAgICAgdGhpcy5zdG9wLnNldCh0cnVlKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIiBleGl0aW5nIik7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogT3ZlcnJpZGUgdG8gcnVuIGEgdGFzayBiZWZvcmUgd2Ugc3RhcnQgbG9vcGluZy4KKyAgICogQHJldHVybiB0cnVlIGlmIGluaXRpYWwgY2hvcmUgd2FzIHN1Y2Nlc3NmdWwKKyAgICovCisgIHByb3RlY3RlZCBib29sZWFuIGluaXRpYWxDaG9yZSgpIHsKKyAgICAvLyBEZWZhdWx0IGRvZXMgbm90aGluZy4KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICAKKyAgLyoqCisgICAqIExvb2sgZm9yIGNob3Jlcy4gIElmIGFueSBmb3VuZCwgZG8gdGhlbSBlbHNlIGp1c3QgcmV0dXJuLgorICAgKi8KKyAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgY2hvcmUoKTsKKworICAvKioKKyAgICogU2xlZXAgZm9yIHBlcmlvZC4KKyAgICovCisgIHByb3RlY3RlZCB2b2lkIHNsZWVwKCkgeworICAgIHRoaXMuc2xlZXBlci5zbGVlcCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Db2x1bW5OYW1lUGFyc2VFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0NvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0M2MxZTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Db2x1bW5OYW1lUGFyc2VFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKKy8qKgorICogVGhyb3duIGlmIGlzc3VlIHdpdGggcGFzc2VkIGNvbHVtbiBuYW1lLgorICovCitwdWJsaWMgY2xhc3MgQ29sdW1uTmFtZVBhcnNlRXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMjg5NzM3MzM1Mzk0OTk0MjMwMkw7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBtZXNzYWdlCisgICAqLworICBwdWJsaWMgQ29sdW1uTmFtZVBhcnNlRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgc3VwZXIobWVzc2FnZSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Eb05vdFJldHJ5SU9FeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0RvTm90UmV0cnlJT0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5NzZmNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Eb05vdFJldHJ5SU9FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFN1YmNsYXNzIGlmIGV4Y2VwdGlvbiBpcyBub3QgbWVhbnQgdG8gYmUgcmV0cmllZDogZS5nLgorICoge0BsaW5rIFVua25vd25TY2FubmVyRXhjZXB0aW9ufQorICovCitwdWJsaWMgY2xhc3MgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDExOTc0NDY0NTQ1MTE3MDQxMzlMOworCisgIC8qKgorICAgKiBkZWZhdWx0IGNvbnN0cnVjdG9yCisgICAqLworICBwdWJsaWMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICovCisgIHB1YmxpYyBEb05vdFJldHJ5SU9FeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0Ryb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWRkZmQwYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0Ryb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworCisvKioKKyAqIFRocm93biBkdXJpbmcgZmx1c2ggaWYgdGhlIHBvc3NpYmlsaXR5IHNuYXBzaG90IGNvbnRlbnQgd2FzIG5vdCBwcm9wZXJseQorICogcGVyc2lzdGVkIGludG8gc3RvcmUgZmlsZXMuICBSZXNwb25zZSBzaG91bGQgaW5jbHVkZSByZXBsYXkgb2YgaGxvZyBjb250ZW50LgorICovCitwdWJsaWMgY2xhc3MgRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01NDYzMTU2NTgwODMxNjc3Mzc0TDsKKworICAvKioKKyAgICogQHBhcmFtIG1zZworICAgKi8KKyAgcHVibGljIERyb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CisgICAgc3VwZXIobXNnKTsKKyAgfQorCisgIC8qKgorICAgKiBkZWZhdWx0IGNvbnN0cnVjdG9yCisgICAqLworICBwdWJsaWMgRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hCYXNlQ29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSEJhc2VDb25maWd1cmF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGI1NGMzNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hCYXNlQ29uZmlndXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworCisvKioKKyAqIEFkZHMgSEJhc2UgY29uZmlndXJhdGlvbiBmaWxlcyB0byBhIENvbmZpZ3VyYXRpb24KKyAqLworcHVibGljIGNsYXNzIEhCYXNlQ29uZmlndXJhdGlvbiBleHRlbmRzIENvbmZpZ3VyYXRpb24geworICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIEhCYXNlQ29uZmlndXJhdGlvbigpIHsKKyAgICBzdXBlcigpOworICAgIGFkZEhiYXNlUmVzb3VyY2VzKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDcmVhdGUgYSBjbG9uZSBvZiBwYXNzZWQgY29uZmlndXJhdGlvbi4KKyAgICogQHBhcmFtIGMgQ29uZmlndXJhdGlvbiB0byBjbG9uZS4KKyAgICovCisgIHB1YmxpYyBIQmFzZUNvbmZpZ3VyYXRpb24oZmluYWwgQ29uZmlndXJhdGlvbiBjKSB7CisgICAgdGhpcygpOworICAgIGZvciAoRW50cnk8U3RyaW5nLCBTdHJpbmc+ZTogYykgeworICAgICAgc2V0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHZvaWQgYWRkSGJhc2VSZXNvdXJjZXMoKSB7CisgICAgYWRkUmVzb3VyY2UoImhiYXNlLWRlZmF1bHQueG1sIik7CisgICAgYWRkUmVzb3VyY2UoImhiYXNlLXNpdGUueG1sIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgSEJhc2VDb25maWd1cmF0aW9uLiBUaGUgaGFzaCBjb2RlIG9mIGEKKyAgICogSEJhc2VDb25maWd1cmF0aW9uIGlzIGRlZmluZWQgYnkgdGhlIHN1bSBvZiB0aGUgaGFzaCBjb2RlcyBvZiBpdHMgZW50cmllcy4KKyAgICogCisgICAqIEBzZWUgQ29uZmlndXJhdGlvbiNpdGVyYXRvcigpIEhvdyB0aGUgZW50cmllcyBhcmUgb2J0YWluZWQuCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICBpbnQgaGFzaCA9IDA7CisKKyAgICBJdGVyYXRvcjxFbnRyeTxTdHJpbmcsIFN0cmluZz4+IHByb3BlcnR5SXRlcmF0b3IgPSB0aGlzLml0ZXJhdG9yKCk7CisgICAgd2hpbGUgKHByb3BlcnR5SXRlcmF0b3IuaGFzTmV4dCgpKSB7CisgICAgICBoYXNoIF49IHByb3BlcnR5SXRlcmF0b3IubmV4dCgpLmhhc2hDb2RlKCk7CisgICAgfQorICAgIHJldHVybiBoYXNoOworICB9CisgIAorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSENvbHVtbkRlc2NyaXB0b3IuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hDb2x1bW5EZXNjcmlwdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTU1M2M2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hDb2x1bW5EZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSw2OTEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5Db21wcmVzc2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVNlcmlhbGl6YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlOworCitpbXBvcnQgYWdpbGVqc29uLlRPSlNPTjsKKworLyoqCisgKiBBbiBIQ29sdW1uRGVzY3JpcHRvciBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbHVtbiBmYW1pbHkgc3VjaCBhcyB0aGUKKyAqIG51bWJlciBvZiB2ZXJzaW9ucywgY29tcHJlc3Npb24gc2V0dGluZ3MsIGV0Yy4KKyAqIAorICogSXQgaXMgdXNlZCBhcyBpbnB1dCB3aGVuIGNyZWF0aW5nIGEgdGFibGUgb3IgYWRkaW5nIGEgY29sdW1uLiBPbmNlIHNldCwgdGhlCisgKiBwYXJhbWV0ZXJzIHRoYXQgc3BlY2lmeSBhIGNvbHVtbiBjYW5ub3QgYmUgY2hhbmdlZCB3aXRob3V0IGRlbGV0aW5nIHRoZQorICogY29sdW1uIGFuZCByZWNyZWF0aW5nIGl0LiBJZiB0aGVyZSBpcyBkYXRhIHN0b3JlZCBpbiB0aGUgY29sdW1uLCBpdCB3aWxsIGJlCisgKiBkZWxldGVkIHdoZW4gdGhlIGNvbHVtbiBpcyBkZWxldGVkLgorICovCitwdWJsaWMgY2xhc3MgSENvbHVtbkRlc2NyaXB0b3IgaW1wbGVtZW50cyBJU2VyaWFsaXphYmxlLCBXcml0YWJsZUNvbXBhcmFibGU8SENvbHVtbkRlc2NyaXB0b3I+IHsKKyAgLy8gRm9yIGZ1dHVyZSBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CisKKyAgLy8gVmVyc2lvbiAzIHdhcyB3aGVuIGNvbHVtbiBuYW1lcyBiZWNvbWUgYnl0ZSBhcnJheXMgYW5kIHdoZW4gd2UgcGlja2VkIHVwCisgIC8vIFRpbWUtdG8tbGl2ZSBmZWF0dXJlLiAgVmVyc2lvbiA0IHdhcyB3aGVuIHdlIG1vdmVkIHRvIGJ5dGUgYXJyYXlzLCBIQkFTRS04Mi4KKyAgLy8gVmVyc2lvbiA1IHdhcyB3aGVuIGJsb29tIGZpbHRlciBkZXNjcmlwdG9ycyB3ZXJlIHJlbW92ZWQuCisgIC8vIFZlcnNpb24gNiBhZGRzIG1ldGFkYXRhIGFzIGEgbWFwIHdoZXJlIGtleXMgYW5kIHZhbHVlcyBhcmUgYnl0ZVtdLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIENPTFVNTl9ERVNDUklQVE9SX1ZFUlNJT04gPSAoYnl0ZSk3OworCisgIC8qKiAKKyAgICogVGhlIHR5cGUgb2YgY29tcHJlc3Npb24uCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaW8uU2VxdWVuY2VGaWxlLldyaXRlcgorICAgKiBAZGVwcmVjYXRlZCBDb21wcmVzc2lvbiBub3cgbWVhbnMgd2hpY2ggY29tcHJlc3Npb24gbGlicmFyeQorICAgKiByYXRoZXIgdGhhbiAnd2hhdCcgdG8gY21vcHJlc3MuICBTZWUge0BsaW5rIENvbXByZXNzaW9uLkFsZ29yaXRobX0KKyAgICovCisgIEBEZXByZWNhdGVkCisgIHB1YmxpYyBzdGF0aWMgZW51bSBDb21wcmVzc2lvblR5cGUgeworICAgIC8qKiBEbyBub3QgY29tcHJlc3MgcmVjb3Jkcy4gKi8KKyAgICBOT05FLCAKKyAgICAvKiogQ29tcHJlc3MgdmFsdWVzIG9ubHksIGVhY2ggc2VwYXJhdGVseS4gKi8KKyAgICBSRUNPUkQsCisgICAgLyoqIENvbXByZXNzIHNlcXVlbmNlcyBvZiByZWNvcmRzIHRvZ2V0aGVyIGluIGJsb2Nrcy4gKi8KKyAgICBCTE9DSworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NUFJFU1NJT04gPSAiQ09NUFJFU1NJT04iOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCTE9DS0NBQ0hFID0gIkJMT0NLQ0FDSEUiOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCTE9DS1NJWkUgPSAiQkxPQ0tTSVpFIjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEVOR1RIID0gIkxFTkdUSCI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRUTCA9ICJUVEwiOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBCTE9PTUZJTFRFUiA9ICJCTE9PTUZJTFRFUiI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZPUkVWRVIgPSAiRk9SRVZFUiI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1BUEZJTEVfSU5ERVhfSU5URVJWQUwgPQorICAgICAgIk1BUEZJTEVfSU5ERVhfSU5URVJWQUwiOworCisgIC8qKgorICAgKiBEZWZhdWx0IGNvbXByZXNzaW9uIHR5cGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0NPTVBSRVNTSU9OID0KKyAgICBDb21wcmVzc2lvbi5BbGdvcml0aG0uTk9ORS5nZXROYW1lKCk7CisKKyAgLyoqCisgICAqIERlZmF1bHQgbnVtYmVyIG9mIHZlcnNpb25zIG9mIGEgcmVjb3JkIHRvIGtlZXAuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1ZFUlNJT05TID0gMzsKKworICAvKioKKyAgICogRGVmYXVsdCBtYXhpbXVtIGNlbGwgbGVuZ3RoLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9MRU5HVEggPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgLyoqIERlZmF1bHQgbWF4aW11bSBjZWxsIGxlbmd0aCBhcyBhbiBJbnRlZ2VyLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIEludGVnZXIgREVGQVVMVF9MRU5HVEhfSU5URUdFUiA9CisgICAgSW50ZWdlci52YWx1ZU9mKERFRkFVTFRfTEVOR1RIKTsKKyAgCisgIC8qCisgICAqIENhY2hlIGhlcmUgdGhlIEhDRCB2YWx1ZS4KKyAgICogUXVlc3Rpb246IGl0cyBPSyB0byBjYWNoZSBzaW5jZSB3aGVuIHdlJ3JlIHJlZW5hYmxlLCB3ZSBjcmVhdGUgYSBuZXcgSENEPworICAgKi8KKyAgcHJpdmF0ZSB2b2xhdGlsZSBJbnRlZ2VyIG1heFZhbHVlTGVuZ3RoID0gbnVsbDsKKworICAvKgorICAgKiBDYWNoZSBoZXJlIHRoZSBIQ0QgdmFsdWUuCisgICAqIFF1ZXN0aW9uOiBpdHMgT0sgdG8gY2FjaGUgc2luY2Ugd2hlbiB3ZSdyZSByZWVuYWJsZSwgd2UgY3JlYXRlIGEgbmV3IEhDRD8KKyAgICovCisgIHByaXZhdGUgdm9sYXRpbGUgSW50ZWdlciBibG9ja3NpemUgPSBudWxsOworCisgIC8qKgorICAgKiBEZWZhdWx0IHNldHRpbmcgZm9yIHdoZXRoZXIgdG8gc2VydmUgZnJvbSBtZW1vcnkgb3Igbm90LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIERFRkFVTFRfSU5fTUVNT1JZID0gZmFsc2U7CisKKyAgLyoqCisgICAqIERlZmF1bHQgc2V0dGluZyBmb3Igd2hldGhlciB0byB1c2UgYSBibG9jayBjYWNoZSBvciBub3QuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVGQVVMVF9CTE9DS0NBQ0hFID0gZmFsc2U7CisKKyAgLyoqCisgICAqIERlZmF1bHQgc2l6ZSBvZiBibG9ja3MgaW4gZmlsZXMgc3RvcmUgdG8gdGhlIGZpbGVzeXRlbS4gIFVzZSBzbWFsbGVyIGZvcgorICAgKiBmYXN0ZXIgcmFuZG9tLWFjY2VzcyBhdCBleHBlbnNlIG9mIGxhcmdlciBpbmRpY2VzIChtb3JlIG1lbW9yeSBjb25zdW1wdGlvbikuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JMT0NLU0laRSA9IEhGaWxlLkRFRkFVTFRfQkxPQ0tTSVpFOworCisgIC8qKgorICAgKiBEZWZhdWx0IHNldHRpbmcgZm9yIHdoZXRoZXIgb3Igbm90IHRvIHVzZSBibG9vbWZpbHRlcnMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVGQVVMVF9CTE9PTUZJTFRFUiA9IGZhbHNlOworICAKKyAgLyoqCisgICAqIERlZmF1bHQgdGltZSB0byBsaXZlIG9mIGNlbGwgY29udGVudHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1RUTCA9IEhDb25zdGFudHMuRk9SRVZFUjsKKworICAvLyBDb2x1bW4gZmFtaWx5IG5hbWUKKyAgcHJpdmF0ZSBieXRlIFtdIG5hbWU7CisKKyAgLy8gQ29sdW1uIG1ldGFkYXRhCisgIHByb3RlY3RlZCBNYXA8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSxJbW11dGFibGVCeXRlc1dyaXRhYmxlPiB2YWx1ZXMgPQorICAgIG5ldyBIYXNoTWFwPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4oKTsKKworICAvKgorICAgKiBDYWNoZSB0aGUgbWF4IHZlcnNpb25zIHJhdGhlciB0aGFuIGNhbGN1bGF0ZSBpdCBldmVyeSB0aW1lLgorICAgKi8KKyAgcHJpdmF0ZSBpbnQgY2FjaGVkTWF4VmVyc2lvbnMgPSAtMTsKKworICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gTXVzdCBiZSBwcmVzZW50IGZvciBXcml0YWJsZS4KKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvcigpIHsKKyAgICB0aGlzLm5hbWUgPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIGNvbHVtbiBkZXNjcmlwdG9yIHNwZWNpZnlpbmcgb25seSB0aGUgZmFtaWx5IG5hbWUgCisgICAqIFRoZSBvdGhlciBhdHRyaWJ1dGVzIGFyZSBkZWZhdWx0ZWQuCisgICAqIAorICAgKiBAcGFyYW0gZmFtaWx5TmFtZSBDb2x1bW4gZmFtaWx5IG5hbWUuIE11c3QgYmUgJ3ByaW50YWJsZScgLS0gZGlnaXQgb3IKKyAgICogbGV0dGVyIC0tIGFuZCBlbmQgaW4gYSA8Y29kZT46PGNvZGU+CisgICAqLworICBwdWJsaWMgSENvbHVtbkRlc2NyaXB0b3IoZmluYWwgU3RyaW5nIGZhbWlseU5hbWUpIHsKKyAgICB0aGlzKEJ5dGVzLnRvQnl0ZXMoZmFtaWx5TmFtZSkpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0IGEgY29sdW1uIGRlc2NyaXB0b3Igc3BlY2lmeWluZyBvbmx5IHRoZSBmYW1pbHkgbmFtZSAKKyAgICogVGhlIG90aGVyIGF0dHJpYnV0ZXMgYXJlIGRlZmF1bHRlZC4KKyAgICogCisgICAqIEBwYXJhbSBmYW1pbHlOYW1lIENvbHVtbiBmYW1pbHkgbmFtZS4gTXVzdCBiZSAncHJpbnRhYmxlJyAtLSBkaWdpdCBvcgorICAgKiBsZXR0ZXIgLS0gYW5kIGVuZCBpbiBhIDxjb2RlPjo8Y29kZT4KKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvcihmaW5hbCBieXRlIFtdIGZhbWlseU5hbWUpIHsKKyAgICB0aGlzIChmYW1pbHlOYW1lID09IG51bGwgfHwgZmFtaWx5TmFtZS5sZW5ndGggPD0gMD8KKyAgICAgIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWTogZmFtaWx5TmFtZSwgREVGQVVMVF9WRVJTSU9OUywKKyAgICAgIERFRkFVTFRfQ09NUFJFU1NJT04sIERFRkFVTFRfSU5fTUVNT1JZLCBERUZBVUxUX0JMT0NLQ0FDSEUsCisgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgREVGQVVMVF9UVEwsIGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3Rvci4KKyAgICogTWFrZXMgYSBkZWVwIGNvcHkgb2YgdGhlIHN1cHBsaWVkIGRlc2NyaXB0b3IuIAorICAgKiBDYW4gbWFrZSBhIG1vZGlmaWFibGUgZGVzY3JpcHRvciBmcm9tIGFuIFVubW9kaWZ5YWJsZUhDb2x1bW5EZXNjcmlwdG9yLgorICAgKiBAcGFyYW0gZGVzYyBUaGUgZGVzY3JpcHRvci4KKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvcihIQ29sdW1uRGVzY3JpcHRvciBkZXNjKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLm5hbWUgPSBkZXNjLm5hbWUuY2xvbmUoKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBJbW11dGFibGVCeXRlc1dyaXRhYmxlPiBlOgorICAgICAgICBkZXNjLnZhbHVlcy5lbnRyeVNldCgpKSB7CisgICAgICB0aGlzLnZhbHVlcy5wdXQoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIGZhbWlseU5hbWUgQ29sdW1uIGZhbWlseSBuYW1lLiBNdXN0IGJlICdwcmludGFibGUnIC0tIGRpZ2l0IG9yCisgICAqIGxldHRlciAtLSBhbmQgZW5kIGluIGEgPGNvZGU+Ojxjb2RlPgorICAgKiBAcGFyYW0gbWF4VmVyc2lvbnMgTWF4aW11bSBudW1iZXIgb2YgdmVyc2lvbnMgdG8ga2VlcAorICAgKiBAcGFyYW0gY29tcHJlc3Npb24gQ29tcHJlc3Npb24gdHlwZQorICAgKiBAcGFyYW0gaW5NZW1vcnkgSWYgdHJ1ZSwgY29sdW1uIGRhdGEgc2hvdWxkIGJlIGtlcHQgaW4gYW4gSFJlZ2lvblNlcnZlcidzCisgICAqIGNhY2hlCisgICAqIEBwYXJhbSBibG9ja0NhY2hlRW5hYmxlZCBJZiB0cnVlLCBNYXBGaWxlIGJsb2NrcyBzaG91bGQgYmUgY2FjaGVkCisgICAqIEBwYXJhbSBtYXhWYWx1ZUxlbmd0aCBSZXN0cmljdCB2YWx1ZXMgdG8gJmx0Oz0gdGhpcyB2YWx1ZQorICAgKiBAcGFyYW0gdGltZVRvTGl2ZSBUaW1lLXRvLWxpdmUgb2YgY2VsbCBjb250ZW50cywgaW4gc2Vjb25kcworICAgKiAodXNlIEhDb25zdGFudHMuRk9SRVZFUiBmb3IgdW5saW1pdGVkIFRUTCkKKyAgICogQHBhcmFtIGJsb29tRmlsdGVyIEVuYWJsZSB0aGUgc3BlY2lmaWVkIGJsb29tIGZpbHRlciBmb3IgdGhpcyBjb2x1bW4KKyAgICogCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBhc3NlZCBhIGZhbWlseSBuYW1lIHRoYXQgaXMgbWFkZSBvZiAKKyAgICogb3RoZXIgdGhhbiAnd29yZCcgY2hhcmFjdGVyczogaS5lLiA8Y29kZT5bYS16QS1aXzAtOV08L2NvZGU+IGFuZCBkb2VzIG5vdAorICAgKiBlbmQgaW4gYSA8Y29kZT46PC9jb2RlPgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbnVtYmVyIG9mIHZlcnNpb25zIGlzICZsdDs9IDAKKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvcihmaW5hbCBieXRlIFtdIGZhbWlseU5hbWUsIGZpbmFsIGludCBtYXhWZXJzaW9ucywKKyAgICAgIGZpbmFsIFN0cmluZyBjb21wcmVzc2lvbiwgZmluYWwgYm9vbGVhbiBpbk1lbW9yeSwKKyAgICAgIGZpbmFsIGJvb2xlYW4gYmxvY2tDYWNoZUVuYWJsZWQsIGZpbmFsIGludCBtYXhWYWx1ZUxlbmd0aCwKKyAgICAgIGZpbmFsIGludCB0aW1lVG9MaXZlLCBmaW5hbCBib29sZWFuIGJsb29tRmlsdGVyKSB7CisgICAgdGhpcyhmYW1pbHlOYW1lLCBtYXhWZXJzaW9ucywgY29tcHJlc3Npb24sIGluTWVtb3J5LCBibG9ja0NhY2hlRW5hYmxlZCwKKyAgICAgIERFRkFVTFRfQkxPQ0tTSVpFLCBtYXhWYWx1ZUxlbmd0aCwgdGltZVRvTGl2ZSwgYmxvb21GaWx0ZXIpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBmYW1pbHlOYW1lIENvbHVtbiBmYW1pbHkgbmFtZS4gTXVzdCBiZSAncHJpbnRhYmxlJyAtLSBkaWdpdCBvcgorICAgKiBsZXR0ZXIgLS0gYW5kIGVuZCBpbiBhIDxjb2RlPjo8Y29kZT4KKyAgICogQHBhcmFtIG1heFZlcnNpb25zIE1heGltdW0gbnVtYmVyIG9mIHZlcnNpb25zIHRvIGtlZXAKKyAgICogQHBhcmFtIGNvbXByZXNzaW9uIENvbXByZXNzaW9uIHR5cGUKKyAgICogQHBhcmFtIGluTWVtb3J5IElmIHRydWUsIGNvbHVtbiBkYXRhIHNob3VsZCBiZSBrZXB0IGluIGFuIEhSZWdpb25TZXJ2ZXIncworICAgKiBjYWNoZQorICAgKiBAcGFyYW0gYmxvY2tDYWNoZUVuYWJsZWQgSWYgdHJ1ZSwgTWFwRmlsZSBibG9ja3Mgc2hvdWxkIGJlIGNhY2hlZAorICAgKiBAcGFyYW0gYmxvY2tzaXplCisgICAqIEBwYXJhbSBtYXhWYWx1ZUxlbmd0aCBSZXN0cmljdCB2YWx1ZXMgdG8gJmx0Oz0gdGhpcyB2YWx1ZQorICAgKiBAcGFyYW0gdGltZVRvTGl2ZSBUaW1lLXRvLWxpdmUgb2YgY2VsbCBjb250ZW50cywgaW4gc2Vjb25kcworICAgKiAodXNlIEhDb25zdGFudHMuRk9SRVZFUiBmb3IgdW5saW1pdGVkIFRUTCkKKyAgICogQHBhcmFtIGJsb29tRmlsdGVyIEVuYWJsZSB0aGUgc3BlY2lmaWVkIGJsb29tIGZpbHRlciBmb3IgdGhpcyBjb2x1bW4KKyAgICogCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBhc3NlZCBhIGZhbWlseSBuYW1lIHRoYXQgaXMgbWFkZSBvZiAKKyAgICogb3RoZXIgdGhhbiAnd29yZCcgY2hhcmFjdGVyczogaS5lLiA8Y29kZT5bYS16QS1aXzAtOV08L2NvZGU+IGFuZCBkb2VzIG5vdAorICAgKiBlbmQgaW4gYSA8Y29kZT46PC9jb2RlPgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbnVtYmVyIG9mIHZlcnNpb25zIGlzICZsdDs9IDAKKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvcihmaW5hbCBieXRlIFtdIGZhbWlseU5hbWUsIGZpbmFsIGludCBtYXhWZXJzaW9ucywKKyAgICAgIGZpbmFsIFN0cmluZyBjb21wcmVzc2lvbiwgZmluYWwgYm9vbGVhbiBpbk1lbW9yeSwKKyAgICAgIGZpbmFsIGJvb2xlYW4gYmxvY2tDYWNoZUVuYWJsZWQsIGZpbmFsIGludCBibG9ja3NpemUsCisgICAgICBmaW5hbCBpbnQgbWF4VmFsdWVMZW5ndGgsCisgICAgICBmaW5hbCBpbnQgdGltZVRvTGl2ZSwgZmluYWwgYm9vbGVhbiBibG9vbUZpbHRlcikgeworICAgIGlzTGVnYWxGYW1pbHlOYW1lKGZhbWlseU5hbWUpOworICAgIHRoaXMubmFtZSA9IHN0cmlwQ29sb24oZmFtaWx5TmFtZSk7CisgICAgaWYgKG1heFZlcnNpb25zIDw9IDApIHsKKyAgICAgIC8vIFRPRE86IEFsbG93IG1heFZlcnNpb24gb2YgMCB0byBiZSB0aGUgd2F5IHlvdSBzYXkgIktlZXAgYWxsIHZlcnNpb25zIi4KKyAgICAgIC8vIFVudGlsIHRoZXJlIGlzIHN1cHBvcnQsIGNvbnNpZGVyIDAgb3IgPCAwIC0tIGEgY29uZmlndXJhdGlvbiBlcnJvci4KKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1heGltdW0gdmVyc2lvbnMgbXVzdCBiZSBwb3NpdGl2ZSIpOworICAgIH0KKyAgICBzZXRNYXhWZXJzaW9ucyhtYXhWZXJzaW9ucyk7CisgICAgc2V0SW5NZW1vcnkoaW5NZW1vcnkpOworICAgIHNldEJsb2NrQ2FjaGVFbmFibGVkKGJsb2NrQ2FjaGVFbmFibGVkKTsKKyAgICBzZXRNYXhWYWx1ZUxlbmd0aChtYXhWYWx1ZUxlbmd0aCk7CisgICAgc2V0VGltZVRvTGl2ZSh0aW1lVG9MaXZlKTsKKyAgICBzZXRDb21wcmVzc2lvblR5cGUoQ29tcHJlc3Npb24uQWxnb3JpdGhtLgorICAgICAgdmFsdWVPZihjb21wcmVzc2lvbi50b1VwcGVyQ2FzZSgpKSk7CisgICAgc2V0Qmxvb21maWx0ZXIoYmxvb21GaWx0ZXIpOworICAgIHNldEJsb2Nrc2l6ZShibG9ja3NpemUpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgYnl0ZSBbXSBzdHJpcENvbG9uKGZpbmFsIGJ5dGUgW10gbikgeworICAgIGJ5dGUgW10gcmVzdWx0ID0gbmV3IGJ5dGUgW24ubGVuZ3RoIC0gMV07CisgICAgLy8gSGF2ZSB0aGUgc3RvcmVkIGZhbWlseSBuYW1lIGJlIGFic2VudCB0aGUgY29sb24gZGVsaW1pdGVyCisgICAgU3lzdGVtLmFycmF5Y29weShuLCAwLCByZXN1bHQsIDAsIG4ubGVuZ3RoIC0gMSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYiBGYW1pbHkgbmFtZS4KKyAgICogQHJldHVybiA8Y29kZT5iPC9jb2RlPgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiBub3QgbnVsbCBhbmQgbm90IGEgbGVnaXRpbWF0ZSBmYW1pbHkKKyAgICogbmFtZTogaS5lLiAncHJpbnRhYmxlJyBhbmQgZW5kcyBpbiBhICc6JyAoTnVsbCBwYXNzZXMgYXJlIGFsbG93ZWQgYmVjYXVzZQorICAgKiA8Y29kZT5iPC9jb2RlPiBjYW4gYmUgbnVsbCB3aGVuIGRlc2VyaWFsaXppbmcpLiAgQ2Fubm90IHN0YXJ0IHdpdGggYSAnLicKKyAgICogZWl0aGVyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGlzTGVnYWxGYW1pbHlOYW1lKGZpbmFsIGJ5dGUgW10gYikgeworICAgIGlmIChiID09IG51bGwpIHsKKyAgICAgIHJldHVybiBiOworICAgIH0KKyAgICBpZiAoYltiLmxlbmd0aCAtIDFdICE9ICc6JykgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmFtaWx5IG5hbWVzIG11c3QgZW5kIGluIGEgY29sb246ICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhiKSk7CisgICAgfQorICAgIGlmIChiWzBdID09ICcuJykgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmFtaWx5IG5hbWVzIGNhbm5vdCBzdGFydCB3aXRoIGEgIiArCisgICAgICAgICJwZXJpb2Q6ICIgKyBCeXRlcy50b1N0cmluZyhiKSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGIubGVuZ3RoIC0gMSk7IGkrKykgeworICAgICAgaWYgKENoYXJhY3Rlci5pc0lTT0NvbnRyb2woYltpXSkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBjaGFyYWN0ZXIgPCIgKyBiW2ldICsKKyAgICAgICAgICAiPi4gRmFtaWx5IG5hbWVzIGNhbm5vdCBjb250YWluIGNvbnRyb2wgY2hhcmFjdGVyczogIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcoYikpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gYjsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIE5hbWUgb2YgdGhpcyBjb2x1bW4gZmFtaWx5CisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXROYW1lKCkgeworICAgIHJldHVybiBuYW1lOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gTmFtZSBvZiB0aGlzIGNvbHVtbiBmYW1pbHkgd2l0aCBjb2xvbiBhcyByZXF1aXJlZCBieSBjbGllbnQgQVBJCisgICAqLworICBAVE9KU09OKGZpZWxkTmFtZSA9ICJuYW1lIiwgYmFzZTY0PXRydWUpCisgIHB1YmxpYyBieXRlIFtdIGdldE5hbWVXaXRoQ29sb24oKSB7CisgICAgcmV0dXJuIEhTdG9yZUtleS5hZGREZWxpbWl0ZXIodGhpcy5uYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIE5hbWUgb2YgdGhpcyBjb2x1bW4gZmFtaWx5CisgICAqLworICBwdWJsaWMgU3RyaW5nIGdldE5hbWVBc1N0cmluZygpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcodGhpcy5uYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkuCisgICAqIEByZXR1cm4gVGhlIHZhbHVlLgorICAgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRWYWx1ZShieXRlW10ga2V5KSB7CisgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBpYncgPSB2YWx1ZXMuZ2V0KG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKGtleSkpOworICAgIGlmIChpYncgPT0gbnVsbCkKKyAgICAgIHJldHVybiBudWxsOworICAgIHJldHVybiBpYncuZ2V0KCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGtleSBUaGUga2V5LgorICAgKiBAcmV0dXJuIFRoZSB2YWx1ZSBhcyBhIHN0cmluZy4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIGtleSkgeworICAgIGJ5dGVbXSB2YWx1ZSA9IGdldFZhbHVlKEJ5dGVzLnRvQnl0ZXMoa2V5KSk7CisgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICByZXR1cm4gbnVsbDsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcodmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gQWxsIHZhbHVlcy4KKyAgICovCisgIHB1YmxpYyBNYXA8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSxJbW11dGFibGVCeXRlc1dyaXRhYmxlPiBnZXRWYWx1ZXMoKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcCh2YWx1ZXMpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXkgVGhlIGtleS4KKyAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGJ5dGVbXSBrZXksIGJ5dGVbXSB2YWx1ZSkgeworICAgIHZhbHVlcy5wdXQobmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoa2V5KSwKKyAgICAgIG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKHZhbHVlKSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGtleSBUaGUga2V5LgorICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0VmFsdWUoU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgc2V0VmFsdWUoQnl0ZXMudG9CeXRlcyhrZXkpLCBCeXRlcy50b0J5dGVzKHZhbHVlKSk7CisgIH0KKworICAvKiogQHJldHVybiBjb21wcmVzc2lvbiB0eXBlIGJlaW5nIHVzZWQgZm9yIHRoZSBjb2x1bW4gZmFtaWx5ICovCisgIEBUT0pTT04KKyAgcHVibGljIENvbXByZXNzaW9uLkFsZ29yaXRobSBnZXRDb21wcmVzc2lvbigpIHsKKyAgICByZXR1cm4gQ29tcHJlc3Npb24uQWxnb3JpdGhtLnZhbHVlT2YoZ2V0VmFsdWUoQ09NUFJFU1NJT04pKTsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gbWF4aW11bSBudW1iZXIgb2YgdmVyc2lvbnMgKi8KKyAgQFRPSlNPTgorICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRNYXhWZXJzaW9ucygpIHsKKyAgICBpZiAodGhpcy5jYWNoZWRNYXhWZXJzaW9ucyA9PSAtMSkgeworICAgICAgU3RyaW5nIHZhbHVlID0gZ2V0VmFsdWUoSENvbnN0YW50cy5WRVJTSU9OUyk7CisgICAgICB0aGlzLmNhY2hlZE1heFZlcnNpb25zID0gKHZhbHVlICE9IG51bGwpPworICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodmFsdWUpLmludFZhbHVlKCk6IERFRkFVTFRfVkVSU0lPTlM7CisgICAgfQorICAgIHJldHVybiB0aGlzLmNhY2hlZE1heFZlcnNpb25zOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBtYXhWZXJzaW9ucyBtYXhpbXVtIG51bWJlciBvZiB2ZXJzaW9ucworICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TWF4VmVyc2lvbnMoaW50IG1heFZlcnNpb25zKSB7CisgICAgc2V0VmFsdWUoSENvbnN0YW50cy5WRVJTSU9OUywgSW50ZWdlci50b1N0cmluZyhtYXhWZXJzaW9ucykpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gQmxvY2tzaXplLgorICAgKi8KKyAgQFRPSlNPTgorICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRCbG9ja3NpemUoKSB7CisgICAgaWYgKHRoaXMuYmxvY2tzaXplID09IG51bGwpIHsKKyAgICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKEJMT0NLU0laRSk7CisgICAgICB0aGlzLmJsb2Nrc2l6ZSA9ICh2YWx1ZSAhPSBudWxsKT8KKyAgICAgICAgSW50ZWdlci5kZWNvZGUodmFsdWUpOiBJbnRlZ2VyLnZhbHVlT2YoREVGQVVMVF9CTE9DS1NJWkUpOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5ibG9ja3NpemUuaW50VmFsdWUoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcworICAgKi8KKyAgcHVibGljIHZvaWQgc2V0QmxvY2tzaXplKGludCBzKSB7CisgICAgc2V0VmFsdWUoQkxPQ0tTSVpFLCBJbnRlZ2VyLnRvU3RyaW5nKHMpKTsKKyAgICB0aGlzLmJsb2Nrc2l6ZSA9IG51bGw7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDb21wcmVzc2lvbiB0eXBlIHNldHRpbmcuCisgICAqLworICBAVE9KU09OCisgIHB1YmxpYyBDb21wcmVzc2lvbi5BbGdvcml0aG0gZ2V0Q29tcHJlc3Npb25UeXBlKCkgeworICAgIHJldHVybiBnZXRDb21wcmVzc2lvbigpOworICB9CisKKyAgLyoqCisgICAqIENvbXByZXNzaW9uIHR5cGVzIHN1cHBvcnRlZCBpbiBoYmFzZS4KKyAgICogTFpPIGlzIG5vdCBidW5kbGVkIGFzIHBhcnQgb2YgdGhlIGhiYXNlIGRpc3RyaWJ1dGlvbi4KKyAgICogU2VlIDxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL1VzaW5nTHpvQ29tcHJlc3Npb24iPkxaTyBDb21wcmVzc2lvbjwvYT4KKyAgICogZm9yIGhvdyB0byBlbmFibGUgaXQuCisgICAqIEBwYXJhbSB0eXBlIENvbXByZXNzaW9uIHR5cGUgc2V0dGluZy4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldENvbXByZXNzaW9uVHlwZShDb21wcmVzc2lvbi5BbGdvcml0aG0gdHlwZSkgeworICAgIFN0cmluZyBjb21wcmVzc2lvblR5cGU7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIExaTzogY29tcHJlc3Npb25UeXBlID0gIkxaTyI7IGJyZWFrOworICAgICAgY2FzZSBHWjogY29tcHJlc3Npb25UeXBlID0gIkdaIjsgYnJlYWs7CisgICAgICBkZWZhdWx0OiBjb21wcmVzc2lvblR5cGUgPSAiTk9ORSI7IGJyZWFrOworICAgIH0KKyAgICBzZXRWYWx1ZShDT01QUkVTU0lPTiwgY29tcHJlc3Npb25UeXBlKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRydWUgaWYgd2UgYXJlIHRvIGtlZXAgYWxsIGluIHVzZSBIUmVnaW9uU2VydmVyIGNhY2hlLgorICAgKi8KKyAgQFRPSlNPTihwcmVmaXhMZW5ndGggPSAyKQorICBwdWJsaWMgYm9vbGVhbiBpc0luTWVtb3J5KCkgeworICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKEhDb25zdGFudHMuSU5fTUVNT1JZKTsKKyAgICBpZiAodmFsdWUgIT0gbnVsbCkKKyAgICAgIHJldHVybiBCb29sZWFuLnZhbHVlT2YodmFsdWUpLmJvb2xlYW5WYWx1ZSgpOworICAgIHJldHVybiBERUZBVUxUX0lOX01FTU9SWTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBpbk1lbW9yeSBUcnVlIGlmIHdlIGFyZSB0byBrZWVwIGFsbCB2YWx1ZXMgaW4gdGhlIEhSZWdpb25TZXJ2ZXIKKyAgICogY2FjaGUKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEluTWVtb3J5KGJvb2xlYW4gaW5NZW1vcnkpIHsKKyAgICBzZXRWYWx1ZShIQ29uc3RhbnRzLklOX01FTU9SWSwgQm9vbGVhbi50b1N0cmluZyhpbk1lbW9yeSkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gTWF4aW11bSB2YWx1ZSBsZW5ndGguCisgICAqLworICBAVE9KU09OCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGdldE1heFZhbHVlTGVuZ3RoKCkgeworICAgIGlmICh0aGlzLm1heFZhbHVlTGVuZ3RoID09IG51bGwpIHsKKyAgICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKExFTkdUSCk7CisgICAgICB0aGlzLm1heFZhbHVlTGVuZ3RoID0gKHZhbHVlICE9IG51bGwpPworICAgICAgICBJbnRlZ2VyLmRlY29kZSh2YWx1ZSk6IERFRkFVTFRfTEVOR1RIX0lOVEVHRVI7CisgICAgfQorICAgIHJldHVybiB0aGlzLm1heFZhbHVlTGVuZ3RoLmludFZhbHVlKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG1heExlbmd0aCBNYXhpbXVtIHZhbHVlIGxlbmd0aC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldE1heFZhbHVlTGVuZ3RoKGludCBtYXhMZW5ndGgpIHsKKyAgICBzZXRWYWx1ZShMRU5HVEgsIEludGVnZXIudG9TdHJpbmcobWF4TGVuZ3RoKSk7CisgICAgdGhpcy5tYXhWYWx1ZUxlbmd0aCA9IG51bGw7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBUaW1lLXRvLWxpdmUgb2YgY2VsbCBjb250ZW50cywgaW4gc2Vjb25kcy4KKyAgICovCisgIEBUT0pTT04KKyAgcHVibGljIGludCBnZXRUaW1lVG9MaXZlKCkgeworICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKFRUTCk7CisgICAgcmV0dXJuICh2YWx1ZSAhPSBudWxsKT8gSW50ZWdlci52YWx1ZU9mKHZhbHVlKS5pbnRWYWx1ZSgpOiBERUZBVUxUX1RUTDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdGltZVRvTGl2ZSBUaW1lLXRvLWxpdmUgb2YgY2VsbCBjb250ZW50cywgaW4gc2Vjb25kcy4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFRpbWVUb0xpdmUoaW50IHRpbWVUb0xpdmUpIHsKKyAgICBzZXRWYWx1ZShUVEwsIEludGVnZXIudG9TdHJpbmcodGltZVRvTGl2ZSkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBNYXBGaWxlIGJsb2NrcyBzaG91bGQgYmUgY2FjaGVkLgorICAgKi8KKyAgQFRPSlNPTihwcmVmaXhMZW5ndGggPSAyKQorICBwdWJsaWMgYm9vbGVhbiBpc0Jsb2NrQ2FjaGVFbmFibGVkKCkgeworICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKEJMT0NLQ0FDSEUpOworICAgIGlmICh2YWx1ZSAhPSBudWxsKQorICAgICAgcmV0dXJuIEJvb2xlYW4udmFsdWVPZih2YWx1ZSkuYm9vbGVhblZhbHVlKCk7CisgICAgcmV0dXJuIERFRkFVTFRfQkxPQ0tDQUNIRTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYmxvY2tDYWNoZUVuYWJsZWQgVHJ1ZSBpZiBNYXBGaWxlIGJsb2NrcyBzaG91bGQgYmUgY2FjaGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0QmxvY2tDYWNoZUVuYWJsZWQoYm9vbGVhbiBibG9ja0NhY2hlRW5hYmxlZCkgeworICAgIHNldFZhbHVlKEJMT0NLQ0FDSEUsIEJvb2xlYW4udG9TdHJpbmcoYmxvY2tDYWNoZUVuYWJsZWQpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRydWUgaWYgYSBibG9vbSBmaWx0ZXIgaXMgZW5hYmxlZAorICAgKi8KKyAgQFRPSlNPTihwcmVmaXhMZW5ndGggPSAyKQorICBwdWJsaWMgYm9vbGVhbiBpc0Jsb29tZmlsdGVyKCkgeworICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKEJMT09NRklMVEVSKTsKKyAgICBpZiAodmFsdWUgIT0gbnVsbCkKKyAgICAgIHJldHVybiBCb29sZWFuLnZhbHVlT2YodmFsdWUpLmJvb2xlYW5WYWx1ZSgpOworICAgIHJldHVybiBERUZBVUxUX0JMT09NRklMVEVSOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBvbk9mZiBFbmFibGUvRGlzYWJsZSBibG9vbSBmaWx0ZXIKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEJsb29tZmlsdGVyKGZpbmFsIGJvb2xlYW4gb25PZmYpIHsKKyAgICBzZXRWYWx1ZShCTE9PTUZJTFRFUiwgQm9vbGVhbi50b1N0cmluZyhvbk9mZikpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBpbnRlcnZhbCBUaGUgbnVtYmVyIG9mIGVudHJpZXMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIHN0b3JlIE1hcEZpbGUgYmVmb3JlCisgICAqIGFuIGluZGV4IGVudHJ5IGlzIGFkZGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TWFwRmlsZUluZGV4SW50ZXJ2YWwoaW50IGludGVydmFsKSB7CisgICAgc2V0VmFsdWUoTUFQRklMRV9JTkRFWF9JTlRFUlZBTCwgSW50ZWdlci50b1N0cmluZyhpbnRlcnZhbCkpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICBTdHJpbmdCdWZmZXIgcyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICBzLmFwcGVuZCgneycpOworICAgIHMuYXBwZW5kKEhDb25zdGFudHMuTkFNRSk7CisgICAgcy5hcHBlbmQoIiA9PiAnIik7CisgICAgcy5hcHBlbmQoQnl0ZXMudG9TdHJpbmcobmFtZSkpOworICAgIHMuYXBwZW5kKCInIik7CisgICAgZm9yIChNYXAuRW50cnk8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gZToKKyAgICAgICAgdmFsdWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgIFN0cmluZyBrZXkgPSBCeXRlcy50b1N0cmluZyhlLmdldEtleSgpLmdldCgpKTsKKyAgICAgIFN0cmluZyB2YWx1ZSA9IEJ5dGVzLnRvU3RyaW5nKGUuZ2V0VmFsdWUoKS5nZXQoKSk7CisgICAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5LnRvVXBwZXJDYXNlKCkuZXF1YWxzKEJMT09NRklMVEVSKSkgeworICAgICAgICAvLyBEb24ndCBlbWl0IGJsb29tZmlsdGVyLiAgSXRzIG5vdCB3b3JraW5nLgorICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIHMuYXBwZW5kKCIsICIpOworICAgICAgcy5hcHBlbmQoa2V5KTsKKyAgICAgIHMuYXBwZW5kKCIgPT4gJyIpOworICAgICAgcy5hcHBlbmQodmFsdWUpOworICAgICAgcy5hcHBlbmQoIiciKTsKKyAgICB9CisgICAgcy5hcHBlbmQoJ30nKTsKKyAgICByZXR1cm4gcy50b1N0cmluZygpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgIGlmICh0aGlzID09IG9iaikgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGlmIChvYmogPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBIQ29sdW1uRGVzY3JpcHRvcikpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIGNvbXBhcmVUbygoSENvbHVtbkRlc2NyaXB0b3Ipb2JqKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuaGFzaENvZGUodGhpcy5uYW1lKTsKKyAgICByZXN1bHQgXj0gQnl0ZS52YWx1ZU9mKENPTFVNTl9ERVNDUklQVE9SX1ZFUlNJT04pLmhhc2hDb2RlKCk7CisgICAgcmVzdWx0IF49IHZhbHVlcy5oYXNoQ29kZSgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8vIFdyaXRhYmxlCisKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IHZlcnNpb24gPSBpbi5yZWFkQnl0ZSgpOworICAgIGlmICh2ZXJzaW9uIDwgNikgeworICAgICAgaWYgKHZlcnNpb24gPD0gMikgeworICAgICAgICBUZXh0IHQgPSBuZXcgVGV4dCgpOworICAgICAgICB0LnJlYWRGaWVsZHMoaW4pOworICAgICAgICB0aGlzLm5hbWUgPSB0LmdldEJ5dGVzKCk7CisgICAgICAgIGlmIChIU3RvcmVLZXkuZ2V0RmFtaWx5RGVsaW1pdGVySW5kZXgodGhpcy5uYW1lKSA+IDApIHsKKyAgICAgICAgICB0aGlzLm5hbWUgPSBzdHJpcENvbG9uKHRoaXMubmFtZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRoaXMubmFtZSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgICAgfQorICAgICAgdGhpcy52YWx1ZXMuY2xlYXIoKTsKKyAgICAgIHNldE1heFZlcnNpb25zKGluLnJlYWRJbnQoKSk7CisgICAgICBpbnQgb3JkaW5hbCA9IGluLnJlYWRJbnQoKTsKKyAgICAgIHNldENvbXByZXNzaW9uVHlwZShDb21wcmVzc2lvbi5BbGdvcml0aG0udmFsdWVzKClbb3JkaW5hbF0pOworICAgICAgc2V0SW5NZW1vcnkoaW4ucmVhZEJvb2xlYW4oKSk7CisgICAgICBzZXRNYXhWYWx1ZUxlbmd0aChpbi5yZWFkSW50KCkpOworICAgICAgc2V0Qmxvb21maWx0ZXIoaW4ucmVhZEJvb2xlYW4oKSk7CisgICAgICBpZiAoaXNCbG9vbWZpbHRlcigpICYmIHZlcnNpb24gPCA1KSB7CisgICAgICAgIC8vIElmIGEgYmxvb21GaWx0ZXIgaXMgZW5hYmxlZCBhbmQgdGhlIGNvbHVtbiBkZXNjcmlwdG9yIGlzIGxlc3MgdGhhbgorICAgICAgICAvLyB2ZXJzaW9uIDUsIHdlIG5lZWQgdG8gc2tpcCBvdmVyIGl0IHRvIHJlYWQgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbgorICAgICAgICAvLyBkZXNjcmlwdG9yLiBUaGVyZSBhcmUgbm8gQmxvb21GaWx0ZXJEZXNjcmlwdG9ycyB3cml0dGVuIHRvIGRpc2sgZm9yCisgICAgICAgIC8vIGNvbHVtbiBkZXNjcmlwdG9ycyB3aXRoIGEgdmVyc2lvbiBudW1iZXIgPj0gNQorICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDbGFzc1ZlcnNpb25FcnJvcih0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICIgZG9lcyBub3Qgc3VwcG9ydCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggdmVyc2lvbnMgb2xkZXIgIiArCisgICAgICAgICAgICAidGhhbiB2ZXJzaW9uIDUiKTsKKyAgICAgIH0KKyAgICAgIGlmICh2ZXJzaW9uID4gMSkgeworICAgICAgICBzZXRCbG9ja0NhY2hlRW5hYmxlZChpbi5yZWFkQm9vbGVhbigpKTsKKyAgICAgIH0KKyAgICAgIGlmICh2ZXJzaW9uID4gMikgeworICAgICAgIHNldFRpbWVUb0xpdmUoaW4ucmVhZEludCgpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gdmVyc2lvbiA3KworICAgICAgdGhpcy5uYW1lID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgICB0aGlzLnZhbHVlcy5jbGVhcigpOworICAgICAgaW50IG51bVZhbHVlcyA9IGluLnJlYWRJbnQoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtVmFsdWVzOyBpKyspIHsKKyAgICAgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXkgPSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSgpOworICAgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHZhbHVlID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICAgICAga2V5LnJlYWRGaWVsZHMoaW4pOworICAgICAgICB2YWx1ZS5yZWFkRmllbGRzKGluKTsKKyAgICAgICAgdmFsdWVzLnB1dChrZXksIHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGlmICh2ZXJzaW9uID09IDYpIHsKKyAgICAgICAgLy8gQ29udmVydCBvbGQgdmFsdWVzLgorICAgICAgICBzZXRWYWx1ZShDT01QUkVTU0lPTiwgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUuZ2V0TmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGVCeXRlKENPTFVNTl9ERVNDUklQVE9SX1ZFUlNJT04pOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5uYW1lKTsKKyAgICBvdXQud3JpdGVJbnQodmFsdWVzLnNpemUoKSk7CisgICAgZm9yIChNYXAuRW50cnk8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gZToKKyAgICAgICAgdmFsdWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgIGUuZ2V0S2V5KCkud3JpdGUob3V0KTsKKyAgICAgIGUuZ2V0VmFsdWUoKS53cml0ZShvdXQpOworICAgIH0KKyAgfQorCisgIC8vIENvbXBhcmFibGUKKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhIQ29sdW1uRGVzY3JpcHRvciBvKSB7CisgICAgaW50IHJlc3VsdCA9IEJ5dGVzLmNvbXBhcmVUbyh0aGlzLm5hbWUsIG8uZ2V0TmFtZSgpKTsKKyAgICBpZiAocmVzdWx0ID09IDApIHsKKyAgICAgIC8vIHB1bnQgb24gY29tcGFyaXNvbiBmb3Igb3JkZXJpbmcsIGp1c3QgY2FsY3VsYXRlIGRpZmZlcmVuY2UKKyAgICAgIHJlc3VsdCA9IHRoaXMudmFsdWVzLmhhc2hDb2RlKCkgLSBvLnZhbHVlcy5oYXNoQ29kZSgpOworICAgICAgaWYgKHJlc3VsdCA8IDApCisgICAgICAgIHJlc3VsdCA9IC0xOworICAgICAgZWxzZSBpZiAocmVzdWx0ID4gMCkKKyAgICAgICAgcmVzdWx0ID0gMTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qIChub24tSmF2YWRvYykKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnhtbC5JT3V0cHV0WE1MI3RvWE1MKCkKKyAgICovCisgIHB1YmxpYyB2b2lkIHJlc3RTZXJpYWxpemUoSVJlc3RTZXJpYWxpemVyIHNlcmlhbGl6ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHNlcmlhbGl6ZXIuc2VyaWFsaXplQ29sdW1uRGVzY3JpcHRvcih0aGlzKTsgICAgCisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hDb25zdGFudHMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNzYyZDkxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSENvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsMjg4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEhDb25zdGFudHMgaG9sZHMgYSBidW5jaCBvZiBIQmFzZS1yZWxhdGVkIGNvbnN0YW50cworICovCitwdWJsaWMgaW50ZXJmYWNlIEhDb25zdGFudHMgeworCisgIC8qKiBsb25nIGNvbnN0YW50IGZvciB6ZXJvICovCisgIHN0YXRpYyBmaW5hbCBMb25nIFpFUk9fTCA9IExvbmcudmFsdWVPZigwTCk7CisKKyAgLy9UT0RPOiBOSU5FUyBpcyBvbmx5IHVzZWQgaW4gSEJhc2VBZG1pbiBhbmQgSENvbm5lY3Rpb25NYW5hZ2VyLiBNb3ZlIHRvIGNsaWVudAorICAvLyAgICAgIHBhY2thZ2UgYW5kIGNoYW5nZSB2aXNpYmlsaXR5IHRvIGRlZmF1bHQKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBOSU5FUyA9ICI5OTk5OTk5OTk5OTk5OSI7CisgIC8vVE9ETzogWkVST1MgaXMgb25seSB1c2VkIGluIEhDb25uZWN0aW9uTWFuYWdlciBhbmQgTWV0YVNjYW5uZXIuIE1vdmUgdG8KKyAgLy8gICAgICBjbGllbnQgcGFja2FnZSBhbmQgY2hhbmdlIHZpc2liaWxpdHkgdG8gZGVmYXVsdAorICBzdGF0aWMgZmluYWwgU3RyaW5nIFpFUk9FUyA9ICIwMDAwMDAwMDAwMDAwMCI7CisgIAorICAvLyBGb3IgbWlncmF0aW9uCisKKyAgLyoqIG5hbWUgb2YgdmVyc2lvbiBmaWxlICovCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTl9GSUxFX05BTUUgPSAiaGJhc2UudmVyc2lvbiI7CisgIAorICAvKioKKyAgICogQ3VycmVudCB2ZXJzaW9uIG9mIGZpbGUgc3lzdGVtLgorICAgKiBWZXJzaW9uIDQgc3VwcG9ydHMgb25seSBvbmUga2luZCBvZiBibG9vbSBmaWx0ZXIuCisgICAqIFZlcnNpb24gNSBjaGFuZ2VzIHZlcnNpb25zIGluIGNhdGFsb2cgdGFibGUgcmVnaW9ucy4KKyAgICogVmVyc2lvbiA2IGVuYWJsZXMgYmxvY2tjYWNoaW5nIG9uIGNhdGFsb2cgdGFibGVzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9TWVNURU1fVkVSU0lPTiA9ICI2IjsKKyAgCisgIC8vIENvbmZpZ3VyYXRpb24gcGFyYW1ldGVycworICAKKyAgLy8gVE9ETzogVVJMIGZvciBoYmFzZSBtYXN0ZXIgbGlrZSBoZGZzIFVSTHMgd2l0aCBob3N0IGFuZCBwb3J0LgorICAvLyBMaWtlIGpkYmMgVVJMcz8gIFVSTHMgY291bGQgYmUgdXNlZCB0byByZWZlciB0byB0YWJsZSBjZWxscz8KKyAgLy8gamRiYzpteXNxbDovL1tob3N0XVssZmFpbG92ZXJob3N0Li4uXVs6cG9ydF0vW2RhdGFiYXNlXQorICAvLyBqZGJjOm15c3FsOi8vW2hvc3RdWyxmYWlsb3Zlcmhvc3QuLi5dWzpwb3J0XS9bZGF0YWJhc2VdWz9wcm9wZXJ0eU5hbWUxXVs9cHJvcGVydHlWYWx1ZTFdWyZwcm9wZXJ0eU5hbWUyXVs9cHJvcGVydHlWYWx1ZTJdLi4uCisgIAorICAvLyBLZXkgaW50byBIQmFzZUNvbmZpZ3VyYXRpb24gZm9yIHRoZSBoYmFzZS5tYXN0ZXIgYWRkcmVzcy4KKyAgLy8gVE9ETzogU3VwcG9ydCAnbG9jYWwnOiBpLmUuIGRlZmF1bHQgb2YgYWxsIHJ1bm5pbmcgaW4gc2luZ2xlCisgIC8vIHByb2Nlc3MuICBTYW1lIGZvciByZWdpb25zZXJ2ZXIuIFRPRE86IElzIGhhdmluZyBIQmFzZSBob21lZAorICAvLyBvbiBwb3J0IDYwayBPSz8KKyAgCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3IgbWFzdGVyIGFkZHJlc3MgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBNQVNURVJfQUREUkVTUyA9ICJoYmFzZS5tYXN0ZXIiOworCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3IgbWFzdGVyIGhvc3QgbmFtZS4gKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBNQVNURVJfSE9TVF9OQU1FID0gImhiYXNlLm1hc3Rlci5ob3N0bmFtZSI7CisKKyAgLyoqIGRlZmF1bHQgaG9zdCBhZGRyZXNzICovCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9IT1NUID0gIjAuMC4wLjAiOworCisgIC8qKiBkZWZhdWx0IHBvcnQgdGhhdCB0aGUgbWFzdGVyIGxpc3RlbnMgb24gKi8KKyAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01BU1RFUl9QT1JUID0gNjAwMDA7CisKKyAgLyoqIGRlZmF1bHQgcG9ydCBmb3IgbWFzdGVyIHdlYiBhcGkgKi8KKyAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01BU1RFUl9JTkZPUE9SVCA9IDYwMDEwOworCisgIC8qKiBOYW1lIG9mIFpvb0tlZXBlciBjb25maWcgZmlsZSBpbiBjb25mLyBkaXJlY3RvcnkuICovCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgWk9PS0VFUEVSX0NPTkZJR19OQU1FID0gInpvby5jZmciOworCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3IgbnVtYmVyIG9mIHRpbWVzIHRvIHJldHJ5IHdyaXRlcyB0byBab29LZWVwZXIuICovCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgWk9PS0VFUEVSX1JFVFJJRVMgPSAiem9va2VlcGVyLnJldHJpZXMiOworICAvKiogRGVmYXVsdCBudW1iZXIgb2YgdGltZXMgdG8gcmV0cnkgd3JpdGVzIHRvIFpvb0tlZXBlci4gKi8KKyAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1pPT0tFRVBFUl9SRVRSSUVTID0gNTsKKworICAvKiogUGFyYW1ldGVyIG5hbWUgZm9yIFpvb0tlZXBlciBwYXVzZSBiZXR3ZWVuIHJldHJpZXMuIEluIG1pbGxpc2Vjb25kcy4gKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBaT09LRUVQRVJfUEFVU0UgPSAiem9va2VlcGVyLnBhdXNlIjsKKyAgLyoqIERlZmF1bHQgWm9vS2VlcGVyIHBhdXNlIHZhbHVlLiBJbiBtaWxsaXNlY29uZHMuICovCisgIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9aT09LRUVQRVJfUEFVU0UgPSAyICogMTAwMDsKKworICAvKiogUGFyYW1ldGVyIG5hbWUgZm9yIGhiYXNlLnJlZ2lvbnNlcnZlciBhZGRyZXNzLiAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIFJFR0lPTlNFUlZFUl9BRERSRVNTID0gImhiYXNlLnJlZ2lvbnNlcnZlciI7CisgIAorICAvKiogRGVmYXVsdCByZWdpb24gc2VydmVyIGFkZHJlc3MgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1JFR0lPTlNFUlZFUl9BRERSRVNTID0gREVGQVVMVF9IT1NUICsgIjo2MDAyMCI7CisKKyAgLyoqIGRlZmF1bHQgcG9ydCBmb3IgcmVnaW9uIHNlcnZlciB3ZWIgYXBpICovCisgIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9SRUdJT05TRVJWRVJfSU5GT1BPUlQgPSA2MDAzMDsKKworICAvKiogUGFyYW1ldGVyIG5hbWUgZm9yIHdoYXQgcmVnaW9uIHNlcnZlciBpbnRlcmZhY2UgdG8gdXNlLiAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIFJFR0lPTl9TRVJWRVJfQ0xBU1MgPSAiaGJhc2UucmVnaW9uc2VydmVyLmNsYXNzIjsKKyAgCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3Igd2hhdCByZWdpb24gc2VydmVyIGltcGxlbWVudGF0aW9uIHRvIHVzZS4gKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBSRUdJT05fU0VSVkVSX0lNUEw9ICJoYmFzZS5yZWdpb25zZXJ2ZXIuaW1wbCI7CisgIAorICAvKiogRGVmYXVsdCByZWdpb24gc2VydmVyIGludGVyZmFjZSBjbGFzcyBuYW1lLiAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUkVHSU9OX1NFUlZFUl9DTEFTUyA9IEhSZWdpb25JbnRlcmZhY2UuY2xhc3MuZ2V0TmFtZSgpOworCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3IgaG93IG9mdGVuIHRocmVhZHMgc2hvdWxkIHdha2UgdXAgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBUSFJFQURfV0FLRV9GUkVRVUVOQ1kgPSAiaGJhc2Uuc2VydmVyLnRocmVhZC53YWtlZnJlcXVlbmN5IjsKKyAgCisgIC8qKiBQYXJhbWV0ZXIgbmFtZSBmb3IgaG93IG9mdGVuIGEgcmVnaW9uIHNob3VsZCBzaG91bGQgcGVyZm9ybSBhIG1ham9yIGNvbXBhY3Rpb24gKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBNQUpPUl9DT01QQUNUSU9OX1BFUklPRCA9ICJoYmFzZS5ocmVnaW9uLm1ham9yY29tcGFjdGlvbiI7CisKKyAgLyoqIFBhcmFtZXRlciBuYW1lIGZvciBIQmFzZSBpbnN0YW5jZSByb290IGRpcmVjdG9yeSAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0RJUiA9ICJoYmFzZS5yb290ZGlyIjsKKyAgCisgIC8qKiBVc2VkIHRvIGNvbnN0cnVjdCB0aGUgbmFtZSBvZiB0aGUgbG9nIGRpcmVjdG9yeSBmb3IgYSByZWdpb24gc2VydmVyIAorICAgKiBVc2UgJy4nIGFzIGEgc3BlY2lhbCBjaGFyYWN0ZXIgdG8gc2VwZXJhdGUgdGhlIGxvZyBmaWxlcyBmcm9tIHRhYmxlIGRhdGEgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIUkVHSU9OX0xPR0RJUl9OQU1FID0gIi5sb2dzIjsKKworICAvKiogTmFtZSBvZiBvbGQgbG9nIGZpbGUgZm9yIHJlY29uc3RydWN0aW9uICovCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSFJFR0lPTl9PTERMT0dGSUxFX05BTUUgPSAib2xkbG9nZmlsZS5sb2ciOworICAKKyAgLyoqIFVzZWQgdG8gY29uc3RydWN0IHRoZSBuYW1lIG9mIHRoZSBjb21wYWN0aW9uIGRpcmVjdG9yeSBkdXJpbmcgY29tcGFjdGlvbiAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhSRUdJT05fQ09NUEFDVElPTkRJUl9OQU1FID0gImNvbXBhY3Rpb24uZGlyIjsKKyAgCisgIC8qKiBEZWZhdWx0IG1heGltdW0gZmlsZSBzaXplICovCisgIHN0YXRpYyBmaW5hbCBsb25nIERFRkFVTFRfTUFYX0ZJTEVfU0laRSA9IDI1NiAqIDEwMjQgKiAxMDI0OworICAKKyAgLyoqIERlZmF1bHQgc2l6ZSBvZiBhIHJlc2VydmF0aW9uIGJsb2NrICAgKi8KKyAgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NJWkVfUkVTRVJWQVRJT05fQkxPQ0sgPSAxMDI0ICogMTAyNCAqIDU7CisgIAorICAvLyBBbHdheXMgc3RvcmUgdGhlIGxvY2F0aW9uIG9mIHRoZSByb290IHRhYmxlJ3MgSFJlZ2lvbi4KKyAgLy8gVGhpcyBIUmVnaW9uIGlzIG5ldmVyIHNwbGl0LgorICAKKyAgLy8gcmVnaW9uIG5hbWUgPSB0YWJsZSArIHN0YXJ0a2V5ICsgcmVnaW9uaWQuIFRoaXMgaXMgdGhlIHJvdyBrZXkuCisgIC8vIGVhY2ggcm93IGluIHRoZSByb290IGFuZCBtZXRhIHRhYmxlcyBkZXNjcmliZXMgZXhhY3RseSAxIHJlZ2lvbgorICAvLyBEbyB3ZSBldmVyIG5lZWQgdG8ga25vdyBhbGwgdGhlIGluZm9ybWF0aW9uIHRoYXQgd2UgYXJlIHN0b3Jpbmc/CisKKyAgLy8gTm90ZSB0aGF0IHRoZSBuYW1lIG9mIHRoZSByb290IHRhYmxlIHN0YXJ0cyB3aXRoICItIiBhbmQgdGhlIG5hbWUgb2YgdGhlCisgIC8vIG1ldGEgdGFibGUgc3RhcnRzIHdpdGggIi4iIFdoeT8gaXQncyBhIHRyaWNrLiBJdCB0dXJucyBvdXQgdGhhdCB3aGVuIHdlCisgIC8vIHN0b3JlIHJlZ2lvbiBuYW1lcyBpbiBtZW1vcnksIHdlIHVzZSBhIFNvcnRlZE1hcC4gU2luY2UgIi0iIHNvcnRzIGJlZm9yZQorICAvLyAiLiIgKGFuZCBzaW5jZSBubyBvdGhlciB0YWJsZSBuYW1lIGNhbiBzdGFydCB3aXRoIGVpdGhlciBvZiB0aGVzZQorICAvLyBjaGFyYWN0ZXJzLCB0aGUgcm9vdCByZWdpb24gd2lsbCBhbHdheXMgYmUgdGhlIGZpcnN0IGVudHJ5IGluIHN1Y2ggYSBNYXAsCisgIC8vIGZvbGxvd2VkIGJ5IGFsbCB0aGUgbWV0YSByZWdpb25zICh3aGljaCB3aWxsIGJlIG9yZGVyZWQgYnkgdGhlaXIgc3RhcnRpbmcKKyAgLy8gcm93IGtleSBhcyB3ZWxsKSwgZm9sbG93ZWQgYnkgYWxsIHVzZXIgdGFibGVzLiBTbyB3aGVuIHRoZSBNYXN0ZXIgaXMgCisgIC8vIGNob29zaW5nIHJlZ2lvbnMgdG8gYXNzaWduLCBpdCB3aWxsIGFsd2F5cyBjaG9vc2UgdGhlIHJvb3QgcmVnaW9uIGZpcnN0LAorICAvLyBmb2xsb3dlZCBieSB0aGUgbWV0YSByZWdpb25zLCBmb2xsb3dlZCBieSB1c2VyIHJlZ2lvbnMuIFNpbmNlIHRoZSByb290CisgIC8vIGFuZCBtZXRhIHJlZ2lvbnMgYWx3YXlzIG5lZWQgdG8gYmUgb24tbGluZSwgdGhpcyBlbnN1cmVzIHRoYXQgdGhleSB3aWxsCisgIC8vIGJlIHRoZSBmaXJzdCB0byBiZSByZWFzc2lnbmVkIGlmIHRoZSBzZXJ2ZXIocykgdGhleSBhcmUgYmVpbmcgc2VydmVkIGJ5CisgIC8vIHNob3VsZCBnbyBkb3duLgorCisgIC8qKiBUaGUgcm9vdCB0YWJsZSdzIG5hbWUuKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gUk9PVF9UQUJMRV9OQU1FID0gQnl0ZXMudG9CeXRlcygiLVJPT1QtIik7CisKKyAgLyoqIFRoZSBNRVRBIHRhYmxlJ3MgbmFtZS4gKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gTUVUQV9UQUJMRV9OQU1FID0gQnl0ZXMudG9CeXRlcygiLk1FVEEuIik7ICAKKworICAvKiogZGVsaW1pdGVyIHVzZWQgYmV0d2VlbiBwb3J0aW9ucyBvZiBhIHJlZ2lvbiBuYW1lICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FVEFfUk9XX0RFTElNSVRFUiA9ICcsJzsKKworICAvLyBEZWZpbmVzIGZvciB0aGUgY29sdW1uIG5hbWVzIHVzZWQgaW4gYm90aCBST09UIGFuZCBNRVRBIEhCYXNlICdtZXRhJyB0YWJsZXMuCisgIAorICAvKiogVGhlIFJPT1QgYW5kIE1FVEEgY29sdW1uIGZhbWlseSAoc3RyaW5nKSAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTl9GQU1JTFlfU1RSID0gImluZm86IjsKKyAgCisgIC8qKiBUaGUgTUVUQSBoaXN0b3JpYW4gY29sdW1uIGZhbWlseSAoc3RyaW5nKSAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTl9GQU1JTFlfSElTVE9SSUFOX1NUUiA9ICJoaXN0b3JpYW46IjsKKworICAvKiogVGhlIFJPT1QgYW5kIE1FVEEgY29sdW1uIGZhbWlseSAqLworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xVTU5fRkFNSUxZID0gQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUik7CisgIAorICAvKiogVGhlIE1FVEEgaGlzdG9yaWFuIGNvbHVtbiBmYW1pbHkgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gQ09MVU1OX0ZBTUlMWV9ISVNUT1JJQU4gPSBCeXRlcy50b0J5dGVzKENPTFVNTl9GQU1JTFlfSElTVE9SSUFOX1NUUik7CisKKyAgLyoqIEFycmF5IG9mIG1ldGEgY29sdW1uIG5hbWVzICovCisgIHN0YXRpYyBmaW5hbCBieXRlW11bXSBDT0xVTU5fRkFNSUxZX0FSUkFZID0gbmV3IGJ5dGVbXVtdIHtDT0xVTU5fRkFNSUxZfTsKKyAgCisgIC8qKiBST09UL01FVEEgY29sdW1uIGZhbWlseSBtZW1iZXIgLSBjb250YWlucyBIUmVnaW9uSW5mbyAqLworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xfUkVHSU9OSU5GTyA9CisgICAgQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUiArICJyZWdpb25pbmZvIik7CisKKyAgLyoqIEFycmF5IG9mIGNvbHVtbiAtIGNvbnRhaW5zIEhSZWdpb25JbmZvICovCisgIHN0YXRpYyBmaW5hbCBieXRlW11bXSBDT0xfUkVHSU9OSU5GT19BUlJBWSA9IG5ldyBieXRlW11bXSB7Q09MX1JFR0lPTklORk99OworICAKKyAgLyoqIFJPT1QvTUVUQSBjb2x1bW4gZmFtaWx5IG1lbWJlciAtIGNvbnRhaW5zIEhTZXJ2ZXJBZGRyZXNzLnRvU3RyaW5nKCkgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0xfU0VSVkVSID0gQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUiArICJzZXJ2ZXIiKTsKKyAgCisgIC8qKiBST09UL01FVEEgY29sdW1uIGZhbWlseSBtZW1iZXIgLSBjb250YWlucyBzZXJ2ZXIgc3RhcnQgY29kZSAoYSBsb25nKSAqLworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xfU1RBUlRDT0RFID0KKyAgICBCeXRlcy50b0J5dGVzKENPTFVNTl9GQU1JTFlfU1RSICsgInNlcnZlcnN0YXJ0Y29kZSIpOworCisgIC8qKiB0aGUgbG93ZXIgaGFsZiBvZiBhIHNwbGl0IHJlZ2lvbiAqLworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xfU1BMSVRBID0gQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUiArICJzcGxpdEEiKTsKKyAgCisgIC8qKiB0aGUgdXBwZXIgaGFsZiBvZiBhIHNwbGl0IHJlZ2lvbiAqLworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xfU1BMSVRCID0gQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUiArICJzcGxpdEIiKTsKKyAgCisgIC8qKiBBbGwgdGhlIGNvbHVtbnMgaW4gdGhlIGNhdGFsb2cgLVJPT1QtIGFuZCAuTUVUQS4gdGFibGVzLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGVbXVtdIEFMTF9NRVRBX0NPTFVNTlMgPSB7Q09MX1JFR0lPTklORk8sIENPTF9TRVJWRVIsCisgICAgQ09MX1NUQVJUQ09ERSwgQ09MX1NQTElUQSwgQ09MX1NQTElUQn07CisKKyAgLy8gT3RoZXIgY29uc3RhbnRzCisKKyAgLyoqCisgICAqIEFuIGVtcHR5IGluc3RhbmNlLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gRU1QVFlfQllURV9BUlJBWSA9IG5ldyBieXRlIFswXTsKKyAgCisgIC8qKgorICAgKiBVc2VkIGJ5IHNjYW5uZXJzLCBldGMgd2hlbiB0aGV5IHdhbnQgdG8gc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvZiBhIHJlZ2lvbgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gRU1QVFlfU1RBUlRfUk9XID0gRU1QVFlfQllURV9BUlJBWTsKKyAgCisgIC8qKgorICAgKiBMYXN0IHJvdyBpbiBhIHRhYmxlLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gRU1QVFlfRU5EX1JPVyA9IEVNUFRZX1NUQVJUX1JPVzsKKworICAvKiogCisgICAgKiBVc2VkIGJ5IHNjYW5uZXJzIGFuZCBvdGhlcnMgd2hlbiB0aGV5J3JlIHRyeWluZyB0byBkZXRlY3QgdGhlIGVuZCBvZiBhIAorICAgICogdGFibGUgCisgICAgKi8KKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gTEFTVF9ST1cgPSBFTVBUWV9CWVRFX0FSUkFZOworICAKKyAgLyoqCisgICAqIE1heCBsZW5ndGggYSByb3cgY2FuIGhhdmUgYmVjYXVzZSBvZiB0aGUgbGltaXRhdGlvbiBpbiBURmlsZS4KKyAgICovCisgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1JPV19MRU5HVEggPSAxMDI0KjY0OworICAKKyAgLyoqIFdoZW4gd2UgZW5jb2RlIHN0cmluZ3MsIHdlIGFsd2F5cyBzcGVjaWZ5IFVURjggZW5jb2RpbmcgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBVVEY4X0VOQ09ESU5HID0gIlVURi04IjsKKworICAvKioKKyAgICogVGltZXN0YW1wIHRvIHVzZSB3aGVuIHdlIHdhbnQgdG8gcmVmZXIgdG8gdGhlIGxhdGVzdCBjZWxsLgorICAgKiBUaGlzIGlzIHRoZSB0aW1lc3RhbXAgc2VudCBieSBjbGllbnRzIHdoZW4gbm8gdGltZXN0YW1wIGlzIHNwZWNpZmllZCBvbgorICAgKiBjb21taXQuCisgICAqLworICBzdGF0aWMgZmluYWwgbG9uZyBMQVRFU1RfVElNRVNUQU1QID0gTG9uZy5NQVhfVkFMVUU7CisKKyAgLyoqCisgICAqIERlZmluZSBmb3IgJ3JldHVybi1hbGwtdmVyc2lvbnMnLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGludCBBTExfVkVSU0lPTlMgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgCisgIC8qKgorICAgKiBVbmxpbWl0ZWQgdGltZS10by1saXZlLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIGludCBGT1JFVkVSID0gLTE7CisgIAorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBXRUVLX0lOX1NFQ09ORFMgPSA3ICogMjQgKiAzNjAwOworCisgIC8vVE9ETzogSEJBU0VfQ0xJRU5UX1JFVFJJRVNfTlVNQkVSX0tFWSBpcyBvbmx5IHVzZWQgYnkgVGVzdE1pZ3JhdGUuIE1vdmUgaXQKKyAgLy8gICAgICB0aGVyZS4KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ0xJRU5UX1JFVFJJRVNfTlVNQkVSX0tFWSA9CisgICAgImhiYXNlLmNsaWVudC5yZXRyaWVzLm51bWJlciI7CisKKyAgLy9UT0RPOiBhbHRob3VnaCB0aGUgZm9sbG93aW5nIGFyZSByZWZlcmVuY2VkIHdpZGVseSB0byBmb3JtYXQgc3RyaW5ncyBmb3IKKyAgLy8gICAgICB0aGUgc2hlbGwuIFRoZXkgcmVhbGx5IGFyZW4ndCBhIHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkuIEl0IHdvdWxkIGJlCisgIC8vICAgICAgbmljZSBpZiB3ZSBjb3VsZCBwdXQgdGhlbSBzb21ld2hlcmUgd2hlcmUgdGhleSBkaWQgbm90IG5lZWQgdG8gYmUKKyAgLy8gICAgICBwdWJsaWMuIFRoZXkgY291bGQgaGF2ZSBwYWNrYWdlIHZpc2liaWxpdHkKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gIk5BTUUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIFZFUlNJT05TID0gIlZFUlNJT05TIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBJTl9NRU1PUlkgPSAiSU5fTUVNT1JZIjsKKyAgCisgIC8qKgorICAgKiBUaGlzIGlzIGEgcmV0cnkgYmFja29mZiBtdWx0aXBsaWVyIHRhYmxlIHNpbWlsYXIgdG8gdGhlIEJTRCBUQ1Agc3luCisgICAqIGJhY2tvZmYgdGFibGUsIGEgYml0IG1vcmUgYWdncmVzc2l2ZSB0aGFuIHNpbXBsZSBleHBvbmVudGlhbCBiYWNrb2ZmLgorICAgKi8gCisgIHB1YmxpYyBzdGF0aWMgaW50IFJFVFJZX0JBQ0tPRkZbXSA9IHsgMSwgMSwgMSwgMiwgMiwgNCwgNCwgOCwgMTYsIDMyIH07CisKKyAgLyoqIG1vZGlmeVRhYmxlIG9wIGZvciByZXBsYWNpbmcgdGhlIHRhYmxlIGRlc2NyaXB0b3IgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9ESUZZX1RBQkxFX1NFVF9IVEQgPSAxOworICAvKiogbW9kaWZ5VGFibGUgb3AgZm9yIGZvcmNpbmcgYSBzcGxpdCAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT0RJRllfVEFCTEVfU1BMSVQgPSAyOworICAvKiogbW9kaWZ5VGFibGUgb3AgZm9yIGZvcmNpbmcgYSBjb21wYWN0aW9uICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PRElGWV9UQUJMRV9DT01QQUNUID0gMzsKKyAgCisgIC8vIE1lc3NhZ2VzIGNsaWVudCBjYW4gc2VuZCBtYXN0ZXIuCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1PRElGWV9DTE9TRV9SRUdJT04gPSBNT0RJRllfVEFCTEVfQ09NUEFDVCArIDE7CisgIAorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT0RJRllfVEFCTEVfRkxVU0ggPSBNT0RJRllfQ0xPU0VfUkVHSU9OICsgMTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9ESUZZX1RBQkxFX01BSk9SX0NPTVBBQ1QgPSBNT0RJRllfVEFCTEVfRkxVU0ggKyAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSE1lcmdlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9ITWVyZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTg3ZDE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSE1lcmdlLmphdmEKQEAgLTAsMCArMSwzOTEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQ29ubmVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSENvbm5lY3Rpb25NYW5hZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhMb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkludGVybmFsU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKiogCisgKiBBIG5vbi1pbnN0YW50aWFibGUgY2xhc3MgdGhhdCBoYXMgYSBzdGF0aWMgbWV0aG9kIGNhcGFibGUgb2YgY29tcGFjdGluZworICogYSB0YWJsZSBieSBtZXJnaW5nIGFkamFjZW50IHJlZ2lvbnMuCisgKi8KK2NsYXNzIEhNZXJnZSBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhNZXJnZS5jbGFzcyk7CisgIHN0YXRpYyBmaW5hbCBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKKyAgCisgIC8qCisgICAqIE5vdCBpbnN0YW50aWFibGUKKyAgICovCisgIHByaXZhdGUgSE1lcmdlKCkgeworICAgIHN1cGVyKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTY2FucyB0aGUgdGFibGUgYW5kIG1lcmdlcyB0d28gYWRqYWNlbnQgcmVnaW9ucyBpZiB0aGV5IGFyZSBzbWFsbC4gVGhpcworICAgKiBvbmx5IGhhcHBlbnMgd2hlbiBhIGxvdCBvZiByb3dzIGFyZSBkZWxldGVkLgorICAgKiAKKyAgICogV2hlbiBtZXJnaW5nIHRoZSBNRVRBIHJlZ2lvbiwgdGhlIEhCYXNlIGluc3RhbmNlIG11c3QgYmUgb2ZmbGluZS4KKyAgICogV2hlbiBtZXJnaW5nIGEgbm9ybWFsIHRhYmxlLCB0aGUgSEJhc2UgaW5zdGFuY2UgbXVzdCBiZSBvbmxpbmUsIGJ1dCB0aGUKKyAgICogdGFibGUgbXVzdCBiZSBkaXNhYmxlZC4gCisgICAqIAorICAgKiBAcGFyYW0gY29uZiAgICAgICAgLSBjb25maWd1cmF0aW9uIG9iamVjdCBmb3IgSEJhc2UKKyAgICogQHBhcmFtIGZzICAgICAgICAgIC0gRmlsZVN5c3RlbSB3aGVyZSByZWdpb25zIHJlc2lkZQorICAgKiBAcGFyYW0gdGFibGVOYW1lICAgLSBUYWJsZSB0byBiZSBjb21wYWN0ZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1lcmdlKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBIQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKTsKKyAgICBib29sZWFuIG1hc3RlcklzUnVubmluZyA9IGNvbm5lY3Rpb24uaXNNYXN0ZXJSdW5uaW5nKCk7CisgICAgSENvbm5lY3Rpb25NYW5hZ2VyLmRlbGV0ZUNvbm5lY3Rpb25JbmZvKGNvbmYsIGZhbHNlKTsKKyAgICBpZiAoQnl0ZXMuZXF1YWxzKHRhYmxlTmFtZSwgTUVUQV9UQUJMRV9OQU1FKSkgeworICAgICAgaWYgKG1hc3RlcklzUnVubmluZykgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbiBub3QgY29tcGFjdCBNRVRBIHRhYmxlIGlmIGluc3RhbmNlIGlzIG9uLWxpbmUiKTsKKyAgICAgIH0KKyAgICAgIG5ldyBPZmZsaW5lTWVyZ2VyKGNvbmYsIGZzKS5wcm9jZXNzKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmKCFtYXN0ZXJJc1J1bm5pbmcpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJIQmFzZSBpbnN0YW5jZSBtdXN0IGJlIHJ1bm5pbmcgdG8gbWVyZ2UgYSBub3JtYWwgdGFibGUiKTsKKyAgICAgIH0KKyAgICAgIG5ldyBPbmxpbmVNZXJnZXIoY29uZiwgZnMsIHRhYmxlTmFtZSkucHJvY2VzcygpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIE1lcmdlciB7CisgICAgcHJvdGVjdGVkIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICAgIHByb3RlY3RlZCBmaW5hbCBGaWxlU3lzdGVtIGZzOworICAgIHByb3RlY3RlZCBmaW5hbCBQYXRoIHRhYmxlZGlyOworICAgIHByb3RlY3RlZCBmaW5hbCBITG9nIGhsb2c7CisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG1heEZpbGVzaXplOworCisgICAgCisgICAgcHJvdGVjdGVkIE1lcmdlcihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywKKyAgICAgIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLmNvbmYgPSBjb25mOworICAgICAgdGhpcy5mcyA9IGZzOworICAgICAgdGhpcy5tYXhGaWxlc2l6ZSA9CisgICAgICAgIGNvbmYuZ2V0TG9uZygiaGJhc2UuaHJlZ2lvbi5tYXguZmlsZXNpemUiLCBERUZBVUxUX01BWF9GSUxFX1NJWkUpOworCisgICAgICB0aGlzLnRhYmxlZGlyID0gbmV3IFBhdGgoCisgICAgICAgICAgZnMubWFrZVF1YWxpZmllZChuZXcgUGF0aChjb25mLmdldChIQkFTRV9ESVIpKSksCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKQorICAgICAgKTsKKyAgICAgIFBhdGggbG9nZGlyID0gbmV3IFBhdGgodGFibGVkaXIsICJtZXJnZV8iICsgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKworICAgICAgICAgIEhSRUdJT05fTE9HRElSX05BTUUpOworICAgICAgdGhpcy5obG9nID0KKyAgICAgICAgbmV3IEhMb2coZnMsIGxvZ2RpciwgY29uZiwgbnVsbCk7CisgICAgfQorICAgIAorICAgIHZvaWQgcHJvY2VzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBmb3IoSFJlZ2lvbkluZm9bXSByZWdpb25zVG9NZXJnZSA9IG5leHQoKTsKKyAgICAgICAgICAgIHJlZ2lvbnNUb01lcmdlICE9IG51bGw7CisgICAgICAgICAgICByZWdpb25zVG9NZXJnZSA9IG5leHQoKSkgeworICAgICAgICAgIGlmICghbWVyZ2UocmVnaW9uc1RvTWVyZ2UpKSB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGhsb2cuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgICAgICAKKyAgICAgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmVycm9yKGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIAorICAgIHByb3RlY3RlZCBib29sZWFuIG1lcmdlKGZpbmFsIEhSZWdpb25JbmZvW10gaW5mbykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmKGluZm8ubGVuZ3RoIDwgMikgeworICAgICAgICBMT0cuaW5mbygib25seSBvbmUgcmVnaW9uIC0gbm90aGluZyB0byBtZXJnZSIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAKKyAgICAgIEhSZWdpb24gY3VycmVudFJlZ2lvbiA9IG51bGw7CisgICAgICBsb25nIGN1cnJlbnRTaXplID0gMDsKKyAgICAgIEhSZWdpb24gbmV4dFJlZ2lvbiA9IG51bGw7CisgICAgICBsb25nIG5leHRTaXplID0gMDsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5mby5sZW5ndGggLSAxOyBpKyspIHsKKyAgICAgICAgaWYgKGN1cnJlbnRSZWdpb24gPT0gbnVsbCkgeworICAgICAgICAgIGN1cnJlbnRSZWdpb24gPQorICAgICAgICAgICAgbmV3IEhSZWdpb24odGFibGVkaXIsIGhsb2csIGZzLCBjb25mLCBpbmZvW2ldLCBudWxsKTsKKyAgICAgICAgICBjdXJyZW50UmVnaW9uLmluaXRpYWxpemUobnVsbCwgbnVsbCk7CisgICAgICAgICAgY3VycmVudFNpemUgPSBjdXJyZW50UmVnaW9uLmdldExhcmdlc3RIU3RvcmVTaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgbmV4dFJlZ2lvbiA9CisgICAgICAgICAgbmV3IEhSZWdpb24odGFibGVkaXIsIGhsb2csIGZzLCBjb25mLCBpbmZvW2kgKyAxXSwgbnVsbCk7CisgICAgICAgIG5leHRSZWdpb24uaW5pdGlhbGl6ZShudWxsLCBudWxsKTsKKyAgICAgICAgbmV4dFNpemUgPSBuZXh0UmVnaW9uLmdldExhcmdlc3RIU3RvcmVTaXplKCk7CisKKyAgICAgICAgaWYgKChjdXJyZW50U2l6ZSArIG5leHRTaXplKSA8PSAobWF4RmlsZXNpemUgLyAyKSkgeworICAgICAgICAgIC8vIFdlIG1lcmdlIHR3byBhZGphY2VudCByZWdpb25zIGlmIHRoZWlyIHRvdGFsIHNpemUgaXMgbGVzcyB0aGFuCisgICAgICAgICAgLy8gb25lIGhhbGYgb2YgdGhlIGRlc2lyZWQgbWF4aW11bSBzaXplCisgICAgICAgICAgTE9HLmluZm8oIm1lcmdpbmcgcmVnaW9ucyAiICsgQnl0ZXMudG9TdHJpbmcoY3VycmVudFJlZ2lvbi5nZXRSZWdpb25OYW1lKCkpCisgICAgICAgICAgICAgICsgIiBhbmQgIiArIEJ5dGVzLnRvU3RyaW5nKG5leHRSZWdpb24uZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgICAgICAgSFJlZ2lvbiBtZXJnZWRSZWdpb24gPQorICAgICAgICAgICAgSFJlZ2lvbi5tZXJnZUFkamFjZW50KGN1cnJlbnRSZWdpb24sIG5leHRSZWdpb24pOworICAgICAgICAgIHVwZGF0ZU1ldGEoY3VycmVudFJlZ2lvbi5nZXRSZWdpb25OYW1lKCksIG5leHRSZWdpb24uZ2V0UmVnaW9uTmFtZSgpLAorICAgICAgICAgICAgICBtZXJnZWRSZWdpb24pOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIExPRy5pbmZvKCJub3QgbWVyZ2luZyByZWdpb25zICIgKyBCeXRlcy50b1N0cmluZyhjdXJyZW50UmVnaW9uLmdldFJlZ2lvbk5hbWUoKSkKKyAgICAgICAgICAgICsgIiBhbmQgIiArIEJ5dGVzLnRvU3RyaW5nKG5leHRSZWdpb24uZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgICAgIGN1cnJlbnRSZWdpb24uY2xvc2UoKTsKKyAgICAgICAgY3VycmVudFJlZ2lvbiA9IG5leHRSZWdpb247CisgICAgICAgIGN1cnJlbnRTaXplID0gbmV4dFNpemU7CisgICAgICB9CisgICAgICBpZihjdXJyZW50UmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgY3VycmVudFJlZ2lvbi5jbG9zZSgpOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIAorICAgIHByb3RlY3RlZCBhYnN0cmFjdCBIUmVnaW9uSW5mb1tdIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgdXBkYXRlTWV0YShmaW5hbCBieXRlIFtdIG9sZFJlZ2lvbjEsCisgICAgICBmaW5hbCBieXRlIFtdIG9sZFJlZ2lvbjIsIEhSZWdpb24gbmV3UmVnaW9uKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICAKKyAgfQorCisgIC8qKiBJbnN0YW50aWF0ZWQgdG8gY29tcGFjdCBhIG5vcm1hbCB1c2VyIHRhYmxlICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIE9ubGluZU1lcmdlciBleHRlbmRzIE1lcmdlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEhUYWJsZSB0YWJsZTsKKyAgICBwcml2YXRlIGZpbmFsIFNjYW5uZXIgbWV0YVNjYW5uZXI7CisgICAgcHJpdmF0ZSBIUmVnaW9uSW5mbyBsYXRlc3RSZWdpb247CisgICAgCisgICAgT25saW5lTWVyZ2VyKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGNvbmYsIGZzLCB0YWJsZU5hbWUpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBNRVRBX1RBQkxFX05BTUUpOworICAgICAgdGhpcy5tZXRhU2Nhbm5lciA9IHRhYmxlLmdldFNjYW5uZXIoQ09MX1JFR0lPTklORk9fQVJSQVksIHRhYmxlTmFtZSk7CisgICAgICB0aGlzLmxhdGVzdFJlZ2lvbiA9IG51bGw7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgSFJlZ2lvbkluZm8gbmV4dFJlZ2lvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBSb3dSZXN1bHQgcmVzdWx0cyA9IGdldE1ldGFSb3coKTsKKyAgICAgICAgaWYgKHJlc3VsdHMgPT0gbnVsbCkgeworICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIENlbGwgcmVnaW9uSW5mbyA9IHJlc3VsdHMuZ2V0KENPTF9SRUdJT05JTkZPKTsKKyAgICAgICAgaWYgKHJlZ2lvbkluZm8gPT0gbnVsbCB8fCByZWdpb25JbmZvLmdldFZhbHVlKCkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigibWV0YSByZWdpb24gZW50cnkgbWlzc2luZyAiICsKKyAgICAgICAgICAgICAgQnl0ZXMudG9TdHJpbmcoQ09MX1JFR0lPTklORk8pKTsKKyAgICAgICAgfQorICAgICAgICBIUmVnaW9uSW5mbyByZWdpb24gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8ocmVnaW9uSW5mby5nZXRWYWx1ZSgpKTsKKyAgICAgICAgaWYgKCFCeXRlcy5lcXVhbHMocmVnaW9uLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgdGhpcy50YWJsZU5hbWUpKSB7CisgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgY2hlY2tPZmZsaW5lZChyZWdpb24pOworICAgICAgICByZXR1cm4gcmVnaW9uOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKGUpOworICAgICAgICBMT0cuZXJyb3IoIm1ldGEgc2Nhbm5lciBlcnJvciIsIGUpOworICAgICAgICBtZXRhU2Nhbm5lci5jbG9zZSgpOworICAgICAgICB0aHJvdyBlOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja09mZmxpbmVkKGZpbmFsIEhSZWdpb25JbmZvIGhyaSkKKyAgICB0aHJvd3MgVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbiB7CisgICAgICBpZiAoIWhyaS5pc09mZmxpbmUoKSkgeworICAgICAgICB0aHJvdyBuZXcgVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbigiUmVnaW9uICIgKworICAgICAgICAgIGhyaS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSArICIgaXMgbm90IGRpc2FibGVkIik7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8qCisgICAgICogQ2hlY2sgY3VycmVudCByb3cgaGFzIGEgSFJlZ2lvbkluZm8uICBTa2lwIHRvIG5leHQgcm93IGlmIEhSSSBpcyBlbXB0eS4KKyAgICAgKiBAcmV0dXJuIEEgTWFwIG9mIHRoZSByb3cgY29udGVudCBlbHNlIG51bGwgaWYgd2UgYXJlIG9mZiB0aGUgZW5kLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIFJvd1Jlc3VsdCBnZXRNZXRhUm93KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIFJvd1Jlc3VsdCBjdXJyZW50Um93ID0gbWV0YVNjYW5uZXIubmV4dCgpOworICAgICAgYm9vbGVhbiBmb3VuZFJlc3VsdCA9IGZhbHNlOworICAgICAgd2hpbGUgKGN1cnJlbnRSb3cgIT0gbnVsbCkgeworICAgICAgICBMT0cuaW5mbygiUm93OiA8IiArIEJ5dGVzLnRvU3RyaW5nKGN1cnJlbnRSb3cuZ2V0Um93KCkpICsgIj4iKTsKKyAgICAgICAgQ2VsbCByZWdpb25JbmZvID0gY3VycmVudFJvdy5nZXQoQ09MX1JFR0lPTklORk8pOworICAgICAgICBpZiAocmVnaW9uSW5mbyA9PSBudWxsIHx8IHJlZ2lvbkluZm8uZ2V0VmFsdWUoKS5sZW5ndGggPT0gMCkgeworICAgICAgICAgIGN1cnJlbnRSb3cgPSBtZXRhU2Nhbm5lci5uZXh0KCk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgZm91bmRSZXN1bHQgPSB0cnVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmb3VuZFJlc3VsdCA/IGN1cnJlbnRSb3cgOiBudWxsOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBIUmVnaW9uSW5mb1tdIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTGlzdDxIUmVnaW9uSW5mbz4gcmVnaW9ucyA9IG5ldyBBcnJheUxpc3Q8SFJlZ2lvbkluZm8+KCk7CisgICAgICBpZihsYXRlc3RSZWdpb24gPT0gbnVsbCkgeworICAgICAgICBsYXRlc3RSZWdpb24gPSBuZXh0UmVnaW9uKCk7CisgICAgICB9CisgICAgICBpZihsYXRlc3RSZWdpb24gIT0gbnVsbCkgeworICAgICAgICByZWdpb25zLmFkZChsYXRlc3RSZWdpb24pOworICAgICAgfQorICAgICAgbGF0ZXN0UmVnaW9uID0gbmV4dFJlZ2lvbigpOworICAgICAgaWYobGF0ZXN0UmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgcmVnaW9ucy5hZGQobGF0ZXN0UmVnaW9uKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiByZWdpb25zLnRvQXJyYXkobmV3IEhSZWdpb25JbmZvW3JlZ2lvbnMuc2l6ZSgpXSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdXBkYXRlTWV0YShmaW5hbCBieXRlIFtdIG9sZFJlZ2lvbjEsCisgICAgICAgIGZpbmFsIGJ5dGUgW10gb2xkUmVnaW9uMiwgCisgICAgICBIUmVnaW9uIG5ld1JlZ2lvbikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYnl0ZVtdW10gcmVnaW9uc1RvRGVsZXRlID0ge29sZFJlZ2lvbjEsIG9sZFJlZ2lvbjJ9OworICAgICAgZm9yIChpbnQgciA9IDA7IHIgPCByZWdpb25zVG9EZWxldGUubGVuZ3RoOyByKyspIHsKKyAgICAgICAgaWYoQnl0ZXMuZXF1YWxzKHJlZ2lvbnNUb0RlbGV0ZVtyXSwgbGF0ZXN0UmVnaW9uLmdldFJlZ2lvbk5hbWUoKSkpIHsKKyAgICAgICAgICBsYXRlc3RSZWdpb24gPSBudWxsOworICAgICAgICB9CisgICAgICAgIHRhYmxlLmRlbGV0ZUFsbChyZWdpb25zVG9EZWxldGVbcl0pOworICAgICAgICBpZihMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygidXBkYXRlZCBjb2x1bW5zIGluIHJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbnNUb0RlbGV0ZVtyXSkpOworICAgICAgICB9CisgICAgICB9CisgICAgICBuZXdSZWdpb24uZ2V0UmVnaW9uSW5mbygpLnNldE9mZmxpbmUodHJ1ZSk7CisKKyAgICAgIEJhdGNoVXBkYXRlIHVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShuZXdSZWdpb24uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgIHVwZGF0ZS5wdXQoQ09MX1JFR0lPTklORk8sCisgICAgICAgIFdyaXRhYmxlcy5nZXRCeXRlcyhuZXdSZWdpb24uZ2V0UmVnaW9uSW5mbygpKSk7CisgICAgICB0YWJsZS5jb21taXQodXBkYXRlKTsKKworICAgICAgaWYoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJ1cGRhdGVkIGNvbHVtbnMgaW4gcm93OiAiCisgICAgICAgICAgICArIEJ5dGVzLnRvU3RyaW5nKG5ld1JlZ2lvbi5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKiogSW5zdGFudGlhdGVkIHRvIGNvbXBhY3QgdGhlIG1ldGEgcmVnaW9uICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIE9mZmxpbmVNZXJnZXIgZXh0ZW5kcyBNZXJnZXIgeworICAgIHByaXZhdGUgZmluYWwgTGlzdDxIUmVnaW9uSW5mbz4gbWV0YVJlZ2lvbnMgPSBuZXcgQXJyYXlMaXN0PEhSZWdpb25JbmZvPigpOworICAgIHByaXZhdGUgZmluYWwgSFJlZ2lvbiByb290OworICAgIAorICAgIE9mZmxpbmVNZXJnZXIoSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIEZpbGVTeXN0ZW0gZnMpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAKKyAgICAgIHN1cGVyKGNvbmYsIGZzLCBNRVRBX1RBQkxFX05BTUUpOworCisgICAgICBQYXRoIHJvb3RUYWJsZURpciA9IEhUYWJsZURlc2NyaXB0b3IuZ2V0VGFibGVEaXIoCisgICAgICAgICAgZnMubWFrZVF1YWxpZmllZChuZXcgUGF0aChjb25mLmdldChIQkFTRV9ESVIpKSksCisgICAgICAgICAgUk9PVF9UQUJMRV9OQU1FKTsKKworICAgICAgLy8gU2NhbiByb290IHJlZ2lvbiB0byBmaW5kIGFsbCB0aGUgbWV0YSByZWdpb25zCisgICAgICAKKyAgICAgIHJvb3QgPSBuZXcgSFJlZ2lvbihyb290VGFibGVEaXIsIGhsb2csIGZzLCBjb25mLAorICAgICAgICAgIEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTywgbnVsbCk7CisgICAgICByb290LmluaXRpYWxpemUobnVsbCwgbnVsbCk7CisKKyAgICAgIEludGVybmFsU2Nhbm5lciByb290U2Nhbm5lciA9IAorICAgICAgICByb290LmdldFNjYW5uZXIoQ09MX1JFR0lPTklORk9fQVJSQVksIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLCAKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKyAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgICAgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgIHdoaWxlKHJvb3RTY2FubmVyLm5leHQocmVzdWx0cykpIHsKKyAgICAgICAgICBmb3IoS2V5VmFsdWUga3Y6IHJlc3VsdHMpIHsKKyAgICAgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm9Pck51bGwoa3YuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICBpZiAoaW5mbyAhPSBudWxsKSB7CisgICAgICAgICAgICAgIG1ldGFSZWdpb25zLmFkZChpbmZvKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHJvb3RTY2FubmVyLmNsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcm9vdC5jbG9zZSgpOworICAgICAgICAgIAorICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgSFJlZ2lvbkluZm9bXSBuZXh0KCkgeworICAgICAgSFJlZ2lvbkluZm9bXSByZXN1bHRzID0gbnVsbDsKKyAgICAgIGlmIChtZXRhUmVnaW9ucy5zaXplKCkgPiAwKSB7CisgICAgICAgIHJlc3VsdHMgPSBtZXRhUmVnaW9ucy50b0FycmF5KG5ldyBIUmVnaW9uSW5mb1ttZXRhUmVnaW9ucy5zaXplKCldKTsKKyAgICAgICAgbWV0YVJlZ2lvbnMuY2xlYXIoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHRzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHVwZGF0ZU1ldGEoZmluYWwgYnl0ZSBbXSBvbGRSZWdpb24xLAorICAgICAgZmluYWwgYnl0ZSBbXSBvbGRSZWdpb24yLCBIUmVnaW9uIG5ld1JlZ2lvbikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYnl0ZVtdW10gcmVnaW9uc1RvRGVsZXRlID0ge29sZFJlZ2lvbjEsIG9sZFJlZ2lvbjJ9OworICAgICAgZm9yKGludCByID0gMDsgciA8IHJlZ2lvbnNUb0RlbGV0ZS5sZW5ndGg7IHIrKykgeworICAgICAgICBCYXRjaFVwZGF0ZSBiID0gbmV3IEJhdGNoVXBkYXRlKHJlZ2lvbnNUb0RlbGV0ZVtyXSk7CisgICAgICAgIGIuZGVsZXRlKENPTF9SRUdJT05JTkZPKTsKKyAgICAgICAgYi5kZWxldGUoQ09MX1NFUlZFUik7CisgICAgICAgIGIuZGVsZXRlKENPTF9TVEFSVENPREUpOworICAgICAgICBiLmRlbGV0ZShDT0xfU1BMSVRBKTsKKyAgICAgICAgYi5kZWxldGUoQ09MX1NQTElUQik7CisgICAgICAgIHJvb3QuYmF0Y2hVcGRhdGUoYixudWxsKTsKKworICAgICAgICBpZihMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygidXBkYXRlZCBjb2x1bW5zIGluIHJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbnNUb0RlbGV0ZVtyXSkpOworICAgICAgICB9CisgICAgICB9CisgICAgICBIUmVnaW9uSW5mbyBuZXdJbmZvID0gbmV3UmVnaW9uLmdldFJlZ2lvbkluZm8oKTsKKyAgICAgIG5ld0luZm8uc2V0T2ZmbGluZSh0cnVlKTsKKyAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUobmV3UmVnaW9uLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICBiLnB1dChDT0xfUkVHSU9OSU5GTywgV3JpdGFibGVzLmdldEJ5dGVzKG5ld0luZm8pKTsKKyAgICAgIHJvb3QuYmF0Y2hVcGRhdGUoYixudWxsKTsKKyAgICAgIGlmKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygidXBkYXRlZCBjb2x1bW5zIGluIHJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKG5ld1JlZ2lvbi5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hNc2cuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hNc2cuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWM3YTNkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSE1zZy5qYXZhCkBAIC0wLDAgKzEsMjY0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogSE1zZyBpcyBmb3IgY29tbXVuaWNhdGluZyBpbnN0cnVjdGlvbnMgYmV0d2VlbiB0aGUgSE1hc3RlciBhbmQgdGhlIAorICogSFJlZ2lvblNlcnZlcnMuCisgKiAKKyAqIE1vc3Qgb2YgdGhlIHRpbWUgdGhlIG1lc3NhZ2VzIGFyZSBzaW1wbGUgYnV0IHNvbWUgbWVzc2FnZXMgYXJlIGFjY29tcGFuaWVkCisgKiBieSB0aGUgcmVnaW9uIGFmZmVjdGVkLiAgSE1zZyBtYXkgYWxzbyBjYXJyeSBvcHRpb25hbCBtZXNzYWdlLgorICovCitwdWJsaWMgY2xhc3MgSE1zZyBpbXBsZW1lbnRzIFdyaXRhYmxlIHsKKyAgLyoqCisgICAqIE1lc3NhZ2UgdHlwZXMgc2VudCBiZXR3ZWVuIG1hc3RlciBhbmQgcmVnaW9uc2VydmVycworICAgKi8KKyAgcHVibGljIHN0YXRpYyBlbnVtIFR5cGUgeworICAgIC8qKiBudWxsIG1lc3NhZ2UgKi8KKyAgICBNU0dfTk9ORSwKKyAgICAKKyAgICAvLyBNZXNzYWdlIHR5cGVzIHNlbnQgZnJvbSBtYXN0ZXIgdG8gcmVnaW9uIHNlcnZlcgorICAgIC8qKiBTdGFydCBzZXJ2aW5nIHRoZSBzcGVjaWZpZWQgcmVnaW9uICovCisgICAgTVNHX1JFR0lPTl9PUEVOLAorICAgIAorICAgIC8qKiBTdG9wIHNlcnZpbmcgdGhlIHNwZWNpZmllZCByZWdpb24gKi8KKyAgICBNU0dfUkVHSU9OX0NMT1NFLAorCisgICAgLyoqIFNwbGl0IHRoZSBzcGVjaWZpZWQgcmVnaW9uICovCisgICAgTVNHX1JFR0lPTl9TUExJVCwKKworICAgIC8qKiBDb21wYWN0IHRoZSBzcGVjaWZpZWQgcmVnaW9uICovCisgICAgTVNHX1JFR0lPTl9DT01QQUNULAorCisgICAgLyoqIFJlZ2lvbiBzZXJ2ZXIgaXMgdW5rbm93biB0byBtYXN0ZXIuIFJlc3RhcnQgKi8KKyAgICBNU0dfQ0FMTF9TRVJWRVJfU1RBUlRVUCwKKyAgICAKKyAgICAvKiogTWFzdGVyIHRlbGxzIHJlZ2lvbiBzZXJ2ZXIgdG8gc3RvcCAqLworICAgIE1TR19SRUdJT05TRVJWRVJfU1RPUCwKKyAgICAKKyAgICAvKiogU3RvcCBzZXJ2aW5nIHRoZSBzcGVjaWZpZWQgcmVnaW9uIGFuZCBkb24ndCByZXBvcnQgYmFjayB0aGF0IGl0J3MKKyAgICAgKiBjbG9zZWQKKyAgICAgKi8KKyAgICBNU0dfUkVHSU9OX0NMT1NFX1dJVEhPVVRfUkVQT1JULAorICAKKyAgICAvKiogU3RvcCBzZXJ2aW5nIHVzZXIgcmVnaW9ucyAqLworICAgIE1TR19SRUdJT05TRVJWRVJfUVVJRVNDRSwKKworICAgIC8vIE1lc3NhZ2UgdHlwZXMgc2VudCBmcm9tIHRoZSByZWdpb24gc2VydmVyIHRvIHRoZSBtYXN0ZXIKKyAgICAvKiogcmVnaW9uIHNlcnZlciBpcyBub3cgc2VydmluZyB0aGUgc3BlY2lmaWVkIHJlZ2lvbiAqLworICAgIE1TR19SRVBPUlRfT1BFTiwKKyAgICAKKyAgICAvKiogcmVnaW9uIHNlcnZlciBpcyBubyBsb25nZXIgc2VydmluZyB0aGUgc3BlY2lmaWVkIHJlZ2lvbiAqLworICAgIE1TR19SRVBPUlRfQ0xPU0UsCisKKyAgICAvKiogcmVnaW9uIHNlcnZlciBpcyBwcm9jZXNzaW5nIG9wZW4gcmVxdWVzdCAqLworICAgIE1TR19SRVBPUlRfUFJPQ0VTU19PUEVOLAorCisgICAgLyoqCisgICAgICogUmVnaW9uIHNlcnZlciBzcGxpdCB0aGUgcmVnaW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1lc3NhZ2UuCisgICAgICogCisgICAgICogTm90ZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSB0d28gTVNHX1JFUE9SVF9PUEVOCisgICAgICogbWVzc2FnZXMsIG9uZSBmb3IgZWFjaCBvZiB0aGUgbmV3IHJlZ2lvbnMgcmVzdWx0aW5nIGZyb20gdGhlIHNwbGl0CisgICAgICovCisgICAgTVNHX1JFUE9SVF9TUExJVCwKKworICAgIC8qKgorICAgICAqIFJlZ2lvbiBzZXJ2ZXIgaXMgc2h1dHRpbmcgZG93bgorICAgICAqIAorICAgICAqIE5vdGUgdGhhdCB0aGlzIG1lc3NhZ2UgaXMgZm9sbG93ZWQgYnkgTVNHX1JFUE9SVF9DTE9TRSBtZXNzYWdlcyBmb3IgZWFjaAorICAgICAqIHJlZ2lvbiB0aGUgcmVnaW9uIHNlcnZlciB3YXMgc2VydmluZywgdW5sZXNzIGl0IHdhcyB0b2xkIHRvIHF1aWVzY2UuCisgICAgICovCisgICAgTVNHX1JFUE9SVF9FWElUSU5HLAorCisgICAgLyoqIFJlZ2lvbiBzZXJ2ZXIgaGFzIGNsb3NlZCBhbGwgdXNlciByZWdpb25zIGJ1dCBpcyBzdGlsbCBzZXJ2aW5nIG1ldGEKKyAgICAgKiByZWdpb25zCisgICAgICovCisgICAgTVNHX1JFUE9SVF9RVUlFU0NFRCwKKyAgICAKKyAgICAvKioKKyAgICAgKiBGbHVzaAorICAgICAqLworICAgIE1TR19SRUdJT05fRkxVU0gsCisgICAgCisgICAgLyoqCisgICAgICogUnVuIE1ham9yIENvbXBhY3Rpb24KKyAgICAgKi8KKyAgICBNU0dfUkVHSU9OX01BSk9SX0NPTVBBQ1QsCisgIH0KKworICBwcml2YXRlIFR5cGUgdHlwZSA9IG51bGw7CisgIHByaXZhdGUgSFJlZ2lvbkluZm8gaW5mbyA9IG51bGw7CisgIHByaXZhdGUgYnl0ZVtdIG1lc3NhZ2UgPSBudWxsOworCisgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yLiBVc2VkIGR1cmluZyBkZXNlcmlhbGl6YXRpb24gKi8KKyAgcHVibGljIEhNc2coKSB7CisgICAgdGhpcyhUeXBlLk1TR19OT05FKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlIGFuZCBlbXB0eSBIUmVnaW9uSW5mbworICAgKiBAcGFyYW0gdHlwZSBNZXNzYWdlIHR5cGUKKyAgICovCisgIHB1YmxpYyBITXNnKGZpbmFsIEhNc2cuVHlwZSB0eXBlKSB7CisgICAgdGhpcyh0eXBlLCBuZXcgSFJlZ2lvbkluZm8oKSwgbnVsbCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgYSBtZXNzYWdlIHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlIGFuZCBIUmVnaW9uSW5mbworICAgKiBAcGFyYW0gdHlwZSBNZXNzYWdlIHR5cGUKKyAgICogQHBhcmFtIGhyaSBSZWdpb24gdG8gd2hpY2ggbWVzc2FnZSA8Y29kZT50eXBlPC9jb2RlPiBhcHBsaWVzCisgICAqLworICBwdWJsaWMgSE1zZyhmaW5hbCBITXNnLlR5cGUgdHlwZSwgZmluYWwgSFJlZ2lvbkluZm8gaHJpKSB7CisgICAgdGhpcyh0eXBlLCBocmksIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIG1lc3NhZ2Ugd2l0aCB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UgYW5kIEhSZWdpb25JbmZvCisgICAqIAorICAgKiBAcGFyYW0gdHlwZSBNZXNzYWdlIHR5cGUKKyAgICogQHBhcmFtIGhyaSBSZWdpb24gdG8gd2hpY2ggbWVzc2FnZSA8Y29kZT50eXBlPC9jb2RlPiBhcHBsaWVzLiAgQ2Fubm90IGJlCisgICAqIG51bGwuICBJZiBubyBpbmZvIGFzc29jaWF0ZWQsIHVzZWQgb3RoZXIgQ29uc3RydWN0b3IuCisgICAqIEBwYXJhbSBtc2cgT3B0aW9uYWwgbWVzc2FnZSAoU3RyaW5naWZpZWQgZXhjZXB0aW9uLCBldGMuKQorICAgKi8KKyAgcHVibGljIEhNc2coZmluYWwgSE1zZy5UeXBlIHR5cGUsIGZpbmFsIEhSZWdpb25JbmZvIGhyaSwgZmluYWwgYnl0ZVtdIG1zZykgeworICAgIGlmICh0eXBlID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiTWVzc2FnZSB0eXBlIGNhbm5vdCBiZSBudWxsIik7CisgICAgfQorICAgIHRoaXMudHlwZSA9IHR5cGU7CisgICAgaWYgKGhyaSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlJlZ2lvbiBjYW5ub3QgYmUgbnVsbCIpOworICAgIH0KKyAgICB0aGlzLmluZm8gPSBocmk7CisgICAgdGhpcy5tZXNzYWdlID0gbXNnOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmVnaW9uIGluZm8gb3IgbnVsbCBpZiBub25lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgICovCisgIHB1YmxpYyBIUmVnaW9uSW5mbyBnZXRSZWdpb25JbmZvKCkgeworICAgIHJldHVybiB0aGlzLmluZm87CisgIH0KKworICAvKiogQHJldHVybiB0aGUgdHlwZSBvZiBtZXNzYWdlICovCisgIHB1YmxpYyBUeXBlIGdldFR5cGUoKSB7CisgICAgcmV0dXJuIHRoaXMudHlwZTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBvdGhlciBNZXNzYWdlIHR5cGUgdG8gY29tcGFyZSB0bworICAgKiBAcmV0dXJuIFRydWUgaWYgd2UgYXJlIG9mIHNhbWUgbWVzc2FnZSB0eXBlIGFzIDxjb2RlPm90aGVyPC9jb2RlPgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNUeXBlKGZpbmFsIEhNc2cuVHlwZSBvdGhlcikgeworICAgIHJldHVybiB0aGlzLnR5cGUuZXF1YWxzKG90aGVyKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBtZXNzYWdlIHR5cGUgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRNZXNzYWdlKCkgeworICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIHNiLmFwcGVuZCh0aGlzLnR5cGUudG9TdHJpbmcoKSk7CisgICAgLy8gSWYgbnVsbCBvciBlbXB0eSByZWdpb24sIGRvbid0IGJvdGhlciBwcmludGluZyBpdCBvdXQuCisgICAgaWYgKHRoaXMuaW5mbyAhPSBudWxsICYmIHRoaXMuaW5mby5nZXRSZWdpb25OYW1lKCkubGVuZ3RoID4gMCkgeworICAgICAgc2IuYXBwZW5kKCI6ICIpOworICAgICAgc2IuYXBwZW5kKHRoaXMuaW5mby50b1N0cmluZygpKTsKKyAgICB9CisgICAgaWYgKHRoaXMubWVzc2FnZSAhPSBudWxsICYmIHRoaXMubWVzc2FnZS5sZW5ndGggPiAwKSB7CisgICAgICBzYi5hcHBlbmQoIjogIiArIEJ5dGVzLnRvU3RyaW5nKHRoaXMubWVzc2FnZSkpOworICAgIH0KKyAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGdldENsYXNzKCkgIT0gb2JqLmdldENsYXNzKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgSE1zZyB0aGF0ID0gKEhNc2cpb2JqOworICAgIHJldHVybiB0aGlzLnR5cGUuZXF1YWxzKHRoYXQudHlwZSkgJiYKKyAgICAgICh0aGlzLmluZm8gIT0gbnVsbCk/IHRoaXMuaW5mby5lcXVhbHModGhhdC5pbmZvKToKKyAgICAgICAgdGhhdC5pbmZvID09IG51bGw7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2hhc2hDb2RlKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCByZXN1bHQgPSB0aGlzLnR5cGUuaGFzaENvZGUoKTsKKyAgICBpZiAodGhpcy5pbmZvICE9IG51bGwpIHsKKyAgICAgIHJlc3VsdCBePSB0aGlzLmluZm8uaGFzaENvZGUoKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICAKKyAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAvLyBXcml0YWJsZQorICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZSN3cml0ZShqYXZhLmlvLkRhdGFPdXRwdXQpCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgb3V0LndyaXRlSW50KHRoaXMudHlwZS5vcmRpbmFsKCkpOworICAgICB0aGlzLmluZm8ud3JpdGUob3V0KTsKKyAgICAgaWYgKHRoaXMubWVzc2FnZSA9PSBudWxsIHx8IHRoaXMubWVzc2FnZS5sZW5ndGggPT0gMCkgeworICAgICAgIG91dC53cml0ZUJvb2xlYW4oZmFsc2UpOworICAgICB9IGVsc2UgeworICAgICAgIG91dC53cml0ZUJvb2xlYW4odHJ1ZSk7CisgICAgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCB0aGlzLm1lc3NhZ2UpOworICAgICB9CisgICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGUjcmVhZEZpZWxkcyhqYXZhLmlvLkRhdGFJbnB1dCkKKyAgICovCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICBpbnQgb3JkaW5hbCA9IGluLnJlYWRJbnQoKTsKKyAgICAgdGhpcy50eXBlID0gSE1zZy5UeXBlLnZhbHVlcygpW29yZGluYWxdOworICAgICB0aGlzLmluZm8ucmVhZEZpZWxkcyhpbik7CisgICAgIGJvb2xlYW4gaGFzTWVzc2FnZSA9IGluLnJlYWRCb29sZWFuKCk7CisgICAgIGlmIChoYXNNZXNzYWdlKSB7CisgICAgICAgdGhpcy5tZXNzYWdlID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgIH0KKyAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hSZWdpb25JbmZvLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IUmVnaW9uSW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExYmFlODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IUmVnaW9uSW5mby5qYXZhCkBAIC0wLDAgKzEsNDc3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWUuS1ZDb21wYXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5KZW5raW5zSGFzaDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5WZXJzaW9uZWRXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CisKKy8qKgorICogSFJlZ2lvbiBpbmZvcm1hdGlvbi4KKyAqIENvbnRhaW5zIEhSZWdpb24gaWQsIHN0YXJ0IGFuZCBlbmQga2V5cywgYSByZWZlcmVuY2UgdG8gdGhpcworICogSFJlZ2lvbnMnIHRhYmxlIGRlc2NyaXB0b3IsIGV0Yy4KKyAqLworcHVibGljIGNsYXNzIEhSZWdpb25JbmZvIGV4dGVuZHMgVmVyc2lvbmVkV3JpdGFibGUgaW1wbGVtZW50cyBXcml0YWJsZUNvbXBhcmFibGU8SFJlZ2lvbkluZm8+eworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFZFUlNJT04gPSAwOworCisgIC8qKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcmV0dXJuIHRoZSBlbmNvZGVkTmFtZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgZW5jb2RlUmVnaW9uTmFtZShmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUpIHsKKyAgICByZXR1cm4gTWF0aC5hYnMoSmVua2luc0hhc2guZ2V0SW5zdGFuY2UoKS5oYXNoKHJlZ2lvbk5hbWUsIHJlZ2lvbk5hbWUubGVuZ3RoLCAwKSk7CisgIH0KKworICAvKiogZGVsaW1pdGVyIHVzZWQgYmV0d2VlbiBwb3J0aW9ucyBvZiBhIHJlZ2lvbiBuYW1lICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFTElNSVRFUiA9ICcsJzsKKworICAvKiogSFJlZ2lvbkluZm8gZm9yIHJvb3QgcmVnaW9uICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSFJlZ2lvbkluZm8gUk9PVF9SRUdJT05JTkZPID0KKyAgICBuZXcgSFJlZ2lvbkluZm8oMEwsIEhUYWJsZURlc2NyaXB0b3IuUk9PVF9UQUJMRURFU0MpOworCisgIC8qKiBIUmVnaW9uSW5mbyBmb3IgZmlyc3QgbWV0YSByZWdpb24gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBIUmVnaW9uSW5mbyBGSVJTVF9NRVRBX1JFR0lPTklORk8gPQorICAgIG5ldyBIUmVnaW9uSW5mbygxTCwgSFRhYmxlRGVzY3JpcHRvci5NRVRBX1RBQkxFREVTQyk7CisKKyAgcHJpdmF0ZSBieXRlIFtdIGVuZEtleSA9IEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWTsKKyAgcHJpdmF0ZSBib29sZWFuIG9mZkxpbmUgPSBmYWxzZTsKKyAgcHJpdmF0ZSBsb25nIHJlZ2lvbklkID0gLTE7CisgIHByaXZhdGUgdHJhbnNpZW50IGJ5dGUgW10gcmVnaW9uTmFtZSA9IEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWTsKKyAgcHJpdmF0ZSBTdHJpbmcgcmVnaW9uTmFtZVN0ciA9ICIiOworICBwcml2YXRlIGJvb2xlYW4gc3BsaXQgPSBmYWxzZTsKKyAgcHJpdmF0ZSBieXRlIFtdIHN0YXJ0S2V5ID0gSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZOworICBwcm90ZWN0ZWQgSFRhYmxlRGVzY3JpcHRvciB0YWJsZURlc2MgPSBudWxsOworICBwcml2YXRlIGludCBoYXNoQ29kZSA9IC0xOworICAvL1RPRE86IE1vdmUgTk9fSEFTSCB0byBIU3RvcmVGaWxlIHdoaWNoIGlzIHJlYWxseSB0aGUgb25seSBwbGFjZSBpdCBpcyB1c2VkLgorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT19IQVNIID0gLTE7CisgIHByaXZhdGUgdm9sYXRpbGUgaW50IGVuY29kZWROYW1lID0gTk9fSEFTSDsKKyAgcHJpdmF0ZSBib29sZWFuIHNwbGl0UmVxdWVzdCA9IGZhbHNlOworCisgIHByaXZhdGUgdm9pZCBzZXRIYXNoQ29kZSgpIHsKKyAgICBpbnQgcmVzdWx0ID0gQXJyYXlzLmhhc2hDb2RlKHRoaXMucmVnaW9uTmFtZSk7CisgICAgcmVzdWx0IF49IHRoaXMucmVnaW9uSWQ7CisgICAgcmVzdWx0IF49IEFycmF5cy5oYXNoQ29kZSh0aGlzLnN0YXJ0S2V5KTsKKyAgICByZXN1bHQgXj0gQXJyYXlzLmhhc2hDb2RlKHRoaXMuZW5kS2V5KTsKKyAgICByZXN1bHQgXj0gQm9vbGVhbi52YWx1ZU9mKHRoaXMub2ZmTGluZSkuaGFzaENvZGUoKTsKKyAgICByZXN1bHQgXj0gdGhpcy50YWJsZURlc2MuaGFzaENvZGUoKTsKKyAgICB0aGlzLmhhc2hDb2RlID0gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogUHJpdmF0ZSBjb25zdHJ1Y3RvciB1c2VkIGNvbnN0cnVjdGluZyBIUmVnaW9uSW5mbyBmb3IgdGhlIGNhdGFsb2cgcm9vdCBhbmQKKyAgICogZmlyc3QgbWV0YSByZWdpb25zCisgICAqLworICBwcml2YXRlIEhSZWdpb25JbmZvKGxvbmcgcmVnaW9uSWQsIEhUYWJsZURlc2NyaXB0b3IgdGFibGVEZXNjKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLnJlZ2lvbklkID0gcmVnaW9uSWQ7CisgICAgdGhpcy50YWJsZURlc2MgPSB0YWJsZURlc2M7CisgICAgdGhpcy5yZWdpb25OYW1lID0gY3JlYXRlUmVnaW9uTmFtZSh0YWJsZURlc2MuZ2V0TmFtZSgpLCBudWxsLCByZWdpb25JZCk7CisgICAgdGhpcy5yZWdpb25OYW1lU3RyID0gQnl0ZXMudG9TdHJpbmcodGhpcy5yZWdpb25OYW1lKTsKKyAgICBzZXRIYXNoQ29kZSgpOworICB9CisKKyAgLyoqIERlZmF1bHQgY29uc3RydWN0b3IgLSBjcmVhdGVzIGVtcHR5IG9iamVjdCAqLworICBwdWJsaWMgSFJlZ2lvbkluZm8oKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLnRhYmxlRGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgSFJlZ2lvbkluZm8gd2l0aCBleHBsaWNpdCBwYXJhbWV0ZXJzCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVEZXNjIHRoZSB0YWJsZSBkZXNjcmlwdG9yCisgICAqIEBwYXJhbSBzdGFydEtleSBmaXJzdCBrZXkgaW4gcmVnaW9uCisgICAqIEBwYXJhbSBlbmRLZXkgZW5kIG9mIGtleSByYW5nZQorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25JbmZvKGZpbmFsIEhUYWJsZURlc2NyaXB0b3IgdGFibGVEZXNjLCBmaW5hbCBieXRlIFtdIHN0YXJ0S2V5LAorICAgICAgZmluYWwgYnl0ZSBbXSBlbmRLZXkpCisgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24geworICAgIHRoaXModGFibGVEZXNjLCBzdGFydEtleSwgZW5kS2V5LCBmYWxzZSk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0IEhSZWdpb25JbmZvIHdpdGggZXhwbGljaXQgcGFyYW1ldGVycworICAgKiAKKyAgICogQHBhcmFtIHRhYmxlRGVzYyB0aGUgdGFibGUgZGVzY3JpcHRvcgorICAgKiBAcGFyYW0gc3RhcnRLZXkgZmlyc3Qga2V5IGluIHJlZ2lvbgorICAgKiBAcGFyYW0gZW5kS2V5IGVuZCBvZiBrZXkgcmFuZ2UKKyAgICogQHBhcmFtIHNwbGl0IHRydWUgaWYgdGhpcyByZWdpb24gaGFzIHNwbGl0IGFuZCB3ZSBoYXZlIGRhdWdodGVyIHJlZ2lvbnMKKyAgICogcmVnaW9ucyB0aGF0IG1heSBvciBtYXkgbm90IGhvbGQgcmVmZXJlbmNlcyB0byB0aGlzIHJlZ2lvbi4KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIUmVnaW9uSW5mbyhIVGFibGVEZXNjcmlwdG9yIHRhYmxlRGVzYywgZmluYWwgYnl0ZSBbXSBzdGFydEtleSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gZW5kS2V5LCBmaW5hbCBib29sZWFuIHNwbGl0KQorICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHsKKyAgICB0aGlzKHRhYmxlRGVzYywgc3RhcnRLZXksIGVuZEtleSwgc3BsaXQsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgSFJlZ2lvbkluZm8gd2l0aCBleHBsaWNpdCBwYXJhbWV0ZXJzCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVEZXNjIHRoZSB0YWJsZSBkZXNjcmlwdG9yCisgICAqIEBwYXJhbSBzdGFydEtleSBmaXJzdCBrZXkgaW4gcmVnaW9uCisgICAqIEBwYXJhbSBlbmRLZXkgZW5kIG9mIGtleSByYW5nZQorICAgKiBAcGFyYW0gc3BsaXQgdHJ1ZSBpZiB0aGlzIHJlZ2lvbiBoYXMgc3BsaXQgYW5kIHdlIGhhdmUgZGF1Z2h0ZXIgcmVnaW9ucworICAgKiByZWdpb25zIHRoYXQgbWF5IG9yIG1heSBub3QgaG9sZCByZWZlcmVuY2VzIHRvIHRoaXMgcmVnaW9uLgorICAgKiBAcGFyYW0gcmVnaW9uaWQgUmVnaW9uIGlkIHRvIHVzZS4KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIUmVnaW9uSW5mbyhIVGFibGVEZXNjcmlwdG9yIHRhYmxlRGVzYywgZmluYWwgYnl0ZSBbXSBzdGFydEtleSwKKyAgICBmaW5hbCBieXRlIFtdIGVuZEtleSwgZmluYWwgYm9vbGVhbiBzcGxpdCwgZmluYWwgbG9uZyByZWdpb25pZCkKKyAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgc3VwZXIoKTsKKyAgICBpZiAodGFibGVEZXNjID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInRhYmxlRGVzYyBjYW5ub3QgYmUgbnVsbCIpOworICAgIH0KKyAgICB0aGlzLm9mZkxpbmUgPSBmYWxzZTsKKyAgICB0aGlzLnJlZ2lvbklkID0gcmVnaW9uaWQ7CisgICAgdGhpcy5yZWdpb25OYW1lID0gY3JlYXRlUmVnaW9uTmFtZSh0YWJsZURlc2MuZ2V0TmFtZSgpLCBzdGFydEtleSwgcmVnaW9uSWQpOworICAgIHRoaXMucmVnaW9uTmFtZVN0ciA9IEJ5dGVzLnRvU3RyaW5nKHRoaXMucmVnaW9uTmFtZSk7CisgICAgdGhpcy5zcGxpdCA9IHNwbGl0OworICAgIHRoaXMuZW5kS2V5ID0gZW5kS2V5ID09IG51bGw/IEhDb25zdGFudHMuRU1QVFlfRU5EX1JPVzogZW5kS2V5LmNsb25lKCk7CisgICAgdGhpcy5zdGFydEtleSA9IHN0YXJ0S2V5ID09IG51bGw/CisgICAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVzogc3RhcnRLZXkuY2xvbmUoKTsKKyAgICB0aGlzLnRhYmxlRGVzYyA9IHRhYmxlRGVzYzsKKyAgICBzZXRIYXNoQ29kZSgpOworICB9CisgIAorICAvKioKKyAgICogQ29zdHJ1Y3QgYSBjb3B5IG9mIGFub3RoZXIgSFJlZ2lvbkluZm8KKyAgICogCisgICAqIEBwYXJhbSBvdGhlcgorICAgKi8KKyAgcHVibGljIEhSZWdpb25JbmZvKEhSZWdpb25JbmZvIG90aGVyKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLmVuZEtleSA9IG90aGVyLmdldEVuZEtleSgpOworICAgIHRoaXMub2ZmTGluZSA9IG90aGVyLmlzT2ZmbGluZSgpOworICAgIHRoaXMucmVnaW9uSWQgPSBvdGhlci5nZXRSZWdpb25JZCgpOworICAgIHRoaXMucmVnaW9uTmFtZSA9IG90aGVyLmdldFJlZ2lvbk5hbWUoKTsKKyAgICB0aGlzLnJlZ2lvbk5hbWVTdHIgPSBCeXRlcy50b1N0cmluZyh0aGlzLnJlZ2lvbk5hbWUpOworICAgIHRoaXMuc3BsaXQgPSBvdGhlci5pc1NwbGl0KCk7CisgICAgdGhpcy5zdGFydEtleSA9IG90aGVyLmdldFN0YXJ0S2V5KCk7CisgICAgdGhpcy50YWJsZURlc2MgPSBvdGhlci5nZXRUYWJsZURlc2MoKTsKKyAgICB0aGlzLmhhc2hDb2RlID0gb3RoZXIuaGFzaENvZGUoKTsKKyAgICB0aGlzLmVuY29kZWROYW1lID0gb3RoZXIuZ2V0RW5jb2RlZE5hbWUoKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgYnl0ZSBbXSBjcmVhdGVSZWdpb25OYW1lKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgYnl0ZSBbXSBzdGFydEtleSwgZmluYWwgbG9uZyByZWdpb25pZCkgeworICAgIHJldHVybiBjcmVhdGVSZWdpb25OYW1lKHRhYmxlTmFtZSwgc3RhcnRLZXksIExvbmcudG9TdHJpbmcocmVnaW9uaWQpKTsKKyAgfQorCisgIC8qKgorICAgKiBNYWtlIGEgcmVnaW9uIG5hbWUgb2YgcGFzc2VkIHBhcmFtZXRlcnMuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIHN0YXJ0S2V5IENhbiBiZSBudWxsCisgICAqIEBwYXJhbSBpZCBSZWdpb24gaWQuCisgICAqIEByZXR1cm4gUmVnaW9uIG5hbWUgbWFkZSBvZiBwYXNzZWQgdGFibGVOYW1lLCBzdGFydEtleSBhbmQgaWQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBjcmVhdGVSZWdpb25OYW1lKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgYnl0ZSBbXSBzdGFydEtleSwgZmluYWwgU3RyaW5nIGlkKSB7CisgICAgcmV0dXJuIGNyZWF0ZVJlZ2lvbk5hbWUodGFibGVOYW1lLCBzdGFydEtleSwgQnl0ZXMudG9CeXRlcyhpZCkpOworICB9CisgIC8qKgorICAgKiBNYWtlIGEgcmVnaW9uIG5hbWUgb2YgcGFzc2VkIHBhcmFtZXRlcnMuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIHN0YXJ0S2V5IENhbiBiZSBudWxsCisgICAqIEBwYXJhbSBpZCBSZWdpb24gaWQKKyAgICogQHJldHVybiBSZWdpb24gbmFtZSBtYWRlIG9mIHBhc3NlZCB0YWJsZU5hbWUsIHN0YXJ0S2V5IGFuZCBpZAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGNyZWF0ZVJlZ2lvbk5hbWUoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsCisgICAgICBmaW5hbCBieXRlIFtdIHN0YXJ0S2V5LCBmaW5hbCBieXRlIFtdIGlkKSB7CisgICAgYnl0ZSBbXSBiID0gbmV3IGJ5dGUgW3RhYmxlTmFtZS5sZW5ndGggKyAyICsgaWQubGVuZ3RoICsKKyAgICAgICAoc3RhcnRLZXkgPT0gbnVsbD8gMDogc3RhcnRLZXkubGVuZ3RoKV07CisgICAgaW50IG9mZnNldCA9IHRhYmxlTmFtZS5sZW5ndGg7CisgICAgU3lzdGVtLmFycmF5Y29weSh0YWJsZU5hbWUsIDAsIGIsIDAsIG9mZnNldCk7CisgICAgYltvZmZzZXQrK10gPSBERUxJTUlURVI7CisgICAgaWYgKHN0YXJ0S2V5ICE9IG51bGwgJiYgc3RhcnRLZXkubGVuZ3RoID4gMCkgeworICAgICAgU3lzdGVtLmFycmF5Y29weShzdGFydEtleSwgMCwgYiwgb2Zmc2V0LCBzdGFydEtleS5sZW5ndGgpOworICAgICAgb2Zmc2V0ICs9IHN0YXJ0S2V5Lmxlbmd0aDsKKyAgICB9CisgICAgYltvZmZzZXQrK10gPSBERUxJTUlURVI7CisgICAgU3lzdGVtLmFycmF5Y29weShpZCwgMCwgYiwgb2Zmc2V0LCBpZC5sZW5ndGgpOworICAgIHJldHVybiBiOworICB9CisgIAorICAvKioKKyAgICogU2VwYXJhdGUgZWxlbWVudHMgb2YgYSByZWdpb25OYW1lLgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcmV0dXJuIEFycmF5IG9mIGJ5dGVbXSBjb250YWluaW5nIHRhYmxlTmFtZSwgc3RhcnRLZXkgYW5kIGlkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXVtdIHBhcnNlUmVnaW9uTmFtZShmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IG9mZnNldCA9IC0xOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVnaW9uTmFtZS5sZW5ndGg7IGkrKykgeworICAgICAgaWYgKHJlZ2lvbk5hbWVbaV0gPT0gREVMSU1JVEVSKSB7CisgICAgICAgIG9mZnNldCA9IGk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICBpZihvZmZzZXQgPT0gLTEpIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCByZWdpb25OYW1lIGZvcm1hdCIpOworICAgIGJ5dGUgW10gdGFibGVOYW1lID0gbmV3IGJ5dGVbb2Zmc2V0XTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHJlZ2lvbk5hbWUsIDAsIHRhYmxlTmFtZSwgMCwgb2Zmc2V0KTsKKyAgICBvZmZzZXQgPSAtMTsKKyAgICBmb3IgKGludCBpID0gcmVnaW9uTmFtZS5sZW5ndGggLSAxOyBpID4gMDsgaS0tKSB7CisgICAgICBpZihyZWdpb25OYW1lW2ldID09IERFTElNSVRFUikgeworICAgICAgICBvZmZzZXQgPSBpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgaWYob2Zmc2V0ID09IC0xKSB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgcmVnaW9uTmFtZSBmb3JtYXQiKTsKKyAgICBieXRlIFtdIHN0YXJ0S2V5ID0gSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZOworICAgIGlmKG9mZnNldCAhPSB0YWJsZU5hbWUubGVuZ3RoICsgMSkgeworICAgICAgc3RhcnRLZXkgPSBuZXcgYnl0ZVtvZmZzZXQgLSB0YWJsZU5hbWUubGVuZ3RoIC0gMV07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KHJlZ2lvbk5hbWUsIHRhYmxlTmFtZS5sZW5ndGggKyAxLCBzdGFydEtleSwgMCwgCisgICAgICAgICAgb2Zmc2V0IC0gdGFibGVOYW1lLmxlbmd0aCAtIDEpOworICAgIH0KKyAgICBieXRlIFtdIGlkID0gbmV3IGJ5dGVbcmVnaW9uTmFtZS5sZW5ndGggLSBvZmZzZXQgLSAxXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHJlZ2lvbk5hbWUsIG9mZnNldCArIDEsIGlkLCAwLCAKKyAgICAgICAgcmVnaW9uTmFtZS5sZW5ndGggLSBvZmZzZXQgLSAxKTsKKyAgICBieXRlIFtdW10gZWxlbWVudHMgPSBuZXcgYnl0ZVszXVtdOworICAgIGVsZW1lbnRzWzBdID0gdGFibGVOYW1lOworICAgIGVsZW1lbnRzWzFdID0gc3RhcnRLZXk7CisgICAgZWxlbWVudHNbMl0gPSBpZDsKKyAgICByZXR1cm4gZWxlbWVudHM7CisgIH0KKyAgCisgIC8qKiBAcmV0dXJuIHRoZSBlbmRLZXkgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0RW5kS2V5KCl7CisgICAgcmV0dXJuIGVuZEtleTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSByZWdpb25JZCAqLworICBwdWJsaWMgbG9uZyBnZXRSZWdpb25JZCgpeworICAgIHJldHVybiByZWdpb25JZDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSByZWdpb25OYW1lIGFzIGFuIGFycmF5IG9mIGJ5dGVzLgorICAgKiBAc2VlICNnZXRSZWdpb25OYW1lQXNTdHJpbmcoKQorICAgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0UmVnaW9uTmFtZSgpeworICAgIHJldHVybiByZWdpb25OYW1lOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmVnaW9uIG5hbWUgYXMgYSBTdHJpbmcgZm9yIHVzZSBpbiBsb2dnaW5nLCBldGMuCisgICAqLworICBwdWJsaWMgU3RyaW5nIGdldFJlZ2lvbk5hbWVBc1N0cmluZygpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25OYW1lU3RyOworICB9CisgIAorICAvKiogQHJldHVybiB0aGUgZW5jb2RlZCByZWdpb24gbmFtZSAqLworICBwdWJsaWMgc3luY2hyb25pemVkIGludCBnZXRFbmNvZGVkTmFtZSgpIHsKKyAgICBpZiAodGhpcy5lbmNvZGVkTmFtZSA9PSBOT19IQVNIKSB7CisgICAgICB0aGlzLmVuY29kZWROYW1lID0gZW5jb2RlUmVnaW9uTmFtZSh0aGlzLnJlZ2lvbk5hbWUpOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5lbmNvZGVkTmFtZTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBzdGFydEtleSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRTdGFydEtleSgpeworICAgIHJldHVybiBzdGFydEtleTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSB0YWJsZURlc2MgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3IgZ2V0VGFibGVEZXNjKCl7CisgICAgcmV0dXJuIHRhYmxlRGVzYzsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbmV3RGVzYyBuZXcgdGFibGUgZGVzY3JpcHRvciB0byB1c2UKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFRhYmxlRGVzYyhIVGFibGVEZXNjcmlwdG9yIG5ld0Rlc2MpIHsKKyAgICB0aGlzLnRhYmxlRGVzYyA9IG5ld0Rlc2M7CisgIH0KKworICAvKiogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgdGhlIHJvb3QgcmVnaW9uICovCisgIHB1YmxpYyBib29sZWFuIGlzUm9vdFJlZ2lvbigpIHsKKyAgICByZXR1cm4gdGhpcy50YWJsZURlc2MuaXNSb290UmVnaW9uKCk7CisgIH0KKyAgCisgIC8qKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyB0aGUgbWV0YSB0YWJsZSAqLworICBwdWJsaWMgYm9vbGVhbiBpc01ldGFUYWJsZSgpIHsKKyAgICByZXR1cm4gdGhpcy50YWJsZURlc2MuaXNNZXRhVGFibGUoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRydWUgaWYgdGhpcyByZWdpb24gaXMgYSBtZXRhIHJlZ2lvbiAqLworICBwdWJsaWMgYm9vbGVhbiBpc01ldGFSZWdpb24oKSB7CisgICAgcmV0dXJuIHRoaXMudGFibGVEZXNjLmlzTWV0YVJlZ2lvbigpOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiBUcnVlIGlmIGhhcyBiZWVuIHNwbGl0IGFuZCBoYXMgZGF1Z2h0ZXJzLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNTcGxpdCgpIHsKKyAgICByZXR1cm4gdGhpcy5zcGxpdDsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBzcGxpdCBzZXQgc3BsaXQgc3RhdHVzCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRTcGxpdChib29sZWFuIHNwbGl0KSB7CisgICAgdGhpcy5zcGxpdCA9IHNwbGl0OworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIHJlZ2lvbiBpcyBvZmZsaW5lLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNPZmZsaW5lKCkgeworICAgIHJldHVybiB0aGlzLm9mZkxpbmU7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG9mZkxpbmUgc2V0IG9ubGluZSAtIG9mZmxpbmUgc3RhdHVzCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRPZmZsaW5lKGJvb2xlYW4gb2ZmTGluZSkgeworICAgIHRoaXMub2ZmTGluZSA9IG9mZkxpbmU7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiUkVHSU9OID0+IHsiICsgSENvbnN0YW50cy5OQU1FICsgIiA9PiAnIiArCisgICAgICB0aGlzLnJlZ2lvbk5hbWVTdHIgKworICAgICAgIicsIFNUQVJUS0VZID0+ICciICsKKyAgICAgIEJ5dGVzLnRvU3RyaW5nKHRoaXMuc3RhcnRLZXkpICsgIicsIEVOREtFWSA9PiAnIiArCisgICAgICBCeXRlcy50b1N0cmluZyh0aGlzLmVuZEtleSkgKyAKKyAgICAgICInLCBFTkNPREVEID0+ICIgKyBnZXRFbmNvZGVkTmFtZSgpICsgIiwiICsKKyAgICAgIChpc09mZmxpbmUoKT8gIiBPRkZMSU5FID0+IHRydWUsIjogIiIpICsgCisgICAgICAoaXNTcGxpdCgpPyAiIFNQTElUID0+IHRydWUsIjogIiIpICsKKyAgICAgICIgVEFCTEUgPT4geyIgKyB0aGlzLnRhYmxlRGVzYy50b1N0cmluZygpICsgIn0iOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNlcXVhbHMoamF2YS5sYW5nLk9iamVjdCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICBpZiAodGhpcyA9PSBvKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKG8gPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIShvIGluc3RhbmNlb2YgSFJlZ2lvbkluZm8pKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0aGlzLmNvbXBhcmVUbygoSFJlZ2lvbkluZm8pbykgPT0gMDsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjaGFzaENvZGUoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIHRoaXMuaGFzaENvZGU7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgb2JqZWN0IHZlcnNpb24gbnVtYmVyICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYnl0ZSBnZXRWZXJzaW9uKCkgeworICAgIHJldHVybiBWRVJTSU9OOworICB9CisKKyAgLy8KKyAgLy8gV3JpdGFibGUKKyAgLy8KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIud3JpdGUob3V0KTsKKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGVuZEtleSk7CisgICAgb3V0LndyaXRlQm9vbGVhbihvZmZMaW5lKTsKKyAgICBvdXQud3JpdGVMb25nKHJlZ2lvbklkKTsKKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIHJlZ2lvbk5hbWUpOworICAgIG91dC53cml0ZUJvb2xlYW4oc3BsaXQpOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgc3RhcnRLZXkpOworICAgIHRhYmxlRGVzYy53cml0ZShvdXQpOworICAgIG91dC53cml0ZUludChoYXNoQ29kZSk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlci5yZWFkRmllbGRzKGluKTsKKyAgICB0aGlzLmVuZEtleSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgIHRoaXMub2ZmTGluZSA9IGluLnJlYWRCb29sZWFuKCk7CisgICAgdGhpcy5yZWdpb25JZCA9IGluLnJlYWRMb25nKCk7CisgICAgdGhpcy5yZWdpb25OYW1lID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgdGhpcy5yZWdpb25OYW1lU3RyID0gQnl0ZXMudG9TdHJpbmcodGhpcy5yZWdpb25OYW1lKTsKKyAgICB0aGlzLnNwbGl0ID0gaW4ucmVhZEJvb2xlYW4oKTsKKyAgICB0aGlzLnN0YXJ0S2V5ID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgdGhpcy50YWJsZURlc2MucmVhZEZpZWxkcyhpbik7CisgICAgdGhpcy5oYXNoQ29kZSA9IGluLnJlYWRJbnQoKTsKKyAgfQorICAKKyAgLy8KKyAgLy8gQ29tcGFyYWJsZQorICAvLworICAKKyAgcHVibGljIGludCBjb21wYXJlVG8oSFJlZ2lvbkluZm8gbykgeworICAgIGlmIChvID09IG51bGwpIHsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICAKKyAgICAvLyBBcmUgcmVnaW9ucyBvZiBzYW1lIHRhYmxlPworICAgIGludCByZXN1bHQgPSB0aGlzLnRhYmxlRGVzYy5jb21wYXJlVG8oby50YWJsZURlc2MpOworICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvLyBDb21wYXJlIHN0YXJ0IGtleXMuCisgICAgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKHRoaXMuc3RhcnRLZXksIG8uc3RhcnRLZXkpOworICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgCisgICAgLy8gQ29tcGFyZSBlbmQga2V5cy4KKyAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKHRoaXMuZW5kS2V5LCBvLmVuZEtleSk7CisgIH0KKworICAvKioKKyAgICogRm9yIGludGVybmFsIHVzZSBpbiBmb3JjaW5nIHNwbGl0cyBhaGVhZCBvZiBmaWxlIHNpemUgbGltaXQuCisgICAqIEBwYXJhbSBiCisgICAqIEByZXR1cm4gcHJldmlvdXMgdmFsdWUKKyAgICovCisgIHB1YmxpYyBib29sZWFuIHNob3VsZFNwbGl0KGJvb2xlYW4gYikgeworICAgIGJvb2xlYW4gb2xkID0gdGhpcy5zcGxpdFJlcXVlc3Q7CisgICAgdGhpcy5zcGxpdFJlcXVlc3QgPSBiOworICAgIHJldHVybiBvbGQ7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDb21wYXJhdG9yIHRvIHVzZSBjb21wYXJpbmcge0BsaW5rIEtleVZhbHVlfXMuCisgICAqLworICBwdWJsaWMgS1ZDb21wYXJhdG9yIGdldENvbXBhcmF0b3IoKSB7CisgICAgcmV0dXJuIGlzUm9vdFJlZ2lvbigpPyBLZXlWYWx1ZS5ST09UX0NPTVBBUkFUT1I6IGlzTWV0YVJlZ2lvbigpPworICAgICAgS2V5VmFsdWUuTUVUQV9DT01QQVJBVE9SOiBLZXlWYWx1ZS5DT01QQVJBVE9SOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFJlZ2lvbkxvY2F0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IUmVnaW9uTG9jYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YmUwY2ZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFJlZ2lvbkxvY2F0aW9uLmphdmEKQEAgLTAsMCArMSw5OCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisvKioKKyAqIENvbnRhaW5zIHRoZSBIUmVnaW9uSW5mbyBmb3IgdGhlIHJlZ2lvbiBhbmQgdGhlIEhTZXJ2ZXJBZGRyZXNzIGZvciB0aGUKKyAqIEhSZWdpb25TZXJ2ZXIgc2VydmluZyB0aGUgcmVnaW9uCisgKi8KK3B1YmxpYyBjbGFzcyBIUmVnaW9uTG9jYXRpb24gaW1wbGVtZW50cyBDb21wYXJhYmxlPEhSZWdpb25Mb2NhdGlvbj4geworICBwcml2YXRlIEhSZWdpb25JbmZvIHJlZ2lvbkluZm87CisgIHByaXZhdGUgSFNlcnZlckFkZHJlc3Mgc2VydmVyQWRkcmVzczsKKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogCisgICAqIEBwYXJhbSByZWdpb25JbmZvIHRoZSBIUmVnaW9uSW5mbyBmb3IgdGhlIHJlZ2lvbgorICAgKiBAcGFyYW0gc2VydmVyQWRkcmVzcyB0aGUgSFNlcnZlckFkZHJlc3MgZm9yIHRoZSByZWdpb24gc2VydmVyCisgICAqLworICBwdWJsaWMgSFJlZ2lvbkxvY2F0aW9uKEhSZWdpb25JbmZvIHJlZ2lvbkluZm8sIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlckFkZHJlc3MpIHsKKyAgICB0aGlzLnJlZ2lvbkluZm8gPSByZWdpb25JbmZvOworICAgIHRoaXMuc2VydmVyQWRkcmVzcyA9IHNlcnZlckFkZHJlc3M7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiYWRkcmVzczogIiArIHRoaXMuc2VydmVyQWRkcmVzcy50b1N0cmluZygpICsgIiwgcmVnaW9uaW5mbzogIiArCisgICAgICB0aGlzLnJlZ2lvbkluZm87CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICghKG8gaW5zdGFuY2VvZiBIUmVnaW9uTG9jYXRpb24pKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0aGlzLmNvbXBhcmVUbygoSFJlZ2lvbkxvY2F0aW9uKW8pID09IDA7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2hhc2hDb2RlKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCByZXN1bHQgPSB0aGlzLnJlZ2lvbkluZm8uaGFzaENvZGUoKTsKKyAgICByZXN1bHQgXj0gdGhpcy5zZXJ2ZXJBZGRyZXNzLmhhc2hDb2RlKCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gSFJlZ2lvbkluZm8gKi8KKyAgcHVibGljIEhSZWdpb25JbmZvIGdldFJlZ2lvbkluZm8oKXsKKyAgICByZXR1cm4gcmVnaW9uSW5mbzsKKyAgfQorCisgIC8qKiBAcmV0dXJuIEhTZXJ2ZXJBZGRyZXNzICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyBnZXRTZXJ2ZXJBZGRyZXNzKCl7CisgICAgcmV0dXJuIHNlcnZlckFkZHJlc3M7CisgIH0KKworICAvLworICAvLyBDb21wYXJhYmxlCisgIC8vCisgIAorICBwdWJsaWMgaW50IGNvbXBhcmVUbyhIUmVnaW9uTG9jYXRpb24gbykgeworICAgIGludCByZXN1bHQgPSB0aGlzLnJlZ2lvbkluZm8uY29tcGFyZVRvKG8ucmVnaW9uSW5mbyk7CisgICAgaWYocmVzdWx0ID09IDApIHsKKyAgICAgIHJlc3VsdCA9IHRoaXMuc2VydmVyQWRkcmVzcy5jb21wYXJlVG8oby5zZXJ2ZXJBZGRyZXNzKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hTZXJ2ZXJBZGRyZXNzLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IU2VydmVyQWRkcmVzcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViNTRiMTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IU2VydmVyQWRkcmVzcy5qYXZhCkBAIC0wLDAgKzEsMTg3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby4qOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CisKKy8qKgorICogSFNlcnZlckFkZHJlc3MgaXMgYSAibGFiZWwiIGZvciBhIEhCYXNlIHNlcnZlciB0aGF0IGNvbWJpbmVzIHRoZSBob3N0CisgKiBuYW1lIGFuZCBwb3J0IG51bWJlci4KKyAqLworcHVibGljIGNsYXNzIEhTZXJ2ZXJBZGRyZXNzIGltcGxlbWVudHMgV3JpdGFibGVDb21wYXJhYmxlPEhTZXJ2ZXJBZGRyZXNzPiB7CisgIHByaXZhdGUgSW5ldFNvY2tldEFkZHJlc3MgYWRkcmVzczsKKyAgU3RyaW5nIHN0cmluZ1ZhbHVlOworCisgIC8qKiBFbXB0eSBjb25zdHJ1Y3RvciwgdXNlZCBmb3IgV3JpdGFibGUgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzKCkgeworICAgIHRoaXMuYWRkcmVzcyA9IG51bGw7CisgICAgdGhpcy5zdHJpbmdWYWx1ZSA9IG51bGw7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0IGEgSFNlcnZlckFkZHJlc3MgZnJvbSBhbiBJbmV0U29ja2V0QWRkcmVzcworICAgKiBAcGFyYW0gYWRkcmVzcyBJbmV0U29ja2V0QWRkcmVzcyBvZiBzZXJ2ZXIKKyAgICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyhJbmV0U29ja2V0QWRkcmVzcyBhZGRyZXNzKSB7CisgICAgdGhpcy5hZGRyZXNzID0gYWRkcmVzczsKKyAgICB0aGlzLnN0cmluZ1ZhbHVlID0gYWRkcmVzcy5nZXRBZGRyZXNzKCkuZ2V0SG9zdEFkZHJlc3MoKSArICI6IiArCisgICAgICBhZGRyZXNzLmdldFBvcnQoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIEhTZXJ2ZXJBZGRyZXNzIGZyb20gYSBzdHJpbmcgb2YgdGhlIGZvcm0gaG9zdG5hbWU6cG9ydAorICAgKiAKKyAgICogQHBhcmFtIGhvc3RBbmRQb3J0IGZvcm1hdCAnaG9zdG5hbWU6cG9ydCcKKyAgICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyhTdHJpbmcgaG9zdEFuZFBvcnQpIHsKKyAgICBpbnQgY29sb25JbmRleCA9IGhvc3RBbmRQb3J0Lmxhc3RJbmRleE9mKCc6Jyk7CisgICAgaWYoY29sb25JbmRleCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhIGhvc3Q6cG9ydCBwYWlyOiAiICsgaG9zdEFuZFBvcnQpOworICAgIH0KKyAgICBTdHJpbmcgaG9zdCA9IGhvc3RBbmRQb3J0LnN1YnN0cmluZygwLCBjb2xvbkluZGV4KTsKKyAgICBpbnQgcG9ydCA9CisgICAgICBJbnRlZ2VyLnZhbHVlT2YoaG9zdEFuZFBvcnQuc3Vic3RyaW5nKGNvbG9uSW5kZXggKyAxKSkuaW50VmFsdWUoKTsKKyAgICB0aGlzLmFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoaG9zdCwgcG9ydCk7CisgICAgdGhpcy5zdHJpbmdWYWx1ZSA9IGhvc3RBbmRQb3J0OworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0IGEgSFNlcnZlckFkZHJlc3MgZnJvbSBob3N0bmFtZSwgcG9ydCBudW1iZXIKKyAgICogQHBhcmFtIGJpbmRBZGRyZXNzIGhvc3QgbmFtZQorICAgKiBAcGFyYW0gcG9ydCBwb3J0IG51bWJlcgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzKFN0cmluZyBiaW5kQWRkcmVzcywgaW50IHBvcnQpIHsKKyAgICB0aGlzLmFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoYmluZEFkZHJlc3MsIHBvcnQpOworICAgIHRoaXMuc3RyaW5nVmFsdWUgPSBiaW5kQWRkcmVzcyArICI6IiArIHBvcnQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgYSBIU2VydmVyQWRkcmVzcyBmcm9tIGFub3RoZXIgSFNlcnZlckFkZHJlc3MKKyAgICogCisgICAqIEBwYXJhbSBvdGhlciB0aGUgSFNlcnZlckFkZHJlc3MgdG8gY29weSBmcm9tCisgICAqLworICBwdWJsaWMgSFNlcnZlckFkZHJlc3MoSFNlcnZlckFkZHJlc3Mgb3RoZXIpIHsKKyAgICBTdHJpbmcgYmluZEFkZHJlc3MgPSBvdGhlci5nZXRCaW5kQWRkcmVzcygpOworICAgIGludCBwb3J0ID0gb3RoZXIuZ2V0UG9ydCgpOworICAgIGFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoYmluZEFkZHJlc3MsIHBvcnQpOworICAgIHN0cmluZ1ZhbHVlID0gYmluZEFkZHJlc3MgKyAiOiIgKyBwb3J0OworICB9CisKKyAgLyoqIEByZXR1cm4gYmluZCBhZGRyZXNzICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0QmluZEFkZHJlc3MoKSB7CisgICAgcmV0dXJuIGFkZHJlc3MuZ2V0QWRkcmVzcygpLmdldEhvc3RBZGRyZXNzKCk7CisgIH0KKworICAvKiogQHJldHVybiBwb3J0IG51bWJlciAqLworICBwdWJsaWMgaW50IGdldFBvcnQoKSB7CisgICAgcmV0dXJuIGFkZHJlc3MuZ2V0UG9ydCgpOworICB9CisgIAorICAvKiogQHJldHVybiBob3N0IG5hbWUgKi8KKyAgcHVibGljIFN0cmluZyBnZXRIb3N0bmFtZSgpIHsKKyAgICByZXR1cm4gYWRkcmVzcy5nZXRIb3N0TmFtZSgpOworICB9CisKKyAgLyoqIEByZXR1cm4gdGhlIEluZXRTb2NrZXRBZGRyZXNzICovCisgIHB1YmxpYyBJbmV0U29ja2V0QWRkcmVzcyBnZXRJbmV0U29ja2V0QWRkcmVzcygpIHsKKyAgICByZXR1cm4gYWRkcmVzczsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjdG9TdHJpbmcoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIChzdHJpbmdWYWx1ZSA9PSBudWxsID8gIiIgOiBzdHJpbmdWYWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChnZXRDbGFzcygpICE9IG8uZ2V0Q2xhc3MoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5jb21wYXJlVG8oKEhTZXJ2ZXJBZGRyZXNzKW8pID09IDA7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2hhc2hDb2RlKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCByZXN1bHQgPSB0aGlzLmFkZHJlc3MuaGFzaENvZGUoKTsKKyAgICByZXN1bHQgXj0gdGhpcy5zdHJpbmdWYWx1ZS5oYXNoQ29kZSgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8vCisgIC8vIFdyaXRhYmxlCisgIC8vCisKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU3RyaW5nIGJpbmRBZGRyZXNzID0gaW4ucmVhZFVURigpOworICAgIGludCBwb3J0ID0gaW4ucmVhZEludCgpOworICAgIAorICAgIGlmKGJpbmRBZGRyZXNzID09IG51bGwgfHwgYmluZEFkZHJlc3MubGVuZ3RoKCkgPT0gMCkgeworICAgICAgYWRkcmVzcyA9IG51bGw7CisgICAgICBzdHJpbmdWYWx1ZSA9IG51bGw7CisgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgYWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhiaW5kQWRkcmVzcywgcG9ydCk7CisgICAgICBzdHJpbmdWYWx1ZSA9IGJpbmRBZGRyZXNzICsgIjoiICsgcG9ydDsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZihhZGRyZXNzID09IG51bGwpIHsKKyAgICAgIG91dC53cml0ZVVURigiIik7CisgICAgICBvdXQud3JpdGVJbnQoMCk7CisgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgb3V0LndyaXRlVVRGKGFkZHJlc3MuZ2V0QWRkcmVzcygpLmdldEhvc3RBZGRyZXNzKCkpOworICAgICAgb3V0LndyaXRlSW50KGFkZHJlc3MuZ2V0UG9ydCgpKTsKKyAgICB9CisgIH0KKyAgCisgIC8vCisgIC8vIENvbXBhcmFibGUKKyAgLy8KKyAgCisgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEhTZXJ2ZXJBZGRyZXNzIG8pIHsKKyAgICAvLyBBZGRyZXNzZXMgYXMgU3RyaW5ncyBtYXkgbm90IGNvbXBhcmUgdGhvdWdoIGFkZHJlc3MgaXMgZm9yIHRoZSBvbmUKKyAgICAvLyBzZXJ2ZXIgd2l0aCBvbmx5IGRpZmZlcmVuY2UgYmVpbmcgdGhhdCBvbmUgYWRkcmVzcyBoYXMgaG9zdG5hbWUKKyAgICAvLyByZXNvbHZlZCB3aGVyZWFzIG90aGVyIG9ubHkgaGFzIElQLgorICAgIGlmICh0aGlzLmFkZHJlc3MuZXF1YWxzKG8uYWRkcmVzcykpIHJldHVybiAwOworICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKCkuY29tcGFyZVRvKG8udG9TdHJpbmcoKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IU2VydmVySW5mby5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFNlcnZlckluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzAwNWUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFNlcnZlckluZm8uamF2YQpAQCAtMCwwICsxLDI1NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CisKKworLyoqCisgKiBIU2VydmVySW5mbyBjb250YWlucyBtZXRhaW5mbyBhYm91dCBhbiBIUmVnaW9uU2VydmVyLCBDdXJyZW50bHkgaXQgb25seQorICogY29udGFpbnMgdGhlIHNlcnZlciBzdGFydCBjb2RlLgorICogCisgKiBJbiB0aGUgZnV0dXJlIGl0IHdpbGwgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc291cmNlIG1hY2hpbmUgYW5kCisgKiBsb2FkIHN0YXRpc3RpY3MuCisgKi8KK3B1YmxpYyBjbGFzcyBIU2VydmVySW5mbyBpbXBsZW1lbnRzIFdyaXRhYmxlQ29tcGFyYWJsZTxIU2VydmVySW5mbz4geworICBwcml2YXRlIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlckFkZHJlc3M7CisgIHByaXZhdGUgbG9uZyBzdGFydENvZGU7CisgIHByaXZhdGUgSFNlcnZlckxvYWQgbG9hZDsKKyAgcHJpdmF0ZSBpbnQgaW5mb1BvcnQ7CisgIHByaXZhdGUgdHJhbnNpZW50IHZvbGF0aWxlIFN0cmluZyBzZXJ2ZXJOYW1lID0gbnVsbDsKKyAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAtIHVzZWQgYnkgV3JpdGFibGUgKi8KKyAgcHVibGljIEhTZXJ2ZXJJbmZvKCkgeworICAgIHRoaXMobmV3IEhTZXJ2ZXJBZGRyZXNzKCksIDAsIAorICAgICAgICBIQ29uc3RhbnRzLkRFRkFVTFRfUkVHSU9OU0VSVkVSX0lORk9QT1JULCAiZGVmYXVsdCBuYW1lIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gc2VydmVyQWRkcmVzcworICAgKiBAcGFyYW0gc3RhcnRDb2RlCisgICAqIEBwYXJhbSBpbmZvUG9ydCBQb3J0IHRoZSBpbmZvIHNlcnZlciBpcyBsaXN0ZW5pbmcgb24uCisgICAqLworICBwdWJsaWMgSFNlcnZlckluZm8oSFNlcnZlckFkZHJlc3Mgc2VydmVyQWRkcmVzcywgbG9uZyBzdGFydENvZGUsCisgICAgICBmaW5hbCBpbnQgaW5mb1BvcnQsIFN0cmluZyBuYW1lKSB7CisgICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gc2VydmVyQWRkcmVzczsKKyAgICB0aGlzLnN0YXJ0Q29kZSA9IHN0YXJ0Q29kZTsKKyAgICB0aGlzLmxvYWQgPSBuZXcgSFNlcnZlckxvYWQoKTsKKyAgICB0aGlzLmluZm9Qb3J0ID0gaW5mb1BvcnQ7CisgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIG5ldyBvYmplY3QgdXNpbmcgYW5vdGhlciBhcyBpbnB1dCAobGlrZSBhIGNvcHkgY29uc3RydWN0b3IpCisgICAqIEBwYXJhbSBvdGhlcgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJJbmZvKEhTZXJ2ZXJJbmZvIG90aGVyKSB7CisgICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gbmV3IEhTZXJ2ZXJBZGRyZXNzKG90aGVyLmdldFNlcnZlckFkZHJlc3MoKSk7CisgICAgdGhpcy5zdGFydENvZGUgPSBvdGhlci5nZXRTdGFydENvZGUoKTsKKyAgICB0aGlzLmxvYWQgPSBvdGhlci5nZXRMb2FkKCk7CisgICAgdGhpcy5pbmZvUG9ydCA9IG90aGVyLmdldEluZm9Qb3J0KCk7CisgICAgdGhpcy5uYW1lID0gb3RoZXIuZ2V0TmFtZSgpOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiB0aGUgbG9hZAorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJMb2FkIGdldExvYWQoKSB7CisgICAgcmV0dXJuIGxvYWQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGxvYWQgdGhlIGxvYWQgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRMb2FkKEhTZXJ2ZXJMb2FkIGxvYWQpIHsKKyAgICB0aGlzLmxvYWQgPSBsb2FkOworICB9CisKKyAgLyoqIEByZXR1cm4gdGhlIHNlcnZlciBhZGRyZXNzICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgSFNlcnZlckFkZHJlc3MgZ2V0U2VydmVyQWRkcmVzcygpIHsKKyAgICByZXR1cm4gbmV3IEhTZXJ2ZXJBZGRyZXNzKHNlcnZlckFkZHJlc3MpOworICB9CisgIAorICAvKioKKyAgICogQ2hhbmdlIHRoZSBzZXJ2ZXIgYWRkcmVzcy4KKyAgICogQHBhcmFtIHNlcnZlckFkZHJlc3MgTmV3IHNlcnZlciBhZGRyZXNzCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U2VydmVyQWRkcmVzcyhIU2VydmVyQWRkcmVzcyBzZXJ2ZXJBZGRyZXNzKSB7CisgICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gc2VydmVyQWRkcmVzczsKKyAgICB0aGlzLnNlcnZlck5hbWUgPSBudWxsOworICB9CisgCisgIC8qKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgc3RhcnQgY29kZSAqLworICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgZ2V0U3RhcnRDb2RlKCkgeworICAgIHJldHVybiBzdGFydENvZGU7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIFBvcnQgdGhlIGluZm8gc2VydmVyIGlzIGxpc3RlbmluZyBvbi4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0SW5mb1BvcnQoKSB7CisgICAgcmV0dXJuIHRoaXMuaW5mb1BvcnQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gaW5mb1BvcnQgLSBuZXcgcG9ydCBvZiBpbmZvIHNlcnZlcgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0SW5mb1BvcnQoaW50IGluZm9Qb3J0KSB7CisgICAgdGhpcy5pbmZvUG9ydCA9IGluZm9Qb3J0OworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHN0YXJ0Q29kZSB0aGUgc3RhcnRDb2RlIHRvIHNldAorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNldFN0YXJ0Q29kZShsb25nIHN0YXJ0Q29kZSkgeworICAgIHRoaXMuc3RhcnRDb2RlID0gc3RhcnRDb2RlOworICAgIHRoaXMuc2VydmVyTmFtZSA9IG51bGw7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgbmFtZSBpbiB0aGUgZm9ybSBob3N0bmFtZV9zdGFydGNvZGVfcG9ydAorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0U2VydmVyTmFtZSgpIHsKKyAgICBpZiAodGhpcy5zZXJ2ZXJOYW1lID09IG51bGwpIHsKKyAgICAgIHRoaXMuc2VydmVyTmFtZSA9IGdldFNlcnZlck5hbWUodGhpcy5zZXJ2ZXJBZGRyZXNzLCB0aGlzLnN0YXJ0Q29kZSk7CisgICAgfQorICAgIHJldHVybiB0aGlzLnNlcnZlck5hbWU7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIGhvc3RuYW1lIG9mIHRoZSBzZXJ2ZXIKKyAgICogQHJldHVybiBob3N0bmFtZQorICAgKi8KKyAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgIHJldHVybiBuYW1lOworICB9CisgCisgIC8qKgorICAgKiBTZXQgdGhlIGhvc3RuYW1lIG9mIHRoZSBzZXJ2ZXIKKyAgICogQHBhcmFtIG5hbWUgaG9zdG5hbWUKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKKyAgICB0aGlzLm5hbWUgPSBuYW1lOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gImFkZHJlc3M6ICIgKyB0aGlzLnNlcnZlckFkZHJlc3MgKyAiLCBzdGFydGNvZGU6ICIgKyB0aGlzLnN0YXJ0Q29kZQorICAgICsgIiwgbG9hZDogKCIgKyB0aGlzLmxvYWQudG9TdHJpbmcoKSArICIpIjsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGdldENsYXNzKCkgIT0gb2JqLmdldENsYXNzKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIGNvbXBhcmVUbygoSFNlcnZlckluZm8pb2JqKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gdGhpcy5nZXRTZXJ2ZXJOYW1lKCkuaGFzaENvZGUoKTsKKyAgfQorCisKKyAgLy8gV3JpdGFibGUKKyAgCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuc2VydmVyQWRkcmVzcy5yZWFkRmllbGRzKGluKTsKKyAgICB0aGlzLnN0YXJ0Q29kZSA9IGluLnJlYWRMb25nKCk7CisgICAgdGhpcy5sb2FkLnJlYWRGaWVsZHMoaW4pOworICAgIHRoaXMuaW5mb1BvcnQgPSBpbi5yZWFkSW50KCk7CisgICAgdGhpcy5uYW1lID0gaW4ucmVhZFVURigpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5zZXJ2ZXJBZGRyZXNzLndyaXRlKG91dCk7CisgICAgb3V0LndyaXRlTG9uZyh0aGlzLnN0YXJ0Q29kZSk7CisgICAgdGhpcy5sb2FkLndyaXRlKG91dCk7CisgICAgb3V0LndyaXRlSW50KHRoaXMuaW5mb1BvcnQpOworICAgIG91dC53cml0ZVVURihuYW1lKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEhTZXJ2ZXJJbmZvIG8pIHsKKyAgICByZXR1cm4gdGhpcy5nZXRTZXJ2ZXJOYW1lKCkuY29tcGFyZVRvKG8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgbmFtZSBpbiB0aGUgZm9ybSBob3N0bmFtZV9zdGFydGNvZGVfcG9ydAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U2VydmVyTmFtZShIU2VydmVySW5mbyBpbmZvKSB7CisgICAgcmV0dXJuIGdldFNlcnZlck5hbWUoaW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCksIGluZm8uZ2V0U3RhcnRDb2RlKCkpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHNlcnZlckFkZHJlc3MgaW4gdGhlIGZvcm0gaG9zdG5hbWU6cG9ydAorICAgKiBAcGFyYW0gc3RhcnRDb2RlCisgICAqIEByZXR1cm4gdGhlIHNlcnZlciBuYW1lIGluIHRoZSBmb3JtIGhvc3RuYW1lX3N0YXJ0Y29kZV9wb3J0CisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTZXJ2ZXJOYW1lKFN0cmluZyBzZXJ2ZXJBZGRyZXNzLCBsb25nIHN0YXJ0Q29kZSkgeworICAgIFN0cmluZyBuYW1lID0gbnVsbDsKKyAgICBpZiAoc2VydmVyQWRkcmVzcyAhPSBudWxsKSB7CisgICAgICBIU2VydmVyQWRkcmVzcyBhZGRyZXNzID0gbmV3IEhTZXJ2ZXJBZGRyZXNzKHNlcnZlckFkZHJlc3MpOworICAgICAgbmFtZSA9IGdldFNlcnZlck5hbWUoYWRkcmVzcy5nZXRIb3N0bmFtZSgpLCBhZGRyZXNzLmdldFBvcnQoKSwgc3RhcnRDb2RlKTsKKyAgICB9CisgICAgcmV0dXJuIG5hbWU7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGFkZHJlc3MKKyAgICogQHBhcmFtIHN0YXJ0Q29kZQorICAgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgbmFtZSBpbiB0aGUgZm9ybSBob3N0bmFtZV9zdGFydGNvZGVfcG9ydAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U2VydmVyTmFtZShIU2VydmVyQWRkcmVzcyBhZGRyZXNzLCBsb25nIHN0YXJ0Q29kZSkgeworICAgIHJldHVybiBnZXRTZXJ2ZXJOYW1lKGFkZHJlc3MuZ2V0SG9zdG5hbWUoKSwgYWRkcmVzcy5nZXRQb3J0KCksIHN0YXJ0Q29kZSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0U2VydmVyTmFtZShTdHJpbmcgaG9zdE5hbWUsIGludCBwb3J0LCBsb25nIHN0YXJ0Q29kZSkgeworICAgIFN0cmluZ0J1aWxkZXIgbmFtZSA9IG5ldyBTdHJpbmdCdWlsZGVyKGhvc3ROYW1lKTsKKyAgICBuYW1lLmFwcGVuZCgiXyIpOworICAgIG5hbWUuYXBwZW5kKHN0YXJ0Q29kZSk7CisgICAgbmFtZS5hcHBlbmQoIl8iKTsKKyAgICBuYW1lLmFwcGVuZChwb3J0KTsKKyAgICByZXR1cm4gbmFtZS50b1N0cmluZygpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IU2VydmVyTG9hZC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFNlcnZlckxvYWQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWJhZTQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFNlcnZlckxvYWQuamF2YQpAQCAtMCwwICsxLDQzNyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuU3RyaW5nczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CisKKy8qKgorICogVGhpcyBjbGFzcyBlbmNhcHN1bGF0ZXMgbWV0cmljcyBmb3IgZGV0ZXJtaW5pbmcgdGhlIGxvYWQgb24gYSBIUmVnaW9uU2VydmVyCisgKi8KK3B1YmxpYyBjbGFzcyBIU2VydmVyTG9hZCBpbXBsZW1lbnRzIFdyaXRhYmxlQ29tcGFyYWJsZTxIU2VydmVyTG9hZD4geworICAvKiogbnVtYmVyIG9mIHJlZ2lvbnMgKi8KKyAgICAvLyBjb3VsZCBqdXN0IHVzZSByZWdpb25Mb2FkLnNpemUoKSBidXQgbWFzdGVyLlJlZ2lvbk1hbmFnZXIgbGlrZXMgdG8gcGxheQorICAgIC8vIGFyb3VuZCB3aXRoIHRoaXMgdmFsdWUgd2hpbGUgcGFzc2luZyBIU2VydmVyTG9hZCBvYmplY3RzIGFyb3VuZCBkdXJpbmcKKyAgICAvLyBiYWxhbmNlciBjYWxjdWxhdGlvbnMKKyAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZSZWdpb25zOworICAvKiogbnVtYmVyIG9mIHJlcXVlc3RzIHNpbmNlIGxhc3QgcmVwb3J0ICovCisgIHByaXZhdGUgaW50IG51bWJlck9mUmVxdWVzdHM7CisgIC8qKiB0aGUgYW1vdW50IG9mIHVzZWQgaGVhcCwgaW4gTUIgKi8KKyAgcHJpdmF0ZSBpbnQgdXNlZEhlYXBNQjsKKyAgLyoqIHRoZSBtYXhpbXVtIGFsbG93YWJsZSBzaXplIG9mIHRoZSBoZWFwLCBpbiBNQiAqLworICBwcml2YXRlIGludCBtYXhIZWFwTUI7CisgIC8qKiBwZXItcmVnaW9uIGxvYWQgbWV0cmljcyAqLworICBwcml2YXRlIEFycmF5TGlzdDxSZWdpb25Mb2FkPiByZWdpb25Mb2FkID0gbmV3IEFycmF5TGlzdDxSZWdpb25Mb2FkPigpOworCisgIC8qKiAKKyAgICogRW5jYXBzdWxhdGVzIHBlci1yZWdpb24gbG9hZGluZyBtZXRyaWNzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBSZWdpb25Mb2FkIGltcGxlbWVudHMgV3JpdGFibGUgeworICAgIC8qKiB0aGUgcmVnaW9uIG5hbWUgKi8KKyAgICBwcml2YXRlIGJ5dGVbXSBuYW1lOworICAgIC8qKiB0aGUgbnVtYmVyIG9mIHN0b3JlcyBmb3IgdGhlIHJlZ2lvbiAqLworICAgIHByaXZhdGUgaW50IHN0b3JlczsKKyAgICAvKiogdGhlIG51bWJlciBvZiBzdG9yZWZpbGVzIGZvciB0aGUgcmVnaW9uICovCisgICAgcHJpdmF0ZSBpbnQgc3RvcmVmaWxlczsKKyAgICAvKiogdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgbWVtY2FjaGUgZm9yIHRoZSByZWdpb24sIGluIE1CICovCisgICAgcHJpdmF0ZSBpbnQgbWVtY2FjaGVTaXplTUI7CisgICAgLyoqIHRoZSBjdXJyZW50IHRvdGFsIHNpemUgb2Ygc3RvcmVmaWxlIGluZGV4ZXMgZm9yIHRoZSByZWdpb24sIGluIE1CICovCisgICAgcHJpdmF0ZSBpbnQgc3RvcmVmaWxlSW5kZXhTaXplTUI7CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciwgZm9yIFdyaXRhYmxlCisgICAgICovCisgICAgcHVibGljIFJlZ2lvbkxvYWQoKSB7CisgICAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIG5hbWUKKyAgICAgKiBAcGFyYW0gc3RvcmVzCisgICAgICogQHBhcmFtIHN0b3JlZmlsZXMKKyAgICAgKiBAcGFyYW0gbWVtY2FjaGVTaXplTUIKKyAgICAgKiBAcGFyYW0gc3RvcmVmaWxlSW5kZXhTaXplTUIKKyAgICAgKi8KKyAgICBwdWJsaWMgUmVnaW9uTG9hZChmaW5hbCBieXRlW10gbmFtZSwgZmluYWwgaW50IHN0b3JlcywKKyAgICAgICAgZmluYWwgaW50IHN0b3JlZmlsZXMsIGZpbmFsIGludCBtZW1jYWNoZVNpemVNQiwKKyAgICAgICAgZmluYWwgaW50IHN0b3JlZmlsZUluZGV4U2l6ZU1CKSB7CisgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgdGhpcy5zdG9yZXMgPSBzdG9yZXM7CisgICAgICB0aGlzLnN0b3JlZmlsZXMgPSBzdG9yZWZpbGVzOworICAgICAgdGhpcy5tZW1jYWNoZVNpemVNQiA9IG1lbWNhY2hlU2l6ZU1COworICAgICAgdGhpcy5zdG9yZWZpbGVJbmRleFNpemVNQiA9IHN0b3JlZmlsZUluZGV4U2l6ZU1COworICAgIH0KKworICAgIC8vIEdldHRlcnMKKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIHJlZ2lvbiBuYW1lCisgICAgICovCisgICAgcHVibGljIGJ5dGVbXSBnZXROYW1lKCkgeworICAgICAgcmV0dXJuIG5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHN0b3JlcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3RvcmVzKCkgeworICAgICAgcmV0dXJuIHN0b3JlczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygc3RvcmVmaWxlcworICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3RvcmVmaWxlcygpIHsKKyAgICAgIHJldHVybiBzdG9yZWZpbGVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gdGhlIG1lbWNhY2hlIHNpemUsIGluIE1CCisgICAgICovCisgICAgcHVibGljIGludCBnZXRNZW1jYWNoZVNpemVNQigpIHsKKyAgICAgIHJldHVybiBtZW1jYWNoZVNpemVNQjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBhcHByb3hpbWF0ZSBzaXplIG9mIHN0b3JlZmlsZSBpbmRleGVzIG9uIHRoZSBoZWFwLCBpbiBNQgorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U3RvcmVmaWxlSW5kZXhTaXplTUIoKSB7CisgICAgICByZXR1cm4gc3RvcmVmaWxlSW5kZXhTaXplTUI7CisgICAgfQorCisgICAgLy8gU2V0dGVycworCisgICAgLyoqCisgICAgICogQHBhcmFtIG5hbWUgdGhlIHJlZ2lvbiBuYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0TmFtZShieXRlW10gbmFtZSkgeworICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gc3RvcmVzIHRoZSBudW1iZXIgb2Ygc3RvcmVzCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0U3RvcmVzKGludCBzdG9yZXMpIHsKKyAgICAgIHRoaXMuc3RvcmVzID0gc3RvcmVzOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBzdG9yZWZpbGVzIHRoZSBudW1iZXIgb2Ygc3RvcmVmaWxlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFN0b3JlZmlsZXMoaW50IHN0b3JlZmlsZXMpIHsKKyAgICAgIHRoaXMuc3RvcmVmaWxlcyA9IHN0b3JlZmlsZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIG1lbWNhY2hlU2l6ZU1CIHRoZSBtZW1jYWNoZSBzaXplLCBpbiBNQgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldE1lbWNhY2hlU2l6ZU1CKGludCBtZW1jYWNoZVNpemVNQikgeworICAgICAgdGhpcy5tZW1jYWNoZVNpemVNQiA9IG1lbWNhY2hlU2l6ZU1COworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBzdG9yZWZpbGVJbmRleFNpemVNQiB0aGUgYXBwcm94aW1hdGUgc2l6ZSBvZiBzdG9yZWZpbGUgaW5kZXhlcworICAgICAqICBvbiB0aGUgaGVhcCwgaW4gTUIKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdG9yZWZpbGVJbmRleFNpemVNQihpbnQgc3RvcmVmaWxlSW5kZXhTaXplTUIpIHsKKyAgICAgIHRoaXMuc3RvcmVmaWxlSW5kZXhTaXplTUIgPSBzdG9yZWZpbGVJbmRleFNpemVNQjsKKyAgICB9CisKKyAgICAvLyBXcml0YWJsZQorICAgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaW50IG5hbWVsZW4gPSBpbi5yZWFkSW50KCk7CisgICAgICB0aGlzLm5hbWUgPSBuZXcgYnl0ZVtuYW1lbGVuXTsKKyAgICAgIGluLnJlYWRGdWxseSh0aGlzLm5hbWUpOworICAgICAgdGhpcy5zdG9yZXMgPSBpbi5yZWFkSW50KCk7CisgICAgICB0aGlzLnN0b3JlZmlsZXMgPSBpbi5yZWFkSW50KCk7CisgICAgICB0aGlzLm1lbWNhY2hlU2l6ZU1CID0gaW4ucmVhZEludCgpOworICAgICAgdGhpcy5zdG9yZWZpbGVJbmRleFNpemVNQiA9IGluLnJlYWRJbnQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIG91dC53cml0ZUludChuYW1lLmxlbmd0aCk7CisgICAgICBvdXQud3JpdGUobmFtZSk7CisgICAgICBvdXQud3JpdGVJbnQoc3RvcmVzKTsKKyAgICAgIG91dC53cml0ZUludChzdG9yZWZpbGVzKTsKKyAgICAgIG91dC53cml0ZUludChtZW1jYWNoZVNpemVNQik7CisgICAgICBvdXQud3JpdGVJbnQoc3RvcmVmaWxlSW5kZXhTaXplTUIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKG5ldyBTdHJpbmdCdWlsZGVyKCksICJzdG9yZXMiLAorICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodGhpcy5zdG9yZXMpKTsKKyAgICAgIHNiID0gU3RyaW5ncy5hcHBlbmRLZXlWYWx1ZShzYiwgInN0b3JlZmlsZXMiLAorICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodGhpcy5zdG9yZWZpbGVzKSk7CisgICAgICBzYiA9IFN0cmluZ3MuYXBwZW5kS2V5VmFsdWUoc2IsICJtZW1jYWNoZVNpemUiLAorICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodGhpcy5tZW1jYWNoZVNpemVNQikpOworICAgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAic3RvcmVmaWxlSW5kZXhTaXplIiwKKyAgICAgICAgSW50ZWdlci52YWx1ZU9mKHRoaXMuc3RvcmVmaWxlSW5kZXhTaXplTUIpKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIFRPRE86IE90aGVyIG1ldHJpY3MgdGhhdCBtaWdodCBiZSBjb25zaWRlcmVkIHdoZW4gdGhlIG1hc3RlciBpcyBhY3R1YWxseQorICAgKiBkb2luZyBsb2FkIGJhbGFuY2luZyBpbnN0ZWFkIG9mIG1lcmVseSB0cnlpbmcgdG8gZGVjaWRlIHdoZXJlIHRvIGFzc2lnbgorICAgKiBhIHJlZ2lvbjoKKyAgICogPHVsPgorICAgKiAgIDxsaT4jIG9mIENQVXMsIGhlYXAgc2l6ZSAodG8gZGV0ZXJtaW5lIHRoZSAiY2xhc3MiIG9mIG1hY2hpbmUpLiBGb3IKKyAgICogICAgICAgbm93LCB3ZSBjb25zaWRlciB0aGVtIHRvIGJlIGhvbW9nZW5lb3VzLjwvbGk+CisgICAqICAgPGxpPiNyZXF1ZXN0cyBwZXIgcmVnaW9uIChNYXA8e1N0cmluZ3xIUmVnaW9uSW5mb30sIEludGVnZXI+KTwvbGk+CisgICAqICAgPGxpPiNjb21wYWN0aW9ucyBhbmQvb3IgI3NwbGl0cyAoY2h1cm4pPC9saT4KKyAgICogICA8bGk+c2VydmVyIGRlYXRoIHJhdGUgKG1heWJlIHRoZXJlIGlzIHNvbWV0aGluZyB3cm9uZyB3aXRoIHRoaXMgc2VydmVyKTwvbGk+CisgICAqIDwvdWw+CisgICAqLworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICh1c2VkIGJ5IFdyaXRhYmxlKSAqLworICBwdWJsaWMgSFNlcnZlckxvYWQoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBudW1iZXJPZlJlcXVlc3RzCisgICAqIEBwYXJhbSB1c2VkSGVhcE1CCisgICAqIEBwYXJhbSBtYXhIZWFwTUIKKyAgICovCisgIHB1YmxpYyBIU2VydmVyTG9hZChmaW5hbCBpbnQgbnVtYmVyT2ZSZXF1ZXN0cywgZmluYWwgaW50IHVzZWRIZWFwTUIsCisgICAgICBmaW5hbCBpbnQgbWF4SGVhcE1CKSB7CisgICAgdGhpcy5udW1iZXJPZlJlcXVlc3RzID0gbnVtYmVyT2ZSZXF1ZXN0czsKKyAgICB0aGlzLnVzZWRIZWFwTUIgPSB1c2VkSGVhcE1COworICAgIHRoaXMubWF4SGVhcE1CID0gbWF4SGVhcE1COworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBoc2wgdGhlIHRlbXBsYXRlIEhTZXJ2ZXJMb2FkCisgICAqLworICBwdWJsaWMgSFNlcnZlckxvYWQoZmluYWwgSFNlcnZlckxvYWQgaHNsKSB7CisgICAgdGhpcyhoc2wubnVtYmVyT2ZSZXF1ZXN0cywgaHNsLnVzZWRIZWFwTUIsIGhzbC5tYXhIZWFwTUIpOworICAgIHRoaXMucmVnaW9uTG9hZC5hZGRBbGwoaHNsLnJlZ2lvbkxvYWQpOworICB9CisKKyAgLyoqCisgICAqIE9yaWdpbmFsbHksIHRoaXMgbWV0aG9kIGZhY3RvcmVkIGluIHRoZSBlZmZlY3Qgb2YgcmVxdWVzdHMgZ29pbmcgdG8gdGhlCisgICAqIHNlcnZlciBhcyB3ZWxsLiBIb3dldmVyLCB0aGlzIGRvZXMgbm90IGludGVyYWN0IHZlcnkgd2VsbCB3aXRoIHRoZSBjdXJyZW50CisgICAqIHJlZ2lvbiByZWJhbGFuY2luZyBjb2RlLCB3aGljaCBvbmx5IGZhY3RvcnMgbnVtYmVyIG9mIHJlZ2lvbnMuIEZvciB0aGUgCisgICAqIGludGVyaW0sIHVudGlsIHdlIGNhbiBmaWd1cmUgb3V0IGhvdyB0byBtYWtlIHJlYmFsYW5jaW5nIHVzZSBhbGwgdGhlIGluZm8KKyAgICogYXZhaWxhYmxlLCB3ZSdyZSBqdXN0IGdvaW5nIHRvIG1ha2UgbG9hZCBwdXJlbHkgdGhlIG51bWJlciBvZiByZWdpb25zLgorICAgKgorICAgKiBAcmV0dXJuIGxvYWQgZmFjdG9yIGZvciB0aGlzIHNlcnZlcgorICAgKi8KKyAgcHVibGljIGludCBnZXRMb2FkKCkgeworICAgIC8vIGludCBsb2FkID0gbnVtYmVyT2ZSZXF1ZXN0cyA9PSAwID8gMSA6IG51bWJlck9mUmVxdWVzdHM7CisgICAgLy8gbG9hZCAqPSBudW1iZXJPZlJlZ2lvbnMgPT0gMCA/IDEgOiBudW1iZXJPZlJlZ2lvbnM7CisgICAgLy8gcmV0dXJuIGxvYWQ7CisgICAgcmV0dXJuIG51bWJlck9mUmVnaW9uczsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjdG9TdHJpbmcoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nKDEpOworICB9CisgIAorICAvKioKKyAgICogUmV0dXJucyB0b1N0cmluZygpIHdpdGggdGhlIG51bWJlciBvZiByZXF1ZXN0cyBkaXZpZGVkIGJ5IHRoZSBtZXNzYWdlCisgICAqIGludGVydmFsIGluIHNlY29uZHMKKyAgICogQHBhcmFtIG1zZ0ludGVydmFsCisgICAqIEByZXR1cm4gVGhlIGxvYWQgYXMgYSBTdHJpbmcKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoaW50IG1zZ0ludGVydmFsKSB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAicmVxdWVzdHMiLAorICAgICAgSW50ZWdlci52YWx1ZU9mKG51bWJlck9mUmVxdWVzdHMvbXNnSW50ZXJ2YWwpKTsKKyAgICBzYiA9IFN0cmluZ3MuYXBwZW5kS2V5VmFsdWUoc2IsICJyZWdpb25zIiwKKyAgICAgIEludGVnZXIudmFsdWVPZihudW1iZXJPZlJlZ2lvbnMpKTsKKyAgICBzYiA9IFN0cmluZ3MuYXBwZW5kS2V5VmFsdWUoc2IsICJ1c2VkSGVhcCIsCisgICAgICBJbnRlZ2VyLnZhbHVlT2YodGhpcy51c2VkSGVhcE1CKSk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAibWF4SGVhcCIsIEludGVnZXIudmFsdWVPZihtYXhIZWFwTUIpKTsKKyAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgaWYgKHRoaXMgPT0gbykgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGlmIChvID09IG51bGwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiBjb21wYXJlVG8oKEhTZXJ2ZXJMb2FkKW8pID09IDA7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2hhc2hDb2RlKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCByZXN1bHQgPSBJbnRlZ2VyLnZhbHVlT2YobnVtYmVyT2ZSZXF1ZXN0cykuaGFzaENvZGUoKTsKKyAgICByZXN1bHQgXj0gSW50ZWdlci52YWx1ZU9mKG51bWJlck9mUmVnaW9ucykuaGFzaENvZGUoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvLyBHZXR0ZXJzCisgIAorICAvKioKKyAgICogQHJldHVybiB0aGUgbnVtYmVyT2ZSZWdpb25zCisgICAqLworICBwdWJsaWMgaW50IGdldE51bWJlck9mUmVnaW9ucygpIHsKKyAgICByZXR1cm4gbnVtYmVyT2ZSZWdpb25zOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIG51bWJlck9mUmVxdWVzdHMKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyT2ZSZXF1ZXN0cygpIHsKKyAgICByZXR1cm4gbnVtYmVyT2ZSZXF1ZXN0czsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIENvdW50IG9mIHN0b3JlZmlsZXMgb24gdGhpcyByZWdpb25zZXJ2ZXIKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0U3RvcmVmaWxlcygpIHsKKyAgICBpbnQgY291bnQgPSAwOworICAgIGZvciAoUmVnaW9uTG9hZCBpbmZvOiByZWdpb25Mb2FkKQorICAgIAljb3VudCArPSBpbmZvLmdldFN0b3JlZmlsZXMoKTsKKyAgICByZXR1cm4gY291bnQ7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBTaXplIG9mIG1lbWNhY2hlcyBpbiBNQgorICAgKi8KKyAgcHVibGljIGludCBnZXRNZW1jYWNoZVNpemVJbk1CKCkgeworICAgIGludCBjb3VudCA9IDA7CisgICAgZm9yIChSZWdpb25Mb2FkIGluZm86IHJlZ2lvbkxvYWQpCisgICAgCWNvdW50ICs9IGluZm8uZ2V0TWVtY2FjaGVTaXplTUIoKTsKKyAgICByZXR1cm4gY291bnQ7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBTaXplIG9mIHN0b3JlIGZpbGUgaW5kZXhlcyBpbiBNQgorICAgKi8KKyAgcHVibGljIGludCBnZXRTdG9yZWZpbGVJbmRleFNpemVJbk1CKCkgeworICAgIGludCBjb3VudCA9IDA7CisgICAgZm9yIChSZWdpb25Mb2FkIGluZm86IHJlZ2lvbkxvYWQpCisgICAgCWNvdW50ICs9IGluZm8uZ2V0U3RvcmVmaWxlSW5kZXhTaXplTUIoKTsKKyAgICByZXR1cm4gY291bnQ7CisgIH0KKworICAvLyBTZXR0ZXJzCisKKyAgLyoqCisgICAqIEBwYXJhbSBudW1iZXJPZlJlZ2lvbnMgdGhlIG51bWJlciBvZiByZWdpb25zCisgICAqLworICBwdWJsaWMgdm9pZCBzZXROdW1iZXJPZlJlZ2lvbnMoaW50IG51bWJlck9mUmVnaW9ucykgeworICAgIHRoaXMubnVtYmVyT2ZSZWdpb25zID0gbnVtYmVyT2ZSZWdpb25zOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBudW1iZXJPZlJlcXVlc3RzIHRoZSBudW1iZXIgb2YgcmVxdWVzdHMgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXROdW1iZXJPZlJlcXVlc3RzKGludCBudW1iZXJPZlJlcXVlc3RzKSB7CisgICAgdGhpcy5udW1iZXJPZlJlcXVlc3RzID0gbnVtYmVyT2ZSZXF1ZXN0czsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdXNlZEhlYXBNQiB0aGUgYW1vdW50IG9mIGhlYXAgaW4gdXNlLCBpbiBNQgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0VXNlZEhlYXBNQihpbnQgdXNlZEhlYXBNQikgeworICAgIHRoaXMudXNlZEhlYXBNQiA9IHVzZWRIZWFwTUI7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG1heEhlYXBNQiB0aGUgbWF4aW11bSBhbGxvd2FibGUgaGVhcCBzaXplLCBpbiBNQgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TWF4SGVhcE1CKGludCBtYXhIZWFwTUIpIHsKKyAgICB0aGlzLm1heEhlYXBNQiA9IG1heEhlYXBNQjsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbG9hZCBJbnN0YW5jZSBvZiBIU2VydmVyTG9hZAorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkUmVnaW9uSW5mbyhmaW5hbCBIU2VydmVyTG9hZC5SZWdpb25Mb2FkIGxvYWQpIHsKKyAgICB0aGlzLm51bWJlck9mUmVnaW9ucysrOworICAgIHRoaXMucmVnaW9uTG9hZC5hZGQobG9hZCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG5hbWUKKyAgICogQHBhcmFtIHN0b3JlcworICAgKiBAcGFyYW0gc3RvcmVmaWxlcworICAgKiBAcGFyYW0gbWVtY2FjaGVTaXplTUIKKyAgICogQHBhcmFtIHN0b3JlZmlsZUluZGV4U2l6ZU1CCisgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2FkZFJlZ2lvbkluZm8oUmVnaW9uTG9hZCl9CisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgdm9pZCBhZGRSZWdpb25JbmZvKGZpbmFsIGJ5dGVbXSBuYW1lLCBmaW5hbCBpbnQgc3RvcmVzLAorICAgICAgZmluYWwgaW50IHN0b3JlZmlsZXMsIGZpbmFsIGludCBtZW1jYWNoZVNpemVNQiwKKyAgICAgIGZpbmFsIGludCBzdG9yZWZpbGVJbmRleFNpemVNQikgeworICAgIHRoaXMucmVnaW9uTG9hZC5hZGQobmV3IEhTZXJ2ZXJMb2FkLlJlZ2lvbkxvYWQobmFtZSwgc3RvcmVzLCBzdG9yZWZpbGVzLAorICAgICAgbWVtY2FjaGVTaXplTUIsIHN0b3JlZmlsZUluZGV4U2l6ZU1CKSk7CisgIH0KKworICAvLyBXcml0YWJsZQorCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG51bWJlck9mUmVxdWVzdHMgPSBpbi5yZWFkSW50KCk7CisgICAgdXNlZEhlYXBNQiA9IGluLnJlYWRJbnQoKTsKKyAgICBtYXhIZWFwTUIgPSBpbi5yZWFkSW50KCk7CisgICAgbnVtYmVyT2ZSZWdpb25zID0gaW4ucmVhZEludCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtYmVyT2ZSZWdpb25zOyBpKyspIHsKKyAgICAgIFJlZ2lvbkxvYWQgcmwgPSBuZXcgUmVnaW9uTG9hZCgpOworICAgICAgcmwucmVhZEZpZWxkcyhpbik7CisgICAgICByZWdpb25Mb2FkLmFkZChybCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlSW50KG51bWJlck9mUmVxdWVzdHMpOworICAgIG91dC53cml0ZUludCh1c2VkSGVhcE1CKTsKKyAgICBvdXQud3JpdGVJbnQobWF4SGVhcE1CKTsKKyAgICBvdXQud3JpdGVJbnQobnVtYmVyT2ZSZWdpb25zKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mUmVnaW9uczsgaSsrKQorICAgICAgcmVnaW9uTG9hZC5nZXQoaSkud3JpdGUob3V0KTsKKyAgfQorCisgIC8vIENvbXBhcmFibGUKKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhIU2VydmVyTG9hZCBvKSB7CisgICAgcmV0dXJuIHRoaXMuZ2V0TG9hZCgpIC0gby5nZXRMb2FkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hTdG9yZUtleS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFN0b3JlS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhiOTQxNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hTdG9yZUtleS5qYXZhCkBAIC0wLDAgKzEsMTExNiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGVhcFNpemU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5SYXdDb21wYXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVVdGlsczsKKworLyoqCisgKiBBIEtleSBmb3IgYSBzdG9yZWQgcm93LgorICogQGRlcHJlY2F0ZWQgUmVwbGFjZWQgYnkge0BsaW5rIEtleVZhbHVlfS4KKyAqLworcHVibGljIGNsYXNzIEhTdG9yZUtleSBpbXBsZW1lbnRzIFdyaXRhYmxlQ29tcGFyYWJsZTxIU3RvcmVLZXk+LCBIZWFwU2l6ZSB7CisgIC8qKgorICAgKiBDb2xvbiBjaGFyYWN0ZXIgaW4gVVRGLTgKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBDT0xVTU5fRkFNSUxZX0RFTElNSVRFUiA9ICc6JzsKKworICAvKioKKyAgICogRXN0aW1hdGVkIHNpemUgdGF4IHBhaWQgZm9yIGVhY2ggaW5zdGFuY2Ugb2YgSFNLLiAgRXN0aW1hdGUgYmFzZWQgb24KKyAgICogc3R1ZHkgb2YgamhhdCBhbmQganByb2ZpbGVyIG51bWJlcnMuCisgICAqLworICAvLyBJbiBqcHJvZmlsZXIsIHNheXMgc2hhbGxvdyBzaXplIGlzIDQ4IGJ5dGVzLiAgQWRkIHRvIGl0IGNvc3Qgb2YgdHdvCisgIC8vIGJ5dGUgYXJyYXlzIGFuZCB0aGVuIHNvbWV0aGluZyBmb3IgdGhlIEhSSSBob3N0aW5nLgorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFU1RJTUFURURfSEVBUF9UQVggPSA0ODsKKworICBwcml2YXRlIGJ5dGUgW10gcm93ID0gSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZOworICBwcml2YXRlIGJ5dGUgW10gY29sdW1uID0gSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZOworICBwcml2YXRlIGxvbmcgdGltZXN0YW1wID0gTG9uZy5NQVhfVkFMVUU7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSFN0b3JlS2V5LlN0b3JlS2V5Q29tcGFyYXRvciBQTEFJTl9DT01QQVJBVE9SID0KKyAgICBuZXcgSFN0b3JlS2V5LlN0b3JlS2V5Q29tcGFyYXRvcigpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIU3RvcmVLZXkuU3RvcmVLZXlDb21wYXJhdG9yIE1FVEFfQ09NUEFSQVRPUiA9CisgICAgbmV3IEhTdG9yZUtleS5NZXRhU3RvcmVLZXlDb21wYXJhdG9yKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhTdG9yZUtleS5TdG9yZUtleUNvbXBhcmF0b3IgUk9PVF9DT01QQVJBVE9SID0KKyAgICBuZXcgSFN0b3JlS2V5LlJvb3RTdG9yZUtleUNvbXBhcmF0b3IoKTsKKworICAvKiogRGVmYXVsdCBjb25zdHJ1Y3RvciB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggV3JpdGFibGUgaW50ZXJmYWNlICovCisgIHB1YmxpYyBIU3RvcmVLZXkoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyBvbmx5IHRoZSByb3cKKyAgICogVGhlIGNvbHVtbiBkZWZhdWx0cyB0byB0aGUgZW1wdHkgc3RyaW5nLCB0aGUgdGltZSBzdGFtcCBkZWZhdWx0cyB0bworICAgKiBMb25nLk1BWF9WQUxVRSBhbmQgdGhlIHRhYmxlIGRlZmF1bHRzIHRvIGVtcHR5IHN0cmluZworICAgKiAKKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkKKyAgICovCisgIHB1YmxpYyBIU3RvcmVLZXkoZmluYWwgYnl0ZSBbXSByb3cpIHsKKyAgICB0aGlzKHJvdywgTG9uZy5NQVhfVkFMVUUpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyBvbmx5IHRoZSByb3cKKyAgICogVGhlIGNvbHVtbiBkZWZhdWx0cyB0byB0aGUgZW1wdHkgc3RyaW5nLCB0aGUgdGltZSBzdGFtcCBkZWZhdWx0cyB0bworICAgKiBMb25nLk1BWF9WQUxVRSBhbmQgdGhlIHRhYmxlIGRlZmF1bHRzIHRvIGVtcHR5IHN0cmluZworICAgKiAKKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkKKyAgICovCisgIHB1YmxpYyBIU3RvcmVLZXkoZmluYWwgU3RyaW5nIHJvdykgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLCBMb25nLk1BWF9WQUxVRSk7CisgIH0KKyAKKyAgLyoqCisgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyB0aGUgcm93IGFuZCB0aW1lc3RhbXAKKyAgICogVGhlIGNvbHVtbiBhbmQgdGFibGUgbmFtZXMgZGVmYXVsdCB0byB0aGUgZW1wdHkgc3RyaW5nCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAgdmFsdWUKKyAgICovCisgIHB1YmxpYyBIU3RvcmVLZXkoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGxvbmcgdGltZXN0YW1wKSB7CisgICAgdGhpcyhyb3csIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwgdGltZXN0YW1wKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYW4gSFN0b3JlS2V5IHNwZWNpZnlpbmcgdGhlIHJvdyBhbmQgY29sdW1uIG5hbWVzCisgICAqIFRoZSB0aW1lc3RhbXAgZGVmYXVsdHMgdG8gTEFURVNUX1RJTUVTVEFNUAorICAgKiBhbmQgdGFibGUgbmFtZSBkZWZhdWx0cyB0byB0aGUgZW1wdHkgc3RyaW5nCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4ga2V5CisgICAqLworICBwdWJsaWMgSFN0b3JlS2V5KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBjb2x1bW4pIHsKKyAgICB0aGlzKHJvdywgY29sdW1uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyB0aGUgcm93IGFuZCBjb2x1bW4gbmFtZXMKKyAgICogVGhlIHRpbWVzdGFtcCBkZWZhdWx0cyB0byBMQVRFU1RfVElNRVNUQU1QCisgICAqIGFuZCB0YWJsZSBuYW1lIGRlZmF1bHRzIHRvIHRoZSBlbXB0eSBzdHJpbmcKKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBrZXkKKyAgICovCisgIHB1YmxpYyBIU3RvcmVLZXkoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgdGhpcyhyb3csIGNvbHVtbiwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYW4gSFN0b3JlS2V5IHNwZWNpZnlpbmcgYWxsIHRoZSBmaWVsZHMKKyAgICogRG9lcyBub3QgbWFrZSBjb3BpZXMgb2YgdGhlIHBhc3NlZCBieXRlIGFycmF5cy4gUHJlc3VtZXMgdGhlIHBhc3NlZCAKKyAgICogYXJyYXlzIGltbXV0YWJsZS4KKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIGtleQorICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcCB2YWx1ZQorICAgKi8KKyAgcHVibGljIEhTdG9yZUtleShmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgY29sdW1uLCBmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMgKEJ5dGVzLnRvQnl0ZXMocm93KSwgQnl0ZXMudG9CeXRlcyhjb2x1bW4pLCB0aW1lc3RhbXApOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyBhbGwgdGhlIGZpZWxkcyB3aXRoIHNwZWNpZmllZCB0YWJsZQorICAgKiBEb2VzIG5vdCBtYWtlIGNvcGllcyBvZiB0aGUgcGFzc2VkIGJ5dGUgYXJyYXlzLiBQcmVzdW1lcyB0aGUgcGFzc2VkIAorICAgKiBhcnJheXMgaW1tdXRhYmxlLgorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4ga2V5CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wIHZhbHVlCisgICAqLworICBwdWJsaWMgSFN0b3JlS2V5KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwgZmluYWwgbG9uZyB0aW1lc3RhbXApIHsKKyAgICAvLyBNYWtlIGNvcGllcworICAgIHRoaXMucm93ID0gcm93OworICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcgSFN0b3JlS2V5IGZyb20gYW5vdGhlcgorICAgKiAKKyAgICogQHBhcmFtIG90aGVyIHRoZSBzb3VyY2Uga2V5CisgICAqLworICBwdWJsaWMgSFN0b3JlS2V5KGZpbmFsIEhTdG9yZUtleSBvdGhlcikgeworICAgIHRoaXMob3RoZXIuZ2V0Um93KCksIG90aGVyLmdldENvbHVtbigpLCBvdGhlci5nZXRUaW1lc3RhbXAoKSk7CisgIH0KKworICBwdWJsaWMgSFN0b3JlS2V5KGZpbmFsIEJ5dGVCdWZmZXIgYmIpIHsKKyAgICB0aGlzKGdldFJvdyhiYiksIGdldENvbHVtbihiYiksIGdldFRpbWVzdGFtcChiYikpOworICB9CisKKyAgLyoqCisgICAqIENoYW5nZSB0aGUgdmFsdWUgb2YgdGhlIHJvdyBrZXkKKyAgICogCisgICAqIEBwYXJhbSBuZXdyb3cgbmV3IHJvdyBrZXkgdmFsdWUKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFJvdyhmaW5hbCBieXRlIFtdIG5ld3JvdykgeworICAgIHRoaXMucm93ID0gbmV3cm93OworICB9CisgIAorICAvKioKKyAgICogQ2hhbmdlIHRoZSB2YWx1ZSBvZiB0aGUgY29sdW1uIGluIHRoaXMga2V5CisgICAqIAorICAgKiBAcGFyYW0gYyBuZXcgY29sdW1uIGZhbWlseSB2YWx1ZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0Q29sdW1uKGZpbmFsIGJ5dGUgW10gYykgeworICAgIHRoaXMuY29sdW1uID0gYzsKKyAgfQorCisgIC8qKgorICAgKiBDaGFuZ2UgdGhlIHZhbHVlIG9mIHRoZSB0aW1lc3RhbXAgZmllbGQKKyAgICogCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgbmV3IHRpbWVzdGFtcCB2YWx1ZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICB9CisgIAorICAvKioKKyAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGlzIEhTdG9yZUtleSBmcm9tIHRoZSBzdXBwbGllZCBrZXkKKyAgICogCisgICAqIEBwYXJhbSBrIGtleSB2YWx1ZSB0byBjb3B5CisgICAqLworICBwdWJsaWMgdm9pZCBzZXQoZmluYWwgSFN0b3JlS2V5IGspIHsKKyAgICB0aGlzLnJvdyA9IGsuZ2V0Um93KCk7CisgICAgdGhpcy5jb2x1bW4gPSBrLmdldENvbHVtbigpOworICAgIHRoaXMudGltZXN0YW1wID0gay5nZXRUaW1lc3RhbXAoKTsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gdmFsdWUgb2Ygcm93IGtleSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRSb3coKSB7CisgICAgcmV0dXJuIHJvdzsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gdmFsdWUgb2YgY29sdW1uICovCisgIHB1YmxpYyBieXRlIFtdIGdldENvbHVtbigpIHsKKyAgICByZXR1cm4gdGhpcy5jb2x1bW47CisgIH0KKworICAvKiogQHJldHVybiB2YWx1ZSBvZiB0aW1lc3RhbXAgKi8KKyAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgcm93IGFuZCBjb2x1bW4gb2YgdHdvIGtleXMKKyAgICogQHBhcmFtIG90aGVyIEtleSB0byBjb21wYXJlIGFnYWluc3QuIENvbXBhcmVzIHJvdyBhbmQgY29sdW1uLgorICAgKiBAcmV0dXJuIFRydWUgaWYgc2FtZSByb3cgYW5kIGNvbHVtbi4KKyAgICogQHNlZSAjbWF0Y2hlc1dpdGhvdXRDb2x1bW4oSFN0b3JlS2V5KQorICAgKiBAc2VlICNtYXRjaGVzUm93RmFtaWx5KEhTdG9yZUtleSkKKyAgICovIAorICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzUm93Q29sKGZpbmFsIEhTdG9yZUtleSBvdGhlcikgeworICAgIHJldHVybiBIU3RvcmVLZXkuZXF1YWxzVHdvUm93S2V5cyhnZXRSb3coKSwgb3RoZXIuZ2V0Um93KCkpICYmCisgICAgICBCeXRlcy5lcXVhbHMoZ2V0Q29sdW1uKCksIG90aGVyLmdldENvbHVtbigpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbXBhcmVzIHRoZSByb3cgYW5kIHRpbWVzdGFtcCBvZiB0d28ga2V5cworICAgKiAKKyAgICogQHBhcmFtIG90aGVyIEtleSB0byBjb3BtYXJlIGFnYWluc3QuIENvbXBhcmVzIHJvdyBhbmQgdGltZXN0YW1wLgorICAgKiAKKyAgICogQHJldHVybiBUcnVlIGlmIHNhbWUgcm93IGFuZCB0aW1lc3RhbXAgaXMgZ3JlYXRlciB0aGFuIDxjb2RlPm90aGVyPC9jb2RlPgorICAgKiBAc2VlICNtYXRjaGVzUm93Q29sKEhTdG9yZUtleSkKKyAgICogQHNlZSAjbWF0Y2hlc1Jvd0ZhbWlseShIU3RvcmVLZXkpCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzV2l0aG91dENvbHVtbihmaW5hbCBIU3RvcmVLZXkgb3RoZXIpIHsKKyAgICByZXR1cm4gZXF1YWxzVHdvUm93S2V5cyhnZXRSb3coKSwgb3RoZXIuZ2V0Um93KCkpICYmCisgICAgICBnZXRUaW1lc3RhbXAoKSA+PSBvdGhlci5nZXRUaW1lc3RhbXAoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgcm93IGFuZCBjb2x1bW4gZmFtaWx5IG9mIHR3byBrZXlzCisgICAqIAorICAgKiBAcGFyYW0gdGhhdCBLZXkgdG8gY29tcGFyZSBhZ2FpbnN0LiBDb21wYXJlcyByb3cgYW5kIGNvbHVtbiBmYW1pbHkKKyAgICogCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBzYW1lIHJvdyBhbmQgY29sdW1uIGZhbWlseQorICAgKiBAc2VlICNtYXRjaGVzUm93Q29sKEhTdG9yZUtleSkKKyAgICogQHNlZSAjbWF0Y2hlc1dpdGhvdXRDb2x1bW4oSFN0b3JlS2V5KQorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gbWF0Y2hlc1Jvd0ZhbWlseShmaW5hbCBIU3RvcmVLZXkgdGhhdCkgeworICAgIGZpbmFsIGludCBkZWxpbWl0ZXJJbmRleCA9IGdldEZhbWlseURlbGltaXRlckluZGV4KGdldENvbHVtbigpKTsKKyAgICByZXR1cm4gZXF1YWxzVHdvUm93S2V5cyhnZXRSb3coKSwgdGhhdC5nZXRSb3coKSkgJiYKKyAgICBCeXRlcy5jb21wYXJlVG8oZ2V0Q29sdW1uKCksIDAsIGRlbGltaXRlckluZGV4LCB0aGF0LmdldENvbHVtbigpLCAwLAorICAgICAgICBkZWxpbWl0ZXJJbmRleCkgPT0gMDsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjdG9TdHJpbmcoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIEJ5dGVzLnRvU3RyaW5nKHRoaXMucm93KSArICIvIiArIEJ5dGVzLnRvU3RyaW5nKHRoaXMuY29sdW1uKSArICIvIiArCisgICAgICB0aW1lc3RhbXA7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBPYmplY3Qgb2JqKSB7CisgICAgaWYgKHRoaXMgPT0gb2JqKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGZpbmFsIEhTdG9yZUtleSBvdGhlciA9IChIU3RvcmVLZXkpb2JqOworICAgIC8vIERvIGEgcXVpY2sgY2hlY2suCisgICAgaWYgKHRoaXMucm93Lmxlbmd0aCAhPSBvdGhlci5yb3cubGVuZ3RoIHx8CisgICAgICAgIHRoaXMuY29sdW1uLmxlbmd0aCAhPSBvdGhlci5jb2x1bW4ubGVuZ3RoIHx8CisgICAgICAgIHRoaXMudGltZXN0YW1wICE9IG90aGVyLnRpbWVzdGFtcCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gY29tcGFyZVRvKG90aGVyKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICBpbnQgYyA9IEJ5dGVzLmhhc2hDb2RlKGdldFJvdygpKTsKKyAgICBjIF49IEJ5dGVzLmhhc2hDb2RlKGdldENvbHVtbigpKTsKKyAgICBjIF49IGdldFRpbWVzdGFtcCgpOworICAgIHJldHVybiBjOworICB9CisKKyAgLy8gQ29tcGFyYWJsZQorCisgIC8qKgorICAgKiBAcGFyYW0gbyAKKyAgICogQHJldHVybiBpbnQKKyAgICogQGRlcHJlY2F0ZWQgVXNlIENvbXBhcmF0b3JzIGluc3RlYWQuICBUaGlzIGNhbiBnaXZlIHdyb25nIHJlc3VsdHMuCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgaW50IGNvbXBhcmVUbyhmaW5hbCBIU3RvcmVLZXkgbykgeworICAgIHJldHVybiBjb21wYXJlVG8odGhpcywgbyk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGxlZnQKKyAgICogQHBhcmFtIHJpZ2h0CisgICAqIEByZXR1cm4KKyAgICogQGRlcHJlY2F0ZWQgVXNlIENvbXBhcmF0b3JzIGluc3RlYWQuICBUaGlzIGNhbiBnaXZlIHdyb25nIHJlc3VsdHMgYmVjYXVzZQorICAgKiBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCBzcGVjaWFsIGhhbmRsaW5nIG5lZWRlZCBmb3IgbWV0YSBhbmQgcm9vdCByb3dzLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgc3RhdGljIGludCBjb21wYXJlVG8oZmluYWwgSFN0b3JlS2V5IGxlZnQsIGZpbmFsIEhTdG9yZUtleSByaWdodCkgeworICAgIC8vIFdlIGNhbiBiZSBwYXNzZWQgbnVsbAorICAgIGlmIChsZWZ0ID09IG51bGwgJiYgcmlnaHQgPT0gbnVsbCkgcmV0dXJuIDA7CisgICAgaWYgKGxlZnQgPT0gbnVsbCkgcmV0dXJuIC0xOworICAgIGlmIChyaWdodCA9PSBudWxsKSByZXR1cm4gMTsKKyAgICAKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKGxlZnQuZ2V0Um93KCksIHJpZ2h0LmdldFJvdygpKTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIHJlc3VsdCA9IGxlZnQuZ2V0Q29sdW1uKCkgPT0gbnVsbCAmJiByaWdodC5nZXRDb2x1bW4oKSA9PSBudWxsPyAwOgorICAgICAgbGVmdC5nZXRDb2x1bW4oKSA9PSBudWxsICYmIHJpZ2h0LmdldENvbHVtbigpICE9IG51bGw/IC0xOgorICAgICAgICBsZWZ0LmdldENvbHVtbigpICE9IG51bGwgJiYgcmlnaHQuZ2V0Q29sdW1uKCkgPT0gbnVsbD8gMToKKyAgICAgICAgICBCeXRlcy5jb21wYXJlVG8obGVmdC5nZXRDb2x1bW4oKSwgcmlnaHQuZ2V0Q29sdW1uKCkpOworICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgLy8gVGhlIGJlbG93IG9sZGVyIHRpbWVzdGFtcHMgc29ydGluZyBhaGVhZCBvZiBuZXdlciB0aW1lc3RhbXBzIGxvb2tzCisgICAgLy8gd3JvbmcgYnV0IGl0IGlzIGludGVudGlvbmFsLiBUaGlzIHdheSwgbmV3ZXIgdGltZXN0YW1wcyBhcmUgZmlyc3QKKyAgICAvLyBmb3VuZCB3aGVuIHdlIGl0ZXJhdGUgb3ZlciBhIG1lbWNhY2hlIGFuZCBuZXdlciB2ZXJzaW9ucyBhcmUgdGhlCisgICAgLy8gZmlyc3Qgd2UgdHJpcCBvdmVyIHdoZW4gcmVhZGluZyBmcm9tIGEgc3RvcmUgZmlsZS4KKyAgICBpZiAobGVmdC5nZXRUaW1lc3RhbXAoKSA8IHJpZ2h0LmdldFRpbWVzdGFtcCgpKSB7CisgICAgICByZXN1bHQgPSAxOworICAgIH0gZWxzZSBpZiAobGVmdC5nZXRUaW1lc3RhbXAoKSA+IHJpZ2h0LmdldFRpbWVzdGFtcCgpKSB7CisgICAgICByZXN1bHQgPSAtMTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEByZXR1cm4gTmV3IGJ5dGUgYXJyYXkgdGhhdCBob2xkcyA8Y29kZT5jb2x1bW48L2NvZGU+IGZhbWlseSBwcmVmaXggb25seQorICAgKiAoRG9lcyBub3QgaW5jbHVkZSB0aGUgY29sb24gREVMSU1JVEVSKS4KKyAgICogQHRocm93cyBDb2x1bW5OYW1lUGFyc2VFeGNlcHRpb24gCisgICAqIEBzZWUgI3BhcnNlQ29sdW1uKGJ5dGVbXSkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBnZXRGYW1pbHkoZmluYWwgYnl0ZSBbXSBjb2x1bW4pCisgIHRocm93cyBDb2x1bW5OYW1lUGFyc2VFeGNlcHRpb24geworICAgIGZpbmFsIGludCBpbmRleCA9IGdldEZhbWlseURlbGltaXRlckluZGV4KGNvbHVtbik7CisgICAgaWYgKGluZGV4IDw9IDApIHsKKyAgICAgIHRocm93IG5ldyBDb2x1bW5OYW1lUGFyc2VFeGNlcHRpb24oIk1pc3NpbmcgJzonIGRlbGltaXRlciBiZXR3ZWVuICIgKworICAgICAgICAiY29sdW1uIGZhbWlseSBhbmQgcXVhbGlmaWVyIGluIHRoZSBwYXNzZWQgY29sdW1uIG5hbWUgPCIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhjb2x1bW4pICsgIj4iKTsKKyAgICB9CisgICAgZmluYWwgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtpbmRleF07CisgICAgU3lzdGVtLmFycmF5Y29weShjb2x1bW4sIDAsIHJlc3VsdCwgMCwgaW5kZXgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEByZXR1cm4gUmV0dXJuIGhhc2ggb2YgZmFtaWx5IHBvcnRpb24gb2YgcGFzc2VkIGNvbHVtbi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSW50ZWdlciBnZXRGYW1pbHlNYXBLZXkoZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICBmaW5hbCBpbnQgaW5kZXggPSBnZXRGYW1pbHlEZWxpbWl0ZXJJbmRleChjb2x1bW4pOworICAgIC8vIElmIGluZGV4IDwgLTEsIHByZXN1bWUgcGFzc2VkIGNvbHVtbiBpcyBhIGZhbWlseSBuYW1lIGFic2VudCBjb2xvbgorICAgIC8vIGRlbGltaXRlcgorICAgIHJldHVybiBCeXRlcy5tYXBLZXkoY29sdW1uLCBpbmRleCA+IDA/IGluZGV4OiBjb2x1bW4ubGVuZ3RoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBmYW1pbHkKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+Y29sdW1uPC9jb2RlPiBoYXMgYSBmYW1pbHkgb2YgPGNvZGU+ZmFtaWx5PC9jb2RlPi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBtYXRjaGluZ0ZhbWlseShmaW5hbCBieXRlIFtdIGZhbWlseSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgLy8gTWFrZSBzdXJlIGluZGV4IG9mIHRoZSAnOicgaXMgYXQgc2FtZSBvZmZzZXQuCisgICAgZmluYWwgaW50IGluZGV4ID0gZ2V0RmFtaWx5RGVsaW1pdGVySW5kZXgoY29sdW1uKTsKKyAgICBpZiAoaW5kZXggIT0gZmFtaWx5Lmxlbmd0aCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKGZhbWlseSwgMCwgaW5kZXgsIGNvbHVtbiwgMCwgaW5kZXgpID09IDA7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGZhbWlseQorICAgKiBAcmV0dXJuIFJldHVybiA8Y29kZT5mYW1pbHk8L2NvZGU+IHBsdXMgdGhlIGZhbWlseSBkZWxpbWl0ZXIuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gYWRkRGVsaW1pdGVyKGZpbmFsIGJ5dGUgW10gZmFtaWx5KSB7CisgICAgLy8gTWFudWZhY3R1cmUga2V5IGJ5IGFkZGluZyBkZWxpbWl0ZXIgdG8gdGhlIHBhc3NlZCBpbiBjb2xGYW1pbHkuCisgICAgZmluYWwgYnl0ZSBbXSBmYW1pbHlQbHVzRGVsaW1pdGVyID0gbmV3IGJ5dGUgW2ZhbWlseS5sZW5ndGggKyAxXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGZhbWlseSwgMCwgZmFtaWx5UGx1c0RlbGltaXRlciwgMCwgZmFtaWx5Lmxlbmd0aCk7CisgICAgZmFtaWx5UGx1c0RlbGltaXRlcltmYW1pbHkubGVuZ3RoXSA9IEhTdG9yZUtleS5DT0xVTU5fRkFNSUxZX0RFTElNSVRFUjsKKyAgICByZXR1cm4gZmFtaWx5UGx1c0RlbGltaXRlcjsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEByZXR1cm4gTmV3IGJ5dGUgYXJyYXkgdGhhdCBob2xkcyA8Y29kZT5jb2x1bW48L2NvZGU+IHF1YWxpZmllciBzdWZmaXguCisgICAqIEBzZWUgI3BhcnNlQ29sdW1uKGJ5dGVbXSkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBnZXRRdWFsaWZpZXIoZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICBmaW5hbCBpbnQgaW5kZXggPSBnZXRGYW1pbHlEZWxpbWl0ZXJJbmRleChjb2x1bW4pOworICAgIGZpbmFsIGludCBsZW4gPSBjb2x1bW4ubGVuZ3RoIC0gKGluZGV4ICsgMSk7CisgICAgZmluYWwgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtsZW5dOworICAgIFN5c3RlbS5hcnJheWNvcHkoY29sdW1uLCBpbmRleCArIDEsIHJlc3VsdCwgMCwgbGVuKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjIENvbHVtbiBuYW1lCisgICAqIEByZXR1cm4gUmV0dXJuIGFycmF5IG9mIHNpemUgdHdvIHdob3NlIGZpcnN0IGVsZW1lbnQgaGFzIHRoZSBmYW1pbHkKKyAgICogcHJlZml4IG9mIHBhc3NlZCBjb2x1bW4gPGNvZGU+YzwvY29kZT4gYW5kIHdob3NlIHNlY29uZCBlbGVtZW50IGlzIHRoZQorICAgKiBjb2x1bW4gcXVhbGlmaWVyLgorICAgKiBAdGhyb3dzIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXVtdIHBhcnNlQ29sdW1uKGZpbmFsIGJ5dGUgW10gYykKKyAgdGhyb3dzIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbiB7CisgICAgZmluYWwgYnl0ZSBbXVtdIHJlc3VsdCA9IG5ldyBieXRlIFsyXVtdOworICAgIGZpbmFsIGludCBpbmRleCA9IGdldEZhbWlseURlbGltaXRlckluZGV4KGMpOworICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgdGhyb3cgbmV3IENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbigiSW1wb3NzaWJsZSBjb2x1bW4gbmFtZTogIiArIEJ5dGVzLnRvU3RyaW5nKGMpKTsKKyAgICB9CisgICAgcmVzdWx0WzBdID0gbmV3IGJ5dGUgW2luZGV4XTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGMsIDAsIHJlc3VsdFswXSwgMCwgaW5kZXgpOworICAgIGZpbmFsIGludCBsZW4gPSBjLmxlbmd0aCAtIChpbmRleCArIDEpOworICAgIHJlc3VsdFsxXSA9IG5ldyBieXRlW2xlbl07CisgICAgU3lzdGVtLmFycmF5Y29weShjLCBpbmRleCArIDEgLypTa2lwIGRlbGltaXRlciovLCByZXN1bHRbMV0sIDAsCisgICAgICBsZW4pOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGIKKyAgICogQHJldHVybiBJbmRleCBvZiB0aGUgZmFtaWx5LXF1YWxpZmllciBjb2xvbiBkZWxpbWl0ZXIgY2hhcmFjdGVyIGluIHBhc3NlZAorICAgKiBidWZmZXIuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBnZXRGYW1pbHlEZWxpbWl0ZXJJbmRleChmaW5hbCBieXRlIFtdIGIpIHsKKyAgICByZXR1cm4gZ2V0RGVsaW1pdGVyKGIsIDAsIGIubGVuZ3RoLCBDT0xVTU5fRkFNSUxZX0RFTElNSVRFUik7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0UmVxdWlyZWREZWxpbWl0ZXJJblJldmVyc2UoZmluYWwgYnl0ZSBbXSBiLAorICAgICAgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCwgZmluYWwgaW50IGRlbGltaXRlcikgeworICAgIGludCBpbmRleCA9IGdldERlbGltaXRlckluUmV2ZXJzZShiLCBvZmZzZXQsIGxlbmd0aCwgZGVsaW1pdGVyKTsKKyAgICBpZiAoaW5kZXggPCAwKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJObyAiICsgZGVsaW1pdGVyICsgIiBpbiA8IiArCisgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGIpICsgIj4iICsgIiwgbGVuZ3RoPSIgKyBsZW5ndGggKyAiLCBvZmZzZXQ9IiArIG9mZnNldCk7CisgICAgfQorICAgIHJldHVybiBpbmRleDsKKyAgfQorICAvKgorICAgKiBAcGFyYW0gYgorICAgKiBAcGFyYW0gZGVsaW1pdGVyCisgICAqIEByZXR1cm4gSW5kZXggb2YgZGVsaW1pdGVyIGhhdmluZyBzdGFydGVkIGZyb20gZW5kIG9mIDxjb2RlPmI8L2NvZGU+IG1vdmluZworICAgKiBsZWZ0d2FyZC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGludCBnZXREZWxpbWl0ZXIoZmluYWwgYnl0ZSBbXSBiLCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoLAorICAgICAgZmluYWwgaW50IGRlbGltaXRlcikgeworICAgIGlmIChiID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGxlbmd0aCArIG9mZnNldDsgaSsrKSB7CisgICAgICBpZiAoYltpXSA9PSBkZWxpbWl0ZXIpIHsKKyAgICAgICAgcmVzdWx0ID0gaTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gYgorICAgKiBAcGFyYW0gZGVsaW1pdGVyCisgICAqIEByZXR1cm4gSW5kZXggb2YgZGVsaW1pdGVyCisgICAqLworICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0RGVsaW1pdGVySW5SZXZlcnNlKGZpbmFsIGJ5dGUgW10gYiwgZmluYWwgaW50IG9mZnNldCwKKyAgICAgIGZpbmFsIGludCBsZW5ndGgsIGZpbmFsIGludCBkZWxpbWl0ZXIpIHsKKyAgICBpZiAoYiA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgaW50IHJlc3VsdCA9IC0xOworICAgIGZvciAoaW50IGkgPSAob2Zmc2V0ICsgbGVuZ3RoKSAtIDE7IGkgPj0gb2Zmc2V0OyBpLS0pIHsKKyAgICAgIGlmIChiW2ldID09IGRlbGltaXRlcikgeworICAgICAgICByZXN1bHQgPSBpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBVdGlsaXR5IG1ldGhvZCB0byBjaGVjayBpZiB0d28gcm93IGtleXMgYXJlIGVxdWFsLgorICAgKiBUaGlzIGlzIHJlcXVpcmVkIGJlY2F1c2Ugb2YgdGhlIG1ldGEgZGVsaW1pdGVycworICAgKiBUaGlzIGlzIGEgaGFjaworICAgKiBAcGFyYW0gcm93QQorICAgKiBAcGFyYW0gcm93QgorICAgKiBAcmV0dXJuIGlmIGl0J3MgZXF1YWwKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHNUd29Sb3dLZXlzKGZpbmFsIGJ5dGVbXSByb3dBLCBmaW5hbCBieXRlW10gcm93QikgeworICAgIHJldHVybiAoKHJvd0EgPT0gbnVsbCkgJiYgKHJvd0IgPT0gbnVsbCkpID8gdHJ1ZToKKyAgICAgIChyb3dBID09IG51bGwpIHx8IChyb3dCID09IG51bGwpIHx8IChyb3dBLmxlbmd0aCAhPSByb3dCLmxlbmd0aCkgPyBmYWxzZToKKyAgICAgICAgQnl0ZXMuY29tcGFyZVRvKHJvd0EsIHJvd0IpID09IDA7CisgIH0KKworICAvLyBXcml0YWJsZQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5yb3cpOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5jb2x1bW4pOworICAgIG91dC53cml0ZUxvbmcodGltZXN0YW1wKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoZmluYWwgRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMucm93ID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgdGhpcy5jb2x1bW4gPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICB0aGlzLnRpbWVzdGFtcCA9IGluLnJlYWRMb25nKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGhzaworICAgKiBAcmV0dXJuIFNpemUgb2YgdGhpcyBrZXkgaW4gc2VyaWFsaXplZCBieXRlcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKGZpbmFsIEhTdG9yZUtleSBoc2spIHsKKyAgICByZXR1cm4gZ2V0U2VyaWFsaXplZFNpemUoaHNrLmdldFJvdygpKSArCisgICAgICBnZXRTZXJpYWxpemVkU2l6ZShoc2suZ2V0Q29sdW1uKCkpICsKKyAgICAgIEJ5dGVzLlNJWkVPRl9MT05HOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEByZXR1cm4gTGVuZ3RoIG9mIGJ1ZmZlciB3aGVuIGl0cyBiZWVuIHNlcmlhbGl6ZWQuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgcmV0dXJuIGIgPT0gbnVsbD8gMTogYi5sZW5ndGggKyBXcml0YWJsZVV0aWxzLmdldFZJbnRTaXplKGIubGVuZ3RoKTsKKyAgfQorCisgIHB1YmxpYyBsb25nIGhlYXBTaXplKCkgeworICAgIHJldHVybiBnZXRSb3coKS5sZW5ndGggKyBCeXRlcy5FU1RJTUFURURfSEVBUF9UQVggKworICAgICAgZ2V0Q29sdW1uKCkubGVuZ3RoICsgQnl0ZXMuRVNUSU1BVEVEX0hFQVBfVEFYICsKKyAgICAgIEVTVElNQVRFRF9IRUFQX1RBWDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiA8Y29kZT5oc2s8L2NvZGU+IGdvdHRlbiBieSBydW5uaW5nIGl0cyAKKyAgICoge0BsaW5rIFdyaXRhYmxlI3dyaXRlKGphdmEuaW8uRGF0YU91dHB1dCl9IG1ldGhvZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0Qnl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRCeXRlcyh0aGlzKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gc2VyaWFsaXplIDxjb2RlPmhzazwvY29kZT4gYnl0ZXMuCisgICAqIE5vdGUsIHRoaXMgbWV0aG9kJ3MgaW1wbGVtZW50YXRpb24gaGFzIGNoYW5nZWQuICBVc2VkIHRvIGp1c3QgcmV0dXJuCisgICAqIHJvdyBhbmQgY29sdW1uLiAgVGhpcyBpcyBhIGN1c3RvbWl6ZWQgdmVyc2lvbiBvZgorICAgKiB7QGxpbmsgV3JpdGFibGVzI2dldEJ5dGVzKFdyaXRhYmxlKX0KKyAgICogQHBhcmFtIGhzayBJbnN0YW5jZQorICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiA8Y29kZT5oc2s8L2NvZGU+IGdvdHRlbiBieSBydW5uaW5nIGl0cyAKKyAgICoge0BsaW5rIFdyaXRhYmxlI3dyaXRlKGphdmEuaW8uRGF0YU91dHB1dCl9IG1ldGhvZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGdldEJ5dGVzKGZpbmFsIEhTdG9yZUtleSBoc2spIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldEJ5dGVzKGhzay5nZXRSb3coKSwgaHNrLmdldENvbHVtbigpLCBoc2suZ2V0VGltZXN0YW1wKCkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByb3cgQ2FuJ3QgYmUgbnVsbAorICAgKiBAcmV0dXJuIFBhc3NlZCBhcmd1bWVudHMgYXMgYSBzZXJpYWxpemVkIEhTSy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGdldEJ5dGVzKGZpbmFsIGJ5dGUgW10gcm93KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRCeXRlcyhyb3csIG51bGwsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJvdyBDYW4ndCBiZSBudWxsCisgICAqIEBwYXJhbSBjb2x1bW4gQ2FuIGJlIG51bGwKKyAgICogQHBhcmFtIHRzCisgICAqIEByZXR1cm4gUGFzc2VkIGFyZ3VtZW50cyBhcyBhIHNlcmlhbGl6ZWQgSFNLLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gZ2V0Qnl0ZXMoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uLAorICAgIGZpbmFsIGxvbmcgdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gVE9ETzogR2V0IHZpbnQgc2l6ZXMgYXMgSSBjYWxjdWxhdGUgc2VyaWFsaXplZCBzaXplIG9mIGhzay4KKyAgICBieXRlIFtdIGIgPSBuZXcgYnl0ZSBbZ2V0U2VyaWFsaXplZFNpemUocm93KSArCisgICAgICBnZXRTZXJpYWxpemVkU2l6ZShjb2x1bW4pICsgQnl0ZXMuU0laRU9GX0xPTkddOworICAgIGludCBvZmZzZXQgPSBCeXRlcy53cml0ZUJ5dGVBcnJheShiLCAwLCByb3csIDAsIHJvdy5sZW5ndGgpOworICAgIGJ5dGUgW10gYyA9IGNvbHVtbiA9PSBudWxsPyBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVk6IGNvbHVtbjsKKyAgICBvZmZzZXQgPSBCeXRlcy53cml0ZUJ5dGVBcnJheShiLCBvZmZzZXQsIGMsIDAsIGMubGVuZ3RoKTsKKyAgICBieXRlIFtdIHRpbWVzdGFtcCA9IEJ5dGVzLnRvQnl0ZXModHMpOworICAgIFN5c3RlbS5hcnJheWNvcHkodGltZXN0YW1wLCAwLCBiLCBvZmZzZXQsIHRpbWVzdGFtcC5sZW5ndGgpOworICAgIHJldHVybiBiOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiYiBCeXRlQnVmZmVyIHRoYXQgY29udGFpbnMgc2VyaWFsaXplZCBIU3RvcmVLZXkKKyAgICogQHJldHVybiBSb3cKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBnZXRSb3coZmluYWwgQnl0ZUJ1ZmZlciBiYikgeworICAgIGJ5dGUgZmlyc3RCeXRlID0gYmIuZ2V0KDApOworICAgIGludCB2aW50ID0gZmlyc3RCeXRlOworICAgIGludCB2aW50V2lkdGggPSBXcml0YWJsZVV0aWxzLmRlY29kZVZJbnRTaXplKGZpcnN0Qnl0ZSk7CisgICAgaWYgKHZpbnRXaWR0aCAhPSAxKSB7CisgICAgICB2aW50ID0gZ2V0QmlnVmludCh2aW50V2lkdGgsIGZpcnN0Qnl0ZSwgYmIuYXJyYXkoKSwgYmIuYXJyYXlPZmZzZXQoKSk7CisgICAgfQorICAgIGJ5dGUgW10gYiA9IG5ldyBieXRlIFt2aW50XTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGJiLmFycmF5KCksIGJiLmFycmF5T2Zmc2V0KCkgKyB2aW50V2lkdGgsIGIsIDAsIHZpbnQpOworICAgIHJldHVybiBiOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiYiBCeXRlQnVmZmVyIHRoYXQgY29udGFpbnMgc2VyaWFsaXplZCBIU3RvcmVLZXkKKyAgICogQHJldHVybiBDb2x1bW4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBnZXRDb2x1bW4oZmluYWwgQnl0ZUJ1ZmZlciBiYikgeworICAgIC8vIFNraXAgb3ZlciByb3cuCisgICAgaW50IG9mZnNldCA9IHNraXBWaW50ZEJ5dGVBcnJheShiYiwgMCk7CisgICAgYnl0ZSBmaXJzdEJ5dGUgPSBiYi5nZXQob2Zmc2V0KTsKKyAgICBpbnQgdmludCA9IGZpcnN0Qnl0ZTsKKyAgICBpbnQgdmludFdpZHRoID0gV3JpdGFibGVVdGlscy5kZWNvZGVWSW50U2l6ZShmaXJzdEJ5dGUpOworICAgIGlmICh2aW50V2lkdGggIT0gMSkgeworICAgICAgdmludCA9IGdldEJpZ1ZpbnQodmludFdpZHRoLCBmaXJzdEJ5dGUsIGJiLmFycmF5KCksCisgICAgICAgIGJiLmFycmF5T2Zmc2V0KCkgKyBvZmZzZXQpOworICAgIH0KKyAgICBieXRlIFtdIGIgPSBuZXcgYnl0ZSBbdmludF07CisgICAgU3lzdGVtLmFycmF5Y29weShiYi5hcnJheSgpLCBiYi5hcnJheU9mZnNldCgpICsgb2Zmc2V0ICsgdmludFdpZHRoLCBiLCAwLAorICAgICAgdmludCk7CisgICAgcmV0dXJuIGI7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGJiIEJ5dGVCdWZmZXIgdGhhdCBjb250YWlucyBzZXJpYWxpemVkIEhTdG9yZUtleQorICAgKiBAcmV0dXJuIFRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGdldFRpbWVzdGFtcChmaW5hbCBCeXRlQnVmZmVyIGJiKSB7CisgICAgcmV0dXJuIGJiLmdldExvbmcoYmIubGltaXQoKSAtIEJ5dGVzLlNJWkVPRl9MT05HKTsKKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSBiYgorICAgKiBAcGFyYW0gb2Zmc2V0CisgICAqIEByZXR1cm4gQW1vdW50IHRvIHNraXAgdG8gZ2V0IHBhc3RlIGEgYnl0ZSBhcnJheSB0aGF0IGlzIHByZWNlZGVkIGJ5IGEKKyAgICogdmludCBvZiBob3cgbG9uZyBpdCBpcy4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGludCBza2lwVmludGRCeXRlQXJyYXkoZmluYWwgQnl0ZUJ1ZmZlciBiYiwgZmluYWwgaW50IG9mZnNldCkgeworICAgIGJ5dGUgZmlyc3RCeXRlID0gYmIuZ2V0KG9mZnNldCk7CisgICAgaW50IHZpbnQgPSBmaXJzdEJ5dGU7CisgICAgaW50IHZpbnRXaWR0aCA9IFdyaXRhYmxlVXRpbHMuZGVjb2RlVkludFNpemUoZmlyc3RCeXRlKTsKKyAgICBpZiAodmludFdpZHRoICE9IDEpIHsKKyAgICAgIHZpbnQgPSBnZXRCaWdWaW50KHZpbnRXaWR0aCwgZmlyc3RCeXRlLCBiYi5hcnJheSgpLAorICAgICAgICBiYi5hcnJheU9mZnNldCgpICsgb2Zmc2V0KTsKKyAgICB9CisgICAgcmV0dXJuIHZpbnQgKyB2aW50V2lkdGggKyBvZmZzZXQ7CisgIH0KKworICAvKgorICAgKiBWaW50IGlzIHdpZGVyIHRoYW4gb25lIGJ5dGUuICBGaW5kIG91dCBob3cgbXVjaCBiaWdnZXIgaXQgaXMuCisgICAqIEBwYXJhbSB2aW50V2lkdGgKKyAgICogQHBhcmFtIGZpcnN0Qnl0ZQorICAgKiBAcGFyYW0gYnVmZmVyCisgICAqIEBwYXJhbSBvZmZzZXQKKyAgICogQHJldHVybgorICAgKi8KKyAgc3RhdGljIGludCBnZXRCaWdWaW50KGZpbmFsIGludCB2aW50V2lkdGgsIGZpbmFsIGJ5dGUgZmlyc3RCeXRlLAorICAgICAgZmluYWwgYnl0ZSBbXSBidWZmZXIsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICBsb25nIGkgPSAwOworICAgIGZvciAoaW50IGlkeCA9IDA7IGlkeCA8IHZpbnRXaWR0aCAtIDE7IGlkeCsrKSB7CisgICAgICBmaW5hbCBieXRlIGIgPSBidWZmZXJbb2Zmc2V0ICsgMSArIGlkeF07CisgICAgICBpID0gaSA8PCA4OworICAgICAgaSA9IGkgfCAoYiAmIDB4RkYpOworICAgIH0KKyAgICBpID0gKFdyaXRhYmxlVXRpbHMuaXNOZWdhdGl2ZVZJbnQoZmlyc3RCeXRlKSA/IChpIF4gLTFMKSA6IGkpOworICAgIGlmIChpID4gSW50ZWdlci5NQVhfVkFMVUUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbGN1bGF0ZWQgdmludCB0b28gbGFyZ2UiKTsKKyAgICB9CisgICAgcmV0dXJuIChpbnQpaTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBzdG9yZSBrZXkuCisgICAqIEBwYXJhbSBiYgorICAgKiBAcmV0dXJuIEhTdG9yZUtleSBpbnN0YW5jZSBtYWRlIG9mIHRoZSBwYXNzZWQgPGNvZGU+YjwvY29kZT4uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFN0b3JlS2V5IGNyZWF0ZShmaW5hbCBCeXRlQnVmZmVyIGJiKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBIU3RvcmVLZXkuY3JlYXRlKGJiLmFycmF5KCksIGJiLmFycmF5T2Zmc2V0KCksIGJiLmxpbWl0KCkpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIHN0b3JlIGtleS4KKyAgICogQHBhcmFtIGIgU2VyaWFsaXplZCBIU3RvcmVLZXk7IGEgYnl0ZSBhcnJheSB3aXRoIGEgcm93IG9ubHkgaW4gaXQgd29uJ3QgZG8uCisgICAqIEl0IG11c3QgaGF2ZSBhbGwgdGhlIHZpbnRzIGRlbm90aW5nIHIvYy90cyBsZW5ndGhzLgorICAgKiBAcmV0dXJuIEhTdG9yZUtleSBpbnN0YW5jZSBtYWRlIG9mIHRoZSBwYXNzZWQgPGNvZGU+YjwvY29kZT4uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFN0b3JlS2V5IGNyZWF0ZShmaW5hbCBieXRlIFtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNyZWF0ZShiLCAwLCBiLmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgc3RvcmUga2V5LgorICAgKiBAcGFyYW0gYiBTZXJpYWxpemVkIEhTdG9yZUtleQorICAgKiBAcGFyYW0gb2Zmc2V0CisgICAqIEBwYXJhbSBsZW5ndGgKKyAgICogQHJldHVybiBIU3RvcmVLZXkgaW5zdGFuY2UgbWFkZSBvZiB0aGUgcGFzc2VkIDxjb2RlPmI8L2NvZGU+LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIEhTdG9yZUtleSBjcmVhdGUoZmluYWwgYnl0ZSBbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgIGZpbmFsIGludCBsZW5ndGgpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZSBmaXJzdEJ5dGUgPSBiW29mZnNldF07CisgICAgaW50IHZpbnQgPSBmaXJzdEJ5dGU7CisgICAgaW50IHZpbnRXaWR0aCA9IFdyaXRhYmxlVXRpbHMuZGVjb2RlVkludFNpemUoZmlyc3RCeXRlKTsKKyAgICBpZiAodmludFdpZHRoICE9IDEpIHsKKyAgICAgIHZpbnQgPSBnZXRCaWdWaW50KHZpbnRXaWR0aCwgZmlyc3RCeXRlLCBiLCBvZmZzZXQpOworICAgIH0KKyAgICBieXRlIFtdIHJvdyA9IG5ldyBieXRlIFt2aW50XTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIG9mZnNldCArIHZpbnRXaWR0aCwKKyAgICAgIHJvdywgMCwgcm93Lmxlbmd0aCk7CisgICAgLy8gU2tpcCBvdmVyIHJvdy4KKyAgICBpbnQgZXh0cmFPZmZzZXQgPSB2aW50ICsgdmludFdpZHRoOworICAgIGZpcnN0Qnl0ZSA9IGJbb2Zmc2V0ICsgZXh0cmFPZmZzZXRdOworICAgIHZpbnQgPSBmaXJzdEJ5dGU7CisgICAgdmludFdpZHRoID0gV3JpdGFibGVVdGlscy5kZWNvZGVWSW50U2l6ZShmaXJzdEJ5dGUpOworICAgIGlmICh2aW50V2lkdGggIT0gMSkgeworICAgICAgdmludCA9IGdldEJpZ1ZpbnQodmludFdpZHRoLCBmaXJzdEJ5dGUsIGIsIG9mZnNldCArIGV4dHJhT2Zmc2V0KTsKKyAgICB9CisgICAgYnl0ZSBbXSBjb2x1bW4gPSBuZXcgYnl0ZSBbdmludF07CisgICAgU3lzdGVtLmFycmF5Y29weShiLCBvZmZzZXQgKyBleHRyYU9mZnNldCArIHZpbnRXaWR0aCwKKyAgICAgIGNvbHVtbiwgMCwgY29sdW1uLmxlbmd0aCk7CisgICAgLy8gU2tpcCBvdmVyIGNvbHVtbgorICAgIGV4dHJhT2Zmc2V0ICs9ICh2aW50ICsgdmludFdpZHRoKTsKKyAgICByZXR1cm4gbmV3IEhTdG9yZUtleShyb3csIGNvbHVtbiwgQnl0ZXMudG9Mb25nKGIsIG9mZnNldCArIGV4dHJhT2Zmc2V0KSk7CisgIH0KKworICAvKioKKyAgICogUGFzc2VkIGFzIGNvbXBhcmF0b3IgZm9yIG1lbWNhY2hlIGFuZCBmb3Igc3RvcmUgZmlsZXMuICBTZWUgSEJBU0UtODY4LgorICAgKiBVc2UgdGhpcyBjb21wYXJpbmcga2V5cyBpbiB0aGUgLVJPT1RfIHRhYmxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBIU3RvcmVLZXlSb290Q29tcGFyYXRvciBleHRlbmRzIEhTdG9yZUtleU1ldGFDb21wYXJhdG9yIHsKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGNvbXBhcmVSb3dzKGJ5dGUgW10gbGVmdCwgaW50IGxvZmZzZXQsIGludCBsbGVuZ3RoLAorICAgICAgICBieXRlIFtdIHJpZ2h0LCBpbnQgcm9mZnNldCwgaW50IHJsZW5ndGgpIHsKKyAgICAgIHJldHVybiBjb21wYXJlUm9vdFJvd3MobGVmdCwgbG9mZnNldCwgbGxlbmd0aCwgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQYXNzZWQgYXMgY29tcGFyYXRvciBmb3IgbWVtY2FjaGUgYW5kIGZvciBzdG9yZSBmaWxlcy4gIFNlZSBIQkFTRS04NjguCisgICAqIFVzZSB0aGlzIGNvbXByYXRvciBmb3Iga2V5cyBpbiB0aGUgLk1FVEEuIHRhYmxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBIU3RvcmVLZXlNZXRhQ29tcGFyYXRvciBleHRlbmRzIEhTdG9yZUtleUNvbXBhcmF0b3IgeworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgY29tcGFyZVJvd3MoYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGUgW10gcmlnaHQsIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCkgeworICAgICAgcmV0dXJuIGNvbXBhcmVNZXRhUm93cyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLCByaWdodCwgcm9mZnNldCwgcmxlbmd0aCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFBhc3NlZCBhcyBjb21wYXJhdG9yIGZvciBtZW1jYWNoZSBhbmQgZm9yIHN0b3JlIGZpbGVzLiAgU2VlIEhCQVNFLTg2OC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSFN0b3JlS2V5Q29tcGFyYXRvciBleHRlbmRzIFdyaXRhYmxlQ29tcGFyYXRvciB7CisgICAgcHVibGljIEhTdG9yZUtleUNvbXBhcmF0b3IoKSB7CisgICAgICBzdXBlcihIU3RvcmVLZXkuY2xhc3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBpbnQgY29tcGFyZShmaW5hbCBXcml0YWJsZUNvbXBhcmFibGUgbCwKKyAgICAgICAgZmluYWwgV3JpdGFibGVDb21wYXJhYmxlIHIpIHsKKyAgICAgIEhTdG9yZUtleSBsZWZ0ID0gKEhTdG9yZUtleSlsOworICAgICAgSFN0b3JlS2V5IHJpZ2h0ID0gKEhTdG9yZUtleSlyOworICAgICAgLy8gV2UgY2FuIGJlIHBhc3NlZCBudWxsCisgICAgICBpZiAobGVmdCA9PSBudWxsICYmIHJpZ2h0ID09IG51bGwpIHJldHVybiAwOworICAgICAgaWYgKGxlZnQgPT0gbnVsbCkgcmV0dXJuIC0xOworICAgICAgaWYgKHJpZ2h0ID09IG51bGwpIHJldHVybiAxOworICAgICAgCisgICAgICBieXRlIFtdIGxyb3cgPSBsZWZ0LmdldFJvdygpOworICAgICAgYnl0ZSBbXSBycm93ID0gcmlnaHQuZ2V0Um93KCk7CisgICAgICBpbnQgcmVzdWx0ID0gY29tcGFyZVJvd3MobHJvdywgMCwgbHJvdy5sZW5ndGgsIHJyb3csIDAsIHJyb3cubGVuZ3RoKTsKKyAgICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgICAgcmVzdWx0ID0gbGVmdC5nZXRDb2x1bW4oKSA9PSBudWxsICYmIHJpZ2h0LmdldENvbHVtbigpID09IG51bGw/IDA6CisgICAgICAgIGxlZnQuZ2V0Q29sdW1uKCkgPT0gbnVsbCA/IC0xOnJpZ2h0LmdldENvbHVtbigpID09IG51bGw/IDE6CisgICAgICAgICAgICBCeXRlcy5jb21wYXJlVG8obGVmdC5nZXRDb2x1bW4oKSwgcmlnaHQuZ2V0Q29sdW1uKCkpOworICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9CisgICAgICAvLyBUaGUgYmVsb3cgb2xkZXIgdGltZXN0YW1wcyBzb3J0aW5nIGFoZWFkIG9mIG5ld2VyIHRpbWVzdGFtcHMgbG9va3MKKyAgICAgIC8vIHdyb25nIGJ1dCBpdCBpcyBpbnRlbnRpb25hbC4gVGhpcyB3YXksIG5ld2VyIHRpbWVzdGFtcHMgYXJlIGZpcnN0CisgICAgICAvLyBmb3VuZCB3aGVuIHdlIGl0ZXJhdGUgb3ZlciBhIG1lbWNhY2hlIGFuZCBuZXdlciB2ZXJzaW9ucyBhcmUgdGhlCisgICAgICAvLyBmaXJzdCB3ZSB0cmlwIG92ZXIgd2hlbiByZWFkaW5nIGZyb20gYSBzdG9yZSBmaWxlLgorICAgICAgaWYgKGxlZnQuZ2V0VGltZXN0YW1wKCkgPCByaWdodC5nZXRUaW1lc3RhbXAoKSkgeworICAgICAgICByZXN1bHQgPSAxOworICAgICAgfSBlbHNlIGlmIChsZWZ0LmdldFRpbWVzdGFtcCgpID4gcmlnaHQuZ2V0VGltZXN0YW1wKCkpIHsKKyAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OyAvLyBhcmUgZXF1YWwKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgaW50IGNvbXBhcmVSb3dzKGZpbmFsIGJ5dGUgW10gbGVmdCwgZmluYWwgaW50IGxvZmZzZXQsCisgICAgICAgIGZpbmFsIGludCBsbGVuZ3RoLCBmaW5hbCBieXRlIFtdIHJpZ2h0LCBmaW5hbCBpbnQgcm9mZnNldCwKKyAgICAgICAgZmluYWwgaW50IHJsZW5ndGgpIHsKKyAgICAgIHJldHVybiBCeXRlcy5jb21wYXJlVG8obGVmdCwgbG9mZnNldCwgbGxlbmd0aCwgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTdG9yZUtleUNvbXBhcmF0b3IgZm9yIHRoZSAtUk9PVC0gdGFibGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFJvb3RTdG9yZUtleUNvbXBhcmF0b3IKKyAgZXh0ZW5kcyBNZXRhU3RvcmVLZXlDb21wYXJhdG9yIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGUgW10gcmlnaHQsIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCkgeworICAgICAgcmV0dXJuIGNvbXBhcmVSb290Um93cyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLCByaWdodCwgcm9mZnNldCwgcmxlbmd0aCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFN0b3JlS2V5Q29tcGFyYXRvciBmb3IgdGhlIC5NRVRBLiB0YWJsZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTWV0YVN0b3JlS2V5Q29tcGFyYXRvciBleHRlbmRzIFN0b3JlS2V5Q29tcGFyYXRvciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjb21wYXJlUm93cyhieXRlIFtdIGxlZnQsIGludCBsb2Zmc2V0LCBpbnQgbGxlbmd0aCwKKyAgICAgICAgYnl0ZSBbXSByaWdodCwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgICByZXR1cm4gY29tcGFyZU1ldGFSb3dzKGxlZnQsIGxvZmZzZXQsIGxsZW5ndGgsIHJpZ2h0LCByb2Zmc2V0LCBybGVuZ3RoKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gbGVmdAorICAgKiBAcGFyYW0gbG9mZnNldAorICAgKiBAcGFyYW0gbGxlbmd0aAorICAgKiBAcGFyYW0gcmlnaHQKKyAgICogQHBhcmFtIHJvZmZzZXQKKyAgICogQHBhcmFtIHJsZW5ndGgKKyAgICogQHJldHVybiBSZXN1bHQgb2YgY29tcGFyaW5nIHR3byByb3dzIGZyb20gdGhlIC1ST09ULSB0YWJsZSBib3RoIG9mIHdoaWNoCisgICAqIGFyZSBvZiB0aGUgZm9ybSAuTUVUQS4sKFRBQkxFLFJFR0lPTk5BTUUsUkVHSU9OSUQpLFJFR0lPTklELgorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBpbnQgY29tcGFyZVJvb3RSb3dzKGJ5dGUgW10gbGVmdCwgaW50IGxvZmZzZXQsIGludCBsbGVuZ3RoLAorICAgICAgYnl0ZSBbXSByaWdodCwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgLy8gUm93cyBsb29rIGxpa2UgdGhpczogLk1FVEEuLFJPV19GUk9NX01FVEEsUklECisgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJST09UICIgKyBCeXRlcy50b1N0cmluZyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoKSArCisgICAgLy8gICItLS0iICsgQnl0ZXMudG9TdHJpbmcocmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgpKTsKKyAgICBpbnQgbG1ldGFPZmZzZXRQbHVzRGVsaW1pdGVyID0gbG9mZnNldCArIDc7IC8vICcuTUVUQS4sJworICAgIGludCBsZWZ0RmFyRGVsaW1pdGVyID0gZ2V0RGVsaW1pdGVySW5SZXZlcnNlKGxlZnQsIGxtZXRhT2Zmc2V0UGx1c0RlbGltaXRlciwKKyAgICAgIGxsZW5ndGggLSBsbWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsIEhSZWdpb25JbmZvLkRFTElNSVRFUik7CisgICAgaW50IHJtZXRhT2Zmc2V0UGx1c0RlbGltaXRlciA9IHJvZmZzZXQgKyA3OyAvLyAnLk1FVEEuLCcKKyAgICBpbnQgcmlnaHRGYXJEZWxpbWl0ZXIgPSBnZXREZWxpbWl0ZXJJblJldmVyc2UocmlnaHQsCisgICAgICBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsIHJsZW5ndGggLSBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsCisgICAgICBIUmVnaW9uSW5mby5ERUxJTUlURVIpOworICAgIGlmIChsZWZ0RmFyRGVsaW1pdGVyIDwgMCAmJiByaWdodEZhckRlbGltaXRlciA+PSAwKSB7CisgICAgICAvLyBOb3RoaW5nIGJldHdlZW4gLk1FVEEuIGFuZCByZWdpb25pZC4gIEl0cyBmaXJzdCBrZXkuCisgICAgICByZXR1cm4gLTE7CisgICAgfSBlbHNlIGlmIChyaWdodEZhckRlbGltaXRlciA8IDAgJiYgbGVmdEZhckRlbGltaXRlciA+PSAwKSB7CisgICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIGlmIChsZWZ0RmFyRGVsaW1pdGVyIDwgMCAmJiByaWdodEZhckRlbGltaXRlciA8IDApIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gY29tcGFyZU1ldGFSb3dzKGxlZnQsIGxtZXRhT2Zmc2V0UGx1c0RlbGltaXRlciwKKyAgICAgIGxlZnRGYXJEZWxpbWl0ZXIgLSBsbWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsCisgICAgICByaWdodCwgcm1ldGFPZmZzZXRQbHVzRGVsaW1pdGVyLAorICAgICAgcmlnaHRGYXJEZWxpbWl0ZXIgLSBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIpOworICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgLy8gQ29tcGFyZSBsYXN0IHBhcnQgb2Ygcm93LCB0aGUgcm93aWQuCisgICAgbGVmdEZhckRlbGltaXRlcisrOworICAgIHJpZ2h0RmFyRGVsaW1pdGVyKys7CisgICAgcmVzdWx0ID0gY29tcGFyZVJvd2lkKGxlZnQsIGxlZnRGYXJEZWxpbWl0ZXIsIGxsZW5ndGggLSBsZWZ0RmFyRGVsaW1pdGVyLAorICAgICAgcmlnaHQsIHJpZ2h0RmFyRGVsaW1pdGVyLCBybGVuZ3RoIC0gcmlnaHRGYXJEZWxpbWl0ZXIpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gbGVmdAorICAgKiBAcGFyYW0gbG9mZnNldAorICAgKiBAcGFyYW0gbGxlbmd0aAorICAgKiBAcGFyYW0gcmlnaHQKKyAgICogQHBhcmFtIHJvZmZzZXQKKyAgICogQHBhcmFtIHJsZW5ndGgKKyAgICogQHJldHVybiBSZXN1bHQgb2YgY29tcGFyaW5nIHR3byByb3dzIGZyb20gdGhlIC5NRVRBLiB0YWJsZSBib3RoIG9mIHdoaWNoCisgICAqIGFyZSBvZiB0aGUgZm9ybSBUQUJMRSxSRUdJT05OQU1FLFJFR0lPTklELgorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBpbnQgY29tcGFyZU1ldGFSb3dzKGZpbmFsIGJ5dGVbXSBsZWZ0LCBmaW5hbCBpbnQgbG9mZnNldCwKKyAgICAgIGZpbmFsIGludCBsbGVuZ3RoLCBmaW5hbCBieXRlW10gcmlnaHQsIGZpbmFsIGludCByb2Zmc2V0LAorICAgICAgZmluYWwgaW50IHJsZW5ndGgpIHsKKy8vICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTUVUQSAiICsgQnl0ZXMudG9TdHJpbmcobGVmdCwgbG9mZnNldCwgbGxlbmd0aCkgKworLy8gICAgICAiLS0tIiArIEJ5dGVzLnRvU3RyaW5nKHJpZ2h0LCByb2Zmc2V0LCBybGVuZ3RoKSk7CisgICAgaW50IGxlZnREZWxpbWl0ZXIgPSBnZXREZWxpbWl0ZXIobGVmdCwgbG9mZnNldCwgbGxlbmd0aCwKKyAgICAgIEhSZWdpb25JbmZvLkRFTElNSVRFUik7CisgICAgaW50IHJpZ2h0RGVsaW1pdGVyID0gZ2V0RGVsaW1pdGVyKHJpZ2h0LCByb2Zmc2V0LCBybGVuZ3RoLAorICAgICAgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICBpZiAobGVmdERlbGltaXRlciA8IDAgJiYgcmlnaHREZWxpbWl0ZXIgPj0gMCkgeworICAgICAgLy8gTm90aGluZyBiZXR3ZWVuIC5NRVRBLiBhbmQgcmVnaW9uaWQuICBJdHMgZmlyc3Qga2V5LgorICAgICAgcmV0dXJuIC0xOworICAgIH0gZWxzZSBpZiAocmlnaHREZWxpbWl0ZXIgPCAwICYmIGxlZnREZWxpbWl0ZXIgPj0gMCkgeworICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIGlmIChsZWZ0RGVsaW1pdGVyIDwgMCAmJiByaWdodERlbGltaXRlciA8IDApIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICAvLyBDb21wYXJlIHVwIHRvIHRoZSBkZWxpbWl0ZXIKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKGxlZnQsIGxvZmZzZXQsIGxlZnREZWxpbWl0ZXIgLSBsb2Zmc2V0LAorICAgICAgcmlnaHQsIHJvZmZzZXQsIHJpZ2h0RGVsaW1pdGVyIC0gcm9mZnNldCk7CisgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICAvLyBDb21wYXJlIG1pZGRsZSBiaXQgb2YgdGhlIHJvdy4KKyAgICAvLyBNb3ZlIHBhc3QgZGVsaW1pdGVyCisgICAgbGVmdERlbGltaXRlcisrOworICAgIHJpZ2h0RGVsaW1pdGVyKys7CisgICAgaW50IGxlZnRGYXJEZWxpbWl0ZXIgPSBnZXRSZXF1aXJlZERlbGltaXRlckluUmV2ZXJzZShsZWZ0LCBsZWZ0RGVsaW1pdGVyLAorICAgICAgICBsbGVuZ3RoIC0gKGxlZnREZWxpbWl0ZXIgLSBsb2Zmc2V0KSwgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICBpbnQgcmlnaHRGYXJEZWxpbWl0ZXIgPSBnZXRSZXF1aXJlZERlbGltaXRlckluUmV2ZXJzZShyaWdodCwKKyAgICAgICAgcmlnaHREZWxpbWl0ZXIsIHJsZW5ndGggLSAocmlnaHREZWxpbWl0ZXIgLSByb2Zmc2V0KSwKKyAgICAgICAgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICAvLyBOb3cgY29tcGFyZSBtaWRkbGVzZWN0aW9uIG9mIHJvdy4KKyAgICByZXN1bHQgPSBCeXRlcy5jb21wYXJlVG8obGVmdCwgbGVmdERlbGltaXRlciwKKyAgICAgIGxlZnRGYXJEZWxpbWl0ZXIgLSBsZWZ0RGVsaW1pdGVyLCByaWdodCwgcmlnaHREZWxpbWl0ZXIsCisgICAgICByaWdodEZhckRlbGltaXRlciAtIHJpZ2h0RGVsaW1pdGVyKTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIC8vIENvbXBhcmUgbGFzdCBwYXJ0IG9mIHJvdywgdGhlIHJvd2lkLgorICAgIGxlZnRGYXJEZWxpbWl0ZXIrKzsKKyAgICByaWdodEZhckRlbGltaXRlcisrOworICAgIHJlc3VsdCA9IGNvbXBhcmVSb3dpZChsZWZ0LCBsZWZ0RmFyRGVsaW1pdGVyLAorICAgICAgbGxlbmd0aCAtIChsZWZ0RmFyRGVsaW1pdGVyIC0gbG9mZnNldCksCisgICAgICByaWdodCwgcmlnaHRGYXJEZWxpbWl0ZXIsIHJsZW5ndGggLSAocmlnaHRGYXJEZWxpbWl0ZXIgLSByb2Zmc2V0KSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGludCBjb21wYXJlUm93aWQoYnl0ZVtdIGxlZnQsIGludCBsb2Zmc2V0LCBpbnQgbGxlbmd0aCwKKyAgICAgIGJ5dGVbXSByaWdodCwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLCByaWdodCwgcm9mZnNldCwgcmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogUmF3Q29tcGFyYXRvciBmb3IgcGxhaW4gLS0gaS5lLiBub24tY2F0YWxvZyB0YWJsZSBrZXlzIHN1Y2ggYXMgCisgICAqIC1ST09ULSBhbmQgLk1FVEEuIC0tIEhTdG9yZUtleXMuICBDb21wYXJlcyBhdCBieXRlIGxldmVsLiAgS25vd3MgaG93IHRvCisgICAqIGhhbmRsZSB0aGUgdmludHMgdGhhdCBpbnRyb2R1Y2Ugcm93IGFuZCBjb2x1bW5zIGluIHRoZSBIU0sgYnl0ZSBhcnJheQorICAgKiByZXByZXNlbnRhdGlvbi4gQWRkcworICAgKiB7QGxpbmsgI2NvbXBhcmVSb3dzKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50LCBpbnQpfSB0bworICAgKiB7QGxpbmsgUmF3Q29tcGFyYXRvcn0KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU3RvcmVLZXlDb21wYXJhdG9yIGltcGxlbWVudHMgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiB7CisgICAgcHVibGljIFN0b3JlS2V5Q29tcGFyYXRvcigpIHsKKyAgICAgIHN1cGVyKCk7CisgICAgfQorCisgICAgcHVibGljIGludCBjb21wYXJlKGZpbmFsIGJ5dGVbXSBiMSwgZmluYWwgYnl0ZVtdIGIyKSB7CisgICAgICByZXR1cm4gY29tcGFyZShiMSwgMCwgYjEubGVuZ3RoLCBiMiwgMCwgYjIubGVuZ3RoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmUoZmluYWwgYnl0ZSBbXSBiMSwgaW50IG8xLCBpbnQgbDEsCisgICAgICAgIGZpbmFsIGJ5dGUgW10gYjIsIGludCBvMiwgaW50IGwyKSB7CisgICAgICAvLyBCZWxvdyBpcyBieXRlIGNvbXBhcmUgd2l0aG91dCBjcmVhdGluZyBuZXcgb2JqZWN0cy4gIEl0cyBhd2t3YXJkIGJ1dAorICAgICAgLy8gc2VlbXMgbm8gd2F5IGFyb3VuZCBnZXR0aW5nIHZpbnQgd2lkdGgsIHZhbHVlLCBhbmQgY29tcGFyZSByZXN1bHQgYW55CisgICAgICAvLyBvdGhlciB3YXkuIFRoZSBwYXNzZWQgYnl0ZSBhcnJheXMsIGIxIGFuZCBiMiwgaGF2ZSBhIHZpbnQsIHJvdywgdmludCwKKyAgICAgIC8vIGNvbHVtbiwgdGltZXN0YW1wIGluIHRoZW0uICBUaGUgYnl0ZSBhcnJheSB3YXMgd3JpdHRlbiBieSB0aGUKKyAgICAgIC8vICN3cml0ZShEYXRhT3V0cHV0U3RyZWFtKSBtZXRob2QgYWJvdmUuIFNlZSBpdCB0byBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUKKyAgICAgIC8vIGJlbG93LgorCisgICAgICAvLyBDYWxjdWxhdGUgdmludCBhbmQgdmludCB3aWR0aCBmb3Igcm93cyBpbiBiMSBhbmQgYjIuCisgICAgICBieXRlIGZpcnN0Qnl0ZTEgPSBiMVtvMV07CisgICAgICBpbnQgdmludDEgPSBmaXJzdEJ5dGUxOworICAgICAgaW50IHZpbnRXaWR0aDEgPSBXcml0YWJsZVV0aWxzLmRlY29kZVZJbnRTaXplKGZpcnN0Qnl0ZTEpOworICAgICAgaWYgKHZpbnRXaWR0aDEgIT0gMSkgeworICAgICAgICB2aW50MSA9IGdldEJpZ1ZpbnQodmludFdpZHRoMSwgZmlyc3RCeXRlMSwgYjEsIG8xKTsKKyAgICAgIH0KKyAgICAgIGJ5dGUgZmlyc3RCeXRlMiA9IGIyW28yXTsKKyAgICAgIGludCB2aW50MiA9IGZpcnN0Qnl0ZTI7CisgICAgICBpbnQgdmludFdpZHRoMiA9IFdyaXRhYmxlVXRpbHMuZGVjb2RlVkludFNpemUoZmlyc3RCeXRlMik7CisgICAgICBpZiAodmludFdpZHRoMiAhPSAxKSB7CisgICAgICAgIHZpbnQyID0gZ2V0QmlnVmludCh2aW50V2lkdGgyLCBmaXJzdEJ5dGUyLCBiMiwgbzIpOworICAgICAgfQorICAgICAgLy8gQ29tcGFyZSB0aGUgcm93cy4KKyAgICAgIGludCByZXN1bHQgPSBjb21wYXJlUm93cyhiMSwgbzEgKyB2aW50V2lkdGgxLCB2aW50MSwKKyAgICAgICAgICBiMiwgbzIgKyB2aW50V2lkdGgyLCB2aW50Mik7CisgICAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKworICAgICAgLy8gVXBkYXRlIG9mZnNldHMgYW5kIGxlbmd0aHMgc28gd2UgYXJlIGFsaWduZWQgb24gY29sdW1ucy4KKyAgICAgIGludCBkaWZmMSA9IHZpbnRXaWR0aDEgKyB2aW50MTsKKyAgICAgIG8xICs9IGRpZmYxOworICAgICAgbDEgLT0gZGlmZjE7CisgICAgICBpbnQgZGlmZjIgPSB2aW50V2lkdGgyICsgdmludDI7CisgICAgICBvMiArPSBkaWZmMjsKKyAgICAgIGwyIC09IGRpZmYyOworICAgICAgLy8gQ2FsY3VsYXRlIHZpbnQgYW5kIHZpbnQgd2lkdGggZm9yIGNvbHVtbnMgaW4gYjEgYW5kIGIyLgorICAgICAgZmlyc3RCeXRlMSA9IGIxW28xXTsKKyAgICAgIHZpbnQxID0gZmlyc3RCeXRlMTsKKyAgICAgIHZpbnRXaWR0aDEgPSBXcml0YWJsZVV0aWxzLmRlY29kZVZJbnRTaXplKGZpcnN0Qnl0ZTEpOworICAgICAgaWYgKHZpbnRXaWR0aDEgIT0gMSkgeworICAgICAgICB2aW50MSA9IGdldEJpZ1ZpbnQodmludFdpZHRoMSwgZmlyc3RCeXRlMSwgYjEsIG8xKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0Qnl0ZTIgPSBiMltvMl07CisgICAgICB2aW50MiA9IGZpcnN0Qnl0ZTI7CisgICAgICB2aW50V2lkdGgyID0gV3JpdGFibGVVdGlscy5kZWNvZGVWSW50U2l6ZShmaXJzdEJ5dGUyKTsKKyAgICAgIGlmICh2aW50V2lkdGgyICE9IDEpIHsKKyAgICAgICAgdmludDIgPSBnZXRCaWdWaW50KHZpbnRXaWR0aDIsIGZpcnN0Qnl0ZTIsIGIyLCBvMik7CisgICAgICB9CisgICAgICAvLyBDb21wYXJlIGNvbHVtbnMuCisgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIkNPTCA8IiArIEJ5dGVzLnRvU3RyaW5nKGIxLCBvMSArIHZpbnRXaWR0aDEsIHZpbnQxKSArCisgICAgICAvLyAgIj4gPCIgKyBCeXRlcy50b1N0cmluZyhiMiwgbzIgKyB2aW50V2lkdGgyLCB2aW50MikgKyAiPiIpOworICAgICAgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKGIxLCBvMSArIHZpbnRXaWR0aDEsIHZpbnQxLAorICAgICAgICBiMiwgbzIgKyB2aW50V2lkdGgyLCB2aW50Mik7CisgICAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKworICAgICAgLy8gVXBkYXRlIG9mZnNldHMgYW5kIGxlbmd0aHMuCisgICAgICBkaWZmMSA9IHZpbnRXaWR0aDEgKyB2aW50MTsKKyAgICAgIG8xICs9IGRpZmYxOworICAgICAgbDEgLT0gZGlmZjE7CisgICAgICBkaWZmMiA9IHZpbnRXaWR0aDIgKyB2aW50MjsKKyAgICAgIG8yICs9IGRpZmYyOworICAgICAgbDIgLT0gZGlmZjI7CisgICAgICAvLyBUaGUgYmVsb3cgb2xkZXIgdGltZXN0YW1wcyBzb3J0aW5nIGFoZWFkIG9mIG5ld2VyIHRpbWVzdGFtcHMgbG9va3MKKyAgICAgIC8vIHdyb25nIGJ1dCBpdCBpcyBpbnRlbnRpb25hbC4gVGhpcyB3YXksIG5ld2VyIHRpbWVzdGFtcHMgYXJlIGZpcnN0CisgICAgICAvLyBmb3VuZCB3aGVuIHdlIGl0ZXJhdGUgb3ZlciBhIG1lbWNhY2hlIGFuZCBuZXdlciB2ZXJzaW9ucyBhcmUgdGhlCisgICAgICAvLyBmaXJzdCB3ZSB0cmlwIG92ZXIgd2hlbiByZWFkaW5nIGZyb20gYSBzdG9yZSBmaWxlLgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsMTsgaSsrKSB7CisgICAgICAgIGludCBsZWZ0YiA9IGIxW28xICsgaV0gJiAweGZmOworICAgICAgICBpbnQgcmlnaHRiID0gYjJbbzIgKyBpXSAmIDB4ZmY7CisgICAgICAgIGlmIChsZWZ0YiA8IHJpZ2h0YikgeworICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9IGVsc2UgaWYgKGxlZnRiID4gcmlnaHRiKSB7CisgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqIEByZXR1cm4gUmVzdWx0IGNvbXBhcmluZyByb3dzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoZmluYWwgYnl0ZSBbXSBsZWZ0LCBmaW5hbCBieXRlIFtdIHJpZ2h0KSB7CisgICAgICByZXR1cm4gY29tcGFyZVJvd3MobGVmdCwgMCwgbGVmdC5sZW5ndGgsIHJpZ2h0LCAwLCByaWdodC5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBsZWZ0CisgICAgICogQHBhcmFtIGxvZmZzZXQKKyAgICAgKiBAcGFyYW0gbGxlbmd0aAorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqIEBwYXJhbSByb2Zmc2V0CisgICAgICogQHBhcmFtIHJsZW5ndGgKKyAgICAgKiBAcmV0dXJuIFJlc3VsdCBjb21wYXJpbmcgcm93cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVSb3dzKGZpbmFsIGJ5dGUgW10gbGVmdCwgZmluYWwgaW50IGxvZmZzZXQsCisgICAgICAgIGZpbmFsIGludCBsbGVuZ3RoLCBmaW5hbCBieXRlIFtdIHJpZ2h0LCBmaW5hbCBpbnQgcm9mZnNldCwgZmluYWwgaW50IHJsZW5ndGgpIHsKKyAgICAgIHJldHVybiBCeXRlcy5jb21wYXJlVG8obGVmdCwgbG9mZnNldCwgbGxlbmd0aCwgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gaHJpCisgICAqIEByZXR1cm4gQ29tcGF0aWJsZSBjb21wYXJhdG9yCisgICAqLworICBwdWJsaWMgc3RhdGljIFdyaXRhYmxlQ29tcGFyYXRvciBnZXRXcml0YWJsZUNvbXBhcmF0b3IoZmluYWwgSFJlZ2lvbkluZm8gaHJpKSB7CisgICAgcmV0dXJuIGhyaS5pc1Jvb3RSZWdpb24oKT8KKyAgICAgICAgbmV3IEhTdG9yZUtleS5IU3RvcmVLZXlSb290Q29tcGFyYXRvcigpOiBocmkuaXNNZXRhUmVnaW9uKCk/CisgICAgICAgICAgbmV3IEhTdG9yZUtleS5IU3RvcmVLZXlNZXRhQ29tcGFyYXRvcigpOgorICAgICAgICAgICAgbmV3IEhTdG9yZUtleS5IU3RvcmVLZXlDb21wYXJhdG9yKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGhyaQorICAgKiBAcmV0dXJuIENvbXBhdGlibGUgcmF3IGNvbXBhcmF0b3IKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RvcmVLZXlDb21wYXJhdG9yIGdldFJhd0NvbXBhcmF0b3IoZmluYWwgSFJlZ2lvbkluZm8gaHJpKSB7CisgICAgcmV0dXJuIGhyaS5pc1Jvb3RSZWdpb24oKSA/IFJPT1RfQ09NUEFSQVRPUiA6CisgICAgICBocmkuaXNNZXRhUmVnaW9uKCkgPyBNRVRBX0NPTVBBUkFUT1IgOiBQTEFJTl9DT01QQVJBVE9SOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZW5hbWUKKyAgICogQHJldHVybiBDb21wYXRpYmxlIHJhdyBjb21wYXJhdG9yCisgICAqLworICBwdWJsaWMgc3RhdGljIEhTdG9yZUtleS5TdG9yZUtleUNvbXBhcmF0b3IgZ2V0Q29tcGFyYXRvcihmaW5hbCBieXRlIFtdIHRhYmxlbmFtZSkgeworICAgIHJldHVybiBCeXRlcy5lcXVhbHMoSFRhYmxlRGVzY3JpcHRvci5ST09UX1RBQkxFREVTQy5nZXROYW1lKCksIHRhYmxlbmFtZSk/CisgICAgICBST09UX0NPTVBBUkFUT1I6CisgICAgICAoQnl0ZXMuZXF1YWxzKEhUYWJsZURlc2NyaXB0b3IuTUVUQV9UQUJMRURFU0MuZ2V0TmFtZSgpLHRhYmxlbmFtZSkpPworICAgICAgTUVUQV9DT01QQVJBVE9SOiBQTEFJTl9DT01QQVJBVE9SOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFRhYmxlRGVzY3JpcHRvci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSFRhYmxlRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlYzJiYjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IVGFibGVEZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSw3MTAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZC5JbmRleFNwZWNpZmljYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5Db21wcmVzc2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVNlcmlhbGl6YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKKworaW1wb3J0IGFnaWxlanNvbi5UT0pTT047CisKKy8qKgorICogSFRhYmxlRGVzY3JpcHRvciBjb250YWlucyB0aGUgbmFtZSBvZiBhbiBIVGFibGUsIGFuZCBpdHMKKyAqIGNvbHVtbiBmYW1pbGllcy4KKyAqLworcHVibGljIGNsYXNzIEhUYWJsZURlc2NyaXB0b3IgaW1wbGVtZW50cyBXcml0YWJsZUNvbXBhcmFibGU8SFRhYmxlRGVzY3JpcHRvcj4sIElTZXJpYWxpemFibGUgeworCisgIC8vIENoYW5nZXMgcHJpb3IgdG8gdmVyc2lvbiAzIHdlcmUgbm90IHJlY29yZGVkIGhlcmUuCisgIC8vIFZlcnNpb24gMyBhZGRzIG1ldGFkYXRhIGFzIGEgbWFwIHdoZXJlIGtleXMgYW5kIHZhbHVlcyBhcmUgYnl0ZVtdLgorICAvLyBWZXJzaW9uIDQgYWRkcyBpbmRleGVzCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBUQUJMRV9ERVNDUklQVE9SX1ZFUlNJT04gPSA0OworCisgIHByaXZhdGUgYnl0ZSBbXSBuYW1lID0gSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZOworICBwcml2YXRlIFN0cmluZyBuYW1lQXNTdHJpbmcgPSAiIjsKKworICAvLyBUYWJsZSBtZXRhZGF0YQorICBwcm90ZWN0ZWQgTWFwPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGU+IHZhbHVlcyA9CisgICAgbmV3IEhhc2hNYXA8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4oKTsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGQU1JTElFUyA9ICJGQU1JTElFUyI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBGQU1JTElFU19LRVkgPQorICAgIG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKEJ5dGVzLnRvQnl0ZXMoRkFNSUxJRVMpKTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFYX0ZJTEVTSVpFID0gIk1BWF9GSUxFU0laRSI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBNQVhfRklMRVNJWkVfS0VZID0KKyAgICBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKE1BWF9GSUxFU0laRSkpOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRUFET05MWSA9ICJSRUFET05MWSI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBSRUFET05MWV9LRVkgPQorICAgIG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKEJ5dGVzLnRvQnl0ZXMoUkVBRE9OTFkpKTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVNQ0FDSEVfRkxVU0hTSVpFID0gIk1FTUNBQ0hFX0ZMVVNIU0laRSI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBNRU1DQUNIRV9GTFVTSFNJWkVfS0VZID0KKyAgICBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKE1FTUNBQ0hFX0ZMVVNIU0laRSkpOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJU19ST09UID0gIklTX1JPT1QiOworICBwdWJsaWMgc3RhdGljIGZpbmFsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgSVNfUk9PVF9LRVkgPQorICAgIG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKEJ5dGVzLnRvQnl0ZXMoSVNfUk9PVCkpOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJU19NRVRBID0gIklTX01FVEEiOworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBJU19NRVRBX0tFWSA9CisgICAgbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoQnl0ZXMudG9CeXRlcyhJU19NRVRBKSk7CisKKworICAvLyBUaGUgYmVsb3cgYXJlIHVnbHkgYnV0IGJldHRlciB0aGFuIGNyZWF0aW5nIHRoZW0gZWFjaCB0aW1lIHRpbGwgd2UKKyAgLy8gcmVwbGFjZSBib29sZWFucyBiZWluZyBzYXZlZCBhcyBTdHJpbmdzIHdpdGggcGxhaW4gYm9vbGVhbnMuICBOZWVkIGEKKyAgLy8gbWlncmF0aW9uIHNjcmlwdCB0byBkbyB0aGlzLiAgVE9ETy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBGQUxTRSA9CisgICAgbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoQnl0ZXMudG9CeXRlcyhCb29sZWFuLkZBTFNFLnRvU3RyaW5nKCkpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBUUlVFID0KKyAgICBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKEJvb2xlYW4uVFJVRS50b1N0cmluZygpKSk7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIERFRkFVTFRfSU5fTUVNT1JZID0gZmFsc2U7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBib29sZWFuIERFRkFVTFRfUkVBRE9OTFkgPSBmYWxzZTsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01FTUNBQ0hFX0ZMVVNIX1NJWkUgPSAxMDI0KjEwMjQqNjQ7CisgIAorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01BWF9GSUxFU0laRSA9IDEwMjQqMTAyNCoyNTY7CisgICAgCisgIHByaXZhdGUgdm9sYXRpbGUgQm9vbGVhbiBtZXRhID0gbnVsbDsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBCb29sZWFuIHJvb3QgPSBudWxsOworCisgIC8vIEtleSBpcyBoYXNoIG9mIHRoZSBmYW1pbHkgbmFtZS4KKyAgcHJpdmF0ZSBmaW5hbCBNYXA8Ynl0ZSBbXSwgSENvbHVtbkRlc2NyaXB0b3I+IGZhbWlsaWVzID0KKyAgICBuZXcgVHJlZU1hcDxieXRlIFtdLCBIQ29sdW1uRGVzY3JpcHRvcj4oS2V5VmFsdWUuRkFNSUxZX0NPTVBBUkFUT1IpOworCisgIC8vIEtleSBpcyBpbmRleElkCisgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgSW5kZXhTcGVjaWZpY2F0aW9uPiBpbmRleGVzID0KKyAgICBuZXcgSGFzaE1hcDxTdHJpbmcsIEluZGV4U3BlY2lmaWNhdGlvbj4oKTsKKyAgCisgIC8qKgorICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHVzZWQgaW50ZXJuYWxseSBjcmVhdGluZyB0YWJsZSBkZXNjcmlwdG9ycyBmb3IgCisgICAqIGNhdGFsb2cgdGFibGVzOiBlLmcuIC5NRVRBLiBhbmQgLVJPT1QtLgorICAgKi8KKyAgcHJvdGVjdGVkIEhUYWJsZURlc2NyaXB0b3IoZmluYWwgYnl0ZSBbXSBuYW1lLCBIQ29sdW1uRGVzY3JpcHRvcltdIGZhbWlsaWVzKSB7CisgICAgdGhpcy5uYW1lID0gbmFtZS5jbG9uZSgpOworICAgIHRoaXMubmFtZUFzU3RyaW5nID0gQnl0ZXMudG9TdHJpbmcodGhpcy5uYW1lKTsKKyAgICBzZXRNZXRhRmxhZ3MobmFtZSk7CisgICAgZm9yKEhDb2x1bW5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgOiBmYW1pbGllcykgeworICAgICAgdGhpcy5mYW1pbGllcy5wdXQoZGVzY3JpcHRvci5nZXROYW1lKCksIGRlc2NyaXB0b3IpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQcml2YXRlIGNvbnN0cnVjdG9yIHVzZWQgaW50ZXJuYWxseSBjcmVhdGluZyB0YWJsZSBkZXNjcmlwdG9ycyBmb3IgCisgICAqIGNhdGFsb2cgdGFibGVzOiBlLmcuIC5NRVRBLiBhbmQgLVJPT1QtLgorICAgKi8KKyAgcHJvdGVjdGVkIEhUYWJsZURlc2NyaXB0b3IoZmluYWwgYnl0ZSBbXSBuYW1lLCBIQ29sdW1uRGVzY3JpcHRvcltdIGZhbWlsaWVzLAorICAgICAgQ29sbGVjdGlvbjxJbmRleFNwZWNpZmljYXRpb24+IGluZGV4ZXMsCisgICAgICAgTWFwPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gdmFsdWVzKSB7CisgICAgdGhpcy5uYW1lID0gbmFtZS5jbG9uZSgpOworICAgIHRoaXMubmFtZUFzU3RyaW5nID0gQnl0ZXMudG9TdHJpbmcodGhpcy5uYW1lKTsKKyAgICBzZXRNZXRhRmxhZ3MobmFtZSk7CisgICAgZm9yKEhDb2x1bW5EZXNjcmlwdG9yIGRlc2NyaXB0b3IgOiBmYW1pbGllcykgeworICAgICAgdGhpcy5mYW1pbGllcy5wdXQoZGVzY3JpcHRvci5nZXROYW1lKCksIGRlc2NyaXB0b3IpOworICAgIH0KKyAgICBmb3IoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4IDogaW5kZXhlcykgeworICAgICAgdGhpcy5pbmRleGVzLnB1dChpbmRleC5nZXRJbmRleElkKCksIGluZGV4KTsKKyAgICB9CisgICAgZm9yIChNYXAuRW50cnk8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gZW50cnk6CisgICAgICAgIHZhbHVlcy5lbnRyeVNldCgpKSB7CisgICAgICB0aGlzLnZhbHVlcy5wdXQoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IG9iamVjdC4KKyAgICogRm9yIGRlc2VyaWFsaXppbmcgYW4gSFRhYmxlRGVzY3JpcHRvciBpbnN0YW5jZSBvbmx5LgorICAgKiBAc2VlICNIVGFibGVEZXNjcmlwdG9yKGJ5dGVbXSkKKyAgICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IuCisgICAqIEBwYXJhbSBuYW1lIFRhYmxlIG5hbWUuCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHBhc3NlZCBhIHRhYmxlIG5hbWUKKyAgICogdGhhdCBpcyBtYWRlIG9mIG90aGVyIHRoYW4gJ3dvcmQnIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmUgb3IgcGVyaW9kOiBpLmUuCisgICAqIDxjb2RlPlthLXpBLVpfMC05Ll0uCisgICAqIEBzZWUgPGEgaHJlZj0iSEFET09QLTE1ODEiPkhBRE9PUC0xNTgxIEhCQVNFOiBVbi1vcGVuYWJsZSB0YWJsZW5hbWUgYnVnPC9hPgorICAgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3IoZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICB0aGlzKEJ5dGVzLnRvQnl0ZXMobmFtZSkpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yLgorICAgKiBAcGFyYW0gbmFtZSBUYWJsZSBuYW1lLgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBwYXNzZWQgYSB0YWJsZSBuYW1lCisgICAqIHRoYXQgaXMgbWFkZSBvZiBvdGhlciB0aGFuICd3b3JkJyBjaGFyYWN0ZXJzLCB1bmRlcnNjb3JlIG9yIHBlcmlvZDogaS5lLgorICAgKiA8Y29kZT5bYS16QS1aXzAtOS0uXS4KKyAgICogQHNlZSA8YSBocmVmPSJIQURPT1AtMTU4MSI+SEFET09QLTE1ODEgSEJBU0U6IFVuLW9wZW5hYmxlIHRhYmxlbmFtZSBidWc8L2E+CisgICAqLworICBwdWJsaWMgSFRhYmxlRGVzY3JpcHRvcihmaW5hbCBieXRlIFtdIG5hbWUpIHsKKyAgICBzdXBlcigpOworICAgIHNldE1ldGFGbGFncyh0aGlzLm5hbWUpOworICAgIHRoaXMubmFtZSA9IHRoaXMuaXNNZXRhUmVnaW9uKCk/IG5hbWU6IGlzTGVnYWxUYWJsZU5hbWUobmFtZSk7CisgICAgdGhpcy5uYW1lQXNTdHJpbmcgPSBCeXRlcy50b1N0cmluZyh0aGlzLm5hbWUpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yLgorICAgKiA8cD4KKyAgICogTWFrZXMgYSBkZWVwIGNvcHkgb2YgdGhlIHN1cHBsaWVkIGRlc2NyaXB0b3IuIAorICAgKiBDYW4gbWFrZSBhIG1vZGlmaWFibGUgZGVzY3JpcHRvciBmcm9tIGFuIFVubW9kaWZ5YWJsZUhUYWJsZURlc2NyaXB0b3IuCisgICAqIEBwYXJhbSBkZXNjIFRoZSBkZXNjcmlwdG9yLgorICAgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3IoZmluYWwgSFRhYmxlRGVzY3JpcHRvciBkZXNjKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLm5hbWUgPSBkZXNjLm5hbWUuY2xvbmUoKTsKKyAgICB0aGlzLm5hbWVBc1N0cmluZyA9IEJ5dGVzLnRvU3RyaW5nKHRoaXMubmFtZSk7CisgICAgc2V0TWV0YUZsYWdzKHRoaXMubmFtZSk7CisgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBjOiBkZXNjLmZhbWlsaWVzLnZhbHVlcygpKSB7CisgICAgICB0aGlzLmZhbWlsaWVzLnB1dChjLmdldE5hbWUoKSwgbmV3IEhDb2x1bW5EZXNjcmlwdG9yKGMpKTsKKyAgICB9CisgICAgZm9yIChNYXAuRW50cnk8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gZToKKyAgICAgICAgZGVzYy52YWx1ZXMuZW50cnlTZXQoKSkgeworICAgICAgdGhpcy52YWx1ZXMucHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CisgICAgfQorICAgIHRoaXMuaW5kZXhlcy5wdXRBbGwoZGVzYy5pbmRleGVzKTsKKyAgfQorCisgIC8qCisgICAqIFNldCBtZXRhIGZsYWdzIG9uIHRoaXMgdGFibGUuCisgICAqIENhbGxlZCBieSBjb25zdHJ1Y3RvcnMuCisgICAqIEBwYXJhbSBuYW1lCisgICAqLworICBwcml2YXRlIHZvaWQgc2V0TWV0YUZsYWdzKGZpbmFsIGJ5dGUgW10gbmFtZSkgeworICAgIHNldFJvb3RSZWdpb24oQnl0ZXMuZXF1YWxzKG5hbWUsIEhDb25zdGFudHMuUk9PVF9UQUJMRV9OQU1FKSk7CisgICAgc2V0TWV0YVJlZ2lvbihpc1Jvb3RSZWdpb24oKSB8fAorICAgICAgQnl0ZXMuZXF1YWxzKG5hbWUsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKSk7CisgIH0KKworICAvKiogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgdGhlIHJvb3QgcmVnaW9uICovCisgIHB1YmxpYyBib29sZWFuIGlzUm9vdFJlZ2lvbigpIHsKKyAgICBpZiAodGhpcy5yb290ID09IG51bGwpIHsKKyAgICAgIHRoaXMucm9vdCA9IGlzU29tZXRoaW5nKElTX1JPT1RfS0VZLCBmYWxzZSk/IEJvb2xlYW4uVFJVRTogQm9vbGVhbi5GQUxTRTsKKyAgICB9CisgICAgcmV0dXJuIHRoaXMucm9vdC5ib29sZWFuVmFsdWUoKTsKKyAgfQorCisgIC8qKiBAcGFyYW0gaXNSb290IHRydWUgaWYgdGhpcyBpcyB0aGUgcm9vdCByZWdpb24gKi8KKyAgcHJvdGVjdGVkIHZvaWQgc2V0Um9vdFJlZ2lvbihib29sZWFuIGlzUm9vdCkgeworICAgIC8vIFRPRE86IE1ha2UgdGhlIHZhbHVlIGEgYm9vbGVhbiByYXRoZXIgdGhhbiBTdHJpbmcgb2YgYm9vbGVhbi4KKyAgICB2YWx1ZXMucHV0KElTX1JPT1RfS0VZLCBpc1Jvb3Q/IFRSVUU6IEZBTFNFKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIG1ldGEgcmVnaW9uIChwYXJ0IG9mIHRoZSByb290IG9yIG1ldGEgdGFibGVzKSAqLworICBwdWJsaWMgYm9vbGVhbiBpc01ldGFSZWdpb24oKSB7CisgICAgaWYgKHRoaXMubWV0YSA9PSBudWxsKSB7CisgICAgICB0aGlzLm1ldGEgPSBjYWxjdWxhdGVJc01ldGFSZWdpb24oKTsKKyAgICB9CisgICAgcmV0dXJuIHRoaXMubWV0YS5ib29sZWFuVmFsdWUoKTsKKyAgfQorCisgIHByaXZhdGUgc3luY2hyb25pemVkIEJvb2xlYW4gY2FsY3VsYXRlSXNNZXRhUmVnaW9uKCkgeworICAgIGJ5dGUgW10gdmFsdWUgPSBnZXRWYWx1ZShJU19NRVRBX0tFWSk7CisgICAgcmV0dXJuICh2YWx1ZSAhPSBudWxsKT8gQm9vbGVhbi52YWx1ZU9mKEJ5dGVzLnRvU3RyaW5nKHZhbHVlKSk6IEJvb2xlYW4uRkFMU0U7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gaXNTb21ldGhpbmcoZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXksCisgICAgICBmaW5hbCBib29sZWFuIHZhbHVlSWZOdWxsKSB7CisgICAgYnl0ZSBbXSB2YWx1ZSA9IGdldFZhbHVlKGtleSk7CisgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKKyAgICAgIC8vIFRPRE86IE1ha2UgdmFsdWUgYmUgYSBib29sZWFuIHJhdGhlciB0aGFuIFN0cmluZyBvZiBib29sZWFuLgorICAgICAgcmV0dXJuIEJvb2xlYW4udmFsdWVPZihCeXRlcy50b1N0cmluZyh2YWx1ZSkpLmJvb2xlYW5WYWx1ZSgpOworICAgIH0KKyAgICByZXR1cm4gdmFsdWVJZk51bGw7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGlzTWV0YSB0cnVlIGlmIHRoaXMgaXMgYSBtZXRhIHJlZ2lvbiAocGFydCBvZiB0aGUgcm9vdCBvciBtZXRhCisgICAqIHRhYmxlcykgKi8KKyAgcHJvdGVjdGVkIHZvaWQgc2V0TWV0YVJlZ2lvbihib29sZWFuIGlzTWV0YSkgeworICAgIHZhbHVlcy5wdXQoSVNfTUVUQV9LRVksIGlzTWV0YT8gVFJVRTogRkFMU0UpOworICB9CisKKyAgLyoqIEByZXR1cm4gdHJ1ZSBpZiB0YWJsZSBpcyB0aGUgbWV0YSB0YWJsZSAqLworICBwdWJsaWMgYm9vbGVhbiBpc01ldGFUYWJsZSgpIHsKKyAgICByZXR1cm4gaXNNZXRhUmVnaW9uKCkgJiYgIWlzUm9vdFJlZ2lvbigpOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIHBhc3NlZCBidWZmZXIgaXMgbGVnYWwgdXNlci1zcGFjZSB0YWJsZSBuYW1lLgorICAgKiBAcGFyYW0gYiBUYWJsZSBuYW1lLgorICAgKiBAcmV0dXJuIFJldHVybnMgcGFzc2VkIDxjb2RlPmI8L2NvZGU+IHBhcmFtCisgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gSWYgcGFzc2VkIDxjb2RlPmI8L2NvZGU+IGlzIG51bGwKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgcGFzc2VkIGEgdGFibGUgbmFtZQorICAgKiB0aGF0IGlzIG1hZGUgb2Ygb3RoZXIgdGhhbiAnd29yZCcgY2hhcmFjdGVycyBvciB1bmRlcnNjb3JlczogaS5lLgorICAgKiA8Y29kZT5bYS16QS1aXzAtOV0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gaXNMZWdhbFRhYmxlTmFtZShmaW5hbCBieXRlIFtdIGIpIHsKKyAgICBpZiAoYiA9PSBudWxsIHx8IGIubGVuZ3RoIDw9IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5hbWUgaXMgbnVsbCBvciBlbXB0eSIpOworICAgIH0KKyAgICBpZiAoYlswXSA9PSAnLicgfHwgYlswXSA9PSAnLScpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgZmlyc3QgY2hhcmFjdGVyIDwiICsgYlswXSArCisgICAgICAgICAgIj4uICIgKyAiVXNlci1zcGFjZSB0YWJsZSBuYW1lcyBjYW4gb25seSBzdGFydCB3aXRoICd3b3JkICIgKworICAgICAgICAgICJjaGFyYWN0ZXJzJzogaS5lLiBbYS16QS1aXzAtOV06ICIgKyBCeXRlcy50b1N0cmluZyhiKSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykgeworICAgICAgaWYgKENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoYltpXSkgfHwgYltpXSA9PSAnXycgfHwgYltpXSA9PSAnLScgfHwKKyAgICAgICAgICBiW2ldID09ICcuJykgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgY2hhcmFjdGVyIDwiICsgYltpXSArICI+LiAiICsKKyAgICAgICAgIlVzZXItc3BhY2UgdGFibGUgbmFtZXMgY2FuIG9ubHkgY29udGFpbiAnd29yZCBjaGFyYWN0ZXJzJzoiICsKKyAgICAgICAgImkuZS4gW2EtekEtWl8wLTktLl06ICIgKyBCeXRlcy50b1N0cmluZyhiKSk7CisgICAgfQorICAgIHJldHVybiBiOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXkgVGhlIGtleS4KKyAgICogQHJldHVybiBUaGUgdmFsdWUuCisgICAqLworICBwdWJsaWMgYnl0ZVtdIGdldFZhbHVlKGJ5dGVbXSBrZXkpIHsKKyAgICByZXR1cm4gZ2V0VmFsdWUobmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoa2V5KSk7CisgIH0KKyAgCisgIHByaXZhdGUgYnl0ZVtdIGdldFZhbHVlKGZpbmFsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUga2V5KSB7CisgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBpYncgPSB2YWx1ZXMuZ2V0KGtleSk7CisgICAgaWYgKGlidyA9PSBudWxsKQorICAgICAgcmV0dXJuIG51bGw7CisgICAgcmV0dXJuIGlidy5nZXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkuCisgICAqIEByZXR1cm4gVGhlIHZhbHVlIGFzIGEgc3RyaW5nLgorICAgKi8KKyAgcHVibGljIFN0cmluZyBnZXRWYWx1ZShTdHJpbmcga2V5KSB7CisgICAgYnl0ZVtdIHZhbHVlID0gZ2V0VmFsdWUoQnl0ZXMudG9CeXRlcyhrZXkpKTsKKyAgICBpZiAodmFsdWUgPT0gbnVsbCkKKyAgICAgIHJldHVybiBudWxsOworICAgIHJldHVybiBCeXRlcy50b1N0cmluZyh2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBBbGwgdmFsdWVzLgorICAgKi8KKyAgcHVibGljIE1hcDxJbW11dGFibGVCeXRlc1dyaXRhYmxlLEltbXV0YWJsZUJ5dGVzV3JpdGFibGU+IGdldFZhbHVlcygpIHsKKyAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcCh2YWx1ZXMpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXkgVGhlIGtleS4KKyAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGJ5dGVbXSBrZXksIGJ5dGVbXSB2YWx1ZSkgeworICAgIHNldFZhbHVlKG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKGtleSksIHZhbHVlKTsKKyAgfQorICAKKyAgLyoKKyAgICogQHBhcmFtIGtleSBUaGUga2V5LgorICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHNldFZhbHVlKGZpbmFsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUga2V5LAorICAgICAgZmluYWwgYnl0ZVtdIHZhbHVlKSB7CisgICAgdmFsdWVzLnB1dChrZXksIG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKHZhbHVlKSk7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkuCisgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUuCisgICAqLworICBwcml2YXRlIHZvaWQgc2V0VmFsdWUoZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXksCisgICAgICBmaW5hbCBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHZhbHVlKSB7CisgICAgdmFsdWVzLnB1dChrZXksIHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkuCisgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUuCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICBzZXRWYWx1ZShCeXRlcy50b0J5dGVzKGtleSksIEJ5dGVzLnRvQnl0ZXModmFsdWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsIGNvbHVtbnMgaW4gdGhlIHRhYmxlIHNob3VsZCBiZSBrZXB0IGluIHRoZSAKKyAgICogSFJlZ2lvblNlcnZlciBjYWNoZSBvbmx5CisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0luTWVtb3J5KCkgeworICAgIFN0cmluZyB2YWx1ZSA9IGdldFZhbHVlKEhDb25zdGFudHMuSU5fTUVNT1JZKTsKKyAgICBpZiAodmFsdWUgIT0gbnVsbCkKKyAgICAgIHJldHVybiBCb29sZWFuLnZhbHVlT2YodmFsdWUpLmJvb2xlYW5WYWx1ZSgpOworICAgIHJldHVybiBERUZBVUxUX0lOX01FTU9SWTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gaW5NZW1vcnkgVHJ1ZSBpZiBhbGwgb2YgdGhlIGNvbHVtbnMgaW4gdGhlIHRhYmxlIHNob3VsZCBiZSBrZXB0IGluCisgICAqIHRoZSBIUmVnaW9uU2VydmVyIGNhY2hlIG9ubHkuCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRJbk1lbW9yeShib29sZWFuIGluTWVtb3J5KSB7CisgICAgc2V0VmFsdWUoSENvbnN0YW50cy5JTl9NRU1PUlksIEJvb2xlYW4udG9TdHJpbmcoaW5NZW1vcnkpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRydWUgaWYgYWxsIGNvbHVtbnMgaW4gdGhlIHRhYmxlIHNob3VsZCBiZSByZWFkIG9ubHkKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzUmVhZE9ubHkoKSB7CisgICAgcmV0dXJuIGlzU29tZXRoaW5nKFJFQURPTkxZX0tFWSwgREVGQVVMVF9SRUFET05MWSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJlYWRPbmx5IFRydWUgaWYgYWxsIG9mIHRoZSBjb2x1bW5zIGluIHRoZSB0YWJsZSBzaG91bGQgYmUgcmVhZAorICAgKiBvbmx5LgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0UmVhZE9ubHkoZmluYWwgYm9vbGVhbiByZWFkT25seSkgeworICAgIHNldFZhbHVlKFJFQURPTkxZX0tFWSwgcmVhZE9ubHk/IFRSVUU6IEZBTFNFKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIG5hbWUgb2YgdGFibGUgKi8KKyAgQFRPSlNPTgorICBwdWJsaWMgYnl0ZSBbXSBnZXROYW1lKCkgeworICAgIHJldHVybiBuYW1lOworICB9CisKKyAgLyoqIEByZXR1cm4gbmFtZSBvZiB0YWJsZSAqLworICBwdWJsaWMgU3RyaW5nIGdldE5hbWVBc1N0cmluZygpIHsKKyAgICByZXR1cm4gdGhpcy5uYW1lQXNTdHJpbmc7CisgIH0KKworICAvKiogQHJldHVybiBtYXggaHJlZ2lvbiBzaXplIGZvciB0YWJsZSAqLworICBwdWJsaWMgbG9uZyBnZXRNYXhGaWxlU2l6ZSgpIHsKKyAgICBieXRlIFtdIHZhbHVlID0gZ2V0VmFsdWUoTUFYX0ZJTEVTSVpFX0tFWSk7CisgICAgaWYgKHZhbHVlICE9IG51bGwpCisgICAgICByZXR1cm4gTG9uZy52YWx1ZU9mKEJ5dGVzLnRvU3RyaW5nKHZhbHVlKSkubG9uZ1ZhbHVlKCk7CisgICAgcmV0dXJuIEhDb25zdGFudHMuREVGQVVMVF9NQVhfRklMRV9TSVpFOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBtYXhGaWxlU2l6ZSBUaGUgbWF4aW11bSBmaWxlIHNpemUgdGhhdCBhIHN0b3JlIGZpbGUgY2FuIGdyb3cgdG8KKyAgICogYmVmb3JlIGEgc3BsaXQgaXMgdHJpZ2dlcmVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TWF4RmlsZVNpemUobG9uZyBtYXhGaWxlU2l6ZSkgeworICAgIHNldFZhbHVlKE1BWF9GSUxFU0laRV9LRVksIEJ5dGVzLnRvQnl0ZXMoTG9uZy50b1N0cmluZyhtYXhGaWxlU2l6ZSkpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIG1lbW9yeSBjYWNoZSBmbHVzaCBzaXplIGZvciBlYWNoIGhyZWdpb24KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0TWVtY2FjaGVGbHVzaFNpemUoKSB7CisgICAgYnl0ZSBbXSB2YWx1ZSA9IGdldFZhbHVlKE1FTUNBQ0hFX0ZMVVNIU0laRV9LRVkpOworICAgIGlmICh2YWx1ZSAhPSBudWxsKQorICAgICAgcmV0dXJuIEludGVnZXIudmFsdWVPZihCeXRlcy50b1N0cmluZyh2YWx1ZSkpLmludFZhbHVlKCk7CisgICAgcmV0dXJuIERFRkFVTFRfTUVNQ0FDSEVfRkxVU0hfU0laRTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBtZW1jYWNoZUZsdXNoU2l6ZSBtZW1vcnkgY2FjaGUgZmx1c2ggc2l6ZSBmb3IgZWFjaCBocmVnaW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRNZW1jYWNoZUZsdXNoU2l6ZShpbnQgbWVtY2FjaGVGbHVzaFNpemUpIHsKKyAgICBzZXRWYWx1ZShNRU1DQUNIRV9GTFVTSFNJWkVfS0VZLAorICAgICAgQnl0ZXMudG9CeXRlcyhJbnRlZ2VyLnRvU3RyaW5nKG1lbWNhY2hlRmx1c2hTaXplKSkpOworICB9CisgICAgCisgIHB1YmxpYyBDb2xsZWN0aW9uPEluZGV4U3BlY2lmaWNhdGlvbj4gZ2V0SW5kZXhlcygpIHsKKyAgICByZXR1cm4gaW5kZXhlcy52YWx1ZXMoKTsKKyAgfQorICAKKyAgcHVibGljIEluZGV4U3BlY2lmaWNhdGlvbiBnZXRJbmRleChTdHJpbmcgaW5kZXhJZCkgeworICAgIHJldHVybiBpbmRleGVzLmdldChpbmRleElkKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgYWRkSW5kZXgoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4KSB7CisgICAgaW5kZXhlcy5wdXQoaW5kZXguZ2V0SW5kZXhJZCgpLCBpbmRleCk7CisgIH0KKworICAvKioKKyAgICogQWRkcyBhIGNvbHVtbiBmYW1pbHkuCisgICAqIEBwYXJhbSBmYW1pbHkgSENvbHVtbkRlc2NyaXB0b3Igb2YgZmFtaWx5dG8gYWRkLgorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkRmFtaWx5KGZpbmFsIEhDb2x1bW5EZXNjcmlwdG9yIGZhbWlseSkgeworICAgIGlmIChmYW1pbHkuZ2V0TmFtZSgpID09IG51bGwgfHwgZmFtaWx5LmdldE5hbWUoKS5sZW5ndGggPD0gMCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJGYW1pbHkgbmFtZSBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eSIpOworICAgIH0KKyAgICB0aGlzLmZhbWlsaWVzLnB1dChmYW1pbHkuZ2V0TmFtZSgpLCBmYW1pbHkpOworICB9CisKKyAgLyoqCisgICAqIENoZWNrcyB0byBzZWUgaWYgdGhpcyB0YWJsZSBjb250YWlucyB0aGUgZ2l2ZW4gY29sdW1uIGZhbWlseQorICAgKiBAcGFyYW0gYyBGYW1pbHkgbmFtZSBvciBjb2x1bW4gbmFtZS4KKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSB0YWJsZSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGZhbWlseSBuYW1lCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBoYXNGYW1pbHkoZmluYWwgYnl0ZSBbXSBjKSB7CisgICAgcmV0dXJuIGZhbWlsaWVzLmNvbnRhaW5zS2V5KGMpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gTmFtZSBvZiB0aGlzIHRhYmxlIGFuZCB0aGVuIGEgbWFwIG9mIGFsbCBvZiB0aGUgY29sdW1uIGZhbWlseQorICAgKiBkZXNjcmlwdG9ycy4KKyAgICogQHNlZSAjZ2V0TmFtZUFzU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1ZmZlciBzID0gbmV3IFN0cmluZ0J1ZmZlcigpOworICAgIHMuYXBwZW5kKCd7Jyk7CisgICAgcy5hcHBlbmQoSENvbnN0YW50cy5OQU1FKTsKKyAgICBzLmFwcGVuZCgiID0+ICciKTsKKyAgICBzLmFwcGVuZChCeXRlcy50b1N0cmluZyhuYW1lKSk7CisgICAgcy5hcHBlbmQoIiciKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBJbW11dGFibGVCeXRlc1dyaXRhYmxlPiBlOgorICAgICAgICB2YWx1ZXMuZW50cnlTZXQoKSkgeworICAgICAgU3RyaW5nIGtleSA9IEJ5dGVzLnRvU3RyaW5nKGUuZ2V0S2V5KCkuZ2V0KCkpOworICAgICAgU3RyaW5nIHZhbHVlID0gQnl0ZXMudG9TdHJpbmcoZS5nZXRWYWx1ZSgpLmdldCgpKTsKKyAgICAgIGlmIChrZXkgPT0gbnVsbCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIFN0cmluZyB1cHBlckNhc2UgPSBrZXkudG9VcHBlckNhc2UoKTsKKyAgICAgIGlmICh1cHBlckNhc2UuZXF1YWxzKElTX1JPT1QpIHx8IHVwcGVyQ2FzZS5lcXVhbHMoSVNfTUVUQSkpIHsKKyAgICAgICAgLy8gU2tpcC4gRG9uJ3QgYm90aGVyIHByaW50aW5nIG91dCByZWFkLW9ubHkgdmFsdWVzIGlmIGZhbHNlLgorICAgICAgICBpZiAodmFsdWUudG9Mb3dlckNhc2UoKS5lcXVhbHMoQm9vbGVhbi5GQUxTRS50b1N0cmluZygpKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICB9CisgICAgICBzLmFwcGVuZCgiLCAiKTsKKyAgICAgIHMuYXBwZW5kKEJ5dGVzLnRvU3RyaW5nKGUuZ2V0S2V5KCkuZ2V0KCkpKTsKKyAgICAgIHMuYXBwZW5kKCIgPT4gJyIpOworICAgICAgcy5hcHBlbmQoQnl0ZXMudG9TdHJpbmcoZS5nZXRWYWx1ZSgpLmdldCgpKSk7CisgICAgICBzLmFwcGVuZCgiJyIpOworICAgIH0KKyAgICBzLmFwcGVuZCgiLCAiKTsKKyAgICBzLmFwcGVuZChGQU1JTElFUyk7CisgICAgcy5hcHBlbmQoIiA9PiAiKTsKKyAgICBzLmFwcGVuZChmYW1pbGllcy52YWx1ZXMoKSk7CisgICAgaWYgKCFpbmRleGVzLmlzRW1wdHkoKSkgeworICAgICAgLy8gRG9uJ3QgZW1pdCBpZiBlbXB0eS4gIEhhcyB0byBkbyB3LyB0cmFuc2FjdGlvbmFsIGhiYXNlLgorICAgICAgcy5hcHBlbmQoIiwgIik7CisgICAgICBzLmFwcGVuZCgiSU5ERVhFUyIpOworICAgICAgcy5hcHBlbmQoIiA9PiAiKTsKKyAgICAgIHMuYXBwZW5kKGluZGV4ZXMudmFsdWVzKCkpOworICAgIH0KKyAgICBzLmFwcGVuZCgnfScpOworICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgaWYgKHRoaXMgPT0gb2JqKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKG9iaiA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIEhUYWJsZURlc2NyaXB0b3IpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiBjb21wYXJlVG8oKEhUYWJsZURlc2NyaXB0b3Ipb2JqKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCNoYXNoQ29kZSgpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuaGFzaENvZGUodGhpcy5uYW1lKTsKKyAgICByZXN1bHQgXj0gQnl0ZS52YWx1ZU9mKFRBQkxFX0RFU0NSSVBUT1JfVkVSU0lPTikuaGFzaENvZGUoKTsKKyAgICBpZiAodGhpcy5mYW1pbGllcyAhPSBudWxsICYmIHRoaXMuZmFtaWxpZXMuc2l6ZSgpID4gMCkgeworICAgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBlOiB0aGlzLmZhbWlsaWVzLnZhbHVlcygpKSB7CisgICAgICAgIHJlc3VsdCBePSBlLmhhc2hDb2RlKCk7CisgICAgICB9CisgICAgfQorICAgIHJlc3VsdCBePSB2YWx1ZXMuaGFzaENvZGUoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gV3JpdGFibGUKKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgdmVyc2lvbiA9IGluLnJlYWRJbnQoKTsKKyAgICBpZiAodmVyc2lvbiA8IDMpCisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInZlcnNpb25zIDwgMyBhcmUgbm90IHN1cHBvcnRlZCAoYW5kIG5ldmVyIGV4aXN0ZWQhPykiKTsKKyAgICAvLyB2ZXJzaW9uIDMrCisgICAgbmFtZSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgIG5hbWVBc1N0cmluZyA9IEJ5dGVzLnRvU3RyaW5nKHRoaXMubmFtZSk7CisgICAgc2V0Um9vdFJlZ2lvbihpbi5yZWFkQm9vbGVhbigpKTsKKyAgICBzZXRNZXRhUmVnaW9uKGluLnJlYWRCb29sZWFuKCkpOworICAgIHZhbHVlcy5jbGVhcigpOworICAgIGludCBudW1WYWxzID0gaW4ucmVhZEludCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtVmFsczsgaSsrKSB7CisgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKCk7CisgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHZhbHVlID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICAgIGtleS5yZWFkRmllbGRzKGluKTsKKyAgICAgIHZhbHVlLnJlYWRGaWVsZHMoaW4pOworICAgICAgdmFsdWVzLnB1dChrZXksIHZhbHVlKTsKKyAgICB9CisgICAgZmFtaWxpZXMuY2xlYXIoKTsKKyAgICBpbnQgbnVtRmFtaWxpZXMgPSBpbi5yZWFkSW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1GYW1pbGllczsgaSsrKSB7CisgICAgICBIQ29sdW1uRGVzY3JpcHRvciBjID0gbmV3IEhDb2x1bW5EZXNjcmlwdG9yKCk7CisgICAgICBjLnJlYWRGaWVsZHMoaW4pOworICAgICAgZmFtaWxpZXMucHV0KGMuZ2V0TmFtZSgpLCBjKTsKKyAgICB9CisgICAgaW5kZXhlcy5jbGVhcigpOworICAgIGlmICh2ZXJzaW9uIDwgNCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpbnQgbnVtSW5kZXhlcyA9IGluLnJlYWRJbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUluZGV4ZXM7IGkrKykgeworICAgICAgSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4ID0gbmV3IEluZGV4U3BlY2lmaWNhdGlvbigpOworICAgICAgaW5kZXgucmVhZEZpZWxkcyhpbik7CisgICAgICBhZGRJbmRleChpbmRleCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisJb3V0LndyaXRlSW50KFRBQkxFX0RFU0NSSVBUT1JfVkVSU0lPTik7CisgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCBuYW1lKTsKKyAgICBvdXQud3JpdGVCb29sZWFuKGlzUm9vdFJlZ2lvbigpKTsKKyAgICBvdXQud3JpdGVCb29sZWFuKGlzTWV0YVJlZ2lvbigpKTsKKyAgICBvdXQud3JpdGVJbnQodmFsdWVzLnNpemUoKSk7CisgICAgZm9yIChNYXAuRW50cnk8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZT4gZToKKyAgICAgICAgdmFsdWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgIGUuZ2V0S2V5KCkud3JpdGUob3V0KTsKKyAgICAgIGUuZ2V0VmFsdWUoKS53cml0ZShvdXQpOworICAgIH0KKyAgICBvdXQud3JpdGVJbnQoZmFtaWxpZXMuc2l6ZSgpKTsKKyAgICBmb3IoSXRlcmF0b3I8SENvbHVtbkRlc2NyaXB0b3I+IGl0ID0gZmFtaWxpZXMudmFsdWVzKCkuaXRlcmF0b3IoKTsKKyAgICAgICAgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yIGZhbWlseSA9IGl0Lm5leHQoKTsKKyAgICAgIGZhbWlseS53cml0ZShvdXQpOworICAgIH0KKyAgICBvdXQud3JpdGVJbnQoaW5kZXhlcy5zaXplKCkpOworICAgIGZvcihJbmRleFNwZWNpZmljYXRpb24gaW5kZXggOiBpbmRleGVzLnZhbHVlcygpKSB7CisgICAgICBpbmRleC53cml0ZShvdXQpOworICAgIH0KKyAgfQorCisgIC8vIENvbXBhcmFibGUKKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhmaW5hbCBIVGFibGVEZXNjcmlwdG9yIG90aGVyKSB7CisgICAgaW50IHJlc3VsdCA9IEJ5dGVzLmNvbXBhcmVUbyh0aGlzLm5hbWUsIG90aGVyLm5hbWUpOworICAgIGlmIChyZXN1bHQgPT0gMCkgeworICAgICAgcmVzdWx0ID0gZmFtaWxpZXMuc2l6ZSgpIC0gb3RoZXIuZmFtaWxpZXMuc2l6ZSgpOworICAgIH0KKyAgICBpZiAocmVzdWx0ID09IDAgJiYgZmFtaWxpZXMuc2l6ZSgpICE9IG90aGVyLmZhbWlsaWVzLnNpemUoKSkgeworICAgICAgcmVzdWx0ID0gSW50ZWdlci52YWx1ZU9mKGZhbWlsaWVzLnNpemUoKSkuY29tcGFyZVRvKAorICAgICAgICAgIEludGVnZXIudmFsdWVPZihvdGhlci5mYW1pbGllcy5zaXplKCkpKTsKKyAgICB9CisgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICBmb3IgKEl0ZXJhdG9yPEhDb2x1bW5EZXNjcmlwdG9yPiBpdCA9IGZhbWlsaWVzLnZhbHVlcygpLml0ZXJhdG9yKCksCisgICAgICAgICAgaXQyID0gb3RoZXIuZmFtaWxpZXMudmFsdWVzKCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgcmVzdWx0ID0gaXQubmV4dCgpLmNvbXBhcmVUbyhpdDIubmV4dCgpKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAvLyBwdW50IG9uIGNvbXBhcmlzb24gZm9yIG9yZGVyaW5nLCBqdXN0IGNhbGN1bGF0ZSBkaWZmZXJlbmNlCisgICAgICByZXN1bHQgPSB0aGlzLnZhbHVlcy5oYXNoQ29kZSgpIC0gb3RoZXIudmFsdWVzLmhhc2hDb2RlKCk7CisgICAgICBpZiAocmVzdWx0IDwgMCkKKyAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICBlbHNlIGlmIChyZXN1bHQgPiAwKQorICAgICAgICByZXN1bHQgPSAxOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gSW1tdXRhYmxlIHNvcnRlZCBtYXAgb2YgZmFtaWxpZXMuCisgICAqLworICBwdWJsaWMgQ29sbGVjdGlvbjxIQ29sdW1uRGVzY3JpcHRvcj4gZ2V0RmFtaWxpZXMoKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUNvbGxlY3Rpb24odGhpcy5mYW1pbGllcy52YWx1ZXMoKSk7CisgIH0KKyAgCisgIEBUT0pTT04oZmllbGROYW1lID0gImNvbHVtbnMiKQorICBwdWJsaWMgSENvbHVtbkRlc2NyaXB0b3JbXSBnZXRDb2x1bW5GYW1pbGllcygpIHsKKyAgICByZXR1cm4gZ2V0RmFtaWxpZXMoKS50b0FycmF5KG5ldyBIQ29sdW1uRGVzY3JpcHRvclswXSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcmV0dXJuIENvbHVtbiBkZXNjcmlwdG9yIGZvciB0aGUgcGFzc2VkIGZhbWlseSBuYW1lIG9yIHRoZSBmYW1pbHkgb24KKyAgICogcGFzc2VkIGluIGNvbHVtbi4KKyAgICovCisgIHB1YmxpYyBIQ29sdW1uRGVzY3JpcHRvciBnZXRGYW1pbHkoZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICByZXR1cm4gdGhpcy5mYW1pbGllcy5nZXQoY29sdW1uKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEByZXR1cm4gQ29sdW1uIGRlc2NyaXB0b3IgZm9yIHRoZSBwYXNzZWQgZmFtaWx5IG5hbWUgb3IgdGhlIGZhbWlseSBvbgorICAgKiBwYXNzZWQgaW4gY29sdW1uLgorICAgKi8KKyAgcHVibGljIEhDb2x1bW5EZXNjcmlwdG9yIHJlbW92ZUZhbWlseShmaW5hbCBieXRlIFtdIGNvbHVtbikgeworICAgIHJldHVybiB0aGlzLmZhbWlsaWVzLnJlbW92ZShjb2x1bW4pOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByb290ZGlyIHF1YWxpZmllZCBwYXRoIG9mIEhCYXNlIHJvb3QgZGlyZWN0b3J5CisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcmV0dXJuIHBhdGggZm9yIHRhYmxlCisgICAqLworICBwdWJsaWMgc3RhdGljIFBhdGggZ2V0VGFibGVEaXIoUGF0aCByb290ZGlyLCBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSkgeworICAgIHJldHVybiBuZXcgUGF0aChyb290ZGlyLCBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgfQorCisgIC8qKiBUYWJsZSBkZXNjcmlwdG9yIGZvciA8Y29yZT4tUk9PVC08L2NvZGU+IGNhdGFsb2cgdGFibGUgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBIVGFibGVEZXNjcmlwdG9yIFJPT1RfVEFCTEVERVNDID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoCisgICAgICBIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSwKKyAgICAgIG5ldyBIQ29sdW1uRGVzY3JpcHRvcltdIHsgbmV3IEhDb2x1bW5EZXNjcmlwdG9yKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSwKKyAgICAgICAgICAxMCwgIC8vIFRlbiBpcyBhcmJpdHJhcnkgbnVtYmVyLiAgS2VlcCB2ZXJzaW9ucyB0byBoZWxwIGRlYnVnZ2dpbmcuCisgICAgICAgICAgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUuZ2V0TmFtZSgpLCBmYWxzZSwgdHJ1ZSwgOCAqIDEwMjQsCisgICAgICAgICAgSW50ZWdlci5NQVhfVkFMVUUsIEhDb25zdGFudHMuRk9SRVZFUiwgZmFsc2UpIH0pOworICAKKyAgLyoqIFRhYmxlIGRlc2NyaXB0b3IgZm9yIDxjb2RlPi5NRVRBLjwvY29kZT4gY2F0YWxvZyB0YWJsZSAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIEhUYWJsZURlc2NyaXB0b3IgTUVUQV9UQUJMRURFU0MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcigKKyAgICAgIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FLCBuZXcgSENvbHVtbkRlc2NyaXB0b3JbXSB7CisgICAgICAgICAgbmV3IEhDb2x1bW5EZXNjcmlwdG9yKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSwKKyAgICAgICAgICAgIDEwLCAvLyBUZW4gaXMgYXJiaXRyYXJ5IG51bWJlci4gIEtlZXAgdmVyc2lvbnMgdG8gaGVscCBkZWJ1Z2dnaW5nLgorICAgICAgICAgICAgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUuZ2V0TmFtZSgpLCBmYWxzZSwgdHJ1ZSwgOCAqIDEwMjQsCisgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgSENvbnN0YW50cy5GT1JFVkVSLCBmYWxzZSksCisgICAgICAgICAgbmV3IEhDb2x1bW5EZXNjcmlwdG9yKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9ISVNUT1JJQU4sCisgICAgICAgICAgICBIQ29uc3RhbnRzLkFMTF9WRVJTSU9OUywgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUuZ2V0TmFtZSgpLAorICAgICAgICAgICAgZmFsc2UsIGZhbHNlLCAgOCAqIDEwMjQsCisgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgSENvbnN0YW50cy5XRUVLX0lOX1NFQ09ORFMsIGZhbHNlKX0pOworCisgIC8qIChub24tSmF2YWRvYykKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnhtbC5JT3V0cHV0WE1MI3RvWE1MKCkKKyAgICovCisgIHB1YmxpYyB2b2lkIHJlc3RTZXJpYWxpemUoSVJlc3RTZXJpYWxpemVyIHNlcmlhbGl6ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHNlcmlhbGl6ZXIuc2VyaWFsaXplVGFibGVEZXNjcmlwdG9yKHRoaXMpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvS2V5VmFsdWUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0tleVZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdiNDQyNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0tleVZhbHVlLmphdmEKQEAgLTAsMCArMSwxNDQ4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGVhcFNpemU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uUmF3Q29tcGFyYXRvcjsKKworLyoqCisgKiBBbiBIQmFzZSBLZXkvVmFsdWUuICBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgaW1tdXRhYmxlLiAgVGhleSBhcmUgbm90CisgKiBjb21wYXJhYmxlIGJ1dCBDb21wYXJhdG9ycyBhcmUgcHJvdmlkZWQgIENvbXBhcmF0b3JzIGNoYW5nZSB3aXRoIGNvbnRleHQsCisgKiB3aGV0aGVyIHVzZXIgdGFibGUgb3IgYSBjYXRhbG9nIHRhYmxlIGNvbXBhcmlzb24gY29udGV4dC4gIEl0cworICogaW1wb3J0YW50IHRoYXQgeW91IHVzZSB0aGUgYXBwcm9wcmlhdGUgY29tcGFyYXRvciBjb21wYXJpbmcgcm93cyBpbgorICogcGFydGljdWxhci4gIFRoZXJlIGFyZSBDb21wYXJhdG9ycyBmb3IgS2V5VmFsdWUgaW5zdGFuY2VzIGFuZCB0aGVuIGZvcgorICoganVzdCB0aGUgS2V5IHBvcnRpb24gb2YgYSBLZXlWYWx1ZSB1c2VkIG1vc3RseSBpbiB7QGxpbmsgSEZpbGV9LgorICogCisgKiA8cD5LZXlWYWx1ZSB3cmFwcyBhIGJ5dGUgYXJyYXkgYW5kIGhhcyBvZmZzZXQgYW5kIGxlbmd0aCBmb3IgcGFzc2VkIGFycmF5CisgKiBhdCB3aGVyZSB0byBzdGFydCBpbnRlcnByZXRpbmcgdGhlIGNvbnRlbnQgYXMgYSBLZXlWYWx1ZSBibG9iLiAgVGhlIEtleVZhbHVlCisgKiBibG9iIGZvcm1hdCBpbnNpZGUgdGhlIGJ5dGUgYXJyYXkgaXM6CisgKiA8Y29kZT4mbHQ7a2V5bGVuZ3RoPiAmbHQ7dmFsdWVsZW5ndGg+ICZsdDtrZXk+ICZsdDt2YWx1ZT48L2NvZGU+CisgKiBLZXkgaXMgZGVjb21wb3NlZCBhczoKKyAqIDxjb2RlPiZsdDtyb3dsZW5ndGg+ICZsdDtyb3c+ICZsdDtjb2x1bW5mYW1pbHlsZW5ndGg+ICZsdDtjb2x1bW5mYW1pbHk+ICZsdDtjb2x1bW5xdWFsaWZpZXI+ICZsdDt0aW1lc3RhbXA+ICZsdDtrZXl0eXBlPjwvY29kZT4KKyAqIFJvd2xlbmd0aCBtYXhpbXVtIGlzIFNob3J0Lk1BWF9TSVpFLCBjb2x1bW4gZmFtaWx5IGxlbmd0aCBtYXhpbXVtIGlzCisgKiBCeXRlLk1BWF9TSVpFLCBhbmQgY29sdW1uIHF1YWxpZmllciArIGtleSBsZW5ndGggbXVzdCBiZSA8IEludGVnZXIuTUFYX1NJWkUuCisgKiBUaGUgY29sdW1uIGRvZXMgbm90IGNvbnRhaW4gdGhlIGZhbWlseS9xdWFsaWZpZXIgZGVsaW1pdGVyLgorICogCisgKiA8cD5UT0RPOiBHcm91cCBLZXktb25seSBjb21wYXJhdG9ycyBhbmQgb3BlcmF0aW9ucyBpbnRvIGEgS2V5IGNsYXNzLCBqdXN0CisgKiBmb3IgbmVhdG5lc3Mgc2FrZSwgaWYgY2FuIGZpZ3VyZSB3aGF0IHRvIGNhbGwgaXQuCisgKi8KK3B1YmxpYyBjbGFzcyBLZXlWYWx1ZSBpbXBsZW1lbnRzIFdyaXRhYmxlLCBIZWFwU2l6ZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coS2V5VmFsdWUuY2xhc3MpOworCisgIC8qKgorICAgKiBDb2xvbiBjaGFyYWN0ZXIgaW4gVVRGLTgKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBDT0xVTU5fRkFNSUxZX0RFTElNSVRFUiA9ICc6JzsKKyAgCisgIC8qKgorICAgKiBDb21wYXJhdG9yIGZvciBwbGFpbiBrZXkvdmFsdWVzOyBpLmUuIG5vbi1jYXRhbG9nIHRhYmxlIGtleS92YWx1ZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIEtWQ29tcGFyYXRvciBDT01QQVJBVE9SID0gbmV3IEtWQ29tcGFyYXRvcigpOworCisgIC8qKgorICAgKiBDb21wYXJhdG9yIGZvciBwbGFpbiBrZXk7IGkuZS4gbm9uLWNhdGFsb2cgdGFibGUga2V5LiAgV29ya3Mgb24gS2V5IHBvcnRpb24KKyAgICogb2YgS2V5VmFsdWUgb25seS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgS2V5Q29tcGFyYXRvciBLRVlfQ09NUEFSQVRPUiA9IG5ldyBLZXlDb21wYXJhdG9yKCk7CisKKyAgLyoqCisgICAqIEEge0BsaW5rIEtWQ29tcGFyYXRvcn0gZm9yIDxjb2RlPi5NRVRBLjwvY29kZT4gY2F0YWxvZyB0YWJsZQorICAgKiB7QGxpbmsgS2V5VmFsdWV9cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgS1ZDb21wYXJhdG9yIE1FVEFfQ09NUEFSQVRPUiA9IG5ldyBNZXRhQ29tcGFyYXRvcigpOworCisgIC8qKgorICAgKiBBIHtAbGluayBLVkNvbXBhcmF0b3J9IGZvciA8Y29kZT4uTUVUQS48L2NvZGU+IGNhdGFsb2cgdGFibGUKKyAgICoge0BsaW5rIEtleVZhbHVlfSBrZXlzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBLZXlDb21wYXJhdG9yIE1FVEFfS0VZX0NPTVBBUkFUT1IgPSBuZXcgTWV0YUtleUNvbXBhcmF0b3IoKTsKKworICAvKioKKyAgICogQSB7QGxpbmsgS1ZDb21wYXJhdG9yfSBmb3IgPGNvZGU+LVJPT1QtPC9jb2RlPiBjYXRhbG9nIHRhYmxlCisgICAqIHtAbGluayBLZXlWYWx1ZX1zLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBLVkNvbXBhcmF0b3IgUk9PVF9DT01QQVJBVE9SID0gbmV3IFJvb3RDb21wYXJhdG9yKCk7CisKKyAgLyoqCisgICAqIEEge0BsaW5rIEtWQ29tcGFyYXRvcn0gZm9yIDxjb2RlPi1ST09ULTwvY29kZT4gY2F0YWxvZyB0YWJsZQorICAgKiB7QGxpbmsgS2V5VmFsdWV9IGtleXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIEtleUNvbXBhcmF0b3IgUk9PVF9LRVlfQ09NUEFSQVRPUiA9IG5ldyBSb290S2V5Q29tcGFyYXRvcigpOworCisgIC8qKgorICAgKiBDb21wYXJhdG9yIHRoYXQgY29tcGFyZXMgdGhlIGZhbWlseSBwb3J0aW9uIG9mIGNvbHVtbnMgb25seS4KKyAgICogVXNlIHRoaXMgbWFraW5nIE5hdmlnYWJsZU1hcHMgb2YgU3RvcmVzIG9yIHdoZW4geW91IG5lZWQgdG8gY29tcGFyZQorICAgKiBjb2x1bW4gZmFtaWx5IHBvcnRpb24gb25seSBvZiB0d28gY29sdW1uIG5hbWVzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBSYXdDb21wYXJhdG9yPGJ5dGUgW10+IEZBTUlMWV9DT01QQVJBVE9SID0KKyAgICBuZXcgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiAoKSB7CisgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoYnl0ZSBbXSBhLCBpbnQgYW8sIGludCBhbCwgYnl0ZSBbXSBiLCBpbnQgYm8sIGludCBibCkgeworICAgICAgICBpbnQgaW5kZXhhID0gS2V5VmFsdWUuZ2V0RGVsaW1pdGVyKGEsIGFvLCBhbCwgQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVIpOworICAgICAgICBpZiAoaW5kZXhhIDwgMCkgeworICAgICAgICAgIGluZGV4YSA9IGFsOworICAgICAgICB9CisgICAgICAgIGludCBpbmRleGIgPSBLZXlWYWx1ZS5nZXREZWxpbWl0ZXIoYiwgYm8sIGJsLCBDT0xVTU5fRkFNSUxZX0RFTElNSVRFUik7CisgICAgICAgIGlmIChpbmRleGIgPCAwKSB7CisgICAgICAgICAgaW5kZXhiID0gYmw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhhLCBhbywgaW5kZXhhLCBiLCBibywgaW5kZXhiKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGludCBjb21wYXJlKGJ5dGVbXSBhLCBieXRlW10gYikgeworICAgICAgICByZXR1cm4gY29tcGFyZShhLCAwLCBhLmxlbmd0aCwgYiwgMCwgYi5sZW5ndGgpOworICAgICAgfQorICAgIH07CisKKyAgLy8gU2l6ZSBvZiB0aGUgdGltZXN0YW1wIGFuZCB0eXBlIGJ5dGUgb24gZW5kIG9mIGEga2V5IC0tIGEgbG9uZyArIGEgYnl0ZS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUF9UWVBFX1NJWkUgPQorICAgIEJ5dGVzLlNJWkVPRl9MT05HIC8qIHRpbWVzdGFtcCAqLyArCisgICAgQnl0ZXMuU0laRU9GX0JZVEUgLyprZXl0eXBlKi87CisKKyAgLy8gU2l6ZSBvZiB0aGUgbGVuZ3RoIHNob3J0cyBhbmQgYnl0ZXMgaW4ga2V5LgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0VZX0lORlJBU1RSVUNUVVJFX1NJWkUgPQorICAgIEJ5dGVzLlNJWkVPRl9TSE9SVCAvKnJvd2xlbmd0aCovICsKKyAgICBCeXRlcy5TSVpFT0ZfQllURSAvKmNvbHVtbmZhbWlseWxlbmd0aCovICsKKyAgICBUSU1FU1RBTVBfVFlQRV9TSVpFOworCisgIC8vIEhvdyBmYXIgaW50byB0aGUga2V5IHRoZSByb3cgc3RhcnRzIGF0LiBGaXJzdCB0aGluZyB0byByZWFkIGlzIHRoZSBzaG9ydAorICAvLyB0aGF0IHNheXMgaG93IGxvbmcgdGhlIHJvdyBpcy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJPV19PRkZTRVQgPQorICAgIEJ5dGVzLlNJWkVPRl9JTlQgLyprZXlsZW5ndGgqLyArCisgICAgQnl0ZXMuU0laRU9GX0lOVCAvKnZhbHVlbGVuZ3RoKi87CisKKyAgLy8gU2l6ZSBvZiB0aGUgbGVuZ3RoIGludHMgaW4gYSBLZXlWYWx1ZSBkYXRhc3RydWN0dXJlLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgS0VZVkFMVUVfSU5GUkFTVFJVQ1RVUkVfU0laRSA9IFJPV19PRkZTRVQ7CisKKyAgLyoqCisgICAqIEtleSB0eXBlLgorICAgKiBIYXMgc3BhY2UgZm9yIG90aGVyIGtleSB0eXBlcyB0byBiZSBhZGRlZCBsYXRlci4gIENhbm5vdCByZWx5IG9uCisgICAqIGVudW0gb3JkaW5hbHMgLiBUaGV5IGNoYW5nZSBpZiBpdGVtIGlzIHJlbW92ZWQgb3IgbW92ZWQuICBEbyBvdXIgb3duIGNvZGVzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBlbnVtIFR5cGUgeworICAgIFB1dCgoYnl0ZSk0KSwKKyAgICBEZWxldGUoKGJ5dGUpOCksCisgICAgRGVsZXRlQ29sdW1uKChieXRlKTEyKSwKKyAgICBEZWxldGVGYW1pbHkoKGJ5dGUpMTQpLAorICAgIC8vIE1heGltdW0gaXMgdXNlZCB3aGVuIHNlYXJjaGluZzsgeW91IGxvb2sgZnJvbSBtYXhpbXVtIG9uIGRvd24uCisgICAgTWF4aW11bSgoYnl0ZSkyNTUpOworICAgIAorICAgIHByaXZhdGUgZmluYWwgYnl0ZSBjb2RlOworICAgIAorICAgIFR5cGUoZmluYWwgYnl0ZSBjKSB7CisgICAgICB0aGlzLmNvZGUgPSBjOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgYnl0ZSBnZXRDb2RlKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYW5ub3QgcmVseSBvbiBlbnVtIG9yZGluYWxzIC4gVGhleSBjaGFuZ2UgaWYgaXRlbSBpcyByZW1vdmVkIG9yIG1vdmVkLgorICAgICAqIERvIG91ciBvd24gY29kZXMuCisgICAgICogQHBhcmFtIGIKKyAgICAgKiBAcmV0dXJuIFR5cGUgYXNzb2NpYXRlZCB3aXRoIHBhc3NlZCBjb2RlLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVHlwZSBjb2RlVG9UeXBlKGZpbmFsIGJ5dGUgYikgeworICAgICAgLy8gVGhpcyBpcyBtZXNzeSByZXBlYXRpbmcgZWFjaCB0eXBlIGhlcmUgYmVsb3cgYnV0IG5vIHdheSBhcm91bmQgaXQ7IHdlCisgICAgICAvLyBjYW4ndCB1c2UgdGhlIGVudW0gb3JkaW5hbC4KKyAgICAgIGlmIChiID09IFB1dC5nZXRDb2RlKCkpIHsKKyAgICAgICAgcmV0dXJuIFB1dDsKKyAgICAgIH0gZWxzZSBpZiAoYiA9PSBEZWxldGUuZ2V0Q29kZSgpKSB7CisgICAgICAgIHJldHVybiBEZWxldGU7CisgICAgICB9IGVsc2UgaWYgKGIgPT0gRGVsZXRlQ29sdW1uLmdldENvZGUoKSkgeworICAgICAgICByZXR1cm4gRGVsZXRlQ29sdW1uOworICAgICAgfSBlbHNlIGlmIChiID09IERlbGV0ZUZhbWlseS5nZXRDb2RlKCkpIHsKKyAgICAgICAgcmV0dXJuIERlbGV0ZUZhbWlseTsKKyAgICAgIH0gZWxzZSBpZiAoYiA9PSBNYXhpbXVtLmdldENvZGUoKSkgeworICAgICAgICByZXR1cm4gTWF4aW11bTsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJVbmtub3duIGNvZGUgIiArIGIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBMb3dlc3QgcG9zc2libGUga2V5LgorICAgKiBNYWtlcyBhIEtleSB3aXRoIGhpZ2hlc3QgcG9zc2libGUgVGltZXN0YW1wLCBlbXB0eSByb3cgYW5kIGNvbHVtbi4gIE5vCisgICAqIGtleSBjYW4gYmUgZXF1YWwgb3IgbG93ZXIgdGhhbiB0aGlzIG9uZSBpbiBtZW1jYWNoZSBvciBpbiBzdG9yZSBmaWxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBLZXlWYWx1ZSBMT1dFU1RLRVkgPSAKKyAgICBuZXcgS2V5VmFsdWUoSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAKKyAgcHJpdmF0ZSBieXRlIFtdIGJ5dGVzID0gbnVsbDsKKyAgcHJpdmF0ZSBpbnQgb2Zmc2V0ID0gMDsKKyAgcHJpdmF0ZSBpbnQgbGVuZ3RoID0gMDsKKworICAvKiogV3JpdGFibGUgQ29uc3RydWN0b3IgLS0gRE8gTk9UIFVTRSAqLworICBwdWJsaWMgS2V5VmFsdWUoKSB7fQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEgS2V5VmFsdWUgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHNwZWNpZmllZCBieXRlIGFycmF5LgorICAgKiBQcmVzdW1lcyA8Y29kZT5ieXRlczwvY29kZT4gY29udGVudCBpcyBmb3JtYXR0ZWQgYXMgYSBLZXlWYWx1ZSBibG9iLgorICAgKiBAcGFyYW0gYnl0ZXMgYnl0ZSBhcnJheQorICAgKi8KKyAgcHVibGljIEtleVZhbHVlKGZpbmFsIGJ5dGUgW10gYnl0ZXMpIHsKKyAgICB0aGlzKGJ5dGVzLCAwKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBLZXlWYWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgYnl0ZSBhcnJheSBhbmQgb2Zmc2V0LgorICAgKiBQcmVzdW1lcyA8Y29kZT5ieXRlczwvY29kZT4gY29udGVudCBzdGFydGluZyBhdCA8Y29kZT5vZmZzZXQ8L2NvZGU+IGlzCisgICAqIGZvcm1hdHRlZCBhcyBhIEtleVZhbHVlIGJsb2IuCisgICAqIEBwYXJhbSBieXRlcyBieXRlIGFycmF5CisgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IHRvIHN0YXJ0IG9mIEtleVZhbHVlCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgYnl0ZSBbXSBieXRlcywgZmluYWwgaW50IG9mZnNldCkgeworICAgIHRoaXMoYnl0ZXMsIG9mZnNldCwgZ2V0TGVuZ3RoKGJ5dGVzLCBvZmZzZXQpKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEgS2V5VmFsdWUgZnJvbSB0aGUgc3BlY2lmaWVkIGJ5dGUgYXJyYXksIHN0YXJ0aW5nIGF0IG9mZnNldCwgYW5kCisgICAqIGZvciBsZW5ndGggPGNvZGU+bGVuZ3RoPC9jb2RlPi4KKyAgICogQHBhcmFtIGJ5dGVzIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIG9mZnNldCBvZmZzZXQgdG8gc3RhcnQgb2YgdGhlIEtleVZhbHVlCisgICAqIEBwYXJhbSBsZW5ndGggbGVuZ3RoIG9mIHRoZSBLZXlWYWx1ZQorICAgKi8KKyAgcHVibGljIEtleVZhbHVlKGZpbmFsIGJ5dGUgW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICB0aGlzLmJ5dGVzID0gYnl0ZXM7CisgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIEtleVZhbHVlIHN0cnVjdHVyZSBmaWxsZWQgd2l0aCBudWxsIHZhbHVlLgorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleSAoYXJiaXRyYXJ5IGJ5dGUgYXJyYXkpCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLCB0aW1lc3RhbXApOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIG51bGwgdmFsdWUuCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIEtleVZhbHVlKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMocm93LCBudWxsLCB0aW1lc3RhbXAsIFR5cGUuUHV0LCBudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIEtleVZhbHVlIHN0cnVjdHVyZSBmaWxsZWQgd2l0aCBudWxsIHZhbHVlLgorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleSAoYXJiaXRyYXJ5IGJ5dGUgYXJyYXkpCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIHdpdGggZGVsaW1pdGVyIGJldHdlZW4gZmFtaWx5IGFuZCBxdWFsaWZpZXIKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgY29sdW1uKSB7CisgICAgdGhpcyhyb3csIGNvbHVtbiwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0cyBLZXlWYWx1ZSBzdHJ1Y3R1cmUgZmlsbGVkIHdpdGggbnVsbCB2YWx1ZS4KKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gY29sdW1uIENvbHVtbiB3aXRoIGRlbGltaXRlciBiZXR3ZWVuIGZhbWlseSBhbmQgcXVhbGlmaWVyCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgdGhpcyhyb3csIGNvbHVtbiwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0cyBLZXlWYWx1ZSBzdHJ1Y3R1cmUgZmlsbGVkIHdpdGggc3BlY2lmaWVkIHZhbHVlLgorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleSAoYXJiaXRyYXJ5IGJ5dGUgYXJyYXkpCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIHdpdGggZGVsaW1pdGVyIGJldHdlZW4gZmFtaWx5IGFuZCBxdWFsaWZpZXIKKyAgICogQHBhcmFtIHZhbHVlCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbiwgZmluYWwgYnl0ZSBbXSB2YWx1ZSkgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLCBCeXRlcy50b0J5dGVzKGNvbHVtbiksIHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIEtleVZhbHVlIHN0cnVjdHVyZSBmaWxsZWQgd2l0aCBzcGVjaWZpZWQgdmFsdWUuCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIGNvbHVtbiBDb2x1bW4gd2l0aCBkZWxpbWl0ZXIgYmV0d2VlbiBmYW1pbHkgYW5kIHF1YWxpZmllcgorICAgKiBAcGFyYW0gdmFsdWUKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGJ5dGUgW10gdmFsdWUpIHsKKyAgICB0aGlzKHJvdywgY29sdW1uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIHZhbHVlKTsKKyAgfQorCisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIG51bGwgdmFsdWUuCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIGNvbHVtbiBDb2x1bW4gd2l0aCBkZWxpbWl0ZXIgYmV0d2VlbiBmYW1pbHkgYW5kIHF1YWxpZmllcgorICAgKiBAcGFyYW0gdHMKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgY29sdW1uLCBmaW5hbCBsb25nIHRzKSB7CisgICAgdGhpcyhyb3csIGNvbHVtbiwgdHMsIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIG51bGwgdmFsdWUuCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIGNvbHVtbiBDb2x1bW4gd2l0aCBkZWxpbWl0ZXIgYmV0d2VlbiBmYW1pbHkgYW5kIHF1YWxpZmllcgorICAgKiBAcGFyYW0gdHMKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdHMpIHsKKyAgICB0aGlzKHJvdywgY29sdW1uLCB0cywgVHlwZS5QdXQpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIHNwZWNpZmllZCB2YWx1ZS4KKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gY29sdW1uIENvbHVtbiB3aXRoIGRlbGltaXRlciBiZXR3ZWVuIGZhbWlseSBhbmQgcXVhbGlmaWVyCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHBhcmFtIHZhbHVlCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbiwKKyAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgYnl0ZSBbXSB2YWx1ZSkgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLAorICAgICAgY29sdW1uID09IG51bGw/IEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWTogQnl0ZXMudG9CeXRlcyhjb2x1bW4pLAorICAgICAgdGltZXN0YW1wLCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0cyBLZXlWYWx1ZSBzdHJ1Y3R1cmUgZmlsbGVkIHdpdGggc3BlY2lmaWVkIHZhbHVlLgorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleSAoYXJiaXRyYXJ5IGJ5dGUgYXJyYXkpCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIHdpdGggZGVsaW1pdGVyIGJldHdlZW4gZmFtaWx5IGFuZCBxdWFsaWZpZXIKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gdmFsdWUKKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sCisgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBieXRlIFtdIHZhbHVlKSB7CisgICAgdGhpcyhyb3csIGNvbHVtbiwgdGltZXN0YW1wLCBUeXBlLlB1dCwgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIHNwZWNpZmllZCB2YWx1ZS4KKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gY29sdW1uIENvbHVtbiB3aXRoIGRlbGltaXRlciBiZXR3ZWVuIGZhbWlseSBhbmQgcXVhbGlmaWVyCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHBhcmFtIHR5cGUKKyAgICogQHBhcmFtIHZhbHVlCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbiwKKyAgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIFR5cGUgdHlwZSwgZmluYWwgYnl0ZSBbXSB2YWx1ZSkgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLCBCeXRlcy50b0J5dGVzKGNvbHVtbiksIHRpbWVzdGFtcCwgdHlwZSwKKyAgICAgIHZhbHVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIEtleVZhbHVlIHN0cnVjdHVyZSBmaWxsZWQgd2l0aCBudWxsIHZhbHVlLgorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleSAoYXJiaXRyYXJ5IGJ5dGUgYXJyYXkpCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIHdpdGggZGVsaW1pdGVyIGJldHdlZW4gZmFtaWx5IGFuZCBxdWFsaWZpZXIKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gdHlwZQorICAgKi8KKyAgcHVibGljIEtleVZhbHVlKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBUeXBlIHR5cGUpIHsKKyAgICB0aGlzKHJvdywgMCwgcm93Lmxlbmd0aCwgY29sdW1uLCAwLCBjb2x1bW4gPT0gbnVsbD8gMDogY29sdW1uLmxlbmd0aCwKKyAgICAgIHRpbWVzdGFtcCwgdHlwZSwgbnVsbCwgMCwgLTEpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgS2V5VmFsdWUgc3RydWN0dXJlIGZpbGxlZCB3aXRoIHNwZWNpZmllZCB2YWx1ZS4KKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gY29sdW1uIENvbHVtbiB3aXRoIGRlbGltaXRlciBiZXR3ZWVuIGZhbWlseSBhbmQgcXVhbGlmaWVyCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHBhcmFtIHR5cGUKKyAgICogQHBhcmFtIHZhbHVlCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uLAorICAgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIFR5cGUgdHlwZSwgZmluYWwgYnl0ZSBbXSB2YWx1ZSkgeworICAgIHRoaXMocm93LCAwLCByb3cubGVuZ3RoLCBjb2x1bW4sIDAsIGNvbHVtbiA9PSBudWxsPyAwOiBjb2x1bW4ubGVuZ3RoLAorICAgICAgdGltZXN0YW1wLCB0eXBlLCB2YWx1ZSwgMCwgdmFsdWUgPT0gbnVsbD8gMDogdmFsdWUubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIEtleVZhbHVlIHN0cnVjdHVyZSBmaWxsZWQgd2l0aCBzcGVjaWZpZWQgdmFsdWUuCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIHJvZmZzZXQKKyAgICogQHBhcmFtIHJsZW5ndGgKKyAgICogQHBhcmFtIGNvbHVtbiBDb2x1bW4gd2l0aCBkZWxpbWl0ZXIgYmV0d2VlbiBmYW1pbHkgYW5kIHF1YWxpZmllcgorICAgKiBAcGFyYW0gY29mZnNldCBXaGVyZSB0byBzdGFydCByZWFkaW5nIHRoZSBjb2x1bW4uCisgICAqIEBwYXJhbSBjbGVuZ3RoIEhvdyBsb25nIGNvbHVtbiBpcyAoaW5jbHVkaW5nIHRoZSBmYW1pbHkvcXVhbGlmaWVyIGRlbGltaXRlci4KKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gdHlwZQorICAgKiBAcGFyYW0gdmFsdWUKKyAgICogQHBhcmFtIHZvZmZzZXQKKyAgICogQHBhcmFtIHZsZW5ndGgKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgaW50IHJvZmZzZXQsIGZpbmFsIGludCBybGVuZ3RoLAorICAgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGludCBjb2Zmc2V0LCBpbnQgY2xlbmd0aCwKKyAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBUeXBlIHR5cGUsCisgICAgICBmaW5hbCBieXRlIFtdIHZhbHVlLCBmaW5hbCBpbnQgdm9mZnNldCwgaW50IHZsZW5ndGgpIHsKKyAgICB0aGlzLmJ5dGVzID0gY3JlYXRlQnl0ZUFycmF5KHJvdywgcm9mZnNldCwgcmxlbmd0aCwgY29sdW1uLCBjb2Zmc2V0LAorICAgICAgY2xlbmd0aCwgdGltZXN0YW1wLCB0eXBlLCB2YWx1ZSwgdm9mZnNldCwgdmxlbmd0aCk7CisgICAgdGhpcy5sZW5ndGggPSBieXRlcy5sZW5ndGg7CisgICAgdGhpcy5vZmZzZXQgPSAwOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIEtleVZhbHVlIGZvcm1hdCBpbnRvIGEgYnl0ZSBhcnJheS4KKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gcm9mZnNldAorICAgKiBAcGFyYW0gcmxlbmd0aAorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEBwYXJhbSBjb2Zmc2V0CisgICAqIEBwYXJhbSBjbGVuZ3RoCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHBhcmFtIHR5cGUKKyAgICogQHBhcmFtIHZhbHVlCisgICAqIEBwYXJhbSB2b2Zmc2V0CisgICAqIEBwYXJhbSB2bGVuZ3RoCisgICAqIEByZXR1cm4KKyAgICovCisgIHN0YXRpYyBieXRlIFtdIGNyZWF0ZUJ5dGVBcnJheShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgaW50IHJvZmZzZXQsCisgICAgICAgIGZpbmFsIGludCBybGVuZ3RoLAorICAgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGludCBjb2Zmc2V0LCBpbnQgY2xlbmd0aCwKKyAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBUeXBlIHR5cGUsCisgICAgICBmaW5hbCBieXRlIFtdIHZhbHVlLCBmaW5hbCBpbnQgdm9mZnNldCwgaW50IHZsZW5ndGgpIHsKKyAgICBpZiAocmxlbmd0aCA+IFNob3J0Lk1BWF9WQUxVRSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUm93ID4gIiArIFNob3J0Lk1BWF9WQUxVRSk7CisgICAgfQorICAgIGlmIChyb3cgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUm93IGlzIG51bGwiKTsKKyAgICB9CisgICAgLy8gSWYgY29sdW1uIGlzIG5vbi1udWxsLCBmaWd1cmUgd2hlcmUgdGhlIGRlbGltaXRlciBpcyBhdC4KKyAgICBpbnQgZGVsaW1pdGVyb2Zmc2V0ID0gMDsKKyAgICBpZiAoY29sdW1uICE9IG51bGwgJiYgY29sdW1uLmxlbmd0aCA+IDApIHsKKyAgICAgIGRlbGltaXRlcm9mZnNldCA9IGdldEZhbWlseURlbGltaXRlckluZGV4KGNvbHVtbiwgY29mZnNldCwgY2xlbmd0aCk7CisgICAgICBpZiAoZGVsaW1pdGVyb2Zmc2V0ID4gQnl0ZS5NQVhfVkFMVUUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmFtaWx5ID4gIiArIEJ5dGUuTUFYX1ZBTFVFKTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gVmFsdWUgbGVuZ3RoCisgICAgdmxlbmd0aCA9IHZhbHVlID09IG51bGw/IDA6IHZsZW5ndGg7CisgICAgLy8gQ29sdW1uIGxlbmd0aCAtIG1pbnVzIGRlbGltaXRlcgorICAgIGNsZW5ndGggPSBjb2x1bW4gPT0gbnVsbCB8fCBjb2x1bW4ubGVuZ3RoID09IDA/IDA6IGNsZW5ndGggLSAxOworICAgIGxvbmcgbG9uZ2tleWxlbmd0aCA9IEtFWV9JTkZSQVNUUlVDVFVSRV9TSVpFICsgcmxlbmd0aCArIGNsZW5ndGg7CisgICAgaWYgKGxvbmdrZXlsZW5ndGggPiBJbnRlZ2VyLk1BWF9WQUxVRSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigia2V5bGVuZ3RoICIgKyBsb25na2V5bGVuZ3RoICsgIiA+ICIgKworICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgfQorICAgIGludCBrZXlsZW5ndGggPSAoaW50KWxvbmdrZXlsZW5ndGg7CisgICAgLy8gQWxsb2NhdGUgcmlnaHQtc2l6ZWQgYnl0ZSBhcnJheS4KKyAgICBieXRlIFtdIGJ5dGVzID0gbmV3IGJ5dGVbS0VZVkFMVUVfSU5GUkFTVFJVQ1RVUkVfU0laRSArIGtleWxlbmd0aCArIHZsZW5ndGhdOworICAgIC8vIFdyaXRlIGtleSwgdmFsdWUgYW5kIGtleSByb3cgbGVuZ3RoLgorICAgIGludCBwb3MgPSAwOworICAgIHBvcyA9IEJ5dGVzLnB1dEludChieXRlcywgcG9zLCBrZXlsZW5ndGgpOworICAgIHBvcyA9IEJ5dGVzLnB1dEludChieXRlcywgcG9zLCB2bGVuZ3RoKTsKKyAgICBwb3MgPSBCeXRlcy5wdXRTaG9ydChieXRlcywgcG9zLCAoc2hvcnQpKHJsZW5ndGggJiAweDAwMDBmZmZmKSk7CisgICAgcG9zID0gQnl0ZXMucHV0Qnl0ZXMoYnl0ZXMsIHBvcywgcm93LCByb2Zmc2V0LCBybGVuZ3RoKTsKKyAgICAvLyBXcml0ZSBvdXQgY29sdW1uIGZhbWlseSBsZW5ndGguCisgICAgcG9zID0gQnl0ZXMucHV0Qnl0ZShieXRlcywgcG9zLCAoYnl0ZSkoZGVsaW1pdGVyb2Zmc2V0ICYgMHgwMDAwZmYpKTsKKyAgICBpZiAoY29sdW1uICE9IG51bGwgJiYgY29sdW1uLmxlbmd0aCAhPSAwKSB7CisgICAgICAvLyBXcml0ZSBmYW1pbHkuCisgICAgICBwb3MgPSBCeXRlcy5wdXRCeXRlcyhieXRlcywgcG9zLCBjb2x1bW4sIGNvZmZzZXQsIGRlbGltaXRlcm9mZnNldCk7CisgICAgICAvLyBXcml0ZSBxdWFsaWZpZXIuCisgICAgICBkZWxpbWl0ZXJvZmZzZXQrKzsKKyAgICAgIHBvcyA9IEJ5dGVzLnB1dEJ5dGVzKGJ5dGVzLCBwb3MsIGNvbHVtbiwgY29mZnNldCArIGRlbGltaXRlcm9mZnNldCwKKyAgICAgICAgY29sdW1uLmxlbmd0aCAtIGRlbGltaXRlcm9mZnNldCk7CisgICAgfQorICAgIHBvcyA9IEJ5dGVzLnB1dExvbmcoYnl0ZXMsIHBvcywgdGltZXN0YW1wKTsKKyAgICBwb3MgPSBCeXRlcy5wdXRCeXRlKGJ5dGVzLCBwb3MsIHR5cGUuZ2V0Q29kZSgpKTsKKyAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZS5sZW5ndGggPiAwKSB7CisgICAgICBwb3MgPSBCeXRlcy5wdXRCeXRlcyhieXRlcywgcG9zLCB2YWx1ZSwgdm9mZnNldCwgdmxlbmd0aCk7CisgICAgfQorICAgIHJldHVybiBieXRlczsKKyAgfQorCisgIC8vIE5lZWRlZCBkb2luZyAnY29udGFpbnMnIG9uIExpc3QuICBPbmx5IGNvbXBhcmVzIHRoZSBrZXkgcG9ydGlvbiwgbm90IHRoZQorICAvLyB2YWx1ZS4KKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgeworICAgIEtleVZhbHVlIGt2ID0gKEtleVZhbHVlKW90aGVyOworICAgIC8vIENvbXBhcmluZyBieXRlcyBzaG91bGQgYmUgZmluZSBkb2luZyBlcXVhbHMgdGVzdC4gIFNob3VsZG4ndCBoYXZlIHRvCisgICAgLy8gd29ycnkgYWJvdXQgc3BlY2lhbCAuTUVUQS4gY29tcGFyYXRvcnMgZG9pbmcgc3RyYWlnaHQgZXF1YWxzLgorICAgIGJvb2xlYW4gcmVzdWx0ID0gQnl0ZXMuQllURVNfUkFXQ09NUEFSQVRPUi5jb21wYXJlKGdldEJ1ZmZlcigpLAorICAgICAgICBnZXRLZXlPZmZzZXQoKSwgZ2V0S2V5TGVuZ3RoKCksCisgICAgICBrdi5nZXRCdWZmZXIoKSwga3YuZ2V0S2V5T2Zmc2V0KCksIGt2LmdldEtleUxlbmd0aCgpKSA9PSAwOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcmV0dXJuIENsb25lIG9mIGJiJ3Mga2V5IHBvcnRpb24gd2l0aCBvbmx5IHRoZSByb3cgYW5kIHRpbWVzdGFtcCBmaWxsZWQgaW4uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBLZXlWYWx1ZSBjbG9uZVJvdyhmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIHJldHVybiBuZXcgS2V5VmFsdWUoZ2V0QnVmZmVyKCksIGdldFJvd09mZnNldCgpLCBnZXRSb3dMZW5ndGgoKSwKKyAgICAgIG51bGwsIDAsIDAsIHRpbWVzdGFtcCwgVHlwZS5jb2RlVG9UeXBlKGdldFR5cGUoKSksIG51bGwsIDAsIDApOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gQ2xvbmUgb2YgYmIncyBrZXkgcG9ydGlvbiB3aXRoIHR5cGUgc2V0IHRvIFR5cGUuRGVsZXRlLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUgY2xvbmVEZWxldGUoKSB7CisgICAgcmV0dXJuIGNyZWF0ZUtleShUeXBlLkRlbGV0ZSk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDbG9uZSBvZiBiYidzIGtleSBwb3J0aW9uIHdpdGggdHlwZSBzZXQgdG8gVHlwZS5NYXhpbXVtLiBVc2UgdGhpcworICAgKiBkb2luZyBsb29rdXBzIHdoZXJlIHlvdSBhcmUgZG9pbmcgZ2V0Q2xvc2VzdC4gIFVzaW5nIE1heGltdW0sIHlvdSdsbCBiZQorICAgKiBzdXJlIHRvIHRyaXAgb3ZlciBhbGwgb2YgdGhlIG90aGVyIGtleSB0eXBlcyBzaW5jZSBNYXhpbXVtIHNvcnRzIGZpcnN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUgY2xvbmVNYXhpbXVtKCkgeworICAgICByZXR1cm4gY3JlYXRlS2V5KFR5cGUuTWF4aW11bSk7CisgIH0KKworICAvKgorICAgKiBNYWtlIGEgY2xvbmUgd2l0aCB0aGUgbmV3IHR5cGUuCisgICAqIERvZXMgbm90IGNvcHkgdmFsdWUuCisgICAqIEBwYXJhbSBuZXd0eXBlIE5ldyB0eXBlIHRvIHNldCBvbiBjbG9uZSBvZiB0aGlzIGtleS4KKyAgICogQHJldHVybiBDbG9uZSBvZiB0aGlzIGtleSB3aXRoIHR5cGUgc2V0IHRvIDxjb2RlPm5ld3R5cGU8L2NvZGU+CisgICAqLworICBwcml2YXRlIEtleVZhbHVlIGNyZWF0ZUtleShmaW5hbCBUeXBlIG5ld3R5cGUpIHsKKyAgICBpbnQga2V5bGVuZ3RoID0gZ2V0S2V5TGVuZ3RoKCk7CisgICAgaW50IGwgPSBrZXlsZW5ndGggKyBST1dfT0ZGU0VUOworICAgIGJ5dGUgW10gb3RoZXIgPSBuZXcgYnl0ZVtsXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGdldEJ1ZmZlcigpLCBnZXRPZmZzZXQoKSwgb3RoZXIsIDAsIGwpOworICAgIC8vIFNldCB2YWx1ZSBsZW5ndGggdG8gemVyby4KKyAgICBCeXRlcy5wdXRJbnQob3RoZXIsIEJ5dGVzLlNJWkVPRl9JTlQsIDApOworICAgIC8vIFNldCBsYXN0IGJ5dGUsIHRoZSB0eXBlLCB0byBuZXcgdHlwZQorICAgIG90aGVyW2wgLSAxXSA9IG5ld3R5cGUuZ2V0Q29kZSgpOworICAgIHJldHVybiBuZXcgS2V5VmFsdWUob3RoZXIsIDAsIG90aGVyLmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiBrZXlUb1N0cmluZyh0aGlzLmJ5dGVzLCB0aGlzLm9mZnNldCArIFJPV19PRkZTRVQsIGdldEtleUxlbmd0aCgpKSArCisgICAgICAiL3ZsZW49IiArIGdldFZhbHVlTGVuZ3RoKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGsgS2V5IHBvcnRpb24gb2YgYSBLZXlWYWx1ZS4KKyAgICogQHJldHVybiBLZXkgYXMgYSBTdHJpbmcuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBrZXlUb1N0cmluZyhmaW5hbCBieXRlIFtdIGspIHsKKyAgICByZXR1cm4ga2V5VG9TdHJpbmcoaywgMCwgay5sZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiIEtleSBwb3J0aW9uIG9mIGEgS2V5VmFsdWUuCisgICAqIEBwYXJhbSBvIE9mZnNldCB0byBzdGFydCBvZiBrZXkKKyAgICogQHBhcmFtIGwgTGVuZ3RoIG9mIGtleS4KKyAgICogQHJldHVybiBLZXkgYXMgYSBTdHJpbmcuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBrZXlUb1N0cmluZyhmaW5hbCBieXRlIFtdIGIsIGZpbmFsIGludCBvLCBmaW5hbCBpbnQgbCkgeworICAgIGludCByb3dsZW5ndGggPSBCeXRlcy50b1Nob3J0KGIsIG8pOworICAgIFN0cmluZyByb3cgPSBCeXRlcy50b1N0cmluZyhiLCBvICsgQnl0ZXMuU0laRU9GX1NIT1JULCByb3dsZW5ndGgpOworICAgIGludCBjb2x1bW5vZmZzZXQgPSBvICsgQnl0ZXMuU0laRU9GX1NIT1JUICsgMSArIHJvd2xlbmd0aDsKKyAgICBpbnQgZmFtaWx5bGVuZ3RoID0gYltjb2x1bW5vZmZzZXQgLSAxXTsKKyAgICBpbnQgY29sdW1ubGVuZ3RoID0gbCAtICgoY29sdW1ub2Zmc2V0IC0gbykgKyBUSU1FU1RBTVBfVFlQRV9TSVpFKTsKKyAgICBTdHJpbmcgZmFtaWx5ID0gZmFtaWx5bGVuZ3RoID09IDA/ICIiOgorICAgICAgQnl0ZXMudG9TdHJpbmcoYiwgY29sdW1ub2Zmc2V0LCBmYW1pbHlsZW5ndGgpOworICAgIFN0cmluZyBxdWFsaWZpZXIgPSBjb2x1bW5sZW5ndGggPT0gMD8gIiI6CisgICAgICBCeXRlcy50b1N0cmluZyhiLCBjb2x1bW5vZmZzZXQgKyBmYW1pbHlsZW5ndGgsCisgICAgICBjb2x1bW5sZW5ndGggLSBmYW1pbHlsZW5ndGgpOworICAgIGxvbmcgdGltZXN0YW1wID0gQnl0ZXMudG9Mb25nKGIsIG8gKyAobCAtIFRJTUVTVEFNUF9UWVBFX1NJWkUpKTsKKyAgICBieXRlIHR5cGUgPSBiW28gKyBsIC0gMV07CisgICAgcmV0dXJuIHJvdyArICIvIiArIGZhbWlseSArCisgICAgICAoZmFtaWx5ICE9IG51bGwgJiYgZmFtaWx5Lmxlbmd0aCgpID4gMD8gQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVI6ICIiKSArCisgICAgICBxdWFsaWZpZXIgKyAiLyIgKyB0aW1lc3RhbXAgKyAiLyIgKyBUeXBlLmNvZGVUb1R5cGUodHlwZSk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBUaGUgYnl0ZSBhcnJheSBiYWNraW5nIHRoaXMgS2V5VmFsdWUuCisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRCdWZmZXIoKSB7CisgICAgcmV0dXJuIHRoaXMuYnl0ZXM7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBPZmZzZXQgaW50byB7QGxpbmsgI2dldEJ1ZmZlcigpfSBhdCB3aGljaCB0aGlzIEtleVZhbHVlIHN0YXJ0cy4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0T2Zmc2V0KCkgeworICAgIHJldHVybiB0aGlzLm9mZnNldDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIExlbmd0aCBvZiBieXRlcyB0aGlzIEtleVZhbHVlIG9jY3VwaWVzIGluIHtAbGluayAjZ2V0QnVmZmVyKCl9LgorICAgKi8KKyAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7CisgICAgcmV0dXJuIGxlbmd0aDsKKyAgfQorCisgIC8qCisgICAqIERldGVybWluZXMgdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgS2V5VmFsdWUgc3RvcmVkIGluIHRoZSBzcGVjaWZpZWQKKyAgICogYnl0ZSBhcnJheSBhbmQgb2Zmc2V0LiAgSW5jbHVkZXMgYWxsIGhlYWRlcnMuCisgICAqIEBwYXJhbSBieXRlcyBieXRlIGFycmF5CisgICAqIEBwYXJhbSBvZmZzZXQgb2Zmc2V0IHRvIHN0YXJ0IG9mIHRoZSBLZXlWYWx1ZQorICAgKiBAcmV0dXJuIGxlbmd0aCBvZiBlbnRpcmUgS2V5VmFsdWUsIGluIGJ5dGVzCisgICAqLworICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0TGVuZ3RoKGJ5dGUgW10gYnl0ZXMsIGludCBvZmZzZXQpIHsKKyAgICByZXR1cm4gKDIgKiBCeXRlcy5TSVpFT0ZfSU5UKSArIAorICAgICAgICBCeXRlcy50b0ludChieXRlcywgb2Zmc2V0KSArCisgICAgICAgIEJ5dGVzLnRvSW50KGJ5dGVzLCBvZmZzZXQgKyBCeXRlcy5TSVpFT0ZfSU5UKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIENvcHkgb2YgdGhlIGtleSBwb3J0aW9uIG9ubHkuICBVc2VkIGNvbXBhY3RpbmcgYW5kIHRlc3RpbmcuCisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRLZXkoKSB7CisgICAgaW50IGtleWxlbmd0aCA9IGdldEtleUxlbmd0aCgpOworICAgIGJ5dGUgW10ga2V5ID0gbmV3IGJ5dGVba2V5bGVuZ3RoXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGdldEJ1ZmZlcigpLCBnZXRLZXlPZmZzZXQoKSwga2V5LCAwLCBrZXlsZW5ndGgpOworICAgIHJldHVybiBrZXk7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIGdldEtleVN0cmluZygpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcoZ2V0QnVmZmVyKCksIGdldEtleU9mZnNldCgpLCBnZXRLZXlMZW5ndGgoKSk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBLZXkgb2Zmc2V0IGluIGJhY2tpbmcgYnVmZmVyLi4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0S2V5T2Zmc2V0KCkgeworICAgIHJldHVybiB0aGlzLm9mZnNldCArIFJPV19PRkZTRVQ7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBSb3cgbGVuZ3RoLgorICAgKi8KKyAgcHVibGljIHNob3J0IGdldFJvd0xlbmd0aCgpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9TaG9ydCh0aGlzLmJ5dGVzLCBnZXRLZXlPZmZzZXQoKSk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBPZmZzZXQgaW50byBiYWNraW5nIGJ1ZmZlciBhdCB3aGljaCByb3cgc3RhcnRzLgorICAgKi8KKyAgcHVibGljIGludCBnZXRSb3dPZmZzZXQoKSB7CisgICAgcmV0dXJuIGdldEtleU9mZnNldCgpICsgQnl0ZXMuU0laRU9GX1NIT1JUOworICB9CisKKyAgLyoqCisgICAqIERvIG5vdCB1c2UgdGhpcyB1bmxlc3MgeW91IGhhdmUgdG8uCisgICAqIFVzZSB7QGxpbmsgI2dldEJ1ZmZlcigpfSB3aXRoIGFwcHJvcHJpYXRlIG9mZnNldHMgYW5kIGxlbmd0aHMgaW5zdGVhZC4KKyAgICogQHJldHVybiBSb3cgaW4gYSBuZXcgYnl0ZSBhcnJheS4KKyAgICovCisgIHB1YmxpYyBieXRlIFtdIGdldFJvdygpIHsKKyAgICBpbnQgbyA9IGdldFJvd09mZnNldCgpOworICAgIHNob3J0IGwgPSBnZXRSb3dMZW5ndGgoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IG5ldyBieXRlW2xdOworICAgIFN5c3RlbS5hcnJheWNvcHkoZ2V0QnVmZmVyKCksIG8sIHJlc3VsdCwgMCwgbCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgIHJldHVybiBnZXRUaW1lc3RhbXAoZ2V0S2V5TGVuZ3RoKCkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXlsZW5ndGggUGFzcyBpZiB5b3UgaGF2ZSBpdCB0byBzYXZlIG9uIGEgaW50IGNyZWF0aW9uLgorICAgKiBAcmV0dXJuIFRpbWVzdGFtcAorICAgKi8KKyAgbG9uZyBnZXRUaW1lc3RhbXAoZmluYWwgaW50IGtleWxlbmd0aCkgeworICAgIGludCB0c09mZnNldCA9IGdldFRpbWVzdGFtcE9mZnNldChrZXlsZW5ndGgpOworICAgIHJldHVybiBCeXRlcy50b0xvbmcodGhpcy5ieXRlcywgdHNPZmZzZXQpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXlsZW5ndGggUGFzcyBpZiB5b3UgaGF2ZSBpdCB0byBzYXZlIG9uIGEgaW50IGNyZWF0aW9uLgorICAgKiBAcmV0dXJuIE9mZnNldCBpbnRvIGJhY2tpbmcgYnVmZmVyIGF0IHdoaWNoIHRpbWVzdGFtcCBzdGFydHMuCisgICAqLworICBpbnQgZ2V0VGltZXN0YW1wT2Zmc2V0KGZpbmFsIGludCBrZXlsZW5ndGgpIHsKKyAgICByZXR1cm4gZ2V0S2V5T2Zmc2V0KCkgKyBrZXlsZW5ndGggLSBUSU1FU1RBTVBfVFlQRV9TSVpFOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBhIHtAbGluayBUeXBlI0RlbGV0ZX0uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0RlbGV0ZVR5cGUoKSB7CisgICAgcmV0dXJuIGdldFR5cGUoKSA9PSBUeXBlLkRlbGV0ZS5nZXRDb2RlKCk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBUeXBlIG9mIHRoaXMgS2V5VmFsdWUuCisgICAqLworICBieXRlIGdldFR5cGUoKSB7CisgICAgcmV0dXJuIGdldFR5cGUoZ2V0S2V5TGVuZ3RoKCkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrZXlsZW5ndGggUGFzcyBpZiB5b3UgaGF2ZSBpdCB0byBzYXZlIG9uIGEgaW50IGNyZWF0aW9uLgorICAgKiBAcmV0dXJuIFR5cGUgb2YgdGhpcyBLZXlWYWx1ZS4KKyAgICovCisgIGJ5dGUgZ2V0VHlwZShmaW5hbCBpbnQga2V5bGVuZ3RoKSB7CisgICAgcmV0dXJuIHRoaXMuYnl0ZXNbdGhpcy5vZmZzZXQgKyBrZXlsZW5ndGggLSAxICsgUk9XX09GRlNFVF07CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBMZW5ndGggb2Yga2V5IHBvcnRpb24uCisgICAqLworICBwdWJsaWMgaW50IGdldEtleUxlbmd0aCgpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9JbnQodGhpcy5ieXRlcywgdGhpcy5vZmZzZXQpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVmFsdWUgbGVuZ3RoCisgICAqLworICBwdWJsaWMgaW50IGdldFZhbHVlTGVuZ3RoKCkgeworICAgIHJldHVybiBCeXRlcy50b0ludCh0aGlzLmJ5dGVzLCB0aGlzLm9mZnNldCArIEJ5dGVzLlNJWkVPRl9JTlQpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gT2Zmc2V0IGludG8gYmFja2luZyBidWZmZXIgYXQgd2hpY2ggdmFsdWUgc3RhcnRzLgorICAgKi8KKyAgcHVibGljIGludCBnZXRWYWx1ZU9mZnNldCgpIHsKKyAgICByZXR1cm4gZ2V0S2V5T2Zmc2V0KCkgKyBnZXRLZXlMZW5ndGgoKTsKKyAgfQorCisgIC8qKgorICAgKiBEbyBub3QgdXNlIHVubGVzcyB5b3UgaGF2ZSB0by4gIFVzZSB7QGxpbmsgI2dldEJ1ZmZlcigpfSB3aXRoIGFwcHJvcHJpYXRlCisgICAqIG9mZnNldCBhbmQgbGVuZ3RocyBpbnN0ZWFkLgorICAgKiBAcmV0dXJuIFZhbHVlIGluIGEgbmV3IGJ5dGUgYXJyYXkuCisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRWYWx1ZSgpIHsKKyAgICBpbnQgbyA9IGdldFZhbHVlT2Zmc2V0KCk7CisgICAgaW50IGwgPSBnZXRWYWx1ZUxlbmd0aCgpOworICAgIGJ5dGUgW10gcmVzdWx0ID0gbmV3IGJ5dGVbbF07CisgICAgU3lzdGVtLmFycmF5Y29weShnZXRCdWZmZXIoKSwgbywgcmVzdWx0LCAwLCBsKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gT2Zmc2V0IGludG8gYmFja2luZyBidWZmZXIgYXQgd2hpY2ggdGhlIGNvbHVtbiBiZWdpbnMKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uT2Zmc2V0KCkgeworICAgIHJldHVybiBnZXRDb2x1bW5PZmZzZXQoZ2V0Um93TGVuZ3RoKCkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByb3dsZW5ndGggLSBsZW5ndGggb2Ygcm93LgorICAgKiBAcmV0dXJuIE9mZnNldCBpbnRvIGJhY2tpbmcgYnVmZmVyIGF0IHdoaWNoIHRoZSBjb2x1bW4gYmVnaW5zCisgICAqLworICBwdWJsaWMgaW50IGdldENvbHVtbk9mZnNldChmaW5hbCBpbnQgcm93bGVuZ3RoKSB7CisgICAgcmV0dXJuIGdldFJvd09mZnNldCgpICsgcm93bGVuZ3RoICsgMTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1ub2Zmc2V0IFBhc3MgaWYgeW91IGhhdmUgaXQgdG8gc2F2ZSBvbiBhbiBpbnQgY3JlYXRpb24uCisgICAqIEByZXR1cm4gTGVuZ3RoIG9mIGZhbWlseSBwb3J0aW9uIG9mIGNvbHVtbi4KKyAgICovCisgIGludCBnZXRGYW1pbHlMZW5ndGgoZmluYWwgaW50IGNvbHVtbm9mZnNldCkgeworICAgIHJldHVybiB0aGlzLmJ5dGVzW2NvbHVtbm9mZnNldCAtIDFdOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb2x1bW5vZmZzZXQgUGFzcyBpZiB5b3UgaGF2ZSBpdCB0byBzYXZlIG9uIGFuIGludCBjcmVhdGlvbi4KKyAgICogQHJldHVybiBMZW5ndGggb2YgY29sdW1uLgorICAgKi8KKyAgcHVibGljIGludCBnZXRDb2x1bW5MZW5ndGgoZmluYWwgaW50IGNvbHVtbm9mZnNldCkgeworICAgIHJldHVybiBnZXRDb2x1bW5MZW5ndGgoY29sdW1ub2Zmc2V0LCBnZXRLZXlMZW5ndGgoKSk7CisgIH0KKworICBpbnQgZ2V0Q29sdW1uTGVuZ3RoKGZpbmFsIGludCBjb2x1bW5vZmZzZXQsIGZpbmFsIGludCBrZXlsZW5ndGgpIHsKKyAgICByZXR1cm4gKGtleWxlbmd0aCArIFJPV19PRkZTRVQpIC0gKGNvbHVtbm9mZnNldCAtIHRoaXMub2Zmc2V0KSAtCisgICAgICBUSU1FU1RBTVBfVFlQRV9TSVpFOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBmYW1pbHkKKyAgICogQHJldHVybiBUcnVlIGlmIG1hdGNoaW5nIGZhbWlsaWVzLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gbWF0Y2hpbmdGYW1pbHkoZmluYWwgYnl0ZSBbXSBmYW1pbHkpIHsKKyAgICBpbnQgbyA9IGdldENvbHVtbk9mZnNldCgpOworICAgIC8vIEZhbWlseSBsZW5ndGggYnl0ZSBpcyBqdXN0IGJlZm9yZSB0aGUgY29sdW1uIHN0YXJ0cy4KKyAgICBpbnQgbCA9IHRoaXMuYnl0ZXNbbyAtIDFdOworICAgIHJldHVybiBCeXRlcy5jb21wYXJlVG8oZmFtaWx5LCAwLCBmYW1pbHkubGVuZ3RoLCB0aGlzLmJ5dGVzLCBvLCBsKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIG1pbnVzIGl0cyBkZWxpbWl0ZXIKKyAgICogQHBhcmFtIGZhbWlseWxlbmd0aCBMZW5ndGggb2YgZmFtaWx5IGluIHBhc3NlZCA8Y29kZT5jb2x1bW48L2NvZGU+CisgICAqIEByZXR1cm4gVHJ1ZSBpZiBjb2x1bW4gbWF0Y2hlcy4KKyAgICogQHNlZSAjbWF0Y2hpbmdDb2x1bW4oYnl0ZVtdKQorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gbWF0Y2hpbmdDb2x1bW5Ob0RlbGltaXRlcihmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGZpbmFsIGludCBmYW1pbHlsZW5ndGgpIHsKKyAgICBpbnQgbyA9IGdldENvbHVtbk9mZnNldCgpOworICAgIGludCBsID0gZ2V0Q29sdW1uTGVuZ3RoKG8pOworICAgIGludCBmID0gZ2V0RmFtaWx5TGVuZ3RoKG8pOworICAgIHJldHVybiBjb21wYXJlQ29sdW1ucyhnZXRCdWZmZXIoKSwgbywgbCwgZiwKKyAgICAgIGNvbHVtbiwgMCwgY29sdW1uLmxlbmd0aCwgZmFtaWx5bGVuZ3RoKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb2x1bW4gQ29sdW1uIHdpdGggZGVsaW1pdGVyCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBjb2x1bW4gbWF0Y2hlcy4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIG1hdGNoaW5nQ29sdW1uKGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgaW50IGluZGV4ID0gZ2V0RmFtaWx5RGVsaW1pdGVySW5kZXgoY29sdW1uLCAwLCBjb2x1bW4ubGVuZ3RoKTsKKyAgICBpbnQgbyA9IGdldENvbHVtbk9mZnNldCgpOworICAgIGludCBsID0gZ2V0Q29sdW1uTGVuZ3RoKG8pOworICAgIGludCByZXN1bHQgPSBCeXRlcy5jb21wYXJlVG8oZ2V0QnVmZmVyKCksIG8sIGluZGV4LCBjb2x1bW4sIDAsIGluZGV4KTsKKyAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhnZXRCdWZmZXIoKSwgbyArIGluZGV4LCBsIC0gaW5kZXgsCisgICAgICBjb2x1bW4sIGluZGV4ICsgMSwgY29sdW1uLmxlbmd0aCAtIChpbmRleCArIDEpKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBsZWZ0CisgICAqIEBwYXJhbSBsb2Zmc2V0CisgICAqIEBwYXJhbSBsbGVuZ3RoCisgICAqIEBwYXJhbSBsZmFtaWx5bGVuZ3RoIE9mZnNldCBvZiBmYW1pbHkgZGVsaW1pdGVyIGluIGxlZnQgY29sdW1uLgorICAgKiBAcGFyYW0gcmlnaHQKKyAgICogQHBhcmFtIHJvZmZzZXQKKyAgICogQHBhcmFtIHJsZW5ndGgKKyAgICogQHBhcmFtIHJmYW1pbHlsZW5ndGggT2Zmc2V0IG9mIGZhbWlseSBkZWxpbWl0ZXIgaW4gcmlnaHQgY29sdW1uLgorICAgKiBAcmV0dXJuCisgICAqLworICBzdGF0aWMgaW50IGNvbXBhcmVDb2x1bW5zKGZpbmFsIGJ5dGUgW10gbGVmdCwgZmluYWwgaW50IGxvZmZzZXQsCisgICAgICBmaW5hbCBpbnQgbGxlbmd0aCwgZmluYWwgaW50IGxmYW1pbHlsZW5ndGgsCisgICAgICBmaW5hbCBieXRlIFtdIHJpZ2h0LCBmaW5hbCBpbnQgcm9mZnNldCwgZmluYWwgaW50IHJsZW5ndGgsCisgICAgICBmaW5hbCBpbnQgcmZhbWlseWxlbmd0aCkgeworICAgIC8vIENvbXBhcmUgZmFtaWx5IHBvcnRpb24gZmlyc3QuCisgICAgaW50IGRpZmYgPSBCeXRlcy5jb21wYXJlVG8obGVmdCwgbG9mZnNldCwgbGZhbWlseWxlbmd0aCwKKyAgICAgIHJpZ2h0LCByb2Zmc2V0LCByZmFtaWx5bGVuZ3RoKTsKKyAgICBpZiAoZGlmZiAhPSAwKSB7CisgICAgICByZXR1cm4gZGlmZjsKKyAgICB9CisgICAgLy8gQ29tcGFyZSBxdWFsaWZpZXIgcG9ydGlvbgorICAgIHJldHVybiBCeXRlcy5jb21wYXJlVG8obGVmdCwgbG9mZnNldCArIGxmYW1pbHlsZW5ndGgsCisgICAgICBsbGVuZ3RoIC0gbGZhbWlseWxlbmd0aCwKKyAgICAgIHJpZ2h0LCByb2Zmc2V0ICsgcmZhbWlseWxlbmd0aCwgcmxlbmd0aCAtIHJmYW1pbHlsZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBub24tbnVsbCByb3cgYW5kIGNvbHVtbi4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIG5vbk51bGxSb3dBbmRDb2x1bW4oKSB7CisgICAgcmV0dXJuIGdldFJvd0xlbmd0aCgpID4gMCAmJiAhaXNFbXB0eUNvbHVtbigpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmV0dXJucyBjb2x1bW4gU3RyaW5nIHdpdGggZGVsaW1pdGVyIGFkZGVkIGJhY2suIEV4cGVuc2l2ZSEKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0Q29sdW1uU3RyaW5nKCkgeworICAgIGludCBvID0gZ2V0Q29sdW1uT2Zmc2V0KCk7CisgICAgaW50IGwgPSBnZXRDb2x1bW5MZW5ndGgobyk7CisgICAgaW50IGZhbWlseWxlbmd0aCA9IGdldEZhbWlseUxlbmd0aChvKTsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcodGhpcy5ieXRlcywgbywgZmFtaWx5bGVuZ3RoKSArCisgICAgICBDT0xVTU5fRkFNSUxZX0RFTElNSVRFUiArIEJ5dGVzLnRvU3RyaW5nKHRoaXMuYnl0ZXMsCisgICAgICAgbyArIGZhbWlseWxlbmd0aCwgbCAtIGZhbWlseWxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogRG8gbm90IHVzZSB0aGlzIHVubGVzcyB5b3UgaGF2ZSB0by4KKyAgICogVXNlIHtAbGluayAjZ2V0QnVmZmVyKCl9IHdpdGggYXBwcm9wcmlhdGUgb2Zmc2V0cyBhbmQgbGVuZ3RocyBpbnN0ZWFkLgorICAgKiBAcmV0dXJuIFJldHVybnMgY29sdW1uLiBNYWtlcyBhIGNvcHkuICBJbnNlcnRzIGRlbGltaXRlci4KKyAgICovCisgIHB1YmxpYyBieXRlIFtdIGdldENvbHVtbigpIHsKKyAgICBpbnQgbyA9IGdldENvbHVtbk9mZnNldCgpOworICAgIGludCBsID0gZ2V0Q29sdW1uTGVuZ3RoKG8pOworICAgIGludCBmYW1pbHlsZW5ndGggPSBnZXRGYW1pbHlMZW5ndGgobyk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtsICsgMV07CisgICAgU3lzdGVtLmFycmF5Y29weShnZXRCdWZmZXIoKSwgbywgcmVzdWx0LCAwLCBmYW1pbHlsZW5ndGgpOworICAgIHJlc3VsdFtmYW1pbHlsZW5ndGhdID0gQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVI7CisgICAgU3lzdGVtLmFycmF5Y29weShnZXRCdWZmZXIoKSwgbyArIGZhbWlseWxlbmd0aCwgcmVzdWx0LAorICAgICAgZmFtaWx5bGVuZ3RoICsgMSwgbCAtIGZhbWlseWxlbmd0aCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRydWUgaWYgY29sdW1uIGlzIGVtcHR5LgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNFbXB0eUNvbHVtbigpIHsKKyAgICByZXR1cm4gZ2V0Q29sdW1uTGVuZ3RoKGdldENvbHVtbk9mZnNldCgpKSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEByZXR1cm4gSW5kZXggb2YgdGhlIGZhbWlseS1xdWFsaWZpZXIgY29sb24gZGVsaW1pdGVyIGNoYXJhY3RlciBpbiBwYXNzZWQKKyAgICogYnVmZmVyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgZ2V0RmFtaWx5RGVsaW1pdGVySW5kZXgoZmluYWwgYnl0ZSBbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgZmluYWwgaW50IGxlbmd0aCkgeworICAgIHJldHVybiBnZXRSZXF1aXJlZERlbGltaXRlcihiLCBvZmZzZXQsIGxlbmd0aCwgQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVIpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldFJlcXVpcmVkRGVsaW1pdGVyKGZpbmFsIGJ5dGUgW10gYiwKKyAgICAgIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgsIGZpbmFsIGludCBkZWxpbWl0ZXIpIHsKKyAgICBpbnQgaW5kZXggPSBnZXREZWxpbWl0ZXIoYiwgb2Zmc2V0LCBsZW5ndGgsIGRlbGltaXRlcik7CisgICAgaWYgKGluZGV4IDwgMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm8gIiArIChjaGFyKWRlbGltaXRlciArICIgaW4gPCIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhiKSArICI+IiArICIsIGxlbmd0aD0iICsgbGVuZ3RoICsgIiwgb2Zmc2V0PSIgKyBvZmZzZXQpOworICAgIH0KKyAgICByZXR1cm4gaW5kZXg7CisgIH0KKworICBzdGF0aWMgaW50IGdldFJlcXVpcmVkRGVsaW1pdGVySW5SZXZlcnNlKGZpbmFsIGJ5dGUgW10gYiwKKyAgICAgIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgsIGZpbmFsIGludCBkZWxpbWl0ZXIpIHsKKyAgICBpbnQgaW5kZXggPSBnZXREZWxpbWl0ZXJJblJldmVyc2UoYiwgb2Zmc2V0LCBsZW5ndGgsIGRlbGltaXRlcik7CisgICAgaWYgKGluZGV4IDwgMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm8gIiArIGRlbGltaXRlciArICIgaW4gPCIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhiKSArICI+IiArICIsIGxlbmd0aD0iICsgbGVuZ3RoICsgIiwgb2Zmc2V0PSIgKyBvZmZzZXQpOworICAgIH0KKyAgICByZXR1cm4gaW5kZXg7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gYgorICAgKiBAcGFyYW0gZGVsaW1pdGVyCisgICAqIEByZXR1cm4gSW5kZXggb2YgZGVsaW1pdGVyIGhhdmluZyBzdGFydGVkIGZyb20gZW5kIG9mIDxjb2RlPmI8L2NvZGU+IG1vdmluZworICAgKiBsZWZ0d2FyZC4KKyAgICovCisgIHN0YXRpYyBpbnQgZ2V0RGVsaW1pdGVyKGZpbmFsIGJ5dGUgW10gYiwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCwKKyAgICAgIGZpbmFsIGludCBkZWxpbWl0ZXIpIHsKKyAgICBpZiAoYiA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgaW50IHJlc3VsdCA9IC0xOworICAgIGZvciAoaW50IGkgPSBvZmZzZXQ7IGkgPCBsZW5ndGggKyBvZmZzZXQ7IGkrKykgeworICAgICAgaWYgKGJbaV0gPT0gZGVsaW1pdGVyKSB7CisgICAgICAgIHJlc3VsdCA9IGk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIGIKKyAgICogQHBhcmFtIGRlbGltaXRlcgorICAgKiBAcmV0dXJuIEluZGV4IG9mIGRlbGltaXRlcgorICAgKi8KKyAgc3RhdGljIGludCBnZXREZWxpbWl0ZXJJblJldmVyc2UoZmluYWwgYnl0ZSBbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LAorICAgICAgZmluYWwgaW50IGxlbmd0aCwgZmluYWwgaW50IGRlbGltaXRlcikgeworICAgIGlmIChiID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgZm9yIChpbnQgaSA9IChvZmZzZXQgKyBsZW5ndGgpIC0gMTsgaSA+PSBvZmZzZXQ7IGktLSkgeworICAgICAgaWYgKGJbaV0gPT0gZGVsaW1pdGVyKSB7CisgICAgICAgIHJlc3VsdCA9IGk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEEge0BsaW5rIEtWQ29tcGFyYXRvcn0gZm9yIDxjb2RlPi1ST09ULTwvY29kZT4gY2F0YWxvZyB0YWJsZQorICAgKiB7QGxpbmsgS2V5VmFsdWV9cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUm9vdENvbXBhcmF0b3IgZXh0ZW5kcyBNZXRhQ29tcGFyYXRvciB7CisgICAgcHJpdmF0ZSBmaW5hbCBLZXlDb21wYXJhdG9yIHJhd2NvbXBhcmF0b3IgPSBuZXcgUm9vdEtleUNvbXBhcmF0b3IoKTsKKyAgICAKKyAgICBwdWJsaWMgS2V5Q29tcGFyYXRvciBnZXRSYXdDb21wYXJhdG9yKCkgeworICAgICAgcmV0dXJuIHRoaXMucmF3Y29tcGFyYXRvcjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgT2JqZWN0IGNsb25lKCkgdGhyb3dzIENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBuZXcgUm9vdENvbXBhcmF0b3IoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQSB7QGxpbmsgS1ZDb21wYXJhdG9yfSBmb3IgPGNvZGU+Lk1FVEEuPC9jb2RlPiBjYXRhbG9nIHRhYmxlCisgICAqIHtAbGluayBLZXlWYWx1ZX1zLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBNZXRhQ29tcGFyYXRvciBleHRlbmRzIEtWQ29tcGFyYXRvciB7CisgICAgcHJpdmF0ZSBmaW5hbCBLZXlDb21wYXJhdG9yIHJhd2NvbXBhcmF0b3IgPSBuZXcgTWV0YUtleUNvbXBhcmF0b3IoKTsKKworICAgIHB1YmxpYyBLZXlDb21wYXJhdG9yIGdldFJhd0NvbXBhcmF0b3IoKSB7CisgICAgICByZXR1cm4gdGhpcy5yYXdjb21wYXJhdG9yOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgcmV0dXJuIG5ldyBNZXRhQ29tcGFyYXRvcigpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlIEtleVZhbHVlcy4gIFdoZW4gd2UgY29tcGFyZSBLZXlWYWx1ZXMsIHdlIG9ubHkgY29tcGFyZSB0aGUgS2V5CisgICAqIHBvcnRpb24uICBUaGlzIG1lYW5zIHR3byBLZXlWYWx1ZXMgd2l0aCBzYW1lIEtleSBidXQgZGlmZmVyZW50IFZhbHVlcyBhcmUKKyAgICogY29uc2lkZXJlZCB0aGUgc2FtZSBhcyBmYXIgYXMgdGhpcyBDb21wYXJhdG9yIGlzIGNvbmNlcm5lZC4KKyAgICogSG9zdHMgYSB7QGxpbmsgS2V5Q29tcGFyYXRvcn0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEtWQ29tcGFyYXRvciBpbXBsZW1lbnRzIGphdmEudXRpbC5Db21wYXJhdG9yPEtleVZhbHVlPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBLZXlDb21wYXJhdG9yIHJhd2NvbXBhcmF0b3IgPSBuZXcgS2V5Q29tcGFyYXRvcigpOworCisgICAgLyoqCisgICAgICogQHJldHVybiBSYXdDb21wYXJhdG9yIHRoYXQgY2FuIGNvbXBhcmUgdGhlIEtleSBwb3J0aW9uIG9mIGEgS2V5VmFsdWUuCisgICAgICogVXNlZCBpbiBoZmlsZSB3aGVyZSBpbmRpY2VzIGFyZSB0aGUgS2V5IHBvcnRpb24gb2YgYSBLZXlWYWx1ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgS2V5Q29tcGFyYXRvciBnZXRSYXdDb21wYXJhdG9yKCkgeworICAgICAgcmV0dXJuIHRoaXMucmF3Y29tcGFyYXRvcjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmUoZmluYWwgS2V5VmFsdWUgbGVmdCwgZmluYWwgS2V5VmFsdWUgcmlnaHQpIHsKKyAgICAgIHJldHVybiBnZXRSYXdDb21wYXJhdG9yKCkuY29tcGFyZShsZWZ0LmdldEJ1ZmZlcigpLAorICAgICAgICAgIGxlZnQuZ2V0T2Zmc2V0KCkgKyBST1dfT0ZGU0VULCBsZWZ0LmdldEtleUxlbmd0aCgpLAorICAgICAgICByaWdodC5nZXRCdWZmZXIoKSwgcmlnaHQuZ2V0T2Zmc2V0KCkgKyBST1dfT0ZGU0VULAorICAgICAgICAgIHJpZ2h0LmdldEtleUxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUaW1lc3RhbXBzKGZpbmFsIEtleVZhbHVlIGxlZnQsIGZpbmFsIEtleVZhbHVlIHJpZ2h0KSB7CisgICAgICByZXR1cm4gY29tcGFyZVRpbWVzdGFtcHMobGVmdCwgbGVmdC5nZXRLZXlMZW5ndGgoKSwgcmlnaHQsCisgICAgICAgIHJpZ2h0LmdldEtleUxlbmd0aCgpKTsKKyAgICB9CisKKyAgICBpbnQgY29tcGFyZVRpbWVzdGFtcHMoZmluYWwgS2V5VmFsdWUgbGVmdCwgZmluYWwgaW50IGxrZXlsZW5ndGgsCisgICAgICAgIGZpbmFsIEtleVZhbHVlIHJpZ2h0LCBmaW5hbCBpbnQgcmtleWxlbmd0aCkgeworICAgICAgLy8gQ29tcGFyZSB0aW1lc3RhbXBzCisgICAgICBsb25nIGx0aW1lc3RhbXAgPSBsZWZ0LmdldFRpbWVzdGFtcChsa2V5bGVuZ3RoKTsKKyAgICAgIGxvbmcgcnRpbWVzdGFtcCA9IHJpZ2h0LmdldFRpbWVzdGFtcChya2V5bGVuZ3RoKTsKKyAgICAgIHJldHVybiBnZXRSYXdDb21wYXJhdG9yKCkuY29tcGFyZVRpbWVzdGFtcHMobHRpbWVzdGFtcCwgcnRpbWVzdGFtcCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiBAcmV0dXJuIFJlc3VsdCBjb21wYXJpbmcgcm93cy4KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGNvbXBhcmVSb3dzKGZpbmFsIEtleVZhbHVlIGxlZnQsIGZpbmFsIEtleVZhbHVlIHJpZ2h0KSB7CisgICAgICByZXR1cm4gY29tcGFyZVJvd3MobGVmdCwgbGVmdC5nZXRSb3dMZW5ndGgoKSwgcmlnaHQsIHJpZ2h0LmdldFJvd0xlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqIEBwYXJhbSBscm93bGVuZ3RoIExlbmd0aCBvZiBsZWZ0IHJvdy4KKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiBAcGFyYW0gcnJvd2xlbmd0aCBMZW5ndGggb2YgcmlnaHQgcm93LgorICAgICAqIEByZXR1cm4gUmVzdWx0IGNvbXBhcmluZyByb3dzLgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoZmluYWwgS2V5VmFsdWUgbGVmdCwgZmluYWwgc2hvcnQgbHJvd2xlbmd0aCwKKyAgICAgICAgZmluYWwgS2V5VmFsdWUgcmlnaHQsIGZpbmFsIHNob3J0IHJyb3dsZW5ndGgpIHsKKyAgICAgIHJldHVybiBnZXRSYXdDb21wYXJhdG9yKCkuY29tcGFyZVJvd3MobGVmdC5nZXRCdWZmZXIoKSwKKyAgICAgICAgICBsZWZ0LmdldFJvd09mZnNldCgpLCBscm93bGVuZ3RoLAorICAgICAgICByaWdodC5nZXRCdWZmZXIoKSwgcmlnaHQuZ2V0Um93T2Zmc2V0KCksIHJyb3dsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBsZWZ0CisgICAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgICAqIEByZXR1cm4gUmF3Q29tcGFyYXRvcgorICAgICAqLworICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoZmluYWwgS2V5VmFsdWUgbGVmdCwgZmluYWwgYnl0ZSBbXSByb3cpIHsKKyAgICAgIHJldHVybiBnZXRSYXdDb21wYXJhdG9yKCkuY29tcGFyZVJvd3MobGVmdC5nZXRCdWZmZXIoKSwKKyAgICAgICAgICBsZWZ0LmdldFJvd09mZnNldCgpLCBsZWZ0LmdldFJvd0xlbmd0aCgpLCByb3csIDAsIHJvdy5sZW5ndGgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGUgW10gcmlnaHQsIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCkgeworICAgICAgcmV0dXJuIGdldFJhd0NvbXBhcmF0b3IoKS5jb21wYXJlUm93cyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLAorICAgICAgICByaWdodCwgcm9mZnNldCwgcmxlbmd0aCk7CisgICAgfQorCisgICAgcHVibGljIGludCBjb21wYXJlQ29sdW1ucyhmaW5hbCBLZXlWYWx1ZSBsZWZ0LCBmaW5hbCBieXRlIFtdIHJpZ2h0LAorICAgICAgICBmaW5hbCBpbnQgcm9mZnNldCwgZmluYWwgaW50IHJsZW5ndGgsIGZpbmFsIGludCByZmFtaWx5b2Zmc2V0KSB7CisgICAgICBpbnQgb2Zmc2V0ID0gbGVmdC5nZXRDb2x1bW5PZmZzZXQoKTsKKyAgICAgIGludCBsZW5ndGggPSBsZWZ0LmdldENvbHVtbkxlbmd0aChvZmZzZXQpOworICAgICAgcmV0dXJuIGdldFJhd0NvbXBhcmF0b3IoKS5jb21wYXJlQ29sdW1ucyhsZWZ0LmdldEJ1ZmZlcigpLCBvZmZzZXQsIGxlbmd0aCwKKyAgICAgICAgbGVmdC5nZXRGYW1pbHlMZW5ndGgob2Zmc2V0KSwKKyAgICAgICAgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgsIHJmYW1pbHlvZmZzZXQpOworICAgIH0KKworICAgIGludCBjb21wYXJlQ29sdW1ucyhmaW5hbCBLZXlWYWx1ZSBsZWZ0LCBmaW5hbCBzaG9ydCBscm93bGVuZ3RoLAorICAgICAgICBmaW5hbCBpbnQgbGtleWxlbmd0aCwgZmluYWwgS2V5VmFsdWUgcmlnaHQsIGZpbmFsIHNob3J0IHJyb3dsZW5ndGgsCisgICAgICAgIGZpbmFsIGludCBya2V5bGVuZ3RoKSB7CisgICAgICBpbnQgbG9mZnNldCA9IGxlZnQuZ2V0Q29sdW1uT2Zmc2V0KGxyb3dsZW5ndGgpOworICAgICAgaW50IHJvZmZzZXQgPSByaWdodC5nZXRDb2x1bW5PZmZzZXQocnJvd2xlbmd0aCk7CisgICAgICBpbnQgbGxlbmd0aCA9IGxlZnQuZ2V0Q29sdW1uTGVuZ3RoKGxvZmZzZXQsIGxrZXlsZW5ndGgpOworICAgICAgaW50IHJsZW5ndGggPSByaWdodC5nZXRDb2x1bW5MZW5ndGgocm9mZnNldCwgcmtleWxlbmd0aCk7CisgICAgICBpbnQgbGZhbWlseWxlbmd0aCA9IGxlZnQuZ2V0RmFtaWx5TGVuZ3RoKGxvZmZzZXQpOworICAgICAgaW50IHJmYW1pbHlsZW5ndGggPSByaWdodC5nZXRGYW1pbHlMZW5ndGgocm9mZnNldCk7CisgICAgICByZXR1cm4gZ2V0UmF3Q29tcGFyYXRvcigpLmNvbXBhcmVDb2x1bW5zKGxlZnQuZ2V0QnVmZmVyKCksIGxvZmZzZXQsCisgICAgICAgICAgbGxlbmd0aCwgbGZhbWlseWxlbmd0aCwKKyAgICAgICAgcmlnaHQuZ2V0QnVmZmVyKCksIHJvZmZzZXQsIHJsZW5ndGgsIHJmYW1pbHlsZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbXBhcmVzIHRoZSByb3cgYW5kIGNvbHVtbiBvZiB0d28ga2V5dmFsdWVzCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgc2FtZSByb3cgYW5kIGNvbHVtbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGluZ1Jvd0NvbHVtbihmaW5hbCBLZXlWYWx1ZSBsZWZ0LAorICAgICAgICBmaW5hbCBLZXlWYWx1ZSByaWdodCkgeworICAgICAgc2hvcnQgbHJvd2xlbmd0aCA9IGxlZnQuZ2V0Um93TGVuZ3RoKCk7CisgICAgICBzaG9ydCBycm93bGVuZ3RoID0gcmlnaHQuZ2V0Um93TGVuZ3RoKCk7CisgICAgICBpZiAoIW1hdGNoaW5nUm93cyhsZWZ0LCBscm93bGVuZ3RoLCByaWdodCwgcnJvd2xlbmd0aCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaW50IGxrZXlsZW5ndGggPSBsZWZ0LmdldEtleUxlbmd0aCgpOworICAgICAgaW50IHJrZXlsZW5ndGggPSByaWdodC5nZXRLZXlMZW5ndGgoKTsKKyAgICAgIHJldHVybiBjb21wYXJlQ29sdW1ucyhsZWZ0LCBscm93bGVuZ3RoLCBsa2V5bGVuZ3RoLAorICAgICAgICByaWdodCwgcnJvd2xlbmd0aCwgcmtleWxlbmd0aCkgPT0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbGVmdAorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqIEByZXR1cm4gVHJ1ZSBpZiByb3dzIG1hdGNoLgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hdGNoaW5nUm93cyhmaW5hbCBLZXlWYWx1ZSBsZWZ0LCBmaW5hbCBieXRlIFtdIHJpZ2h0KSB7CisgICAgICByZXR1cm4gY29tcGFyZVJvd3MobGVmdCwgcmlnaHQpID09IDA7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiBAcGFyYW0gcmlnaHQKKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgcm93cyBtYXRjaC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGluZ1Jvd3MoZmluYWwgS2V5VmFsdWUgbGVmdCwgZmluYWwgS2V5VmFsdWUgcmlnaHQpIHsKKyAgICAgIHNob3J0IGxyb3dsZW5ndGggPSBsZWZ0LmdldFJvd0xlbmd0aCgpOworICAgICAgc2hvcnQgcnJvd2xlbmd0aCA9IHJpZ2h0LmdldFJvd0xlbmd0aCgpOworICAgICAgcmV0dXJuIG1hdGNoaW5nUm93cyhsZWZ0LCBscm93bGVuZ3RoLCByaWdodCwgcnJvd2xlbmd0aCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGxlZnQKKyAgICAgKiBAcGFyYW0gbHJvd2xlbmd0aAorICAgICAqIEBwYXJhbSByaWdodAorICAgICAqIEBwYXJhbSBycm93bGVuZ3RoCisgICAgICogQHJldHVybiBUcnVlIGlmIHJvd3MgbWF0Y2guCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hpbmdSb3dzKGZpbmFsIEtleVZhbHVlIGxlZnQsIGZpbmFsIHNob3J0IGxyb3dsZW5ndGgsCisgICAgICAgIGZpbmFsIEtleVZhbHVlIHJpZ2h0LCBmaW5hbCBzaG9ydCBycm93bGVuZ3RoKSB7CisgICAgICBpbnQgY29tcGFyZSA9IGNvbXBhcmVSb3dzKGxlZnQsIGxyb3dsZW5ndGgsIHJpZ2h0LCBycm93bGVuZ3RoKTsKKyAgICAgIGlmIChjb21wYXJlICE9IDApIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hpbmdSb3dzKGZpbmFsIGJ5dGUgW10gbGVmdCwgZmluYWwgaW50IGxvZmZzZXQsCisgICAgICAgIGZpbmFsIGludCBsbGVuZ3RoLAorICAgICAgICBmaW5hbCBieXRlIFtdIHJpZ2h0LCBmaW5hbCBpbnQgcm9mZnNldCwgZmluYWwgaW50IHJsZW5ndGgpIHsKKyAgICAgIGludCBjb21wYXJlID0gY29tcGFyZVJvd3MobGVmdCwgbG9mZnNldCwgbGxlbmd0aCwgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgpOworICAgICAgaWYgKGNvbXBhcmUgIT0gMCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb21wYXJlcyB0aGUgcm93IGFuZCB0aW1lc3RhbXAgb2YgdHdvIGtleXMKKyAgICAgKiBXYXMgY2FsbGVkIG1hdGNoZXNXaXRob3V0Q29sdW1uIGluIEhTdG9yZUtleS4KKyAgICAgKiBAcGFyYW0gcmlnaHQgS2V5IHRvIGNvbXBhcmUgYWdhaW5zdC4KKyAgICAgKiBAcmV0dXJuIFRydWUgaWYgc2FtZSByb3cgYW5kIHRpbWVzdGFtcCBpcyBncmVhdGVyIHRoYW4gdGhlIHRpbWVzdGFtcCBpbgorICAgICAqIDxjb2RlPnJpZ2h0PC9jb2RlPgorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIG1hdGNoaW5nUm93c0dyZWF0ZXJUaW1lc3RhbXAoZmluYWwgS2V5VmFsdWUgbGVmdCwKKyAgICAgICAgZmluYWwgS2V5VmFsdWUgcmlnaHQpIHsKKyAgICAgIHNob3J0IGxyb3dsZW5ndGggPSBsZWZ0LmdldFJvd0xlbmd0aCgpOworICAgICAgc2hvcnQgcnJvd2xlbmd0aCA9IHJpZ2h0LmdldFJvd0xlbmd0aCgpOworICAgICAgaWYgKCFtYXRjaGluZ1Jvd3MobGVmdCwgbHJvd2xlbmd0aCwgcmlnaHQsIHJyb3dsZW5ndGgpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBsZWZ0LmdldFRpbWVzdGFtcCgpID49IHJpZ2h0LmdldFRpbWVzdGFtcCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBPYmplY3QgY2xvbmUoKSB0aHJvd3MgQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24geworICAgICAgcmV0dXJuIG5ldyBLVkNvbXBhcmF0b3IoKTsKKyAgICB9CisgCisgICAgLyoqCisgICAgICogQHJldHVybiBDb21wYXJhdG9yIHRoYXQgaWdub3JlcyB0aW1lc3RhbXBzOyB1c2VmdWwgY291bnRpbmcgdmVyc2lvbnMuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBLVkNvbXBhcmF0b3IgZ2V0Q29tcGFyYXRvcklnbm9yaW5nVGltZXN0YW1wcygpIHsKKyAgICAgIEtWQ29tcGFyYXRvciBjID0gbnVsbDsKKyAgICAgIHRyeSB7CisgICAgICAgIGMgPSAoS1ZDb21wYXJhdG9yKXRoaXMuY2xvbmUoKTsKKyAgICAgICAgYy5nZXRSYXdDb21wYXJhdG9yKCkuaWdub3JlVGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIH0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLmVycm9yKCJOb3Qgc3VwcG9ydGVkIiwgZSk7CisgICAgICB9CisgICAgICByZXR1cm4gYzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIENvbXBhcmF0b3IgdGhhdCBpZ25vcmVzIGtleSB0eXBlOyB1c2VmdWwgY2hlY2tpbmcgZGVsZXRlcworICAgICAqLworICAgIHB1YmxpYyBLVkNvbXBhcmF0b3IgZ2V0Q29tcGFyYXRvcklnbm9yaW5nVHlwZSgpIHsKKyAgICAgIEtWQ29tcGFyYXRvciBjID0gbnVsbDsKKyAgICAgIHRyeSB7CisgICAgICAgIGMgPSAoS1ZDb21wYXJhdG9yKXRoaXMuY2xvbmUoKTsKKyAgICAgICAgYy5nZXRSYXdDb21wYXJhdG9yKCkuaWdub3JlVHlwZSA9IHRydWU7CisgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiTm90IHN1cHBvcnRlZCIsIGUpOworICAgICAgfQorICAgICAgcmV0dXJuIGM7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHJldHVybiBGaXJzdCBwb3NzaWJsZSBLZXlWYWx1ZSBvbiBwYXNzZWQgPGNvZGU+cm93PC9jb2RlPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBLZXlWYWx1ZSBjcmVhdGVGaXJzdE9uUm93KGZpbmFsIGJ5dGUgW10gcm93KSB7CisgICAgcmV0dXJuIGNyZWF0ZUZpcnN0T25Sb3cocm93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByb3cgLSByb3cga2V5IChhcmJpdHJhcnkgYnl0ZSBhcnJheSkKKyAgICogQHBhcmFtIHRzIC0gdGltZXN0YW1wCisgICAqIEByZXR1cm4gRmlyc3QgcG9zc2libGUga2V5IG9uIHBhc3NlZCA8Y29kZT5yb3c8L2NvZGU+IGFuZCB0aW1lc3RhbXAuCisgICAqLworICBwdWJsaWMgc3RhdGljIEtleVZhbHVlIGNyZWF0ZUZpcnN0T25Sb3coZmluYWwgYnl0ZSBbXSByb3csCisgICAgICBmaW5hbCBsb25nIHRzKSB7CisgICAgcmV0dXJuIGNyZWF0ZUZpcnN0T25Sb3cocm93LCBudWxsLCB0cyk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkgKGFyYml0cmFyeSBieXRlIGFycmF5KQorICAgKiBAcGFyYW0gdHMgLSB0aW1lc3RhbXAKKyAgICogQHJldHVybiBGaXJzdCBwb3NzaWJsZSBrZXkgb24gcGFzc2VkIDxjb2RlPnJvdzwvY29kZT4sIGNvbHVtbiBhbmQgdGltZXN0YW1wLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBLZXlWYWx1ZSBjcmVhdGVGaXJzdE9uUm93KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGMsCisgICAgICBmaW5hbCBsb25nIHRzKSB7CisgICAgcmV0dXJuIG5ldyBLZXlWYWx1ZShyb3csIGMsIHRzLCBUeXBlLk1heGltdW0pOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEBwYXJhbSBvCisgICAqIEBwYXJhbSBsCisgICAqIEByZXR1cm4gQSBLZXlWYWx1ZSBtYWRlIG9mIGEgYnl0ZSBhcnJheSB0aGF0IGhvbGRzIHRoZSBrZXktb25seSBwYXJ0LgorICAgKiBOZWVkZWQgdG8gY29udmVydCBoZmlsZSBpbmRleCBtZW1iZXJzIHRvIEtleVZhbHVlcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgS2V5VmFsdWUgY3JlYXRlS2V5VmFsdWVGcm9tS2V5KGZpbmFsIGJ5dGUgW10gYiwgZmluYWwgaW50IG8sCisgICAgICBmaW5hbCBpbnQgbCkgeworICAgIGJ5dGUgW10gbmV3YiA9IG5ldyBieXRlW2IubGVuZ3RoICsgUk9XX09GRlNFVF07CisgICAgU3lzdGVtLmFycmF5Y29weShiLCBvLCBuZXdiLCBST1dfT0ZGU0VULCBsKTsKKyAgICBCeXRlcy5wdXRJbnQobmV3YiwgMCwgYi5sZW5ndGgpOworICAgIEJ5dGVzLnB1dEludChuZXdiLCBCeXRlcy5TSVpFT0ZfSU5ULCAwKTsKKyAgICByZXR1cm4gbmV3IEtleVZhbHVlKG5ld2IpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhcmUga2V5IHBvcnRpb24gb2YgYSB7QGxpbmsgS2V5VmFsdWV9IGZvciBrZXlzIGluIDxjb2RlPi1ST09ULTxjb2RlPgorICAgKiB0YWJsZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUm9vdEtleUNvbXBhcmF0b3IgZXh0ZW5kcyBNZXRhS2V5Q29tcGFyYXRvciB7CisgICAgcHVibGljIGludCBjb21wYXJlUm93cyhieXRlIFtdIGxlZnQsIGludCBsb2Zmc2V0LCBpbnQgbGxlbmd0aCwKKyAgICAgICAgYnl0ZSBbXSByaWdodCwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgICAvLyBSb3dzIGxvb2sgbGlrZSB0aGlzOiAuTUVUQS4sUk9XX0ZST01fTUVUQSxSSUQKKyAgICAgIC8vICAgICAgICBMT0cuaW5mbygiUk9PVCAiICsgQnl0ZXMudG9TdHJpbmcobGVmdCwgbG9mZnNldCwgbGxlbmd0aCkgKworICAgICAgLy8gICAgICAgICAgIi0tLSIgKyBCeXRlcy50b1N0cmluZyhyaWdodCwgcm9mZnNldCwgcmxlbmd0aCkpOworICAgICAgZmluYWwgaW50IG1ldGFsZW5ndGggPSA3OyAvLyAnLk1FVEEuJyBsZW5ndGgKKyAgICAgIGludCBsbWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIgPSBsb2Zmc2V0ICsgbWV0YWxlbmd0aDsKKyAgICAgIGludCBsZWZ0RmFyRGVsaW1pdGVyID0gZ2V0RGVsaW1pdGVySW5SZXZlcnNlKGxlZnQsIGxtZXRhT2Zmc2V0UGx1c0RlbGltaXRlciwKKyAgICAgICAgICBsbGVuZ3RoIC0gbWV0YWxlbmd0aCwgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICAgIGludCBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIgPSByb2Zmc2V0ICsgbWV0YWxlbmd0aDsKKyAgICAgIGludCByaWdodEZhckRlbGltaXRlciA9IGdldERlbGltaXRlckluUmV2ZXJzZShyaWdodCwKKyAgICAgICAgICBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsIHJsZW5ndGggLSBtZXRhbGVuZ3RoLAorICAgICAgICAgIEhSZWdpb25JbmZvLkRFTElNSVRFUik7CisgICAgICBpZiAobGVmdEZhckRlbGltaXRlciA8IDAgJiYgcmlnaHRGYXJEZWxpbWl0ZXIgPj0gMCkgeworICAgICAgICAvLyBOb3RoaW5nIGJldHdlZW4gLk1FVEEuIGFuZCByZWdpb25pZC4gIEl0cyBmaXJzdCBrZXkuCisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0gZWxzZSBpZiAocmlnaHRGYXJEZWxpbWl0ZXIgPCAwICYmIGxlZnRGYXJEZWxpbWl0ZXIgPj0gMCkgeworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0gZWxzZSBpZiAobGVmdEZhckRlbGltaXRlciA8IDAgJiYgcmlnaHRGYXJEZWxpbWl0ZXIgPCAwKSB7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgaW50IHJlc3VsdCA9IHN1cGVyLmNvbXBhcmVSb3dzKGxlZnQsIGxtZXRhT2Zmc2V0UGx1c0RlbGltaXRlciwKKyAgICAgICAgICBsZWZ0RmFyRGVsaW1pdGVyIC0gbG1ldGFPZmZzZXRQbHVzRGVsaW1pdGVyLAorICAgICAgICAgIHJpZ2h0LCBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIsCisgICAgICAgICAgcmlnaHRGYXJEZWxpbWl0ZXIgLSBybWV0YU9mZnNldFBsdXNEZWxpbWl0ZXIpOworICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9CisgICAgICAvLyBDb21wYXJlIGxhc3QgcGFydCBvZiByb3csIHRoZSByb3dpZC4KKyAgICAgIGxlZnRGYXJEZWxpbWl0ZXIrKzsKKyAgICAgIHJpZ2h0RmFyRGVsaW1pdGVyKys7CisgICAgICByZXN1bHQgPSBjb21wYXJlUm93aWQobGVmdCwgbGVmdEZhckRlbGltaXRlciwKKyAgICAgICAgICBsbGVuZ3RoIC0gKGxlZnRGYXJEZWxpbWl0ZXIgLSBsb2Zmc2V0KSwKKyAgICAgICAgICByaWdodCwgcmlnaHRGYXJEZWxpbWl0ZXIsIHJsZW5ndGggLSAocmlnaHRGYXJEZWxpbWl0ZXIgLSByb2Zmc2V0KSk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wYXJlIGtleSBwb3J0aW9uIG9mIGEge0BsaW5rIEtleVZhbHVlfSBmb3Iga2V5cyBpbiA8Y29kZT4uTUVUQS48L2NvZGU+CisgICAqIHRhYmxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBNZXRhS2V5Q29tcGFyYXRvciBleHRlbmRzIEtleUNvbXBhcmF0b3IgeworICAgIHB1YmxpYyBpbnQgY29tcGFyZVJvd3MoYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGUgW10gcmlnaHQsIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCkgeworICAgICAgLy8gICAgICAgIExPRy5pbmZvKCJNRVRBICIgKyBCeXRlcy50b1N0cmluZyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoKSArCisgICAgICAvLyAgICAgICAgICAiLS0tIiArIEJ5dGVzLnRvU3RyaW5nKHJpZ2h0LCByb2Zmc2V0LCBybGVuZ3RoKSk7CisgICAgICBpbnQgbGVmdERlbGltaXRlciA9IGdldERlbGltaXRlcihsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLAorICAgICAgICAgIEhSZWdpb25JbmZvLkRFTElNSVRFUik7CisgICAgICBpbnQgcmlnaHREZWxpbWl0ZXIgPSBnZXREZWxpbWl0ZXIocmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgsCisgICAgICAgICAgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICAgIGlmIChsZWZ0RGVsaW1pdGVyIDwgMCAmJiByaWdodERlbGltaXRlciA+PSAwKSB7CisgICAgICAgIC8vIE5vdGhpbmcgYmV0d2VlbiAuTUVUQS4gYW5kIHJlZ2lvbmlkLiAgSXRzIGZpcnN0IGtleS4KKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfSBlbHNlIGlmIChyaWdodERlbGltaXRlciA8IDAgJiYgbGVmdERlbGltaXRlciA+PSAwKSB7CisgICAgICAgIHJldHVybiAxOworICAgICAgfSBlbHNlIGlmIChsZWZ0RGVsaW1pdGVyIDwgMCAmJiByaWdodERlbGltaXRlciA8IDApIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICB9CisgICAgICAvLyBDb21wYXJlIHVwIHRvIHRoZSBkZWxpbWl0ZXIKKyAgICAgIGludCByZXN1bHQgPSBCeXRlcy5jb21wYXJlVG8obGVmdCwgbG9mZnNldCwgbGVmdERlbGltaXRlciAtIGxvZmZzZXQsCisgICAgICAgICAgcmlnaHQsIHJvZmZzZXQsIHJpZ2h0RGVsaW1pdGVyIC0gcm9mZnNldCk7CisgICAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKyAgICAgIC8vIENvbXBhcmUgbWlkZGxlIGJpdCBvZiB0aGUgcm93LgorICAgICAgLy8gTW92ZSBwYXN0IGRlbGltaXRlcgorICAgICAgbGVmdERlbGltaXRlcisrOworICAgICAgcmlnaHREZWxpbWl0ZXIrKzsKKyAgICAgIGludCBsZWZ0RmFyRGVsaW1pdGVyID0gZ2V0UmVxdWlyZWREZWxpbWl0ZXJJblJldmVyc2UobGVmdCwgbGVmdERlbGltaXRlciwKKyAgICAgICAgICBsbGVuZ3RoIC0gKGxlZnREZWxpbWl0ZXIgLSBsb2Zmc2V0KSwgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICAgIGludCByaWdodEZhckRlbGltaXRlciA9IGdldFJlcXVpcmVkRGVsaW1pdGVySW5SZXZlcnNlKHJpZ2h0LAorICAgICAgICAgIHJpZ2h0RGVsaW1pdGVyLCBybGVuZ3RoIC0gKHJpZ2h0RGVsaW1pdGVyIC0gcm9mZnNldCksCisgICAgICAgICAgSFJlZ2lvbkluZm8uREVMSU1JVEVSKTsKKyAgICAgIC8vIE5vdyBjb21wYXJlIG1pZGRsZXNlY3Rpb24gb2Ygcm93LgorICAgICAgcmVzdWx0ID0gc3VwZXIuY29tcGFyZVJvd3MobGVmdCwgbGVmdERlbGltaXRlciwKKyAgICAgICAgICBsZWZ0RmFyRGVsaW1pdGVyIC0gbGVmdERlbGltaXRlciwgcmlnaHQsIHJpZ2h0RGVsaW1pdGVyLAorICAgICAgICAgIHJpZ2h0RmFyRGVsaW1pdGVyIC0gcmlnaHREZWxpbWl0ZXIpOworICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICB9CisgICAgICAvLyBDb21wYXJlIGxhc3QgcGFydCBvZiByb3csIHRoZSByb3dpZC4KKyAgICAgIGxlZnRGYXJEZWxpbWl0ZXIrKzsKKyAgICAgIHJpZ2h0RmFyRGVsaW1pdGVyKys7CisgICAgICByZXN1bHQgPSBjb21wYXJlUm93aWQobGVmdCwgbGVmdEZhckRlbGltaXRlciwKKyAgICAgICAgICBsbGVuZ3RoIC0gKGxlZnRGYXJEZWxpbWl0ZXIgLSBsb2Zmc2V0KSwKKyAgICAgICAgICByaWdodCwgcmlnaHRGYXJEZWxpbWl0ZXIsIHJsZW5ndGggLSAocmlnaHRGYXJEZWxpbWl0ZXIgLSByb2Zmc2V0KSk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgY29tcGFyZVJvd2lkKGJ5dGVbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGVbXSByaWdodCwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKGxlZnQsIGxvZmZzZXQsIGxsZW5ndGgsIHJpZ2h0LCByb2Zmc2V0LCBybGVuZ3RoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29tcGFyZSBrZXkgcG9ydGlvbiBvZiBhIHtAbGluayBLZXlWYWx1ZX0uCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEtleUNvbXBhcmF0b3IgaW1wbGVtZW50cyBSYXdDb21wYXJhdG9yPGJ5dGUgW10+IHsKKyAgICB2b2xhdGlsZSBib29sZWFuIGlnbm9yZVRpbWVzdGFtcCA9IGZhbHNlOworICAgIHZvbGF0aWxlIGJvb2xlYW4gaWdub3JlVHlwZSA9IGZhbHNlOworCisgICAgcHVibGljIGludCBjb21wYXJlKGJ5dGVbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsIGJ5dGVbXSByaWdodCwKKyAgICAgICAgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoKSB7CisgICAgICAvLyBDb21wYXJlIHJvdworICAgICAgc2hvcnQgbHJvd2xlbmd0aCA9IEJ5dGVzLnRvU2hvcnQobGVmdCwgbG9mZnNldCk7CisgICAgICBzaG9ydCBycm93bGVuZ3RoID0gQnl0ZXMudG9TaG9ydChyaWdodCwgcm9mZnNldCk7CisgICAgICBpbnQgY29tcGFyZSA9IGNvbXBhcmVSb3dzKGxlZnQsIGxvZmZzZXQgKyBCeXRlcy5TSVpFT0ZfU0hPUlQsCisgICAgICAgICAgbHJvd2xlbmd0aCwKKyAgICAgICAgICByaWdodCwgcm9mZnNldCArIEJ5dGVzLlNJWkVPRl9TSE9SVCwgcnJvd2xlbmd0aCk7CisgICAgICBpZiAoY29tcGFyZSAhPSAwKSB7CisgICAgICAgIHJldHVybiBjb21wYXJlOworICAgICAgfQorCisgICAgICAvLyBDb21wYXJlIGNvbHVtbiBmYW1pbHkuICBTdGFydCBjb21wYXJlIHBhc3Qgcm93IGFuZCBmYW1pbHkgbGVuZ3RoLgorICAgICAgaW50IGxjb2x1bW5vZmZzZXQgPSBCeXRlcy5TSVpFT0ZfU0hPUlQgKyBscm93bGVuZ3RoICsgMSArIGxvZmZzZXQ7CisgICAgICBpbnQgcmNvbHVtbm9mZnNldCA9IEJ5dGVzLlNJWkVPRl9TSE9SVCArIHJyb3dsZW5ndGggKyAxICsgcm9mZnNldDsKKyAgICAgIGludCBsY29sdW1ubGVuZ3RoID0gbGxlbmd0aCAtIFRJTUVTVEFNUF9UWVBFX1NJWkUgLQorICAgICAgICAobGNvbHVtbm9mZnNldCAtIGxvZmZzZXQpOworICAgICAgaW50IHJjb2x1bW5sZW5ndGggPSBybGVuZ3RoIC0gVElNRVNUQU1QX1RZUEVfU0laRSAtCisgICAgICAgIChyY29sdW1ub2Zmc2V0IC0gcm9mZnNldCk7CisgICAgICBjb21wYXJlID0gQnl0ZXMuY29tcGFyZVRvKGxlZnQsIGxjb2x1bW5vZmZzZXQsIGxjb2x1bW5sZW5ndGgsIHJpZ2h0LAorICAgICAgICAgIHJjb2x1bW5vZmZzZXQsIHJjb2x1bW5sZW5ndGgpOworICAgICAgaWYgKGNvbXBhcmUgIT0gMCkgeworICAgICAgICByZXR1cm4gY29tcGFyZTsKKyAgICAgIH0KKworICAgICAgaWYgKCF0aGlzLmlnbm9yZVRpbWVzdGFtcCkgeworICAgICAgICAvLyBHZXQgdGltZXN0YW1wcy4KKyAgICAgICAgbG9uZyBsdGltZXN0YW1wID0gQnl0ZXMudG9Mb25nKGxlZnQsCisgICAgICAgICAgICBsb2Zmc2V0ICsgKGxsZW5ndGggLSBUSU1FU1RBTVBfVFlQRV9TSVpFKSk7CisgICAgICAgIGxvbmcgcnRpbWVzdGFtcCA9IEJ5dGVzLnRvTG9uZyhyaWdodCwKKyAgICAgICAgICAgIHJvZmZzZXQgKyAocmxlbmd0aCAtIFRJTUVTVEFNUF9UWVBFX1NJWkUpKTsKKyAgICAgICAgY29tcGFyZSA9IGNvbXBhcmVUaW1lc3RhbXBzKGx0aW1lc3RhbXAsIHJ0aW1lc3RhbXApOworICAgICAgICBpZiAoY29tcGFyZSAhPSAwKSB7CisgICAgICAgICAgcmV0dXJuIGNvbXBhcmU7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgaWYgKCF0aGlzLmlnbm9yZVR5cGUpIHsKKyAgICAgICAgLy8gQ29tcGFyZSB0eXBlcy4gTGV0IHRoZSBkZWxldGUgdHlwZXMgc29ydCBhaGVhZCBvZiBwdXRzOyBpLmUuIHR5cGVzCisgICAgICAgIC8vIG9mIGhpZ2hlciBudW1iZXJzIHNvcnQgYmVmb3JlIHRob3NlIG9mIGxlc3NlciBudW1iZXJzCisgICAgICAgIGJ5dGUgbHR5cGUgPSBsZWZ0W2xvZmZzZXQgKyAobGxlbmd0aCAtIDEpXTsKKyAgICAgICAgYnl0ZSBydHlwZSA9IHJpZ2h0W3JvZmZzZXQgKyAocmxlbmd0aCAtIDEpXTsKKyAgICAgICAgcmV0dXJuICgweGZmICYgcnR5cGUpIC0gKDB4ZmYgJiBsdHlwZSk7CisgICAgICB9CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmUoYnl0ZVtdIGxlZnQsIGJ5dGVbXSByaWdodCkgeworICAgICAgcmV0dXJuIGNvbXBhcmUobGVmdCwgMCwgbGVmdC5sZW5ndGgsIHJpZ2h0LCAwLCByaWdodC5sZW5ndGgpOworICAgIH0KKworICAgIHByb3RlY3RlZCBpbnQgY29tcGFyZVJvd3MoYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsCisgICAgICAgIGJ5dGUgW10gcmlnaHQsIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCkgeworICAgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhsZWZ0LCBsb2Zmc2V0LCBsbGVuZ3RoLCByaWdodCwgcm9mZnNldCwgcmxlbmd0aCk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIGludCBjb21wYXJlQ29sdW1ucygKKyAgICAgICAgYnl0ZSBbXSBsZWZ0LCBpbnQgbG9mZnNldCwgaW50IGxsZW5ndGgsIGZpbmFsIGludCBsZmFtaWx5bGVuZ3RoLAorICAgICAgICBieXRlIFtdIHJpZ2h0LCBpbnQgcm9mZnNldCwgaW50IHJsZW5ndGgsIGZpbmFsIGludCByZmFtaWx5bGVuZ3RoKSB7CisgICAgICByZXR1cm4gS2V5VmFsdWUuY29tcGFyZUNvbHVtbnMobGVmdCwgbG9mZnNldCwgbGxlbmd0aCwgbGZhbWlseWxlbmd0aCwKKyAgICAgICAgcmlnaHQsIHJvZmZzZXQsIHJsZW5ndGgsIHJmYW1pbHlsZW5ndGgpOworICAgIH0KKworICAgIGludCBjb21wYXJlVGltZXN0YW1wcyhmaW5hbCBsb25nIGx0aW1lc3RhbXAsIGZpbmFsIGxvbmcgcnRpbWVzdGFtcCkgeworICAgICAgLy8gVGhlIGJlbG93IG9sZGVyIHRpbWVzdGFtcHMgc29ydGluZyBhaGVhZCBvZiBuZXdlciB0aW1lc3RhbXBzIGxvb2tzCisgICAgICAvLyB3cm9uZyBidXQgaXQgaXMgaW50ZW50aW9uYWwuIFRoaXMgd2F5LCBuZXdlciB0aW1lc3RhbXBzIGFyZSBmaXJzdAorICAgICAgLy8gZm91bmQgd2hlbiB3ZSBpdGVyYXRlIG92ZXIgYSBtZW1jYWNoZSBhbmQgbmV3ZXIgdmVyc2lvbnMgYXJlIHRoZQorICAgICAgLy8gZmlyc3Qgd2UgdHJpcCBvdmVyIHdoZW4gcmVhZGluZyBmcm9tIGEgc3RvcmUgZmlsZS4KKyAgICAgIGlmIChsdGltZXN0YW1wIDwgcnRpbWVzdGFtcCkgeworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0gZWxzZSBpZiAobHRpbWVzdGFtcCA+IHJ0aW1lc3RhbXApIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfQorICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisgIAorICAvLyBIZWFwU2l6ZQorICBwdWJsaWMgbG9uZyBoZWFwU2l6ZSgpIHsKKyAgICByZXR1cm4gdGhpcy5sZW5ndGg7CisgIH0KKyAgCisgIC8vIFdyaXRhYmxlCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoZmluYWwgRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMubGVuZ3RoID0gaW4ucmVhZEludCgpOworICAgIHRoaXMub2Zmc2V0ID0gMDsKKyAgICB0aGlzLmJ5dGVzID0gbmV3IGJ5dGVbdGhpcy5sZW5ndGhdOworICAgIGluLnJlYWRGdWxseSh0aGlzLmJ5dGVzLCAwLCB0aGlzLmxlbmd0aCk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG91dC53cml0ZUludCh0aGlzLmxlbmd0aCk7CisgICAgb3V0LndyaXRlKHRoaXMuYnl0ZXMsIHRoaXMub2Zmc2V0LCB0aGlzLmxlbmd0aCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0xlYXNlRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9MZWFzZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0OGNjN2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9MZWFzZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworLyoqCisgKiBSZXBvcnRzIGEgcHJvYmxlbSB3aXRoIGEgbGVhc2UKKyAqLworcHVibGljIGNsYXNzIExlYXNlRXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4MTc5NzAzOTk1MjkyNDE4NjUwTDsKKworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgTGVhc2VFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbWVzc2FnZQorICAgKi8KKyAgcHVibGljIExlYXNlRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgc3VwZXIobWVzc2FnZSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9MZWFzZUxpc3RlbmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9MZWFzZUxpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTBhMzJlZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0xlYXNlTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKKworLyoqCisgKiBMZWFzZUxpc3RlbmVyIGlzIGFuIGludGVyZmFjZSBtZWFudCB0byBiZSBpbXBsZW1lbnRlZCBieSB1c2VycyBvZiB0aGUgTGVhc2VzIAorICogY2xhc3MuCisgKgorICogSXQgcmVjZWl2ZXMgZXZlbnRzIGZyb20gdGhlIExlYXNlcyBjbGFzcyBhYm91dCB0aGUgc3RhdHVzIG9mIGl0cyBhY2NvbXBhbnlpbmcKKyAqIGxlYXNlLiAgVXNlcnMgb2YgdGhlIExlYXNlcyBjbGFzcyBjYW4gdXNlIGEgTGVhc2VMaXN0ZW5lciBzdWJjbGFzcyB0bywgZm9yIAorICogZXhhbXBsZSwgY2xlYW4gdXAgcmVzb3VyY2VzIGFmdGVyIGEgbGVhc2UgaGFzIGV4cGlyZWQuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgTGVhc2VMaXN0ZW5lciB7CisgIC8qKiBXaGVuIGEgbGVhc2UgZXhwaXJlcywgdGhpcyBtZXRob2QgaXMgY2FsbGVkLiAqLworICBwdWJsaWMgdm9pZCBsZWFzZUV4cGlyZWQoKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0xlYXNlcy5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvTGVhc2VzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQwMDg2NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0xlYXNlcy5qYXZhCkBAIC0wLDAgKzEsMjcwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKKworaW1wb3J0IGphdmEudXRpbC5Db25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRGVsYXllZDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5EZWxheVF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBMZWFzZXMKKyAqCisgKiBUaGVyZSBhcmUgc2V2ZXJhbCBzZXJ2ZXIgY2xhc3NlcyBpbiBIQmFzZSB0aGF0IG5lZWQgdG8gdHJhY2sgZXh0ZXJuYWwKKyAqIGNsaWVudHMgdGhhdCBvY2Nhc2lvbmFsbHkgc2VuZCBoZWFydGJlYXRzLgorICogCisgKiA8cD5UaGVzZSBleHRlcm5hbCBjbGllbnRzIGhvbGQgcmVzb3VyY2VzIGluIHRoZSBzZXJ2ZXIgY2xhc3MuCisgKiBUaG9zZSByZXNvdXJjZXMgbmVlZCB0byBiZSByZWxlYXNlZCBpZiB0aGUgZXh0ZXJuYWwgY2xpZW50IGZhaWxzIHRvIHNlbmQgYQorICogaGVhcnRiZWF0IGFmdGVyIHNvbWUgaW50ZXJ2YWwgb2YgdGltZSBwYXNzZXMuCisgKgorICogPHA+VGhlIExlYXNlcyBjbGFzcyBpcyBhIGdlbmVyYWwgcmV1c2FibGUgY2xhc3MgZm9yIHRoaXMga2luZCBvZiBwYXR0ZXJuLgorICogQW4gaW5zdGFuY2Ugb2YgdGhlIExlYXNlcyBjbGFzcyB3aWxsIGNyZWF0ZSBhIHRocmVhZCB0byBkbyBpdHMgZGlydHkgd29yay4gIAorICogWW91IHNob3VsZCBjbG9zZSgpIHRoZSBpbnN0YW5jZSBpZiB5b3Ugd2FudCB0byBjbGVhbiB1cCB0aGUgdGhyZWFkIHByb3Blcmx5LgorICogCisgKiA8cD4KKyAqIE5PVEU6IFRoaXMgY2xhc3MgZXh0ZW5kcyBUaHJlYWQgcmF0aGVyIHRoYW4gQ2hvcmUgYmVjYXVzZSB0aGUgc2xlZXAgdGltZQorICogY2FuIGJlIGludGVycnVwdGVkIHdoZW4gdGhlcmUgaXMgc29tZXRoaW5nIHRvIGRvLCByYXRoZXIgdGhhbiB0aGUgQ2hvcmUKKyAqIHNsZWVwIHRpbWUgd2hpY2ggaXMgaW52YXJpYW50LgorICovCitwdWJsaWMgY2xhc3MgTGVhc2VzIGV4dGVuZHMgVGhyZWFkIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKExlYXNlcy5jbGFzcy5nZXROYW1lKCkpOworICBwcml2YXRlIGZpbmFsIGludCBsZWFzZVBlcmlvZDsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgbGVhc2VDaGVja0ZyZXF1ZW5jeTsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBEZWxheVF1ZXVlPExlYXNlPiBsZWFzZVF1ZXVlID0gbmV3IERlbGF5UXVldWU8TGVhc2U+KCk7CisgIHByb3RlY3RlZCBmaW5hbCBNYXA8U3RyaW5nLCBMZWFzZT4gbGVhc2VzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBMZWFzZT4oKTsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIHN0b3BSZXF1ZXN0ZWQgPSBmYWxzZTsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIGxlYXNlIG1vbml0b3IKKyAgICogCisgICAqIEBwYXJhbSBsZWFzZVBlcmlvZCAtIGxlbmd0aCBvZiB0aW1lIChtaWxsaXNlY29uZHMpIHRoYXQgdGhlIGxlYXNlIGlzIHZhbGlkCisgICAqIEBwYXJhbSBsZWFzZUNoZWNrRnJlcXVlbmN5IC0gaG93IG9mdGVuIHRoZSBsZWFzZSBzaG91bGQgYmUgY2hlY2tlZAorICAgKiAobWlsbGlzZWNvbmRzKQorICAgKi8KKyAgcHVibGljIExlYXNlcyhmaW5hbCBpbnQgbGVhc2VQZXJpb2QsIGZpbmFsIGludCBsZWFzZUNoZWNrRnJlcXVlbmN5KSB7CisgICAgdGhpcy5sZWFzZVBlcmlvZCA9IGxlYXNlUGVyaW9kOworICAgIHRoaXMubGVhc2VDaGVja0ZyZXF1ZW5jeSA9IGxlYXNlQ2hlY2tGcmVxdWVuY3k7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuVGhyZWFkI3J1bigpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcnVuKCkgeworICAgIHdoaWxlICghc3RvcFJlcXVlc3RlZCB8fCAoc3RvcFJlcXVlc3RlZCAmJiBsZWFzZVF1ZXVlLnNpemUoKSA+IDApICkgeworICAgICAgTGVhc2UgbGVhc2UgPSBudWxsOworICAgICAgdHJ5IHsKKyAgICAgICAgbGVhc2UgPSBsZWFzZVF1ZXVlLnBvbGwobGVhc2VDaGVja0ZyZXF1ZW5jeSwgVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9IGNhdGNoIChDb25jdXJyZW50TW9kaWZpY2F0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICBMT0cuZmF0YWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGtpbGxlZCBsZWFzZXMgdGhyZWFkIiwgZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKGxlYXNlID09IG51bGwpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICAvLyBBIGxlYXNlIGV4cGlyZWQuICBSdW4gdGhlIGV4cGlyZWQgY29kZSBiZWZvcmUgcmVtb3ZpbmcgZnJvbSBxdWV1ZQorICAgICAgLy8gc2luY2UgaXRzIHByZXNlbmNlIGluIHF1ZXVlIGlzIHVzZWQgdG8gc2VlIGlmIGxlYXNlIGV4aXN0cyBzdGlsbC4KKyAgICAgIGlmIChsZWFzZS5nZXRMaXN0ZW5lcigpID09IG51bGwpIHsKKyAgICAgICAgTE9HLmVycm9yKCJsZWFzZSBsaXN0ZW5lciBpcyBudWxsIGZvciBsZWFzZSAiICsgbGVhc2UuZ2V0TGVhc2VOYW1lKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgbGVhc2UuZ2V0TGlzdGVuZXIoKS5sZWFzZUV4cGlyZWQoKTsKKyAgICAgIH0KKyAgICAgIHN5bmNocm9uaXplZCAobGVhc2VRdWV1ZSkgeworICAgICAgICBsZWFzZXMucmVtb3ZlKGxlYXNlLmdldExlYXNlTmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgY2xvc2UoKTsKKyAgfQorCisgIC8qKgorICAgKiBTaHV0cyBkb3duIHRoaXMgbGVhc2UgaW5zdGFuY2Ugd2hlbiBhbGwgb3V0c3RhbmRpbmcgbGVhc2VzIGV4cGlyZS4KKyAgICogTGlrZSB7QGxpbmsgI2Nsb3NlKCl9IGJ1dCByYXRoZXIgdGhhbiB2aW9sZW50bHkgZW5kIGFsbCBsZWFzZXMsIHdhaXRzCisgICAqIGZpcnN0IG9uIGV4dGFudCBsZWFzZXMgdG8gZmluaXNoLiAgVXNlIHRoaXMgbWV0aG9kIGlmIHRoZSBsZWFzZSBob2xkZXJzCisgICAqIGNvdWxkIGxvb3NlIGRhdGEsIGxlYWsgbG9ja3MsIGV0Yy4gIFByZXN1bWVzIGNsaWVudCBoYXMgc2h1dGRvd24KKyAgICogYWxsb2NhdGlvbiBvZiBuZXcgbGVhc2VzLgorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2VBZnRlckxlYXNlc0V4cGlyZSgpIHsKKyAgICB0aGlzLnN0b3BSZXF1ZXN0ZWQgPSB0cnVlOworICB9CisgIAorICAvKioKKyAgICogU2h1dCBkb3duIHRoaXMgTGVhc2VzIGluc3RhbmNlLiAgQWxsIHBlbmRpbmcgbGVhc2VzIHdpbGwgYmUgZGVzdHJveWVkLCAKKyAgICogd2l0aG91dCBhbnkgY2FuY2VsbGF0aW9uIGNhbGxzLgorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgTE9HLmluZm8oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiIGNsb3NpbmcgbGVhc2VzIik7CisgICAgdGhpcy5zdG9wUmVxdWVzdGVkID0gdHJ1ZTsKKyAgICBzeW5jaHJvbml6ZWQgKGxlYXNlUXVldWUpIHsKKyAgICAgIGxlYXNlUXVldWUuY2xlYXIoKTsKKyAgICAgIGxlYXNlcy5jbGVhcigpOworICAgICAgbGVhc2VRdWV1ZS5ub3RpZnlBbGwoKTsKKyAgICB9CisgICAgTE9HLmluZm8oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiIGNsb3NlZCBsZWFzZXMiKTsKKyAgfQorCisgIC8qKgorICAgKiBPYnRhaW4gYSBsZWFzZQorICAgKiAKKyAgICogQHBhcmFtIGxlYXNlTmFtZSBuYW1lIG9mIHRoZSBsZWFzZQorICAgKiBAcGFyYW0gbGlzdGVuZXIgbGlzdGVuZXIgdGhhdCB3aWxsIHByb2Nlc3MgbGVhc2UgZXhwaXJhdGlvbnMKKyAgICogQHRocm93cyBMZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIGNyZWF0ZUxlYXNlKFN0cmluZyBsZWFzZU5hbWUsIGZpbmFsIExlYXNlTGlzdGVuZXIgbGlzdGVuZXIpCisgIHRocm93cyBMZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbiB7CisgICAgaWYgKHN0b3BSZXF1ZXN0ZWQpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgTGVhc2UgbGVhc2UgPSBuZXcgTGVhc2UobGVhc2VOYW1lLCBsaXN0ZW5lciwKKyAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyBsZWFzZVBlcmlvZCk7CisgICAgc3luY2hyb25pemVkIChsZWFzZVF1ZXVlKSB7CisgICAgICBpZiAobGVhc2VzLmNvbnRhaW5zS2V5KGxlYXNlTmFtZSkpIHsKKyAgICAgICAgdGhyb3cgbmV3IExlYXNlU3RpbGxIZWxkRXhjZXB0aW9uKGxlYXNlTmFtZSk7CisgICAgICB9CisgICAgICBsZWFzZXMucHV0KGxlYXNlTmFtZSwgbGVhc2UpOworICAgICAgbGVhc2VRdWV1ZS5hZGQobGVhc2UpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUaHJvd24gaWYgd2UgYXJlIGFza2VkIGNyZWF0ZSBhIGxlYXNlIGJ1dCBsZWFzZSBvbiBwYXNzZWQgbmFtZSBhbHJlYWR5CisgICAqIGV4aXN0cy4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQorICBwdWJsaWMgc3RhdGljIGNsYXNzIExlYXNlU3RpbGxIZWxkRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGxlYXNlTmFtZTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbmFtZQorICAgICAqLworICAgIHB1YmxpYyBMZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbihmaW5hbCBTdHJpbmcgbmFtZSkgeworICAgICAgdGhpcy5sZWFzZU5hbWUgPSBuYW1lOworICAgIH0KKyAgICAKKyAgICAvKiogQHJldHVybiBuYW1lIG9mIGxlYXNlICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMubGVhc2VOYW1lOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFJlbmV3IGEgbGVhc2UKKyAgICogCisgICAqIEBwYXJhbSBsZWFzZU5hbWUgbmFtZSBvZiBsZWFzZQorICAgKiBAdGhyb3dzIExlYXNlRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgcmVuZXdMZWFzZShmaW5hbCBTdHJpbmcgbGVhc2VOYW1lKSB0aHJvd3MgTGVhc2VFeGNlcHRpb24geworICAgIHN5bmNocm9uaXplZCAobGVhc2VRdWV1ZSkgeworICAgICAgTGVhc2UgbGVhc2UgPSBsZWFzZXMuZ2V0KGxlYXNlTmFtZSk7CisgICAgICBpZiAobGVhc2UgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTGVhc2VFeGNlcHRpb24oImxlYXNlICciICsgbGVhc2VOYW1lICsKKyAgICAgICAgICAgICInIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICB9CisgICAgICBsZWFzZVF1ZXVlLnJlbW92ZShsZWFzZSk7CisgICAgICBsZWFzZS5zZXRFeHBpcmF0aW9uVGltZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIGxlYXNlUGVyaW9kKTsKKyAgICAgIGxlYXNlUXVldWUuYWRkKGxlYXNlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ2xpZW50IGV4cGxpY2l0bHkgY2FuY2VscyBhIGxlYXNlLgorICAgKiAKKyAgICogQHBhcmFtIGxlYXNlTmFtZSBuYW1lIG9mIGxlYXNlCisgICAqIEB0aHJvd3MgTGVhc2VFeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCBjYW5jZWxMZWFzZShmaW5hbCBTdHJpbmcgbGVhc2VOYW1lKSB0aHJvd3MgTGVhc2VFeGNlcHRpb24geworICAgIHN5bmNocm9uaXplZCAobGVhc2VRdWV1ZSkgeworICAgICAgTGVhc2UgbGVhc2UgPSBsZWFzZXMucmVtb3ZlKGxlYXNlTmFtZSk7CisgICAgICBpZiAobGVhc2UgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTGVhc2VFeGNlcHRpb24oImxlYXNlICciICsgbGVhc2VOYW1lICsgIicgZG9lcyBub3QgZXhpc3QiKTsKKyAgICAgIH0KKyAgICAgIGxlYXNlUXVldWUucmVtb3ZlKGxlYXNlKTsKKyAgICB9CisgIH0KKworICAvKiogVGhpcyBjbGFzcyB0cmFja3MgYSBzaW5nbGUgTGVhc2UuICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIExlYXNlIGltcGxlbWVudHMgRGVsYXllZCB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbGVhc2VOYW1lOworICAgIHByaXZhdGUgZmluYWwgTGVhc2VMaXN0ZW5lciBsaXN0ZW5lcjsKKyAgICBwcml2YXRlIGxvbmcgZXhwaXJhdGlvblRpbWU7CisKKyAgICBMZWFzZShmaW5hbCBTdHJpbmcgbGVhc2VOYW1lLCBMZWFzZUxpc3RlbmVyIGxpc3RlbmVyLCBsb25nIGV4cGlyYXRpb25UaW1lKSB7CisgICAgICB0aGlzLmxlYXNlTmFtZSA9IGxlYXNlTmFtZTsKKyAgICAgIHRoaXMubGlzdGVuZXIgPSBsaXN0ZW5lcjsKKyAgICAgIHRoaXMuZXhwaXJhdGlvblRpbWUgPSBleHBpcmF0aW9uVGltZTsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiB0aGUgbGVhc2UgbmFtZSAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGVhc2VOYW1lKCkgeworICAgICAgcmV0dXJuIGxlYXNlTmFtZTsKKyAgICB9CisgICAgCisgICAgLyoqIEByZXR1cm4gbGlzdGVuZXIgKi8KKyAgICBwdWJsaWMgTGVhc2VMaXN0ZW5lciBnZXRMaXN0ZW5lcigpIHsKKyAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgICBpZiAodGhpcyA9PSBvYmopIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAob2JqID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaWYgKGdldENsYXNzKCkgIT0gb2JqLmdldENsYXNzKCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgcmV0dXJuIHRoaXMuaGFzaENvZGUoKSA9PSAoKExlYXNlKSBvYmopLmhhc2hDb2RlKCk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gdGhpcy5sZWFzZU5hbWUuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXREZWxheShUaW1lVW5pdCB1bml0KSB7CisgICAgICByZXR1cm4gdW5pdC5jb252ZXJ0KHRoaXMuZXhwaXJhdGlvblRpbWUgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAgICAgICAgICBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKERlbGF5ZWQgbykgeworICAgICAgbG9uZyBkZWx0YSA9IHRoaXMuZ2V0RGVsYXkoVGltZVVuaXQuTUlMTElTRUNPTkRTKSAtCisgICAgICAgIG8uZ2V0RGVsYXkoVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKworICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKG8pID8gMCA6IChkZWx0YSA+IDAgPyAxIDogLTEpOworICAgIH0KKworICAgIC8qKiBAcGFyYW0gZXhwaXJhdGlvblRpbWUgdGhlIGV4cGlyYXRpb25UaW1lIHRvIHNldCAqLworICAgIHB1YmxpYyB2b2lkIHNldEV4cGlyYXRpb25UaW1lKGxvbmcgZXhwaXJhdGlvblRpbWUpIHsKKyAgICAgIHRoaXMuZXhwaXJhdGlvblRpbWUgPSBleHBpcmF0aW9uVGltZTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0xvY2FsSEJhc2VDbHVzdGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Mb2NhbEhCYXNlQ2x1c3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2MzkwMjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Mb2NhbEhCYXNlQ2x1c3Rlci5qYXZhCkBAIC0wLDAgKzEsMzc3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5SZWZsZWN0aW9uVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyLkhNYXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvblNlcnZlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuVGhyZWFkczsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNyZWF0ZXMgYSBzaW5nbGUgcHJvY2VzcyBIQmFzZSBjbHVzdGVyLiBPbmUgdGhyZWFkIGlzIGNyZWF0ZWQgZm9yCisgKiBhIG1hc3RlciBhbmQgb25lIHBlciByZWdpb24gc2VydmVyLgorICogCisgKiBDYWxsIHtAbGluayAjc3RhcnR1cCgpfSB0byBzdGFydCB0aGUgY2x1c3RlciBydW5uaW5nIGFuZCB7QGxpbmsgI3NodXRkb3duKCl9CisgKiB0byBjbG9zZSBpdCBhbGwgZG93bi4ge0BsaW5rICNqb2lufSB0aGUgY2x1c3RlciBpcyB5b3Ugd2FudCB0byB3YWl0IG9uCisgKiBzaHV0ZG93biBjb21wbGV0aW9uLgorICogCisgKiA8cD5SdW5zIG1hc3RlciBvbiBwb3J0IDYwMDAwIGJ5IGRlZmF1bHQuICBCZWNhdXNlIHdlIGNhbid0IGp1c3Qga2lsbCB0aGUKKyAqIHByb2Nlc3MgLS0gbm90IHRpbGwgSEFET09QLTE3MDAgZ2V0cyBmaXhlZCBhbmQgZXZlbiB0aGVuLi4uLiAtLSB3ZSBuZWVkIHRvCisgKiBiZSBhYmxlIHRvIGZpbmQgdGhlIG1hc3RlciB3aXRoIGEgcmVtb3RlIGNsaWVudCB0byBydW4gc2h1dGRvd24uICBUbyB1c2UgYQorICogcG9ydCBvdGhlciB0aGFuIDYwMDAwLCBzZXQgdGhlIGhiYXNlLm1hc3RlciB0byBhIHZhbHVlIG9mICdsb2NhbDpQT1JUJzoKKyAqIHRoYXQgaXMgJ2xvY2FsJywgbm90ICdsb2NhbGhvc3QnLCBhbmQgdGhlIHBvcnQgbnVtYmVyIHRoZSBtYXN0ZXIgc2hvdWxkIHVzZQorICogaW5zdGVhZCBvZiA2MDAwMC4KKyAqIAorICogPHA+VG8gbWFrZSAnbG9jYWwnIG1vZGUgbW9yZSByZXNwb25zaXZlLCBtYWtlIHZhbHVlcyBzdWNoIGFzCisgKiA8Y29kZT5oYmFzZS5yZWdpb25zZXJ2ZXIubXNnaW50ZXJ2YWw8L2NvZGU+LAorICogPGNvZGU+aGJhc2UubWFzdGVyLm1ldGEudGhyZWFkLnJlc2NhbmZyZXF1ZW5jeTwvY29kZT4sIGFuZAorICogPGNvZGU+aGJhc2Uuc2VydmVyLnRocmVhZC53YWtlZnJlcXVlbmN5PC9jb2RlPiBhIHNlY29uZCBvciBsZXNzLgorICovCitwdWJsaWMgY2xhc3MgTG9jYWxIQmFzZUNsdXN0ZXIgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhMb2NhbEhCYXNlQ2x1c3Rlci5jbGFzcyk7CisgIHByaXZhdGUgZmluYWwgSE1hc3RlciBtYXN0ZXI7CisgIHByaXZhdGUgZmluYWwgTGlzdDxSZWdpb25TZXJ2ZXJUaHJlYWQ+IHJlZ2lvblRocmVhZHM7CisgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBERUZBVUxUX05PID0gMTsKKyAgLyoqIGxvY2FsIG1vZGUgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUwgPSAibG9jYWwiOworICAvKiogJ2xvY2FsOicgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxfQ09MT04gPSBMT0NBTCArICI6IjsKKyAgcHJpdmF0ZSBmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBmaW5hbCBDbGFzczw/IGV4dGVuZHMgSFJlZ2lvblNlcnZlcj4gcmVnaW9uU2VydmVyQ2xhc3M7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yLgorICAgKiBAcGFyYW0gY29uZgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgTG9jYWxIQmFzZUNsdXN0ZXIoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcyhjb25mLCBERUZBVUxUX05PKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3Rvci4KKyAgICogQHBhcmFtIGNvbmYgQ29uZmlndXJhdGlvbiB0byB1c2UuICBQb3N0IGNvbnN0cnVjdGlvbiBoYXMgdGhlIG1hc3RlcidzCisgICAqIGFkZHJlc3MuCisgICAqIEBwYXJhbSBub1JlZ2lvblNlcnZlcnMgQ291bnQgb2YgcmVnaW9uc2VydmVycyB0byBzdGFydC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHB1YmxpYyBMb2NhbEhCYXNlQ2x1c3RlcihmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwKKyAgICBmaW5hbCBpbnQgbm9SZWdpb25TZXJ2ZXJzKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgZG9Mb2NhbChjb25mKTsKKyAgICAvLyBDcmVhdGUgdGhlIG1hc3RlcgorICAgIHRoaXMubWFzdGVyID0gbmV3IEhNYXN0ZXIoY29uZik7CisgICAgLy8gU3RhcnQgdGhlIEhSZWdpb25TZXJ2ZXJzLiAgQWx3YXlzIGhhdmUgcmVnaW9uIHNlcnZlcnMgY29tZSB1cCBvbgorICAgIC8vIHBvcnQgJzAnIHNvIHRoZXJlIHdvbid0IGJlIGNsYXNoZXMgb3ZlciBkZWZhdWx0IHBvcnQgYXMgdW5pdCB0ZXN0cworICAgIC8vIHN0YXJ0L3N0b3AgcG9ydHMgYXQgZGlmZmVyZW50IHRpbWVzIGR1cmluZyB0aGUgbGlmZSBvZiB0aGUgdGVzdC4KKyAgICBjb25mLnNldChSRUdJT05TRVJWRVJfQUREUkVTUywgREVGQVVMVF9IT1NUICsgIjowIik7CisgICAgdGhpcy5yZWdpb25UaHJlYWRzID0gbmV3IEFycmF5TGlzdDxSZWdpb25TZXJ2ZXJUaHJlYWQ+KCk7CisgICAgcmVnaW9uU2VydmVyQ2xhc3MgPSAoQ2xhc3M8PyBleHRlbmRzIEhSZWdpb25TZXJ2ZXI+KSBjb25mLmdldENsYXNzKEhDb25zdGFudHMuUkVHSU9OX1NFUlZFUl9JTVBMLCBIUmVnaW9uU2VydmVyLmNsYXNzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG5vUmVnaW9uU2VydmVyczsgaSsrKSB7CisgICAgICBhZGRSZWdpb25TZXJ2ZXIoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIHJlZ2lvbiBzZXJ2ZXIuCisgICAqIENhbGwgJ3N0YXJ0JyBvbiB0aGUgcmV0dXJuZWQgdGhyZWFkIHRvIG1ha2UgaXQgcnVuLgorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEByZXR1cm4gUmVnaW9uIHNlcnZlciBhZGRlZC4KKyAgICovCisgIHB1YmxpYyBSZWdpb25TZXJ2ZXJUaHJlYWQgYWRkUmVnaW9uU2VydmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzeW5jaHJvbml6ZWQgKHJlZ2lvblRocmVhZHMpIHsKKyAgICAgIEhSZWdpb25TZXJ2ZXIgc2VydmVyOyAKKyAgICAgIHRyeSB7CisgICAgICAgIHNlcnZlciA9IHJlZ2lvblNlcnZlckNsYXNzLmdldENvbnN0cnVjdG9yKEhCYXNlQ29uZmlndXJhdGlvbi5jbGFzcykuCisgICAgICAgICAgbmV3SW5zdGFuY2UoY29uZik7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICBJT0V4Y2VwdGlvbiBpb2UgPSBuZXcgSU9FeGNlcHRpb24oKTsKKyAgICAgICAgaW9lLmluaXRDYXVzZShlKTsKKyAgICAgICAgdGhyb3cgaW9lOworICAgICAgfQorICAgICAgUmVnaW9uU2VydmVyVGhyZWFkIHQgPSBuZXcgUmVnaW9uU2VydmVyVGhyZWFkKHNlcnZlciwKKyAgICAgICAgICB0aGlzLnJlZ2lvblRocmVhZHMuc2l6ZSgpKTsKKyAgICAgIHRoaXMucmVnaW9uVGhyZWFkcy5hZGQodCk7CisgICAgICByZXR1cm4gdDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHNlcnZlck51bWJlcgorICAgKiBAcmV0dXJuIHJlZ2lvbiBzZXJ2ZXIKKyAgICovCisgIHB1YmxpYyBIUmVnaW9uU2VydmVyIGdldFJlZ2lvblNlcnZlcihpbnQgc2VydmVyTnVtYmVyKSB7CisgICAgc3luY2hyb25pemVkIChyZWdpb25UaHJlYWRzKSB7CisgICAgICByZXR1cm4gcmVnaW9uVGhyZWFkcy5nZXQoc2VydmVyTnVtYmVyKS5nZXRSZWdpb25TZXJ2ZXIoKTsKKyAgICB9CisgIH0KKworICAvKiogcnVucyByZWdpb24gc2VydmVycyAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlZ2lvblNlcnZlclRocmVhZCBleHRlbmRzIFRocmVhZCB7CisgICAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uU2VydmVyIHJlZ2lvblNlcnZlcjsKKyAgICAKKyAgICBSZWdpb25TZXJ2ZXJUaHJlYWQoZmluYWwgSFJlZ2lvblNlcnZlciByLCBmaW5hbCBpbnQgaW5kZXgpIHsKKyAgICAgIHN1cGVyKHIsICJSZWdpb25TZXJ2ZXI6IiArIGluZGV4KTsKKyAgICAgIHRoaXMucmVnaW9uU2VydmVyID0gcjsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiB0aGUgcmVnaW9uIHNlcnZlciAqLworICAgIHB1YmxpYyBIUmVnaW9uU2VydmVyIGdldFJlZ2lvblNlcnZlcigpIHsKKyAgICAgIHJldHVybiB0aGlzLnJlZ2lvblNlcnZlcjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQmxvY2sgdW50aWwgdGhlIHJlZ2lvbiBzZXJ2ZXIgaGFzIGNvbWUgb25saW5lLCBpbmRpY2F0aW5nIGl0IGlzIHJlYWR5CisgICAgICogdG8gYmUgdXNlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3YWl0Rm9yU2VydmVyT25saW5lKCkgeworICAgICAgd2hpbGUgKCFyZWdpb25TZXJ2ZXIuaXNPbmxpbmUoKSkgeworICAgICAgICB0cnkgeworICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGNvbnRpbnVlIHdhaXRpbmcKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBITWFzdGVyIHRocmVhZAorICAgKi8KKyAgcHVibGljIEhNYXN0ZXIgZ2V0TWFzdGVyKCkgeworICAgIHJldHVybiB0aGlzLm1hc3RlcjsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFJlYWQtb25seSBsaXN0IG9mIHJlZ2lvbiBzZXJ2ZXIgdGhyZWFkcy4KKyAgICovCisgIHB1YmxpYyBMaXN0PFJlZ2lvblNlcnZlclRocmVhZD4gZ2V0UmVnaW9uU2VydmVycygpIHsKKyAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0aGlzLnJlZ2lvblRocmVhZHMpOworICB9CisKKyAgLyoqCisgICAqIFdhaXQgZm9yIHRoZSBzcGVjaWZpZWQgcmVnaW9uIHNlcnZlciB0byBzdG9wCisgICAqIFJlbW92ZXMgdGhpcyB0aHJlYWQgZnJvbSBsaXN0IG9mIHJ1bm5pbmcgdGhyZWFkcy4KKyAgICogQHBhcmFtIHNlcnZlck51bWJlcgorICAgKiBAcmV0dXJuIE5hbWUgb2YgcmVnaW9uIHNlcnZlciB0aGF0IGp1c3Qgd2VudCBkb3duLgorICAgKi8KKyAgcHVibGljIFN0cmluZyB3YWl0T25SZWdpb25TZXJ2ZXIoaW50IHNlcnZlck51bWJlcikgeworICAgIFJlZ2lvblNlcnZlclRocmVhZCByZWdpb25TZXJ2ZXJUaHJlYWQ7CisgICAgc3luY2hyb25pemVkIChyZWdpb25UaHJlYWRzKSB7CisgICAgICByZWdpb25TZXJ2ZXJUaHJlYWQgPSB0aGlzLnJlZ2lvblRocmVhZHMucmVtb3ZlKHNlcnZlck51bWJlcik7CisgICAgfQorICAgIHdoaWxlIChyZWdpb25TZXJ2ZXJUaHJlYWQuaXNBbGl2ZSgpKSB7CisgICAgICB0cnkgeworICAgICAgICBMT0cuaW5mbygiV2FpdGluZyBvbiAiICsKKyAgICAgICAgICByZWdpb25TZXJ2ZXJUaHJlYWQuZ2V0UmVnaW9uU2VydmVyKCkuZ2V0U2VydmVySW5mbygpLnRvU3RyaW5nKCkpOworICAgICAgICByZWdpb25TZXJ2ZXJUaHJlYWQuam9pbigpOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVnaW9uU2VydmVyVGhyZWFkLmdldE5hbWUoKTsKKyAgfQorCisgIC8qKgorICAgKiBXYWl0IGZvciBNaW5pIEhCYXNlIENsdXN0ZXIgdG8gc2h1dCBkb3duLgorICAgKiBQcmVzdW1lcyB5b3UndmUgYWxyZWFkeSBjYWxsZWQge0BsaW5rICNzaHV0ZG93bigpfS4KKyAgICovCisgIHB1YmxpYyB2b2lkIGpvaW4oKSB7CisgICAgaWYgKHRoaXMucmVnaW9uVGhyZWFkcyAhPSBudWxsKSB7CisgICAgICBzeW5jaHJvbml6ZWQodGhpcy5yZWdpb25UaHJlYWRzKSB7CisgICAgICAgIGZvcihUaHJlYWQgdDogdGhpcy5yZWdpb25UaHJlYWRzKSB7CisgICAgICAgICAgaWYgKHQuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICB0LmpvaW4oKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHRoaXMubWFzdGVyICE9IG51bGwgJiYgdGhpcy5tYXN0ZXIuaXNBbGl2ZSgpKSB7CisgICAgICB0cnkgeworICAgICAgICB0aGlzLm1hc3Rlci5qb2luKCk7CisgICAgICB9IGNhdGNoKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gY29udGludWUKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBTdGFydCB0aGUgY2x1c3Rlci4KKyAgICogQHJldHVybiBBZGRyZXNzIHRvIHVzZSBjb250YWN0aW5nIG1hc3Rlci4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgc3RhcnR1cCgpIHsKKyAgICB0aGlzLm1hc3Rlci5zdGFydCgpOworICAgIHN5bmNocm9uaXplZCAocmVnaW9uVGhyZWFkcykgeworICAgICAgZm9yIChSZWdpb25TZXJ2ZXJUaHJlYWQgdDogdGhpcy5yZWdpb25UaHJlYWRzKSB7CisgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRoaXMubWFzdGVyLmdldE1hc3RlckFkZHJlc3MoKS50b1N0cmluZygpOworICB9CisKKyAgLyoqCisgICAqIFNodXQgZG93biB0aGUgbWluaSBIQmFzZSBjbHVzdGVyCisgICAqLworICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICBMT0cuZGVidWcoIlNodXR0aW5nIGRvd24gSEJhc2UgQ2x1c3RlciIpOworICAgIC8vIEJlIGNhcmVmdWwgaG93IHRoZSBoZGZzIHNodXRkb3duIHRocmVhZCBydW5zIGluIGNvbnRleHQgd2hlcmUgbW9yZSB0aGFuCisgICAgLy8gb25lIHJlZ2lvbnNlcnZlciBpbiB0aGUgbWl4LgorICAgIFRocmVhZCBzaHV0ZG93blRocmVhZCA9IG51bGw7CisgICAgc3luY2hyb25pemVkICh0aGlzLnJlZ2lvblRocmVhZHMpIHsKKyAgICAgIGZvciAoUmVnaW9uU2VydmVyVGhyZWFkIHQ6IHRoaXMucmVnaW9uVGhyZWFkcykgeworICAgICAgICBUaHJlYWQgdHQgPSB0LmdldFJlZ2lvblNlcnZlcigpLnNldEhERlNTaHV0ZG93blRocmVhZE9uRXhpdChudWxsKTsKKyAgICAgICAgaWYgKHNodXRkb3duVGhyZWFkID09IG51bGwgJiYgdHQgIT0gbnVsbCkgeworICAgICAgICAgIHNodXRkb3duVGhyZWFkID0gdHQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaWYodGhpcy5tYXN0ZXIgIT0gbnVsbCkgeworICAgICAgdGhpcy5tYXN0ZXIuc2h1dGRvd24oKTsKKyAgICB9CisgICAgLy8gcmVnaW9uU2VydmVyVGhyZWFkcyBjYW4gbmV2ZXIgYmUgbnVsbCBiZWNhdXNlIHRoZXkgYXJlIGluaXRpYWxpemVkIHdoZW4KKyAgICAvLyB0aGUgY2xhc3MgaXMgY29uc3RydWN0ZWQuCisgICAgc3luY2hyb25pemVkKHRoaXMucmVnaW9uVGhyZWFkcykgeworICAgICAgZm9yKFRocmVhZCB0OiB0aGlzLnJlZ2lvblRocmVhZHMpIHsKKyAgICAgICAgaWYgKHQuaXNBbGl2ZSgpKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHQuam9pbigpOworICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGlmICh0aGlzLm1hc3RlciAhPSBudWxsKSB7CisgICAgICB3aGlsZSAodGhpcy5tYXN0ZXIuaXNBbGl2ZSgpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgLy8gVGhlIGJlbG93IGhhcyBiZWVuIHJlcGxhY2VkIHRvIGRlYnVnIHNvbWV0aW1lIGhhbmdzIG9uIGVuZCBvZgorICAgICAgICAgIC8vIHRlc3RzLgorICAgICAgICAgIC8vIHRoaXMubWFzdGVyLmpvaW4oKToKKyAgICAgICAgICB0aHJlYWREdW1waW5nSm9pbih0aGlzLm1hc3Rlcik7CisgICAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgVGhyZWFkcy5zaHV0ZG93bihzaHV0ZG93blRocmVhZCk7CisgICAgTE9HLmluZm8oIlNodXRkb3duICIgKworICAgICAgKCh0aGlzLnJlZ2lvblRocmVhZHMgIT0gbnVsbCk/IHRoaXMubWFzdGVyLmdldE5hbWUoKTogIjAgbWFzdGVycyIpICsKKyAgICAgICIgIiArIHRoaXMucmVnaW9uVGhyZWFkcy5zaXplKCkgKyAiIHJlZ2lvbiBzZXJ2ZXIocykiKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdAorICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0aHJlYWREdW1waW5nSm9pbihmaW5hbCBUaHJlYWQgdCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBpZiAodCA9PSBudWxsKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGxvbmcgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgd2hpbGUgKHQuaXNBbGl2ZSgpKSB7CisgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUgPiA2MDAwMCkgeworICAgICAgICBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgUmVmbGVjdGlvblV0aWxzLnByaW50VGhyZWFkSW5mbyhuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLm91dCksCisgICAgICAgICAgICAiQXV0b21hdGljIFN0YWNrIFRyYWNlIGV2ZXJ5IDYwIHNlY29uZHMgd2FpdGluZyBvbiAiICsKKyAgICAgICAgICAgIHQuZ2V0TmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ2hhbmdlcyA8Y29kZT5oYmFzZS5tYXN0ZXI8L2NvZGU+IGZyb20gJ2xvY2FsJyB0byAnbG9jYWxob3N0OlBPUlQnIGluCisgICAqIHBhc3NlZCBDb25maWd1cmF0aW9uIGluc3RhbmNlLgorICAgKiBAcGFyYW0gYworICAgKiBAcmV0dXJuIFRoZSBwYXNzZWQgPGNvZGU+YzwvY29kZT4gY29uZmlndXJhdGlvbiBtb2RpZmllZCBpZiBoYmFzZS5tYXN0ZXIKKyAgICogdmFsdWUgd2FzICdsb2NhbCcgb3RoZXJ3aXNlLCB1bmFsdGVyZWQuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBIQmFzZUNvbmZpZ3VyYXRpb24gZG9Mb2NhbChmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gYykgeworICAgIGlmICghaXNMb2NhbChjKSkgeworICAgICAgcmV0dXJuIGM7CisgICAgfQorCisgICAgLy8gTmVlZCB0byByZXdyaXRlIGFkZHJlc3MgaW4gQ29uZmlndXJhdGlvbiBpZiBub3QgZG9uZSBhbHJlYWR5LgorICAgIFN0cmluZyBhZGRyZXNzID0gYy5nZXQoTUFTVEVSX0FERFJFU1MpOworICAgIGlmIChhZGRyZXNzICE9IG51bGwpIHsKKyAgICAgIFN0cmluZyBwb3J0ID0gYWRkcmVzcy5zdGFydHNXaXRoKExPQ0FMX0NPTE9OKT8KKyAgICAgICAgYWRkcmVzcy5zdWJzdHJpbmcoTE9DQUxfQ09MT04ubGVuZ3RoKCkpOgorICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKERFRkFVTFRfTUFTVEVSX1BPUlQpOworICAgICAgYy5zZXQoTUFTVEVSX0FERFJFU1MsICJsb2NhbGhvc3Q6IiArIHBvcnQpOworICAgIH0KKworICAgIC8vIE5lZWQgdG8gcmV3cml0ZSBob3N0IGluIENvbmZpZ3VyYXRpb24gaWYgbm90IGRvbmUgYWxyZWFkeS4KKyAgICBTdHJpbmcgaG9zdCA9IGMuZ2V0KE1BU1RFUl9IT1NUX05BTUUpOworICAgIGlmIChob3N0ICE9IG51bGwgJiYgaG9zdC5lcXVhbHMoTE9DQUwpKSB7CisgICAgICBjLnNldChNQVNURVJfSE9TVF9OQU1FLCAibG9jYWxob3N0Iik7CisgICAgfQorCisgICAgcmV0dXJuIGM7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGMgQ29uZmlndXJhdGlvbiB0byBjaGVjay4KKyAgICogQHJldHVybiBUcnVlIGlmIGEgJ2xvY2FsJyBhZGRyZXNzIGluIGhiYXNlLm1hc3RlciB2YWx1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xvY2FsKGZpbmFsIENvbmZpZ3VyYXRpb24gYykgeworICAgIFN0cmluZyBhZGRyZXNzID0gYy5nZXQoTUFTVEVSX0FERFJFU1MpOworICAgIGJvb2xlYW4gYWRkcmVzc0lzTG9jYWwgPSBhZGRyZXNzID09IG51bGwgfHwgYWRkcmVzcy5lcXVhbHMoTE9DQUwpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3Muc3RhcnRzV2l0aChMT0NBTF9DT0xPTik7CisgICAgU3RyaW5nIGhvc3QgPSBjLmdldChNQVNURVJfSE9TVF9OQU1FKTsKKyAgICBib29sZWFuIGhvc3RJc0xvY2FsID0gaG9zdCA9PSBudWxsIHx8IGhvc3QuZXF1YWxzKExPQ0FMKTsKKyAgICByZXR1cm4gYWRkcmVzc0lzTG9jYWwgJiYgaG9zdElzTG9jYWw7CisgIH0KKworICAvKioKKyAgICogVGVzdCB0aGluZ3MgYmFzaWNhbGx5IHdvcmsuCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgTG9jYWxIQmFzZUNsdXN0ZXIgY2x1c3RlciA9IG5ldyBMb2NhbEhCYXNlQ2x1c3Rlcihjb25mKTsKKyAgICBjbHVzdGVyLnN0YXJ0dXAoKTsKKyAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPQorICAgICAgbmV3IEhUYWJsZURlc2NyaXB0b3IoQnl0ZXMudG9CeXRlcyhjbHVzdGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpKSk7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoaHRkKTsKKyAgICBjbHVzdGVyLnNodXRkb3duKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42Y2Y1NjRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIGlmIHRoZSBtYXN0ZXIgaXMgbm90IHJ1bm5pbmcKKyAqLworcHVibGljIGNsYXNzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMIDw8IDIzIC0gMUw7CisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHMgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvciB0YWtpbmcgYW5vdGhlciBleGNlcHRpb24uCisgICAqIEBwYXJhbSBlIEV4Y2VwdGlvbiB0byBncmFiIGRhdGEgZnJvbS4KKyAgICovCisgIHB1YmxpYyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKEV4Y2VwdGlvbiBlKSB7CisgICAgc3VwZXIoZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL05vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL05vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzkzZWJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRocm93biBieSBhIHJlZ2lvbiBzZXJ2ZXIgaWYgaXQgaXMgc2VudCBhIHJlcXVlc3QgZm9yIGEgcmVnaW9uIGl0IGlzIG5vdAorICogc2VydmluZy4KKyAqLworcHVibGljIGNsYXNzIE5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMIDw8IDE3IC0gMUw7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIE5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgIHN1cGVyKHMpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHMgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIE5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24oZmluYWwgYnl0ZSBbXSBzKSB7CisgICAgc3VwZXIoQnl0ZXMudG9TdHJpbmcocykpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvUmVnaW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9SZWdpb25FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MzA2M2E1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvUmVnaW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKy8qKgorICogVGhyb3duIHdoZW4gc29tZXRoaW5nIGhhcHBlbnMgcmVsYXRlZCB0byByZWdpb24gaGFuZGxpbmcuCisgKiBTdWJjbGFzc2VzIGhhdmUgdG8gYmUgbW9yZSBzcGVjaWZpYy4KKyAqLworcHVibGljIGNsYXNzIFJlZ2lvbkV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTQ3MzUxMDI1ODA3MTExMTM3MUw7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIFJlZ2lvbkV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBzIG1lc3NhZ2UKKyAgICovCisgIHB1YmxpYyBSZWdpb25FeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9SZWdpb25IaXN0b3JpYW4uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1JlZ2lvbkhpc3Rvcmlhbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmMDhjZTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9SZWdpb25IaXN0b3JpYW4uamF2YQpAQCAtMCwwICsxLDMzMSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5HcmVnb3JpYW5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRoZSBSZWdpb24gSGlzdG9yaWFuIHRhc2sgaXMgdG8ga2VlcCB0cmFjayBvZiBldmVyeSBtb2RpZmljYXRpb24gYSByZWdpb24KKyAqIGhhcyB0byBnbyB0aHJvdWdoLiBQdWJsaWMgbWV0aG9kcyBhcmUgdXNlZCB0byB1cGRhdGUgdGhlIGluZm9ybWF0aW9uIGluIHRoZQorICogPGNvZGU+Lk1FVEEuPC9jb2RlPiB0YWJsZSBhbmQgdG8gcmV0cmlldmUgaXQuICBUaGlzIGlzIGEgU2luZ2xldG9uLiAgQnkKKyAqIGRlZmF1bHQsIHRoZSBIaXN0b3JpYW4gaXMgb2ZmbGluZTsgaXQgd2lsbCBub3QgbG9nLiAgSXRzIGVuYWJsZWQgaW4gdGhlCisgKiByZWdpb25zZXJ2ZXIgYW5kIG1hc3RlciBkb3duIGluIHRoZWlyIGd1dHMgYWZ0ZXIgdGhlcmUncyBzb21lIGNlcnRhaW50eSB0aGUKKyAqIC5NRVRBLiBoYXMgYmVlbiBkZXBsb3llZC4KKyAqLworcHVibGljIGNsYXNzIFJlZ2lvbkhpc3RvcmlhbiBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coUmVnaW9uSGlzdG9yaWFuLmNsYXNzKTsKKyAgCisgIHByaXZhdGUgSFRhYmxlIG1ldGFUYWJsZTsKKworCisKKyAgLyoqIFNpbmdsZXRvbiByZWZlcmVuY2UgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgUmVnaW9uSGlzdG9yaWFuIGhpc3RvcmlhbjsKKworICAvKiogRGF0ZSBmb3JtYXRlciBmb3IgdGhlIHRpbWVzdGFtcCBpbiBSZWdpb25IaXN0b3J5SW5mb3JtYXRpb24gKi8KKyAgc3RhdGljIFNpbXBsZURhdGVGb3JtYXQgZGF0ZUZvcm1hdCA9IG5ldyBTaW1wbGVEYXRlRm9ybWF0KAorICAiRUVFLCBkIE1NTSB5eXl5IEhIOm1tOnNzIik7CisKKyAgCisgIHByaXZhdGUgc3RhdGljIGVudW0gSGlzdG9yaWFuQ29sdW1uS2V5ICB7CisgICAgUkVHSU9OX0NSRUFUSU9OICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrImNyZWF0aW9uIikpLAorICAgIFJFR0lPTl9PUEVOICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrIm9wZW4iKSksCisgICAgUkVHSU9OX1NQTElUICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrInNwbGl0IikpLAorICAgIFJFR0lPTl9DT01QQUNUSU9OICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrImNvbXBhY3Rpb24iKSksCisgICAgUkVHSU9OX0ZMVVNIICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrImZsdXNoIikpLAorICAgIFJFR0lPTl9BU1NJR05NRU5UICggQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX0hJU1RPUklBTl9TVFIrImFzc2lnbm1lbnQiKSk7CisKKyAgYnl0ZVtdIGtleTsKKworICAgIEhpc3RvcmlhbkNvbHVtbktleShieXRlW10ga2V5KSB7CisgICAgICB0aGlzLmtleSA9IGtleTsKKyAgICB9CisgIH0gCisgIAorICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTUExJVF9QUkVGSVggPSAiUmVnaW9uIHNwbGl0IGZyb206ICI7CisKKyAgLyoqCisgICAqIERlZmF1bHQgY29uc3RydWN0b3IuIEluaXRpYWxpemVzIHJlZmVyZW5jZSB0byAuTUVUQS4gdGFibGUuICBJbmFjY2Vzc2libGUuCisgICAqIFVzZSB7QGxpbmsgI2dldEluc3RhbmNlKEhCYXNlQ29uZmlndXJhdGlvbil9IHRvIG9idGFpbiB0aGUgU2luZ2xldG9uCisgICAqIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCisgICAqLworICBwcml2YXRlIFJlZ2lvbkhpc3RvcmlhbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgUmVnaW9uSGlzdG9yaWFuIFNpbmdsZXRvbiBpbnN0YW5jZS4KKyAgICogQHJldHVybiBUaGUgcmVnaW9uIGhpc3RvcmlhbgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBzdGF0aWMgUmVnaW9uSGlzdG9yaWFuIGdldEluc3RhbmNlKCkgeworICAgIGlmIChoaXN0b3JpYW4gPT0gbnVsbCkgeworICAgICAgaGlzdG9yaWFuID0gbmV3IFJlZ2lvbkhpc3RvcmlhbigpOworICAgIH0KKyAgICByZXR1cm4gaGlzdG9yaWFuOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMsIGZvciBhIGdpdmVuIHJlZ2lvbiBuYW1lLCBhbiBvcmRlcmVkIGxpc3QgYnkgdGltZXN0YW1wIG9mIGFsbAorICAgKiB2YWx1ZXMgaW4gdGhlIGhpc3RvcmlhbiBjb2x1bW4gb2YgdGhlIC5NRVRBLiB0YWJsZS4KKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogICAgICAgICAgUmVnaW9uIG5hbWUgYXMgYSBzdHJpbmcKKyAgICogQHJldHVybiBMaXN0IG9mIFJlZ2lvbkhpc3RvcnlJbmZvcm1hdGlvbiBvciBudWxsIGlmIHdlJ3JlIG9mZmxpbmUuCisgICAqLworICBwdWJsaWMgTGlzdDxSZWdpb25IaXN0b3J5SW5mb3JtYXRpb24+IGdldFJlZ2lvbkhpc3RvcnkoU3RyaW5nIHJlZ2lvbk5hbWUpIHsKKyAgICBpZiAoIWlzT25saW5lKCkpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBMaXN0PFJlZ2lvbkhpc3RvcnlJbmZvcm1hdGlvbj4gaW5mb3JtYXRpb25zID0KKyAgICAgIG5ldyBBcnJheUxpc3Q8UmVnaW9uSGlzdG9yeUluZm9ybWF0aW9uPigpOworICAgIHRyeSB7CisgICAgICAvKgorICAgICAgICogVE9ETyBSRUdJT05fSElTVE9SSUFOX0tFWVMgaXMgdXNlZCBiZWNhdXNlIHRoZXJlIGlzIG5vIG90aGVyIGZvciB0aGUKKyAgICAgICAqIG1vbWVudCB0byByZXRyaWV2ZSBhbGwgdmVyc2lvbiBhbmQgdG8gaGF2ZSB0aGUgY29sdW1uIGtleSBpbmZvcm1hdGlvbi4KKyAgICAgICAqIFRvIGJlIGNoYW5nZWQgd2hlbiBIVGFibGUuZ2V0Um93IGhhbmRsZXMgdmVyc2lvbnMuCisgICAgICAgKi8KKyAgICAgIGZvciAoSGlzdG9yaWFuQ29sdW1uS2V5IGtleUVudSA6IEhpc3RvcmlhbkNvbHVtbktleS52YWx1ZXMoKSkgeworICAgICAgICBieXRlW10gY29sdW1uS2V5ID0ga2V5RW51LmtleTsKKyAgICAgICAgQ2VsbFtdIGNlbGxzID0gdGhpcy5tZXRhVGFibGUuZ2V0KEJ5dGVzLnRvQnl0ZXMocmVnaW9uTmFtZSksCisgICAgICAgICAgICBjb2x1bW5LZXksIEFMTF9WRVJTSU9OUyk7CisgICAgICAgIGlmIChjZWxscyAhPSBudWxsKSB7CisgICAgICAgICAgZm9yIChDZWxsIGNlbGwgOiBjZWxscykgeworICAgICAgICAgICAgaW5mb3JtYXRpb25zLmFkZChoaXN0b3JpYW4ubmV3IFJlZ2lvbkhpc3RvcnlJbmZvcm1hdGlvbihjZWxsCisgICAgICAgICAgICAgICAgLmdldFRpbWVzdGFtcCgpLCBCeXRlcy50b1N0cmluZyhjb2x1bW5LZXkpLnNwbGl0KCI6IilbMV0sIEJ5dGVzCisgICAgICAgICAgICAgICAgLnRvU3RyaW5nKGNlbGwuZ2V0VmFsdWUoKSkpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgIExPRy53YXJuKCJVbmFibGUgdG8gcmV0cmlldmUgcmVnaW9uIGhpc3RvcnkiLCBpb2UpOworICAgIH0KKyAgICBDb2xsZWN0aW9ucy5zb3J0KGluZm9ybWF0aW9ucyk7CisgICAgcmV0dXJuIGluZm9ybWF0aW9uczsKKyAgfQorICAKKyAgLyoqCisgICAqIE1ldGhvZCB0byBhZGQgYSBjcmVhdGlvbiBldmVudCB0byB0aGUgcm93IGluIHRoZSAuTUVUQSB0YWJsZQorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcGFyYW0gc2VydmVyTmFtZQorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkUmVnaW9uQXNzaWdubWVudChIUmVnaW9uSW5mbyBpbmZvLCBTdHJpbmcgc2VydmVyTmFtZSkgeworICAgIGFkZChIaXN0b3JpYW5Db2x1bW5LZXkuUkVHSU9OX0FTU0lHTk1FTlQua2V5LCAiUmVnaW9uIGFzc2lnbmVkIHRvIHNlcnZlciAiCisgICAgICAgICsgc2VydmVyTmFtZSwgaW5mbyk7CisgIH0KKworICAvKioKKyAgICogTWV0aG9kIHRvIGFkZCBhIGNyZWF0aW9uIGV2ZW50IHRvIHRoZSByb3cgaW4gdGhlIC5NRVRBIHRhYmxlCisgICAqIEBwYXJhbSBpbmZvCisgICAqLworICBwdWJsaWMgdm9pZCBhZGRSZWdpb25DcmVhdGlvbihIUmVnaW9uSW5mbyBpbmZvKSB7CisgICAgYWRkKEhpc3RvcmlhbkNvbHVtbktleS5SRUdJT05fQ1JFQVRJT04ua2V5LCAiUmVnaW9uIGNyZWF0aW9uIiwgaW5mbyk7CisgIH0KKworICAvKioKKyAgICogTWV0aG9kIHRvIGFkZCBhIG9wZW5pbmcgZXZlbnQgdG8gdGhlIHJvdyBpbiB0aGUgLk1FVEEgdGFibGUKKyAgICogQHBhcmFtIGluZm8KKyAgICogQHBhcmFtIGFkZHJlc3MKKyAgICovCisgIHB1YmxpYyB2b2lkIGFkZFJlZ2lvbk9wZW4oSFJlZ2lvbkluZm8gaW5mbywgSFNlcnZlckFkZHJlc3MgYWRkcmVzcykgeworICAgIGFkZChIaXN0b3JpYW5Db2x1bW5LZXkuUkVHSU9OX09QRU4ua2V5LCAiUmVnaW9uIG9wZW5lZCBvbiBzZXJ2ZXIgOiAiCisgICAgICAgICsgYWRkcmVzcy5nZXRIb3N0bmFtZSgpLCBpbmZvKTsKKyAgfQorCisgIC8qKgorICAgKiBNZXRob2QgdG8gYWRkIGEgc3BsaXQgZXZlbnQgdG8gdGhlIHJvd3MgaW4gdGhlIC5NRVRBIHRhYmxlIHdpdGgKKyAgICogaW5mb3JtYXRpb24gZnJvbSBvbGRJbmZvLgorICAgKiBAcGFyYW0gb2xkSW5mbworICAgKiBAcGFyYW0gbmV3SW5mbzEgCisgICAqIEBwYXJhbSBuZXdJbmZvMgorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkUmVnaW9uU3BsaXQoSFJlZ2lvbkluZm8gb2xkSW5mbywgSFJlZ2lvbkluZm8gbmV3SW5mbzEsCisgICAgIEhSZWdpb25JbmZvIG5ld0luZm8yKSB7CisgICAgSFJlZ2lvbkluZm9bXSBpbmZvcyA9IG5ldyBIUmVnaW9uSW5mb1tdIHsgbmV3SW5mbzEsIG5ld0luZm8yIH07CisgICAgZm9yIChIUmVnaW9uSW5mbyBpbmZvIDogaW5mb3MpIHsKKyAgICAgIGFkZChIaXN0b3JpYW5Db2x1bW5LZXkuUkVHSU9OX1NQTElULmtleSwgU1BMSVRfUFJFRklYICsKKyAgICAgICAgb2xkSW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSwgaW5mbyk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIE1ldGhvZCB0byBhZGQgYSBjb21wYWN0aW9uIGV2ZW50IHRvIHRoZSByb3cgaW4gdGhlIC5NRVRBIHRhYmxlCisgICAqIEBwYXJhbSBpbmZvCisgICAqIEBwYXJhbSB0aW1lVGFrZW4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFkZFJlZ2lvbkNvbXBhY3Rpb24oZmluYWwgSFJlZ2lvbkluZm8gaW5mbywKKyAgICAgIGZpbmFsIFN0cmluZyB0aW1lVGFrZW4pIHsKKyAgICAvLyBXaGlsZSBoaXN0b3JpYW4gY2FuIG5vdCBsb2cgZmx1c2hlcyBiZWNhdXNlIGl0IGNvdWxkIGRlYWRsb2NrIHRoZQorICAgIC8vIHJlZ2lvbnNlcnZlciAtLSBzZWUgdGhlIG5vdGUgaW4gYWRkUmVnaW9uRmx1c2ggLS0gdGhlcmUgc2hvdWxkIGJlIG5vCisgICAgLy8gc3VjaCBkYW5nZXIgY29tcGFjdGluZzsgY29tcGFjdGlvbnMgYXJlIG5vdCBhbGxvd2VkIHdoZW4KKyAgICAvLyBGbHVzaGVyI2ZsdXNoU29tZVJlZ2lvbnMgaXMgcnVuLgorICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgYWRkKEhpc3RvcmlhbkNvbHVtbktleS5SRUdJT05fQ09NUEFDVElPTi5rZXksCisgICAgICAgICJSZWdpb24gY29tcGFjdGlvbiBjb21wbGV0ZWQgaW4gIiArIHRpbWVUYWtlbiwgaW5mbyk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIE1ldGhvZCB0byBhZGQgYSBmbHVzaCBldmVudCB0byB0aGUgcm93IGluIHRoZSAuTUVUQSB0YWJsZQorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcGFyYW0gdGltZVRha2VuCisgICAqLworICBwdWJsaWMgdm9pZCBhZGRSZWdpb25GbHVzaChIUmVnaW9uSW5mbyBpbmZvLCBTdHJpbmcgdGltZVRha2VuKSB7CisgICAgLy8gRGlzYWJsZWQuICBOb29wLiAgSWYgdGhpcyByZWdpb25zZXJ2ZXIgaXMgaG9zdGluZyB0aGUgLk1FVEEuIEFORCBpcworICAgIC8vIGhvbGRpbmcgdGhlIHJlY2xhaW1NZW1jYWNoZU1lbW9yeSBnbG9iYWwgbG9jayAtLQorICAgIC8vIHNlZSBGbHVzaGVyI2ZsdXNoU29tZVJlZ2lvbnMgLS0gIHdlIGRlYWRsb2NrLiAgRm9yIG5vdywganVzdCBkaXNhYmxlCisgICAgLy8gbG9nZ2luZyBvZiBmbHVzaGVzLgorICB9CisKKyAgLyoqCisgICAqIE1ldGhvZCB0byBhZGQgYW4gZXZlbnQgd2l0aCBMQVRFU1RfVElNRVNUQU1QLgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEBwYXJhbSB0ZXh0CisgICAqIEBwYXJhbSBpbmZvCisgICAqLworICBwcml2YXRlIHZvaWQgYWRkKGJ5dGVbXSBjb2x1bW4sCisgICAgICBTdHJpbmcgdGV4dCwgSFJlZ2lvbkluZm8gaW5mbykgeworICAgIGFkZChjb2x1bW4sIHRleHQsIGluZm8sIExBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIE1ldGhvZCB0byBhZGQgYW4gZXZlbnQgd2l0aCBwcm92aWRlZCBpbmZvcm1hdGlvbi4KKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcGFyYW0gdGV4dAorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqLworICBwcml2YXRlIHZvaWQgYWRkKGJ5dGVbXSBjb2x1bW4sCisgICAgICBTdHJpbmcgdGV4dCwgSFJlZ2lvbkluZm8gaW5mbywgbG9uZyB0aW1lc3RhbXApIHsKKyAgICBpZiAoIWlzT25saW5lKCkpIHsKKyAgICAgIC8vIEl0cyBhIG5vb3AKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKCFpbmZvLmlzTWV0YVJlZ2lvbigpKSB7CisgICAgICBCYXRjaFVwZGF0ZSBiYXRjaCA9IG5ldyBCYXRjaFVwZGF0ZShpbmZvLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICBiYXRjaC5zZXRUaW1lc3RhbXAodGltZXN0YW1wKTsKKyAgICAgIGJhdGNoLnB1dChjb2x1bW4sIEJ5dGVzLnRvQnl0ZXModGV4dCkpOworICAgICAgdHJ5IHsKKyAgICAgICAgdGhpcy5tZXRhVGFibGUuY29tbWl0KGJhdGNoKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICBMT0cud2FybigiVW5hYmxlIHRvICciICsgdGV4dCArICInIiwgaW9lKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogSW5uZXIgY2xhc3MgdGhhdCBvbmx5IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFuIGV2ZW50LgorICAgKiAKKyAgICovCisgIHB1YmxpYyBjbGFzcyBSZWdpb25IaXN0b3J5SW5mb3JtYXRpb24gaW1wbGVtZW50cworICBDb21wYXJhYmxlPFJlZ2lvbkhpc3RvcnlJbmZvcm1hdGlvbj4geworICAgIAorICAgIHByaXZhdGUgR3JlZ29yaWFuQ2FsZW5kYXIgY2FsID0gbmV3IEdyZWdvcmlhbkNhbGVuZGFyKCk7CisKKyAgICBwcml2YXRlIGxvbmcgdGltZXN0YW1wOworCisgICAgcHJpdmF0ZSBTdHJpbmcgZXZlbnQ7CisKKyAgICBwcml2YXRlIFN0cmluZyBkZXNjcmlwdGlvbjsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiBAcGFyYW0gZGVzY3JpcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVnaW9uSGlzdG9yeUluZm9ybWF0aW9uKGxvbmcgdGltZXN0YW1wLCBTdHJpbmcgZXZlbnQsCisgICAgICAgIFN0cmluZyBkZXNjcmlwdGlvbikgeworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLmV2ZW50ID0gZXZlbnQ7CisgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CisgICAgfQorCisgICAgcHVibGljIGludCBjb21wYXJlVG8oUmVnaW9uSGlzdG9yeUluZm9ybWF0aW9uIG90aGVySW5mbykgeworICAgICAgcmV0dXJuIC0xICogTG9uZy52YWx1ZU9mKHRpbWVzdGFtcCkuY29tcGFyZVRvKG90aGVySW5mby5nZXRUaW1lc3RhbXAoKSk7CisgICAgfQorCisgICAgLyoqIEByZXR1cm4gdGhlIGV2ZW50ICovCisgICAgcHVibGljIFN0cmluZyBnZXRFdmVudCgpIHsKKyAgICAgIHJldHVybiBldmVudDsKKyAgICB9CisKKyAgICAvKiogQHJldHVybiB0aGUgZGVzY3JpcHRpb24gKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgeworICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOworICAgIH0KKworICAgIC8qKiBAcmV0dXJuIHRoZSB0aW1lc3RhbXAgKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGltZXN0YW1wOworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSB0aW1lc3RhbXAgcHJvY2Vzc2VkIHdpdGggdGhlIGRhdGUgZm9ybWF0ZXIuCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRUaW1lc3RhbXBBc1N0cmluZygpIHsKKyAgICAgIGNhbC5zZXRUaW1lSW5NaWxsaXModGltZXN0YW1wKTsKKyAgICAgIHJldHVybiBkYXRlRm9ybWF0LmZvcm1hdChjYWwuZ2V0VGltZSgpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBUcnVlIGlmIHRoZSBoaXN0b3JpYW4gaXMgb25saW5lLiBXaGVuIG9mZmxpbmUsIHdpbGwgbm90IGFkZAorICAgKiB1cGRhdGVzIHRvIHRoZSAuTUVUQS4gdGFibGUuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc09ubGluZSgpIHsKKyAgICByZXR1cm4gdGhpcy5tZXRhVGFibGUgIT0gbnVsbDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYyBPbmxpbmUgdGhlIGhpc3Rvcmlhbi4gIEludm9rZSBhZnRlciBjbHVzdGVyIGhhcyBzcHVuIHVwLgorICAgKi8KKyAgcHVibGljIHZvaWQgb25saW5lKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjKSB7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMubWV0YVRhYmxlID0gbmV3IEhUYWJsZShjLCBNRVRBX1RBQkxFX05BTUUpOworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiT25saW5lZCIpOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgTE9HLmVycm9yKCJVbmFibGUgdG8gY3JlYXRlIFJlZ2lvbkhpc3RvcmlhbiIsIGlvZSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogT2ZmbGluZXMgdGhlIGhpc3Rvcmlhbi4KKyAgICogQHNlZSAjb25saW5lKEhCYXNlQ29uZmlndXJhdGlvbikKKyAgICovCisgIHB1YmxpYyB2b2lkIG9mZmxpbmUoKSB7CisgICAgdGhpcy5tZXRhVGFibGUgPSBudWxsOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJPZmZsaW5lZCIpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1JlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1JlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZmM4ZTU3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pcGMuUmVtb3RlRXhjZXB0aW9uOworCisvKiogCisgKiBBbiBpbW11dGFibGUgY2xhc3Mgd2hpY2ggY29udGFpbnMgYSBzdGF0aWMgbWV0aG9kIGZvciBoYW5kbGluZworICogb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbiBleGNlcHRpb25zLgorICovCitwdWJsaWMgY2xhc3MgUmVtb3RlRXhjZXB0aW9uSGFuZGxlciB7CisgIC8qIE5vdCBpbnN0YW50aWFibGUgKi8KKyAgcHJpdmF0ZSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyKCkge3N1cGVyKCk7fQorICAKKyAgLyoqCisgICAqIEV4YW1pbmUgcGFzc2VkIFRocm93YWJsZS4gIFNlZSBpZiBpdHMgY2FycnlpbmcgYSBSZW1vdGVFeGNlcHRpb24uIElmIHNvLAorICAgKiBydW4ge0BsaW5rICNkZWNvZGVSZW1vdGVFeGNlcHRpb24oUmVtb3RlRXhjZXB0aW9uKX0gb24gaXQuICBPdGhlcndpc2UsCisgICAqIHBhc3MgYmFjayA8Y29kZT50PC9jb2RlPiB1bmFsdGVyZWQuCisgICAqIEBwYXJhbSB0IFRocm93YWJsZSB0byBleGFtaW5lLgorICAgKiBAcmV0dXJuIERlY29kZWQgUmVtb3RlRXhjZXB0aW9uIGNhcnJpZWQgYnkgPGNvZGU+dDwvY29kZT4gb3IKKyAgICogPGNvZGU+dDwvY29kZT4gdW5hbHRlcmVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBUaHJvd2FibGUgY2hlY2tUaHJvd2FibGUoZmluYWwgVGhyb3dhYmxlIHQpIHsKKyAgICBUaHJvd2FibGUgcmVzdWx0ID0gdDsKKyAgICBpZiAodCBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgdHJ5IHsKKyAgICAgICAgcmVzdWx0ID0KKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbigoUmVtb3RlRXhjZXB0aW9uKXQpOworICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHR0KSB7CisgICAgICAgIHJlc3VsdCA9IHR0OworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogRXhhbWluZSBwYXNzZWQgSU9FeGNlcHRpb24uICBTZWUgaWYgaXRzIGNhcnJ5aW5nIGEgUmVtb3RlRXhjZXB0aW9uLiBJZiBzbywKKyAgICogcnVuIHtAbGluayAjZGVjb2RlUmVtb3RlRXhjZXB0aW9uKFJlbW90ZUV4Y2VwdGlvbil9IG9uIGl0LiAgT3RoZXJ3aXNlLAorICAgKiBwYXNzIGJhY2sgPGNvZGU+ZTwvY29kZT4gdW5hbHRlcmVkLgorICAgKiBAcGFyYW0gZSBFeGNlcHRpb24gdG8gZXhhbWluZS4KKyAgICogQHJldHVybiBEZWNvZGVkIFJlbW90ZUV4Y2VwdGlvbiBjYXJyaWVkIGJ5IDxjb2RlPmU8L2NvZGU+IG9yCisgICAqIDxjb2RlPmU8L2NvZGU+IHVuYWx0ZXJlZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSU9FeGNlcHRpb24gY2hlY2tJT0V4Y2VwdGlvbihmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgVGhyb3dhYmxlIHQgPSBjaGVja1Rocm93YWJsZShlKTsKKyAgICByZXR1cm4gdCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uPyAoSU9FeGNlcHRpb24pdDogbmV3IElPRXhjZXB0aW9uKHQpOworICB9CisgIAorICAvKioKKyAgICogQ29udmVydHMgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbiBpbnRvIG9yaWdpbmFsIGV4Y2VwdGlvbiwKKyAgICogaWYgcG9zc2libGUuIElmIHRoZSBvcmlnaW5hbCBleGNlcHRpb24gaXMgYW4gRXJyb3Igb3IgYSBSdW50aW1lRXhjZXB0aW9uLAorICAgKiB0aHJvd3MgdGhlIG9yaWdpbmFsIGV4Y2VwdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSByZSBvcmlnaW5hbCBleGNlcHRpb24KKyAgICogQHJldHVybiBkZWNvZGVkIFJlbW90ZUV4Y2VwdGlvbiBpZiBpdCBpcyBhbiBpbnN0YW5jZSBvZiBvciBhIHN1YmNsYXNzIG9mCisgICAqICAgICAgICAgSU9FeGNlcHRpb24sIG9yIHRoZSBvcmlnaW5hbCBSZW1vdGVFeGNlcHRpb24gaWYgaXQgY2Fubm90IGJlIGRlY29kZWQuCisgICAqIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGluZGljYXRpbmcgYSBzZXJ2ZXIgZXJyb3Igb2N1cnJlZCBpZiB0aGUgZGVjb2RlZCAKKyAgICogICAgICAgICBleGNlcHRpb24gaXMgbm90IGFuIElPRXhjZXB0aW9uLiBUaGUgZGVjb2RlZCBleGNlcHRpb24gaXMgc2V0IGFzCisgICAqICAgICAgICAgdGhlIGNhdXNlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBJT0V4Y2VwdGlvbiBkZWNvZGVSZW1vdGVFeGNlcHRpb24oZmluYWwgUmVtb3RlRXhjZXB0aW9uIHJlKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIElPRXhjZXB0aW9uIGkgPSByZTsKKworICAgIHRyeSB7CisgICAgICBDbGFzczw/PiBjID0gQ2xhc3MuZm9yTmFtZShyZS5nZXRDbGFzc05hbWUoKSk7CisKKyAgICAgIENsYXNzPD8+W10gcGFyYW1ldGVyVHlwZXMgPSB7IFN0cmluZy5jbGFzcyB9OworICAgICAgQ29uc3RydWN0b3I8Pz4gY3RvciA9IGMuZ2V0Q29uc3RydWN0b3IocGFyYW1ldGVyVHlwZXMpOworICAgICAgCisgICAgICBPYmplY3RbXSBhcmd1bWVudHMgPSB7IHJlLmdldE1lc3NhZ2UoKSB9OworICAgICAgVGhyb3dhYmxlIHQgPSAoVGhyb3dhYmxlKSBjdG9yLm5ld0luc3RhbmNlKGFyZ3VtZW50cyk7CisgICAgICAKKyAgICAgIGlmICh0IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHsKKyAgICAgICAgaSA9IChJT0V4Y2VwdGlvbikgdDsKKworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaSA9IG5ldyBJT0V4Y2VwdGlvbigic2VydmVyIGVycm9yIik7CisgICAgICAgIGkuaW5pdENhdXNlKHQpOworICAgICAgICB0aHJvdyBpOworICAgICAgfQorCisgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4KSB7CisgICAgICAvLyBjb250aW51ZQorICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB4KSB7CisgICAgICAvLyBjb250aW51ZQorICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24geCkgeworICAgICAgLy8gY29udGludWUKKyAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIHgpIHsKKyAgICAgIC8vIGNvbnRpbnVlCisgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiB4KSB7CisgICAgICAvLyBjb250aW51ZQorICAgIH0KKyAgICByZXR1cm4gaTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGFibGVFeGlzdHNFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1RhYmxlRXhpc3RzRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJjYzI5NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1RhYmxlRXhpc3RzRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIHdoZW4gYSB0YWJsZSBleGlzdHMgYnV0IHNob3VsZCBub3QKKyAqLworcHVibGljIGNsYXNzIFRhYmxlRXhpc3RzRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTCA8PCA3IC0gMUw7CisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBUYWJsZUV4aXN0c0V4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIAorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgVGFibGVFeGlzdHNFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1RhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1RhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Mjg3ODAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRocm93biBpZiBhIHRhYmxlIHNob3VsZCBiZSBvZmZsaW5lIGJ1dCBpcyBub3QKKyAqLworcHVibGljIGNsYXNzIFRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMIDw8IDE5IC0gMUw7CisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBUYWJsZU5vdERpc2FibGVkRXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHMgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIFRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIE5hbWUgb2YgdGFibGUgdGhhdCBpcyBub3QgZGlzYWJsZWQKKyAgICovCisgIHB1YmxpYyBUYWJsZU5vdERpc2FibGVkRXhjZXB0aW9uKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICB0aGlzKEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGFibGVOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGFibGVOb3RGb3VuZEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNmRhNDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UYWJsZU5vdEZvdW5kRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzNSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisvKiogVGhyb3duIHdoZW4gYSB0YWJsZSBjYW4gbm90IGJlIGxvY2F0ZWQgKi8KK3B1YmxpYyBjbGFzcyBUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIGV4dGVuZHMgUmVnaW9uRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gOTkzMTc5NjI3ODU2MzkyNTI2TDsKKworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVGFibGVOb3RGb3VuZEV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqIEBwYXJhbSBzIG1lc3NhZ2UgKi8KKyAgcHVibGljIFRhYmxlTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVW5rbm93blJvd0xvY2tFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Vua25vd25Sb3dMb2NrRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGNiMzk4NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Vua25vd25Sb3dMb2NrRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisKKy8qKgorICogVGhyb3duIGlmIGEgcmVnaW9uIHNlcnZlciBpcyBwYXNzZWQgYW4gdW5rbm93biByb3cgbG9jayBpZAorICovCitwdWJsaWMgY2xhc3MgVW5rbm93blJvd0xvY2tFeGNlcHRpb24gZXh0ZW5kcyBEb05vdFJldHJ5SU9FeGNlcHRpb24geworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA5OTMxNzk2Mjc4NTYzOTI1MjZMOworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVW5rbm93blJvd0xvY2tFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgVW5rbm93blJvd0xvY2tFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVW5rbm93blNjYW5uZXJFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Vua25vd25TY2FubmVyRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWFiNDFlZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Vua25vd25TY2FubmVyRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisKKy8qKgorICogVGhyb3duIGlmIGEgcmVnaW9uIHNlcnZlciBpcyBwYXNzZWQgYW4gdW5rbm93biBzY2FubmVyIGlkCisgKi8KK3B1YmxpYyBjbGFzcyBVbmtub3duU2Nhbm5lckV4Y2VwdGlvbiBleHRlbmRzIERvTm90UmV0cnlJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDk5MzE3OTYyNzg1NjM5MjUyNkw7CisKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBVbmtub3duU2Nhbm5lckV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBzIG1lc3NhZ2UKKyAgICovCisgIHB1YmxpYyBVbmtub3duU2Nhbm5lckV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgIHN1cGVyKHMpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVmFsdWVPdmVyTWF4TGVuZ3RoRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9WYWx1ZU92ZXJNYXhMZW5ndGhFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmMxMzZkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVmFsdWVPdmVyTWF4TGVuZ3RoRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCisvKioKKyAqIFRocm93biB3aGVuIGEgdmFsdWUgaXMgbG9uZ2VyIHRoYW4gdGhlIHNwZWNpZmllZCBMRU5HVEgKKyAqLworcHVibGljIGNsYXNzIFZhbHVlT3Zlck1heExlbmd0aEV4Y2VwdGlvbiBleHRlbmRzIERvTm90UmV0cnlJT0V4Y2VwdGlvbiB7CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTUyNTY1NjM1MjM3MjAwODMxNkw7CisKKyAgLyoqCisgICAqIGRlZmF1bHQgY29uc3RydWN0b3IKKyAgICovCisgIHB1YmxpYyBWYWx1ZU92ZXJNYXhMZW5ndGhFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbWVzc2FnZQorICAgKi8KKyAgcHVibGljIFZhbHVlT3Zlck1heExlbmd0aEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1ZlcnNpb25Bbm5vdGF0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9WZXJzaW9uQW5ub3RhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJmMjlhZGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9WZXJzaW9uQW5ub3RhdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uKjsKKworLyoqCisgKiBBIHBhY2thZ2UgYXR0cmlidXRlIHRoYXQgY2FwdHVyZXMgdGhlIHZlcnNpb24gb2YgaGJhc2UgdGhhdCB3YXMgY29tcGlsZWQuCisgKiBDb3BpZWQgZG93biBmcm9tIGhhZG9vcC4gIEFsbCBpcyBzYW1lIGV4Y2VwdCBuYW1lIG9mIGludGVyZmFjZS4KKyAqLworQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKK0BUYXJnZXQoRWxlbWVudFR5cGUuUEFDS0FHRSkKK3B1YmxpYyBAaW50ZXJmYWNlIFZlcnNpb25Bbm5vdGF0aW9uIHsKKyAKKyAgLyoqCisgICAqIEdldCB0aGUgSGFkb29wIHZlcnNpb24KKyAgICogQHJldHVybiB0aGUgdmVyc2lvbiBzdHJpbmcgIjAuNi4zLWRldiIKKyAgICovCisgIFN0cmluZyB2ZXJzaW9uKCk7CisgIAorICAvKioKKyAgICogR2V0IHRoZSB1c2VybmFtZSB0aGF0IGNvbXBpbGVkIEhhZG9vcC4KKyAgICovCisgIFN0cmluZyB1c2VyKCk7CisgIAorICAvKioKKyAgICogR2V0IHRoZSBkYXRlIHdoZW4gSGFkb29wIHdhcyBjb21waWxlZC4KKyAgICogQHJldHVybiB0aGUgZGF0ZSBpbiB1bml4ICdkYXRlJyBmb3JtYXQKKyAgICovCisgIFN0cmluZyBkYXRlKCk7CisgIAorICAvKioKKyAgICogR2V0IHRoZSB1cmwgZm9yIHRoZSBzdWJ2ZXJzaW9uIHJlcG9zaXRvcnkuCisgICAqLworICBTdHJpbmcgdXJsKCk7CisgIAorICAvKioKKyAgICogR2V0IHRoZSBzdWJ2ZXJzaW9uIHJldmlzaW9uLgorICAgKiBAcmV0dXJuIHRoZSByZXZpc2lvbiBudW1iZXIgYXMgYSBzdHJpbmcgKGVnLiAiNDUxNDUxIikKKyAgICovCisgIFN0cmluZyByZXZpc2lvbigpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvV3JpdGFibGVDb21wYXJhdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9Xcml0YWJsZUNvbXBhcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzY1ZDY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvV3JpdGFibGVDb21wYXJhdG9yLmphdmEKQEAgLTAsMCArMSwyOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKKworcHVibGljIGludGVyZmFjZSBXcml0YWJsZUNvbXBhcmF0b3I8VD4gZXh0ZW5kcyBXcml0YWJsZSwgQ29tcGFyYXRvcjxUPiB7CisvLyBObyBtZXRob2RzLCBqdXN0IGJyaW5nIHRoZSB0d28gaW50ZXJmYWNlcyB0b2dldGhlcgorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L0hCYXNlQWRtaW4uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQmFzZUFkbWluLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTE3OTVjMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQmFzZUFkbWluLmphdmEKQEAgLTAsMCArMSw4MTIgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uTG9jYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5NYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlZ2lvbkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhNYXN0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLk1ldGFVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Cb29sZWFuV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbjsKKworLyoqCisgKiBQcm92aWRlcyBhZG1pbmlzdHJhdGl2ZSBmdW5jdGlvbnMgZm9yIEhCYXNlCisgKi8KK3B1YmxpYyBjbGFzcyBIQmFzZUFkbWluIHsKKyAgcHJpdmF0ZSBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgIHByaXZhdGUgZmluYWwgSENvbm5lY3Rpb24gY29ubmVjdGlvbjsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIHBhdXNlOworICBwcml2YXRlIGZpbmFsIGludCBudW1SZXRyaWVzOworICBwcml2YXRlIHZvbGF0aWxlIEhNYXN0ZXJJbnRlcmZhY2UgbWFzdGVyOworCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiAKKyAgICogQHBhcmFtIGNvbmYgQ29uZmlndXJhdGlvbiBvYmplY3QKKyAgICogQHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSEJhc2VBZG1pbihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24geworICAgIHRoaXMuY29ubmVjdGlvbiA9IEhDb25uZWN0aW9uTWFuYWdlci5nZXRDb25uZWN0aW9uKGNvbmYpOworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgdGhpcy5wYXVzZSA9IGNvbmYuZ2V0TG9uZygiaGJhc2UuY2xpZW50LnBhdXNlIiwgMzAgKiAxMDAwKTsKKyAgICB0aGlzLm51bVJldHJpZXMgPSBjb25mLmdldEludCgiaGJhc2UuY2xpZW50LnJldHJpZXMubnVtYmVyIiwgNSk7CisgICAgdGhpcy5tYXN0ZXIgPSBjb25uZWN0aW9uLmdldE1hc3RlcigpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gcHJveHkgY29ubmVjdGlvbiB0byBtYXN0ZXIgc2VydmVyIGZvciB0aGlzIGluc3RhbmNlCisgICAqIEB0aHJvd3MgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhNYXN0ZXJJbnRlcmZhY2UgZ2V0TWFzdGVyKCkgdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb257CisgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbi5nZXRNYXN0ZXIoKTsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gLSB0cnVlIGlmIHRoZSBtYXN0ZXIgc2VydmVyIGlzIHJ1bm5pbmcgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNNYXN0ZXJSdW5uaW5nKCkgeworICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uaXNNYXN0ZXJSdW5uaW5nKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBUYWJsZSB0byBjaGVjay4KKyAgICogQHJldHVybiBUcnVlIGlmIHRhYmxlIGV4aXN0cyBhbHJlYWR5LgorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHRhYmxlRXhpc3RzKGZpbmFsIFN0cmluZyB0YWJsZU5hbWUpCisgIHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gdGFibGVFeGlzdHMoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIFRhYmxlIHRvIGNoZWNrLgorICAgKiBAcmV0dXJuIFRydWUgaWYgdGFibGUgZXhpc3RzIGFscmVhZHkuCisgICAqIEB0aHJvd3MgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gdGFibGVFeGlzdHMoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpCisgIHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5tYXN0ZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oIm1hc3RlciBoYXMgYmVlbiBzaHV0IGRvd24iKTsKKyAgICB9CisgICAgcmV0dXJuIGNvbm5lY3Rpb24udGFibGVFeGlzdHModGFibGVOYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBMaXN0IGFsbCB0aGUgdXNlcnNwYWNlIHRhYmxlcy4gIEluIG90aGVyIHdvcmRzLCBzY2FuIHRoZSBNRVRBIHRhYmxlLgorICAgKgorICAgKiBJZiB3ZSB3YW50ZWQgdGhpcyB0byBiZSByZWFsbHkgZmFzdCwgd2UgY291bGQgaW1wbGVtZW50IGEgc3BlY2lhbAorICAgKiBjYXRhbG9nIHRhYmxlIHRoYXQganVzdCBjb250YWlucyB0YWJsZSBuYW1lcyBhbmQgdGhlaXIgZGVzY3JpcHRvcnMuCisgICAqIFJpZ2h0IG5vdywgaXQgb25seSBleGlzdHMgYXMgcGFydCBvZiB0aGUgTUVUQSB0YWJsZSdzIHJlZ2lvbiBpbmZvLgorICAgKgorICAgKiBAcmV0dXJuIC0gcmV0dXJucyBhbiBhcnJheSBvZiBIVGFibGVEZXNjcmlwdG9ycyAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3JbXSBsaXN0VGFibGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uLmxpc3RUYWJsZXMoKTsKKyAgfQorCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlRGVzY3JpcHRvcihmaW5hbCBTdHJpbmcgdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRUYWJsZURlc2NyaXB0b3IoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgfQorICAKKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3IgZ2V0VGFibGVEZXNjcmlwdG9yKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uZ2V0SFRhYmxlRGVzY3JpcHRvcih0YWJsZU5hbWUpOworICB9CisgIAorICBwcml2YXRlIGxvbmcgZ2V0UGF1c2VUaW1lKGludCB0cmllcykgeworCWludCB0cmllc0NvdW50ID0gdHJpZXM7CisgICAgaWYgKHRyaWVzQ291bnQgPj0gSENvbnN0YW50cy5SRVRSWV9CQUNLT0ZGLmxlbmd0aCkKKyAgICAJdHJpZXNDb3VudCA9IEhDb25zdGFudHMuUkVUUllfQkFDS09GRi5sZW5ndGggLSAxOworICAgIHJldHVybiB0aGlzLnBhdXNlICogSENvbnN0YW50cy5SRVRSWV9CQUNLT0ZGW3RyaWVzQ291bnRdOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgdGFibGUuCisgICAqIFN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSBkZXNjIHRhYmxlIGRlc2NyaXB0b3IgZm9yIHRhYmxlCisgICAqIAorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdGFibGUgbmFtZSBpcyByZXNlcnZlZAorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24gaWYgbWFzdGVyIGlzIG5vdCBydW5uaW5nCisgICAqIEB0aHJvd3MgVGFibGVFeGlzdHNFeGNlcHRpb24gaWYgdGFibGUgYWxyZWFkeSBleGlzdHMgKElmIGNvbmN1cnJlbnQKKyAgICogdGhyZWFkcywgdGhlIHRhYmxlIG1heSBoYXZlIGJlZW4gY3JlYXRlZCBiZXR3ZWVuIHRlc3QtZm9yLWV4aXN0ZW5jZQorICAgKiBhbmQgYXR0ZW1wdC1hdC1jcmVhdGlvbikuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGNyZWF0ZVRhYmxlKEhUYWJsZURlc2NyaXB0b3IgZGVzYykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yLmlzTGVnYWxUYWJsZU5hbWUoZGVzYy5nZXROYW1lKCkpOworICAgIGNyZWF0ZVRhYmxlQXN5bmMoZGVzYyk7CisgICAgZm9yIChpbnQgdHJpZXMgPSAwOyB0cmllcyA8IG51bVJldHJpZXM7IHRyaWVzKyspIHsKKyAgICAgIHRyeSB7CisgICAgICAgIC8vIFdhaXQgZm9yIG5ldyB0YWJsZSB0byBjb21lIG9uLWxpbmUKKyAgICAgICAgY29ubmVjdGlvbi5sb2NhdGVSZWdpb24oZGVzYy5nZXROYW1lKCksIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgICAgfSBjYXRjaCAoUmVnaW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgaWYgKHRyaWVzID09IG51bVJldHJpZXMgLSAxKSB7CisgICAgICAgICAgLy8gUmFuIG91dCBvZiB0cmllcworICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUodHJpZXMpKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gY29udGludWUKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBDcmVhdGVzIGEgbmV3IHRhYmxlIGJ1dCBkb2VzIG5vdCBibG9jayBhbmQgd2FpdCBmb3IgaXQgdG8gY29tZSBvbmxpbmUuCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gZGVzYyB0YWJsZSBkZXNjcmlwdG9yIGZvciB0YWJsZQorICAgKiAKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gQmFkIHRhYmxlIG5hbWUuCisgICAqIEB0aHJvd3MgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbiBpZiBtYXN0ZXIgaXMgbm90IHJ1bm5pbmcKKyAgICogQHRocm93cyBUYWJsZUV4aXN0c0V4Y2VwdGlvbiBpZiB0YWJsZSBhbHJlYWR5IGV4aXN0cyAoSWYgY29uY3VycmVudAorICAgKiB0aHJlYWRzLCB0aGUgdGFibGUgbWF5IGhhdmUgYmVlbiBjcmVhdGVkIGJldHdlZW4gdGVzdC1mb3ItZXhpc3RlbmNlCisgICAqIGFuZCBhdHRlbXB0LWF0LWNyZWF0aW9uKS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY3JlYXRlVGFibGVBc3luYyhIVGFibGVEZXNjcmlwdG9yIGRlc2MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMubWFzdGVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCJtYXN0ZXIgaGFzIGJlZW4gc2h1dCBkb3duIik7CisgICAgfQorICAgIEhUYWJsZURlc2NyaXB0b3IuaXNMZWdhbFRhYmxlTmFtZShkZXNjLmdldE5hbWUoKSk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMubWFzdGVyLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIH0gY2F0Y2ggKFJlbW90ZUV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRGVsZXRlcyBhIHRhYmxlLgorICAgKiBTeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gZGVsZXRlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZVRhYmxlKGZpbmFsIFN0cmluZyB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlVGFibGUoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGVzIGEgdGFibGUuCisgICAqIFN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBkZWxldGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlVGFibGUoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMubWFzdGVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCJtYXN0ZXIgaGFzIGJlZW4gc2h1dCBkb3duIik7CisgICAgfQorICAgIEhUYWJsZURlc2NyaXB0b3IuaXNMZWdhbFRhYmxlTmFtZSh0YWJsZU5hbWUpOworICAgIEhSZWdpb25Mb2NhdGlvbiBmaXJzdE1ldGFTZXJ2ZXIgPSBnZXRGaXJzdE1ldGFTZXJ2ZXJGb3JUYWJsZSh0YWJsZU5hbWUpOworICAgIHRyeSB7CisgICAgICB0aGlzLm1hc3Rlci5kZWxldGVUYWJsZSh0YWJsZU5hbWUpOworICAgIH0gY2F0Y2ggKFJlbW90ZUV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbihlKTsKKyAgICB9CisKKyAgICAvLyBXYWl0IHVudGlsIGZpcnN0IHJlZ2lvbiBpcyBkZWxldGVkCisgICAgSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXIgPQorICAgICAgY29ubmVjdGlvbi5nZXRIUmVnaW9uQ29ubmVjdGlvbihmaXJzdE1ldGFTZXJ2ZXIuZ2V0U2VydmVyQWRkcmVzcygpKTsKKyAgICBIUmVnaW9uSW5mbyBpbmZvID0gbmV3IEhSZWdpb25JbmZvKCk7CisgICAgZm9yIChpbnQgdHJpZXMgPSAwOyB0cmllcyA8IG51bVJldHJpZXM7IHRyaWVzKyspIHsKKyAgICAgIGxvbmcgc2Nhbm5lcklkID0gLTFMOworICAgICAgdHJ5IHsKKyAgICAgICAgc2Nhbm5lcklkID0KKyAgICAgICAgICBzZXJ2ZXIub3BlblNjYW5uZXIoZmlyc3RNZXRhU2VydmVyLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgICBIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPX0FSUkFZLCB0YWJsZU5hbWUsCisgICAgICAgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgICAgICBSb3dSZXN1bHQgdmFsdWVzID0gc2VydmVyLm5leHQoc2Nhbm5lcklkKTsKKyAgICAgICAgaWYgKHZhbHVlcyA9PSBudWxsIHx8IHZhbHVlcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4gZTogdmFsdWVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICBpZiAoQnl0ZXMuZXF1YWxzKGUuZ2V0S2V5KCksIEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8pKSB7CisgICAgICAgICAgICBpbmZvID0gKEhSZWdpb25JbmZvKSBXcml0YWJsZXMuZ2V0V3JpdGFibGUoCisgICAgICAgICAgICAgIGUuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpLCBpbmZvKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgdGFibGVOYW1lKSkgeworICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICghZm91bmQpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICBpZih0cmllcyA9PSBudW1SZXRyaWVzIC0gMSkgeyAgICAgICAgICAgLy8gbm8gbW9yZSB0cmllcyBsZWZ0CisgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgUmVtb3RlRXhjZXB0aW9uKSB7CisgICAgICAgICAgICBleCA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKChSZW1vdGVFeGNlcHRpb24pIGV4KTsKKyAgICAgICAgICB9CisgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgIH0KKworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgaWYgKHNjYW5uZXJJZCAhPSAtMUwpIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyLmNsb3NlKHNjYW5uZXJJZCk7CisgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBMT0cud2FybihleCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHRyeSB7CisgICAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUodHJpZXMpKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gY29udGludWUKKyAgICAgIH0KKyAgICB9CisgICAgLy8gRGVsZXRlIGNhY2hlZCBpbmZvcm1hdGlvbiB0byBwcmV2ZW50IGNsaWVudHMgZnJvbSB1c2luZyBvbGQgbG9jYXRpb25zCisgICAgSENvbm5lY3Rpb25NYW5hZ2VyLmRlbGV0ZUNvbm5lY3Rpb25JbmZvKGNvbmYsIGZhbHNlKTsKKyAgICBMT0cuaW5mbygiRGVsZXRlZCAiICsgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogQnJpbmdzIGEgdGFibGUgb24tbGluZSAoZW5hYmxlcyBpdCkuCisgICAqIFN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZW5hYmxlVGFibGUoZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBlbmFibGVUYWJsZShCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSkpOworICB9CisKKyAgLyoqCisgICAqIEJyaW5ncyBhIHRhYmxlIG9uLWxpbmUgKGVuYWJsZXMgaXQpLgorICAgKiBTeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGhlIHRhYmxlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGVuYWJsZVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLm1hc3RlciA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbigibWFzdGVyIGhhcyBiZWVuIHNodXQgZG93biIpOworICAgIH0KKyAgICB0cnkgeworICAgICAgdGhpcy5tYXN0ZXIuZW5hYmxlVGFibGUodGFibGVOYW1lKTsKKyAgICB9IGNhdGNoIChSZW1vdGVFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oZSk7CisgICAgfQorCisgICAgLy8gV2FpdCB1bnRpbCBhbGwgcmVnaW9ucyBhcmUgZW5hYmxlZAorICAgIAorICAgIGZvciAoaW50IHRyaWVzID0gMDsKKyAgICAgICAgKHRyaWVzIDwgbnVtUmV0cmllcykgJiYgKCFpc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpKTsKKyAgICAgICAgdHJpZXMrKykgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiU2xlZXAuIFdhaXRpbmcgZm9yIGFsbCByZWdpb25zIHRvIGJlIGVuYWJsZWQgZnJvbSAiICsKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUodHJpZXMpKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gY29udGludWUKKyAgICAgIH0KKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoIldha2UuIFdhaXRpbmcgZm9yIGFsbCByZWdpb25zIHRvIGJlIGVuYWJsZWQgZnJvbSAiICsKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKCFpc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpKQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ1bmFibGUgdG8gZW5hYmxlIHRhYmxlICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgICBMT0cuaW5mbygiRW5hYmxlZCB0YWJsZSAiICsgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogRGlzYWJsZXMgYSB0YWJsZSAodGFrZXMgaXQgb2ZmLWxpbmUpIElmIGl0IGlzIGJlaW5nIHNlcnZlZCwgdGhlIG1hc3RlcgorICAgKiB3aWxsIHRlbGwgdGhlIHNlcnZlcnMgdG8gc3RvcCBzZXJ2aW5nIGl0LgorICAgKiBTeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGlzYWJsZVRhYmxlKGZpbmFsIFN0cmluZyB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGlzYWJsZVRhYmxlKEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogRGlzYWJsZXMgYSB0YWJsZSAodGFrZXMgaXQgb2ZmLWxpbmUpIElmIGl0IGlzIGJlaW5nIHNlcnZlZCwgdGhlIG1hc3RlcgorICAgKiB3aWxsIHRlbGwgdGhlIHNlcnZlcnMgdG8gc3RvcCBzZXJ2aW5nIGl0LgorICAgKiBTeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGlzYWJsZVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLm1hc3RlciA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbigibWFzdGVyIGhhcyBiZWVuIHNodXQgZG93biIpOworICAgIH0KKyAgICB0cnkgeworICAgICAgdGhpcy5tYXN0ZXIuZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgfSBjYXRjaCAoUmVtb3RlRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKGUpOworICAgIH0KKworICAgIC8vIFdhaXQgdW50aWwgYWxsIHJlZ2lvbnMgYXJlIGRpc2FibGVkCisgICAgZm9yIChpbnQgdHJpZXMgPSAwOworICAgICAgICAodHJpZXMgPCBudW1SZXRyaWVzKSAmJiAoIWlzVGFibGVEaXNhYmxlZCh0YWJsZU5hbWUpKTsKKyAgICAgICAgdHJpZXMrKykgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiU2xlZXAuIFdhaXRpbmcgZm9yIGFsbCByZWdpb25zIHRvIGJlIGRpc2FibGVkIGZyb20gIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoZ2V0UGF1c2VUaW1lKHRyaWVzKSk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICB9CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJXYWtlLiBXYWl0aW5nIGZvciBhbGwgcmVnaW9ucyB0byBiZSBkaXNhYmxlZCBmcm9tICIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkpOworICAgICAgfQorICAgIH0KKyAgICBpZiAoIWlzVGFibGVEaXNhYmxlZCh0YWJsZU5hbWUpKSB7CisgICAgICB0aHJvdyBuZXcgUmVnaW9uRXhjZXB0aW9uKCJSZXRyaWVzIGV4aGF1c3RlZCwgaXQgdG9vayB0b28gbG9uZyB0byB3YWl0IisKKyAgICAgICAgIiBmb3IgdGhlIHRhYmxlICIgKyBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpICsgIiB0byBiZSBkaXNhYmxlZC4iKTsKKyAgICB9CisgICAgTE9HLmluZm8oIkRpc2FibGVkICIgKyBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBjaGVjaworICAgKiBAcmV0dXJuIHRydWUgaWYgdGFibGUgaXMgb24tbGluZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1RhYmxlRW5hYmxlZChTdHJpbmcgdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBpc1RhYmxlRW5hYmxlZChCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSkpOworICB9CisgIC8qKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gY2hlY2sKKyAgICogQHJldHVybiB0cnVlIGlmIHRhYmxlIGlzIG9uLWxpbmUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNUYWJsZUVuYWJsZWQoYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5pc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlIHRvIGNoZWNrCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0YWJsZSBpcyBvZmYtbGluZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1RhYmxlRGlzYWJsZWQoYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5pc1RhYmxlRGlzYWJsZWQodGFibGVOYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGQgYSBjb2x1bW4gdG8gYW4gZXhpc3RpbmcgdGFibGUuCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGhlIHRhYmxlIHRvIGFkZCBjb2x1bW4gdG8KKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gZGVzY3JpcHRvciBvZiBjb2x1bW4gdG8gYmUgYWRkZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkQ29sdW1uKGZpbmFsIFN0cmluZyB0YWJsZU5hbWUsIEhDb2x1bW5EZXNjcmlwdG9yIGNvbHVtbikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhZGRDb2x1bW4oQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpLCBjb2x1bW4pOworICB9CisKKyAgLyoqCisgICAqIEFkZCBhIGNvbHVtbiB0byBhbiBleGlzdGluZyB0YWJsZS4KKyAgICogQXN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUgdG8gYWRkIGNvbHVtbiB0bworICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBkZXNjcmlwdG9yIG9mIGNvbHVtbiB0byBiZSBhZGRlZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBhZGRDb2x1bW4oZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsIEhDb2x1bW5EZXNjcmlwdG9yIGNvbHVtbikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5tYXN0ZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oIm1hc3RlciBoYXMgYmVlbiBzaHV0IGRvd24iKTsKKyAgICB9CisgICAgSFRhYmxlRGVzY3JpcHRvci5pc0xlZ2FsVGFibGVOYW1lKHRhYmxlTmFtZSk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMubWFzdGVyLmFkZENvbHVtbih0YWJsZU5hbWUsIGNvbHVtbik7CisgICAgfSBjYXRjaCAoUmVtb3RlRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYSBjb2x1bW4gZnJvbSBhIHRhYmxlLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lIG5hbWUgb2YgY29sdW1uIHRvIGJlIGRlbGV0ZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQ29sdW1uKGZpbmFsIFN0cmluZyB0YWJsZU5hbWUsIGZpbmFsIFN0cmluZyBjb2x1bW5OYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUNvbHVtbihCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSksIEJ5dGVzLnRvQnl0ZXMoY29sdW1uTmFtZSkpOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZSBhIGNvbHVtbiBmcm9tIGEgdGFibGUuCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIGNvbHVtbk5hbWUgbmFtZSBvZiBjb2x1bW4gdG8gYmUgZGVsZXRlZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVDb2x1bW4oZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsIGZpbmFsIGJ5dGUgW10gY29sdW1uTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5tYXN0ZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oIm1hc3RlciBoYXMgYmVlbiBzaHV0IGRvd24iKTsKKyAgICB9CisgICAgSFRhYmxlRGVzY3JpcHRvci5pc0xlZ2FsVGFibGVOYW1lKHRhYmxlTmFtZSk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMubWFzdGVyLmRlbGV0ZUNvbHVtbih0YWJsZU5hbWUsIGNvbHVtbk5hbWUpOworICAgIH0gY2F0Y2ggKFJlbW90ZUV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTW9kaWZ5IGFuIGV4aXN0aW5nIGNvbHVtbiBmYW1pbHkgb24gYSB0YWJsZS4KKyAgICogQXN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gY29sdW1uTmFtZSBuYW1lIG9mIGNvbHVtbiB0byBiZSBtb2RpZmllZAorICAgKiBAcGFyYW0gZGVzY3JpcHRvciBuZXcgY29sdW1uIGRlc2NyaXB0b3IgdG8gdXNlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIG1vZGlmeUNvbHVtbihmaW5hbCBTdHJpbmcgdGFibGVOYW1lLCBmaW5hbCBTdHJpbmcgY29sdW1uTmFtZSwgCisgICAgICBIQ29sdW1uRGVzY3JpcHRvciBkZXNjcmlwdG9yKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG1vZGlmeUNvbHVtbihCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSksIEJ5dGVzLnRvQnl0ZXMoY29sdW1uTmFtZSksCisgICAgICBkZXNjcmlwdG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBNb2RpZnkgYW4gZXhpc3RpbmcgY29sdW1uIGZhbWlseSBvbiBhIHRhYmxlLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lIG5hbWUgb2YgY29sdW1uIHRvIGJlIG1vZGlmaWVkCisgICAqIEBwYXJhbSBkZXNjcmlwdG9yIG5ldyBjb2x1bW4gZGVzY3JpcHRvciB0byB1c2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgbW9kaWZ5Q29sdW1uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLCBmaW5hbCBieXRlIFtdIGNvbHVtbk5hbWUsIAorICAgIEhDb2x1bW5EZXNjcmlwdG9yIGRlc2NyaXB0b3IpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMubWFzdGVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCJtYXN0ZXIgaGFzIGJlZW4gc2h1dCBkb3duIik7CisgICAgfQorICAgIEhUYWJsZURlc2NyaXB0b3IuaXNMZWdhbFRhYmxlTmFtZSh0YWJsZU5hbWUpOworICAgIHRyeSB7CisgICAgICB0aGlzLm1hc3Rlci5tb2RpZnlDb2x1bW4odGFibGVOYW1lLCBjb2x1bW5OYW1lLCBkZXNjcmlwdG9yKTsKKyAgICB9IGNhdGNoIChSZW1vdGVFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENsb3NlIGEgcmVnaW9uLiBGb3IgZXhwZXJ0LWFkbWlucy4KKyAgICogQXN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb25uYW1lCisgICAqIEBwYXJhbSBhcmdzIE9wdGlvbmFsIHNlcnZlciBuYW1lLiAgT3RoZXJ3aXNlLCB3ZSdsbCBzZW5kIGNsb3NlIHRvIHRoZQorICAgKiBzZXJ2ZXIgcmVnaXN0ZXJlZCBpbiAuTUVUQS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2VSZWdpb24oZmluYWwgU3RyaW5nIHJlZ2lvbm5hbWUsIGZpbmFsIE9iamVjdC4uLiBhcmdzKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNsb3NlUmVnaW9uKEJ5dGVzLnRvQnl0ZXMocmVnaW9ubmFtZSksIGFyZ3MpOworICB9CisKKyAgLyoqCisgICAqIENsb3NlIGEgcmVnaW9uLiAgRm9yIGV4cGVydC1hZG1pbnMuCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9ubmFtZQorICAgKiBAcGFyYW0gYXJncyBPcHRpb25hbCBzZXJ2ZXIgbmFtZS4gIE90aGVyd2lzZSwgd2UnbGwgc2VuZCBjbG9zZSB0byB0aGUKKyAgICogc2VydmVyIHJlZ2lzdGVyZWQgaW4gLk1FVEEuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGNsb3NlUmVnaW9uKGZpbmFsIGJ5dGUgW10gcmVnaW9ubmFtZSwgZmluYWwgT2JqZWN0Li4uIGFyZ3MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQmUgY2FyZWZ1bC4gTXVzdCBtYXRjaCB0aGUgaGFuZGxlciBvdmVyIGluIEhNYXN0ZXIgYXQgTU9ESUZZX0NMT1NFX1JFR0lPTgorICAgIGludCBsZW4gPSAoYXJncyA9PSBudWxsKT8gMDogYXJncy5sZW5ndGg7CisgICAgaW50IHh0cmFBcmdzQ291bnQgPSAxOworICAgIE9iamVjdCBbXSBuZXdhcmdzID0gbmV3IE9iamVjdFtsZW4gKyB4dHJhQXJnc0NvdW50XTsKKyAgICBuZXdhcmdzWzBdID0gcmVnaW9ubmFtZTsKKyAgICBpZihhcmdzICE9IG51bGwpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgbmV3YXJnc1tpICsgeHRyYUFyZ3NDb3VudF0gPSBhcmdzW2ldOworICAgICAgfQorICAgIH0KKyAgICBtb2RpZnlUYWJsZShIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSwgSENvbnN0YW50cy5NT0RJRllfQ0xPU0VfUkVHSU9OLAorICAgICAgbmV3YXJncyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBGbHVzaCBhIHRhYmxlIG9yIGFuIGluZGl2aWR1YWwgcmVnaW9uLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZU9yUmVnaW9uTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBmbHVzaChmaW5hbCBTdHJpbmcgdGFibGVOYW1lT3JSZWdpb25OYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZsdXNoKEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lT3JSZWdpb25OYW1lKSk7CisgIH0KKworICAvKioKKyAgICogRmx1c2ggYSB0YWJsZSBvciBhbiBpbmRpdmlkdWFsIHJlZ2lvbi4KKyAgICogQXN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZmx1c2goZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbW9kaWZ5VGFibGUodGFibGVOYW1lT3JSZWdpb25OYW1lLCBIQ29uc3RhbnRzLk1PRElGWV9UQUJMRV9GTFVTSCk7CisgIH0KKworICAvKioKKyAgICogQ29tcGFjdCBhIHRhYmxlIG9yIGFuIGluZGl2aWR1YWwgcmVnaW9uLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZU9yUmVnaW9uTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBjb21wYWN0KGZpbmFsIFN0cmluZyB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29tcGFjdChCeXRlcy50b0J5dGVzKHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkpOworICB9CisKKyAgLyoqCisgICAqIENvbXBhY3QgYSB0YWJsZSBvciBhbiBpbmRpdmlkdWFsIHJlZ2lvbi4KKyAgICogQXN5bmNocm9ub3VzIG9wZXJhdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY29tcGFjdChmaW5hbCBieXRlIFtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBtb2RpZnlUYWJsZSh0YWJsZU5hbWVPclJlZ2lvbk5hbWUsIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX0NPTVBBQ1QpOworICB9CisgIAorICAvKioKKyAgICogTWFqb3IgY29tcGFjdCBhIHRhYmxlIG9yIGFuIGluZGl2aWR1YWwgcmVnaW9uLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZU9yUmVnaW9uTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBtYWpvckNvbXBhY3QoZmluYWwgU3RyaW5nIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBtYWpvckNvbXBhY3QoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBNYWpvciBjb21wYWN0IGEgdGFibGUgb3IgYW4gaW5kaXZpZHVhbCByZWdpb24uCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lT3JSZWdpb25OYW1lCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIG1ham9yQ29tcGFjdChmaW5hbCBieXRlIFtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBtb2RpZnlUYWJsZSh0YWJsZU5hbWVPclJlZ2lvbk5hbWUsIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX01BSk9SX0NPTVBBQ1QpOworICB9CisKKyAgLyoqCisgICAqIFNwbGl0IGEgdGFibGUgb3IgYW4gaW5kaXZpZHVhbCByZWdpb24uCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lT3JSZWdpb25OYW1lCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHNwbGl0KGZpbmFsIFN0cmluZyB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3BsaXQoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWVPclJlZ2lvbk5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBTcGxpdCBhIHRhYmxlIG9yIGFuIGluZGl2aWR1YWwgcmVnaW9uLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZU9yUmVnaW9uTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzcGxpdChmaW5hbCBieXRlIFtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBtb2RpZnlUYWJsZSh0YWJsZU5hbWVPclJlZ2lvbk5hbWUsIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX1NQTElUKTsKKyAgfQorCisgIC8qCisgICAqIENhbGwgbW9kaWZ5VGFibGUgdXNpbmcgcGFzc2VkIHRhYmxlTmFtZSBvciByZWdpb24gbmFtZSBTdHJpbmcuICBJZiBubworICAgKiBzdWNoIHRhYmxlLCBwcmVzdW1lIHdlIGhhdmUgYmVlbiBwYXNzZWQgYSByZWdpb24gbmFtZS4KKyAgICogQHBhcmFtIHRhYmxlTmFtZU9yUmVnaW9uTmFtZQorICAgKiBAcGFyYW0gb3AKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIG1vZGlmeVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lT3JSZWdpb25OYW1lLCBmaW5hbCBpbnQgb3ApCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQYXNzIGEgdGFibGUgbmFtZSBvciByZWdpb24gbmFtZSIpOworICAgIH0KKyAgICBieXRlIFtdIHRhYmxlTmFtZSA9IHRhYmxlRXhpc3RzKHRhYmxlTmFtZU9yUmVnaW9uTmFtZSk/CisgICAgICB0YWJsZU5hbWVPclJlZ2lvbk5hbWU6IG51bGw7CisgICAgYnl0ZSBbXSByZWdpb25OYW1lID0gdGFibGVOYW1lID09IG51bGw/IHRhYmxlTmFtZU9yUmVnaW9uTmFtZTogbnVsbDsKKyAgICBPYmplY3QgW10gYXJncyA9IHJlZ2lvbk5hbWUgPT0gbnVsbD8gbnVsbDogbmV3IGJ5dGUgW11bXSB7cmVnaW9uTmFtZX07CisgICAgbW9kaWZ5VGFibGUodGFibGVOYW1lID09IG51bGw/IG51bGw6IHRhYmxlTmFtZSwgb3AsIGFyZ3MpOworICB9CisgIAorICAvKioKKyAgICogTW9kaWZ5IGFuIGV4aXN0aW5nIHRhYmxlLCBtb3JlIElSQiBmcmllbmRseSB2ZXJzaW9uLgorICAgKiBBc3luY2hyb25vdXMgb3BlcmF0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlLgorICAgKiBAcGFyYW0gaHRkIG1vZGlmaWVkIGRlc2NyaXB0aW9uIG9mIHRoZSB0YWJsZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBtb2RpZnlUYWJsZShmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgSFRhYmxlRGVzY3JpcHRvciBodGQpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG1vZGlmeVRhYmxlKHRhYmxlTmFtZSwgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfU0VUX0hURCwgaHRkKTsKKyAgfQorCisgIC8qKgorICAgKiBNb2RpZnkgYW4gZXhpc3RpbmcgdGFibGUuCisgICAqIEFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUuICBNYXkgYmUgbnVsbCBpZiB3ZSBhcmUgb3BlcmF0aW5nIG9uIGEKKyAgICogcmVnaW9uLgorICAgKiBAcGFyYW0gb3AgdGFibGUgbW9kaWZpY2F0aW9uIG9wZXJhdGlvbgorICAgKiBAcGFyYW0gYXJncyBvcGVyYXRpb24gc3BlY2lmaWMgYXJndW1lbnRzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIG1vZGlmeVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLCBpbnQgb3AsIE9iamVjdC4uLiBhcmdzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5tYXN0ZXIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oIm1hc3RlciBoYXMgYmVlbiBzaHV0IGRvd24iKTsKKyAgICB9CisgICAgLy8gTGV0IHBhc3MgaWYgaXRzIGEgY2F0YWxvZyB0YWJsZS4gIFVzZWQgYnkgYWRtaW5zLgorICAgIGlmICh0YWJsZU5hbWUgIT0gbnVsbCAmJiAhTWV0YVV0aWxzLmlzTWV0YVRhYmxlTmFtZSh0YWJsZU5hbWUpKSB7CisgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgZXhjZXB0aW9uCisgICAgICBIVGFibGVEZXNjcmlwdG9yLmlzTGVnYWxUYWJsZU5hbWUodGFibGVOYW1lKTsKKyAgICB9CisgICAgV3JpdGFibGVbXSBhcnIgPSBudWxsOworICAgIHRyeSB7CisgICAgICBzd2l0Y2ggKG9wKSB7CisgICAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX1NFVF9IVEQ6CisgICAgICAgIGlmIChhcmdzID09IG51bGwgfHwgYXJncy5sZW5ndGggPCAxIHx8IAorICAgICAgICAgICAgIShhcmdzWzBdIGluc3RhbmNlb2YgSFRhYmxlRGVzY3JpcHRvcikpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTRVRfSFREIHJlcXVpcmVzIGEgSFRhYmxlRGVzY3JpcHRvciIpOworICAgICAgICB9CisgICAgICAgIGFyciA9IG5ldyBXcml0YWJsZVsxXTsKKyAgICAgICAgYXJyWzBdID0gKEhUYWJsZURlc2NyaXB0b3IpYXJnc1swXTsKKyAgICAgICAgdGhpcy5tYXN0ZXIubW9kaWZ5VGFibGUodGFibGVOYW1lLCBvcCwgYXJyKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfQ09NUEFDVDoKKyAgICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfU1BMSVQ6CisgICAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX01BSk9SX0NPTVBBQ1Q6CisgICAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX0ZMVVNIOgorICAgICAgICBpZiAoYXJncyAhPSBudWxsICYmIGFyZ3MubGVuZ3RoID4gMCkgeworICAgICAgICAgIGFyciA9IG5ldyBXcml0YWJsZVsxXTsKKyAgICAgICAgICBpZiAoYXJnc1swXSBpbnN0YW5jZW9mIGJ5dGVbXSkgeworICAgICAgICAgICAgYXJyWzBdID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKGJ5dGVbXSlhcmdzWzBdKTsKKyAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3NbMF0gaW5zdGFuY2VvZiBJbW11dGFibGVCeXRlc1dyaXRhYmxlKSB7CisgICAgICAgICAgICBhcnJbMF0gPSAoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSlhcmdzWzBdOworICAgICAgICAgIH0gZWxzZSBpZiAoYXJnc1swXSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICAgICAgYXJyWzBdID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoQnl0ZXMudG9CeXRlcygoU3RyaW5nKWFyZ3NbMF0pKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUmVxdWlyZXMgYnl0ZVtdLCBTdHJpbmcsIG9yIiArCisgICAgICAgICAgICAgICJJbW11dGFibGVCeXRlc1dyaXRhYmxlIik7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMubWFzdGVyLm1vZGlmeVRhYmxlKHRhYmxlTmFtZSwgb3AsIGFycik7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX0NMT1NFX1JFR0lPTjoKKyAgICAgICAgaWYgKGFyZ3MgPT0gbnVsbCB8fCBhcmdzLmxlbmd0aCA8IDEpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZXF1aXJlcyBhdCBsZWFzdCBhIHJlZ2lvbiBuYW1lIik7CisgICAgICAgIH0KKyAgICAgICAgYXJyID0gbmV3IFdyaXRhYmxlW2FyZ3MubGVuZ3RoXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgaWYgKGFyZ3NbaV0gaW5zdGFuY2VvZiBieXRlW10pIHsKKyAgICAgICAgICAgIGFycltpXSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKChieXRlW10pYXJnc1tpXSk7CisgICAgICAgICAgfSBlbHNlIGlmIChhcmdzW2ldIGluc3RhbmNlb2YgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSkgeworICAgICAgICAgICAgYXJyW2ldID0gKEltbXV0YWJsZUJ5dGVzV3JpdGFibGUpYXJnc1tpXTsKKyAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3NbaV0gaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgICAgICAgIGFycltpXSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKEJ5dGVzLnRvQnl0ZXMoKFN0cmluZylhcmdzW2ldKSk7CisgICAgICAgICAgfSBlbHNlIGlmIChhcmdzW2ldIGluc3RhbmNlb2YgQm9vbGVhbikgeworICAgICAgICAgICAgYXJyW2ldID0gbmV3IEJvb2xlYW5Xcml0YWJsZSgoKEJvb2xlYW4pYXJnc1tpXSkuYm9vbGVhblZhbHVlKCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZXF1aXJlcyBieXRlIFtdIG9yICIgKworICAgICAgICAgICAgICAiSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgbm90ICIgKyBhcmdzW2ldKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5tYXN0ZXIubW9kaWZ5VGFibGUodGFibGVOYW1lLCBvcCwgYXJyKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5rbm93biBtb2RpZnlUYWJsZSBvcCAiICsgb3ApOworICAgICAgfQorICAgIH0gY2F0Y2ggKFJlbW90ZUV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICAvKiogCisgICAqIFNodXRzIGRvd24gdGhlIEhCYXNlIGluc3RhbmNlIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2h1dGRvd24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLm1hc3RlciA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbigibWFzdGVyIGhhcyBiZWVuIHNodXQgZG93biIpOworICAgIH0KKyAgICB0cnkgeworICAgICAgdGhpcy5tYXN0ZXIuc2h1dGRvd24oKTsKKyAgICB9IGNhdGNoIChSZW1vdGVFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oZSk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubWFzdGVyID0gbnVsbDsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEhSZWdpb25Mb2NhdGlvbiBnZXRGaXJzdE1ldGFTZXJ2ZXJGb3JUYWJsZShmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5sb2NhdGVSZWdpb24oSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUsCisgICAgICBIUmVnaW9uSW5mby5jcmVhdGVSZWdpb25OYW1lKHRhYmxlTmFtZSwgbnVsbCwgSENvbnN0YW50cy5OSU5FUykpOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIHRvIHNlZSBpZiBIQmFzZSBpcyBydW5uaW5nLiBUaHJvdyBhbiBleGNlcHRpb24gaWYgbm90LgorICAgKgorICAgKiBAcGFyYW0gY29uZgorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja0hCYXNlQXZhaWxhYmxlKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKQorICB0aHJvd3MgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbiB7CisgICAgSEJhc2VDb25maWd1cmF0aW9uIGNvcHlPZkNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKGNvbmYpOworICAgIGNvcHlPZkNvbmYuc2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCAxKTsKKyAgICBuZXcgSEJhc2VBZG1pbihjb3B5T2ZDb25mKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQ29ubmVjdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L0hDb25uZWN0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDIxYWZlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQ29ubmVjdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTg0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkxvY2F0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJBZGRyZXNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSE1hc3RlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS56b29rZWVwZXIuWm9vS2VlcGVyV3JhcHBlcjsKKworLyoqCisgKiBDbHVzdGVyIGNvbm5lY3Rpb24uCisgKiB7QGxpbmsgSENvbm5lY3Rpb25NYW5hZ2VyfSBtYW5hZ2VzIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEhDb25uZWN0aW9uIHsKKyAgLyoqCisgICAqIFJldHJpZXZlIFpvb0tlZXBlcldyYXBwZXIgdXNlZCBieSB0aGUgY29ubmVjdGlvbi4KKyAgICogQHJldHVybiBab29LZWVwZXJXcmFwcGVyIGhhbmRsZSBiZWluZyB1c2VkIGJ5IHRoZSBjb25uZWN0aW9uLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgWm9vS2VlcGVyV3JhcHBlciBnZXRab29LZWVwZXJXcmFwcGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBAcmV0dXJuIHByb3h5IGNvbm5lY3Rpb24gdG8gbWFzdGVyIHNlcnZlciBmb3IgdGhpcyBpbnN0YW5jZQorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBITWFzdGVySW50ZXJmYWNlIGdldE1hc3RlcigpIHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uOworCisgIC8qKiBAcmV0dXJuIC0gdHJ1ZSBpZiB0aGUgbWFzdGVyIHNlcnZlciBpcyBydW5uaW5nICovCisgIHB1YmxpYyBib29sZWFuIGlzTWFzdGVyUnVubmluZygpOworICAKKyAgLyoqCisgICAqIENoZWNrcyBpZiA8Y29kZT50YWJsZU5hbWU8L2NvZGU+IGV4aXN0cy4KKyAgICogQHBhcmFtIHRhYmxlTmFtZSBUYWJsZSB0byBjaGVjay4KKyAgICogQHJldHVybiBUcnVlIGlmIHRhYmxlIGV4aXN0cyBhbHJlYWR5LgorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHRhYmxlRXhpc3RzKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogQSB0YWJsZSB0aGF0IGlzVGFibGVFbmFibGVkID09IGZhbHNlIGFuZCBpc1RhYmxlRGlzYWJsZWQgPT0gZmFsc2UKKyAgICogaXMgcG9zc2libGUuIFRoaXMgaGFwcGVucyB3aGVuIGEgdGFibGUgaGFzIGEgbG90IG9mIHJlZ2lvbnMKKyAgICogdGhhdCBtdXN0IGJlIHByb2Nlc3NlZC4KKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRhYmxlIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1RhYmxlRW5hYmxlZChieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHRhYmxlIGlzIGRpc2FibGVkLCBmYWxzZSBvdGhlcndpc2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNUYWJsZURpc2FibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBMaXN0IGFsbCB0aGUgdXNlcnNwYWNlIHRhYmxlcy4gIEluIG90aGVyIHdvcmRzLCBzY2FuIHRoZSBNRVRBIHRhYmxlLgorICAgKgorICAgKiBJZiB3ZSB3YW50ZWQgdGhpcyB0byBiZSByZWFsbHkgZmFzdCwgd2UgY291bGQgaW1wbGVtZW50IGEgc3BlY2lhbAorICAgKiBjYXRhbG9nIHRhYmxlIHRoYXQganVzdCBjb250YWlucyB0YWJsZSBuYW1lcyBhbmQgdGhlaXIgZGVzY3JpcHRvcnMuCisgICAqIFJpZ2h0IG5vdywgaXQgb25seSBleGlzdHMgYXMgcGFydCBvZiB0aGUgTUVUQSB0YWJsZSdzIHJlZ2lvbiBpbmZvLgorICAgKgorICAgKiBAcmV0dXJuIC0gcmV0dXJucyBhbiBhcnJheSBvZiBIVGFibGVEZXNjcmlwdG9ycyAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3JbXSBsaXN0VGFibGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHJldHVybiB0YWJsZSBtZXRhZGF0YSAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZURlc2NyaXB0b3IgZ2V0SFRhYmxlRGVzY3JpcHRvcihieXRlW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogRmluZCB0aGUgbG9jYXRpb24gb2YgdGhlIHJlZ2lvbiBvZiA8aT50YWJsZU5hbWU8L2k+IHRoYXQgPGk+cm93PC9pPgorICAgKiBsaXZlcyBpbi4KKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRoZSB0YWJsZSA8aT5yb3c8L2k+IGlzIGluCisgICAqIEBwYXJhbSByb3cgcm93IGtleSB5b3UncmUgdHJ5aW5nIHRvIGZpbmQgdGhlIHJlZ2lvbiBvZgorICAgKiBAcmV0dXJuIEhSZWdpb25Mb2NhdGlvbiB0aGF0IGRlc2NyaWJlcyB3aGVyZSB0byBmaW5kIHRoZSByZWlnb24gaW4gCisgICAqIHF1ZXN0aW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIUmVnaW9uTG9jYXRpb24gbG9jYXRlUmVnaW9uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgYnl0ZSBbXSByb3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBGaW5kIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVnaW9uIG9mIDxpPnRhYmxlTmFtZTwvaT4gdGhhdCA8aT5yb3c8L2k+CisgICAqIGxpdmVzIGluLCBpZ25vcmluZyBhbnkgdmFsdWUgdGhhdCBtaWdodCBiZSBpbiB0aGUgY2FjaGUuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUgPGk+cm93PC9pPiBpcyBpbgorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkgeW91J3JlIHRyeWluZyB0byBmaW5kIHRoZSByZWdpb24gb2YKKyAgICogQHJldHVybiBIUmVnaW9uTG9jYXRpb24gdGhhdCBkZXNjcmliZXMgd2hlcmUgdG8gZmluZCB0aGUgcmVpZ29uIGluIAorICAgKiBxdWVzdGlvbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSFJlZ2lvbkxvY2F0aW9uIHJlbG9jYXRlUmVnaW9uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgYnl0ZSBbXSByb3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsgIAorICAKKyAgLyoqIAorICAgKiBFc3RhYmxpc2hlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIHJlZ2lvbiBzZXJ2ZXIgYXQgdGhlIHNwZWNpZmllZCBhZGRyZXNzLgorICAgKiBAcGFyYW0gcmVnaW9uU2VydmVyIC0gdGhlIHNlcnZlciB0byBjb25uZWN0IHRvCisgICAqIEByZXR1cm4gcHJveHkgZm9yIEhSZWdpb25TZXJ2ZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25JbnRlcmZhY2UgZ2V0SFJlZ2lvbkNvbm5lY3Rpb24oSFNlcnZlckFkZHJlc3MgcmVnaW9uU2VydmVyKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogRmluZCByZWdpb24gbG9jYXRpb24gaG9zdGluZyBwYXNzZWQgcm93CisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gZmluZC4KKyAgICogQHBhcmFtIHJlbG9hZCBJZiB0cnVlIGRvIG5vdCB1c2UgY2FjaGUsIG90aGVyd2lzZSBieXBhc3MuCisgICAqIEByZXR1cm4gTG9jYXRpb24gb2Ygcm93LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBIUmVnaW9uTG9jYXRpb24gZ2V0UmVnaW9uTG9jYXRpb24oYnl0ZSBbXSB0YWJsZU5hbWUsIGJ5dGUgW10gcm93LAorICAgIGJvb2xlYW4gcmVsb2FkKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIFBhc3MgaW4gYSBTZXJ2ZXJDYWxsYWJsZSB3aXRoIHlvdXIgcGFydGljdWxhciBiaXQgb2YgbG9naWMgZGVmaW5lZCBhbmQgCisgICAqIHRoaXMgbWV0aG9kIHdpbGwgbWFuYWdlIHRoZSBwcm9jZXNzIG9mIGRvaW5nIHJldHJpZXMgd2l0aCB0aW1lZCB3YWl0cyAKKyAgICogYW5kIHJlZmluZHMgb2YgbWlzc2luZyByZWdpb25zLgorICAgKgorICAgKiBAcGFyYW0gPFQ+IHRoZSB0eXBlIG9mIHRoZSByZXR1cm4gdmFsdWUKKyAgICogQHBhcmFtIGNhbGxhYmxlCisgICAqIEByZXR1cm4gYW4gb2JqZWN0IG9mIHR5cGUgVAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIDxUPiBUIGdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKFNlcnZlckNhbGxhYmxlPFQ+IGNhbGxhYmxlKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uOworICAKKyAgLyoqCisgICAqIFBhc3MgaW4gYSBTZXJ2ZXJDYWxsYWJsZSB3aXRoIHlvdXIgcGFydGljdWxhciBiaXQgb2YgbG9naWMgZGVmaW5lZCBhbmQKKyAgICogdGhpcyBtZXRob2Qgd2lsbCBwYXNzIGl0IHRvIHRoZSBkZWZpbmVkIHJlZ2lvbiBzZXJ2ZXIuCisgICAqIEBwYXJhbSA8VD4gdGhlIHR5cGUgb2YgdGhlIHJldHVybiB2YWx1ZQorICAgKiBAcGFyYW0gY2FsbGFibGUKKyAgICogQHJldHVybiBhbiBvYmplY3Qgb2YgdHlwZSBUCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgPFQ+IFQgZ2V0UmVnaW9uU2VydmVyRm9yV2l0aG91dFJldHJpZXMoU2VydmVyQ2FsbGFibGU8VD4gY2FsbGFibGUpIAorICB0aHJvd3MgSU9FeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb247CisgIAorICAgIAorICAvKioKKyAgICogUHJvY2VzcyBhIGJhdGNoIG9mIHJvd3MuIEN1cnJlbnRseSBpdCBvbmx5IHdvcmtzIGZvciB1cGRhdGVzIHVudGlsIAorICAgKiBIQkFTRS04ODAgaXMgYXZhaWxhYmxlLiBEb2VzIHRoZSByZXRyaWVzLgorICAgKiBAcGFyYW0gbGlzdCBBIGJhdGNoIG9mIHJvd3MgdG8gcHJvY2VzcworICAgKiBAcGFyYW0gdGFibGVOYW1lIFRoZSBuYW1lIG9mIHRoZSB0YWJsZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBwcm9jZXNzQmF0Y2hPZlJvd3MoQXJyYXlMaXN0PEJhdGNoVXBkYXRlPiBsaXN0LCBieXRlW10gdGFibGVOYW1lKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQ29ubmVjdGlvbk1hbmFnZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IQ29ubmVjdGlvbk1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OTc4NzU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L0hDb25uZWN0aW9uTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMTA2MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuVW5kZWNsYXJlZFRocm93YWJsZUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5XZWFrSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkRvTm90UmV0cnlJT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uTG9jYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFN0b3JlS2V5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlRhYmxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50Lk1ldGFTY2FubmVyLk1ldGFTY2FubmVyVmlzaXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSEJhc2VSUEM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhCYXNlUlBDUHJvdG9jb2xWZXJzaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5ITWFzdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5NZXRhVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Tb2Z0VmFsdWVTb3J0ZWRNYXA7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyLlpvb0tlZXBlcldyYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVkRXZlbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVyLkV2ZW50LktlZXBlclN0YXRlOworCisvKioKKyAqIEEgbm9uLWluc3RhbnRpYWJsZSBjbGFzcyB0aGF0IG1hbmFnZXMgY29ubmVjdGlvbnMgdG8gbXVsdGlwbGUgdGFibGVzIGluCisgKiBtdWx0aXBsZSBIQmFzZSBpbnN0YW5jZXMuCisgKiAKKyAqIFVzZWQgYnkge0BsaW5rIEhUYWJsZX0gYW5kIHtAbGluayBIQmFzZUFkbWlufQorICovCitwdWJsaWMgY2xhc3MgSENvbm5lY3Rpb25NYW5hZ2VyIGltcGxlbWVudHMgSENvbnN0YW50cyB7CisKKyAgLyoKKyAgICogTm90IGluc3RhbnRpYWJsZS4KKyAgICovCisgIHByb3RlY3RlZCBIQ29ubmVjdGlvbk1hbmFnZXIoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorICAKKyAgLy8gQSBNYXAgb2YgbWFzdGVyIEhCYXNlQ29uZmlndXJhdGlvbiAtPiBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGZvciB0aGF0IAorICAvLyBpbnN0YW5jZS4gTm90ZSB0aGF0IGFsdGhvdWdoIHRoZSBNYXAgaXMgc3luY2hyb25pemVkLCB0aGUgb2JqZWN0cyBpdCAKKyAgLy8gY29udGFpbnMgYXJlIG11dGFibGUgYW5kIGhlbmNlIHJlcXVpcmUgc3luY2hyb25pemVkIGFjY2VzcyB0byB0aGVtCisgIHByaXZhdGUgc3RhdGljIAorICBmaW5hbCBNYXA8SEJhc2VDb25maWd1cmF0aW9uLCBUYWJsZVNlcnZlcnM+IEhCQVNFX0lOU1RBTkNFUyA9IAorICAgIG5ldyBXZWFrSGFzaE1hcDxIQmFzZUNvbmZpZ3VyYXRpb24sIFRhYmxlU2VydmVycz4oKTsKKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIGNvbm5lY3Rpb24gb2JqZWN0IGZvciB0aGUgaW5zdGFuY2Ugc3BlY2lmaWVkIGJ5IHRoZSBjb25maWd1cmF0aW9uCisgICAqIElmIG5vIGN1cnJlbnQgY29ubmVjdGlvbiBleGlzdHMsIGNyZWF0ZSBhIG5ldyBjb25uZWN0aW9uIGZvciB0aGF0IGluc3RhbmNlCisgICAqIEBwYXJhbSBjb25mCisgICAqIEByZXR1cm4gSENvbm5lY3Rpb24gb2JqZWN0IGZvciB0aGUgaW5zdGFuY2Ugc3BlY2lmaWVkIGJ5IHRoZSBjb25maWd1cmF0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIEhDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICBUYWJsZVNlcnZlcnMgY29ubmVjdGlvbjsKKyAgICBzeW5jaHJvbml6ZWQgKEhCQVNFX0lOU1RBTkNFUykgeworICAgICAgY29ubmVjdGlvbiA9IEhCQVNFX0lOU1RBTkNFUy5nZXQoY29uZik7CisgICAgICBpZiAoY29ubmVjdGlvbiA9PSBudWxsKSB7CisgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgVGFibGVTZXJ2ZXJzKGNvbmYpOworICAgICAgICBIQkFTRV9JTlNUQU5DRVMucHV0KGNvbmYsIGNvbm5lY3Rpb24pOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY29ubmVjdGlvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIERlbGV0ZSBjb25uZWN0aW9uIGluZm9ybWF0aW9uIGZvciB0aGUgaW5zdGFuY2Ugc3BlY2lmaWVkIGJ5IGNvbmZpZ3VyYXRpb24KKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHBhcmFtIHN0b3BQcm94eQorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGRlbGV0ZUNvbm5lY3Rpb25JbmZvKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgYm9vbGVhbiBzdG9wUHJveHkpIHsKKyAgICBzeW5jaHJvbml6ZWQgKEhCQVNFX0lOU1RBTkNFUykgeworICAgICAgVGFibGVTZXJ2ZXJzIHQgPSBIQkFTRV9JTlNUQU5DRVMucmVtb3ZlKGNvbmYpOworICAgICAgaWYgKHQgIT0gbnVsbCkgeworICAgICAgICB0LmNsb3NlKHN0b3BQcm94eSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyogRW5jYXBzdWxhdGVzIGZpbmRpbmcgdGhlIHNlcnZlcnMgZm9yIGFuIEhCYXNlIGluc3RhbmNlICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFRhYmxlU2VydmVycyBpbXBsZW1lbnRzIFNlcnZlckNvbm5lY3Rpb24sIEhDb25zdGFudHMsIFdhdGNoZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUYWJsZVNlcnZlcnMuY2xhc3MpOworICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEhSZWdpb25JbnRlcmZhY2U+IHNlcnZlckludGVyZmFjZUNsYXNzOworICAgIHByaXZhdGUgZmluYWwgbG9uZyBwYXVzZTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBudW1SZXRyaWVzOworICAgIHByaXZhdGUgZmluYWwgaW50IG1heFJQQ0F0dGVtcHRzOworICAgIHByaXZhdGUgZmluYWwgbG9uZyBycGNUaW1lb3V0OworCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgbWFzdGVyTG9jayA9IG5ldyBPYmplY3QoKTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gY2xvc2VkOworICAgIHByaXZhdGUgdm9sYXRpbGUgSE1hc3RlckludGVyZmFjZSBtYXN0ZXI7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIG1hc3RlckNoZWNrZWQ7CisgICAgCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgcm9vdFJlZ2lvbkxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgbWV0YVJlZ2lvbkxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgdXNlclJlZ2lvbkxvY2sgPSBuZXcgT2JqZWN0KCk7CisgICAgICAgIAorICAgIHByaXZhdGUgdm9sYXRpbGUgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisgICAgCisgICAgLy8gS25vd24gcmVnaW9uIEhTZXJ2ZXJBZGRyZXNzLnRvU3RyaW5nKCkgLT4gSFJlZ2lvbkludGVyZmFjZSAKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEhSZWdpb25JbnRlcmZhY2U+IHNlcnZlcnMgPQorICAgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPFN0cmluZywgSFJlZ2lvbkludGVyZmFjZT4oKTsKKworICAgIC8vIFVzZWQgYnkgbWFzdGVyIGFuZCByZWdpb24gc2VydmVycyBkdXJpbmcgc2FmZSBtb2RlIG9ubHkKKyAgICBwcml2YXRlIHZvbGF0aWxlIEhSZWdpb25Mb2NhdGlvbiByb290UmVnaW9uTG9jYXRpb247IAorICAgIAorICAgIHByaXZhdGUgZmluYWwgTWFwPEludGVnZXIsIFNvZnRWYWx1ZVNvcnRlZE1hcDxieXRlIFtdLCBIUmVnaW9uTG9jYXRpb24+PiAKKyAgICAgIGNhY2hlZFJlZ2lvbkxvY2F0aW9ucyA9CisgICAgICAgIG5ldyBIYXNoTWFwPEludGVnZXIsIFNvZnRWYWx1ZVNvcnRlZE1hcDxieXRlIFtdLCBIUmVnaW9uTG9jYXRpb24+PigpOworCisgICAgcHJpdmF0ZSBab29LZWVwZXJXcmFwcGVyIHpvb0tlZXBlcldyYXBwZXI7CisKKyAgICAvKiogCisgICAgICogY29uc3RydWN0b3IKKyAgICAgKiBAcGFyYW0gY29uZiBDb25maWd1cmF0aW9uIG9iamVjdAorICAgICAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBUYWJsZVNlcnZlcnMoSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICAgIHRoaXMuY29uZiA9IGNvbmY7CisKKyAgICAgIFN0cmluZyBzZXJ2ZXJDbGFzc05hbWUgPQorICAgICAgICBjb25mLmdldChSRUdJT05fU0VSVkVSX0NMQVNTLCBERUZBVUxUX1JFR0lPTl9TRVJWRVJfQ0xBU1MpOworCisgICAgICB0aGlzLmNsb3NlZCA9IGZhbHNlOworICAgICAgCisgICAgICB0cnkgeworICAgICAgICB0aGlzLnNlcnZlckludGVyZmFjZUNsYXNzID0KKyAgICAgICAgICAoQ2xhc3M8PyBleHRlbmRzIEhSZWdpb25JbnRlcmZhY2U+KSBDbGFzcy5mb3JOYW1lKHNlcnZlckNsYXNzTmFtZSk7CisgICAgICAgIAorICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICJVbmFibGUgdG8gZmluZCByZWdpb24gc2VydmVyIGludGVyZmFjZSAiICsgc2VydmVyQ2xhc3NOYW1lLCBlKTsKKyAgICAgIH0KKworICAgICAgdGhpcy5wYXVzZSA9IGNvbmYuZ2V0TG9uZygiaGJhc2UuY2xpZW50LnBhdXNlIiwgMiAqIDEwMDApOworICAgICAgdGhpcy5udW1SZXRyaWVzID0gY29uZi5nZXRJbnQoImhiYXNlLmNsaWVudC5yZXRyaWVzLm51bWJlciIsIDEwKTsKKyAgICAgIHRoaXMubWF4UlBDQXR0ZW1wdHMgPSBjb25mLmdldEludCgiaGJhc2UuY2xpZW50LnJwYy5tYXhhdHRlbXB0cyIsIDEpOworICAgICAgdGhpcy5ycGNUaW1lb3V0ID0gY29uZi5nZXRMb25nKCJoYmFzZS5yZWdpb25zZXJ2ZXIubGVhc2UucGVyaW9kIiwgNjAwMDApOworICAgICAgCisgICAgICB0aGlzLm1hc3RlciA9IG51bGw7CisgICAgICB0aGlzLm1hc3RlckNoZWNrZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwcml2YXRlIGxvbmcgZ2V0UGF1c2VUaW1lKGludCB0cmllcykgeworICAgICAgaW50IG50cmllcyA9IHRyaWVzOworICAgICAgaWYgKG50cmllcyA+PSBIQ29uc3RhbnRzLlJFVFJZX0JBQ0tPRkYubGVuZ3RoKQorICAgICAgICBudHJpZXMgPSBIQ29uc3RhbnRzLlJFVFJZX0JBQ0tPRkYubGVuZ3RoIC0gMTsKKyAgICAgIHJldHVybiB0aGlzLnBhdXNlICogSENvbnN0YW50cy5SRVRSWV9CQUNLT0ZGW250cmllc107CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIGJ5IFpvb0tlZXBlciB3aGVuIGFuIGV2ZW50IG9jY3VycyBvbiBvdXIgY29ubmVjdGlvbi4gV2UgdXNlIHRoaXMgdG8KKyAgICAgKiBkZXRlY3Qgb3VyIHNlc3Npb24gZXhwaXJpbmcuIFdoZW4gb3VyIHNlc3Npb24gZXhwaXJlcywgd2UgaGF2ZSBsb3N0IG91cgorICAgICAqIGNvbm5lY3Rpb24gdG8gWm9vS2VlcGVyLiBPdXIgaGFuZGxlIGlzIGRlYWQsIGFuZCB3ZSBuZWVkIHRvIHJlY3JlYXRlIGl0LgorICAgICAqCisgICAgICogU2VlIGh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy96b29rZWVwZXIvZG9jcy9jdXJyZW50L3pvb2tlZXBlclByb2dyYW1tZXJzLmh0bWwjY2hfemtTZXNzaW9ucworICAgICAqIGZvciBtb3JlIGluZm9ybWF0aW9uLgorICAgICAqCisgICAgICogQHBhcmFtIGV2ZW50IFdhdGNoZWRFdmVudCB3aXRuZXNzZWQgYnkgWm9vS2VlcGVyLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoV2F0Y2hlZEV2ZW50IGV2ZW50KSB7CisgICAgICBLZWVwZXJTdGF0ZSBzdGF0ZSA9IGV2ZW50LmdldFN0YXRlKCk7CisgICAgICBMT0cuZGVidWcoIkdvdCBab29LZWVwZXIgZXZlbnQsIHN0YXRlOiAiICsgc3RhdGUgKyAiLCB0eXBlOiAiICsKKyAgICAgICAgICAgICAgICBldmVudC5nZXRUeXBlKCkgKyAiLCBwYXRoOiAiICsgZXZlbnQuZ2V0UGF0aCgpKTsKKyAgICAgIGlmIChzdGF0ZSA9PSBLZWVwZXJTdGF0ZS5FeHBpcmVkKSB7CisgICAgICAgIHJlc2V0Wm9vS2VlcGVyKCk7CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCByZXNldFpvb0tlZXBlcigpIHsKKyAgICAgIHpvb0tlZXBlcldyYXBwZXIgPSBudWxsOworICAgIH0KKworICAgIC8vIFVzZWQgYnkgbWFzdGVyIGFuZCByZWdpb24gc2VydmVycyBkdXJpbmcgc2FmZSBtb2RlIG9ubHkKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvb3RSZWdpb25Mb2NhdGlvbigpIHsKKyAgICAgIHRoaXMucm9vdFJlZ2lvbkxvY2F0aW9uID0gbnVsbDsKKyAgICB9CisgICAgCisgICAgLy8gVXNlZCBieSBtYXN0ZXIgYW5kIHJlZ2lvbiBzZXJ2ZXJzIGR1cmluZyBzYWZlIG1vZGUgb25seQorICAgIHB1YmxpYyB2b2lkIHNldFJvb3RSZWdpb25Mb2NhdGlvbihIUmVnaW9uTG9jYXRpb24gcm9vdFJlZ2lvbikgeworICAgICAgaWYgKHJvb3RSZWdpb24gPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbm5vdCBzZXQgcm9vdCByZWdpb24gbG9jYXRpb24gdG8gbnVsbC4iKTsKKyAgICAgIH0KKyAgICAgIHRoaXMucm9vdFJlZ2lvbkxvY2F0aW9uID0gcm9vdFJlZ2lvbjsKKyAgICB9CisgICAgCisgICAgcHVibGljIEhNYXN0ZXJJbnRlcmZhY2UgZ2V0TWFzdGVyKCkgdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24geworICAgICAgWm9vS2VlcGVyV3JhcHBlciB6ayA9IG51bGw7CisgICAgICB0cnkgeworICAgICAgICB6ayA9IGdldFpvb0tlZXBlcldyYXBwZXIoKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24oZSk7CisgICAgICB9CisKKyAgICAgIEhTZXJ2ZXJBZGRyZXNzIG1hc3RlckxvY2F0aW9uID0gbnVsbDsKKyAgICAgIHN5bmNocm9uaXplZCAodGhpcy5tYXN0ZXJMb2NrKSB7CisgICAgICAgIGZvciAoaW50IHRyaWVzID0gMDsKKyAgICAgICAgICAhdGhpcy5jbG9zZWQgJiYKKyAgICAgICAgICAhdGhpcy5tYXN0ZXJDaGVja2VkICYmIHRoaXMubWFzdGVyID09IG51bGwgJiYKKyAgICAgICAgICB0cmllcyA8IG51bVJldHJpZXM7CisgICAgICAgIHRyaWVzKyspIHsKKworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBtYXN0ZXJMb2NhdGlvbiA9IHprLnJlYWRNYXN0ZXJBZGRyZXNzT3JUaHJvdygpOworCisgICAgICAgICAgICBITWFzdGVySW50ZXJmYWNlIHRyeU1hc3RlciA9IChITWFzdGVySW50ZXJmYWNlKUhCYXNlUlBDLmdldFByb3h5KAorICAgICAgICAgICAgICAgIEhNYXN0ZXJJbnRlcmZhY2UuY2xhc3MsIEhCYXNlUlBDUHJvdG9jb2xWZXJzaW9uLnZlcnNpb25JRCwgCisgICAgICAgICAgICAgICAgbWFzdGVyTG9jYXRpb24uZ2V0SW5ldFNvY2tldEFkZHJlc3MoKSwgdGhpcy5jb25mKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKHRyeU1hc3Rlci5pc01hc3RlclJ1bm5pbmcoKSkgeworICAgICAgICAgICAgICB0aGlzLm1hc3RlciA9IHRyeU1hc3RlcjsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBpZiAodHJpZXMgPT0gbnVtUmV0cmllcyAtIDEpIHsKKyAgICAgICAgICAgICAgLy8gVGhpcyB3YXMgb3VyIGxhc3QgY2hhbmNlIC0gZG9uJ3QgYm90aGVyIHNsZWVwaW5nCisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgTE9HLmluZm8oImdldE1hc3RlciBhdHRlbXB0ICIgKyB0cmllcyArICIgb2YgIiArIHRoaXMubnVtUmV0cmllcyArCisgICAgICAgICAgICAgICIgZmFpbGVkOyByZXRyeWluZyBhZnRlciBzbGVlcCBvZiAiICsKKyAgICAgICAgICAgICAgZ2V0UGF1c2VUaW1lKHRyaWVzKSwgZSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gQ2Fubm90IGNvbm5lY3QgdG8gbWFzdGVyIG9yIGl0IGlzIG5vdCBydW5uaW5nLiBTbGVlcCAmIHJldHJ5CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUodHJpZXMpKTsKKyAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBjb250aW51ZQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLm1hc3RlckNoZWNrZWQgPSB0cnVlOworICAgICAgfQorICAgICAgaWYgKHRoaXMubWFzdGVyID09IG51bGwpIHsKKyAgICAgICAgaWYgKG1hc3RlckxvY2F0aW9uID09IG51bGwpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKG1hc3RlckxvY2F0aW9uLnRvU3RyaW5nKCkpOworICAgICAgfQorICAgICAgcmV0dXJuIHRoaXMubWFzdGVyOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzTWFzdGVyUnVubmluZygpIHsKKyAgICAgIGlmICh0aGlzLm1hc3RlciA9PSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgZ2V0TWFzdGVyKCk7CisgICAgICAgICAgCisgICAgICAgIH0gY2F0Y2ggKE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24gZSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gdGFibGVFeGlzdHMoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpCisgICAgdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24geworICAgICAgZ2V0TWFzdGVyKCk7CisgICAgICBpZiAodGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGFibGUgbmFtZSBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgfQorICAgICAgaWYgKGlzTWV0YVRhYmxlTmFtZSh0YWJsZU5hbWUpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgYm9vbGVhbiBleGlzdHMgPSBmYWxzZTsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZURlc2NyaXB0b3JbXSB0YWJsZXMgPSBsaXN0VGFibGVzKCk7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyh0YWJsZXNbaV0uZ2V0TmFtZSgpLCB0YWJsZU5hbWUpKSB7CisgICAgICAgICAgICBleGlzdHMgPSB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cud2FybigiVGVzdGluZyBmb3IgdGFibGUgZXhpc3RlbmNlIHRocmV3IGV4Y2VwdGlvbiIsIGUpOworICAgICAgfQorICAgICAgcmV0dXJuIGV4aXN0czsKKyAgICB9CisgICAgCisgICAgLyoKKyAgICAgKiBAcGFyYW0gbgorICAgICAqIEByZXR1cm4gVHJ1ZW4gaWYgcGFzc2VkIHRhYmxlbmFtZSA8Y29kZT5uPC9jb2RlPiBpcyBlcXVhbCB0byB0aGUgbmFtZQorICAgICAqIG9mIGEgY2F0YWxvZyB0YWJsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTWV0YVRhYmxlTmFtZShmaW5hbCBieXRlIFtdIG4pIHsKKyAgICAgIHJldHVybiBNZXRhVXRpbHMuaXNNZXRhVGFibGVOYW1lKG4pOworICAgIH0KKworICAgIHB1YmxpYyBIUmVnaW9uTG9jYXRpb24gZ2V0UmVnaW9uTG9jYXRpb24oZmluYWwgYnl0ZSBbXSBuYW1lLAorICAgICAgICBmaW5hbCBieXRlIFtdIHJvdywgYm9vbGVhbiByZWxvYWQpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGdldE1hc3RlcigpOworICAgICAgcmV0dXJuIHJlbG9hZD8gcmVsb2NhdGVSZWdpb24obmFtZSwgcm93KTogbG9jYXRlUmVnaW9uKG5hbWUsIHJvdyk7CisgICAgfQorCisgICAgcHVibGljIEhUYWJsZURlc2NyaXB0b3JbXSBsaXN0VGFibGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGdldE1hc3RlcigpOworICAgICAgZmluYWwgVHJlZVNldDxIVGFibGVEZXNjcmlwdG9yPiB1bmlxdWVUYWJsZXMgPQorICAgICAgICBuZXcgVHJlZVNldDxIVGFibGVEZXNjcmlwdG9yPigpOworCisgICAgICBNZXRhU2Nhbm5lclZpc2l0b3IgdmlzaXRvciA9IG5ldyBNZXRhU2Nhbm5lclZpc2l0b3IoKSB7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc1JvdyhSb3dSZXN1bHQgcm93UmVzdWx0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8oCisgICAgICAgICAgICAgIHJvd1Jlc3VsdC5nZXQoQ09MX1JFR0lPTklORk8pKTsKKworICAgICAgICAgIC8vIE9ubHkgZXhhbWluZSB0aGUgcm93cyB3aGVyZSB0aGUgc3RhcnRLZXkgaXMgemVybyBsZW5ndGgKKyAgICAgICAgICBpZiAoaW5mby5nZXRTdGFydEtleSgpLmxlbmd0aCA9PSAwKSB7CisgICAgICAgICAgICB1bmlxdWVUYWJsZXMuYWRkKGluZm8uZ2V0VGFibGVEZXNjKCkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICB9OworICAgICAgTWV0YVNjYW5uZXIubWV0YVNjYW4oY29uZiwgdmlzaXRvcik7CisKKyAgICAgIHJldHVybiB1bmlxdWVUYWJsZXMudG9BcnJheShuZXcgSFRhYmxlRGVzY3JpcHRvclt1bmlxdWVUYWJsZXMuc2l6ZSgpXSk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBib29sZWFuIGlzVGFibGVFbmFibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gdGVzdFRhYmxlT25saW5lU3RhdGUodGFibGVOYW1lLCB0cnVlKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIGJvb2xlYW4gaXNUYWJsZURpc2FibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gdGVzdFRhYmxlT25saW5lU3RhdGUodGFibGVOYW1lLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJZiBvbmxpbmUgPT0gdHJ1ZQorICAgICAqICAgUmV0dXJucyB0cnVlIGlmIGFsbCByZWdpb25zIGFyZSBvbmxpbmUKKyAgICAgKiAgIFJldHVybnMgZmFsc2UgaW4gYW55IG90aGVyIGNhc2UKKyAgICAgKiBJZiBvbmxpbmUgPT0gZmFsc2UKKyAgICAgKiAgIFJldHVybnMgdHJ1ZSBpZiBhbGwgcmVnaW9ucyBhcmUgb2ZmbGluZQorICAgICAqICAgUmV0dXJucyBmYWxzZSBpbiBhbnkgb3RoZXIgY2FzZQorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiB0ZXN0VGFibGVPbmxpbmVTdGF0ZShieXRlW10gdGFibGVOYW1lLCAKKyAgICAgICAgYm9vbGVhbiBvbmxpbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoIXRhYmxlRXhpc3RzKHRhYmxlTmFtZSkpIHsKKyAgICAgICAgdGhyb3cgbmV3IFRhYmxlTm90Rm91bmRFeGNlcHRpb24oQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgICB9CisgICAgICBpZiAoQnl0ZXMuZXF1YWxzKHRhYmxlTmFtZSwgSENvbnN0YW50cy5ST09UX1RBQkxFX05BTUUpKSB7CisgICAgICAgIC8vIFRoZSByb290IHJlZ2lvbiBpcyBhbHdheXMgZW5hYmxlZAorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgaW50IHJvd3NTY2FubmVkID0gMDsKKyAgICAgIGludCByb3dzT2ZmbGluZSA9IDA7CisgICAgICBieXRlW10gc3RhcnRLZXkgPQorICAgICAgICBIUmVnaW9uSW5mby5jcmVhdGVSZWdpb25OYW1lKHRhYmxlTmFtZSwgbnVsbCwgSENvbnN0YW50cy5aRVJPRVMpOworICAgICAgYnl0ZVtdIGVuZEtleSA9IG51bGw7CisgICAgICBIUmVnaW9uSW5mbyBjdXJyZW50UmVnaW9uID0gbnVsbDsKKyAgICAgIFNjYW5uZXJDYWxsYWJsZSBzID0gbmV3IFNjYW5uZXJDYWxsYWJsZSh0aGlzLCAKKyAgICAgICAgICAoQnl0ZXMuZXF1YWxzKHRhYmxlTmFtZSwgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpID8KKyAgICAgICAgICAgICAgSENvbnN0YW50cy5ST09UX1RBQkxFX05BTUUgOiBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSksCisgICAgICAgICAgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GT19BUlJBWSwgc3RhcnRLZXksCisgICAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsCisgICAgICApOworICAgICAgdHJ5IHsKKyAgICAgICAgLy8gT3BlbiBzY2FubmVyCisgICAgICAgIGdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKHMpOworICAgICAgICBkbyB7CisgICAgICAgICAgSFJlZ2lvbkluZm8gb2xkUmVnaW9uID0gY3VycmVudFJlZ2lvbjsKKyAgICAgICAgICBpZiAob2xkUmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN0YXJ0S2V5ID0gb2xkUmVnaW9uLmdldEVuZEtleSgpOworICAgICAgICAgIH0KKyAgICAgICAgICBjdXJyZW50UmVnaW9uID0gcy5nZXRIUmVnaW9uSW5mbygpOworICAgICAgICAgIFJvd1Jlc3VsdCByID0gbnVsbDsKKyAgICAgICAgICBSb3dSZXN1bHRbXSBycnMgPSBudWxsOworICAgICAgICAgIHdoaWxlICgocnJzID0gZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMocykpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHIgPSBycnNbMF07CisgICAgICAgICAgICBDZWxsIGMgPSByLmdldChIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKTsKKyAgICAgICAgICAgIGlmIChjICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgYnl0ZVtdIHZhbHVlID0gYy5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm9Pck51bGwodmFsdWUpOworICAgICAgICAgICAgICAgIGlmIChpbmZvICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgIGlmIChCeXRlcy5lcXVhbHMoaW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCksIHRhYmxlTmFtZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcm93c1NjYW5uZWQgKz0gMTsKKyAgICAgICAgICAgICAgICAgICAgcm93c09mZmxpbmUgKz0gaW5mby5pc09mZmxpbmUoKSA/IDEgOiAwOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBlbmRLZXkgPSBjdXJyZW50UmVnaW9uLmdldEVuZEtleSgpOworICAgICAgICB9IHdoaWxlICghKGVuZEtleSA9PSBudWxsIHx8IEhTdG9yZUtleS5lcXVhbHNUd29Sb3dLZXlzKGVuZEtleSwKKyAgICAgICAgICAgIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSkpKTsKKyAgICAgIH0KKyAgICAgIGZpbmFsbHkgeworICAgICAgICBzLnNldENsb3NlKCk7CisgICAgICB9CisgICAgICBib29sZWFuIG9ubGluZU9mZmxpbmUgPSAKKyAgICAgICAgb25saW5lID8gcm93c09mZmxpbmUgPT0gMCA6IHJvd3NPZmZsaW5lID09IHJvd3NTY2FubmVkOworICAgICAgcmV0dXJuIHJvd3NTY2FubmVkID4gMCAmJiBvbmxpbmVPZmZsaW5lOworICAgICAgCisgICAgfQorICAgIAorICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEhUYWJsZURlc2NyaXB0b3JGaW5kZXIgCisgICAgaW1wbGVtZW50cyBNZXRhU2Nhbm5lci5NZXRhU2Nhbm5lclZpc2l0b3IgeworICAgICAgICBieXRlW10gdGFibGVOYW1lOworICAgICAgICBIVGFibGVEZXNjcmlwdG9yIHJlc3VsdDsKKyAgICAgICAgcHJvdGVjdGVkIEhUYWJsZURlc2NyaXB0b3JGaW5kZXIoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgICB9CisgICAgICAgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NSb3coUm93UmVzdWx0IHJvd1Jlc3VsdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICBIUmVnaW9uSW5mbyBpbmZvID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKAorICAgICAgICAgICAgcm93UmVzdWx0LmdldChIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKSk7CisgICAgICAgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gaW5mby5nZXRUYWJsZURlc2MoKTsKKyAgICAgICAgICBpZiAoQnl0ZXMuY29tcGFyZVRvKGRlc2MuZ2V0TmFtZSgpLCB0YWJsZU5hbWUpID09IDApIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGRlc2M7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIEhUYWJsZURlc2NyaXB0b3IgZ2V0UmVzdWx0KCkgeworICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSFRhYmxlRGVzY3JpcHRvciBnZXRIVGFibGVEZXNjcmlwdG9yKGZpbmFsIGJ5dGVbXSB0YWJsZU5hbWUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChCeXRlcy5lcXVhbHModGFibGVOYW1lLCBIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSkpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBVbm1vZGlmeWFibGVIVGFibGVEZXNjcmlwdG9yKEhUYWJsZURlc2NyaXB0b3IuUk9PVF9UQUJMRURFU0MpOworICAgICAgfQorICAgICAgaWYgKEJ5dGVzLmVxdWFscyh0YWJsZU5hbWUsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKSkgeworICAgICAgICByZXR1cm4gbmV3IFVubW9kaWZ5YWJsZUhUYWJsZURlc2NyaXB0b3IoSFRhYmxlRGVzY3JpcHRvci5NRVRBX1RBQkxFREVTQyk7CisgICAgICB9CisgICAgICBIVGFibGVEZXNjcmlwdG9yRmluZGVyIGZpbmRlciA9IG5ldyBIVGFibGVEZXNjcmlwdG9yRmluZGVyKHRhYmxlTmFtZSk7CisgICAgICBNZXRhU2Nhbm5lci5tZXRhU2Nhbihjb25mLCBmaW5kZXIpOworICAgICAgSFRhYmxlRGVzY3JpcHRvciByZXN1bHQgPSBmaW5kZXIuZ2V0UmVzdWx0KCk7CisgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IFRhYmxlTm90Rm91bmRFeGNlcHRpb24oQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIHB1YmxpYyBIUmVnaW9uTG9jYXRpb24gbG9jYXRlUmVnaW9uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgICBmaW5hbCBieXRlIFtdIHJvdykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICBnZXRNYXN0ZXIoKTsKKyAgICAgIHJldHVybiBsb2NhdGVSZWdpb24odGFibGVOYW1lLCByb3csIHRydWUpOworICAgIH0KKworICAgIHB1YmxpYyBIUmVnaW9uTG9jYXRpb24gcmVsb2NhdGVSZWdpb24oZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsCisgICAgICAgIGZpbmFsIGJ5dGUgW10gcm93KQorICAgIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgIGdldE1hc3RlcigpOworICAgICAgcmV0dXJuIGxvY2F0ZVJlZ2lvbih0YWJsZU5hbWUsIHJvdywgZmFsc2UpOworICAgIH0KKworICAgIHByaXZhdGUgSFJlZ2lvbkxvY2F0aW9uIGxvY2F0ZVJlZ2lvbihmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gcm93LCBib29sZWFuIHVzZUNhY2hlKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICAgIGlmICh0YWJsZU5hbWUgPT0gbnVsbCB8fCB0YWJsZU5hbWUubGVuZ3RoID09IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJ0YWJsZSBuYW1lIGNhbm5vdCBiZSBudWxsIG9yIHplcm8gbGVuZ3RoIik7CisgICAgICB9CisgICAgICAgICAgICAKKyAgICAgIGlmIChCeXRlcy5lcXVhbHModGFibGVOYW1lLCBST09UX1RBQkxFX05BTUUpKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAocm9vdFJlZ2lvbkxvY2spIHsKKyAgICAgICAgICAvLyBUaGlzIGJsb2NrIGd1YXJkcyBhZ2FpbnN0IHR3byB0aHJlYWRzIHRyeWluZyB0byBmaW5kIHRoZSByb290CisgICAgICAgICAgLy8gcmVnaW9uIGF0IHRoZSBzYW1lIHRpbWUuIE9uZSB3aWxsIGdvIGRvIHRoZSBmaW5kIHdoaWxlIHRoZSAKKyAgICAgICAgICAvLyBzZWNvbmQgd2FpdHMuIFRoZSBzZWNvbmQgdGhyZWFkIHdpbGwgbm90IGRvIGZpbmQuCisgICAgICAgICAgCisgICAgICAgICAgaWYgKCF1c2VDYWNoZSB8fCByb290UmVnaW9uTG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGxvY2F0ZVJvb3RSZWdpb24oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHJvb3RSZWdpb25Mb2NhdGlvbjsKKyAgICAgICAgfSAgICAgICAgCisgICAgICB9IGVsc2UgaWYgKEJ5dGVzLmVxdWFscyh0YWJsZU5hbWUsIE1FVEFfVEFCTEVfTkFNRSkpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChtZXRhUmVnaW9uTG9jaykgeworICAgICAgICAgIC8vIFRoaXMgYmxvY2sgZ3VhcmRzIGFnYWluc3QgdHdvIHRocmVhZHMgdHJ5aW5nIHRvIGxvYWQgdGhlIG1ldGEgCisgICAgICAgICAgLy8gcmVnaW9uIGF0IHRoZSBzYW1lIHRpbWUuIFRoZSBmaXJzdCB3aWxsIGxvYWQgdGhlIG1ldGEgcmVnaW9uIGFuZAorICAgICAgICAgIC8vIHRoZSBzZWNvbmQgd2lsbCB1c2UgdGhlIHZhbHVlIHRoYXQgdGhlIGZpcnN0IG9uZSBmb3VuZC4KKyAgICAgICAgICByZXR1cm4gbG9jYXRlUmVnaW9uSW5NZXRhKFJPT1RfVEFCTEVfTkFNRSwgdGFibGVOYW1lLCByb3csIHVzZUNhY2hlKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3luY2hyb25pemVkKHVzZXJSZWdpb25Mb2NrKXsKKyAgICAgICAgICByZXR1cm4gbG9jYXRlUmVnaW9uSW5NZXRhKE1FVEFfVEFCTEVfTkFNRSwgdGFibGVOYW1lLCByb3csIHVzZUNhY2hlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICAqIFNlYXJjaCBvbmUgb2YgdGhlIG1ldGEgdGFibGVzICgtUk9PVC0gb3IgLk1FVEEuKSBmb3IgdGhlIEhSZWdpb25Mb2NhdGlvbgorICAgICAgKiBpbmZvIHRoYXQgY29udGFpbnMgdGhlIHRhYmxlIGFuZCByb3cgd2UncmUgc2Vla2luZy4KKyAgICAgICovCisgICAgcHJpdmF0ZSBIUmVnaW9uTG9jYXRpb24gbG9jYXRlUmVnaW9uSW5NZXRhKGZpbmFsIGJ5dGUgW10gcGFyZW50VGFibGUsCisgICAgICBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgZmluYWwgYnl0ZSBbXSByb3csIGJvb2xlYW4gdXNlQ2FjaGUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgSFJlZ2lvbkxvY2F0aW9uIGxvY2F0aW9uID0gbnVsbDsKKyAgICAgIC8vIElmIHN1cHBvc2VkIHRvIGJlIHVzaW5nIHRoZSBjYWNoZSwgdGhlbiBjaGVjayBpdCBmb3IgYSBwb3NzaWJsZSBoaXQuCisgICAgICAvLyBPdGhlcndpc2UsIGRlbGV0ZSBhbnkgZXhpc3RpbmcgY2FjaGVkIGxvY2F0aW9uIHNvIGl0IHdvbid0IGludGVyZmVyZS4KKyAgICAgIGlmICh1c2VDYWNoZSkgeworICAgICAgICBsb2NhdGlvbiA9IGdldENhY2hlZExvY2F0aW9uKHRhYmxlTmFtZSwgcm93KTsKKyAgICAgICAgaWYgKGxvY2F0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICByZXR1cm4gbG9jYXRpb247CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRlbGV0ZUNhY2hlZExvY2F0aW9uKHRhYmxlTmFtZSwgcm93KTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLy8gYnVpbGQgdGhlIGtleSBvZiB0aGUgbWV0YSByZWdpb24gd2Ugc2hvdWxkIGJlIGxvb2tpbmcgZm9yLgorICAgICAgLy8gdGhlIGV4dHJhIDkncyBvbiB0aGUgZW5kIGFyZSBuZWNlc3NhcnkgdG8gYWxsb3cgImV4YWN0IiBtYXRjaGVzCisgICAgICAvLyB3aXRob3V0IGtub3dpbmcgdGhlIHByZWNpc2UgcmVnaW9uIG5hbWVzLgorICAgICAgYnl0ZSBbXSBtZXRhS2V5ID0gSFJlZ2lvbkluZm8uY3JlYXRlUmVnaW9uTmFtZSh0YWJsZU5hbWUsIHJvdywKKyAgICAgICAgSENvbnN0YW50cy5OSU5FUyk7CisgICAgICBmb3IgKGludCB0cmllcyA9IDA7IHRydWU7IHRyaWVzKyspIHsKKyAgICAgICAgaWYgKHRyaWVzID49IG51bVJldHJpZXMpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24oIlVuYWJsZSB0byBmaW5kIHJlZ2lvbiBmb3IgIiAKKyAgICAgICAgICAgICsgQnl0ZXMudG9TdHJpbmcocm93KSArICIgYWZ0ZXIgIiArIG51bVJldHJpZXMgKyAiIHRyaWVzLiIpOworICAgICAgICB9CisKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAvLyBsb2NhdGUgdGhlIHJvb3Qgb3IgbWV0YSByZWdpb24KKyAgICAgICAgICBIUmVnaW9uTG9jYXRpb24gbWV0YUxvY2F0aW9uID0gbG9jYXRlUmVnaW9uKHBhcmVudFRhYmxlLCBtZXRhS2V5KTsKKyAgICAgICAgICBIUmVnaW9uSW50ZXJmYWNlIHNlcnZlciA9CisgICAgICAgICAgICBnZXRIUmVnaW9uQ29ubmVjdGlvbihtZXRhTG9jYXRpb24uZ2V0U2VydmVyQWRkcmVzcygpKTsKKworICAgICAgICAgIC8vIFF1ZXJ5IHRoZSByb290IG9yIG1ldGEgcmVnaW9uIGZvciB0aGUgbG9jYXRpb24gb2YgdGhlIG1ldGEgcmVnaW9uCisgICAgICAgICAgUm93UmVzdWx0IHJlZ2lvbkluZm9Sb3cgPSBzZXJ2ZXIuZ2V0Q2xvc2VzdFJvd0JlZm9yZSgKKyAgICAgICAgICAgIG1ldGFMb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpLCBtZXRhS2V5LAorICAgICAgICAgICAgSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKTsKKyAgICAgICAgICBpZiAocmVnaW9uSW5mb1JvdyA9PSBudWxsKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVGFibGVOb3RGb3VuZEV4Y2VwdGlvbihCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBDZWxsIHZhbHVlID0gcmVnaW9uSW5mb1Jvdy5nZXQoQ09MX1JFR0lPTklORk8pOworICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlLmdldFZhbHVlKCkubGVuZ3RoID09IDApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSFJlZ2lvbkluZm8gd2FzIG51bGwgb3IgZW1wdHkgaW4gIiArIAorICAgICAgICAgICAgICBCeXRlcy50b1N0cmluZyhwYXJlbnRUYWJsZSkpOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBjb252ZXJ0IHRoZSByb3cgcmVzdWx0IGludG8gdGhlIEhSZWdpb25Mb2NhdGlvbiB3ZSBuZWVkIQorICAgICAgICAgIEhSZWdpb25JbmZvIHJlZ2lvbkluZm8gPSAoSFJlZ2lvbkluZm8pIFdyaXRhYmxlcy5nZXRXcml0YWJsZSgKKyAgICAgICAgICAgICAgdmFsdWUuZ2V0VmFsdWUoKSwgbmV3IEhSZWdpb25JbmZvKCkpOworICAgICAgICAgIC8vIHBvc3NpYmxlIHdlIGdvdCBhIHJlZ2lvbiBvZiBhIGRpZmZlcmVudCB0YWJsZS4uLgorICAgICAgICAgIGlmICghQnl0ZXMuZXF1YWxzKHJlZ2lvbkluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLCB0YWJsZU5hbWUpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVGFibGVOb3RGb3VuZEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIlRhYmxlICciICsgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSArICInIHdhcyBub3QgZm91bmQuIik7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChyZWdpb25JbmZvLmlzT2ZmbGluZSgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUmVnaW9uT2ZmbGluZUV4Y2VwdGlvbigicmVnaW9uIG9mZmxpbmU6ICIgKyAKKyAgICAgICAgICAgICAgcmVnaW9uSW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIFN0cmluZyBzZXJ2ZXJBZGRyZXNzID0gCisgICAgICAgICAgICBXcml0YWJsZXMuY2VsbFRvU3RyaW5nKHJlZ2lvbkluZm9Sb3cuZ2V0KENPTF9TRVJWRVIpKTsKKyAgICAgICAgICBpZiAoc2VydmVyQWRkcmVzcy5lcXVhbHMoIiIpKSB7IAorICAgICAgICAgICAgdGhyb3cgbmV3IE5vU2VydmVyRm9yUmVnaW9uRXhjZXB0aW9uKCJObyBzZXJ2ZXIgYWRkcmVzcyBsaXN0ZWQgIiArCisgICAgICAgICAgICAgICJpbiAiICsgQnl0ZXMudG9TdHJpbmcocGFyZW50VGFibGUpICsgIiBmb3IgcmVnaW9uICIgKworICAgICAgICAgICAgICByZWdpb25JbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgICAgICB9CisgICAgICAgIAorICAgICAgICAgIC8vIGluc3RhbnRpYXRlIHRoZSBsb2NhdGlvbgorICAgICAgICAgIGxvY2F0aW9uID0gbmV3IEhSZWdpb25Mb2NhdGlvbihyZWdpb25JbmZvLAorICAgICAgICAgICAgICBuZXcgSFNlcnZlckFkZHJlc3Moc2VydmVyQWRkcmVzcykpOworICAgICAgICAgIGNhY2hlTG9jYXRpb24odGFibGVOYW1lLCBsb2NhdGlvbik7CisgICAgICAgICAgcmV0dXJuIGxvY2F0aW9uOworICAgICAgICB9IGNhdGNoIChUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvLyBpZiB3ZSBnb3QgdGhpcyBlcnJvciwgcHJvYmFibHkgbWVhbnMgdGhlIHRhYmxlIGp1c3QgcGxhaW4gZG9lc24ndAorICAgICAgICAgIC8vIGV4aXN0LiByZXRocm93IHRoZSBlcnJvciBpbW1lZGlhdGVseS4gdGhpcyBzaG91bGQgYWx3YXlzIGJlIGNvbWluZworICAgICAgICAgIC8vIGZyb20gdGhlIEhUYWJsZSBjb25zdHJ1Y3Rvci4KKyAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSZW1vdGVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgIGUgPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAoUmVtb3RlRXhjZXB0aW9uKSBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKHRyaWVzIDwgbnVtUmV0cmllcyAtIDEpIHsKKyAgICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgICBMT0cuZGVidWcoImxvY2F0ZVJlZ2lvbkluTWV0YSBhdHRlbXB0ICIgKyB0cmllcyArICIgb2YgIiArCisgICAgICAgICAgICAgICAgdGhpcy5udW1SZXRyaWVzICsgIiBmYWlsZWQ7IHJldHJ5aW5nIGFmdGVyIHNsZWVwIG9mICIgKworICAgICAgICAgICAgICAgIGdldFBhdXNlVGltZSh0cmllcyksIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVsb2NhdGVSZWdpb24ocGFyZW50VGFibGUsIG1ldGFLZXkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgCisgICAgICAgIHRyeXsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoZ2V0UGF1c2VUaW1lKHRyaWVzKSk7ICAgICAgICAgICAgICAKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSl7CisgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU2VhcmNoIHRoZSBjYWNoZSBmb3IgYSBsb2NhdGlvbiB0aGF0IGZpdHMgb3VyIHRhYmxlIGFuZCByb3cga2V5LgorICAgICAqIFJldHVybiBudWxsIGlmIG5vIHN1aXRhYmxlIHJlZ2lvbiBpcyBsb2NhdGVkLiBUT0RPOiBzeW5jaHJvbml6YXRpb24gbm90ZQorICAgICAqIAorICAgICAqIDxwPlRPRE86IFRoaXMgbWV0aG9kIGR1cmluZyB3cml0aW5nIGNvbnN1bWVzIDE1JSBvZiBDUFUgZG9pbmcgbG9va3VwCisgICAgICogaW50byB0aGUgU29mdCBSZWZlcmVuY2UgU29ydGVkTWFwLiAgSW1wcm92ZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEByZXR1cm4gTnVsbCBvciByZWdpb24gbG9jYXRpb24gZm91bmQgaW4gY2FjaGUuCisgICAgICovCisgICAgcHJpdmF0ZSBIUmVnaW9uTG9jYXRpb24gZ2V0Q2FjaGVkTG9jYXRpb24oZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsCisgICAgICAgIGZpbmFsIGJ5dGUgW10gcm93KSB7CisgICAgICBTb2Z0VmFsdWVTb3J0ZWRNYXA8Ynl0ZSBbXSwgSFJlZ2lvbkxvY2F0aW9uPiB0YWJsZUxvY2F0aW9ucyA9CisgICAgICAgIGdldFRhYmxlTG9jYXRpb25zKHRhYmxlTmFtZSk7CisKKyAgICAgIC8vIHN0YXJ0IHRvIGV4YW1pbmUgdGhlIGNhY2hlLiB3ZSBjYW4gb25seSBkbyBjYWNoZSBhY3Rpb25zCisgICAgICAvLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgY2FjaGUgZm9yIHRoaXMgdGFibGUuCisgICAgICBpZiAodGFibGVMb2NhdGlvbnMuaXNFbXB0eSgpKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorCisgICAgICBIUmVnaW9uTG9jYXRpb24gcmwgPSB0YWJsZUxvY2F0aW9ucy5nZXQocm93KTsKKyAgICAgIGlmIChybCAhPSBudWxsKSB7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygiQ2FjaGUgaGl0IGZvciByb3cgPCIgKworICAgICAgICAgICAgQnl0ZXMudG9TdHJpbmcocm93KSArCisgICAgICAgICAgICAiPiBpbiB0YWJsZU5hbWUgIiArIEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkgKworICAgICAgICAgICAgIjogbG9jYXRpb24gc2VydmVyICIgKyBybC5nZXRTZXJ2ZXJBZGRyZXNzKCkgKworICAgICAgICAgICAgIiwgbG9jYXRpb24gcmVnaW9uIG5hbWUgIiArCisgICAgICAgICAgICBybC5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBybDsKKyAgICAgIH0KKworICAgICAgLy8gQ3V0IHRoZSBjYWNoZSBzbyB0aGF0IHdlIG9ubHkgZ2V0IHRoZSBwYXJ0IHRoYXQgY291bGQgY29udGFpbgorICAgICAgLy8gcmVnaW9ucyB0aGF0IG1hdGNoIG91ciBrZXkKKyAgICAgIFNvZnRWYWx1ZVNvcnRlZE1hcDxieXRlW10sIEhSZWdpb25Mb2NhdGlvbj4gbWF0Y2hpbmdSZWdpb25zID0KKyAgICAgICAgdGFibGVMb2NhdGlvbnMuaGVhZE1hcChyb3cpOworCisgICAgICAvLyBpZiB0aGF0IHBvcnRpb24gb2YgdGhlIG1hcCBpcyBlbXB0eSwgdGhlbiB3ZSdyZSBkb25lLiBvdGhlcndpc2UsCisgICAgICAvLyB3ZSBuZWVkIHRvIGV4YW1pbmUgdGhlIGNhY2hlZCBsb2NhdGlvbiB0byB2ZXJpZnkgdGhhdCBpdCBpcworICAgICAgLy8gYSBtYXRjaCBieSBlbmQga2V5IGFzIHdlbGwuCisgICAgICBpZiAoIW1hdGNoaW5nUmVnaW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgICAgSFJlZ2lvbkxvY2F0aW9uIHBvc3NpYmxlUmVnaW9uID0KKyAgICAgICAgICBtYXRjaGluZ1JlZ2lvbnMuZ2V0KG1hdGNoaW5nUmVnaW9ucy5sYXN0S2V5KCkpOworCisgICAgICAgIC8vIHRoZXJlIGlzIGEgcG9zc2liaWxpdHkgdGhhdCB0aGUgcmVmZXJlbmNlIHdhcyBnYXJiYWdlIGNvbGxlY3RlZAorICAgICAgICAvLyBpbiB0aGUgaW5zdGFudCBzaW5jZSB3ZSBjaGVja2VkIGlzRW1wdHkoKS4KKyAgICAgICAgaWYgKHBvc3NpYmxlUmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgICBieXRlW10gZW5kS2V5ID0gcG9zc2libGVSZWdpb24uZ2V0UmVnaW9uSW5mbygpLmdldEVuZEtleSgpOworCisgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIGVuZCBrZXkgaXMgZ3JlYXRlciB0aGFuIHRoZSByb3cgd2UncmUgbG9va2luZworICAgICAgICAgIC8vIGZvciwgb3RoZXJ3aXNlIHRoZSByb3cgYWN0dWFsbHkgYmVsb25ncyBpbiB0aGUgbmV4dCByZWdpb24sIG5vdAorICAgICAgICAgIC8vIHRoaXMgb25lLiB0aGUgZXhjZXB0aW9uIGNhc2UgaXMgd2hlbiB0aGUgZW5ka2V5IGlzIEVNUFRZX1NUQVJUX1JPVywKKyAgICAgICAgICAvLyBzaWduaWZ5aW5nIHRoYXQgdGhlIHJlZ2lvbiB3ZSdyZSBjaGVja2luZyBpcyBhY3R1YWxseSB0aGUgbGFzdAorICAgICAgICAgIC8vIHJlZ2lvbiBpbiB0aGUgdGFibGUuCisgICAgICAgICAgaWYgKEhTdG9yZUtleS5lcXVhbHNUd29Sb3dLZXlzKGVuZEtleSwgSENvbnN0YW50cy5FTVBUWV9FTkRfUk9XKSB8fAorICAgICAgICAgICAgICBIU3RvcmVLZXkuZ2V0Q29tcGFyYXRvcih0YWJsZU5hbWUpLmNvbXBhcmVSb3dzKGVuZEtleSwgcm93KSA+IDApIHsKKyAgICAgICAgICAgIHJldHVybiBwb3NzaWJsZVJlZ2lvbjsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLy8gUGFzc2VkIGFsbCB0aGUgd2F5IHRocm91Z2gsIHNvIHdlIGdvdCBub3RoaW4gLSBjb21wbGV0ZSBjYWNoZSBtaXNzCisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIERlbGV0ZSBhIGNhY2hlZCBsb2NhdGlvbiwgaWYgaXQgc2F0aXNmaWVzIHRoZSB0YWJsZSBuYW1lIGFuZCByb3cKKyAgICAgKiByZXF1aXJlbWVudHMuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGRlbGV0ZUNhY2hlZExvY2F0aW9uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgICBmaW5hbCBieXRlIFtdIHJvdykgeworICAgICAgU29mdFZhbHVlU29ydGVkTWFwPGJ5dGUgW10sIEhSZWdpb25Mb2NhdGlvbj4gdGFibGVMb2NhdGlvbnMgPQorICAgICAgICBnZXRUYWJsZUxvY2F0aW9ucyh0YWJsZU5hbWUpOworCisgICAgICAvLyBzdGFydCB0byBleGFtaW5lIHRoZSBjYWNoZS4gd2UgY2FuIG9ubHkgZG8gY2FjaGUgYWN0aW9ucworICAgICAgLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGNhY2hlIGZvciB0aGlzIHRhYmxlLgorICAgICAgaWYgKCF0YWJsZUxvY2F0aW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgICAgLy8gY3V0IHRoZSBjYWNoZSBzbyB0aGF0IHdlIG9ubHkgZ2V0IHRoZSBwYXJ0IHRoYXQgY291bGQgY29udGFpbgorICAgICAgICAvLyByZWdpb25zIHRoYXQgbWF0Y2ggb3VyIGtleQorICAgICAgICBTb2Z0VmFsdWVTb3J0ZWRNYXA8Ynl0ZSBbXSwgSFJlZ2lvbkxvY2F0aW9uPiBtYXRjaGluZ1JlZ2lvbnMgPQorICAgICAgICAgIHRhYmxlTG9jYXRpb25zLmhlYWRNYXAocm93KTsKKworICAgICAgICAvLyBpZiB0aGF0IHBvcnRpb24gb2YgdGhlIG1hcCBpcyBlbXB0eSwgdGhlbiB3ZSdyZSBkb25lLiBvdGhlcndpc2UsCisgICAgICAgIC8vIHdlIG5lZWQgdG8gZXhhbWluZSB0aGUgY2FjaGVkIGxvY2F0aW9uIHRvIHZlcmlmeSB0aGF0IGl0IGlzIAorICAgICAgICAvLyBhIG1hdGNoIGJ5IGVuZCBrZXkgYXMgd2VsbC4KKyAgICAgICAgaWYgKCFtYXRjaGluZ1JlZ2lvbnMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgSFJlZ2lvbkxvY2F0aW9uIHBvc3NpYmxlUmVnaW9uID0KKyAgICAgICAgICAgIG1hdGNoaW5nUmVnaW9ucy5nZXQobWF0Y2hpbmdSZWdpb25zLmxhc3RLZXkoKSk7CisgICAgICAgICAgYnl0ZSBbXSBlbmRLZXkgPSBwb3NzaWJsZVJlZ2lvbi5nZXRSZWdpb25JbmZvKCkuZ2V0RW5kS2V5KCk7CisKKyAgICAgICAgICAvLyBieSBuYXR1cmUgb2YgdGhlIG1hcCwgd2Uga25vdyB0aGF0IHRoZSBzdGFydCBrZXkgaGFzIHRvIGJlIDwgCisgICAgICAgICAgLy8gb3RoZXJ3aXNlIGl0IHdvdWxkbid0IGJlIGluIHRoZSBoZWFkTWFwLiAKKyAgICAgICAgICBpZiAoSFN0b3JlS2V5LmdldENvbXBhcmF0b3IodGFibGVOYW1lKS5jb21wYXJlUm93cyhlbmRLZXksIHJvdykgPD0gMCkgeworICAgICAgICAgICAgLy8gZGVsZXRlIGFueSBtYXRjaGluZyBlbnRyeQorICAgICAgICAgICAgSFJlZ2lvbkxvY2F0aW9uIHJsID0KKyAgICAgICAgICAgICAgdGFibGVMb2NhdGlvbnMucmVtb3ZlKG1hdGNoaW5nUmVnaW9ucy5sYXN0S2V5KCkpOworICAgICAgICAgICAgaWYgKHJsICE9IG51bGwgJiYgTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKCJSZW1vdmVkICIgKyBybC5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKworICAgICAgICAgICAgICAgICIgZm9yIHRhYmxlTmFtZT0iICsgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSArICIgZnJvbSBjYWNoZSAiICsKKyAgICAgICAgICAgICAgICAiYmVjYXVzZSBvZiAiICsgQnl0ZXMudG9TdHJpbmcocm93KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8qCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEByZXR1cm4gTWFwIG9mIGNhY2hlZCBsb2NhdGlvbnMgZm9yIHBhc3NlZCA8Y29kZT50YWJsZU5hbWU8L2NvZGU+CisgICAgICovCisgICAgcHJpdmF0ZSBTb2Z0VmFsdWVTb3J0ZWRNYXA8Ynl0ZSBbXSwgSFJlZ2lvbkxvY2F0aW9uPiBnZXRUYWJsZUxvY2F0aW9ucygKKyAgICAgICAgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpIHsKKyAgICAgIC8vIGZpbmQgdGhlIG1hcCBvZiBjYWNoZWQgbG9jYXRpb25zIGZvciB0aGlzIHRhYmxlCisgICAgICBJbnRlZ2VyIGtleSA9IEJ5dGVzLm1hcEtleSh0YWJsZU5hbWUpOworICAgICAgU29mdFZhbHVlU29ydGVkTWFwPGJ5dGUgW10sIEhSZWdpb25Mb2NhdGlvbj4gcmVzdWx0ID0gbnVsbDsKKyAgICAgIHN5bmNocm9uaXplZCAodGhpcy5jYWNoZWRSZWdpb25Mb2NhdGlvbnMpIHsKKyAgICAgICAgcmVzdWx0ID0gdGhpcy5jYWNoZWRSZWdpb25Mb2NhdGlvbnMuZ2V0KGtleSk7CisgICAgICAgIC8vIGlmIHRhYmxlTG9jYXRpb25zIGZvciB0aGlzIHRhYmxlIGlzbid0IGJ1aWx0IHlldCwgbWFrZSBvbmUKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgICAgcmVzdWx0ID0gbmV3IFNvZnRWYWx1ZVNvcnRlZE1hcDxieXRlIFtdLCBIUmVnaW9uTG9jYXRpb24+KAorICAgICAgICAgICAgICBCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICAgICAgICB0aGlzLmNhY2hlZFJlZ2lvbkxvY2F0aW9ucy5wdXQoa2V5LCByZXN1bHQpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qCisgICAgICogUHV0IGEgbmV3bHkgZGlzY292ZXJlZCBIUmVnaW9uTG9jYXRpb24gaW50byB0aGUgY2FjaGUuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNhY2hlTG9jYXRpb24oZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsCisgICAgICAgIGZpbmFsIEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvbikgeworICAgICAgYnl0ZSBbXSBzdGFydEtleSA9IGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRTdGFydEtleSgpOworICAgICAgU29mdFZhbHVlU29ydGVkTWFwPGJ5dGUgW10sIEhSZWdpb25Mb2NhdGlvbj4gdGFibGVMb2NhdGlvbnMgPQorICAgICAgICBnZXRUYWJsZUxvY2F0aW9ucyh0YWJsZU5hbWUpOworICAgICAgdGFibGVMb2NhdGlvbnMucHV0KHN0YXJ0S2V5LCBsb2NhdGlvbik7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBIUmVnaW9uSW50ZXJmYWNlIGdldEhSZWdpb25Db25uZWN0aW9uKEhTZXJ2ZXJBZGRyZXNzIHJlZ2lvblNlcnZlcikgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGdldE1hc3RlcigpOworICAgICAgSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXI7CisgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMuc2VydmVycykgeworICAgICAgICAvLyBTZWUgaWYgd2UgYWxyZWFkeSBoYXZlIGEgY29ubmVjdGlvbgorICAgICAgICBzZXJ2ZXIgPSB0aGlzLnNlcnZlcnMuZ2V0KHJlZ2lvblNlcnZlci50b1N0cmluZygpKTsKKyAgICAgICAgaWYgKHNlcnZlciA9PSBudWxsKSB7IC8vIEdldCBhIGNvbm5lY3Rpb24KKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2VydmVyID0gKEhSZWdpb25JbnRlcmZhY2UpSEJhc2VSUEMud2FpdEZvclByb3h5KAorICAgICAgICAgICAgICAgIHNlcnZlckludGVyZmFjZUNsYXNzLCBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi52ZXJzaW9uSUQsCisgICAgICAgICAgICAgICAgcmVnaW9uU2VydmVyLmdldEluZXRTb2NrZXRBZGRyZXNzKCksIHRoaXMuY29uZiwgCisgICAgICAgICAgICAgICAgdGhpcy5tYXhSUENBdHRlbXB0cywgdGhpcy5ycGNUaW1lb3V0KTsKKyAgICAgICAgICB9IGNhdGNoIChSZW1vdGVFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oZSk7CisgICAgICAgICAgfQorICAgICAgICAgIHRoaXMuc2VydmVycy5wdXQocmVnaW9uU2VydmVyLnRvU3RyaW5nKCksIHNlcnZlcik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBzZXJ2ZXI7CisgICAgfQorCisgICAgcHVibGljIHN5bmNocm9uaXplZCBab29LZWVwZXJXcmFwcGVyIGdldFpvb0tlZXBlcldyYXBwZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHpvb0tlZXBlcldyYXBwZXIgPT0gbnVsbCkgeworICAgICAgICB6b29LZWVwZXJXcmFwcGVyID0gbmV3IFpvb0tlZXBlcldyYXBwZXIoY29uZiwgdGhpcyk7CisgICAgICB9CisgICAgICByZXR1cm4gem9vS2VlcGVyV3JhcHBlcjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlcGVhdGVkbHkgdHJ5IHRvIGZpbmQgdGhlIHJvb3QgcmVnaW9uIGJ5IGFza2luZyB0aGUgbWFzdGVyIGZvciB3aGVyZSBpdCBpcworICAgICAqIEByZXR1cm4gSFJlZ2lvbkxvY2F0aW9uIGZvciByb290IHJlZ2lvbiBpZiBmb3VuZAorICAgICAqIEB0aHJvd3MgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24gLSBpZiB0aGUgcm9vdCByZWdpb24gY2FuIG5vdCBiZQorICAgICAqIGxvY2F0ZWQgYWZ0ZXIgcmV0cnlpbmcKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgICAqLworICAgIHByaXZhdGUgSFJlZ2lvbkxvY2F0aW9uIGxvY2F0ZVJvb3RSZWdpb24oKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBnZXRNYXN0ZXIoKTsKKworICAgICAgLy8gV2UgbGF6aWx5IGluc3RhbnRpYXRlIHRoZSBab29LZWVwZXIgb2JqZWN0IGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0bworICAgICAgLy8gbWFrZSB0aGUgY29uc3RydWN0b3IgaGF2ZSB0byB0aHJvdyBJT0V4Y2VwdGlvbiBvciBoYW5kbGUgaXQgaXRzZWxmLgorICAgICAgWm9vS2VlcGVyV3JhcHBlciB6ayA9IGdldFpvb0tlZXBlcldyYXBwZXIoKTsKKworICAgICAgSFNlcnZlckFkZHJlc3Mgcm9vdFJlZ2lvbkFkZHJlc3MgPSBudWxsOworICAgICAgZm9yIChpbnQgdHJpZXMgPSAwOyB0cmllcyA8IG51bVJldHJpZXM7IHRyaWVzKyspIHsKKyAgICAgICAgaW50IGxvY2FsVGltZW91dHMgPSAwOworICAgICAgICAvLyBhc2sgdGhlIG1hc3RlciB3aGljaCBzZXJ2ZXIgaGFzIHRoZSByb290IHJlZ2lvbgorICAgICAgICB3aGlsZSAocm9vdFJlZ2lvbkFkZHJlc3MgPT0gbnVsbCAmJiBsb2NhbFRpbWVvdXRzIDwgbnVtUmV0cmllcykgeworICAgICAgICAgIC8vIERvbid0IHJlYWQgcm9vdCByZWdpb24gdW50aWwgd2UncmUgb3V0IG9mIHNhZmUgbW9kZSBzbyB3ZSBrbm93CisgICAgICAgICAgLy8gdGhhdCB0aGUgbWV0YSByZWdpb25zIGhhdmUgYmVlbiBhc3NpZ25lZC4KKyAgICAgICAgICBib29sZWFuIG91dE9mU2FmZU1vZGUgPSB6ay5jaGVja091dE9mU2FmZU1vZGUoKTsKKyAgICAgICAgICBpZiAob3V0T2ZTYWZlTW9kZSkgeworICAgICAgICAgICAgcm9vdFJlZ2lvbkFkZHJlc3MgPSB6ay5yZWFkUm9vdFJlZ2lvbkxvY2F0aW9uKCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChyb290UmVnaW9uQWRkcmVzcyA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgICBMT0cuZGVidWcoIlNsZWVwaW5nICIgKyBnZXRQYXVzZVRpbWUodHJpZXMpICsKKyAgICAgICAgICAgICAgICAgICJtcywgd2FpdGluZyBmb3Igcm9vdCByZWdpb24uIik7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKGdldFBhdXNlVGltZSh0cmllcykpOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWV4KSB7CisgICAgICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBsb2NhbFRpbWVvdXRzKys7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKHJvb3RSZWdpb25BZGRyZXNzID09IG51bGwpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24oCisgICAgICAgICAgICAgICJUaW1lZCBvdXQgdHJ5aW5nIHRvIGxvY2F0ZSByb290IHJlZ2lvbiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gZ2V0IGEgY29ubmVjdGlvbiB0byB0aGUgcmVnaW9uIHNlcnZlcgorICAgICAgICBIUmVnaW9uSW50ZXJmYWNlIHNlcnZlciA9IGdldEhSZWdpb25Db25uZWN0aW9uKHJvb3RSZWdpb25BZGRyZXNzKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAvLyBpZiB0aGlzIHdvcmtzLCB0aGVuIHdlJ3JlIGdvb2QsIGFuZCB3ZSBoYXZlIGFuIGFjY2VwdGFibGUgYWRkcmVzcywKKyAgICAgICAgICAvLyBzbyB3ZSBjYW4gc3RvcCBkb2luZyByZXRyaWVzIGFuZCByZXR1cm4gdGhlIHJlc3VsdC4KKyAgICAgICAgICBzZXJ2ZXIuZ2V0UmVnaW9uSW5mbyhIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgIExPRy5kZWJ1ZygiRm91bmQgUk9PVCBhdCAiICsgcm9vdFJlZ2lvbkFkZHJlc3MpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIGlmICh0cmllcyA9PSBudW1SZXRyaWVzIC0gMSkgeworICAgICAgICAgICAgLy8gRG9uJ3QgYm90aGVyIHNsZWVwaW5nLiBXZSd2ZSBydW4gb3V0IG9mIHJldHJpZXMuCisgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAoUmVtb3RlRXhjZXB0aW9uKSBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIC8vIFNsZWVwIGFuZCByZXRyeSBmaW5kaW5nIHJvb3QgcmVnaW9uLgorICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKCJSb290IHJlZ2lvbiBsb2NhdGlvbiBjaGFuZ2VkLiBTbGVlcGluZy4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUodHJpZXMpKTsKKyAgICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgICBMT0cuZGVidWcoIldha2UuIFJldHJ5IGZpbmRpbmcgcm9vdCByZWdpb24uIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWV4KSB7CisgICAgICAgICAgICAvLyBjb250aW51ZQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcm9vdFJlZ2lvbkFkZHJlc3MgPSBudWxsOworICAgICAgfQorICAgICAgCisgICAgICAvLyBpZiB0aGUgYWRkcmVzcyBpcyBudWxsIGJ5IHRoaXMgcG9pbnQsIHRoZW4gdGhlIHJldHJpZXMgaGF2ZSBmYWlsZWQsCisgICAgICAvLyBhbmQgd2UncmUgc29ydCBvZiBzdW5rCisgICAgICBpZiAocm9vdFJlZ2lvbkFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24oCisgICAgICAgICAgInVuYWJsZSB0byBsb2NhdGUgcm9vdCByZWdpb24gc2VydmVyIik7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIHJldHVybiB0aGUgcmVnaW9uIGxvY2F0aW9uCisgICAgICByZXR1cm4gbmV3IEhSZWdpb25Mb2NhdGlvbigKKyAgICAgICAgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLCByb290UmVnaW9uQWRkcmVzcyk7CisgICAgfQorCisgICAgcHVibGljIDxUPiBUIGdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKFNlcnZlckNhbGxhYmxlPFQ+IGNhbGxhYmxlKSAKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24geworICAgICAgZ2V0TWFzdGVyKCk7CisgICAgICBMaXN0PFRocm93YWJsZT4gZXhjZXB0aW9ucyA9IG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigpOworICAgICAgZm9yKGludCB0cmllcyA9IDA7IHRyaWVzIDwgbnVtUmV0cmllczsgdHJpZXMrKykgeworICAgICAgICB0cnkgeworICAgICAgICAgIGNhbGxhYmxlLmluc3RhbnRpYXRlU2VydmVyKHRyaWVzICE9IDApOworICAgICAgICAgIHJldHVybiBjYWxsYWJsZS5jYWxsKCk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0ID0gdC5nZXRDYXVzZSgpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgdCA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKChSZW1vdGVFeGNlcHRpb24pdCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmICh0IGluc3RhbmNlb2YgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uKSB7CisgICAgICAgICAgICB0aHJvdyAoRG9Ob3RSZXRyeUlPRXhjZXB0aW9uKXQ7CisgICAgICAgICAgfQorICAgICAgICAgIGV4Y2VwdGlvbnMuYWRkKHQpOworICAgICAgICAgIGlmICh0cmllcyA9PSBudW1SZXRyaWVzIC0gMSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJldHJpZXNFeGhhdXN0ZWRFeGNlcHRpb24oY2FsbGFibGUuZ2V0U2VydmVyTmFtZSgpLAorICAgICAgICAgICAgICAgIGNhbGxhYmxlLmdldFJlZ2lvbk5hbWUoKSwgY2FsbGFibGUuZ2V0Um93KCksIHRyaWVzLCBleGNlcHRpb25zKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoZ2V0UGF1c2VUaW1lKHRyaWVzKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvLyBjb250aW51ZQorICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsgICAgCisgICAgfQorICAgIAorICAgIHB1YmxpYyA8VD4gVCBnZXRSZWdpb25TZXJ2ZXJGb3JXaXRob3V0UmV0cmllcyhTZXJ2ZXJDYWxsYWJsZTxUPiBjYWxsYWJsZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uIHsKKyAgICAgIGdldE1hc3RlcigpOworICAgICAgdHJ5IHsKKyAgICAgICAgY2FsbGFibGUuaW5zdGFudGlhdGVTZXJ2ZXIoZmFsc2UpOworICAgICAgICByZXR1cm4gY2FsbGFibGUuY2FsbCgpOworICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBVbmRlY2xhcmVkVGhyb3dhYmxlRXhjZXB0aW9uKSB7CisgICAgICAgICAgdCA9IHQuZ2V0Q2F1c2UoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgICAgIHQgPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbigoUmVtb3RlRXhjZXB0aW9uKSB0KTsKKyAgICAgICAgfQorICAgICAgICBpZiAodCBpbnN0YW5jZW9mIERvTm90UmV0cnlJT0V4Y2VwdGlvbikgeworICAgICAgICAgIHRocm93IChEb05vdFJldHJ5SU9FeGNlcHRpb24pIHQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBudWxsOyAgICAKKyAgICB9CisKKyAgICBwcml2YXRlIEhSZWdpb25Mb2NhdGlvbgorICAgIGdldFJlZ2lvbkxvY2F0aW9uRm9yUm93V2l0aFJldHJpZXMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd0tleSwgCisgICAgICBib29sZWFuIHJlbG9hZCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYm9vbGVhbiByZWxvYWRGbGFnID0gcmVsb2FkOworICAgICAgZ2V0TWFzdGVyKCk7CisgICAgICBMaXN0PFRocm93YWJsZT4gZXhjZXB0aW9ucyA9IG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigpOworICAgICAgSFJlZ2lvbkxvY2F0aW9uIGxvY2F0aW9uID0gbnVsbDsKKyAgICAgIGludCB0cmllcyA9IDA7CisgICAgICB3aGlsZSAodHJpZXMgPCBudW1SZXRyaWVzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgbG9jYXRpb24gPSBnZXRSZWdpb25Mb2NhdGlvbih0YWJsZU5hbWUsIHJvd0tleSwgcmVsb2FkRmxhZyk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgZXhjZXB0aW9ucy5hZGQodCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGxvY2F0aW9uICE9IG51bGwpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICByZWxvYWRGbGFnID0gdHJ1ZTsKKyAgICAgICAgdHJpZXMrKzsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoZ2V0UGF1c2VUaW1lKHRyaWVzKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvLyBjb250aW51ZQorICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgUmV0cmllc0V4aGF1c3RlZEV4Y2VwdGlvbigiU29tZSBzZXJ2ZXIiLAorICAgICAgICAgIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwgcm93S2V5LCB0cmllcywgZXhjZXB0aW9ucyk7CisgICAgICB9CisgICAgICByZXR1cm4gbG9jYXRpb247CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHJvY2Vzc0JhdGNoT2ZSb3dzKEFycmF5TGlzdDxCYXRjaFVwZGF0ZT4gbGlzdCwgYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChsaXN0LmlzRW1wdHkoKSkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBib29sZWFuIHJldHJ5T25seU9uZSA9IGZhbHNlOworICAgICAgaW50IHRyaWVzID0gMDsKKyAgICAgIENvbGxlY3Rpb25zLnNvcnQobGlzdCk7CisgICAgICBMaXN0PEJhdGNoVXBkYXRlPiB0ZW1wVXBkYXRlcyA9IG5ldyBBcnJheUxpc3Q8QmF0Y2hVcGRhdGU+KCk7CisgICAgICBIUmVnaW9uTG9jYXRpb24gbG9jYXRpb24gPQorICAgICAgICBnZXRSZWdpb25Mb2NhdGlvbkZvclJvd1dpdGhSZXRyaWVzKHRhYmxlTmFtZSwgbGlzdC5nZXQoMCkuZ2V0Um93KCksCisgICAgICAgICAgICBmYWxzZSk7CisgICAgICBieXRlIFtdIGN1cnJlbnRSZWdpb24gPSBsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpOworICAgICAgYnl0ZSBbXSByZWdpb24gPSBjdXJyZW50UmVnaW9uOworICAgICAgYm9vbGVhbiBpc0xhc3RSb3cgPSBmYWxzZTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdC5zaXplKCkgJiYgdHJpZXMgPCBudW1SZXRyaWVzOyBpKyspIHsKKyAgICAgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBsaXN0LmdldChpKTsKKyAgICAgICAgdGVtcFVwZGF0ZXMuYWRkKGJhdGNoVXBkYXRlKTsKKyAgICAgICAgaXNMYXN0Um93ID0gKGkgKyAxKSA9PSBsaXN0LnNpemUoKTsKKyAgICAgICAgaWYgKCFpc0xhc3RSb3cpIHsKKyAgICAgICAgICBsb2NhdGlvbiA9IGdldFJlZ2lvbkxvY2F0aW9uRm9yUm93V2l0aFJldHJpZXModGFibGVOYW1lLAorICAgICAgICAgICAgbGlzdC5nZXQoaSsxKS5nZXRSb3coKSwgZmFsc2UpOworICAgICAgICAgIHJlZ2lvbiA9IGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFCeXRlcy5lcXVhbHMoY3VycmVudFJlZ2lvbiwgcmVnaW9uKSB8fCBpc0xhc3RSb3cgfHwgcmV0cnlPbmx5T25lKSB7CisgICAgICAgICAgZmluYWwgQmF0Y2hVcGRhdGVbXSB1cGRhdGVzID0gdGVtcFVwZGF0ZXMudG9BcnJheShuZXcgQmF0Y2hVcGRhdGVbMF0pOworICAgICAgICAgIGludCBpbmRleCA9IGdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKG5ldyBTZXJ2ZXJDYWxsYWJsZTxJbnRlZ2VyPigKKyAgICAgICAgICAgICAgdGhpcywgdGFibGVOYW1lLCBiYXRjaFVwZGF0ZS5nZXRSb3coKSkgeworICAgICAgICAgICAgcHVibGljIEludGVnZXIgY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICAgIGludCBpID0gc2VydmVyLmJhdGNoVXBkYXRlcyhsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkKKyAgICAgICAgICAgICAgICAgIC5nZXRSZWdpb25OYW1lKCksIHVwZGF0ZXMpOworICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9KTsKKyAgICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKKyAgICAgICAgICAgIGlmICh0cmllcyA9PSBudW1SZXRyaWVzIC0gMSkgeworICAgICAgICAgICAgICB0aHJvdyBuZXcgUmV0cmllc0V4aGF1c3RlZEV4Y2VwdGlvbigiU29tZSBzZXJ2ZXIiLAorICAgICAgICAgICAgICAgICAgY3VycmVudFJlZ2lvbiwgYmF0Y2hVcGRhdGUuZ2V0Um93KCksIAorICAgICAgICAgICAgICAgICAgdHJpZXMsIG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGxvbmcgc2xlZXBUaW1lID0gZ2V0UGF1c2VUaW1lKHRyaWVzKTsKKyAgICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgICBMT0cuZGVidWcoIlJlbG9hZGluZyByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKGN1cnJlbnRSZWdpb24pICsKKyAgICAgICAgICAgICAgICAiIGxvY2F0aW9uIGJlY2F1c2UgcmVnaW9uc2VydmVyIGRpZG4ndCBhY2NlcHQgdXBkYXRlczsgIiArCisgICAgICAgICAgICAgICAgInRyaWVzPSIgKyB0cmllcyArCisgICAgICAgICAgICAgICAgIiBvZiBtYXg9IiArIHRoaXMubnVtUmV0cmllcyArICIsIHdhaXRpbmc9IiArIHNsZWVwVGltZSArICJtcyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKHNsZWVwVGltZSk7CisgICAgICAgICAgICAgIHRyaWVzKys7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpID0gaSAtIHVwZGF0ZXMubGVuZ3RoICsgaW5kZXg7CisgICAgICAgICAgICByZXRyeU9ubHlPbmUgPSB0cnVlOworICAgICAgICAgICAgbG9jYXRpb24gPSBnZXRSZWdpb25Mb2NhdGlvbkZvclJvd1dpdGhSZXRyaWVzKHRhYmxlTmFtZSwgCisgICAgICAgICAgICAgIGxpc3QuZ2V0KGkgKyAxKS5nZXRSb3coKSwgdHJ1ZSk7CisgICAgICAgICAgICByZWdpb24gPSBsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpOworICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHJldHJ5T25seU9uZSA9IGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgICBjdXJyZW50UmVnaW9uID0gcmVnaW9uOworICAgICAgICAgIHRlbXBVcGRhdGVzLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGNsb3NlKGJvb2xlYW4gc3RvcFByb3h5KSB7CisgICAgICBpZiAobWFzdGVyICE9IG51bGwpIHsKKyAgICAgICAgaWYgKHN0b3BQcm94eSkgeworICAgICAgICAgIEhCYXNlUlBDLnN0b3BQcm94eShtYXN0ZXIpOworICAgICAgICB9CisgICAgICAgIG1hc3RlciA9IG51bGw7CisgICAgICAgIG1hc3RlckNoZWNrZWQgPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmIChzdG9wUHJveHkpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChzZXJ2ZXJzKSB7CisgICAgICAgICAgZm9yIChIUmVnaW9uSW50ZXJmYWNlIGk6IHNlcnZlcnMudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIEhCYXNlUlBDLnN0b3BQcm94eShpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0gCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L0hUYWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L0hUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI3MWRiYzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvSFRhYmxlLmphdmEKQEAgLTAsMCArMSwxNzcwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkxvY2F0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJBZGRyZXNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTdG9yZUtleTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlVua25vd25TY2FubmVyRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5NZXRhU2Nhbm5lci5NZXRhU2Nhbm5lclZpc2l0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuU3RvcFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuV2hpbGVNYXRjaFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaE9wZXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5IYmFzZU1hcFdyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5QYWlyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKioKKyAqIFVzZWQgdG8gY29tbXVuaWNhdGUgd2l0aCBhIHNpbmdsZSBIQmFzZSB0YWJsZQorICovCitwdWJsaWMgY2xhc3MgSFRhYmxlIHsKKyAgcHJpdmF0ZSBmaW5hbCBIQ29ubmVjdGlvbiBjb25uZWN0aW9uOworICBwcml2YXRlIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lOworICBwcm90ZWN0ZWQgZmluYWwgaW50IHNjYW5uZXJUaW1lb3V0OworICBwcml2YXRlIHZvbGF0aWxlIEhCYXNlQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uOworICBwcml2YXRlIEFycmF5TGlzdDxCYXRjaFVwZGF0ZT4gd3JpdGVCdWZmZXI7CisgIHByaXZhdGUgbG9uZyB3cml0ZUJ1ZmZlclNpemU7CisgIHByaXZhdGUgYm9vbGVhbiBhdXRvRmx1c2g7CisgIHByaXZhdGUgbG9uZyBjdXJyZW50V3JpdGVCdWZmZXJTaXplOworICBwcm90ZWN0ZWQgaW50IHNjYW5uZXJDYWNoaW5nOworCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0byBhY2Nlc3MgYSBIQmFzZSB0YWJsZQorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGhlIHRhYmxlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIVGFibGUoZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzKG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKSwgQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0byBhY2Nlc3MgYSBIQmFzZSB0YWJsZQorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGhlIHRhYmxlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIVGFibGUoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcyhuZXcgSEJhc2VDb25maWd1cmF0aW9uKCksIHRhYmxlTmFtZSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhbiBvYmplY3QgdG8gYWNjZXNzIGEgSEJhc2UgdGFibGUKKyAgICogCisgICAqIEBwYXJhbSBjb25mIGNvbmZpZ3VyYXRpb24gb2JqZWN0CisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZShIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzKGNvbmYsIEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhbiBvYmplY3QgdG8gYWNjZXNzIGEgSEJhc2UgdGFibGUKKyAgICogCisgICAqIEBwYXJhbSBjb25mIGNvbmZpZ3VyYXRpb24gb2JqZWN0CisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZShIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5jb25uZWN0aW9uID0gSENvbm5lY3Rpb25NYW5hZ2VyLmdldENvbm5lY3Rpb24oY29uZik7CisgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgdGhpcy5zY2FubmVyVGltZW91dCA9CisgICAgICBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmxlYXNlLnBlcmlvZCIsIDYwICogMTAwMCk7CisgICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZjsKKyAgICB0aGlzLmNvbm5lY3Rpb24ubG9jYXRlUmVnaW9uKHRhYmxlTmFtZSwgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1cpOworICAgIHRoaXMud3JpdGVCdWZmZXIgPSBuZXcgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPigpOworICAgIHRoaXMud3JpdGVCdWZmZXJTaXplID0gCisgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9uZygiaGJhc2UuY2xpZW50LndyaXRlLmJ1ZmZlciIsIDIwOTcxNTIpOworICAgIHRoaXMuYXV0b0ZsdXNoID0gdHJ1ZTsKKyAgICB0aGlzLmN1cnJlbnRXcml0ZUJ1ZmZlclNpemUgPSAwOworICAgIHRoaXMuc2Nhbm5lckNhY2hpbmcgPSBjb25mLmdldEludCgiaGJhc2UuY2xpZW50LnNjYW5uZXIuY2FjaGluZyIsIDEpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBjaGVjaworICAgKiBAcmV0dXJuIHRydWUgaWYgdGFibGUgaXMgb24tbGluZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNUYWJsZUVuYWJsZWQoU3RyaW5nIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gaXNUYWJsZUVuYWJsZWQoQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgfQorICAvKioKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlIHRvIGNoZWNrCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0YWJsZSBpcyBvbi1saW5lCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1RhYmxlRW5hYmxlZChieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBpc1RhYmxlRW5hYmxlZChuZXcgSEJhc2VDb25maWd1cmF0aW9uKCksIHRhYmxlTmFtZSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gY29uZiBIQmFzZUNvbmZpZ3VyYXRpb24gb2JqZWN0CisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBjaGVjaworICAgKiBAcmV0dXJuIHRydWUgaWYgdGFibGUgaXMgb24tbGluZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNUYWJsZUVuYWJsZWQoSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIFN0cmluZyB0YWJsZU5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGlzVGFibGVFbmFibGVkKGNvbmYsIEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGNvbmYgSEJhc2VDb25maWd1cmF0aW9uIG9iamVjdAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gY2hlY2sKKyAgICogQHJldHVybiB0cnVlIGlmIHRhYmxlIGlzIG9uLWxpbmUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVGFibGVFbmFibGVkKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBieXRlW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBIQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKS5pc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgcmVnaW9uIGxvY2F0aW9uIGhvc3RpbmcgcGFzc2VkIHJvdyB1c2luZyBjYWNoZWQgaW5mbworICAgKiBAcGFyYW0gcm93IFJvdyB0byBmaW5kLgorICAgKiBAcmV0dXJuIExvY2F0aW9uIG9mIHJvdy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25Mb2NhdGlvbiBnZXRSZWdpb25Mb2NhdGlvbihmaW5hbCBTdHJpbmcgcm93KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjb25uZWN0aW9uLmdldFJlZ2lvbkxvY2F0aW9uKHRhYmxlTmFtZSwgQnl0ZXMudG9CeXRlcyhyb3cpLCBmYWxzZSk7CisgIH0KKworICAvKioKKyAgICogRmluZCByZWdpb24gbG9jYXRpb24gaG9zdGluZyBwYXNzZWQgcm93IHVzaW5nIGNhY2hlZCBpbmZvCisgICAqIEBwYXJhbSByb3cgUm93IHRvIGZpbmQuCisgICAqIEByZXR1cm4gTG9jYXRpb24gb2Ygcm93LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSFJlZ2lvbkxvY2F0aW9uIGdldFJlZ2lvbkxvY2F0aW9uKGZpbmFsIGJ5dGUgW10gcm93KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjb25uZWN0aW9uLmdldFJlZ2lvbkxvY2F0aW9uKHRhYmxlTmFtZSwgcm93LCBmYWxzZSk7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgdGFibGUgbmFtZSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICB9CisKKyAgLyoqCisgICAqIFVzZWQgYnkgdW5pdCB0ZXN0cyBhbmQgdG9vbHMgdG8gZG8gbG93LWxldmVsIG1hbmlwdWxhdGlvbnMuICBOb3QgZm9yCisgICAqIGdlbmVyYWwgdXNlLgorICAgKiBAcmV0dXJuIEFuIEhDb25uZWN0aW9uIGluc3RhbmNlLgorICAgKi8KKyAgcHVibGljIEhDb25uZWN0aW9uIGdldENvbm5lY3Rpb24oKSB7CisgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgbnVtYmVyIG9mIHJvd3MgZm9yIGNhY2hpbmcgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byBzY2FubmVycworICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygcm93cyBmb3IgY2FjaGluZworICAgKi8KKyAgcHVibGljIGludCBnZXRTY2FubmVyQ2FjaGluZygpIHsKKyAgICByZXR1cm4gc2Nhbm5lckNhY2hpbmc7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBudW1iZXIgb2Ygcm93cyBmb3IgY2FjaGluZyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHNjYW5uZXJzCisgICAqIEBwYXJhbSBzY2FubmVyQ2FjaGluZyB0aGUgbnVtYmVyIG9mIHJvd3MgZm9yIGNhY2hpbmcKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFNjYW5uZXJDYWNoaW5nKGludCBzY2FubmVyQ2FjaGluZykgeworICAgIHRoaXMuc2Nhbm5lckNhY2hpbmcgPSBzY2FubmVyQ2FjaGluZzsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRhYmxlIG1ldGFkYXRhIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSFRhYmxlRGVzY3JpcHRvciBnZXRUYWJsZURlc2NyaXB0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBuZXcgVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvcigKKyAgICAgIHRoaXMuY29ubmVjdGlvbi5nZXRIVGFibGVEZXNjcmlwdG9yKHRoaXMudGFibGVOYW1lKSk7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgc3RhcnRpbmcgcm93IGtleSBmb3IgZXZlcnkgcmVnaW9uIGluIHRoZSBjdXJyZW50bHkgb3BlbiB0YWJsZQorICAgKiAKKyAgICogQHJldHVybiBBcnJheSBvZiByZWdpb24gc3RhcnRpbmcgcm93IGtleXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJ5dGUgW11bXSBnZXRTdGFydEtleXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTdGFydEVuZEtleXMoKS5nZXRGaXJzdCgpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIGVuZGluZyByb3cga2V5IGZvciBldmVyeSByZWdpb24gaW4gdGhlIGN1cnJlbnRseSBvcGVuIHRhYmxlCisgICAqIAorICAgKiBAcmV0dXJuIEFycmF5IG9mIHJlZ2lvbiBlbmRpbmcgcm93IGtleXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJ5dGVbXVtdIGdldEVuZEtleXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTdGFydEVuZEtleXMoKS5nZXRTZWNvbmQoKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBzdGFydGluZyBhbmQgZW5kaW5nIHJvdyBrZXlzIGZvciBldmVyeSByZWdpb24gaW4gdGhlIGN1cnJlbnRseSBvcGVuIHRhYmxlCisgICAqIAorICAgKiBAcmV0dXJuIFBhaXIgb2YgYXJyYXlzIG9mIHJlZ2lvbiBzdGFydGluZyBhbmQgZW5kaW5nIHJvdyBrZXlzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgUGFpcjxieXRlW11bXSxieXRlW11bXT4gZ2V0U3RhcnRFbmRLZXlzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBMaXN0PGJ5dGVbXT4gc3RhcnRLZXlMaXN0ID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgZmluYWwgTGlzdDxieXRlW10+IGVuZEtleUxpc3QgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oKTsKKyAgICBNZXRhU2Nhbm5lclZpc2l0b3IgdmlzaXRvciA9IG5ldyBNZXRhU2Nhbm5lclZpc2l0b3IoKSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KFJvd1Jlc3VsdCByb3dSZXN1bHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8oCisgICAgICAgICAgICByb3dSZXN1bHQuZ2V0KEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8pKTsKKyAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgZ2V0VGFibGVOYW1lKCkpKSB7CisgICAgICAgICAgaWYgKCEoaW5mby5pc09mZmxpbmUoKSB8fCBpbmZvLmlzU3BsaXQoKSkpIHsKKyAgICAgICAgICAgIHN0YXJ0S2V5TGlzdC5hZGQoaW5mby5nZXRTdGFydEtleSgpKTsKKyAgICAgICAgICAgIGVuZEtleUxpc3QuYWRkKGluZm8uZ2V0RW5kS2V5KCkpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9OworICAgIE1ldGFTY2FubmVyLm1ldGFTY2FuKGNvbmZpZ3VyYXRpb24sIHZpc2l0b3IsIHRoaXMudGFibGVOYW1lKTsKKyAgICByZXR1cm4gbmV3IFBhaXIoc3RhcnRLZXlMaXN0LnRvQXJyYXkobmV3IGJ5dGVbc3RhcnRLZXlMaXN0LnNpemUoKV1bXSksCisgICAgICAgICAgICAgICAgZW5kS2V5TGlzdC50b0FycmF5KG5ldyBieXRlW2VuZEtleUxpc3Quc2l6ZSgpXVtdKSk7CisgIH0KKworICAvKioKKyAgICogR2V0IGFsbCB0aGUgcmVnaW9ucyBhbmQgdGhlaXIgYWRkcmVzcyBmb3IgdGhpcyB0YWJsZQorICAgKiAKKyAgICogQHJldHVybiBBIG1hcCBvZiBIUmVnaW9uSW5mbyB3aXRoIGl0J3Mgc2VydmVyIGFkZHJlc3MKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIE1hcDxIUmVnaW9uSW5mbywgSFNlcnZlckFkZHJlc3M+IGdldFJlZ2lvbnNJbmZvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBNYXA8SFJlZ2lvbkluZm8sIEhTZXJ2ZXJBZGRyZXNzPiByZWdpb25NYXAgPQorICAgICAgbmV3IFRyZWVNYXA8SFJlZ2lvbkluZm8sIEhTZXJ2ZXJBZGRyZXNzPigpOworCisgICAgTWV0YVNjYW5uZXJWaXNpdG9yIHZpc2l0b3IgPSBuZXcgTWV0YVNjYW5uZXJWaXNpdG9yKCkgeworICAgICAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc1JvdyhSb3dSZXN1bHQgcm93UmVzdWx0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBIUmVnaW9uSW5mbyBpbmZvID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKAorICAgICAgICAgICAgcm93UmVzdWx0LmdldChIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKSk7CisgICAgICAgIAorICAgICAgICBpZiAoIShCeXRlcy5lcXVhbHMoaW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCksIGdldFRhYmxlTmFtZSgpKSkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBIU2VydmVyQWRkcmVzcyBzZXJ2ZXIgPSBuZXcgSFNlcnZlckFkZHJlc3MoKTsKKyAgICAgICAgQ2VsbCBjID0gcm93UmVzdWx0LmdldChIQ29uc3RhbnRzLkNPTF9TRVJWRVIpOworICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuZ2V0VmFsdWUoKSAhPSBudWxsICYmIGMuZ2V0VmFsdWUoKS5sZW5ndGggPiAwKSB7CisgICAgICAgICAgU3RyaW5nIGFkZHJlc3MgPSBCeXRlcy50b1N0cmluZyhjLmdldFZhbHVlKCkpOworICAgICAgICAgIHNlcnZlciA9IG5ldyBIU2VydmVyQWRkcmVzcyhhZGRyZXNzKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaWYgKCEoaW5mby5pc09mZmxpbmUoKSB8fCBpbmZvLmlzU3BsaXQoKSkpIHsKKyAgICAgICAgICByZWdpb25NYXAucHV0KG5ldyBVbm1vZGlmeWFibGVIUmVnaW9uSW5mbyhpbmZvKSwgc2VydmVyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgIH07CisgICAgTWV0YVNjYW5uZXIubWV0YVNjYW4oY29uZmlndXJhdGlvbiwgdmlzaXRvciwgdGFibGVOYW1lKTsKKyAgICByZXR1cm4gcmVnaW9uTWFwOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNpbmdsZSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCByb3cgYW5kIGNvbHVtbgorICAgKiAKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICogQHJldHVybiB2YWx1ZSBmb3Igc3BlY2lmaWVkIHJvdy9jb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGwgZ2V0KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBjb2x1bW4pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldChCeXRlcy50b0J5dGVzKHJvdyksIEJ5dGVzLnRvQnl0ZXMoY29sdW1uKSk7CisgIH0KKworICAvKiogCisgICAqIEdldCBhIHNpbmdsZSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCByb3cgYW5kIGNvbHVtbgorICAgKgorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gbmFtZQorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgLSBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0cmlldmUKKyAgICogQHJldHVybiB2YWx1ZSBmb3Igc3BlY2lmaWVkIHJvdy9jb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGwgW10gZ2V0KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBjb2x1bW4sIGludCBudW1WZXJzaW9ucykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0KEJ5dGVzLnRvQnl0ZXMocm93KSwgQnl0ZXMudG9CeXRlcyhjb2x1bW4pLCBudW1WZXJzaW9ucyk7CisgIH0KKworICAvKiogCisgICAqIEdldCBhIHNpbmdsZSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCByb3cgYW5kIGNvbHVtbgorICAgKgorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gbmFtZQorICAgKiBAcmV0dXJuIHZhbHVlIGZvciBzcGVjaWZpZWQgcm93L2NvbHVtbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgQ2VsbCBnZXQoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjb25uZWN0aW9uLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKAorICAgICAgICBuZXcgU2VydmVyQ2FsbGFibGU8Q2VsbD4oY29ubmVjdGlvbiwgdGFibGVOYW1lLCByb3cpIHsKKyAgICAgICAgICBwdWJsaWMgQ2VsbCBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIENlbGxbXSByZXN1bHQgPSBzZXJ2ZXIuZ2V0KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIAorICAgICAgICAgICAgICAgIHJvdywgY29sdW1uLCAtMSwgLTEpOworICAgICAgICAgICAgcmV0dXJuIChyZXN1bHQgPT0gbnVsbCk/IG51bGwgOiByZXN1bHRbMF07CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHZlcnNpb25zIG9mIHRoZSBzcGVjaWZpZWQgcm93IGFuZCBjb2x1bW4KKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXRyaWV2ZQorICAgKiBAcmV0dXJuIEFycmF5IG9mIENlbGxzLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgQ2VsbCBbXSBnZXQoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uLAorICAgIGZpbmFsIGludCBudW1WZXJzaW9ucykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNvbm5lY3Rpb24uZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxDZWxsW10+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIENlbGxbXSBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJ2ZXIuZ2V0KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgCisgICAgICAgICAgICAgICAgY29sdW1uLCAtMSwgbnVtVmVyc2lvbnMpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICk7CisgIH0KKworICAvKiogCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBvZiB0aGUgc3BlY2lmaWVkIHJvdyBhbmQgY29sdW1uIHdpdGgKKyAgICogdGhlIHNwZWNpZmllZCB0aW1lc3RhbXAuCisgICAqCisgICAqIEBwYXJhbSByb3cgICAgICAgICAtIHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiAgICAgIC0gY29sdW1uIG5hbWUKKyAgICogQHBhcmFtIHRpbWVzdGFtcCAgIC0gdGltZXN0YW1wCisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyAtIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXRyaWV2ZQorICAgKiBAcmV0dXJuICAgICAgICAgICAgLSBhcnJheSBvZiB2YWx1ZXMgdGhhdCBtYXRjaCB0aGUgYWJvdmUgY3JpdGVyaWEKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGxbXSBnZXQoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbiwKKyAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgaW50IG51bVZlcnNpb25zKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXQoQnl0ZXMudG9CeXRlcyhyb3cpLCBCeXRlcy50b0J5dGVzKGNvbHVtbiksIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOworICB9CisKKyAgLyoqIAorICAgKiBHZXQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdmVyc2lvbnMgb2YgdGhlIHNwZWNpZmllZCByb3cgYW5kIGNvbHVtbiB3aXRoCisgICAqIHRoZSBzcGVjaWZpZWQgdGltZXN0YW1wLgorICAgKgorICAgKiBAcGFyYW0gcm93ICAgICAgICAgLSByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gICAgICAtIGNvbHVtbiBuYW1lCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgICAtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgLSBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0cmlldmUKKyAgICogQHJldHVybiAgICAgICAgICAgIC0gYXJyYXkgb2YgdmFsdWVzIHRoYXQgbWF0Y2ggdGhlIGFib3ZlIGNyaXRlcmlhCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsW10gZ2V0KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgaW50IG51bVZlcnNpb25zKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIENlbGxbXSB2YWx1ZXMgPSBudWxsOworICAgIHZhbHVlcyA9IGNvbm5lY3Rpb24uZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxDZWxsW10+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIENlbGxbXSBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJ2ZXIuZ2V0KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgCisgICAgICAgICAgICAgICAgY29sdW1uLCB0aW1lc3RhbXAsIG51bVZlcnNpb25zKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICApOworCisgICAgaWYgKHZhbHVlcyAhPSBudWxsKSB7CisgICAgICBBcnJheUxpc3Q8Q2VsbD4gY2VsbFZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8Q2VsbD4oKTsKKyAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgeworICAgICAgICBjZWxsVmFsdWVzLmFkZCh2YWx1ZXNbaV0pOworICAgICAgfQorICAgICAgcmV0dXJuIGNlbGxWYWx1ZXMudG9BcnJheShuZXcgQ2VsbFt2YWx1ZXMubGVuZ3RoXSk7CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisKKyAgLyoqIAorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCB0aGUgbGF0ZXN0IHRpbWVzdGFtcAorICAgKiAKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgU3RyaW5nIHJvdykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KEJ5dGVzLnRvQnl0ZXMocm93KSk7CisgIH0KKworICAvKiogCisgICAqIEdldCBhbGwgdGhlIGRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgcm93IGF0IHRoZSBsYXRlc3QgdGltZXN0YW1wCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBieXRlIFtdIHJvdykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHJvdywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorIAorICAvKiogCisgICAqIEdldCBtb3JlIHRoYW4gb25lIHZlcnNpb24gb2YgYWxsIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93CisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXR1cm4KKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFJvdyhCeXRlcy50b0J5dGVzKHJvdyksIG51bGwsIAorICAgICAgICAgICAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudW1WZXJzaW9ucywgbnVsbCk7CisgIH0KKworICAvKiogCisgICAqIEdldCBtb3JlIHRoYW4gb25lIHZlcnNpb24gb2YgYWxsIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93CisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXR1cm4KKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBieXRlW10gcm93LCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFJvdyhyb3csIG51bGwsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgbnVtVmVyc2lvbnMsIG51bGwpOworICB9CisKKyAgLyoqIAorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAKKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gdHMgdGltZXN0YW1wCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgU3RyaW5nIHJvdywgZmluYWwgbG9uZyB0cykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFJvdyhCeXRlcy50b0J5dGVzKHJvdyksIHRzKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGFsbCB0aGUgZGF0YSBmb3IgdGhlIHNwZWNpZmllZCByb3cgYXQgYSBzcGVjaWZpZWQgdGltZXN0YW1wCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIHRzIHRpbWVzdGFtcAorICAgKiBAcmV0dXJuIFJvd1Jlc3VsdCBpcyA8Y29kZT5udWxsPC9jb2RlPiBpZiByb3cgZG9lcyBub3QgZXhpc3QuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBsb25nIHRzKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHJvdyxudWxsLHRzKTsKKyAgfQorICAKKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgU3RyaW5nIHJvdywgZmluYWwgbG9uZyB0cywKKyAgICAgIGZpbmFsIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KEJ5dGVzLnRvQnl0ZXMocm93KSwgbnVsbCwgdHMsIG51bVZlcnNpb25zLCBudWxsKTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBHZXQgbW9yZSB0aGFuIG9uZSB2ZXJzaW9uIG9mIGFsbCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHJvdworICAgKiBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAKKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgbnVtYmVyIG9mIHZlcnNpb25zIHRvIHJldHVybgorICAgKiBAcmV0dXJuIFJvd1Jlc3VsdCBpcyA8Y29kZT5udWxsPC9jb2RlPiBpZiByb3cgZG9lcyBub3QgZXhpc3QuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGxvbmcgdGltZXN0YW1wLAorICAgICAgZmluYWwgaW50IG51bVZlcnNpb25zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSb3cocm93LCBudWxsLCB0aW1lc3RhbXAsIG51bVZlcnNpb25zLCBudWxsKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IHNlbGVjdGVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93IGF0IHRoZSBsYXRlc3QgdGltZXN0YW1wCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1uIG5hbWVzIGFuZCBmYW1pbGllcyB5b3Ugd2FudCB0byByZXRyaWV2ZS4KKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgW10gY29sdW1ucykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFJvdyhCeXRlcy50b0J5dGVzKHJvdyksIEJ5dGVzLnRvQnl0ZUFycmF5cyhjb2x1bW5zKSk7CisgIH0KKworICAvKiogCisgICAqIEdldCBzZWxlY3RlZCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCB0aGUgbGF0ZXN0IHRpbWVzdGFtcAorICAgKiAKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW5zIEFycmF5IG9mIGNvbHVtbiBuYW1lcyBhbmQgZmFtaWxpZXMgeW91IHdhbnQgdG8gcmV0cmlldmUuCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHJvdywgY29sdW1ucywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBHZXQgbW9yZSB0aGFuIG9uZSB2ZXJzaW9uIG9mIHNlbGVjdGVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93CisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1uIG5hbWVzIGFuZCBmYW1pbGllcyB5b3Ugd2FudCB0byByZXRyaWV2ZS4KKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXR1cm4KKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmdbXSBjb2x1bW5zLAorICAgICAgZmluYWwgaW50IG51bVZlcnNpb25zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSb3coQnl0ZXMudG9CeXRlcyhyb3cpLCBCeXRlcy50b0J5dGVBcnJheXMoY29sdW1ucyksCisgICAgICAgICAgICAgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bVZlcnNpb25zLCBudWxsKTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBHZXQgbW9yZSB0aGFuIG9uZSB2ZXJzaW9uIG9mIHNlbGVjdGVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93CisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1uIG5hbWVzIGFuZCBmYW1pbGllcyB5b3Ugd2FudCB0byByZXRyaWV2ZS4KKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXR1cm4KKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW11bXSBjb2x1bW5zLAorICAgICAgZmluYWwgaW50IG51bVZlcnNpb25zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSb3cocm93LCBjb2x1bW5zLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bVZlcnNpb25zLCBudWxsKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IHNlbGVjdGVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgcm93IGF0IGEgc3BlY2lmaWVkIHRpbWVzdGFtcAorICAgKiAKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW5zIEFycmF5IG9mIGNvbHVtbiBuYW1lcyBhbmQgZmFtaWxpZXMgeW91IHdhbnQgdG8gcmV0cmlldmUuCisgICAqIEBwYXJhbSB0cyB0aW1lc3RhbXAKKyAgICogQHJldHVybiBSb3dSZXN1bHQgaXMgPGNvZGU+bnVsbDwvY29kZT4gaWYgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgW10gY29sdW1ucywgCisgICAgZmluYWwgbG9uZyB0cykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7ICAKKyAgICByZXR1cm4gZ2V0Um93KEJ5dGVzLnRvQnl0ZXMocm93KSwgQnl0ZXMudG9CeXRlQXJyYXlzKGNvbHVtbnMpLCB0cyk7CisgIH0KKworICAvKiogCisgICAqIEdldCBzZWxlY3RlZCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAKKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1ucyBBcnJheSBvZiBjb2x1bW4gbmFtZXMgYW5kIGZhbWlsaWVzIHlvdSB3YW50IHRvIHJldHJpZXZlLgorICAgKiBAcGFyYW0gdHMgdGltZXN0YW1wCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIDxjb2RlPm51bGw8L2NvZGU+IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zLCAKKyAgICBmaW5hbCBsb25nIHRzKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsgICAgICAgCisgICAgcmV0dXJuIGdldFJvdyhyb3csY29sdW1ucyx0cywxLG51bGwpOworICB9CisgIAorICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmdbXSBjb2x1bW5zLAorICAgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIGludCBudW1WZXJzaW9ucywgZmluYWwgUm93TG9jayByb3dMb2NrKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSb3coQnl0ZXMudG9CeXRlcyhyb3cpLCBCeXRlcy50b0J5dGVBcnJheXMoY29sdW1ucyksIHRpbWVzdGFtcCwKKyAgICAgICAgICAgICAgICAgIG51bVZlcnNpb25zLCByb3dMb2NrKTsKKyAgfQorICAKKworICAvKiogCisgICAqIEdldCBzZWxlY3RlZCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAKKyAgICogdXNpbmcgZXhpc3Rpbmcgcm93IGxvY2suCisgICAqIAorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1uIG5hbWVzIGFuZCBmYW1pbGllcyB5b3Ugd2FudCB0byByZXRyaWV2ZS4KKyAgICogQHBhcmFtIHRzIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgCisgICAqIEBwYXJhbSBybCByb3cgbG9jaworICAgKiBAcmV0dXJuIFJvd1Jlc3VsdCBpcyA8Y29kZT5udWxsPC9jb2RlPiBpZiByb3cgZG9lcyBub3QgZXhpc3QuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdW10gY29sdW1ucywgCisgICAgZmluYWwgbG9uZyB0cywgZmluYWwgaW50IG51bVZlcnNpb25zLCBmaW5hbCBSb3dMb2NrIHJsKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsgICAgICAgCisgICAgcmV0dXJuIGNvbm5lY3Rpb24uZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxSb3dSZXN1bHQ+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIFJvd1Jlc3VsdCBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIGxvbmcgbG9ja0lkID0gLTFMOworICAgICAgICAgICAgaWYocmwgIT0gbnVsbCkgeworICAgICAgICAgICAgICBsb2NrSWQgPSBybC5nZXRMb2NrSWQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBzZXJ2ZXIuZ2V0Um93KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgCisgICAgICAgICAgICAgICAgY29sdW1ucywgdHMsIG51bVZlcnNpb25zLCBsb2NrSWQpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICk7CisgIH0KKworICBwdWJsaWMgUm93UmVzdWx0IGdldENsb3Nlc3RSb3dCZWZvcmUoZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgYnl0ZVtdIGNvbHVtbkZhbWlseSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxSb3dSZXN1bHQ+KGNvbm5lY3Rpb24sdGFibGVOYW1lLHJvdykgeworICAgICAgICBwdWJsaWMgUm93UmVzdWx0IGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgIHJldHVybiBzZXJ2ZXIuZ2V0Q2xvc2VzdFJvd0JlZm9yZSgKKyAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgcm93LCBjb2x1bW5GYW1pbHkKKyAgICAgICAgICAgICk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICApOworICAgIH0KKworICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgZmlyc3Qgcm93LgorICAgKiBSZXR1cm4gdGhlIHNwZWNpZmllZCBjb2x1bW5zLgorICAgKgorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gIEl0cyBhbHNvIHBvc3NpYmxlCisgICAqIHRvIHBhc3MgYSByZWdleCBpbiB0aGUgY29sdW1uIHF1YWxpZmllci4gQSBjb2x1bW4gcXVhbGlmaWVyIGlzIGp1ZGdlZCB0bworICAgKiBiZSBhIHJlZ2V4IGlmIGl0IGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6CisgICAqIDxjb2RlPlwrfF4mKiRbXV19eykoPC9jb2RlPi4KKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoZmluYWwgU3RyaW5nIFtdIGNvbHVtbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFNjYW5uZXIoQnl0ZXMudG9CeXRlQXJyYXlzKGNvbHVtbnMpLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgIH0KKworICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoZmluYWwgU3RyaW5nIFtdIGNvbHVtbnMsIGZpbmFsIFN0cmluZyBzdGFydFJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0U2Nhbm5lcihCeXRlcy50b0J5dGVBcnJheXMoY29sdW1ucyksIEJ5dGVzLnRvQnl0ZXMoc3RhcnRSb3cpKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCBmaXJzdCByb3cuCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBieXRlW11bXSBjb2x1bW5zKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdy4KKyAgICogUmV0dXJuIHRoZSBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuIEEgY29sdW1uIHF1YWxpZmllciBpcyBqdWRnZWQgdG8KKyAgICogYmUgYSByZWdleCBpZiBpdCBjb250YWlucyBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOgorICAgKiA8Y29kZT5cK3xeJiokW11dfXspKDwvY29kZT4uCisgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2NhbgorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBieXRlW11bXSBjb2x1bW5zLCBmaW5hbCBieXRlIFtdIHN0YXJ0Um93KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKGNvbHVtbnMsIHN0YXJ0Um93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICB9CisgIAorICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCBvbmx5IHJldHVybiByZXN1bHRzIHdob3NlIHRpbWVzdGFtcCA8PSB0aGlzIHZhbHVlCisgICAqIEByZXR1cm4gc2Nhbm5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgU2Nhbm5lciBnZXRTY2FubmVyKGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGJ5dGUgW10gc3RhcnRSb3csCisgICAgbG9uZyB0aW1lc3RhbXApCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFNjYW5uZXIoY29sdW1ucywgc3RhcnRSb3csIHRpbWVzdGFtcCwgbnVsbCk7CisgIH0KKyAgCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdy4KKyAgICogUmV0dXJuIHRoZSBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuIEEgY29sdW1uIHF1YWxpZmllciBpcyBqdWRnZWQgdG8KKyAgICogYmUgYSByZWdleCBpZiBpdCBjb250YWlucyBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOgorICAgKiA8Y29kZT5cK3xeJiokW11dfXspKDwvY29kZT4uCisgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2NhbgorICAgKiBAcGFyYW0gZmlsdGVyIGEgcm93IGZpbHRlciB1c2luZyByb3cta2V5IHJlZ2V4cCBhbmQvb3IgY29sdW1uIGRhdGEgZmlsdGVyLgorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBieXRlW11bXSBjb2x1bW5zLCBmaW5hbCBieXRlIFtdIHN0YXJ0Um93LAorICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgIHJldHVybiBnZXRTY2FubmVyKGNvbHVtbnMsIHN0YXJ0Um93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIGZpbHRlcik7CisgIH0KKyAgCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdyBhbmQKKyAgICogZW5kaW5nIGp1c3QgYmVmb3JlIDxjb2RlPnN0b3BSb3c8Y29kZT4uCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHN0b3BSb3cgUm93IHRvIHN0b3Agc2Nhbm5pbmcgb24uIE9uY2Ugd2UgaGl0IHRoaXMgcm93IHdlIHN0b3AKKyAgICogcmV0dXJuaW5nIHZhbHVlczsgaS5lLiB3ZSByZXR1cm4gdGhlIHJvdyBiZWZvcmUgdGhpcyBvbmUgYnV0IG5vdCB0aGUKKyAgICogPGNvZGU+c3RvcFJvdzwvY29kZT4gaXRzZWxmLgorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBieXRlIFtdW10gY29sdW1ucywKKyAgICBmaW5hbCBieXRlIFtdIHN0YXJ0Um93LCBmaW5hbCBieXRlIFtdIHN0b3BSb3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFNjYW5uZXIoY29sdW1ucywgc3RhcnRSb3csIHN0b3BSb3csCisgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqIAorICAgKiBHZXQgYSBzY2FubmVyIG9uIHRoZSBjdXJyZW50IHRhYmxlIHN0YXJ0aW5nIGF0IHRoZSBzcGVjaWZpZWQgcm93IGFuZAorICAgKiBlbmRpbmcganVzdCBiZWZvcmUgPGNvZGU+c3RvcFJvdzxjb2RlPi4KKyAgICogUmV0dXJuIHRoZSBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuIEEgY29sdW1uIHF1YWxpZmllciBpcyBqdWRnZWQgdG8KKyAgICogYmUgYSByZWdleCBpZiBpdCBjb250YWlucyBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOgorICAgKiA8Y29kZT5cK3xeJiokW11dfXspKDwvY29kZT4uCisgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2NhbgorICAgKiBAcGFyYW0gc3RvcFJvdyBSb3cgdG8gc3RvcCBzY2FubmluZyBvbi4gT25jZSB3ZSBoaXQgdGhpcyByb3cgd2Ugc3RvcAorICAgKiByZXR1cm5pbmcgdmFsdWVzOyBpLmUuIHdlIHJldHVybiB0aGUgcm93IGJlZm9yZSB0aGlzIG9uZSBidXQgbm90IHRoZQorICAgKiA8Y29kZT5zdG9wUm93PC9jb2RlPiBpdHNlbGYuCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgb25seSByZXR1cm4gcmVzdWx0cyB3aG9zZSB0aW1lc3RhbXAgPD0gdGhpcyB2YWx1ZQorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBTdHJpbmcgW10gY29sdW1ucywKKyAgICBmaW5hbCBTdHJpbmcgc3RhcnRSb3csIGZpbmFsIFN0cmluZyBzdG9wUm93LCBmaW5hbCBsb25nIHRpbWVzdGFtcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0U2Nhbm5lcihCeXRlcy50b0J5dGVBcnJheXMoY29sdW1ucyksIEJ5dGVzLnRvQnl0ZXMoc3RhcnRSb3cpLAorICAgICAgQnl0ZXMudG9CeXRlcyhzdG9wUm93KSwgdGltZXN0YW1wKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdyBhbmQKKyAgICogZW5kaW5nIGp1c3QgYmVmb3JlIDxjb2RlPnN0b3BSb3c8Y29kZT4uCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHN0b3BSb3cgUm93IHRvIHN0b3Agc2Nhbm5pbmcgb24uIE9uY2Ugd2UgaGl0IHRoaXMgcm93IHdlIHN0b3AKKyAgICogcmV0dXJuaW5nIHZhbHVlczsgaS5lLiB3ZSByZXR1cm4gdGhlIHJvdyBiZWZvcmUgdGhpcyBvbmUgYnV0IG5vdCB0aGUKKyAgICogPGNvZGU+c3RvcFJvdzwvY29kZT4gaXRzZWxmLgorICAgKiBAcGFyYW0gdGltZXN0YW1wIG9ubHkgcmV0dXJuIHJlc3VsdHMgd2hvc2UgdGltZXN0YW1wIDw9IHRoaXMgdmFsdWUKKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMsCisgICAgZmluYWwgYnl0ZSBbXSBzdGFydFJvdywgZmluYWwgYnl0ZSBbXSBzdG9wUm93LCBmaW5hbCBsb25nIHRpbWVzdGFtcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0U2Nhbm5lcihjb2x1bW5zLCBzdGFydFJvdywgdGltZXN0YW1wLAorICAgICAgbmV3IFdoaWxlTWF0Y2hSb3dGaWx0ZXIobmV3IFN0b3BSb3dGaWx0ZXIoc3RvcFJvdykpKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdy4KKyAgICogUmV0dXJuIHRoZSBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuIEEgY29sdW1uIHF1YWxpZmllciBpcyBqdWRnZWQgdG8KKyAgICogYmUgYSByZWdleCBpZiBpdCBjb250YWlucyBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOgorICAgKiA8Y29kZT5cK3xeJiokW11dfXspKDwvY29kZT4uCisgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2NhbgorICAgKiBAcGFyYW0gdGltZXN0YW1wIG9ubHkgcmV0dXJuIHJlc3VsdHMgd2hvc2UgdGltZXN0YW1wIDw9IHRoaXMgdmFsdWUKKyAgICogQHBhcmFtIGZpbHRlciBhIHJvdyBmaWx0ZXIgdXNpbmcgcm93LWtleSByZWdleHAgYW5kL29yIGNvbHVtbiBkYXRhIGZpbHRlci4KKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoU3RyaW5nW10gY29sdW1ucywKKyAgICBTdHJpbmcgc3RhcnRSb3csIGxvbmcgdGltZXN0YW1wLCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKEJ5dGVzLnRvQnl0ZUFycmF5cyhjb2x1bW5zKSwgQnl0ZXMudG9CeXRlcyhzdGFydFJvdyksCisgICAgICB0aW1lc3RhbXAsIGZpbHRlcik7CisgIH0KKworICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuCisgICAqIFJldHVybiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvCisgICAqIGJlIGEgcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCBvbmx5IHJldHVybiByZXN1bHRzIHdob3NlIHRpbWVzdGFtcCA8PSB0aGlzIHZhbHVlCisgICAqIEBwYXJhbSBmaWx0ZXIgYSByb3cgZmlsdGVyIHVzaW5nIHJvdy1rZXkgcmVnZXhwIGFuZC9vciBjb2x1bW4gZGF0YSBmaWx0ZXIuCisgICAqIEByZXR1cm4gc2Nhbm5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgU2Nhbm5lciBnZXRTY2FubmVyKGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zLAorICAgIGZpbmFsIGJ5dGUgW10gc3RhcnRSb3csIGxvbmcgdGltZXN0YW1wLCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIENsaWVudFNjYW5uZXIgcyA9IG5ldyBDbGllbnRTY2FubmVyKGNvbHVtbnMsIHN0YXJ0Um93LAorICAgICAgICB0aW1lc3RhbXAsIGZpbHRlcik7CisgICAgcy5pbml0aWFsaXplKCk7CisgICAgcmV0dXJuIHM7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21wbGV0ZWx5IGRlbGV0ZSB0aGUgcm93J3MgY2VsbHMuCisgICAqCisgICAqIEBwYXJhbSByb3cgS2V5IG9mIHRoZSByb3cgeW91IHdhbnQgdG8gY29tcGxldGVseSBkZWxldGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBieXRlIFtdIHJvdykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGVBbGwocm93LCBudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wbGV0ZWx5IGRlbGV0ZSB0aGUgcm93J3MgY2VsbHMuCisgICAqCisgICAqIEBwYXJhbSByb3cgS2V5IG9mIHRoZSByb3cgeW91IHdhbnQgdG8gY29tcGxldGVseSBkZWxldGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBTdHJpbmcgcm93KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUFsbChyb3csIG51bGwpOworICB9CisgIAorICAvKioKKyAgICogQ29tcGxldGVseSBkZWxldGUgdGhlIHJvdydzIGNlbGxzLgorICAgKgorICAgKiBAcGFyYW0gcm93IEtleSBvZiB0aGUgcm93IHlvdSB3YW50IHRvIGNvbXBsZXRlbHkgZGVsZXRlLgorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiB0byBiZSBkZWxldGVkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlQWxsKHJvdywgY29sdW1uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIENvbXBsZXRlbHkgZGVsZXRlIHRoZSByb3cncyBjZWxscy4KKyAgICoKKyAgICogQHBhcmFtIHJvdyBLZXkgb2YgdGhlIHJvdyB5b3Ugd2FudCB0byBjb21wbGV0ZWx5IGRlbGV0ZS4KKyAgICogQHBhcmFtIHRzIERlbGV0ZSBhbGwgY2VsbHMgb2YgdGhlIHNhbWUgdGltZXN0YW1wIG9yIG9sZGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGxvbmcgdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlQWxsKHJvdywgbnVsbCwgdHMpOworICB9CisKKyAgLyoqCisgICAqIENvbXBsZXRlbHkgZGVsZXRlIHRoZSByb3cncyBjZWxscy4KKyAgICoKKyAgICogQHBhcmFtIHJvdyBLZXkgb2YgdGhlIHJvdyB5b3Ugd2FudCB0byBjb21wbGV0ZWx5IGRlbGV0ZS4KKyAgICogQHBhcmFtIHRzIERlbGV0ZSBhbGwgY2VsbHMgb2YgdGhlIHNhbWUgdGltZXN0YW1wIG9yIG9sZGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgbG9uZyB0cykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGVBbGwocm93LCBudWxsLCB0cyk7CisgIH0KKworICAvKiogCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgY29sdW1uLgorICAgKiBAcGFyYW0gcm93IFJvdyB0byB1cGRhdGUKKyAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBkZWxldGVkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGVBbGwocm93LCBjb2x1bW4sIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgIH0KKworICAvKiogCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgY29sdW1uIGFuZCB3aG9zZQorICAgKiB0aW1lc3RhbXAgaXMgZXF1YWwtdG8gb3Igb2xkZXIgdGhhbiB0aGUgcGFzc2VkIHRpbWVzdGFtcC4KKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2x1bW4gbmFtZSBvZiBjb2x1bW4gd2hvc2UgdmFsdWUgaXMgdG8gYmUgZGVsZXRlZAorICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBjZWxscyBvZiB0aGUgc2FtZSB0aW1lc3RhbXAgb3Igb2xkZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgU3RyaW5nIHJvdywgZmluYWwgU3RyaW5nIGNvbHVtbiwgZmluYWwgbG9uZyB0cykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGVBbGwoQnl0ZXMudG9CeXRlcyhyb3cpLAorICAgICAgY29sdW1uICE9IG51bGw/IEJ5dGVzLnRvQnl0ZXMoY29sdW1uKTogbnVsbCwgdHMpOworICB9CisKKyAgLyoqIAorICAgKiBEZWxldGUgYWxsIGNlbGxzIHRoYXQgbWF0Y2ggdGhlIHBhc3NlZCByb3cgYW5kIGNvbHVtbiBhbmQgd2hvc2UKKyAgICogdGltZXN0YW1wIGlzIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqIEBwYXJhbSByb3cgUm93IHRvIHVwZGF0ZQorICAgKiBAcGFyYW0gY29sdW1uIG5hbWUgb2YgY29sdW1uIHdob3NlIHZhbHVlIGlzIHRvIGJlIGRlbGV0ZWQKKyAgICogQHBhcmFtIHRzIERlbGV0ZSBhbGwgY2VsbHMgb2YgdGhlIHNhbWUgdGltZXN0YW1wIG9yIG9sZGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwgZmluYWwgbG9uZyB0cykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGVBbGwocm93LGNvbHVtbix0cyxudWxsKTsKKyAgfQorCisgIC8qKiAKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4gYW5kIHdob3NlCisgICAqIHRpbWVzdGFtcCBpcyBlcXVhbC10byBvciBvbGRlciB0aGFuIHRoZSBwYXNzZWQgdGltZXN0YW1wLCB1c2luZyBhbgorICAgKiBleGlzdGluZyByb3cgbG9jay4KKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2x1bW4gbmFtZSBvZiBjb2x1bW4gd2hvc2UgdmFsdWUgaXMgdG8gYmUgZGVsZXRlZAorICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBjZWxscyBvZiB0aGUgc2FtZSB0aW1lc3RhbXAgb3Igb2xkZXIuCisgICAqIEBwYXJhbSBybCBFeGlzdGluZyByb3cgbG9jaworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwgZmluYWwgbG9uZyB0cywKKyAgICAgIGZpbmFsIFJvd0xvY2sgcmwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFNlcnZlckNhbGxhYmxlPEJvb2xlYW4+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBsb25nIGxvY2tJZCA9IC0xTDsKKyAgICAgICAgICAgIGlmKHJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgbG9ja0lkID0gcmwuZ2V0TG9ja0lkKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY29sdW1uICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZGVsZXRlQWxsKGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgICAgICAgcm93LCBjb2x1bW4sIHRzLCBsb2NrSWQpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgdGhpcy5zZXJ2ZXIuZGVsZXRlQWxsKGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgICAgICAgICByb3csIHRzLCBsb2NrSWQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgKTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBEZWxldGUgYWxsIGNlbGxzIHRoYXQgbWF0Y2ggdGhlIHBhc3NlZCByb3cgYW5kIGNvbHVtbi4KKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2xSZWdleCBjb2x1bW4gcmVnZXggZXhwcmVzc2lvbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsQnlSZWdleChmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgY29sUmVnZXgpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlQWxsKHJvdywgY29sUmVnZXgsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgIH0KKworICAvKiogCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgY29sdW1uIGFuZCB3aG9zZQorICAgKiB0aW1lc3RhbXAgaXMgZXF1YWwtdG8gb3Igb2xkZXIgdGhhbiB0aGUgcGFzc2VkIHRpbWVzdGFtcC4KKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2xSZWdleCBDb2x1bW4gUmVnZXggZXhwcmVzc2lvbgorICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBjZWxscyBvZiB0aGUgc2FtZSB0aW1lc3RhbXAgb3Igb2xkZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGxCeVJlZ2V4KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBjb2xSZWdleCwgCisgICAgICBmaW5hbCBsb25nIHRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUFsbEJ5UmVnZXgoQnl0ZXMudG9CeXRlcyhyb3cpLCBjb2xSZWdleCwgdHMpOworICB9CisKKyAgLyoqIAorICAgKiBEZWxldGUgYWxsIGNlbGxzIHRoYXQgbWF0Y2ggdGhlIHBhc3NlZCByb3cgYW5kIGNvbHVtbiBhbmQgd2hvc2UKKyAgICogdGltZXN0YW1wIGlzIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqIEBwYXJhbSByb3cgUm93IHRvIHVwZGF0ZQorICAgKiBAcGFyYW0gY29sUmVnZXggQ29sdW1uIFJlZ2V4IGV4cHJlc3Npb24KKyAgICogQHBhcmFtIHRzIERlbGV0ZSBhbGwgY2VsbHMgb2YgdGhlIHNhbWUgdGltZXN0YW1wIG9yIG9sZGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsQnlSZWdleChmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgU3RyaW5nIGNvbFJlZ2V4LCAKKyAgICAgIGZpbmFsIGxvbmcgdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlQWxsQnlSZWdleChyb3csIGNvbFJlZ2V4LCB0cywgbnVsbCk7CisgIH0KKyAgCisgIC8qKiAKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4gYW5kIHdob3NlCisgICAqIHRpbWVzdGFtcCBpcyBlcXVhbC10byBvciBvbGRlciB0aGFuIHRoZSBwYXNzZWQgdGltZXN0YW1wLCB1c2luZyBhbgorICAgKiBleGlzdGluZyByb3cgbG9jay4KKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2xSZWdleCBDb2x1bW4gcmVnZXggZXhwcmVzc2lvbgorICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBjZWxscyBvZiB0aGUgc2FtZSB0aW1lc3RhbXAgb3Igb2xkZXIuCisgICAqIEBwYXJhbSBybCBFeGlzdGluZyByb3cgbG9jaworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsQnlSZWdleChmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgU3RyaW5nIGNvbFJlZ2V4LCAKKyAgICAgIGZpbmFsIGxvbmcgdHMsIGZpbmFsIFJvd0xvY2sgcmwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFNlcnZlckNhbGxhYmxlPEJvb2xlYW4+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBsb25nIGxvY2tJZCA9IC0xTDsKKyAgICAgICAgICAgIGlmKHJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgbG9ja0lkID0gcmwuZ2V0TG9ja0lkKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0aGlzLnNlcnZlci5kZWxldGVBbGxCeVJlZ2V4KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgICAgIHJvdywgY29sUmVnZXgsIHRzLCBsb2NrSWQpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgYXQgYWxsIHRpbWVzdGFtcHMuCisgICAqCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdyB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSBmYW1pbHkgVGhlIGNvbHVtbiBmYW1pbHkgdG8gbWF0Y2gKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBmYW1pbHkpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUZhbWlseShyb3csIGZhbWlseSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgYXQgYWxsIHRpbWVzdGFtcHMuCisgICAqCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdyB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSBmYW1pbHkgVGhlIGNvbHVtbiBmYW1pbHkgdG8gbWF0Y2gKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5KGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGJ5dGVbXSBmYW1pbHkpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUZhbWlseShyb3csIGZhbWlseSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgd2l0aCB0aW1lc3RhbXBzCisgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5IFRoZSBjb2x1bW4gZmFtaWx5IHRvIG1hdGNoCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovICAKKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5KGZpbmFsIFN0cmluZyByb3csIGZpbmFsIFN0cmluZyBmYW1pbHksCisgICAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgIGRlbGV0ZUZhbWlseShCeXRlcy50b0J5dGVzKHJvdyksIEJ5dGVzLnRvQnl0ZXMoZmFtaWx5KSwgdGltZXN0YW1wKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgd2l0aCB0aW1lc3RhbXBzCisgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5IFRoZSBjb2x1bW4gZmFtaWx5IHRvIG1hdGNoCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUZhbWlseShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBmYW1pbHksIAorICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUZhbWlseShyb3csZmFtaWx5LHRpbWVzdGFtcCxudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgd2l0aCB0aW1lc3RhbXBzCisgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LCB1c2luZyBleGlzdGluZyByb3cgbG9jay4KKyAgICoKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHRvIG9wZXJhdGUgb24KKyAgICogQHBhcmFtIGZhbWlseSBUaGUgY29sdW1uIGZhbWlseSB0byBtYXRjaAorICAgKiBAcGFyYW0gdGltZXN0YW1wIFRpbWVzdGFtcCB0byBtYXRjaAorICAgKiBAcGFyYW0gcmwgRXhpc3Rpbmcgcm93IGxvY2sKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGZhbWlseSwgCisgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIFJvd0xvY2sgcmwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFNlcnZlckNhbGxhYmxlPEJvb2xlYW4+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgcm93KSB7CisgICAgICAgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICBsb25nIGxvY2tJZCA9IC0xTDsKKyAgICAgICAgICAgIGlmKHJsICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgbG9ja0lkID0gcmwuZ2V0TG9ja0lkKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzZXJ2ZXIuZGVsZXRlRmFtaWx5KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgCisgICAgICAgICAgICAgICAgZmFtaWx5LCB0aW1lc3RhbXAsIGxvY2tJZCk7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICApOworICB9CisgIAorICAvKioKKyAgICogRGVsZXRlIGFsbCBjZWxscyBmb3IgYSByb3cgd2l0aCBtYXRjaGluZyBjb2x1bW4gZmFtaWx5IHJlZ2V4IAorICAgKiBhdCBhbGwgdGltZXN0YW1wcy4KKyAgICoKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHRvIG9wZXJhdGUgb24KKyAgICogQHBhcmFtIGZhbWlseVJlZ2V4IENvbHVtbiBmYW1pbHkgcmVnZXgKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5QnlSZWdleChmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgZmFtaWx5UmVnZXgpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUZhbWlseUJ5UmVnZXgocm93LCBmYW1pbHlSZWdleCwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgcmVnZXggCisgICAqIGF0IGFsbCB0aW1lc3RhbXBzLgorICAgKgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5UmVnZXggQ29sdW1uIGZhbWlseSByZWdleAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVGYW1pbHlCeVJlZ2V4KGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIFN0cmluZyBmYW1pbHlSZWdleCkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlRmFtaWx5QnlSZWdleChyb3csIGZhbWlseVJlZ2V4LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgZm9yIGEgcm93IHdpdGggbWF0Y2hpbmcgY29sdW1uIGZhbWlseSByZWdleAorICAgKiB3aXRoIHRpbWVzdGFtcHMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDxpPnRpbWVzdGFtcDwvaT4uCisgICAqCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdyB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSBmYW1pbHlSZWdleCBDb2x1bW4gZmFtaWx5IHJlZ2V4CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovICAKKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5QnlSZWdleChmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBTdHJpbmcgZmFtaWx5UmVnZXgsCisgICAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgIGRlbGV0ZUZhbWlseUJ5UmVnZXgoQnl0ZXMudG9CeXRlcyhyb3cpLCBmYW1pbHlSZWdleCwgdGltZXN0YW1wKTsKKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgcmVnZXgKKyAgICogd2l0aCB0aW1lc3RhbXBzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5UmVnZXggQ29sdW1uIGZhbWlseSByZWdleAorICAgKiBAcGFyYW0gdGltZXN0YW1wIFRpbWVzdGFtcCB0byBtYXRjaAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVGYW1pbHlCeVJlZ2V4KGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBTdHJpbmcgZmFtaWx5UmVnZXgsIAorICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGV0ZUZhbWlseUJ5UmVnZXgocm93LGZhbWlseVJlZ2V4LHRpbWVzdGFtcCxudWxsKTsKKyAgfQorICAKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgZm9yIGEgcm93IHdpdGggbWF0Y2hpbmcgY29sdW1uIGZhbWlseSByZWdleCB3aXRoCisgICAqIHRpbWVzdGFtcHMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDxpPnRpbWVzdGFtcDwvaT4sIHVzaW5nIGV4aXN0aW5nCisgICAqIHJvdyBsb2NrLgorICAgKiAKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHRvIG9wZXJhdGUgb24KKyAgICogQHBhcmFtIGZhbWlseVJlZ2V4IENvbHVtbiBGYW1pbHkgUmVnZXgKKyAgICogQHBhcmFtIHRpbWVzdGFtcCBUaW1lc3RhbXAgdG8gbWF0Y2gKKyAgICogQHBhcmFtIHIxIEV4aXN0aW5nIHJvdyBsb2NrCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUZhbWlseUJ5UmVnZXgoZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgU3RyaW5nIGZhbWlseVJlZ2V4LAorICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBSb3dMb2NrIHIxKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNvbm5lY3Rpb24uZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxCb29sZWFuPihjb25uZWN0aW9uLCB0YWJsZU5hbWUsIHJvdykgeworICAgICAgICAgIHB1YmxpYyBCb29sZWFuIGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgbG9uZyBsb2NrSWQgPSAtMUw7CisgICAgICAgICAgICBpZihyMSAhPSBudWxsKSB7CisgICAgICAgICAgICAgIGxvY2tJZCA9IHIxLmdldExvY2tJZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgc2VydmVyLmRlbGV0ZUZhbWlseUJ5UmVnZXgobG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgCisgICAgICAgICAgICAgICAgcm93LCBmYW1pbHlSZWdleCwgdGltZXN0YW1wLCBsb2NrSWQpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IGZvciB0aGUgZXhpc3RlbmNlIG9mIGEgcm93IGluIHRoZSB0YWJsZS4KKyAgICogCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdworICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHJvdyBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoZmluYWwgYnl0ZSBbXSByb3cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGV4aXN0cyhyb3csIG51bGwsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogVGVzdCBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBhIHJvdyBhbmQgY29sdW1uIGluIHRoZSB0YWJsZS4KKyAgICogCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdworICAgKiBAcGFyYW0gY29sdW1uIFRoZSBjb2x1bW4KKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSByb3cgZXhpc3RzLCBmYWxzZSBvdGhlcndpc2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlW10gY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBleGlzdHMocm93LCBjb2x1bW4sIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogVGVzdCBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBhIGNvb3JkaW5hdGUgaW4gdGhlIHRhYmxlLgorICAgKiAKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93CisgICAqIEBwYXJhbSBjb2x1bW4gVGhlIGNvbHVtbgorICAgKiBAcGFyYW0gdGltZXN0YW1wIFRoZSB0aW1lc3RhbXAKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgY29vcmRpbmF0ZSBleGlzdHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBleGlzdHMocm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogVGVzdCBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBhIGNvb3JkaW5hdGUgaW4gdGhlIHRhYmxlLgorICAgKiAKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93CisgICAqIEBwYXJhbSBjb2x1bW4gVGhlIGNvbHVtbgorICAgKiBAcGFyYW0gdGltZXN0YW1wIFRoZSB0aW1lc3RhbXAKKyAgICogQHBhcmFtIHJsIEV4aXN0aW5nIHJvdyBsb2NrCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNvb3JkaW5hdGUgZXhpc3RzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGV4aXN0cyhmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sCisgICAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgUm93TG9jayBybCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxCb29sZWFuPihjb25uZWN0aW9uLCB0YWJsZU5hbWUsIHJvdykgeworICAgICAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICBsb25nIGxvY2tJZCA9IC0xTDsKKyAgICAgICAgICBpZiAocmwgIT0gbnVsbCkgeworICAgICAgICAgICAgbG9ja0lkID0gcmwuZ2V0TG9ja0lkKCk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBCb29sZWFuLnZhbHVlT2Yoc2VydmVyLgorICAgICAgICAgICAgZXhpc3RzKGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywKKyAgICAgICAgICAgIGNvbHVtbiwgdGltZXN0YW1wLCBsb2NrSWQpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICkuYm9vbGVhblZhbHVlKCk7CisgIH0KKworICAvKioKKyAgICogQ29tbWl0IGEgQmF0Y2hVcGRhdGUgdG8gdGhlIHRhYmxlLgorICAgKiBJZiBhdXRvRmx1c2ggaXMgZmFsc2UsIHRoZSB1cGRhdGUgaXMgYnVmZmVyZWQKKyAgICogQHBhcmFtIGJhdGNoVXBkYXRlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovIAorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29tbWl0KGZpbmFsIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjb21taXQoYmF0Y2hVcGRhdGUsbnVsbCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21taXQgYSBCYXRjaFVwZGF0ZSB0byB0aGUgdGFibGUgdXNpbmcgZXhpc3Rpbmcgcm93IGxvY2suCisgICAqIElmIGF1dG9GbHVzaCBpcyBmYWxzZSwgdGhlIHVwZGF0ZSBpcyBidWZmZXJlZAorICAgKiBAcGFyYW0gYmF0Y2hVcGRhdGUKKyAgICogQHBhcmFtIHJsIEV4aXN0aW5nIHJvdyBsb2NrCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovIAorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29tbWl0KGZpbmFsIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlLAorICAgICAgZmluYWwgUm93TG9jayBybCkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tSb3dBbmRDb2x1bW5zKGJhdGNoVXBkYXRlKTsKKyAgICBpZihybCAhPSBudWxsKSB7CisgICAgICBiYXRjaFVwZGF0ZS5zZXRSb3dMb2NrKHJsLmdldExvY2tJZCgpKTsKKyAgICB9CisgICAgd3JpdGVCdWZmZXIuYWRkKGJhdGNoVXBkYXRlKTsKKyAgICBjdXJyZW50V3JpdGVCdWZmZXJTaXplICs9IGJhdGNoVXBkYXRlLmhlYXBTaXplKCk7CisgICAgaWYgKGF1dG9GbHVzaCB8fCBjdXJyZW50V3JpdGVCdWZmZXJTaXplID4gd3JpdGVCdWZmZXJTaXplKSB7CisgICAgICBmbHVzaENvbW1pdHMoKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21taXQgYSBMaXN0IG9mIEJhdGNoVXBkYXRlIHRvIHRoZSB0YWJsZS4KKyAgICogSWYgYXV0b0ZsdXNoIGlzIGZhbHNlLCB0aGUgdXBkYXRlcyBhcmUgYnVmZmVyZWQKKyAgICogQHBhcmFtIGJhdGNoVXBkYXRlcworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLyAKKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNvbW1pdChmaW5hbCBMaXN0PEJhdGNoVXBkYXRlPiBiYXRjaFVwZGF0ZXMpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoQmF0Y2hVcGRhdGUgYnUgOiBiYXRjaFVwZGF0ZXMpIHsKKyAgICAgIGNoZWNrUm93QW5kQ29sdW1ucyhidSk7CisgICAgICB3cml0ZUJ1ZmZlci5hZGQoYnUpOworICAgICAgY3VycmVudFdyaXRlQnVmZmVyU2l6ZSArPSBidS5oZWFwU2l6ZSgpOworICAgIH0KKyAgICBpZiAoYXV0b0ZsdXNoIHx8IGN1cnJlbnRXcml0ZUJ1ZmZlclNpemUgPiB3cml0ZUJ1ZmZlclNpemUpIHsKKyAgICAgIGZsdXNoQ29tbWl0cygpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEF0b21pY2FsbHkgY2hlY2tzIGlmIGEgcm93J3MgdmFsdWVzIG1hdGNoCisgICAqIHRoZSBleHBlY3RlZFZhbHVlcy4gSWYgaXQgZG9lcywgaXQgdXNlcyB0aGUKKyAgICogYmF0Y2hVcGRhdGUgdG8gdXBkYXRlIHRoZSByb3cuCisgICAqIEBwYXJhbSBiYXRjaFVwZGF0ZSBiYXRjaHVwZGF0ZSB0byBhcHBseSBpZiBjaGVjayBpcyBzdWNjZXNzZnVsCisgICAqIEBwYXJhbSBleHBlY3RlZFZhbHVlcyB2YWx1ZXMgdG8gY2hlY2sKKyAgICogQHBhcmFtIHJsIHJvd2xvY2sKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGNoZWNrQW5kU2F2ZShmaW5hbCBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSwKKyAgICBmaW5hbCBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSxieXRlW10+IGV4cGVjdGVkVmFsdWVzLCBmaW5hbCBSb3dMb2NrIHJsKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrUm93QW5kQ29sdW1ucyhiYXRjaFVwZGF0ZSk7CisgICAgaWYocmwgIT0gbnVsbCkgeworICAgICAgYmF0Y2hVcGRhdGUuc2V0Um93TG9jayhybC5nZXRMb2NrSWQoKSk7CisgICAgfQorICAgIHJldHVybiBjb25uZWN0aW9uLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKAorICAgICAgbmV3IFNlcnZlckNhbGxhYmxlPEJvb2xlYW4+KGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgYmF0Y2hVcGRhdGUuZ2V0Um93KCkpIHsKKyAgICAgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgcmV0dXJuIHNlcnZlci5jaGVja0FuZFNhdmUobG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwKKyAgICAgICAgICAgIGJhdGNoVXBkYXRlLCBleHBlY3RlZFZhbHVlcyk/CisgICAgICAgICAgICAgIEJvb2xlYW4uVFJVRTogQm9vbGVhbi5GQUxTRTsKKyAgICAgICAgfQorICAgICAgfQorICAgICkuYm9vbGVhblZhbHVlKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21taXQgdG8gdGhlIHRhYmxlIHRoZSBidWZmZXIgb2YgQmF0Y2hVcGRhdGUuCisgICAqIENhbGxlZCBhdXRvbWF0aWNhbHkgaW4gdGhlIGNvbW1pdCBtZXRob2RzIHdoZW4gYXV0b0ZsdXNoIGlzIHRydWUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGZsdXNoQ29tbWl0cygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGNvbm5lY3Rpb24ucHJvY2Vzc0JhdGNoT2ZSb3dzKHdyaXRlQnVmZmVyLCB0YWJsZU5hbWUpOworICAgIH0gZmluYWxseSB7CisgICAgICBjdXJyZW50V3JpdGVCdWZmZXJTaXplID0gMDsKKyAgICAgIHdyaXRlQnVmZmVyLmNsZWFyKCk7CisgICAgfQorICB9CisgICAKKyAgLyoqCisgICAqIFJlbGVhc2UgaGVsZCByZXNvdXJjZXMKKyAgICogCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgZmx1c2hDb21taXRzKCk7CisgIH0KKworICAvKioKKyAgICogVXRpbGl0eSBtZXRob2QgdGhhdCBjaGVja3Mgcm93cyBleGlzdGVuY2UsIGxlbmd0aCBhbmQgY29sdW1ucyB3ZWxsCisgICAqIGZvcm1lZG5lc3MuCisgICAqIAorICAgKiBAcGFyYW0gYnUKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNoZWNrUm93QW5kQ29sdW1ucyhCYXRjaFVwZGF0ZSBidSkKKyAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoYnUuZ2V0Um93KCkgPT0gbnVsbCB8fCBidS5nZXRSb3coKS5sZW5ndGggPiBIQ29uc3RhbnRzLk1BWF9ST1dfTEVOR1RIKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSb3cga2V5IGlzIGludmFsaWQiKTsKKyAgICB9CisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBibyA6IGJ1KSB7CisgICAgICBIU3RvcmVLZXkuZ2V0RmFtaWx5KGJvLmdldENvbHVtbigpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogT2J0YWluIGEgcm93IGxvY2sKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHRvIGxvY2sKKyAgICogQHJldHVybiByb3dMb2NrIFJvd0xvY2sgY29udGFpbmluZyByb3cgYW5kIGxvY2sgaWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd0xvY2sgbG9ja1JvdyhmaW5hbCBieXRlIFtdIHJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxSb3dMb2NrPihjb25uZWN0aW9uLCB0YWJsZU5hbWUsIHJvdykgeworICAgICAgICBwdWJsaWMgUm93TG9jayBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICBsb25nIGxvY2tJZCA9CisgICAgICAgICAgICAgIHNlcnZlci5sb2NrUm93KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdyk7CisgICAgICAgICAgUm93TG9jayByb3dMb2NrID0gbmV3IFJvd0xvY2socm93LGxvY2tJZCk7CisgICAgICAgICAgcmV0dXJuIHJvd0xvY2s7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICApOworICB9CisKKyAgLyoqCisgICAqIFJlbGVhc2UgYSByb3cgbG9jaworICAgKiBAcGFyYW0gcmwgVGhlIHJvdyBsb2NrIHRvIHJlbGVhc2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdW5sb2NrUm93KGZpbmFsIFJvd0xvY2sgcmwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgIG5ldyBTZXJ2ZXJDYWxsYWJsZTxCb29sZWFuPihjb25uZWN0aW9uLCB0YWJsZU5hbWUsIHJsLmdldFJvdygpKSB7CisgICAgICAgIHB1YmxpYyBCb29sZWFuIGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgIHNlcnZlci51bmxvY2tSb3cobG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwKKyAgICAgICAgICAgICAgcmwuZ2V0TG9ja0lkKCkpOworICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICB9CisgICAgKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgdmFsdWUgb2YgYXV0b0ZsdXNoLiBJZiB0cnVlLCB1cGRhdGVzIHdpbGwgbm90IGJlIGJ1ZmZlcmVkCisgICAqIEByZXR1cm4gdmFsdWUgb2YgYXV0b0ZsdXNoCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0F1dG9GbHVzaCgpIHsKKyAgICByZXR1cm4gYXV0b0ZsdXNoOworICB9CisKKyAgLyoqCisgICAqIFNldCBpZiB0aGlzIGluc3RhbmNpYXRpb24gb2YgSFRhYmxlIHdpbGwgYXV0b0ZsdXNoCisgICAqIEBwYXJhbSBhdXRvRmx1c2gKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEF1dG9GbHVzaChib29sZWFuIGF1dG9GbHVzaCkgeworICAgIHRoaXMuYXV0b0ZsdXNoID0gYXV0b0ZsdXNoOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgbWF4aW11bSBzaXplIGluIGJ5dGVzIG9mIHRoZSB3cml0ZSBidWZmZXIgZm9yIHRoaXMgSFRhYmxlCisgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdGhlIHdyaXRlIGJ1ZmZlciBpbiBieXRlcworICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0V3JpdGVCdWZmZXJTaXplKCkgeworICAgIHJldHVybiB3cml0ZUJ1ZmZlclNpemU7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBzaXplIG9mIHRoZSBidWZmZXIgaW4gYnl0ZXMKKyAgICogQHBhcmFtIHdyaXRlQnVmZmVyU2l6ZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0V3JpdGVCdWZmZXJTaXplKGxvbmcgd3JpdGVCdWZmZXJTaXplKSB7CisgICAgdGhpcy53cml0ZUJ1ZmZlclNpemUgPSB3cml0ZUJ1ZmZlclNpemU7CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSB3cml0ZSBidWZmZXIgCisgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgd3JpdGUgYnVmZmVyCisgICAqLworICBwdWJsaWMgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPiBnZXRXcml0ZUJ1ZmZlcigpIHsKKyAgICByZXR1cm4gd3JpdGVCdWZmZXI7CisgIH0KKyAgCisgIHB1YmxpYyBsb25nIGluY3JlbWVudENvbHVtblZhbHVlKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGZpbmFsIGxvbmcgYW1vdW50KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjb25uZWN0aW9uLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKAorICAgICAgICBuZXcgU2VydmVyQ2FsbGFibGU8TG9uZz4oY29ubmVjdGlvbiwgdGFibGVOYW1lLCByb3cpIHsKKyAgICAgICAgICBwdWJsaWMgTG9uZyBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBzZXJ2ZXIuaW5jcmVtZW50Q29sdW1uVmFsdWUoCisgICAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgcm93LCBjb2x1bW4sIGFtb3VudCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgKTsKKyAgfQorCisgIC8qKgorICAgKiBJbXBsZW1lbnRzIHRoZSBzY2FubmVyIGludGVyZmFjZSBmb3IgdGhlIEhCYXNlIGNsaWVudC4KKyAgICogSWYgdGhlcmUgYXJlIG11bHRpcGxlIHJlZ2lvbnMgaW4gYSB0YWJsZSwgdGhpcyBzY2FubmVyIHdpbGwgaXRlcmF0ZQorICAgKiB0aHJvdWdoIHRoZW0gYWxsLgorICAgKi8KKyAgcHJvdGVjdGVkIGNsYXNzIENsaWVudFNjYW5uZXIgaW1wbGVtZW50cyBTY2FubmVyIHsKKyAgICBwcml2YXRlIGZpbmFsIExvZyBDTElFTlRfTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpKTsKKyAgICBwcml2YXRlIGJ5dGVbXVtdIGNvbHVtbnM7CisgICAgcHJpdmF0ZSBieXRlIFtdIHN0YXJ0Um93OworICAgIHByb3RlY3RlZCBsb25nIHNjYW5UaW1lOworICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKyAgICBwcml2YXRlIEhSZWdpb25JbmZvIGN1cnJlbnRSZWdpb24gPSBudWxsOworICAgIHByaXZhdGUgU2Nhbm5lckNhbGxhYmxlIGNhbGxhYmxlID0gbnVsbDsKKyAgICBwcm90ZWN0ZWQgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcjsKKyAgICBwcml2YXRlIGZpbmFsIExpbmtlZExpc3Q8Um93UmVzdWx0PiBjYWNoZSA9IG5ldyBMaW5rZWRMaXN0PFJvd1Jlc3VsdD4oKTsKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygiaGlkaW5nIikKKyAgICBwcml2YXRlIGZpbmFsIGludCBzY2FubmVyQ2FjaGluZyA9IEhUYWJsZS50aGlzLnNjYW5uZXJDYWNoaW5nOworICAgIHByaXZhdGUgbG9uZyBsYXN0TmV4dDsKKworICAgIHByb3RlY3RlZCBDbGllbnRTY2FubmVyKGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGJ5dGUgW10gc3RhcnRSb3csCisgICAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB7CisgICAgICBpZiAoQ0xJRU5UX0xPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIENMSUVOVF9MT0cuZGVidWcoIkNyZWF0aW5nIHNjYW5uZXIgb3ZlciAiIAorICAgICAgICAgICAgKyBCeXRlcy50b1N0cmluZyhnZXRUYWJsZU5hbWUoKSkgCisgICAgICAgICAgICArICIgc3RhcnRpbmcgYXQga2V5ICciICsgQnl0ZXMudG9TdHJpbmcoc3RhcnRSb3cpICsgIiciKTsKKyAgICAgIH0KKyAgICAgIC8vIHNhdmUgb2ZmIHRoZSBzaW1wbGUgcGFyYW1ldGVycworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICAgIHRoaXMuc2NhblRpbWUgPSB0aW1lc3RhbXA7CisgICAgICAKKyAgICAgIC8vIHNhdmUgdGhlIGZpbHRlciwgYW5kIG1ha2Ugc3VyZSB0aGF0IHRoZSBmaWx0ZXIgYXBwbGllcyB0byB0aGUgZGF0YQorICAgICAgLy8gd2UncmUgZXhwZWN0aW5nIHRvIHB1bGwgYmFjaworICAgICAgdGhpcy5maWx0ZXIgPSBmaWx0ZXI7CisgICAgICBpZiAoZmlsdGVyICE9IG51bGwpIHsKKyAgICAgICAgZmlsdGVyLnZhbGlkYXRlKGNvbHVtbnMpOworICAgICAgfQorICAgICAgdGhpcy5sYXN0TmV4dCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIH0KKworICAgIC8vVE9ETzogY2hhbmdlIHZpc2liaWxpdHkgdG8gcHJvdGVjdGVkCisgICAgCisgICAgcHVibGljIHZvaWQgaW5pdGlhbGl6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBuZXh0U2Nhbm5lcih0aGlzLnNjYW5uZXJDYWNoaW5nKTsKKyAgICB9CisgICAgCisgICAgcHJvdGVjdGVkIGJ5dGVbXVtdIGdldENvbHVtbnMoKSB7CisgICAgICByZXR1cm4gY29sdW1uczsKKyAgICB9CisgICAgCisgICAgcHJvdGVjdGVkIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHNjYW5UaW1lOworICAgIH0KKyAgICAKKyAgICBwcm90ZWN0ZWQgUm93RmlsdGVySW50ZXJmYWNlIGdldEZpbHRlcigpIHsKKyAgICAgIHJldHVybiBmaWx0ZXI7CisgICAgfQorICAgICAgICAKKyAgICAvKgorICAgICAqIEdldHMgYSBzY2FubmVyIGZvciB0aGUgbmV4dCByZWdpb24uCisgICAgICogUmV0dXJucyBmYWxzZSBpZiB0aGVyZSBhcmUgbm8gbW9yZSBzY2FubmVycy4KKyAgICAgKi8KKyAgICBwcml2YXRlIGJvb2xlYW4gbmV4dFNjYW5uZXIoaW50IG5iUm93cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIENsb3NlIHRoZSBwcmV2aW91cyBzY2FubmVyIGlmIGl0J3Mgb3BlbgorICAgICAgaWYgKHRoaXMuY2FsbGFibGUgIT0gbnVsbCkgeworICAgICAgICB0aGlzLmNhbGxhYmxlLnNldENsb3NlKCk7CisgICAgICAgIGdldENvbm5lY3Rpb24oKS5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcyhjYWxsYWJsZSk7CisgICAgICAgIHRoaXMuY2FsbGFibGUgPSBudWxsOworICAgICAgfQorCisgICAgICAvLyBpZiB3ZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSB0YWJsZSwgdGhlbiBjbG9zZSBhbmQgcmV0dXJuIGZhbHNlCisgICAgICAvLyB0byBzdG9wIGl0ZXJhdGluZworICAgICAgaWYgKGN1cnJlbnRSZWdpb24gIT0gbnVsbCkgeworICAgICAgICBpZiAoQ0xJRU5UX0xPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgQ0xJRU5UX0xPRy5kZWJ1ZygiQWR2YW5jaW5nIGZvcndhcmQgZnJvbSByZWdpb24gIiArIGN1cnJlbnRSZWdpb24pOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZSBbXSBlbmRLZXkgPSBjdXJyZW50UmVnaW9uLmdldEVuZEtleSgpOworICAgICAgICBpZiAoZW5kS2V5ID09IG51bGwgfHwKKyAgICAgICAgICAgIEJ5dGVzLmVxdWFscyhlbmRLZXksIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSkgfHwKKyAgICAgICAgICAgIGZpbHRlclNheXNTdG9wKGVuZEtleSkpIHsKKyAgICAgICAgICBjbG9zZSgpOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfSAKKyAgICAgIAorICAgICAgSFJlZ2lvbkluZm8gb2xkUmVnaW9uID0gdGhpcy5jdXJyZW50UmVnaW9uOworICAgICAgYnl0ZSBbXSBsb2NhbFN0YXJ0S2V5ID0gb2xkUmVnaW9uID09IG51bGw/IHN0YXJ0Um93OiBvbGRSZWdpb24uZ2V0RW5kS2V5KCk7CisKKyAgICAgIGlmIChDTElFTlRfTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgQ0xJRU5UX0xPRy5kZWJ1ZygiQWR2YW5jaW5nIGludGVybmFsIHNjYW5uZXIgdG8gc3RhcnRLZXkgYXQgJyIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGxvY2FsU3RhcnRLZXkpICsgIiciKTsKKyAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgICAgY2FsbGFibGUgPSBnZXRTY2FubmVyQ2FsbGFibGUobG9jYWxTdGFydEtleSwgbmJSb3dzKTsKKyAgICAgICAgLy8gb3BlbiBhIHNjYW5uZXIgb24gdGhlIHJlZ2lvbiBzZXJ2ZXIgc3RhcnRpbmcgYXQgdGhlIAorICAgICAgICAvLyBiZWdpbm5pbmcgb2YgdGhlIHJlZ2lvbgorICAgICAgICBnZXRDb25uZWN0aW9uKCkuZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoY2FsbGFibGUpOworICAgICAgICBjdXJyZW50UmVnaW9uID0gY2FsbGFibGUuZ2V0SFJlZ2lvbkluZm8oKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgY2xvc2UoKTsKKyAgICAgICAgdGhyb3cgZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICAKKyAgICBwcm90ZWN0ZWQgU2Nhbm5lckNhbGxhYmxlIGdldFNjYW5uZXJDYWxsYWJsZShieXRlIFtdIGxvY2FsU3RhcnRLZXksCisgICAgICAgIGludCBuYlJvd3MpIHsKKyAgICAgIFNjYW5uZXJDYWxsYWJsZSBzID0gbmV3IFNjYW5uZXJDYWxsYWJsZShnZXRDb25uZWN0aW9uKCksIAorICAgICAgICAgIGdldFRhYmxlTmFtZSgpLCBjb2x1bW5zLCAKKyAgICAgICAgICBsb2NhbFN0YXJ0S2V5LCBzY2FuVGltZSwgZmlsdGVyKTsKKyAgICAgIHMuc2V0Q2FjaGluZyhuYlJvd3MpOworICAgICAgcmV0dXJuIHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHBhcmFtIGVuZEtleQorICAgICAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIHRoZSBwYXNzZWQgcmVnaW9uIGVuZGtleSBpcyBqdWRnZWQgYmV5b25kCisgICAgICogZmlsdGVyLgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBmaWx0ZXJTYXlzU3RvcChmaW5hbCBieXRlIFtdIGVuZEtleSkgeworICAgICAgaWYgKHRoaXMuZmlsdGVyID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgLy8gTGV0IHRoZSBmaWx0ZXIgc2VlIGN1cnJlbnQgcm93LgorICAgICAgdGhpcy5maWx0ZXIuZmlsdGVyUm93S2V5KGVuZEtleSwgMCwgZW5kS2V5Lmxlbmd0aCk7CisgICAgICByZXR1cm4gdGhpcy5maWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIFJvd1Jlc3VsdCBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIElmIHRoZSBzY2FubmVyIGlzIGNsb3NlZCBidXQgdGhlcmUgaXMgc29tZSByb3dzIGxlZnQgaW4gdGhlIGNhY2hlLAorICAgICAgLy8gaXQgd2lsbCBmaXJzdCBlbXB0eSBpdCBiZWZvcmUgcmV0dXJuaW5nIG51bGwKKyAgICAgIGlmIChjYWNoZS5zaXplKCkgPT0gMCAmJiB0aGlzLmNsb3NlZCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIGlmIChjYWNoZS5zaXplKCkgPT0gMCkgeworICAgICAgICBSb3dSZXN1bHRbXSB2YWx1ZXMgPSBudWxsOworICAgICAgICBpbnQgY291bnRkb3duID0gdGhpcy5zY2FubmVyQ2FjaGluZzsKKyAgICAgICAgLy8gV2UgbmVlZCB0byByZXNldCBpdCBpZiBpdCdzIGEgbmV3IGNhbGxhYmxlIHRoYXQgd2FzIGNyZWF0ZWQgCisgICAgICAgIC8vIHdpdGggYSBjb3VudGRvd24gaW4gbmV4dFNjYW5uZXIKKyAgICAgICAgY2FsbGFibGUuc2V0Q2FjaGluZyh0aGlzLnNjYW5uZXJDYWNoaW5nKTsKKyAgICAgICAgZG8geworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB2YWx1ZXMgPSBnZXRDb25uZWN0aW9uKCkuZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoY2FsbGFibGUpOworICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgVW5rbm93blNjYW5uZXJFeGNlcHRpb24gJiYKKyAgICAgICAgICAgICAgICBsYXN0TmV4dCArIHNjYW5uZXJUaW1lb3V0IDwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpIHsKKyAgICAgICAgICAgICAgU2Nhbm5lclRpbWVvdXRFeGNlcHRpb24gZXggPSBuZXcgU2Nhbm5lclRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICAgICAgICAgICAgZXguaW5pdENhdXNlKGUpOworICAgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgfQorICAgICAgICAgIGxhc3ROZXh0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgICAgaWYgKHZhbHVlcyAhPSBudWxsICYmIHZhbHVlcy5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBmb3IgKFJvd1Jlc3VsdCBycyA6IHZhbHVlcykgeworICAgICAgICAgICAgICBjYWNoZS5hZGQocnMpOworICAgICAgICAgICAgICBjb3VudGRvd24tLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0gd2hpbGUgKGNvdW50ZG93biA+IDAgJiYgbmV4dFNjYW5uZXIoY291bnRkb3duKSk7CisgICAgICB9CisKKyAgICAgIGlmIChjYWNoZS5zaXplKCkgPiAwKSB7CisgICAgICAgIHJldHVybiBjYWNoZS5wb2xsKCk7CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gbmJSb3dzIG51bWJlciBvZiByb3dzIHRvIHJldHVybgorICAgICAqIEByZXR1cm4gQmV0d2VlbiB6ZXJvIGFuZCA8cGFyYW0+bmJSb3dzPC9wYXJhbT4gUm93UmVzdWx0cworICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUm93UmVzdWx0W10gbmV4dChpbnQgbmJSb3dzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gQ29sbGVjdCB2YWx1ZXMgdG8gYmUgcmV0dXJuZWQgaGVyZQorICAgICAgQXJyYXlMaXN0PFJvd1Jlc3VsdD4gcmVzdWx0U2V0cyA9IG5ldyBBcnJheUxpc3Q8Um93UmVzdWx0PihuYlJvd3MpOworICAgICAgZm9yKGludCBpID0gMDsgaSA8IG5iUm93czsgaSsrKSB7CisgICAgICAgIFJvd1Jlc3VsdCBuZXh0ID0gbmV4dCgpOworICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CisgICAgICAgICAgcmVzdWx0U2V0cy5hZGQobmV4dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHRTZXRzLnRvQXJyYXkobmV3IFJvd1Jlc3VsdFtyZXN1bHRTZXRzLnNpemUoKV0pOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgIGlmIChjYWxsYWJsZSAhPSBudWxsKSB7CisgICAgICAgIGNhbGxhYmxlLnNldENsb3NlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgZ2V0Q29ubmVjdGlvbigpLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKGNhbGxhYmxlKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIFdlIHVzZWQgdG8gY2F0Y2ggdGhpcyBlcnJvciwgaW50ZXJwcmV0LCBhbmQgcmV0aHJvdy4gSG93ZXZlciwgd2UKKyAgICAgICAgICAvLyBoYXZlIHNpbmNlIGRlY2lkZWQgdGhhdCBpdCdzIG5vdCBuaWNlIGZvciBhIHNjYW5uZXIncyBjbG9zZSB0bworICAgICAgICAgIC8vIHRocm93IGV4Y2VwdGlvbnMuIENoYW5jZXMgYXJlIGl0IHdhcyBqdXN0IGFuIFVua25vd25TY2FubmVyCisgICAgICAgICAgLy8gZXhjZXB0aW9uIGR1ZSB0byBsZWFzZSB0aW1lIG91dC4KKyAgICAgICAgfQorICAgICAgICBjYWxsYWJsZSA9IG51bGw7CisgICAgICB9CisgICAgICBjbG9zZWQgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyBJdGVyYXRvcjxSb3dSZXN1bHQ+IGl0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxSb3dSZXN1bHQ+KCkgeworICAgICAgICAvLyBUaGUgbmV4dCBSb3dSZXN1bHQsIHBvc3NpYmx5IHByZS1yZWFkCisgICAgICAgIFJvd1Jlc3VsdCBuZXh0ID0gbnVsbDsKKyAgICAgICAgCisgICAgICAgIC8vIHJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGFub3RoZXIgaXRlbSBwZW5kaW5nLCBmYWxzZSBpZiB0aGVyZSBpc24ndC4KKyAgICAgICAgLy8gdGhpcyBtZXRob2QgaXMgd2hlcmUgdGhlIGFjdHVhbCBhZHZhbmNpbmcgdGFrZXMgcGxhY2UsIGJ1dCB5b3UgbmVlZAorICAgICAgICAvLyB0byBjYWxsIG5leHQoKSB0byBjb25zdW1lIGl0LiBoYXNOZXh0KCkgd2lsbCBvbmx5IGFkdmFuY2UgaWYgdGhlcmUKKyAgICAgICAgLy8gaXNuJ3QgYSBwZW5kaW5nIG5leHQoKS4KKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBuZXh0ID0gQ2xpZW50U2Nhbm5lci50aGlzLm5leHQoKTsKKyAgICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICB9ICAgICAgICAgICAgCisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgLy8gZ2V0IHRoZSBwZW5kaW5nIG5leHQgaXRlbSBhbmQgYWR2YW5jZSB0aGUgaXRlcmF0b3IuIHJldHVybnMgbnVsbCBpZgorICAgICAgICAvLyB0aGVyZSBpcyBubyBuZXh0IGl0ZW0uCisgICAgICAgIHB1YmxpYyBSb3dSZXN1bHQgbmV4dCgpIHsKKyAgICAgICAgICAvLyBzaW5jZSBoYXNOZXh0KCkgZG9lcyB0aGUgcmVhbCBhZHZhbmNpbmcsIHdlIGNhbGwgdGhpcyB0byBkZXRlcm1pbmUKKyAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhIG5leHQgYmVmb3JlIHByb2NlZWRpbmcuCisgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgICAKKyAgICAgICAgICAvLyBpZiB3ZSBnZXQgdG8gaGVyZSwgdGhlbiBoYXNOZXh0KCkgaGFzIGdpdmVuIHVzIGFuIGl0ZW0gdG8gcmV0dXJuLgorICAgICAgICAgIC8vIHdlIHdhbnQgdG8gcmV0dXJuIHRoZSBpdGVtIGFuZCB0aGVuIG51bGwgb3V0IHRoZSBuZXh0IHBvaW50ZXIsIHNvCisgICAgICAgICAgLy8gd2UgdXNlIGEgdGVtcG9yYXJ5IHZhcmlhYmxlLgorICAgICAgICAgIFJvd1Jlc3VsdCB0ZW1wID0gbmV4dDsKKyAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICByZXR1cm4gdGVtcDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgfTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9IVGFibGVQb29sLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvSFRhYmxlUG9vbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjMwMTk4MmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvSFRhYmxlUG9vbC5qYXZhCkBAIC0wLDAgKzEsMTI3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheURlcXVlOworLyogdXNpbmcgYSBzdGFjayBpbnN0ZWFkIG9mIGEgRklGTyBtaWdodCBoYXZlIHNvbWUgc21hbGwgcG9zaXRpdmUgcGVyZm9ybWFuY2UKKyAgIGltcGFjdCB3cnQuIGNhY2hlICovCitpbXBvcnQgamF2YS51dGlsLkRlcXVlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEEgc2ltcGxlIHBvb2wgb2YgSFRhYmxlIGluc3RhbmNlcy4KKyAqIDxwPgorICogVGhlIGRlZmF1bHQgcG9vbCBzaXplIGlzIDEwLgorICovCitwdWJsaWMgY2xhc3MgSFRhYmxlUG9vbCB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxieXRlW10sIEhUYWJsZVBvb2w+IHBvb2xNYXAgPSAKKyAgICBuZXcgVHJlZU1hcDxieXRlW10sIEhUYWJsZVBvb2w+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworCisgIHByaXZhdGUgZmluYWwgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgcHJpdmF0ZSBmaW5hbCBEZXF1ZTxIVGFibGU+IHBvb2w7CisgIHByaXZhdGUgZmluYWwgaW50IG1heFNpemU7CisKKyAgLyoqCisgICAqIEdldCBhIHNoYXJlZCB0YWJsZSBwb29sLgorICAgKiBAcGFyYW0gdGFibGVOYW1lIHRoZSB0YWJsZSBuYW1lCisgICAqIEByZXR1cm4gdGhlIHRhYmxlIHBvb2wKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFRhYmxlUG9vbCBnZXRQb29sKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICByZXR1cm4gZ2V0UG9vbCh0YWJsZU5hbWUsIDEwKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgYSBzaGFyZWQgdGFibGUgcG9vbC4KKyAgICogPHA+CisgICAqIE5PVEU6IDxpPm1heFNpemU8L2k+IGlzIGFkdmlzb3J5LiBJZiB0aGUgcG9vbCBkb2VzIG5vdCB5ZXQgZXhpc3QsIGEgbmV3CisgICAqIHNoYXJlZCBwb29sIHdpbGwgYmUgYWxsb2NhdGVkIHdpdGggPGk+bWF4U2l6ZTwvaT4gYXMgdGhlIHNpemUgbGltaXQuCisgICAqIEhvd2V2ZXIsIGlmIHRoZSBzaGFyZWQgcG9vbCBhbHJlYWR5IGV4aXN0cywgYW5kIHdhcyBjcmVhdGVkIHdpdGggYSAKKyAgICogZGlmZmVyZW50IChvciBkZWZhdWx0KSB2YWx1ZSBmb3IgPGk+bWF4U2l6ZTwvaT4sIGl0IHdpbGwgbm90IGJlIGNoYW5nZWQuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgdGhlIHRhYmxlIG5hbWUKKyAgICogQHBhcmFtIG1heFNpemUgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgcG9vbAorICAgKiBAcmV0dXJuIHRoZSB0YWJsZSBwb29sCisgICAqLworICBwdWJsaWMgc3RhdGljIEhUYWJsZVBvb2wgZ2V0UG9vbChieXRlW10gdGFibGVOYW1lLCBpbnQgbWF4U2l6ZSkgeworICAgIHN5bmNocm9uaXplZCAocG9vbE1hcCkgeworICAgICAgSFRhYmxlUG9vbCBwb29sID0gcG9vbE1hcC5nZXQodGFibGVOYW1lKTsKKyAgICAgIGlmIChwb29sID09IG51bGwpIHsKKyAgICAgICAgcG9vbCA9IG5ldyBIVGFibGVQb29sKHRhYmxlTmFtZSwgbWF4U2l6ZSk7CisgICAgICAgIHBvb2xNYXAucHV0KHRhYmxlTmFtZSwgcG9vbCk7CisgICAgICB9CisgICAgICByZXR1cm4gcG9vbDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHRhYmxlTmFtZSB0aGUgdGFibGUgbmFtZQorICAgKi8KKyAgcHVibGljIEhUYWJsZVBvb2woYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIHRoaXMubWF4U2l6ZSA9IDEwOworICAgIHRoaXMucG9vbCA9IG5ldyBBcnJheURlcXVlPEhUYWJsZT4odGhpcy5tYXhTaXplKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gdGFibGVOYW1lIHRoZSB0YWJsZSBuYW1lCisgICAqIEBwYXJhbSBtYXhTaXplIG1heGltdW0gcG9vbCBzaXplCisgICAqLworICBwdWJsaWMgSFRhYmxlUG9vbChieXRlW10gdGFibGVOYW1lLCBpbnQgbWF4U2l6ZSkgeworICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIHRoaXMubWF4U2l6ZSA9IG1heFNpemU7CisgICAgdGhpcy5wb29sID0gbmV3IEFycmF5RGVxdWU8SFRhYmxlPih0aGlzLm1heFNpemUpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIEhUYWJsZSBpbnN0YW5jZSwgcG9zc2libHkgZnJvbSB0aGUgcG9vbCwgaWYgb25lIGlzIGF2YWlsYWJsZS4KKyAgICogQHJldHVybiBIVGFibGUgYSBIVGFibGUgaW5zdGFuY2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhUYWJsZSBnZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN5bmNocm9uaXplZCAocG9vbCkgeworICAgICAgLy8gcGVlayB0aGVuIHBvcCBpbnNpZGUgYSBzeW5jaHJvbml6ZWQgYmxvY2sgYXZvaWRzIHRoZSBvdmVyaGVhZCBvZiBhCisgICAgICAvLyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uCisgICAgICBIVGFibGUgdGFibGUgPSBwb29sLnBlZWsoKTsKKyAgICAgIGlmICh0YWJsZSAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBwb29sLnBvcCgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybiBhIEhUYWJsZSBpbnN0YW5jZSB0byB0aGUgcG9vbC4KKyAgICogQHBhcmFtIHRhYmxlIGEgSFRhYmxlIGluc3RhbmNlCisgICAqLworICBwdWJsaWMgdm9pZCBwdXQoSFRhYmxlIHRhYmxlKSB7CisgICAgc3luY2hyb25pemVkIChwb29sKSB7CisgICAgICBpZiAocG9vbC5zaXplKCkgPCBtYXhTaXplKSB7CisgICAgICAgIHBvb2wucHVzaCh0YWJsZSk7CisgICAgICB9CisgICAgfQorICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9NZXRhU2Nhbm5lci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L01ldGFTY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg5Y2EwMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9NZXRhU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsOTAgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFNjYW5uZXIgY2xhc3MgdGhhdCBjb250YWlucyB0aGUgPGNvZGU+Lk1FVEEuPC9jb2RlPiB0YWJsZSBzY2FubmluZyBsb2dpYyAKKyAqIGFuZCB1c2VzIGEgUmV0cnlhYmxlIHNjYW5uZXIuIFByb3ZpZGVkIHZpc2l0b3JzIHdpbGwgYmUgY2FsbGVkCisgKiBmb3IgZWFjaCByb3cuCisgKi8KK2NsYXNzIE1ldGFTY2FubmVyIGltcGxlbWVudHMgSENvbnN0YW50cyB7CisKKyAgLyoqCisgICAqIFNjYW5zIHRoZSBtZXRhIHRhYmxlIGFuZCBjYWxscyBhIHZpc2l0b3Igb24gZWFjaCBSb3dSZXN1bHQgYW5kIHVzZXMgYSBlbXB0eQorICAgKiBzdGFydCByb3cgdmFsdWUgYXMgdGFibGUgbmFtZS4KKyAgICogCisgICAqIEBwYXJhbSBjb25maWd1cmF0aW9uCisgICAqIEBwYXJhbSB2aXNpdG9yIEEgY3VzdG9tIHZpc2l0b3IKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1ldGFTY2FuKEhCYXNlQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uLAorICAgICAgTWV0YVNjYW5uZXJWaXNpdG9yIHZpc2l0b3IpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbWV0YVNjYW4oY29uZmlndXJhdGlvbiwgdmlzaXRvciwgRU1QVFlfU1RBUlRfUk9XKTsKKyAgfQorCisgIC8qKgorICAgKiBTY2FucyB0aGUgbWV0YSB0YWJsZSBhbmQgY2FsbHMgYSB2aXNpdG9yIG9uIGVhY2ggUm93UmVzdWx0LiBVc2VzIGEgdGFibGUKKyAgICogbmFtZSB0byBsb2NhdGUgbWV0YSByZWdpb25zLgorICAgKiAKKyAgICogQHBhcmFtIGNvbmZpZ3VyYXRpb24KKyAgICogQHBhcmFtIHZpc2l0b3IKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWV0YVNjYW4oSEJhc2VDb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24sCisgICAgICBNZXRhU2Nhbm5lclZpc2l0b3IgdmlzaXRvciwgYnl0ZVtdIHRhYmxlTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gSENvbm5lY3Rpb25NYW5hZ2VyLmdldENvbm5lY3Rpb24oY29uZmlndXJhdGlvbik7CisgICAgYnl0ZSBbXSBzdGFydFJvdyA9IHRhYmxlTmFtZSA9PSBudWxsIHx8IHRhYmxlTmFtZS5sZW5ndGggPT0gMCA/CisgICAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XIDogCisgICAgICAgICAgSFJlZ2lvbkluZm8uY3JlYXRlUmVnaW9uTmFtZSh0YWJsZU5hbWUsIG51bGwsIFpFUk9FUyk7CisgICAgICAKKyAgICAvLyBTY2FuIG92ZXIgZWFjaCBtZXRhIHJlZ2lvbgorICAgIFNjYW5uZXJDYWxsYWJsZSBjYWxsYWJsZSA9IG51bGw7CisgICAgZG8geworICAgICAgY2FsbGFibGUgPSBuZXcgU2Nhbm5lckNhbGxhYmxlKGNvbm5lY3Rpb24sIE1FVEFfVEFCTEVfTkFNRSwKKyAgICAgICAgQ09MVU1OX0ZBTUlMWV9BUlJBWSwgc3RhcnRSb3csIExBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgICAgLy8gT3BlbiBzY2FubmVyCisgICAgICBjb25uZWN0aW9uLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKGNhbGxhYmxlKTsKKyAgICAgIHRyeSB7CisgICAgICAgIFJvd1Jlc3VsdCByID0gbnVsbDsKKyAgICAgICAgZG8geworICAgICAgICAgIFJvd1Jlc3VsdCBbXSBycnMgPSBjb25uZWN0aW9uLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKGNhbGxhYmxlKTsKKyAgICAgICAgICBpZiAocnJzID09IG51bGwgfHwgcnJzLmxlbmd0aCA9PSAwIHx8IHJyc1swXS5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIHIgPSBycnNbMF07CisgICAgICAgIH0gd2hpbGUodmlzaXRvci5wcm9jZXNzUm93KHIpKTsKKyAgICAgICAgLy8gQWR2YW5jZSB0aGUgc3RhcnRSb3cgdG8gdGhlIGVuZCBrZXkgb2YgdGhlIGN1cnJlbnQgcmVnaW9uCisgICAgICAgIHN0YXJ0Um93ID0gY2FsbGFibGUuZ2V0SFJlZ2lvbkluZm8oKS5nZXRFbmRLZXkoKTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIC8vIENsb3NlIHNjYW5uZXIKKyAgICAgICAgY2FsbGFibGUuc2V0Q2xvc2UoKTsKKyAgICAgICAgY29ubmVjdGlvbi5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcyhjYWxsYWJsZSk7CisgICAgICB9CisgICAgfSB3aGlsZSAoQnl0ZXMuY29tcGFyZVRvKHN0YXJ0Um93LCBMQVNUX1JPVykgIT0gMCk7CisgIH0KKworICAvKioKKyAgICogVmlzaXRvciBjbGFzcyBjYWxsZWQgdG8gcHJvY2VzcyBlYWNoIHJvdyBvZiB0aGUgLk1FVEEuIHRhYmxlCisgICAqLworICBpbnRlcmZhY2UgTWV0YVNjYW5uZXJWaXNpdG9yIHsKKyAgICAvKioKKyAgICAgKiBWaXNpdG9yIG1ldGhvZCB0aGF0IGFjY2VwdHMgYSBSb3dSZXN1bHQgYW5kIHRoZSBtZXRhIHJlZ2lvbiBsb2NhdGlvbi4KKyAgICAgKiBJbXBsZW1lbnRhdGlvbnMgY2FuIHJldHVybiBmYWxzZSB0byBzdG9wIHRoZSByZWdpb24ncyBsb29wIGlmIGl0IGJlY29tZXMKKyAgICAgKiB1bm5lY2Vzc2FyeSBmb3Igc29tZSByZWFzb24uCisgICAgICogCisgICAgICogQHBhcmFtIHJvd1Jlc3VsdAorICAgICAqIEByZXR1cm4gQSBib29sZWFuIHRvIGtub3cgaWYgaXQgc2hvdWxkIGNvbnRpbnVlIHRvIGxvb3AgaW4gdGhlIHJlZ2lvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KFJvd1Jlc3VsdCByb3dSZXN1bHQpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L05vU2VydmVyRm9yUmVnaW9uRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTIwNjFiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L05vU2VydmVyRm9yUmVnaW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlZ2lvbkV4Y2VwdGlvbjsKKworLyoqCisgKiBUaHJvd24gd2hlbiBubyByZWdpb24gc2VydmVyIGNhbiBiZSBmb3VuZCBmb3IgYSByZWdpb24KKyAqLworcHVibGljIGNsYXNzIE5vU2VydmVyRm9yUmVnaW9uRXhjZXB0aW9uIGV4dGVuZHMgUmVnaW9uRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUwgPDwgMTEgLSAxTDsKKworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgTm9TZXJ2ZXJGb3JSZWdpb25FeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1JlZ2lvbk9mZmxpbmVFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9SZWdpb25PZmZsaW5lRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NiZDU5MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9SZWdpb25PZmZsaW5lRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzNiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlZ2lvbkV4Y2VwdGlvbjsKKworLyoqIFRocm93biB3aGVuIGEgdGFibGUgY2FuIG5vdCBiZSBsb2NhdGVkICovCitwdWJsaWMgY2xhc3MgUmVnaW9uT2ZmbGluZUV4Y2VwdGlvbiBleHRlbmRzIFJlZ2lvbkV4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDQ2NjAwODQwMkw7CisvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgUmVnaW9uT2ZmbGluZUV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqIEBwYXJhbSBzIG1lc3NhZ2UgKi8KKyAgcHVibGljIFJlZ2lvbk9mZmxpbmVFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1JldHJpZXNFeGhhdXN0ZWRFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9SZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmRjNzY4YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9SZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIAorICogRXhjZXB0aW9uIHRocm93biBieSBIVGFibGUgbWV0aG9kcyB3aGVuIGFuIGF0dGVtcHQgdG8gZG8gc29tZXRoaW5nIChsaWtlCisgKiBjb21taXQgY2hhbmdlcykgZmFpbHMgYWZ0ZXIgYSBidW5jaCBvZiByZXRyaWVzLiAKKyAqLyAKK3B1YmxpYyBjbGFzcyBSZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxODc2Nzc1ODQ0TDsKKyAgLyoqIAorICAgKiBDcmVhdGUgYSBuZXcgUmV0cmllc0V4aGF1c3RlZEV4Y2VwdGlvbiBmcm9tIHRoZSBsaXN0IG9mIHByaW9yIGZhaWx1cmVzLgorICAgKiBAcGFyYW0gc2VydmVyTmFtZSBuYW1lIG9mIEhSZWdpb25TZXJ2ZXIKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgbmFtZSBvZiByZWdpb24KKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHdlIHdlcmUgcHVyc3Vpbmcgd2hlbiB3ZSByYW4gb3V0IG9mIHJldHJpZXMKKyAgICogQHBhcmFtIG51bVRyaWVzIFRoZSBudW1iZXIgb2YgdHJpZXMgd2UgbWFkZQorICAgKiBAcGFyYW0gZXhjZXB0aW9ucyBMaXN0IG9mIGV4Y2VwdGlvbnMgdGhhdCBmYWlsZWQgYmVmb3JlIGdpdmluZyB1cAorICAgKi8gCisgIHB1YmxpYyBSZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uKFN0cmluZyBzZXJ2ZXJOYW1lLCBmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlIFtdICByb3csCisgICAgICBpbnQgbnVtVHJpZXMsIExpc3Q8VGhyb3dhYmxlPiBleGNlcHRpb25zKSB7CisgICAgc3VwZXIoZ2V0TWVzc2FnZShzZXJ2ZXJOYW1lLCByZWdpb25OYW1lLCByb3csIG51bVRyaWVzLCBleGNlcHRpb25zKSk7CisgIH0KKyAgCisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldE1lc3NhZ2UoU3RyaW5nIHNlcnZlck5hbWUsIGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gcm93LAorICAgICAgaW50IG51bVRyaWVzLCBMaXN0PFRocm93YWJsZT4gZXhjZXB0aW9ucykgeworICAgIFN0cmluZ0J1aWxkZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoIlRyeWluZyB0byBjb250YWN0IHJlZ2lvbiBzZXJ2ZXIgIik7CisgICAgYnVmZmVyLmFwcGVuZChzZXJ2ZXJOYW1lKTsKKyAgICBidWZmZXIuYXBwZW5kKCIgZm9yIHJlZ2lvbiAiKTsKKyAgICBidWZmZXIuYXBwZW5kKHJlZ2lvbk5hbWUgPT0gbnVsbD8gIiI6IEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbk5hbWUpKTsKKyAgICBidWZmZXIuYXBwZW5kKCIsIHJvdyAnIik7CisgICAgYnVmZmVyLmFwcGVuZChyb3cgPT0gbnVsbD8gIiI6IEJ5dGVzLnRvU3RyaW5nKHJvdykpOworICAgIGJ1ZmZlci5hcHBlbmQoIicsIGJ1dCBmYWlsZWQgYWZ0ZXIgIik7CisgICAgYnVmZmVyLmFwcGVuZChudW1UcmllcyArIDEpOworICAgIGJ1ZmZlci5hcHBlbmQoIiBhdHRlbXB0cy5cbkV4Y2VwdGlvbnM6XG4iKTsKKyAgICBmb3IgKFRocm93YWJsZSB0IDogZXhjZXB0aW9ucykgeworICAgICAgYnVmZmVyLmFwcGVuZCh0LnRvU3RyaW5nKCkpOworICAgICAgYnVmZmVyLmFwcGVuZCgiXG4iKTsKKyAgICB9CisgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Jvd0xvY2suamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9Sb3dMb2NrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2M4YzQ2MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9Sb3dMb2NrLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworLyoqCisgKiBIb2xkcyByb3cgbmFtZSBhbmQgbG9jayBpZC4KKyAqLworcHVibGljIGNsYXNzIFJvd0xvY2sgeworICBwcml2YXRlIGJ5dGUgW10gcm93ID0gbnVsbDsKKyAgcHJpdmF0ZSBsb25nIGxvY2tJZCA9IC0xTDsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIFJvd0xvY2sgZnJvbSBhIHJvdyBhbmQgbG9jayBpZAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBsb2NrSWQKKyAgICovCisgIHB1YmxpYyBSb3dMb2NrKGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBsb25nIGxvY2tJZCkgeworICAgIHRoaXMucm93ID0gcm93OworICAgIHRoaXMubG9ja0lkID0gbG9ja0lkOworICB9CisgIAorICAvKioKKyAgICogQ3JlYXRlcyBhIFJvd0xvY2sgd2l0aCBvbmx5IGEgbG9jayBpZAorICAgKiBAcGFyYW0gbG9ja0lkCisgICAqLworICBwdWJsaWMgUm93TG9jayhmaW5hbCBsb25nIGxvY2tJZCkgeworICAgIHRoaXMubG9ja0lkID0gbG9ja0lkOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgcm93IGZvciB0aGlzIFJvd0xvY2sKKyAgICogQHJldHVybiB0aGUgcm93CisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRSb3coKSB7CisgICAgcmV0dXJuIHJvdzsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIGxvY2sgaWQgZnJvbSB0aGlzIFJvd0xvY2sKKyAgICogQHJldHVybiB0aGUgbG9jayBpZAorICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0TG9ja0lkKCkgeworICAgIHJldHVybiBsb2NrSWQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9TY2FubmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvU2Nhbm5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmNTBmNDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKKworLyoqCisgKiBJbnRlcmZhY2UgZm9yIGNsaWVudC1zaWRlIHNjYW5uaW5nLgorICogR28gdG8ge0BsaW5rIEhUYWJsZX0gdG8gb2J0YWluIGluc3RhbmNlcy4KKyAqLworcHVibGljIGludGVyZmFjZSBTY2FubmVyIGV4dGVuZHMgQ2xvc2VhYmxlLCBJdGVyYWJsZTxSb3dSZXN1bHQ+IHsKKyAgLyoqCisgICAqIEdyYWIgdGhlIG5leHQgcm93J3Mgd29ydGggb2YgdmFsdWVzLiBUaGUgc2Nhbm5lciB3aWxsIHJldHVybiBhIFJvd1Jlc3VsdAorICAgKiB0aGF0IGNvbnRhaW5zIGJvdGggdGhlIHJvdydzIGtleSBhbmQgYSBtYXAgb2YgYnl0ZVtdIGNvbHVtbiBuYW1lcyB0byBDZWxsIAorICAgKiB2YWx1ZSBvYmplY3RzLiBUaGUgZGF0YSByZXR1cm5lZCB3aWxsIG9ubHkgY29udGFpbiB0aGUgbW9zdCByZWNlbnQgZGF0YSAKKyAgICogdmFsdWUgZm9yIGVhY2ggcm93IHRoYXQgaXMgbm90IG5ld2VyIHRoYW4gdGhlIHRhcmdldCB0aW1lIHBhc3NlZCB3aGVuIHRoZQorICAgKiBzY2FubmVyIHdhcyBjcmVhdGVkLgorICAgKiBAcmV0dXJuIFJvd1Jlc3VsdCBvYmplY3QgaWYgdGhlcmUgaXMgYW5vdGhlciByb3csIG51bGwgaWYgdGhlIHNjYW5uZXIgaXMKKyAgICogZXhoYXVzdGVkLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLyAgCisgIHB1YmxpYyBSb3dSZXN1bHQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBAcGFyYW0gbmJSb3dzIG51bWJlciBvZiByb3dzIHRvIHJldHVybgorICAgKiBAcmV0dXJuIEJldHdlZW4gemVybyBhbmQgPHBhcmFtPm5iUm93czwvcGFyYW0+IFJvd1Jlc3VsdHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBbXSBuZXh0KGludCBuYlJvd3MpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBDbG9zZXMgdGhlIHNjYW5uZXIgYW5kIHJlbGVhc2VzIGFueSByZXNvdXJjZXMgaXQgaGFzIGFsbG9jYXRlZAorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKTsgIAorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9TY2FubmVyQ2FsbGFibGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9TY2FubmVyQ2FsbGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDM1OThkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NjYW5uZXJDYWxsYWJsZS5qYXZhCkBAIC0wLDAgKzEsMTM4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CisKKworLyoqCisgKiBSZXRyaWVzIHNjYW5uZXIgb3BlcmF0aW9ucyBzdWNoIGFzIGNyZWF0ZSwgbmV4dCwgZXRjLgorICogVXNlZCBieSB7QGxpbmsgU2Nhbm5lcn1zIG1hZGUgYnkge0BsaW5rIEhUYWJsZX0uCisgKi8KK3B1YmxpYyBjbGFzcyBTY2FubmVyQ2FsbGFibGUgZXh0ZW5kcyBTZXJ2ZXJDYWxsYWJsZTxSb3dSZXN1bHRbXT4geworICBwcml2YXRlIGxvbmcgc2Nhbm5lcklkID0gLTFMOworICBwcml2YXRlIGJvb2xlYW4gaW5zdGFudGlhdGVkID0gZmFsc2U7CisgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdW10gY29sdW1uczsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIHRpbWVzdGFtcDsKKyAgcHJpdmF0ZSBmaW5hbCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyOworICBwcml2YXRlIGludCBjYWNoaW5nID0gMTsKKworICAvKioKKyAgICogQHBhcmFtIGNvbm5lY3Rpb24KKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcGFyYW0gY29sdW1ucworICAgKiBAcGFyYW0gc3RhcnRSb3cKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gZmlsdGVyCisgICAqLworICBwdWJsaWMgU2Nhbm5lckNhbGxhYmxlIChIQ29ubmVjdGlvbiBjb25uZWN0aW9uLCBieXRlIFtdIHRhYmxlTmFtZSwgYnl0ZSBbXVtdIGNvbHVtbnMsCisgICAgICBieXRlIFtdIHN0YXJ0Um93LCBsb25nIHRpbWVzdGFtcCwgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgeworICAgIHN1cGVyKGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgc3RhcnRSb3cpOworICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgdGhpcy5maWx0ZXIgPSBmaWx0ZXI7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gcmVsb2FkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBpbnN0YW50aWF0ZVNlcnZlcihib29sZWFuIHJlbG9hZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWluc3RhbnRpYXRlZCB8fCByZWxvYWQpIHsKKyAgICAgIHN1cGVyLmluc3RhbnRpYXRlU2VydmVyKHJlbG9hZCk7CisgICAgICBpbnN0YW50aWF0ZWQgPSB0cnVlOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlI2NhbGwoKQorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdFtdIGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChzY2FubmVySWQgIT0gLTFMICYmIGNsb3NlZCkgeworICAgICAgc2VydmVyLmNsb3NlKHNjYW5uZXJJZCk7CisgICAgICBzY2FubmVySWQgPSAtMUw7CisgICAgfSBlbHNlIGlmIChzY2FubmVySWQgPT0gLTFMICYmICFjbG9zZWQpIHsKKyAgICAgIC8vIG9wZW4gdGhlIHNjYW5uZXIKKyAgICAgIHNjYW5uZXJJZCA9IG9wZW5TY2FubmVyKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIFJvd1Jlc3VsdCBbXSBycnMgPSBzZXJ2ZXIubmV4dChzY2FubmVySWQsIGNhY2hpbmcpOworICAgICAgcmV0dXJuIHJycy5sZW5ndGggPT0gMCA/IG51bGwgOiBycnM7CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisgIAorICBwcm90ZWN0ZWQgbG9uZyBvcGVuU2Nhbm5lcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHNlcnZlci5vcGVuU2Nhbm5lcigKKyAgICAgICAgdGhpcy5sb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpLCBjb2x1bW5zLCByb3csCisgICAgICAgIHRpbWVzdGFtcCwgZmlsdGVyKTsKKyAgfQorICAKKyAgcHJvdGVjdGVkIGJ5dGUgW11bXSBnZXRDb2x1bW5zKCkgeworICAgIHJldHVybiBjb2x1bW5zOworICB9CisgIAorICBwcm90ZWN0ZWQgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgcmV0dXJuIHRpbWVzdGFtcDsKKyAgfQorICAKKyAgcHJvdGVjdGVkIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXIoKSB7CisgICAgcmV0dXJuIGZpbHRlcjsKKyAgfQorICAKKyAgLyoqCisgICAqIENhbGwgdGhpcyB3aGVuIHRoZSBuZXh0IGludm9jYXRpb24gb2YgY2FsbCBzaG91bGQgY2xvc2UgdGhlIHNjYW5uZXIKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldENsb3NlKCkgeworICAgIGNsb3NlZCA9IHRydWU7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBIUmVnaW9uSW5mbyBmb3IgdGhlIGN1cnJlbnQgcmVnaW9uCisgICAqLworICBwdWJsaWMgSFJlZ2lvbkluZm8gZ2V0SFJlZ2lvbkluZm8oKSB7CisgICAgaWYgKCFpbnN0YW50aWF0ZWQpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgbnVtYmVyIG9mIHJvd3MgdGhhdCB3aWxsIGJlIGZldGNoZWQgb24gbmV4dAorICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygcm93cyBmb3IgY2FjaGluZworICAgKi8KKyAgcHVibGljIGludCBnZXRDYWNoaW5nKCkgeworICAgIHJldHVybiBjYWNoaW5nOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgbnVtYmVyIG9mIHJvd3MgdGhhdCB3aWxsIGJlIGZldGNoZWQgb24gbmV4dAorICAgKiBAcGFyYW0gY2FjaGluZyB0aGUgbnVtYmVyIG9mIHJvd3MgZm9yIGNhY2hpbmcKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldENhY2hpbmcoaW50IGNhY2hpbmcpIHsKKyAgICB0aGlzLmNhY2hpbmcgPSBjYWNoaW5nOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NjYW5uZXJUaW1lb3V0RXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvU2Nhbm5lclRpbWVvdXRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjMxOTM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NjYW5uZXJUaW1lb3V0RXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRG9Ob3RSZXRyeUlPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGEgc2Nhbm5lciBoYXMgdGltZWQgb3V0LiAKKyAqLworcHVibGljIGNsYXNzIFNjYW5uZXJUaW1lb3V0RXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4Nzg4ODM4NjkwMjkwNjg4MzEzTDsKKworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBTY2FubmVyVGltZW91dEV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqIEBwYXJhbSBzICovCisgIFNjYW5uZXJUaW1lb3V0RXhjZXB0aW9uKFN0cmluZyBzKSB7CisgICAgc3VwZXIocyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9TZXJ2ZXJDYWxsYWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NlcnZlckNhbGxhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI2YTk2YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9TZXJ2ZXJDYWxsYWJsZS5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uTG9jYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhSZWdpb25JbnRlcmZhY2U7CisKKy8qKgorICogQWJzdHJhY3QgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIENhbGxhYmxlLCB1c2VkIGJ5IHJldHJ5YWJsZSBhY3Rpb25zLgorICogQHBhcmFtIDxUPiB0aGUgY2xhc3MgdGhhdCB0aGUgU2VydmVyQ2FsbGFibGUgaGFuZGxlcworICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VydmVyQ2FsbGFibGU8VD4gaW1wbGVtZW50cyBDYWxsYWJsZTxUPiB7CisgIHByb3RlY3RlZCBmaW5hbCBIQ29ubmVjdGlvbiBjb25uZWN0aW9uOworICBwcm90ZWN0ZWQgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWU7CisgIHByb3RlY3RlZCBmaW5hbCBieXRlIFtdIHJvdzsKKyAgcHJvdGVjdGVkIEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvbjsKKyAgcHJvdGVjdGVkIEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyOworCisgIC8qKgorICAgKiBAcGFyYW0gY29ubmVjdGlvbgorICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAqIEBwYXJhbSByb3cKKyAgICovCisgIHB1YmxpYyBTZXJ2ZXJDYWxsYWJsZShIQ29ubmVjdGlvbiBjb25uZWN0aW9uLCBieXRlIFtdIHRhYmxlTmFtZSwgYnl0ZSBbXSByb3cpIHsKKyAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uOworICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIHRoaXMucm93ID0gcm93OworICB9CisgIAorICAvKioKKyAgICogCisgICAqIEBwYXJhbSByZWxvYWQgc2V0IHRoaXMgdG8gdHJ1ZSBpZiBjb25uZWN0aW9uIHNob3VsZCByZS1maW5kIHRoZSByZWdpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgaW5zdGFudGlhdGVTZXJ2ZXIoYm9vbGVhbiByZWxvYWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5sb2NhdGlvbiA9IGNvbm5lY3Rpb24uZ2V0UmVnaW9uTG9jYXRpb24odGFibGVOYW1lLCByb3csIHJlbG9hZCk7CisgICAgdGhpcy5zZXJ2ZXIgPSBjb25uZWN0aW9uLmdldEhSZWdpb25Db25uZWN0aW9uKGxvY2F0aW9uLmdldFNlcnZlckFkZHJlc3MoKSk7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgc2VydmVyIG5hbWUgKi8KKyAgcHVibGljIFN0cmluZyBnZXRTZXJ2ZXJOYW1lKCkgeworICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcmV0dXJuIGxvY2F0aW9uLmdldFNlcnZlckFkZHJlc3MoKS50b1N0cmluZygpOworICB9CisgIAorICAvKiogQHJldHVybiB0aGUgcmVnaW9uIG5hbWUgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRSZWdpb25OYW1lKCkgeworICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcmV0dXJuIGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCk7CisgIH0KKyAgCisgIC8qKiBAcmV0dXJuIHRoZSByb3cgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0Um93KCkgeworICAgIHJldHVybiByb3c7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvU2VydmVyQ29ubmVjdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NlcnZlckNvbm5lY3Rpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZWEyOWZlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NlcnZlckNvbm5lY3Rpb24uamF2YQpAQCAtMCwwICsxLDQyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uTG9jYXRpb247CisKKy8qKgorICogVXNlZCBieSBtYXN0ZXIgYW5kIHJlZ2lvbiBzZXJ2ZXIsIHNvIHRoYXQgdGhleSBkbyBub3QgbmVlZCB0byB3YWl0IGZvciB0aGUKKyAqIGNsdXN0ZXIgdG8gYmUgdXAgdG8gZ2V0IGEgY29ubmVjdGlvbi4KKyAqLworcHVibGljIGludGVyZmFjZSBTZXJ2ZXJDb25uZWN0aW9uIGV4dGVuZHMgSENvbm5lY3Rpb24geworCisgIC8qKgorICAgKiBTZXQgcm9vdCByZWdpb24gbG9jYXRpb24gaW4gY29ubmVjdGlvbgorICAgKiBAcGFyYW0gcm9vdFJlZ2lvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0Um9vdFJlZ2lvbkxvY2F0aW9uKEhSZWdpb25Mb2NhdGlvbiByb290UmVnaW9uKTsKKyAgCisgIC8qKgorICAgKiBVbnNldCB0aGUgcm9vdCByZWdpb24gbG9jYXRpb24gaW4gdGhlIGNvbm5lY3Rpb24uIENhbGxlZCBieSAKKyAgICogU2VydmVyTWFuYWdlci5wcm9jZXNzUmVnaW9uQ2xvc2UuCisgICAqLworICBwdWJsaWMgdm9pZCB1bnNldFJvb3RSZWdpb25Mb2NhdGlvbigpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NlcnZlckNvbm5lY3Rpb25NYW5hZ2VyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvU2VydmVyQ29ubmVjdGlvbk1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNGJjZDhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1NlcnZlckNvbm5lY3Rpb25NYW5hZ2VyLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworCisvKioKKyAqIFVzZWQgYnkgc2VydmVyIHByb2Nlc3NlcyB0byBleHBvc2UgSFNlcnZlckNvbm5lY3Rpb24gbWV0aG9kCisgKiBzZXRSb290UmVnaW9uTG9jYXRpb24KKyAqLworcHVibGljIGNsYXNzIFNlcnZlckNvbm5lY3Rpb25NYW5hZ2VyIGV4dGVuZHMgSENvbm5lY3Rpb25NYW5hZ2VyIHsKKyAgLyoKKyAgICogTm90IGluc3RhbnRpYWJsZQorICAgKi8KKyAgcHJpdmF0ZSBTZXJ2ZXJDb25uZWN0aW9uTWFuYWdlcigpIHt9CisKKyAgLyoqCisgICAqIEdldCB0aGUgY29ubmVjdGlvbiBvYmplY3QgZm9yIHRoZSBpbnN0YW5jZSBzcGVjaWZpZWQgYnkgdGhlIGNvbmZpZ3VyYXRpb24KKyAgICogSWYgbm8gY3VycmVudCBjb25uZWN0aW9uIGV4aXN0cywgY3JlYXRlIGEgbmV3IGNvbm5lY3Rpb24gZm9yIHRoYXQgaW5zdGFuY2UKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHJldHVybiBIQ29ubmVjdGlvbiBvYmplY3QgZm9yIHRoZSBpbnN0YW5jZSBzcGVjaWZpZWQgYnkgdGhlIGNvbmZpZ3VyYXRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU2VydmVyQ29ubmVjdGlvbiBnZXRDb25uZWN0aW9uKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgcmV0dXJuIChTZXJ2ZXJDb25uZWN0aW9uKSBIQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1VubW9kaWZ5YWJsZUhDb2x1bW5EZXNjcmlwdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVW5tb2RpZnlhYmxlSENvbHVtbkRlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZWU2MDljCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1VubW9kaWZ5YWJsZUhDb2x1bW5EZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSw4OSBAQAorcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5Db21wcmVzc2lvbjsKKworLyoqCisgKiBJbW11dGFibGUgSENvbHVtbkRlc2NyaXB0b3IKKyAqLworcHVibGljIGNsYXNzIFVubW9kaWZ5YWJsZUhDb2x1bW5EZXNjcmlwdG9yIGV4dGVuZHMgSENvbHVtbkRlc2NyaXB0b3IgeworCisgIC8qKgorICAgKiBAcGFyYW0gZGVzYworICAgKi8KKyAgcHVibGljIFVubW9kaWZ5YWJsZUhDb2x1bW5EZXNjcmlwdG9yIChmaW5hbCBIQ29sdW1uRGVzY3JpcHRvciBkZXNjKSB7CisgICAgc3VwZXIoZGVzYyk7CisgIH0KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvciNzZXRWYWx1ZShieXRlW10sIGJ5dGVbXSkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShieXRlW10ga2V5LCBieXRlW10gdmFsdWUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhDb2x1bW5EZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3Ijc2V0VmFsdWUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhDb2x1bW5EZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3Ijc2V0TWF4VmVyc2lvbnMoaW50KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldE1heFZlcnNpb25zKGludCBtYXhWZXJzaW9ucykgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSENvbHVtbkRlc2NyaXB0b3IgaXMgcmVhZC1vbmx5Iik7CisgIH0KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvciNzZXRJbk1lbW9yeShib29sZWFuKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldEluTWVtb3J5KGJvb2xlYW4gaW5NZW1vcnkpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhDb2x1bW5EZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3Ijc2V0QmxvY2tDYWNoZUVuYWJsZWQoYm9vbGVhbikKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRCbG9ja0NhY2hlRW5hYmxlZChib29sZWFuIGJsb2NrQ2FjaGVFbmFibGVkKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIQ29sdW1uRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yI3NldE1heFZhbHVlTGVuZ3RoKGludCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRNYXhWYWx1ZUxlbmd0aChpbnQgbWF4TGVuZ3RoKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIQ29sdW1uRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yI3NldFRpbWVUb0xpdmUoaW50KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFRpbWVUb0xpdmUoaW50IHRpbWVUb0xpdmUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhDb2x1bW5EZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3Ijc2V0Q29tcHJlc3Npb25UeXBlKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkNvbXByZXNzaW9uLkFsZ29yaXRobSkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRDb21wcmVzc2lvblR5cGUoQ29tcHJlc3Npb24uQWxnb3JpdGhtIHR5cGUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhDb2x1bW5EZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3Ijc2V0TWFwRmlsZUluZGV4SW50ZXJ2YWwoaW50KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldE1hcEZpbGVJbmRleEludGVydmFsKGludCBpbnRlcnZhbCkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFRhYmxlRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9Vbm1vZGlmeWFibGVIUmVnaW9uSW5mby5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1VubW9kaWZ5YWJsZUhSZWdpb25JbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjUxOWEwNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9Vbm1vZGlmeWFibGVIUmVnaW9uSW5mby5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworCitjbGFzcyBVbm1vZGlmeWFibGVIUmVnaW9uSW5mbyBleHRlbmRzIEhSZWdpb25JbmZvIHsKKyAgLyoKKyAgICogQ3JlYXRlcyBhbiB1bm1vZGlmeWFibGUgY29weSBvZiBhbiBIUmVnaW9uSW5mbworICAgKiAKKyAgICogQHBhcmFtIGluZm8KKyAgICovCisgIFVubW9kaWZ5YWJsZUhSZWdpb25JbmZvKEhSZWdpb25JbmZvIGluZm8pIHsKKyAgICBzdXBlcihpbmZvKTsKKyAgICB0aGlzLnRhYmxlRGVzYyA9IG5ldyBVbm1vZGlmeWFibGVIVGFibGVEZXNjcmlwdG9yKGluZm8uZ2V0VGFibGVEZXNjKCkpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHNwbGl0IHNldCBzcGxpdCBzdGF0dXMKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRTcGxpdChib29sZWFuIHNwbGl0KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIUmVnaW9uSW5mbyBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gb2ZmTGluZSBzZXQgb25saW5lIC0gb2ZmbGluZSBzdGF0dXMKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRPZmZsaW5lKGJvb2xlYW4gb2ZmTGluZSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFJlZ2lvbkluZm8gaXMgcmVhZC1vbmx5Iik7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9Vbm1vZGlmeWFibGVIVGFibGVEZXNjcmlwdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkM2UwMDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQuSW5kZXhTcGVjaWZpY2F0aW9uOworCisvKioKKyAqIFJlYWQtb25seSB0YWJsZSBkZXNjcmlwdG9yLgorICovCitwdWJsaWMgY2xhc3MgVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvciBleHRlbmRzIEhUYWJsZURlc2NyaXB0b3IgeworICAvKiogRGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvcigpIHsKKwkgIHN1cGVyKCk7CisgIH0KKworICAvKgorICAgKiBDcmVhdGUgYW4gdW5tb2RpZnlhYmxlIGNvcHkgb2YgYW4gSFRhYmxlRGVzY3JpcHRvcgorICAgKiBAcGFyYW0gZGVzYworICAgKi8KKyAgVW5tb2RpZnlhYmxlSFRhYmxlRGVzY3JpcHRvcihmaW5hbCBIVGFibGVEZXNjcmlwdG9yIGRlc2MpIHsKKyAgICBzdXBlcihkZXNjLmdldE5hbWUoKSwgZ2V0VW5tb2RpZnlhYmxlRmFtaWxpZXMoZGVzYyksIGRlc2MuZ2V0SW5kZXhlcygpLCBkZXNjLmdldFZhbHVlcygpKTsKKyAgfQorICAKKyAgLyoKKyAgICogQHBhcmFtIGRlc2MKKyAgICogQHJldHVybiBGYW1pbGllcyBhcyB1bm1vZGlmaWFibGUgYXJyYXkuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBIQ29sdW1uRGVzY3JpcHRvcltdIGdldFVubW9kaWZ5YWJsZUZhbWlsaWVzKAorICAgICAgZmluYWwgSFRhYmxlRGVzY3JpcHRvciBkZXNjKSB7CisgICAgSENvbHVtbkRlc2NyaXB0b3IgW10gZiA9IG5ldyBIQ29sdW1uRGVzY3JpcHRvcltkZXNjLmdldEZhbWlsaWVzKCkuc2l6ZSgpXTsKKyAgICBpbnQgaSA9IDA7CisgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBjOiBkZXNjLmdldEZhbWlsaWVzKCkpIHsKKyAgICAgIGZbaSsrXSA9IGM7CisgICAgfQorICAgIHJldHVybiBmOworICB9CisKKyAgLyoqCisgICAqIERvZXMgTk9UIGFkZCBhIGNvbHVtbiBmYW1pbHkuIFRoaXMgb2JqZWN0IGlzIGltbXV0YWJsZQorICAgKiBAcGFyYW0gZmFtaWx5IEhDb2x1bW5EZXNjcmlwdG9yIG9mIGZhbWlseXRvIGFkZC4KKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBhZGRGYW1pbHkoZmluYWwgSENvbHVtbkRlc2NyaXB0b3IgZmFtaWx5KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIVGFibGVEZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHJldHVybiBDb2x1bW4gZGVzY3JpcHRvciBmb3IgdGhlIHBhc3NlZCBmYW1pbHkgbmFtZSBvciB0aGUgZmFtaWx5IG9uCisgICAqIHBhc3NlZCBpbiBjb2x1bW4uCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIEhDb2x1bW5EZXNjcmlwdG9yIHJlbW92ZUZhbWlseShmaW5hbCBieXRlIFtdIGNvbHVtbikgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFRhYmxlRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3Ijc2V0SW5NZW1vcnkoYm9vbGVhbikKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRJbk1lbW9yeShib29sZWFuIGluTWVtb3J5KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIVGFibGVEZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvciNzZXRSZWFkT25seShib29sZWFuKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFJlYWRPbmx5KGJvb2xlYW4gcmVhZE9ubHkpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhUYWJsZURlc2NyaXB0b3IgaXMgcmVhZC1vbmx5Iik7CisgIH0KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yI3NldFZhbHVlKGJ5dGVbXSwgYnl0ZVtdKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGJ5dGVbXSBrZXksIGJ5dGVbXSB2YWx1ZSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFRhYmxlRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3Ijc2V0VmFsdWUoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkhUYWJsZURlc2NyaXB0b3IgaXMgcmVhZC1vbmx5Iik7CisgIH0KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yI3NldE1heEZpbGVTaXplKGxvbmcpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0TWF4RmlsZVNpemUobG9uZyBtYXhGaWxlU2l6ZSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFRhYmxlRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3Ijc2V0TWVtY2FjaGVGbHVzaFNpemUoaW50KQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldE1lbWNhY2hlRmx1c2hTaXplKGludCBtZW1jYWNoZUZsdXNoU2l6ZSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiSFRhYmxlRGVzY3JpcHRvciBpcyByZWFkLW9ubHkiKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3IjYWRkSW5kZXgob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZC5JbmRleFNwZWNpZmljYXRpb24pCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgYWRkSW5kZXgoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJIVGFibGVEZXNjcmlwdG9yIGlzIHJlYWQtb25seSIpOyAKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleEtleUdlbmVyYXRvci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleEtleUdlbmVyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhZTgxMWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4S2V5R2VuZXJhdG9yLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKK3B1YmxpYyBpbnRlcmZhY2UgSW5kZXhLZXlHZW5lcmF0b3IgZXh0ZW5kcyBXcml0YWJsZSB7CisKKyAgYnl0ZSBbXSBjcmVhdGVJbmRleEtleShieXRlIFtdIHJvd0tleSwgTWFwPGJ5dGUgW10sIGJ5dGUgW10+IGNvbHVtbnMpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleE5vdEZvdW5kRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4Tm90Rm91bmRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZTYxNjljCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleE5vdEZvdW5kRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGFza2luZyBmb3IgYW4gaW5kZXggdGhhdCBkb2VzIG5vdCBleGlzdC4KKyAqLworcHVibGljIGNsYXNzIEluZGV4Tm90Rm91bmRFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjUzMzk3MTUyODU1NzAwMDk2NUw7CisKKyAgcHVibGljIEluZGV4Tm90Rm91bmRFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIHB1YmxpYyBJbmRleE5vdEZvdW5kRXhjZXB0aW9uKFN0cmluZyBhcmcwKSB7CisgICAgc3VwZXIoYXJnMCk7CisgIH0KKworICBwdWJsaWMgSW5kZXhOb3RGb3VuZEV4Y2VwdGlvbihUaHJvd2FibGUgYXJnMCkgeworICAgIHN1cGVyKGFyZzAuZ2V0TWVzc2FnZSgpKTsKKyAgfQorCisgIHB1YmxpYyBJbmRleE5vdEZvdW5kRXhjZXB0aW9uKFN0cmluZyBhcmcwLCBUaHJvd2FibGUgYXJnMSkgeworICAgIHN1cGVyKGFyZzArYXJnMS5nZXRNZXNzYWdlKCkpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90YWJsZWluZGV4ZWQvSW5kZXhTcGVjaWZpY2F0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4U3BlY2lmaWNhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0ZjhjNjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4U3BlY2lmaWNhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTkwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uT2JqZWN0V3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKiBIb2xkcyB0aGUgc3BlY2lmaWNhdGlvbiBmb3IgYSBzaW5nbGUgc2Vjb25kYXJ5IGluZGV4LiAqLworcHVibGljIGNsYXNzIEluZGV4U3BlY2lmaWNhdGlvbiBpbXBsZW1lbnRzIFdyaXRhYmxlIHsKKworICAvLyBDb2x1bW5zIHRoYXQgYXJlIGluZGV4ZWQgKHBhcnQgb2YgdGhlIGluZGV4Um93S2V5KQorICBwcml2YXRlIGJ5dGVbXVtdIGluZGV4ZWRDb2x1bW5zOworCisgIC8vIENvbnN0cnVjdHMgdGhlCisgIHByaXZhdGUgSW5kZXhLZXlHZW5lcmF0b3Iga2V5R2VuZXJhdG9yOworCisgIC8vIEFkZGl0aW9uYWwgY29sdW1ucyBtYXBwZWQgaW50byB0aGUgaW5kZXhlZCByb3cuIFRoZXNlIHdpbGwgYmUgYXZhaWxhYmxlIGZvcgorICAvLyBmaWx0ZXJzIHdoZW4gc2Nhbm5pbmcgdGhlIGluZGV4LgorICBwcml2YXRlIGJ5dGVbXVtdIGFkZGl0aW9uYWxDb2x1bW5zOworCisgIHByaXZhdGUgYnl0ZVtdW10gYWxsQ29sdW1uczsKKworICAvLyBJZCBvZiB0aGlzIGluZGV4LCB1bmlxdWUgd2l0aGluIGEgdGFibGUuCisgIHByaXZhdGUgU3RyaW5nIGluZGV4SWQ7CisKKyAgLyoqIENvbnN0cnVjdCBhbiAic2ltcGxlIiBpbmRleCBzcGVjIGZvciBhIHNpbmdsZSBjb2x1bW4uIAorICAgKiBAcGFyYW0gaW5kZXhJZCAKKyAgICogQHBhcmFtIGluZGV4ZWRDb2x1bW4KKyAgICovCisgIHB1YmxpYyBJbmRleFNwZWNpZmljYXRpb24oU3RyaW5nIGluZGV4SWQsIGJ5dGVbXSBpbmRleGVkQ29sdW1uKSB7CisgICAgdGhpcyhpbmRleElkLCBuZXcgYnl0ZVtdW10geyBpbmRleGVkQ29sdW1uIH0sIG51bGwsCisgICAgICAgIG5ldyBTaW1wbGVJbmRleEtleUdlbmVyYXRvcihpbmRleGVkQ29sdW1uKSk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0IGFuIGluZGV4IHNwZWMgYnkgc3BlY2lmeWluZyBldmVyeXRoaW5nLgorICAgKiAKKyAgICogQHBhcmFtIGluZGV4SWQKKyAgICogQHBhcmFtIGluZGV4ZWRDb2x1bW5zCisgICAqIEBwYXJhbSBhZGRpdGlvbmFsQ29sdW1ucworICAgKiBAcGFyYW0ga2V5R2VuZXJhdG9yCisgICAqLworICBwdWJsaWMgSW5kZXhTcGVjaWZpY2F0aW9uKFN0cmluZyBpbmRleElkLCBieXRlW11bXSBpbmRleGVkQ29sdW1ucywKKyAgICAgIGJ5dGVbXVtdIGFkZGl0aW9uYWxDb2x1bW5zLCBJbmRleEtleUdlbmVyYXRvciBrZXlHZW5lcmF0b3IpIHsKKyAgICB0aGlzLmluZGV4SWQgPSBpbmRleElkOworICAgIHRoaXMuaW5kZXhlZENvbHVtbnMgPSBpbmRleGVkQ29sdW1uczsKKyAgICB0aGlzLmFkZGl0aW9uYWxDb2x1bW5zID0gYWRkaXRpb25hbENvbHVtbnM7CisgICAgdGhpcy5rZXlHZW5lcmF0b3IgPSBrZXlHZW5lcmF0b3I7CisgICAgdGhpcy5tYWtlQWxsQ29sdW1ucygpOworICB9CisKKyAgcHVibGljIEluZGV4U3BlY2lmaWNhdGlvbigpIHsKKyAgICAvLyBGb3Igd3JpdGFibGUKKyAgfQorCisgIHByaXZhdGUgdm9pZCBtYWtlQWxsQ29sdW1ucygpIHsKKyAgICB0aGlzLmFsbENvbHVtbnMgPSBuZXcgYnl0ZVtpbmRleGVkQ29sdW1ucy5sZW5ndGgKKyAgICAgICAgKyAoYWRkaXRpb25hbENvbHVtbnMgPT0gbnVsbCA/IDAgOiBhZGRpdGlvbmFsQ29sdW1ucy5sZW5ndGgpXVtdOworICAgIFN5c3RlbS5hcnJheWNvcHkoaW5kZXhlZENvbHVtbnMsIDAsIGFsbENvbHVtbnMsIDAsIGluZGV4ZWRDb2x1bW5zLmxlbmd0aCk7CisgICAgaWYgKGFkZGl0aW9uYWxDb2x1bW5zICE9IG51bGwpIHsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYWRkaXRpb25hbENvbHVtbnMsIDAsIGFsbENvbHVtbnMsIGluZGV4ZWRDb2x1bW5zLmxlbmd0aCwKKyAgICAgICAgICBhZGRpdGlvbmFsQ29sdW1ucy5sZW5ndGgpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgaW5kZXhlZENvbHVtbnMuCisgICAqIAorICAgKiBAcmV0dXJuIFJldHVybiB0aGUgaW5kZXhlZENvbHVtbnMuCisgICAqLworICBwdWJsaWMgYnl0ZVtdW10gZ2V0SW5kZXhlZENvbHVtbnMoKSB7CisgICAgcmV0dXJuIGluZGV4ZWRDb2x1bW5zOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUga2V5R2VuZXJhdG9yLgorICAgKiAKKyAgICogQHJldHVybiBSZXR1cm4gdGhlIGtleUdlbmVyYXRvci4KKyAgICovCisgIHB1YmxpYyBJbmRleEtleUdlbmVyYXRvciBnZXRLZXlHZW5lcmF0b3IoKSB7CisgICAgcmV0dXJuIGtleUdlbmVyYXRvcjsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIGFkZGl0aW9uYWxDb2x1bW5zLgorICAgKiAKKyAgICogQHJldHVybiBSZXR1cm4gdGhlIGFkZGl0aW9uYWxDb2x1bW5zLgorICAgKi8KKyAgcHVibGljIGJ5dGVbXVtdIGdldEFkZGl0aW9uYWxDb2x1bW5zKCkgeworICAgIHJldHVybiBhZGRpdGlvbmFsQ29sdW1uczsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIGluZGV4SWQuCisgICAqIAorICAgKiBAcmV0dXJuIFJldHVybiB0aGUgaW5kZXhJZC4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0SW5kZXhJZCgpIHsKKyAgICByZXR1cm4gaW5kZXhJZDsKKyAgfQorCisgIHB1YmxpYyBieXRlW11bXSBnZXRBbGxDb2x1bW5zKCkgeworICAgIHJldHVybiBhbGxDb2x1bW5zOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNDb2x1bW4oYnl0ZVtdIGNvbHVtbikgeworICAgIGZvciAoYnl0ZVtdIGNvbCA6IGFsbENvbHVtbnMpIHsKKyAgICAgIGlmIChCeXRlcy5lcXVhbHMoY29sdW1uLCBjb2wpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGdldEluZGV4ZWRUYWJsZU5hbWUoYnl0ZVtdIGJhc2VUYWJsZU5hbWUpIHsKKyAgICByZXR1cm4gQnl0ZXMuYWRkKGJhc2VUYWJsZU5hbWUsIEJ5dGVzLnRvQnl0ZXMoIi0iICsgaW5kZXhJZCkpOworICB9CisKKyAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW5kZXhJZCA9IGluLnJlYWRVVEYoKTsKKyAgICBpbnQgbnVtSW5kZXhlZENvbHMgPSBpbi5yZWFkSW50KCk7CisgICAgaW5kZXhlZENvbHVtbnMgPSBuZXcgYnl0ZVtudW1JbmRleGVkQ29sc11bXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUluZGV4ZWRDb2xzOyBpKyspIHsKKyAgICAgIGluZGV4ZWRDb2x1bW5zW2ldID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgfQorICAgIGludCBudW1BZGRpdGlvbmFsQ29scyA9IGluLnJlYWRJbnQoKTsKKyAgICBhZGRpdGlvbmFsQ29sdW1ucyA9IG5ldyBieXRlW251bUFkZGl0aW9uYWxDb2xzXVtdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQWRkaXRpb25hbENvbHM7IGkrKykgeworICAgICAgYWRkaXRpb25hbENvbHVtbnNbaV0gPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICB9CisgICAgbWFrZUFsbENvbHVtbnMoKTsKKyAgICBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKyAgICBrZXlHZW5lcmF0b3IgPSAoSW5kZXhLZXlHZW5lcmF0b3IpIE9iamVjdFdyaXRhYmxlLnJlYWRPYmplY3QoaW4sIGNvbmYpOworICB9CisKKyAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlVVRGKGluZGV4SWQpOworICAgIG91dC53cml0ZUludChpbmRleGVkQ29sdW1ucy5sZW5ndGgpOworICAgIGZvciAoYnl0ZVtdIGNvbCA6IGluZGV4ZWRDb2x1bW5zKSB7CisgICAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGNvbCk7CisgICAgfQorICAgIGlmIChhZGRpdGlvbmFsQ29sdW1ucyAhPSBudWxsKSB7CisgICAgICBvdXQud3JpdGVJbnQoYWRkaXRpb25hbENvbHVtbnMubGVuZ3RoKTsKKyAgICAgIGZvciAoYnl0ZVtdIGNvbCA6IGFkZGl0aW9uYWxDb2x1bW5zKSB7CisgICAgICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgY29sKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgb3V0LndyaXRlSW50KDApOworICAgIH0KKyAgICBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKyAgICBPYmplY3RXcml0YWJsZQorICAgICAgICAud3JpdGVPYmplY3Qob3V0LCBrZXlHZW5lcmF0b3IsIEluZGV4S2V5R2VuZXJhdG9yLmNsYXNzLCBjb25mKTsKKyAgfQorCisgIC8qKiB7QGluaGVyaXREb2N9ICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIHNiLmFwcGVuZCgiSUQgPT4gIik7CisgICAgc2IuYXBwZW5kKGluZGV4SWQpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisgIAorICAKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90YWJsZWluZGV4ZWQvSW5kZXhlZFRhYmxlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4ZWRUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjZmEwZmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4ZWRUYWJsZS5qYXZhCkBAIC0wLDAgKzEsMjI0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU3RvcmVLZXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQudHJhbnNhY3Rpb25hbC5UcmFuc2FjdGlvbmFsVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlTWFwV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKiBIVGFibGUgZXh0ZW5kZWQgd2l0aCBpbmRleGVkIHN1cHBvcnQuICovCitwdWJsaWMgY2xhc3MgSW5kZXhlZFRhYmxlIGV4dGVuZHMgVHJhbnNhY3Rpb25hbFRhYmxlIHsKKworICAvLyBGSVhNRSwgdGhlc2UgYmVsb25nIGVsc2V3aGVyZQorICBzdGF0aWMgZmluYWwgYnl0ZVtdIElOREVYX0NPTF9GQU1JTFlfTkFNRSA9IEJ5dGVzLnRvQnl0ZXMoIl9fSU5ERVhfXyIpOworICBzdGF0aWMgZmluYWwgYnl0ZVtdIElOREVYX0NPTF9GQU1JTFkgPSBCeXRlcy5hZGQoCisgICAgICBJTkRFWF9DT0xfRkFNSUxZX05BTUUsIG5ldyBieXRlW10geyBIU3RvcmVLZXkuQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVIgfSk7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIElOREVYX0JBU0VfUk9XX0NPTFVNTiA9IEJ5dGVzLmFkZCgKKyAgICAgIElOREVYX0NPTF9GQU1JTFksIEJ5dGVzLnRvQnl0ZXMoIlJPVyIpKTsKKworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEluZGV4ZWRUYWJsZS5jbGFzcyk7CisKKyAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBIVGFibGU+IGluZGV4SWRUb1RhYmxlID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBIVGFibGU+KCk7CisKKyAgcHVibGljIEluZGV4ZWRUYWJsZShmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgZmluYWwgYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIoY29uZiwgdGFibGVOYW1lKTsKKworICAgIGZvciAoSW5kZXhTcGVjaWZpY2F0aW9uIHNwZWMgOiBzdXBlci5nZXRUYWJsZURlc2NyaXB0b3IoKS5nZXRJbmRleGVzKCkpIHsKKyAgICAgIGluZGV4SWRUb1RhYmxlLnB1dChzcGVjLmdldEluZGV4SWQoKSwgbmV3IEhUYWJsZShjb25mLCBzcGVjCisgICAgICAgICAgLmdldEluZGV4ZWRUYWJsZU5hbWUodGFibGVOYW1lKSkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBPcGVuIHVwIGFuIGluZGV4ZWQgc2Nhbm5lci4gUmVzdWx0cyB3aWxsIGNvbWUgYmFjayBpbiB0aGUgaW5kZXhlZCBvcmRlciwKKyAgICogYnV0IHdpbGwgY29udGFpbiBSb3dSZXN1bHRzIGZyb20gdGhlIG9yaWdpbmFsIHRhYmxlLgorICAgKiAKKyAgICogQHBhcmFtIGluZGV4SWQgdGhlIGlkIG9mIHRoZSBpbmRleCB0byB1c2UKKyAgICogQHBhcmFtIGluZGV4U3RhcnRSb3cgKGNyZWF0ZWQgZnJvbSB0aGUgSW5kZXhLZXlHZW5lcmF0b3IpCisgICAqIEBwYXJhbSBpbmRleENvbHVtbnMgaW4gdGhlIGluZGV4IHRhYmxlCisgICAqIEBwYXJhbSBpbmRleEZpbHRlciBmaWx0ZXIgdG8gcnVuIG9uIHRoZSBpbmRleCdlZCB0YWJsZS4gVGhpcyBjYW4gb25seSB1c2UKKyAgICogY29sdW1ucyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgaW5kZXguCisgICAqIEBwYXJhbSBiYXNlQ29sdW1ucyBmcm9tIHRoZSBvcmlnaW5hbCB0YWJsZQorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAdGhyb3dzIEluZGV4Tm90Rm91bmRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldEluZGV4ZWRTY2FubmVyKFN0cmluZyBpbmRleElkLCBmaW5hbCBieXRlW10gaW5kZXhTdGFydFJvdywKKyAgICAgIGJ5dGVbXVtdIGluZGV4Q29sdW1ucywgZmluYWwgUm93RmlsdGVySW50ZXJmYWNlIGluZGV4RmlsdGVyLAorICAgICAgZmluYWwgYnl0ZVtdW10gYmFzZUNvbHVtbnMpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW5kZXhOb3RGb3VuZEV4Y2VwdGlvbiB7CisgICAgSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4U3BlYyA9IHN1cGVyLmdldFRhYmxlRGVzY3JpcHRvcigpLmdldEluZGV4KGluZGV4SWQpOworICAgIGlmIChpbmRleFNwZWMgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IEluZGV4Tm90Rm91bmRFeGNlcHRpb24oIkluZGV4ICIgKyBpbmRleElkCisgICAgICAgICAgKyAiIG5vdCBkZWZpbmVkIGluIHRhYmxlICIKKyAgICAgICAgICArIHN1cGVyLmdldFRhYmxlRGVzY3JpcHRvcigpLmdldE5hbWVBc1N0cmluZygpKTsKKyAgICB9CisgICAgdmVyaWZ5SW5kZXhDb2x1bW5zKGluZGV4Q29sdW1ucywgaW5kZXhTcGVjKTsKKyAgICAvLyBUT0RPLCB2ZXJpZnkvcmVtb3ZlIGluZGV4IGNvbHVtbnMgZnJvbSBiYXNlQ29sdW1ucworCisgICAgSFRhYmxlIGluZGV4VGFibGUgPSBpbmRleElkVG9UYWJsZS5nZXQoaW5kZXhJZCk7CisKKyAgICBieXRlW11bXSBhbGxJbmRleENvbHVtbnM7CisgICAgaWYgKGluZGV4Q29sdW1ucyAhPSBudWxsKSB7CisgICAgICBhbGxJbmRleENvbHVtbnMgPSBuZXcgYnl0ZVtpbmRleENvbHVtbnMubGVuZ3RoICsgMV1bXTsKKyAgICAgIFN5c3RlbQorICAgICAgICAgIC5hcnJheWNvcHkoaW5kZXhDb2x1bW5zLCAwLCBhbGxJbmRleENvbHVtbnMsIDAsIGluZGV4Q29sdW1ucy5sZW5ndGgpOworICAgICAgYWxsSW5kZXhDb2x1bW5zW2luZGV4Q29sdW1ucy5sZW5ndGhdID0gSU5ERVhfQkFTRV9ST1dfQ09MVU1OOworICAgIH0gZWxzZSB7CisgICAgICBieXRlW11bXSBhbGxDb2x1bW5zID0gaW5kZXhTcGVjLmdldEFsbENvbHVtbnMoKTsKKyAgICAgIGFsbEluZGV4Q29sdW1ucyA9IG5ldyBieXRlW2FsbENvbHVtbnMubGVuZ3RoICsgMV1bXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYWxsQ29sdW1ucywgMCwgYWxsSW5kZXhDb2x1bW5zLCAwLCBhbGxDb2x1bW5zLmxlbmd0aCk7CisgICAgICBhbGxJbmRleENvbHVtbnNbYWxsQ29sdW1ucy5sZW5ndGhdID0gSU5ERVhfQkFTRV9ST1dfQ09MVU1OOworICAgIH0KKworICAgIFNjYW5uZXIgaW5kZXhTY2FubmVyID0gaW5kZXhUYWJsZS5nZXRTY2FubmVyKGFsbEluZGV4Q29sdW1ucywKKyAgICAgICAgaW5kZXhTdGFydFJvdywgaW5kZXhGaWx0ZXIpOworCisgICAgcmV0dXJuIG5ldyBTY2FubmVyV3JhcHBlcihpbmRleFNjYW5uZXIsIGJhc2VDb2x1bW5zKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB2ZXJpZnlJbmRleENvbHVtbnMoYnl0ZVtdW10gcmVxdWVzdGVkQ29sdW1ucywKKyAgICAgIEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMpIHsKKyAgICBpZiAocmVxdWVzdGVkQ29sdW1ucyA9PSBudWxsKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGZvciAoYnl0ZVtdIHJlcXVlc3RlZENvbHVtbiA6IHJlcXVlc3RlZENvbHVtbnMpIHsKKyAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgIGZvciAoYnl0ZVtdIGluZGV4Q29sdW1uIDogaW5kZXhTcGVjLmdldEFsbENvbHVtbnMoKSkgeworICAgICAgICBpZiAoQnl0ZXMuZXF1YWxzKHJlcXVlc3RlZENvbHVtbiwgaW5kZXhDb2x1bW4pKSB7CisgICAgICAgICAgZm91bmQgPSB0cnVlOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoIWZvdW5kKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDb2x1bW4gWyIgKyBCeXRlcy50b1N0cmluZyhyZXF1ZXN0ZWRDb2x1bW4pCisgICAgICAgICAgICArICJdIG5vdCBpbiBpbmRleCAiICsgaW5kZXhTcGVjLmdldEluZGV4SWQoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBTY2FubmVyV3JhcHBlciBpbXBsZW1lbnRzIFNjYW5uZXIgeworCisgICAgcHJpdmF0ZSBTY2FubmVyIGluZGV4U2Nhbm5lcjsKKyAgICBwcml2YXRlIGJ5dGVbXVtdIGNvbHVtbnM7CisKKyAgICBwdWJsaWMgU2Nhbm5lcldyYXBwZXIoU2Nhbm5lciBpbmRleFNjYW5uZXIsIGJ5dGVbXVtdIGNvbHVtbnMpIHsKKyAgICAgIHRoaXMuaW5kZXhTY2FubmVyID0gaW5kZXhTY2FubmVyOworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIHB1YmxpYyBSb3dSZXN1bHQgbmV4dCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIFJvd1Jlc3VsdFtdIHJlc3VsdCA9IG5leHQoMSk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQubGVuZ3RoIDwgMSkKKyAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgcmV0dXJuIHJlc3VsdFswXTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIHB1YmxpYyBSb3dSZXN1bHRbXSBuZXh0KGludCBuYlJvd3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBSb3dSZXN1bHRbXSBpbmRleFJlc3VsdCA9IGluZGV4U2Nhbm5lci5uZXh0KG5iUm93cyk7CisgICAgICBpZiAoaW5kZXhSZXN1bHQgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIFJvd1Jlc3VsdFtdIHJlc3VsdCA9IG5ldyBSb3dSZXN1bHRbaW5kZXhSZXN1bHQubGVuZ3RoXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kZXhSZXN1bHQubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgUm93UmVzdWx0IHJvdyA9IGluZGV4UmVzdWx0W2ldOworICAgICAgICBieXRlW10gYmFzZVJvdyA9IHJvdy5nZXQoSU5ERVhfQkFTRV9ST1dfQ09MVU1OKS5nZXRWYWx1ZSgpOworICAgICAgICBMT0cuZGVidWcoIm5leHQgaW5kZXggcm93IFsiICsgQnl0ZXMudG9TdHJpbmcocm93LmdldFJvdygpKQorICAgICAgICAgICAgKyAiXSAtPiBiYXNlIHJvdyBbIiArIEJ5dGVzLnRvU3RyaW5nKGJhc2VSb3cpICsgIl0iKTsKKyAgICAgICAgSGJhc2VNYXBXcml0YWJsZTxieXRlW10sIENlbGw+IGNvbFZhbHVlcyA9CisgICAgICAgICAgbmV3IEhiYXNlTWFwV3JpdGFibGU8Ynl0ZVtdLCBDZWxsPigpOworICAgICAgICBpZiAoY29sdW1ucyAhPSBudWxsICYmIGNvbHVtbnMubGVuZ3RoID4gMCkgeworICAgICAgICAgIExPRy5kZWJ1ZygiR29pbmcgdG8gYmFzZSB0YWJsZSBmb3IgcmVtYWluaW5nIGNvbHVtbnMiKTsKKyAgICAgICAgICBSb3dSZXN1bHQgYmFzZVJlc3VsdCA9IEluZGV4ZWRUYWJsZS50aGlzLmdldFJvdyhiYXNlUm93LCBjb2x1bW5zKTsKKyAgICAgICAgICAKKyAgICAgICAgICBpZiAoYmFzZVJlc3VsdCAhPSBudWxsKSB7CisgICAgICAgICAgICBjb2xWYWx1ZXMucHV0QWxsKGJhc2VSZXN1bHQpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBmb3IgKEVudHJ5PGJ5dGVbXSwgQ2VsbD4gZW50cnkgOiByb3cuZW50cnlTZXQoKSkgeworICAgICAgICAgIGJ5dGVbXSBjb2wgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgICBpZiAoSFN0b3JlS2V5Lm1hdGNoaW5nRmFtaWx5KElOREVYX0NPTF9GQU1JTFlfTkFNRSwgY29sKSkgeworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgfQorICAgICAgICAgIGNvbFZhbHVlcy5wdXQoY29sLCBlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHRbaV0gPSBuZXcgUm93UmVzdWx0KGJhc2VSb3csIGNvbFZhbHVlcyk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8qKiB7QGluaGVyaXREb2N9ICovCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICBpbmRleFNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKioge0Bpbmhlcml0RG9jfSAqLworICAgIHB1YmxpYyBJdGVyYXRvcjxSb3dSZXN1bHQ+IGl0ZXJhdG9yKCkgeworICAgICAgLy8gRklYTUUsIGNvcGllZCBmcm9tIEhUYWJsZS5DbGllbnRTY2FubmVyLiBFeHRyYWN0IHRoaXMgdG8gY29tbW9uIGJhc2UKKyAgICAgIC8vIGNsYXNzPworICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxSb3dSZXN1bHQ+KCkgeworICAgICAgICBSb3dSZXN1bHQgbmV4dCA9IG51bGw7CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgICAgICBpZiAobmV4dCA9PSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBuZXh0ID0gU2Nhbm5lcldyYXBwZXIudGhpcy5uZXh0KCk7CisgICAgICAgICAgICAgIHJldHVybiBuZXh0ICE9IG51bGw7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBSb3dSZXN1bHQgbmV4dCgpIHsKKyAgICAgICAgICBpZiAoIWhhc05leHQoKSkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICAgIFJvd1Jlc3VsdCB0ZW1wID0gbmV4dDsKKyAgICAgICAgICBuZXh0ID0gbnVsbDsKKyAgICAgICAgICByZXR1cm4gdGVtcDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKKyAgICAgICAgfQorICAgICAgfTsKKyAgICB9CisKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleGVkVGFibGVBZG1pbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9JbmRleGVkVGFibGVBZG1pbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljNzUzYzgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL0luZGV4ZWRUYWJsZUFkbWluLmphdmEKQEAgLTAsMCArMSw5NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Db2x1bW5OYW1lUGFyc2VFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTdG9yZUtleTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVGFibGVFeGlzdHNFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBFeHRlbnNpb24gb2YgSEJhc2VBZG1pbiB0aGF0IGNyZWF0ZXMgaW5kZXhlZCB0YWJsZXMuCisgKiAKKyAqLworcHVibGljIGNsYXNzIEluZGV4ZWRUYWJsZUFkbWluIGV4dGVuZHMgSEJhc2VBZG1pbiB7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIAorICAgKiBAcGFyYW0gY29uZiBDb25maWd1cmF0aW9uIG9iamVjdAorICAgKiBAdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBJbmRleGVkVGFibGVBZG1pbihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikKKyAgICAgIHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIHsKKyAgICBzdXBlcihjb25mKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEgbmV3IHRhYmxlCisgICAqIAorICAgKiBAcGFyYW0gZGVzYyB0YWJsZSBkZXNjcmlwdG9yIGZvciB0YWJsZQorICAgKiAKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHRhYmxlIG5hbWUgaXMgcmVzZXJ2ZWQKKyAgICogQHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIGlmIG1hc3RlciBpcyBub3QgcnVubmluZworICAgKiBAdGhyb3dzIFRhYmxlRXhpc3RzRXhjZXB0aW9uIGlmIHRhYmxlIGFscmVhZHkgZXhpc3RzIChJZiBjb25jdXJyZW50CisgICAqIHRocmVhZHMsIHRoZSB0YWJsZSBtYXkgaGF2ZSBiZWVuIGNyZWF0ZWQgYmV0d2VlbiB0ZXN0LWZvci1leGlzdGVuY2UgYW5kCisgICAqIGF0dGVtcHQtYXQtY3JlYXRpb24pLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgY3JlYXRlVGFibGUoSFRhYmxlRGVzY3JpcHRvciBkZXNjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIHRoaXMuY3JlYXRlSW5kZXhUYWJsZXMoZGVzYyk7CisgIH0KKworICBwcml2YXRlIHZvaWQgY3JlYXRlSW5kZXhUYWJsZXMoSFRhYmxlRGVzY3JpcHRvciB0YWJsZURlc2MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGJhc2VUYWJsZU5hbWUgPSB0YWJsZURlc2MuZ2V0TmFtZSgpOworICAgIGZvciAoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4U3BlYyA6IHRhYmxlRGVzYy5nZXRJbmRleGVzKCkpIHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaW5kZXhUYWJsZURlc2MgPSBjcmVhdGVJbmRleFRhYmxlRGVzYyhiYXNlVGFibGVOYW1lLAorICAgICAgICAgIGluZGV4U3BlYyk7CisgICAgICBzdXBlci5jcmVhdGVUYWJsZShpbmRleFRhYmxlRGVzYyk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBIVGFibGVEZXNjcmlwdG9yIGNyZWF0ZUluZGV4VGFibGVEZXNjKGJ5dGVbXSBiYXNlVGFibGVOYW1lLAorICAgICAgSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4U3BlYykgdGhyb3dzIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbiB7CisgICAgSFRhYmxlRGVzY3JpcHRvciBpbmRleFRhYmxlRGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKGluZGV4U3BlYworICAgICAgICAuZ2V0SW5kZXhlZFRhYmxlTmFtZShiYXNlVGFibGVOYW1lKSk7CisgICAgU2V0PGJ5dGVbXT4gZmFtaWxpZXMgPSBuZXcgVHJlZVNldDxieXRlW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgIGZhbWlsaWVzLmFkZChJbmRleGVkVGFibGUuSU5ERVhfQ09MX0ZBTUlMWSk7CisgICAgZm9yIChieXRlW10gY29sdW1uIDogaW5kZXhTcGVjLmdldEFsbENvbHVtbnMoKSkgeworICAgICAgZmFtaWxpZXMuYWRkKEJ5dGVzLmFkZChIU3RvcmVLZXkuZ2V0RmFtaWx5KGNvbHVtbiksCisgICAgICAgICAgbmV3IGJ5dGVbXSB7IEhTdG9yZUtleS5DT0xVTU5fRkFNSUxZX0RFTElNSVRFUiB9KSk7CisgICAgfQorCisgICAgZm9yIChieXRlW10gY29sRmFtaWx5IDogZmFtaWxpZXMpIHsKKyAgICAgIGluZGV4VGFibGVEZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoY29sRmFtaWx5KSk7CisgICAgfQorCisgICAgcmV0dXJuIGluZGV4VGFibGVEZXNjOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1JldmVyc2VCeXRlQXJyYXlDb21wYXJhdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1JldmVyc2VCeXRlQXJyYXlDb21wYXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFmN2I4MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90YWJsZWluZGV4ZWQvUmV2ZXJzZUJ5dGVBcnJheUNvbXBhcmF0b3IuamF2YQpAQCAtMCwwICsxLDQ2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuV3JpdGFibGVDb21wYXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK3B1YmxpYyBjbGFzcyBSZXZlcnNlQnl0ZUFycmF5Q29tcGFyYXRvciBpbXBsZW1lbnRzIFdyaXRhYmxlQ29tcGFyYXRvcjxieXRlW10+IHsKKworICAvKioge0Bpbmhlcml0RG9jfSAqLworICBwdWJsaWMgaW50IGNvbXBhcmUoYnl0ZVtdIG8xLCBieXRlW10gbzIpIHsKKyAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKG8yLCBvMSk7CisgIH0KKworICAKKyAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgYXJnMCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBOb3RoaW5nCisgIH0KKworICAvKioge0Bpbmhlcml0RG9jfSAqLworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IGFyZzApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gTm90aGluZworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1NpbXBsZUluZGV4S2V5R2VuZXJhdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1NpbXBsZUluZGV4S2V5R2VuZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDk2OTQxNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90YWJsZWluZGV4ZWQvU2ltcGxlSW5kZXhLZXlHZW5lcmF0b3IuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKiogQ3JlYXRlcyBpbmRleGVkIGtleXMgZm9yIGEgc2luZ2xlIGNvbHVtbi4uLi4KKyAqIAorICovCitwdWJsaWMgY2xhc3MgU2ltcGxlSW5kZXhLZXlHZW5lcmF0b3IgaW1wbGVtZW50cyBJbmRleEtleUdlbmVyYXRvciB7CisKKyAgcHJpdmF0ZSBieXRlIFtdIGNvbHVtbjsKKyAgCisgIHB1YmxpYyBTaW1wbGVJbmRleEtleUdlbmVyYXRvcihieXRlIFtdIGNvbHVtbikgeworICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICB9CisgIAorICBwdWJsaWMgU2ltcGxlSW5kZXhLZXlHZW5lcmF0b3IoKSB7CisgICAgLy8gRm9yIFdyaXRhYmxlCisgIH0KKyAgCisgIC8qKiB7QGluaGVyaXREb2N9ICovCisgIHB1YmxpYyBieXRlW10gY3JlYXRlSW5kZXhLZXkoYnl0ZVtdIHJvd0tleSwgTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjb2x1bW5zKSB7CisgICAgcmV0dXJuIEJ5dGVzLmFkZChjb2x1bW5zLmdldChjb2x1bW4pLCByb3dLZXkpOworICB9CisKKyAgLyoqIHtAaW5oZXJpdERvY30gKi8KKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29sdW1uID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgIH0KKworICAvKioge0Bpbmhlcml0RG9jfSAqLworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGNvbHVtbik7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9wYWNrYWdlLmh0bWwgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjIxNGY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RhYmxlaW5kZXhlZC9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSw0NiBAQAorPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgorPGh0bWw+CisKKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPGhlYWQgLz4KKzxib2R5IGJnY29sb3I9IndoaXRlIj4KKworVGhpcyBwYWNrYWdlIHByb3ZpZGVzIHN1cHBvcnQgZm9yIHNlY29uZGFyeSBpbmRleGluZyBieSBtYWludGFpbmluZyBhIHNlcGFyYXRlLCAiaW5kZXgiLCB0YWJsZSBmb3IgZWFjaCBpbmRleC4gCisKK1RoZSBJbmRleFNwZWNpZmljYXRpb24gY2xhc3MgcHJvdmlkZXMgdGhlIG1ldGFkYXRhIGZvciB0aGUgaW5kZXguIFRoaXMgaW5jbHVkZXM6Cis8bGk+IHRoZSBjb2x1bW5zIHRoYXQgY29udHJpYnV0ZSB0byB0aGUgaW5kZXgga2V5LAorPGxpPiBhZGRpdGlvbmFsIGNvbHVtbnMgdG8gcHV0IGluIHRoZSBpbmRleCB0YWJsZSAoYW5kIGFyZSB0aHVzIG1hZGUgYXZhaWxhYmxlIHRvIGZpbHRlcnMgb24gdGhlIGluZGV4IHRhYmxlKSwKKzxicj4gYW5kIAorPGxpPiBhbiBJbmRleEtleUdlbmVyYXRvciB3aGljaCBjb25zdHJ1Y3RzIHRoZSBpbmRleC1yb3cta2V5IGZyb20gdGhlIGluZGV4ZWQgY29sdW1uKHMpIGFuZCB0aGUgb3JpZ2luYWwgcm93LgorCitJbmRleGVzU3BlY2lmaWNhdGlvbnMgY2FuIGJlIGFkZGVkIHRvIGEgdGFibGUncyBtZXRhZGF0YSAoSFRhYmxlRGVzY3JpcHRvcikgYmVmb3JlIHRoZSB0YWJsZSBpcyBjb25zdHJ1Y3RlZC4gCitBZnRlcndhcmRzLCB1cGRhdGVzIGFuZCBkZWxldGVzIHRvIHRoZSBvcmlnaW5hbCB0YWJsZSB3aWxsIHRyaWdnZXIgdGhlIHVwZGF0ZXMgaW4gdGhlIGluZGV4LCBhbmQgCit0aGUgaW5kZXhlcyBjYW4gYmUgc2Nhbm5lZCB1c2luZyB0aGUgQVBJIG9uIEluZGV4ZWRUYWJsZS4KKworRm9yIGEgc2ltcGxlIGV4YW1wbGUsIGxvb2sgYXQgdGhlIHVuaXQgdGVzdCBpbiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQudGFibGVJbmRleGVkLgorCis8cD4gVG8gZW5hYmxlIHRoZSBpbmRleGluZywgbW9kaWZ5IGhiYXNlLXNpdGUueG1sIHRvIHR1cm4gb24gdGhlCitJbmRleGVkUmVnaW9uU2VydmVyLiAgVGhpcyBpcyBkb25lIGJ5IHNldHRpbmcKKzxpPmhiYXNlLnJlZ2lvbnNlcnZlci5jbGFzczwvaT4gdG8KKzxpPm9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5JbmRleGVkUmVnaW9uSW50ZXJmYWNlPC9pPiBhbmQKKzxpPmhiYXNlLnJlZ2lvbnNlcnZlci5pbXBsIDwvaT4gdG8KKzxpPm9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50YWJsZWluZGV4ZWQuSW5kZXhlZFJlZ2lvblNlcnZlcjwvaT4KKyAKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL0NvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzY1NzM2MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL0NvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQudHJhbnNhY3Rpb25hbDsKKworLyoqIFRocm93biB3aGVuIGEgdHJhbnNhY3Rpb24gY2Fubm90IGJlIGNvbW1pdHRlZC4gCisgKiAKKyAqLworcHVibGljIGNsYXNzIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNzA2MjkyMTQ0NDUzMTEwOTIwMkw7CisKKyAgLyoqIERlZmF1bHQgQ29uc3RydWN0b3IgKi8KKyAgcHVibGljIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhcmcwIG1lc3NhZ2UKKyAgICogQHBhcmFtIGFyZzEgY2F1c2UKKyAgICovCisgIHB1YmxpYyBDb21taXRVbnN1Y2Nlc3NmdWxFeGNlcHRpb24oU3RyaW5nIGFyZzAsIFRocm93YWJsZSBhcmcxKSB7CisgICAgc3VwZXIoYXJnMCwgYXJnMSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGFyZzAgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbihTdHJpbmcgYXJnMCkgeworICAgIHN1cGVyKGFyZzApOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhcmcwIGNhdXNlCisgICAqLworICBwdWJsaWMgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uKFRocm93YWJsZSBhcmcwKSB7CisgICAgc3VwZXIoYXJnMCk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvTG9jYWxUcmFuc2FjdGlvbkxvZ2dlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvTG9jYWxUcmFuc2FjdGlvbkxvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3MzgzMTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9Mb2NhbFRyYW5zYWN0aW9uTG9nZ2VyLmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworLyoqCisgKiBBIGxvY2FsLCBpbi1tZW1vcnkgaW1wbGVtZW50YXRpb24gb2YgdGhlIHRyYW5zYWN0aW9uIGxvZ2dlci4gRG9lcyBub3QgcHJvdmlkZSBhIGdsb2JhbCB2aWV3LCBzbyAKKyAqIGl0IGNhbid0IGJlIHJlbGlnaGVkIG9uIGJ5IAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBMb2NhbFRyYW5zYWN0aW9uTG9nZ2VyIGltcGxlbWVudHMgVHJhbnNhY3Rpb25Mb2dnZXIgeworCisgIHByaXZhdGUgc3RhdGljIExvY2FsVHJhbnNhY3Rpb25Mb2dnZXIgaW5zdGFuY2U7CisgIAorICAvKioKKyAgICogQ3JlYXRlcyBzaW5nbGV0b24gaWYgaXQgZG9lcyBub3QgZXhpc3QKKyAgICogCisgICAqIEByZXR1cm4gcmVmZXJlbmNlIHRvIHNpbmdsZXRvbgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBzdGF0aWMgTG9jYWxUcmFuc2FjdGlvbkxvZ2dlciBnZXRJbnN0YW5jZSgpIHsKKyAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkgeworICAgICAgaW5zdGFuY2UgPSBuZXcgTG9jYWxUcmFuc2FjdGlvbkxvZ2dlcigpOworICAgIH0KKyAgICByZXR1cm4gaW5zdGFuY2U7CisgIH0KKyAgCisgIHByaXZhdGUgUmFuZG9tIHJhbmRvbSA9IG5ldyBSYW5kb20oKTsKKyAgcHJpdmF0ZSBNYXA8TG9uZywgVHJhbnNhY3Rpb25TdGF0dXM+IHRyYW5zYWN0aW9uSWRUb1N0YXR1c01hcCA9IENvbGxlY3Rpb25zCisgICAgICAuc3luY2hyb25pemVkTWFwKG5ldyBIYXNoTWFwPExvbmcsIFRyYW5zYWN0aW9uU3RhdHVzPigpKTsKKworICBwcml2YXRlIExvY2FsVHJhbnNhY3Rpb25Mb2dnZXIoKSB7CisgICAgLy8gRW5mb3JjZSBzaW5nbHRvbgorICB9CisgIAorICAvKiogQHJldHVybiByYW5kb20gbG9uZ3MgdG8gbWluaW1pemUgcG9zc2liaWxpdHkgb2YgY29sbGlzaW9uICovCisgIHB1YmxpYyBsb25nIGNyZWF0ZU5ld1RyYW5zYWN0aW9uTG9nKCkgeworICAgIGxvbmcgaWQgPSByYW5kb20ubmV4dExvbmcoKTsKKyAgICB0cmFuc2FjdGlvbklkVG9TdGF0dXNNYXAucHV0KGlkLCBUcmFuc2FjdGlvblN0YXR1cy5QRU5ESU5HKTsKKyAgICByZXR1cm4gaWQ7CisgIH0KKworICBwdWJsaWMgVHJhbnNhY3Rpb25TdGF0dXMgZ2V0U3RhdHVzRm9yVHJhbnNhY3Rpb24oZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkKSB7CisgICAgcmV0dXJuIHRyYW5zYWN0aW9uSWRUb1N0YXR1c01hcC5nZXQodHJhbnNhY3Rpb25JZCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRTdGF0dXNGb3JUcmFuc2FjdGlvbihmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsCisgICAgICBmaW5hbCBUcmFuc2FjdGlvblN0YXR1cyBzdGF0dXMpIHsKKyAgICB0cmFuc2FjdGlvbklkVG9TdGF0dXNNYXAucHV0KHRyYW5zYWN0aW9uSWQsIHN0YXR1cyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uTG9nZ2VyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbkxvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlYTMyMWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbkxvZ2dlci5qYXZhCkBAIC0wLDAgKzEsNTkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQudHJhbnNhY3Rpb25hbDsKKworLyoqCisgKiBTaW1wbGUgaW50ZXJmYWNlIHVzZWQgdG8gcHJvdmlkZSBhIGxvZyBhYm91dCB0cmFuc2FjdGlvbiBzdGF0dXMuIFdyaXR0ZW4gdG8KKyAqIGJ5IHRoZSBjbGllbnQsIGFuZCByZWFkIGJ5IHJlZ2lvbnNlcnZlcnMgaW4gY2FzZSBvZiBmYWlsdXJlLiAKKyAqIAorICovCitwdWJsaWMgaW50ZXJmYWNlIFRyYW5zYWN0aW9uTG9nZ2VyIHsKKworICAvKiogVHJhbnNhY3Rpb24gc3RhdHVzIHZhbHVlcyAqLworICBlbnVtIFRyYW5zYWN0aW9uU3RhdHVzIHsKKyAgICAvKiogVHJhbnNhY3Rpb24gaXMgcGVuZGluZyAqLworICAgIFBFTkRJTkcsCisgICAgLyoqIFRyYW5zYWN0aW9uIHdhcyBjb21taXR0ZWQgKi8KKyAgICBDT01NSVRURUQsCisgICAgLyoqIFRyYW5zYWN0aW9uIHdhcyBhYm9ydGVkICovCisgICAgQUJPUlRFRAorICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyB0cmFuc2FjdGlvbiBsb2cuIFJldHVybiB0aGUgdHJhbnNhY3Rpb24ncyBnbG9iYWxseSB1bmlxdWUgaWQuCisgICAqIExvZydzIGluaXRpYWwgdmFsdWUgc2hvdWxkIGJlIFBFTkRJTkcKKyAgICogCisgICAqIEByZXR1cm4gdHJhbnNhY3Rpb24gaWQKKyAgICovCisgIGxvbmcgY3JlYXRlTmV3VHJhbnNhY3Rpb25Mb2coKTsKKworICAvKioKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHJldHVybiB0cmFuc2FjdGlvbiBzdGF0dXMKKyAgICovCisgIFRyYW5zYWN0aW9uU3RhdHVzIGdldFN0YXR1c0ZvclRyYW5zYWN0aW9uKGxvbmcgdHJhbnNhY3Rpb25JZCk7CisKKyAgLyoqCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkCisgICAqIEBwYXJhbSBzdGF0dXMKKyAgICovCisgIHZvaWQgc2V0U3RhdHVzRm9yVHJhbnNhY3Rpb24obG9uZyB0cmFuc2FjdGlvbklkLCBUcmFuc2FjdGlvblN0YXR1cyBzdGF0dXMpOworCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbk1hbmFnZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2NmU1MDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbk1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDE1MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uTG9jYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhDb25uZWN0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQ29ubmVjdGlvbk1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLlRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbjsKKworLyoqCisgKiBUcmFuc2FjdGlvbiBNYW5hZ2VyLiBSZXNwb25zaWJsZSBmb3IgY29tbWl0dGluZyB0cmFuc2FjdGlvbnMuCisgKiAKKyAqLworcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uTWFuYWdlciB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVHJhbnNhY3Rpb25NYW5hZ2VyLmNsYXNzKTsKKworICBwcml2YXRlIGZpbmFsIEhDb25uZWN0aW9uIGNvbm5lY3Rpb247CisgIHByaXZhdGUgZmluYWwgVHJhbnNhY3Rpb25Mb2dnZXIgdHJhbnNhY3Rpb25Mb2dnZXI7CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqLworICBwdWJsaWMgVHJhbnNhY3Rpb25NYW5hZ2VyKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgdGhpcyhMb2NhbFRyYW5zYWN0aW9uTG9nZ2VyLmdldEluc3RhbmNlKCksIGNvbmYpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbkxvZ2dlcgorICAgKiBAcGFyYW0gY29uZgorICAgKi8KKyAgcHVibGljIFRyYW5zYWN0aW9uTWFuYWdlcihmaW5hbCBUcmFuc2FjdGlvbkxvZ2dlciB0cmFuc2FjdGlvbkxvZ2dlciwKKyAgICAgIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgdGhpcy50cmFuc2FjdGlvbkxvZ2dlciA9IHRyYW5zYWN0aW9uTG9nZ2VyOworICAgIGNvbm5lY3Rpb24gPSBIQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxsZWQgdG8gc3RhcnQgYSB0cmFuc2FjdGlvbi4KKyAgICogCisgICAqIEByZXR1cm4gbmV3IHRyYW5zYWN0aW9uIHN0YXRlCisgICAqLworICBwdWJsaWMgVHJhbnNhY3Rpb25TdGF0ZSBiZWdpblRyYW5zYWN0aW9uKCkgeworICAgIGxvbmcgdHJhbnNhY3Rpb25JZCA9IHRyYW5zYWN0aW9uTG9nZ2VyLmNyZWF0ZU5ld1RyYW5zYWN0aW9uTG9nKCk7CisgICAgTE9HLmRlYnVnKCJCZWdpbmluZyB0cmFuc2FjdGlvbiAiICsgdHJhbnNhY3Rpb25JZCk7CisgICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvblN0YXRlKHRyYW5zYWN0aW9uSWQpOworICB9CisKKyAgLyoqCisgICAqIFRyeSBhbmQgY29tbWl0IGEgdHJhbnNhY3Rpb24uCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEB0aHJvd3MgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0cnlDb21taXQoZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlKQorICAgICAgdGhyb3dzIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgIExPRy5kZWJ1ZygiYXRlbXB0aW5nIHRvIGNvbW1pdCB0cmFzYWN0aW9uOiAiICsgdHJhbnNhY3Rpb25TdGF0ZS50b1N0cmluZygpKTsKKworICAgIHRyeSB7CisgICAgICBmb3IgKEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvbiA6IHRyYW5zYWN0aW9uU3RhdGUKKyAgICAgICAgICAuZ2V0UGFydGljaXBhdGluZ1JlZ2lvbnMoKSkgeworICAgICAgICBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlIHRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIgPSAoVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZSkgY29ubmVjdGlvbgorICAgICAgICAgICAgLmdldEhSZWdpb25Db25uZWN0aW9uKGxvY2F0aW9uLmdldFNlcnZlckFkZHJlc3MoKSk7CisgICAgICAgIGJvb2xlYW4gY2FuQ29tbWl0ID0gdHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlci5jb21taXRSZXF1ZXN0KGxvY2F0aW9uCisgICAgICAgICAgICAuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgdHJhbnNhY3Rpb25TdGF0ZQorICAgICAgICAgICAgLmdldFRyYW5zYWN0aW9uSWQoKSk7CisgICAgICAgIGlmIChMT0cuaXNUcmFjZUVuYWJsZWQoKSkgeworICAgICAgICAgIExPRy50cmFjZSgiUmVnaW9uIFsiCisgICAgICAgICAgICAgICsgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpICsgIl0gdm90ZXMgIgorICAgICAgICAgICAgICArIChjYW5Db21taXQgPyAidG8gY29tbWl0IiA6ICJ0byBhYm9ydCIpICsgIiB0cmFuc2FjdGlvbiAiCisgICAgICAgICAgICAgICsgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCkpOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFjYW5Db21taXQpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIkFib3J0aW5nIFsiICsgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCkgKyAiXSIpOworICAgICAgICAgIGFib3J0KHRyYW5zYWN0aW9uU3RhdGUsIGxvY2F0aW9uKTsKKyAgICAgICAgICB0aHJvdyBuZXcgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uKCk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgTE9HLmRlYnVnKCJDb21taXRpbmcgWyIgKyB0cmFuc2FjdGlvblN0YXRlLmdldFRyYW5zYWN0aW9uSWQoKSArICJdIik7CisKKyAgICAgIHRyYW5zYWN0aW9uTG9nZ2VyLnNldFN0YXR1c0ZvclRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uU3RhdGUKKyAgICAgICAgICAuZ2V0VHJhbnNhY3Rpb25JZCgpLCBUcmFuc2FjdGlvbkxvZ2dlci5UcmFuc2FjdGlvblN0YXR1cy5DT01NSVRURUQpOworCisgICAgICBmb3IgKEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvbiA6IHRyYW5zYWN0aW9uU3RhdGUKKyAgICAgICAgICAuZ2V0UGFydGljaXBhdGluZ1JlZ2lvbnMoKSkgeworICAgICAgICBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlIHRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIgPSAoVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZSkgY29ubmVjdGlvbgorICAgICAgICAgICAgLmdldEhSZWdpb25Db25uZWN0aW9uKGxvY2F0aW9uLmdldFNlcnZlckFkZHJlc3MoKSk7CisgICAgICAgIHRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuY29tbWl0KGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKQorICAgICAgICAgICAgLmdldFJlZ2lvbk5hbWUoKSwgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKFJlbW90ZUV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZGVidWcoIkNvbW1pdCBvZiB0cmFuc2FjdGlvbiBbIiArIHRyYW5zYWN0aW9uU3RhdGUuZ2V0VHJhbnNhY3Rpb25JZCgpCisgICAgICAgICAgKyAiXSB3YXMgdW5zdWNzZXNzZnVsIiwgZSk7CisgICAgICAvLyBGSVhNRSwgdGhpbmsgYWJvdXQgdGhlIHdoYXQgaWZzCisgICAgICB0aHJvdyBuZXcgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uKGUpOworICAgIH0KKyAgICAvLyBUcmFuIGxvZyBjYW4gYmUgZGVsZXRlZCBub3cgLi4uCisgIH0KKworICAvKioKKyAgICogQWJvcnQgYSBzIHRyYW5zYWN0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uU3RhdGUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYWJvcnQoZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFib3J0KHRyYW5zYWN0aW9uU3RhdGUsIG51bGwpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFib3J0KGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSwKKyAgICAgIGZpbmFsIEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvblRvSWdub3JlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyYW5zYWN0aW9uTG9nZ2VyLnNldFN0YXR1c0ZvclRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uU3RhdGUKKyAgICAgICAgLmdldFRyYW5zYWN0aW9uSWQoKSwgVHJhbnNhY3Rpb25Mb2dnZXIuVHJhbnNhY3Rpb25TdGF0dXMuQUJPUlRFRCk7CisKKyAgICBmb3IgKEhSZWdpb25Mb2NhdGlvbiBsb2NhdGlvbiA6IHRyYW5zYWN0aW9uU3RhdGUuZ2V0UGFydGljaXBhdGluZ1JlZ2lvbnMoKSkgeworICAgICAgaWYgKGxvY2F0aW9uVG9JZ25vcmUgIT0gbnVsbCAmJiBsb2NhdGlvbi5lcXVhbHMobG9jYXRpb25Ub0lnbm9yZSkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UgdHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlciA9IChUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlKSBjb25uZWN0aW9uCisgICAgICAgICAgLmdldEhSZWdpb25Db25uZWN0aW9uKGxvY2F0aW9uLmdldFNlcnZlckFkZHJlc3MoKSk7CisKKyAgICAgIHRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuYWJvcnQobG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwKKyAgICAgICAgICB0cmFuc2FjdGlvblN0YXRlLmdldFRyYW5zYWN0aW9uSWQoKSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvblNjYW5uZXJDYWxsYWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvVHJhbnNhY3Rpb25TY2FubmVyQ2FsbGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODEwNjhmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvVHJhbnNhY3Rpb25TY2FubmVyQ2FsbGFibGUuamF2YQpAQCAtMCwwICsxLDUxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhDb25uZWN0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyQ2FsbGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZTsKKworY2xhc3MgVHJhbnNhY3Rpb25TY2FubmVyQ2FsbGFibGUgZXh0ZW5kcyBTY2FubmVyQ2FsbGFibGUgeworCisgIHByaXZhdGUgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlOworCisgIFRyYW5zYWN0aW9uU2Nhbm5lckNhbGxhYmxlKGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSwKKyAgICAgIGZpbmFsIEhDb25uZWN0aW9uIGNvbm5lY3Rpb24sIGZpbmFsIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBmaW5hbCBieXRlW11bXSBjb2x1bW5zLCBmaW5hbCBieXRlW10gc3RhcnRSb3csIGZpbmFsIGxvbmcgdGltZXN0YW1wLAorICAgICAgZmluYWwgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgeworICAgIHN1cGVyKGNvbm5lY3Rpb24sIHRhYmxlTmFtZSwgY29sdW1ucywgc3RhcnRSb3csIHRpbWVzdGFtcCwgZmlsdGVyKTsKKyAgICB0aGlzLnRyYW5zYWN0aW9uU3RhdGUgPSB0cmFuc2FjdGlvblN0YXRlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBsb25nIG9wZW5TY2FubmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodHJhbnNhY3Rpb25TdGF0ZS5hZGRSZWdpb24obG9jYXRpb24pKSB7CisgICAgICAoKFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UpIHNlcnZlcikuYmVnaW5UcmFuc2FjdGlvbih0cmFuc2FjdGlvblN0YXRlCisgICAgICAgICAgLmdldFRyYW5zYWN0aW9uSWQoKSwgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgfQorICAgIHJldHVybiAoKFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UpIHNlcnZlcikub3BlblNjYW5uZXIodHJhbnNhY3Rpb25TdGF0ZQorICAgICAgICAuZ2V0VHJhbnNhY3Rpb25JZCgpLCB0aGlzLmxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgIGdldENvbHVtbnMoKSwgcm93LCBnZXRUaW1lc3RhbXAoKSwgZ2V0RmlsdGVyKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvblN0YXRlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvblN0YXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGMyZjk4MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uU3RhdGUuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWw7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkxvY2F0aW9uOworCisvKioKKyAqIEhvbGRzIGNsaWVudC1zaWRlIHRyYW5zYWN0aW9uIGluZm9ybWF0aW9uLiBDbGllbnQncyB1c2UgdGhlbSBhcyBvcGFxdWUKKyAqIG9iamVjdHMgcGFzc2VkIGFyb3VuZCB0byB0cmFuc2FjdGlvbiBvcGVyYXRpb25zLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUcmFuc2FjdGlvblN0YXRlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUcmFuc2FjdGlvblN0YXRlLmNsYXNzKTsKKworICBwcml2YXRlIGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZDsKKworICBwcml2YXRlIFNldDxIUmVnaW9uTG9jYXRpb24+IHBhcnRpY2lwYXRpbmdSZWdpb25zID0gbmV3IEhhc2hTZXQ8SFJlZ2lvbkxvY2F0aW9uPigpOworCisgIFRyYW5zYWN0aW9uU3RhdGUoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkKSB7CisgICAgdGhpcy50cmFuc2FjdGlvbklkID0gdHJhbnNhY3Rpb25JZDsKKyAgfQorCisgIGJvb2xlYW4gYWRkUmVnaW9uKGZpbmFsIEhSZWdpb25Mb2NhdGlvbiBocmVnaW9uKSB7CisgICAgYm9vbGVhbiBhZGRlZCA9IHBhcnRpY2lwYXRpbmdSZWdpb25zLmFkZChocmVnaW9uKTsKKworICAgIGlmIChhZGRlZCkgeworICAgICAgTE9HLmRlYnVnKCJBZGRpbmcgbmV3IGhyZWdpb24gWyIKKyAgICAgICAgICArIGhyZWdpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpCisgICAgICAgICAgKyAiXSB0byB0cmFuc2FjdGlvbiBbIiArIHRyYW5zYWN0aW9uSWQgKyAiXSIpOworICAgIH0KKworICAgIHJldHVybiBhZGRlZDsKKyAgfQorCisgIFNldDxIUmVnaW9uTG9jYXRpb24+IGdldFBhcnRpY2lwYXRpbmdSZWdpb25zKCkgeworICAgIHJldHVybiBwYXJ0aWNpcGF0aW5nUmVnaW9uczsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIHRyYW5zYWN0aW9uSWQuCisgICAqIAorICAgKiBAcmV0dXJuIFJldHVybiB0aGUgdHJhbnNhY3Rpb25JZC4KKyAgICovCisgIHB1YmxpYyBsb25nIGdldFRyYW5zYWN0aW9uSWQoKSB7CisgICAgcmV0dXJuIHRyYW5zYWN0aW9uSWQ7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiaWQ6ICIgKyB0cmFuc2FjdGlvbklkICsgIiwgcGFydGljcGFudHM6ICIKKyAgICAgICAgKyBwYXJ0aWNpcGF0aW5nUmVnaW9ucy5zaXplKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uYWxUYWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L3RyYW5zYWN0aW9uYWwvVHJhbnNhY3Rpb25hbFRhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmI1YWFlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uYWxUYWJsZS5qYXZhCkBAIC0wLDAgKzEsNDI4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhDb25uZWN0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXJDYWxsYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2VydmVyQ2FsbGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZTsKKworLyoqCisgKiBUYWJsZSB3aXRoIHRyYW5zYWN0aW9uYWwgc3VwcG9ydC4KKyAqIAorICovCitwdWJsaWMgY2xhc3MgVHJhbnNhY3Rpb25hbFRhYmxlIGV4dGVuZHMgSFRhYmxlIHsKKworICAvKioKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgVHJhbnNhY3Rpb25hbFRhYmxlKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcihjb25mLCB0YWJsZU5hbWUpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFRyYW5zYWN0aW9uYWxUYWJsZShmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwKKyAgICAgIGZpbmFsIGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIoY29uZiwgdGFibGVOYW1lKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIFRyYW5zYWN0aW9uYWxTZXJ2ZXJDYWxsYWJsZTxUPiBleHRlbmRzCisgICAgICBTZXJ2ZXJDYWxsYWJsZTxUPiB7CisgICAgcHJvdGVjdGVkIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZTsKKworICAgIHByb3RlY3RlZCBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlIGdldFRyYW5zYWN0aW9uU2VydmVyKCkgeworICAgICAgcmV0dXJuIChUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlKSBzZXJ2ZXI7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgcmVjb3JkU2VydmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0cmFuc2FjdGlvblN0YXRlLmFkZFJlZ2lvbihsb2NhdGlvbikpIHsKKyAgICAgICAgZ2V0VHJhbnNhY3Rpb25TZXJ2ZXIoKS5iZWdpblRyYW5zYWN0aW9uKAorICAgICAgICAgICAgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCksCisgICAgICAgICAgICBsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gY29ubmVjdGlvbgorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIHRyYW5zYWN0aW9uU3RhdGUKKyAgICAgKi8KKyAgICBwdWJsaWMgVHJhbnNhY3Rpb25hbFNlcnZlckNhbGxhYmxlKGZpbmFsIEhDb25uZWN0aW9uIGNvbm5lY3Rpb24sCisgICAgICAgIGZpbmFsIGJ5dGVbXSB0YWJsZU5hbWUsIGZpbmFsIGJ5dGVbXSByb3csCisgICAgICAgIGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSkgeworICAgICAgc3VwZXIoY29ubmVjdGlvbiwgdGFibGVOYW1lLCByb3cpOworICAgICAgdGhpcy50cmFuc2FjdGlvblN0YXRlID0gdHJhbnNhY3Rpb25TdGF0ZTsKKyAgICB9CisKKyAgfQorCisgIC8qKgorICAgKiBHZXQgYSBzaW5nbGUgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgcm93IGFuZCBjb2x1bW4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvblN0YXRlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAqIEByZXR1cm4gdmFsdWUgZm9yIHNwZWNpZmllZCByb3cvY29sdW1uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsIGdldChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsIGZpbmFsIGJ5dGVbXSByb3csCisgICAgICBmaW5hbCBieXRlW10gY29sdW1uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBzdXBlci5nZXRDb25uZWN0aW9uKCkuZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBUcmFuc2FjdGlvbmFsU2VydmVyQ2FsbGFibGU8Q2VsbD4oc3VwZXIuZ2V0Q29ubmVjdGlvbigpLCBzdXBlcgorICAgICAgICAgICAgLmdldFRhYmxlTmFtZSgpLCByb3csIHRyYW5zYWN0aW9uU3RhdGUpIHsKKyAgICAgICAgICBwdWJsaWMgQ2VsbCBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJlY29yZFNlcnZlcigpOworICAgICAgICAgICAgcmV0dXJuIGdldFRyYW5zYWN0aW9uU2VydmVyKCkuZ2V0KAorICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uU3RhdGUuZ2V0VHJhbnNhY3Rpb25JZCgpLAorICAgICAgICAgICAgICAgIGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgY29sdW1uKTsKKyAgICAgICAgICB9CisgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBvZiB0aGUgc3BlY2lmaWVkIHJvdyBhbmQgY29sdW1uCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIC0gY29sdW1uIG5hbWUKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIC0gbnVtYmVyIG9mIHZlcnNpb25zIHRvIHJldHJpZXZlCisgICAqIEByZXR1cm4gLSBhcnJheSBieXRlIHZhbHVlcworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgQ2VsbFtdIGdldChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsIGZpbmFsIGJ5dGVbXSByb3csCisgICAgICBmaW5hbCBieXRlW10gY29sdW1uLCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQ2VsbFtdIHZhbHVlcyA9IG51bGw7CisgICAgdmFsdWVzID0gc3VwZXIuZ2V0Q29ubmVjdGlvbigpLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKAorICAgICAgICBuZXcgVHJhbnNhY3Rpb25hbFNlcnZlckNhbGxhYmxlPENlbGxbXT4oc3VwZXIuZ2V0Q29ubmVjdGlvbigpLCBzdXBlcgorICAgICAgICAgICAgLmdldFRhYmxlTmFtZSgpLCByb3csIHRyYW5zYWN0aW9uU3RhdGUpIHsKKyAgICAgICAgICBwdWJsaWMgQ2VsbFtdIGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmVjb3JkU2VydmVyKCk7CisgICAgICAgICAgICByZXR1cm4gZ2V0VHJhbnNhY3Rpb25TZXJ2ZXIoKS5nZXQoCisgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCksCisgICAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgcm93LCBjb2x1bW4sCisgICAgICAgICAgICAgICAgbnVtVmVyc2lvbnMpOworICAgICAgICAgIH0KKyAgICAgICAgfSk7CisKKyAgICByZXR1cm4gdmFsdWVzOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBvZiB0aGUgc3BlY2lmaWVkIHJvdyBhbmQgY29sdW1uIHdpdGgKKyAgICogdGhlIHNwZWNpZmllZCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gcm93IC0gcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIC0gY29sdW1uIG5hbWUKKyAgICogQHBhcmFtIHRpbWVzdGFtcCAtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgLSBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0cmlldmUKKyAgICogQHJldHVybiAtIGFycmF5IG9mIHZhbHVlcyB0aGF0IG1hdGNoIHRoZSBhYm92ZSBjcml0ZXJpYQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgQ2VsbFtdIGdldChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsIGZpbmFsIGJ5dGVbXSByb3csCisgICAgICBmaW5hbCBieXRlW10gY29sdW1uLCBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgaW50IG51bVZlcnNpb25zKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDZWxsW10gdmFsdWVzID0gbnVsbDsKKyAgICB2YWx1ZXMgPSBzdXBlci5nZXRDb25uZWN0aW9uKCkuZ2V0UmVnaW9uU2VydmVyV2l0aFJldHJpZXMoCisgICAgICAgIG5ldyBUcmFuc2FjdGlvbmFsU2VydmVyQ2FsbGFibGU8Q2VsbFtdPihzdXBlci5nZXRDb25uZWN0aW9uKCksIHN1cGVyCisgICAgICAgICAgICAuZ2V0VGFibGVOYW1lKCksIHJvdywgdHJhbnNhY3Rpb25TdGF0ZSkgeworICAgICAgICAgIHB1YmxpYyBDZWxsW10gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZWNvcmRTZXJ2ZXIoKTsKKyAgICAgICAgICAgIHJldHVybiBnZXRUcmFuc2FjdGlvblNlcnZlcigpLmdldCgKKyAgICAgICAgICAgICAgICB0cmFuc2FjdGlvblN0YXRlLmdldFRyYW5zYWN0aW9uSWQoKSwKKyAgICAgICAgICAgICAgICBsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpLCByb3csIGNvbHVtbiwKKyAgICAgICAgICAgICAgICB0aW1lc3RhbXAsIG51bVZlcnNpb25zKTsKKyAgICAgICAgICB9CisgICAgICAgIH0pOworCisgICAgcmV0dXJuIHZhbHVlczsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCB0aGUgbGF0ZXN0IHRpbWVzdGFtcAorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uU3RhdGUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIGVtcHR5IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHRyYW5zYWN0aW9uU3RhdGUsIHJvdywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAKKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvblN0YXRlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gdHMgdGltZXN0YW1wCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIGVtcHR5IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgbG9uZyB0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gc3VwZXIuZ2V0Q29ubmVjdGlvbigpLmdldFJlZ2lvblNlcnZlcldpdGhSZXRyaWVzKAorICAgICAgICBuZXcgVHJhbnNhY3Rpb25hbFNlcnZlckNhbGxhYmxlPFJvd1Jlc3VsdD4oc3VwZXIuZ2V0Q29ubmVjdGlvbigpLCBzdXBlcgorICAgICAgICAgICAgLmdldFRhYmxlTmFtZSgpLCByb3csIHRyYW5zYWN0aW9uU3RhdGUpIHsKKyAgICAgICAgICBwdWJsaWMgUm93UmVzdWx0IGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmVjb3JkU2VydmVyKCk7CisgICAgICAgICAgICByZXR1cm4gZ2V0VHJhbnNhY3Rpb25TZXJ2ZXIoKS5nZXRSb3coCisgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCksCisgICAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgcm93LCB0cyk7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgc2VsZWN0ZWQgY29sdW1ucyBmb3IgdGhlIHNwZWNpZmllZCByb3cgYXQgdGhlIGxhdGVzdCB0aW1lc3RhbXAKKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvblN0YXRlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1ucyBBcnJheSBvZiBjb2x1bW4gbmFtZXMgeW91IHdhbnQgdG8gcmV0cmlldmUuCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIGVtcHR5IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgYnl0ZVtdW10gY29sdW1ucykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHRyYW5zYWN0aW9uU3RhdGUsIHJvdywgY29sdW1ucywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgc2VsZWN0ZWQgY29sdW1ucyBmb3IgdGhlIHNwZWNpZmllZCByb3cgYXQgYSBzcGVjaWZpZWQgdGltZXN0YW1wCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1uIG5hbWVzIHlvdSB3YW50IHRvIHJldHJpZXZlLgorICAgKiBAcGFyYW0gdHMgdGltZXN0YW1wCisgICAqIEByZXR1cm4gUm93UmVzdWx0IGlzIGVtcHR5IGlmIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgYnl0ZVtdW10gY29sdW1ucywgZmluYWwgbG9uZyB0cykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHN1cGVyLmdldENvbm5lY3Rpb24oKS5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFRyYW5zYWN0aW9uYWxTZXJ2ZXJDYWxsYWJsZTxSb3dSZXN1bHQ+KHN1cGVyLmdldENvbm5lY3Rpb24oKSwgc3VwZXIKKyAgICAgICAgICAgIC5nZXRUYWJsZU5hbWUoKSwgcm93LCB0cmFuc2FjdGlvblN0YXRlKSB7CisgICAgICAgICAgcHVibGljIFJvd1Jlc3VsdCBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJlY29yZFNlcnZlcigpOworICAgICAgICAgICAgcmV0dXJuIGdldFRyYW5zYWN0aW9uU2VydmVyKCkuZ2V0Um93KAorICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uU3RhdGUuZ2V0VHJhbnNhY3Rpb25JZCgpLAorICAgICAgICAgICAgICAgIGxvY2F0aW9uLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lKCksIHJvdywgY29sdW1ucywgdHMpOworICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCB3aG9zZSB0aW1lc3RhbXAgaXMgZXF1YWwtdG8KKyAgICogb3Igb2xkZXIgdGhhbiB0aGUgcGFzc2VkIHRpbWVzdGFtcC4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvblN0YXRlCisgICAqIEBwYXJhbSByb3cgUm93IHRvIHVwZGF0ZQorICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBjZWxscyBvZiB0aGUgc2FtZSB0aW1lc3RhbXAgb3Igb2xkZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBsb25nIHRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyLmdldENvbm5lY3Rpb24oKS5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFRyYW5zYWN0aW9uYWxTZXJ2ZXJDYWxsYWJsZTxCb29sZWFuPihzdXBlci5nZXRDb25uZWN0aW9uKCksIHN1cGVyCisgICAgICAgICAgICAuZ2V0VGFibGVOYW1lKCksIHJvdywgdHJhbnNhY3Rpb25TdGF0ZSkgeworICAgICAgICAgIHB1YmxpYyBCb29sZWFuIGNhbGwoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgcmVjb3JkU2VydmVyKCk7CisgICAgICAgICAgICBnZXRUcmFuc2FjdGlvblNlcnZlcigpLmRlbGV0ZUFsbCgKKyAgICAgICAgICAgICAgICB0cmFuc2FjdGlvblN0YXRlLmdldFRyYW5zYWN0aW9uSWQoKSwKKyAgICAgICAgICAgICAgICBsb2NhdGlvbi5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZSgpLCByb3csIHRzKTsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCBmaXJzdCByb3cuIFJldHVybiB0aGUKKyAgICogc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEKKyAgICogcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcmV0dXJuIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsCisgICAgICBmaW5hbCBieXRlW11bXSBjb2x1bW5zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKHRyYW5zYWN0aW9uU3RhdGUsIGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuIFJldHVybgorICAgKiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEKKyAgICogcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdW10gY29sdW1ucywgZmluYWwgYnl0ZVtdIHN0YXJ0Um93KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKHRyYW5zYWN0aW9uU3RhdGUsIGNvbHVtbnMsIHN0YXJ0Um93LAorICAgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuIFJldHVybgorICAgKiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEKKyAgICogcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCBvbmx5IHJldHVybiByZXN1bHRzIHdob3NlIHRpbWVzdGFtcCA8PSB0aGlzIHZhbHVlCisgICAqIEByZXR1cm4gc2Nhbm5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgU2Nhbm5lciBnZXRTY2FubmVyKGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSwKKyAgICAgIGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGJ5dGVbXSBzdGFydFJvdywgZmluYWwgbG9uZyB0aW1lc3RhbXApCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRTY2FubmVyKHRyYW5zYWN0aW9uU3RhdGUsIGNvbHVtbnMsIHN0YXJ0Um93LCB0aW1lc3RhbXAsIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuIFJldHVybgorICAgKiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEKKyAgICogcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIGZpbHRlciBhIHJvdyBmaWx0ZXIgdXNpbmcgcm93LWtleSByZWdleHAgYW5kL29yIGNvbHVtbiBkYXRhIGZpbHRlci4KKyAgICogQHJldHVybiBzY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTY2FubmVyIGdldFNjYW5uZXIoZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlLAorICAgICAgZmluYWwgYnl0ZVtdW10gY29sdW1ucywgZmluYWwgYnl0ZVtdIHN0YXJ0Um93LAorICAgICAgZmluYWwgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0U2Nhbm5lcih0cmFuc2FjdGlvblN0YXRlLCBjb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBmaWx0ZXIpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cuIFJldHVybgorICAgKiB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25TdGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEKKyAgICogcmVnZXggaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCBvbmx5IHJldHVybiByZXN1bHRzIHdob3NlIHRpbWVzdGFtcCA8PSB0aGlzIHZhbHVlCisgICAqIEBwYXJhbSBmaWx0ZXIgYSByb3cgZmlsdGVyIHVzaW5nIHJvdy1rZXkgcmVnZXhwIGFuZC9vciBjb2x1bW4gZGF0YSBmaWx0ZXIuCisgICAqIEByZXR1cm4gc2Nhbm5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgU2Nhbm5lciBnZXRTY2FubmVyKGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSwKKyAgICAgIGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGJ5dGVbXSBzdGFydFJvdywgZmluYWwgbG9uZyB0aW1lc3RhbXAsCisgICAgICBmaW5hbCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIENsaWVudFNjYW5uZXIgc2Nhbm5lciA9IG5ldyBUcmFuc2FjdGlvbmFsQ2xpZW50U2Nhbm5lcih0cmFuc2FjdGlvblN0YXRlLCBjb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgdGltZXN0YW1wLCBmaWx0ZXIpOworICAgIHNjYW5uZXIuaW5pdGlhbGl6ZSgpOworICAgIHJldHVybiBzY2FubmVyOworICB9CisKKyAgLyoqCisgICAqIENvbW1pdCBhIEJhdGNoVXBkYXRlIHRvIHRoZSB0YWJsZS4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvblN0YXRlCisgICAqIEBwYXJhbSBiYXRjaFVwZGF0ZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29tbWl0KGZpbmFsIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSwKKyAgICAgIGZpbmFsIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyLmdldENvbm5lY3Rpb24oKS5nZXRSZWdpb25TZXJ2ZXJXaXRoUmV0cmllcygKKyAgICAgICAgbmV3IFRyYW5zYWN0aW9uYWxTZXJ2ZXJDYWxsYWJsZTxCb29sZWFuPihzdXBlci5nZXRDb25uZWN0aW9uKCksIHN1cGVyCisgICAgICAgICAgICAuZ2V0VGFibGVOYW1lKCksIGJhdGNoVXBkYXRlLmdldFJvdygpLCB0cmFuc2FjdGlvblN0YXRlKSB7CisgICAgICAgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICByZWNvcmRTZXJ2ZXIoKTsKKyAgICAgICAgICAgIGdldFRyYW5zYWN0aW9uU2VydmVyKCkuYmF0Y2hVcGRhdGUoCisgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25TdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCksCisgICAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWUoKSwgYmF0Y2hVcGRhdGUpOworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorCisgIHByb3RlY3RlZCBjbGFzcyBUcmFuc2FjdGlvbmFsQ2xpZW50U2Nhbm5lciBleHRlbmRzIEhUYWJsZS5DbGllbnRTY2FubmVyIHsKKworICAgIHByaXZhdGUgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlOworCisgICAgcHJvdGVjdGVkIFRyYW5zYWN0aW9uYWxDbGllbnRTY2FubmVyKAorICAgICAgICBmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUsIGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsCisgICAgICAgIGZpbmFsIGJ5dGVbXSBzdGFydFJvdywgZmluYWwgbG9uZyB0aW1lc3RhbXAsCisgICAgICAgIGZpbmFsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHsKKyAgICAgIHN1cGVyKGNvbHVtbnMsIHN0YXJ0Um93LCB0aW1lc3RhbXAsIGZpbHRlcik7CisgICAgICB0aGlzLnRyYW5zYWN0aW9uU3RhdGUgPSB0cmFuc2FjdGlvblN0YXRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTY2FubmVyQ2FsbGFibGUgZ2V0U2Nhbm5lckNhbGxhYmxlKAorICAgICAgICBmaW5hbCBieXRlW10gbG9jYWxTdGFydEtleSwgaW50IGNhY2hpbmcpIHsKKyAgICAgIFRyYW5zYWN0aW9uU2Nhbm5lckNhbGxhYmxlIHQgPSAKKyAgICAgICAgICBuZXcgVHJhbnNhY3Rpb25TY2FubmVyQ2FsbGFibGUodHJhbnNhY3Rpb25TdGF0ZSwgZ2V0Q29ubmVjdGlvbigpLAorICAgICAgICAgIGdldFRhYmxlTmFtZSgpLCBnZXRDb2x1bW5zKCksIGxvY2FsU3RhcnRLZXksIGdldFRpbWVzdGFtcCgpLAorICAgICAgICAgIGdldEZpbHRlcigpKTsKKyAgICAgIHQuc2V0Q2FjaGluZyhjYWNoaW5nKTsKKyAgICAgIHJldHVybiB0OworICAgIH0KKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9Vbmtub3duVHJhbnNhY3Rpb25FeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1Vua25vd25UcmFuc2FjdGlvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZjJiYzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9Vbmtub3duVHJhbnNhY3Rpb25FeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQzIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Eb05vdFJldHJ5SU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIGlmIGEgcmVnaW9uIHNlcnZlciBpcyBwYXNzZWQgYW4gdW5rbm93biB0cmFuc2FjdGlvbiBpZAorICovCitwdWJsaWMgY2xhc3MgVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA2OTg1NzUzNzQ5Mjk1OTEwOTlMOworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHMgbWVzc2FnZQorICAgKi8KKyAgcHVibGljIFVua25vd25UcmFuc2FjdGlvbkV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgIHN1cGVyKHMpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9wYWNrYWdlLmh0bWwgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzU3NDI1YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDYxIEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Cis8aHRtbD4KKworPCEtLQorICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8aGVhZCAvPgorPGJvZHkgYmdjb2xvcj0id2hpdGUiPgorCitUaGlzIHBhY2thZ2UgcHJvdmlkZXMgc3VwcG9ydCBmb3IgYXRvbWljIHRyYW5zYWN0aW9ucy4gVHJhbnNhY3Rpb25zIGNhbgorc3BhbiBtdWx0aXBsZSByZWdpb25zLiBUcmFuc2FjdGlvbiB3cml0ZXMgYXJlIGFwcGxpZWQgd2hlbiBjb21taXR0aW5nIGEKK3RyYW5zYWN0aW9uLiBBdCBjb21taXQgdGltZSwgdGhlIHRyYW5zYWN0aW9uIGlzIGV4YW1pbmVkIHRvIHNlZSBpZiBpdAorY2FuIGJlIGFwcGxpZWQgd2hpbGUgc3RpbGwgbWFpbnRhaW5pbmcgYXRvbWljaXR5LiBUaGlzIGlzIGRvbmUgYnkKK2xvb2tpbmcgZm9yIGNvbmZsaWN0cyB3aXRoIHRoZSB0cmFuc2FjdGlvbnMgdGhhdCBjb21taXR0ZWQgd2hpbGUgdGhlCitjdXJyZW50IHRyYW5zYWN0aW9uIHdhcyBydW5uaW5nLiBUaGlzIHRlY2huaXF1ZSBpcyBrbm93biBhcyBvcHRpbWlzdGljCitjb25jdXJyZW5jeSBjb250cm9sIChPQ0MpIGJlY2F1c2UgaXQgcmVsaWVzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQKK3RyYW5zYWN0aW9ucyB3aWxsIG1vc3RseSBub3QgaGF2ZSBjb25mbGljdHMgd2l0aCBlYWNoIG90aGVyLgorCis8cD4KK0ZvciBtb3JlIGRldGFpbHMgb24gT0NDLCBzZWUgdGhlIHBhcGVyIDxpPiBPbiBPcHRpbWlzdGljIE1ldGhvZHMgZm9yIENvbmN1cnJlbmN5IENvbnRyb2wgPC9pPiAKK2J5IEt1bmcgYW5kIFJvYmluc29uIGF2YWlsYWJsZSAKKzxhIGhyZWY9aHR0cDovL3d3dy5zZWFzLnVwZW5uLmVkdS9+eml2ZXMvY2lzNjUwL3BhcGVycy9vcHQtY2MucGRmPiBoZXJlIDwvYT4uCisKKzxwPiBUbyBlbmFibGUgdHJhbnNhY3Rpb25zLCBtb2RpZnkgaGJhc2Utc2l0ZS54bWwgdG8gdHVybiBvbiB0aGUKK1RyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuICBUaGlzIGlzIGRvbmUgYnkgc2V0dGluZworPGk+aGJhc2UucmVnaW9uc2VydmVyLmNsYXNzPC9pPiB0bworPGk+b3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLlRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2U8L2k+IGFuZAorPGk+aGJhc2UucmVnaW9uc2VydmVyLmltcGwgPC9pPiB0bworPGk+b3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLnRyYW5zYWN0aW9uYWwuVHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlcjwvaT4KKworPHA+IAorVGhlIHJlYWQgc2V0IGNsYWltZWQgYnkgYSB0cmFuc2FjdGlvbmFsIHNjYW5uZXIgaXMgZGV0ZXJtaW5lZCBmcm9tIHRoZSBzdGFydCBhbmQKKyBlbmQga2V5cyB3aGljaCB0aGUgc2Nhbm5lciBpcyBvcGVuZWQgd2l0aC4gCisKKworCis8aDM+IEtub3duIElzc3VlcyA8L2gzPgorCitSZWNvdmVyeSBpbiB0aGUgZmFjZSBvZiBocmVnaW9uIHNlcnZlciBmYWlsdXJlCitpcyBub3QgZnVsbHkgaW1wbGVtZW50ZWQuIFRodXMsIHlvdSBjYW5ub3QgcmVseSBvbiB0aGUgdHJhbnNhY3Rpb25hbAorcHJvcGVydGllcyBpbiB0aGUgZmFjZSBvZiBub2RlIGZhaWx1cmUuCisKKworCisgCis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvQ29sdW1uVmFsdWVGaWx0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Db2x1bW5WYWx1ZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxYTRjYmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvQ29sdW1uVmFsdWVGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDI5NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlcjsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uT2JqZWN0V3JpdGFibGU7CisKKy8qKgorICogVGhpcyBmaWx0ZXIgaXMgdXNlZCB0byBmaWx0ZXIgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gY29sdW1uLiBJdCB0YWtlcworICogYW4gb3BlcmF0b3IgKGVxdWFsLCBncmVhdGVyLCBub3QgZXF1YWwsIGV0YykgYW5kIGVpdGhlciBhIGJ5dGUgW10gdmFsdWUgb3IgYQorICogYnl0ZSBbXSBjb21wYXJhdG9yLiBJZiB3ZSBoYXZlIGEgYnl0ZSBbXSB2YWx1ZSB0aGVuIHdlIGp1c3QgZG8gYQorICogbGV4aWNvZ3JhcGhpYyBjb21wYXJlLiBJZiB0aGlzIGlzIG5vdCBzdWZmaWNpZW50IChlZyB5b3Ugd2FudCB0byBkZXNlcmlhbGl6ZQorICogYSBsb25nIGFuZCB0aGVuIGNvbXBhcmUgaXQgdG8gYSBmaXhlZCBsb25nIHZhbHVlKSwgdGhlbiB5b3UgY2FuIHBhc3MgaW4geW91cgorICogb3duIGNvbXBhcmF0b3IgaW5zdGVhZC4KKyAqLworcHVibGljIGNsYXNzIENvbHVtblZhbHVlRmlsdGVyIGltcGxlbWVudHMgUm93RmlsdGVySW50ZXJmYWNlIHsKKyAgLyoqIENvbXBhcmlzb24gb3BlcmF0b3JzLiAqLworICBwdWJsaWMgZW51bSBDb21wYXJlT3AgeworICAgIC8qKiBsZXNzIHRoYW4gKi8KKyAgICBMRVNTLAorICAgIC8qKiBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gKi8KKyAgICBMRVNTX09SX0VRVUFMLAorICAgIC8qKiBlcXVhbHMgKi8KKyAgICBFUVVBTCwKKyAgICAvKiogbm90IGVxdWFsICovCisgICAgTk9UX0VRVUFMLAorICAgIC8qKiBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gKi8KKyAgICBHUkVBVEVSX09SX0VRVUFMLAorICAgIC8qKiBncmVhdGVyIHRoYW4gKi8KKyAgICBHUkVBVEVSOworICB9CisKKyAgcHJpdmF0ZSBieXRlW10gY29sdW1uTmFtZTsKKyAgcHJpdmF0ZSBDb21wYXJlT3AgY29tcGFyZU9wOworICBwcml2YXRlIGJ5dGVbXSB2YWx1ZTsKKyAgcHJpdmF0ZSBXcml0YWJsZUJ5dGVBcnJheUNvbXBhcmFibGUgY29tcGFyYXRvcjsKKyAgcHJpdmF0ZSBib29sZWFuIGZpbHRlcklmQ29sdW1uTWlzc2luZzsKKworICBDb2x1bW5WYWx1ZUZpbHRlcigpIHsKKyAgICAvLyBmb3IgV3JpdGFibGUKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3Rvci4KKyAgICogCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lIG5hbWUgb2YgY29sdW1uCisgICAqIEBwYXJhbSBjb21wYXJlT3Agb3BlcmF0b3IKKyAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGNvbXBhcmUgY29sdW1uIHZhbHVlcyBhZ2FpbnN0CisgICAqLworICBwdWJsaWMgQ29sdW1uVmFsdWVGaWx0ZXIoZmluYWwgYnl0ZVtdIGNvbHVtbk5hbWUsIGZpbmFsIENvbXBhcmVPcCBjb21wYXJlT3AsCisgICAgICBmaW5hbCBieXRlW10gdmFsdWUpIHsKKyAgICB0aGlzKGNvbHVtbk5hbWUsIGNvbXBhcmVPcCwgdmFsdWUsIHRydWUpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0b3IuCisgICAqIAorICAgKiBAcGFyYW0gY29sdW1uTmFtZSBuYW1lIG9mIGNvbHVtbgorICAgKiBAcGFyYW0gY29tcGFyZU9wIG9wZXJhdG9yCisgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBjb21wYXJlIGNvbHVtbiB2YWx1ZXMgYWdhaW5zdAorICAgKiBAcGFyYW0gZmlsdGVySWZDb2x1bW5NaXNzaW5nIGlmIHRydWUgdGhlbiB3ZSB3aWxsIGZpbHRlciByb3dzIHRoYXQgZG9uJ3QgaGF2ZSB0aGUgY29sdW1uLiAKKyAgICovCisgIHB1YmxpYyBDb2x1bW5WYWx1ZUZpbHRlcihmaW5hbCBieXRlW10gY29sdW1uTmFtZSwgZmluYWwgQ29tcGFyZU9wIGNvbXBhcmVPcCwKKyAgICAgIGZpbmFsIGJ5dGVbXSB2YWx1ZSwgYm9vbGVhbiBmaWx0ZXJJZkNvbHVtbk1pc3NpbmcpIHsKKyAgICB0aGlzLmNvbHVtbk5hbWUgPSBjb2x1bW5OYW1lOworICAgIHRoaXMuY29tcGFyZU9wID0gY29tcGFyZU9wOworICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICB0aGlzLmZpbHRlcklmQ29sdW1uTWlzc2luZyA9IGZpbHRlcklmQ29sdW1uTWlzc2luZzsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3Rvci4KKyAgICogCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lIG5hbWUgb2YgY29sdW1uCisgICAqIEBwYXJhbSBjb21wYXJlT3Agb3BlcmF0b3IKKyAgICogQHBhcmFtIGNvbXBhcmF0b3IgQ29tcGFyYXRvciB0byB1c2UuCisgICAqLworICBwdWJsaWMgQ29sdW1uVmFsdWVGaWx0ZXIoZmluYWwgYnl0ZVtdIGNvbHVtbk5hbWUsIGZpbmFsIENvbXBhcmVPcCBjb21wYXJlT3AsCisgICAgICBmaW5hbCBXcml0YWJsZUJ5dGVBcnJheUNvbXBhcmFibGUgY29tcGFyYXRvcikgeworICAgIHRoaXMoY29sdW1uTmFtZSwgY29tcGFyZU9wLCBjb21wYXJhdG9yLCB0cnVlKTsKKyAgfQorICAKKyAgLyoqCisgICogQ29uc3RydWN0b3IuCisgICogCisgICogQHBhcmFtIGNvbHVtbk5hbWUgbmFtZSBvZiBjb2x1bW4KKyAgKiBAcGFyYW0gY29tcGFyZU9wIG9wZXJhdG9yCisgICogQHBhcmFtIGNvbXBhcmF0b3IgQ29tcGFyYXRvciB0byB1c2UuCisgICogQHBhcmFtIGZpbHRlcklmQ29sdW1uTWlzc2luZyBpZiB0cnVlIHRoZW4gd2Ugd2lsbCBmaWx0ZXIgcm93cyB0aGF0IGRvbid0IGhhdmUgdGhlIGNvbHVtbi4gCisgICovCisgcHVibGljIENvbHVtblZhbHVlRmlsdGVyKGZpbmFsIGJ5dGVbXSBjb2x1bW5OYW1lLCBmaW5hbCBDb21wYXJlT3AgY29tcGFyZU9wLAorICAgICBmaW5hbCBXcml0YWJsZUJ5dGVBcnJheUNvbXBhcmFibGUgY29tcGFyYXRvciwgYm9vbGVhbiBmaWx0ZXJJZkNvbHVtbk1pc3NpbmcpIHsKKyAgIHRoaXMuY29sdW1uTmFtZSA9IGNvbHVtbk5hbWU7CisgICB0aGlzLmNvbXBhcmVPcCA9IGNvbXBhcmVPcDsKKyAgIHRoaXMuY29tcGFyYXRvciA9IGNvbXBhcmF0b3I7CisgICB0aGlzLmZpbHRlcklmQ29sdW1uTWlzc2luZyA9IGZpbHRlcklmQ29sdW1uTWlzc2luZzsKKyB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGVbXSByb3dLZXkpIHsKKyAgICByZXR1cm4gZmlsdGVyUm93S2V5KHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoYnl0ZVtdIHJvd0tleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIAorICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJDb2x1bW4oZmluYWwgYnl0ZVtdIHJvd0tleSwKKyAgICAgIGZpbmFsIGJ5dGVbXSBjb2xLZXksIGZpbmFsIGJ5dGVbXSBkYXRhKSB7CisgICAgaWYgKCFmaWx0ZXJJZkNvbHVtbk1pc3NpbmcpIHsKKyAgICAgIHJldHVybiBmYWxzZTsgLy8gTXVzdCBmaWx0ZXIgb24gdGhlIHdob2xlIHJvdworICAgIH0KKyAgICBpZiAoIUFycmF5cy5lcXVhbHMoY29sS2V5LCBjb2x1bW5OYW1lKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gZmlsdGVyQ29sdW1uVmFsdWUoZGF0YSwgMCwgZGF0YS5sZW5ndGgpOyAKKyAgfQorCisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGJ5dGVbXSByb3dLZXksIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCwKKyAgICAgIGJ5dGVbXSBjbiwgaW50IGNvZmZzZXQsIGludCBjbGVuZ3RoLCBieXRlW10gY29sdW1uVmFsdWUsCisgICAgICBpbnQgdm9mZnNldCwgaW50IHZsZW5ndGgpIHsKKyAgICBpZiAoIWZpbHRlcklmQ29sdW1uTWlzc2luZykgeworICAgICAgcmV0dXJuIGZhbHNlOyAvLyBNdXN0IGZpbHRlciBvbiB0aGUgd2hvbGUgcm93CisgICAgfQorICAgIGlmIChCeXRlcy5jb21wYXJlVG8oY24sIGNvZmZzZXQsIGNsZW5ndGgsCisgICAgICAgIHRoaXMuY29sdW1uTmFtZSwgMCwgdGhpcy5jb2x1bW5OYW1lLmxlbmd0aCkgIT0gMCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gZmlsdGVyQ29sdW1uVmFsdWUoY29sdW1uVmFsdWUsIHZvZmZzZXQsIHZsZW5ndGgpOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGZpbHRlckNvbHVtblZhbHVlKGZpbmFsIGJ5dGUgW10gZGF0YSwgZmluYWwgaW50IG9mZnNldCwKKyAgICAgIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBpbnQgY29tcGFyZVJlc3VsdDsKKyAgICBpZiAoY29tcGFyYXRvciAhPSBudWxsKSB7CisgICAgICBjb21wYXJlUmVzdWx0ID0gY29tcGFyYXRvci5jb21wYXJlVG8oZGF0YSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbXBhcmVSZXN1bHQgPSBjb21wYXJlKHZhbHVlLCBkYXRhKTsKKyAgICB9CisKKyAgICBzd2l0Y2ggKGNvbXBhcmVPcCkgeworICAgIGNhc2UgTEVTUzoKKyAgICAgIHJldHVybiBjb21wYXJlUmVzdWx0IDw9IDA7CisgICAgY2FzZSBMRVNTX09SX0VRVUFMOgorICAgICAgcmV0dXJuIGNvbXBhcmVSZXN1bHQgPCAwOworICAgIGNhc2UgRVFVQUw6CisgICAgICByZXR1cm4gY29tcGFyZVJlc3VsdCAhPSAwOworICAgIGNhc2UgTk9UX0VRVUFMOgorICAgICAgcmV0dXJuIGNvbXBhcmVSZXN1bHQgPT0gMDsKKyAgICBjYXNlIEdSRUFURVJfT1JfRVFVQUw6CisgICAgICByZXR1cm4gY29tcGFyZVJlc3VsdCA+IDA7CisgICAgY2FzZSBHUkVBVEVSOgorICAgICAgcmV0dXJuIGNvbXBhcmVSZXN1bHQgPj0gMDsKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVua25vd24gQ29tcGFyZSBvcCAiICsgY29tcGFyZU9wLm5hbWUoKSk7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJBbGxSZW1haW5pbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93KGZpbmFsIFNvcnRlZE1hcDxieXRlW10sIENlbGw+IGNvbHVtbnMpIHsKKyAgICBpZiAoY29sdW1ucyA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmIChmaWx0ZXJJZkNvbHVtbk1pc3NpbmcpIHsKKyAgICAgIHJldHVybiAhY29sdW1ucy5jb250YWluc0tleShjb2x1bW5OYW1lKTsKKyAgICB9IAorICAgIC8vIE90aGVyd2lzZSB3ZSBtdXN0IGRvIHRoZSBmaWx0ZXIgaGVyZQorICAgIENlbGwgY29sQ2VsbCA9IGNvbHVtbnMuZ2V0KGNvbHVtbk5hbWUpOworICAgICAgaWYgKGNvbENlbGwgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBieXRlIFtdIHYgPSBjb2xDZWxsLmdldFZhbHVlKCk7CisgICAgICByZXR1cm4gdGhpcy5maWx0ZXJDb2x1bW5WYWx1ZSh2LCAwLCB2Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3coTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cykgeworICAgIGlmIChyZXN1bHRzID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICBLZXlWYWx1ZSBmb3VuZCA9IG51bGw7CisgICAgaWYgKGZpbHRlcklmQ29sdW1uTWlzc2luZykgeworICAgICAgYm9vbGVhbiBkb2VzbnRIYXZlSXQgPSB0cnVlOworICAgICAgZm9yIChLZXlWYWx1ZSBrdjogcmVzdWx0cykgeworICAgICAgICBpZiAoa3YubWF0Y2hpbmdDb2x1bW4oY29sdW1uTmFtZSkpIHsKKyAgICAgICAgICBkb2VzbnRIYXZlSXQgPSBmYWxzZTsKKyAgICAgICAgICBmb3VuZCA9IGt2OworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoZG9lc250SGF2ZUl0KSByZXR1cm4gZG9lc250SGF2ZUl0OworICAgIH0KKyAgICBpZiAoZm91bmQgPT0gbnVsbCkgeworICAgICAgZm9yIChLZXlWYWx1ZSBrdjogcmVzdWx0cykgeworICAgICAgICBpZiAoa3YubWF0Y2hpbmdDb2x1bW4oY29sdW1uTmFtZSkpIHsKKyAgICAgICAgICBmb3VuZCA9IGt2OworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGlmIChmb3VuZCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0aGlzLmZpbHRlckNvbHVtblZhbHVlKGZvdW5kLmdldFZhbHVlKCksIGZvdW5kLmdldFZhbHVlT2Zmc2V0KCksCisgICAgICBmb3VuZC5nZXRWYWx1ZUxlbmd0aCgpKTsKKyAgfQorCisgIHByaXZhdGUgaW50IGNvbXBhcmUoZmluYWwgYnl0ZVtdIGIxLCBmaW5hbCBieXRlW10gYjIpIHsKKyAgICBpbnQgbGVuID0gTWF0aC5taW4oYjEubGVuZ3RoLCBiMi5sZW5ndGgpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgaWYgKGIxW2ldICE9IGIyW2ldKSB7CisgICAgICAgIHJldHVybiBiMVtpXSAtIGIyW2ldOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gYjEubGVuZ3RoIC0gYjIubGVuZ3RoOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc0Fsd2F5cygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAvLyBOb3RoaW5nLgorICB9CisKKyAgcHVibGljIHZvaWQgcm93UHJvY2Vzc2VkKGZpbmFsIGJvb2xlYW4gZmlsdGVyZWQsCisgICAgICBmaW5hbCBieXRlW10ga2V5KSB7CisgICAgLy8gTm90aGluZworICB9CisKKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIC8vIE5vdGhpbmcKKyAgfQorCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMpIHsKKyAgICAvLyBOb3RoaW5nCisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKGZpbmFsIERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgdmFsdWVMZW4gPSBpbi5yZWFkSW50KCk7CisgICAgaWYgKHZhbHVlTGVuID4gMCkgeworICAgICAgdmFsdWUgPSBuZXcgYnl0ZVt2YWx1ZUxlbl07CisgICAgICBpbi5yZWFkRnVsbHkodmFsdWUpOworICAgIH0KKyAgICBjb2x1bW5OYW1lID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgY29tcGFyZU9wID0gQ29tcGFyZU9wLnZhbHVlT2YoaW4ucmVhZFVURigpKTsKKyAgICBjb21wYXJhdG9yID0gKFdyaXRhYmxlQnl0ZUFycmF5Q29tcGFyYWJsZSkgT2JqZWN0V3JpdGFibGUucmVhZE9iamVjdChpbiwKKyAgICAgICAgbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpKTsKKyAgICBmaWx0ZXJJZkNvbHVtbk1pc3NpbmcgPSBpbi5yZWFkQm9vbGVhbigpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgIG91dC53cml0ZUludCgwKTsKKyAgICB9IGVsc2UgeworICAgICAgb3V0LndyaXRlSW50KHZhbHVlLmxlbmd0aCk7CisgICAgICBvdXQud3JpdGUodmFsdWUpOworICAgIH0KKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGNvbHVtbk5hbWUpOworICAgIG91dC53cml0ZVVURihjb21wYXJlT3AubmFtZSgpKTsKKyAgICBPYmplY3RXcml0YWJsZS53cml0ZU9iamVjdChvdXQsIGNvbXBhcmF0b3IsCisgICAgICAgIFdyaXRhYmxlQnl0ZUFycmF5Q29tcGFyYWJsZS5jbGFzcywgbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpKTsKKyAgICBvdXQud3JpdGVCb29sZWFuKGZpbHRlcklmQ29sdW1uTWlzc2luZyk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvSW5jbHVzaXZlU3RvcFJvd0ZpbHRlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL0luY2x1c2l2ZVN0b3BSb3dGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2I1NzJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL0luY2x1c2l2ZVN0b3BSb3dGaWx0ZXIuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBTdWJjbGFzcyBvZiBTdG9wUm93RmlsdGVyIHRoYXQgZmlsdGVycyByb3dzID4gdGhlIHN0b3Agcm93LAorICogbWFraW5nIGl0IGluY2x1ZGUgdXAgdG8gdGhlIGxhc3Qgcm93IGJ1dCBubyBmdXJ0aGVyLgorICovCitwdWJsaWMgY2xhc3MgSW5jbHVzaXZlU3RvcFJvd0ZpbHRlciBleHRlbmRzIFN0b3BSb3dGaWx0ZXJ7CisgIC8qKgorICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBmaWx0ZXJzIG5vdGhpbmcuIFJlcXVpcmVkIHRob3VnaCBmb3IgUlBDCisgICAqIGRlc2VyaWFsaXphdGlvbi4KKyAgICovCisgIHB1YmxpYyBJbmNsdXNpdmVTdG9wUm93RmlsdGVyKCkge3N1cGVyKCk7fQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgc3RvcFJvd0tleSBvbiB3aGljaCB0byBmaWx0ZXIKKyAgICogCisgICAqIEBwYXJhbSBzdG9wUm93S2V5IHJvd0tleSB0byBmaWx0ZXIgb24uCisgICAqLworICBwdWJsaWMgSW5jbHVzaXZlU3RvcFJvd0ZpbHRlcihmaW5hbCBieXRlIFtdIHN0b3BSb3dLZXkpIHsKKyAgICBzdXBlcihzdG9wUm93S2V5KTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5TdG9wUm93RmlsdGVyI2ZpbHRlclJvd0tleShieXRlW10pCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGUgW10gcm93S2V5KSB7CisgICAgaWYgKHJvd0tleSA9PSBudWxsKSB7CisgICAgICBpZiAoZ2V0U3RvcFJvd0tleSgpID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfSAgICAKKyAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKGdldFN0b3BSb3dLZXkoKSwgcm93S2V5KSA8IDA7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9JbnZhbGlkUm93RmlsdGVyRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvSW52YWxpZFJvd0ZpbHRlckV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhZDA1N2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvSW52YWxpZFJvd0ZpbHRlckV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKKy8qKgorICogVXNlZCB0byBpbmRpY2F0ZSBhbiBpbnZhbGlkIFJvd0ZpbHRlci4KKyAqLworcHVibGljIGNsYXNzIEludmFsaWRSb3dGaWx0ZXJFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY2Nzg5NDA0NjM0NTY1Nzg2NUw7CisKKworICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIEludmFsaWRSb3dGaWx0ZXJFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBjb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgSW52YWxpZFJvd0ZpbHRlckV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgIHN1cGVyKHMpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1BhZ2VSb3dGaWx0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9QYWdlUm93RmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThlNzNkNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9QYWdlUm93RmlsdGVyLmphdmEKQEAgLTAsMCArMSwxMzAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKKworLyoqCisgKiBJbXBsZW1lbnRhdGlvbiBvZiBSb3dGaWx0ZXJJbnRlcmZhY2UgdGhhdCBsaW1pdHMgcmVzdWx0cyB0byBhIHNwZWNpZmljIHBhZ2UKKyAqIHNpemUuIEl0IHRlcm1pbmF0ZXMgc2Nhbm5pbmcgb25jZSB0aGUgbnVtYmVyIG9mIGZpbHRlci1wYXNzZWQgcmVzdWx0cyBpcyA+PQorICogdGhlIGdpdmVuIHBhZ2Ugc2l6ZS4KKyAqIAorICogPHA+CisgKiBOb3RlIHRoYXQgdGhpcyBmaWx0ZXIgY2Fubm90IGd1YXJhbnRlZSB0aGF0IHRoZSBudW1iZXIgb2YgcmVzdWx0cyByZXR1cm5lZAorICogdG8gYSBjbGllbnQgYXJlIDw9IHBhZ2Ugc2l6ZS4gVGhpcyBpcyBiZWNhdXNlIHRoZSBmaWx0ZXIgaXMgYXBwbGllZAorICogc2VwYXJhdGVseSBvbiBkaWZmZXJlbnQgcmVnaW9uIHNlcnZlcnMuIEl0IGRvZXMgaG93ZXZlciBvcHRpbWl6ZSB0aGUgc2NhbiBvZgorICogaW5kaXZpZHVhbCBIUmVnaW9ucyBieSBtYWtpbmcgc3VyZSB0aGF0IHRoZSBwYWdlIHNpemUgaXMgbmV2ZXIgZXhjZWVkZWQKKyAqIGxvY2FsbHkuCisgKiA8L3A+CisgKi8KK3B1YmxpYyBjbGFzcyBQYWdlUm93RmlsdGVyIGltcGxlbWVudHMgUm93RmlsdGVySW50ZXJmYWNlIHsKKworICBwcml2YXRlIGxvbmcgcGFnZVNpemUgPSBMb25nLk1BWF9WQUxVRTsKKyAgcHJpdmF0ZSBpbnQgcm93c0FjY2VwdGVkID0gMDsKKworICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciwgZmlsdGVycyBub3RoaW5nLiBSZXF1aXJlZCB0aG91Z2ggZm9yIFJQQworICAgKiBkZXNlcmlhbGl6YXRpb24uCisgICAqLworICBwdWJsaWMgUGFnZVJvd0ZpbHRlcigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBtYXhpbXVtIHBhZ2Ugc2l6ZS4KKyAgICogCisgICAqIEBwYXJhbSBwYWdlU2l6ZSBNYXhpbXVtIHJlc3VsdCBzaXplLgorICAgKi8KKyAgcHVibGljIFBhZ2VSb3dGaWx0ZXIoZmluYWwgbG9uZyBwYWdlU2l6ZSkgeworICAgIHRoaXMucGFnZVNpemUgPSBwYWdlU2l6ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zKSB7CisgICAgLy8gRG9lc24ndCBmaWx0ZXIgY29sdW1ucworICB9CisKKyAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgcm93c0FjY2VwdGVkID0gMDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLAorICAgICAgYnl0ZSBbXSByb3dLZXkpIHsKKyAgICByb3dQcm9jZXNzZWQoZmlsdGVyZWQsIHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIGlmICghZmlsdGVyZWQpIHsKKyAgICAgIHRoaXMucm93c0FjY2VwdGVkKys7CisgICAgfQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc0Fsd2F5cygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJBbGxSZW1haW5pbmcoKSB7CisgICAgcmV0dXJuIHRoaXMucm93c0FjY2VwdGVkID4gdGhpcy5wYWdlU2l6ZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvd0tleShmaW5hbCBieXRlIFtdIHIpIHsKKyAgICByZXR1cm4gZmlsdGVyUm93S2V5KHIsIDAsIHIubGVuZ3RoKTsKKyAgfQorCisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGJ5dGVbXSByb3dLZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gZmlsdGVyQWxsUmVtYWluaW5nKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJDb2x1bW4oZmluYWwgYnl0ZSBbXSByb3dLZXksCisgICAgZmluYWwgYnl0ZSBbXSBjb2xLZXksCisgICAgZmluYWwgYnl0ZVtdIGRhdGEpIHsKKyAgICByZXR1cm4gZmlsdGVyQ29sdW1uKHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCwgY29sS2V5LCAwLCBjb2xLZXkubGVuZ3RoLAorICAgICAgZGF0YSwgMCwgZGF0YS5sZW5ndGgpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGJ5dGVbXSByb3dLZXksIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCwKKyAgICAgIGJ5dGVbXSBjb2x1bm1OYW1lLCBpbnQgY29mZnNldCwgaW50IGNsZW5ndGgsIGJ5dGVbXSBjb2x1bW5WYWx1ZSwKKyAgICAgIGludCB2b2Zmc2V0LCBpbnQgdmxlbmd0aCkgeworICAgIHJldHVybiBmaWx0ZXJBbGxSZW1haW5pbmcoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhmaW5hbCBTb3J0ZWRNYXA8Ynl0ZSBbXSwgQ2VsbD4gY29sdW1ucykgeworICAgIHJldHVybiBmaWx0ZXJBbGxSZW1haW5pbmcoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhMaXN0PEtleVZhbHVlPiByZXN1bHRzKSB7CisgICAgcmV0dXJuIGZpbHRlckFsbFJlbWFpbmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhmaW5hbCBEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5wYWdlU2l6ZSA9IGluLnJlYWRMb25nKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGVMb25nKHBhZ2VTaXplKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9QcmVmaXhSb3dGaWx0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9QcmVmaXhSb3dGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNGUzZWNlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1ByZWZpeFJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMTE4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBSb3dGaWx0ZXJJbnRlcmZhY2UgdGhhdCBmaWx0ZXJzIGV2ZXJ5dGhpbmcgdGhhdCBkb2VzIG5vdCBtYXRjaCBhIHByZWZpeAorICovCitwdWJsaWMgY2xhc3MgUHJlZml4Um93RmlsdGVyIGltcGxlbWVudHMgUm93RmlsdGVySW50ZXJmYWNlIHsKKyAgcHJvdGVjdGVkIGJ5dGVbXSBwcmVmaXg7CisgIAorICAvKioKKyAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIHJvdyBwcmVmaXggdG8gZmlsdGVyIG9uCisgICAqIEBwYXJhbSBwcmVmaXggCisgICAqLworICBwdWJsaWMgUHJlZml4Um93RmlsdGVyKGJ5dGVbXSBwcmVmaXgpIHsKKyAgICB0aGlzLnByZWZpeCA9IHByZWZpeDsKKyAgfQorICAKKyAgLyoqCisgICAqIERlZmF1bHQgQ29uc3RydWN0b3IsIGZpbHRlcnMgbm90aGluZy4gUmVxdWlyZWQgZm9yIFJQQworICAgKiBkZXNlcmlhbGl6YXRpb24KKyAgICovCisgIHB1YmxpYyBQcmVmaXhSb3dGaWx0ZXIoKSB7IH0KKyAgCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIC8vIE5vdGhpbmcgdG8gcmVzZXQKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlIFtdIGtleSkgeworICAgIHJvd1Byb2Nlc3NlZChmaWx0ZXJlZCwga2V5LCAwLCBrZXkubGVuZ3RoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlW10ga2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgLy8gZG9lcyBub3QgY2FyZQorICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzQWx3YXlzKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQWxsUmVtYWluaW5nKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGUgW10gcm93S2V5KSB7CisgICAgcmV0dXJuIGZpbHRlclJvd0tleShyb3dLZXksIDAsIHJvd0tleS5sZW5ndGgpOworICB9CisKKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoYnl0ZVtdIHJvd0tleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIGlmIChyb3dLZXkgPT0gbnVsbCkKKyAgICAgIHJldHVybiB0cnVlOworICAgIGlmIChsZW5ndGggPCBwcmVmaXgubGVuZ3RoKQorICAgICAgcmV0dXJuIHRydWU7CisgICAgZm9yKGludCBpID0gMDtpIDwgcHJlZml4Lmxlbmd0aDtpKyspCisgICAgICBpZiAocHJlZml4W2ldICE9IHJvd0tleVtpICsgb2Zmc2V0XSkKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGZpbmFsIGJ5dGUgW10gcm93S2V5LCBmaW5hbCBieXRlIFtdIGNvbHVubU5hbWUsCisgICAgICBmaW5hbCBieXRlW10gY29sdW1uVmFsdWUpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJDb2x1bW4oYnl0ZVtdIHJvd0tleSwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoLAorICAgICAgYnl0ZVtdIGNvbHVubU5hbWUsIGludCBjb2Zmc2V0LCBpbnQgY2xlbmd0aCwgYnl0ZVtdIGNvbHVtblZhbHVlLAorICAgICAgaW50IHZvZmZzZXQsIGludCB2bGVuZ3RoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93KGZpbmFsIFNvcnRlZE1hcDxieXRlIFtdLCBDZWxsPiBjb2x1bW5zKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShmaW5hbCBieXRlIFtdW10gY29sdW1ucykgeworICAgIC8vIGRvZXMgbm90IGRvIHRoaXMKKyAgfQorICAKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhmaW5hbCBEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcHJlZml4ID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgcHJlZml4KTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1JlZ0V4cFJvd0ZpbHRlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1JlZ0V4cFJvd0ZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzZmQ5ZjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvUmVnRXhwUm93RmlsdGVyLmphdmEKQEAgLTAsMCArMSwzNDUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXAuRW50cnk7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogSW1wbGVtZW50YXRpb24gb2YgUm93RmlsdGVySW50ZXJmYWNlIHRoYXQgY2FuIGZpbHRlciBieSByb3drZXkgcmVndWxhcgorICogZXhwcmVzc2lvbiBhbmQvb3IgaW5kaXZpZHVhbCBjb2x1bW4gdmFsdWVzIChlcXVhbHMgY29tcGFyaXNvbiBvbmx5KS4gTXVsdGlwbGUKKyAqIGNvbHVtbiBmaWx0ZXJzIGltcGx5IGFuIGltcGxpY2l0IGNvbmp1bmN0aW9uIG9mIGZpbHRlciBjcml0ZXJpYS4KKyAqIAorICogTm90ZSB0aGF0IGNvbHVtbiB2YWx1ZSBmaWx0ZXJpbmcgaW4gdGhpcyBpbnRlcmZhY2UgaGFzIGJlZW4gcmVwbGFjZWQgYnkKKyAqIHtAbGluayBDb2x1bW5WYWx1ZUZpbHRlcn0uCisgKiBAZGVwcmVjYXRlZCBUaGlzIGludGVyZmFjZSBkb2Vzbid0IHJlYWxseSB3b3JrIHdlbGwgaW4gbmV3IEtleVZhbHVlIHdvcmxkLgorICogTmVlZHMgdG8gYmUgcmVmYWN0b3JlZC9yZW1vdmVkLiAgTWFya2luZyBpdCBhcyBkZXByZWNhdGVkIHRpbGwgaXQgZ2V0cworICogY2xlYW5lZCB1cC4gIEl0cyBhbHNvIGluZWZmaWNpZW50IGFzIHdyaXR0ZW4uCisgKi8KK3B1YmxpYyBjbGFzcyBSZWdFeHBSb3dGaWx0ZXIgaW1wbGVtZW50cyBSb3dGaWx0ZXJJbnRlcmZhY2UgeworCisgIHByaXZhdGUgUGF0dGVybiByb3dLZXlQYXR0ZXJuID0gbnVsbDsKKyAgcHJpdmF0ZSBTdHJpbmcgcm93S2V5UmVnRXhwID0gbnVsbDsKKyAgcHJpdmF0ZSBNYXA8Ynl0ZSBbXSwgYnl0ZVtdPiBlcXVhbHNNYXAgPQorICAgIG5ldyBUcmVlTWFwPGJ5dGUgW10sIGJ5dGVbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgIHByaXZhdGUgU2V0PGJ5dGUgW10+IG51bGxDb2x1bW5zID0KKyAgICBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKworICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciwgZmlsdGVycyBub3RoaW5nLiBSZXF1aXJlZCB0aG91Z2ggZm9yIFJQQworICAgKiBkZXNlcmlhbGl6YXRpb24uCisgICAqLworICBwdWJsaWMgUmVnRXhwUm93RmlsdGVyKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIHJvdyBrZXkgcmVndWxhciBleHByZXNzaW9uIHRvIGZpbHRlciBvbi4KKyAgICogCisgICAqIEBwYXJhbSByb3dLZXlSZWdFeHAKKyAgICovCisgIHB1YmxpYyBSZWdFeHBSb3dGaWx0ZXIoZmluYWwgU3RyaW5nIHJvd0tleVJlZ0V4cCkgeworICAgIHRoaXMucm93S2V5UmVnRXhwID0gcm93S2V5UmVnRXhwOworICB9CisKKyAgLyoqCisgICAqIEBkZXByZWNhdGVkIENvbHVtbiBmaWx0ZXJpbmcgaGFzIGJlZW4gcmVwbGFjZWQgYnkge0BsaW5rIENvbHVtblZhbHVlRmlsdGVyfQorICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgcm93IGtleSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZmlsdGVyIG9uLgorICAgKiAKKyAgICogQHBhcmFtIHJvd0tleVJlZ0V4cAorICAgKiBAcGFyYW0gY29sdW1uRmlsdGVyCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgUmVnRXhwUm93RmlsdGVyKGZpbmFsIFN0cmluZyByb3dLZXlSZWdFeHAsCisgICAgICBmaW5hbCBNYXA8Ynl0ZSBbXSwgQ2VsbD4gY29sdW1uRmlsdGVyKSB7CisgICAgdGhpcy5yb3dLZXlSZWdFeHAgPSByb3dLZXlSZWdFeHA7CisgICAgdGhpcy5zZXRDb2x1bW5GaWx0ZXJzKGNvbHVtbkZpbHRlcik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlIFtdIHJvd0tleSkgeworICAgIHJvd1Byb2Nlc3NlZChmaWx0ZXJlZCwgcm93S2V5LCAwLCByb3dLZXkubGVuZ3RoKTsKKyAgfQorCisKKyAgcHVibGljIHZvaWQgcm93UHJvY2Vzc2VkKGJvb2xlYW4gZmlsdGVyZWQsIGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAvL2RvZXNuJ3QgY2FyZQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc0Fsd2F5cygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgCisgIC8qKgorICAgKiBAZGVwcmVjYXRlZCBDb2x1bW4gZmlsdGVyaW5nIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IHtAbGluayBDb2x1bW5WYWx1ZUZpbHRlcn0KKyAgICogU3BlY2lmeSBhIHZhbHVlIHRoYXQgbXVzdCBiZSBtYXRjaGVkIGZvciB0aGUgZ2l2ZW4gY29sdW1uLgorICAgKiAKKyAgICogQHBhcmFtIGNvbEtleQorICAgKiAgICAgICAgICB0aGUgY29sdW1uIHRvIG1hdGNoIG9uCisgICAqIEBwYXJhbSB2YWx1ZQorICAgKiAgICAgICAgICB0aGUgdmFsdWUgdGhhdCBtdXN0IGVxdWFsIHRoZSBzdG9yZWQgdmFsdWUuCisgICAqLworICBARGVwcmVjYXRlZAorICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5GaWx0ZXIoZmluYWwgYnl0ZSBbXSBjb2xLZXksIGZpbmFsIGJ5dGVbXSB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICBudWxsQ29sdW1ucy5hZGQoY29sS2V5KTsKKyAgICB9IGVsc2UgeworICAgICAgZXF1YWxzTWFwLnB1dChjb2xLZXksIHZhbHVlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQGRlcHJlY2F0ZWQgQ29sdW1uIGZpbHRlcmluZyBoYXMgYmVlbiByZXBsYWNlZCBieSB7QGxpbmsgQ29sdW1uVmFsdWVGaWx0ZXJ9CisgICAqIFNldCBjb2x1bW4gZmlsdGVycyBmb3IgYSBudW1iZXIgb2YgY29sdW1ucy4KKyAgICogCisgICAqIEBwYXJhbSBjb2x1bW5GaWx0ZXIKKyAgICogICAgICAgICAgTWFwIG9mIGNvbHVtbnMgd2l0aCB2YWx1ZSBjcml0ZXJpYS4KKyAgICovCisgIEBEZXByZWNhdGVkCisgIHB1YmxpYyB2b2lkIHNldENvbHVtbkZpbHRlcnMoZmluYWwgTWFwPGJ5dGUgW10sIENlbGw+IGNvbHVtbkZpbHRlcikgeworICAgIGlmIChudWxsID09IGNvbHVtbkZpbHRlcikgeworICAgICAgbnVsbENvbHVtbnMuY2xlYXIoKTsKKyAgICAgIGVxdWFsc01hcC5jbGVhcigpOworICAgIH0gZWxzZSB7CisgICAgICBmb3IgKEVudHJ5PGJ5dGUgW10sIENlbGw+IGVudHJ5IDogY29sdW1uRmlsdGVyLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgc2V0Q29sdW1uRmlsdGVyKGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpLmdldFZhbHVlKCkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIC8vIE5vdGhpbmcgdG8gcmVzZXQKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlckFsbFJlbWFpbmluZygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoZmluYWwgYnl0ZSBbXSByb3dLZXkpIHsKKyAgICByZXR1cm4gZmlsdGVyUm93S2V5KHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoYnl0ZVtdIHJvd0tleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIHJldHVybiAoZmlsdGVyc0J5Um93S2V5KCkgJiYgcm93S2V5ICE9IG51bGwpPworICAgICAgIWdldFJvd0tleVBhdHRlcm4oKS5tYXRjaGVyKEJ5dGVzLnRvU3RyaW5nKHJvd0tleSwgb2Zmc2V0LCBsZW5ndGgpKS5tYXRjaGVzKCk6CisgICAgICBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlckNvbHVtbihmaW5hbCBieXRlIFtdIHJvd0tleSwgZmluYWwgYnl0ZSBbXSBjb2xLZXksCisgICAgICBmaW5hbCBieXRlW10gZGF0YSkgeworICAgIGlmIChmaWx0ZXJSb3dLZXkocm93S2V5KSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGlmIChmaWx0ZXJzQnlDb2x1bW5WYWx1ZSgpKSB7CisgICAgICBieXRlW10gZmlsdGVyVmFsdWUgPSBlcXVhbHNNYXAuZ2V0KGNvbEtleSk7CisgICAgICBpZiAobnVsbCAhPSBmaWx0ZXJWYWx1ZSkgeworICAgICAgICByZXR1cm4gIUFycmF5cy5lcXVhbHMoZmlsdGVyVmFsdWUsIGRhdGEpOworICAgICAgfQorICAgIH0KKyAgICBpZiAobnVsbENvbHVtbnMuY29udGFpbnMoY29sS2V5KSkgeworICAgICAgaWYgKGRhdGEgIT0gbnVsbCAvKiBERUxFVEUgSVMgSU4gS0VZIE5PVyAmJiAhSExvZ0VkaXQuaXNEZWxldGVkKGRhdGEpKi8pIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGJ5dGVbXSByb3dLZXksIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCwKKyAgICAgIGJ5dGUgW10gY29sdW5tTmFtZSwgaW50IGNvZmZzZXQsIGludCBjbGVuZ3RoLCBieXRlW10gY29sdW1uVmFsdWUsCisgICAgICBpbnQgdm9mZnNldCwgaW50IHZsZW5ndGgpIHsKKyAgICBpZiAoZmlsdGVyUm93S2V5KHJvd0tleSwgcm9mZnNldCwgcmxlbmd0aCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBieXRlIFtdIGNvbGtleSA9IG51bGw7CisgICAgaWYgKGZpbHRlcnNCeUNvbHVtblZhbHVlKCkpIHsKKyAgICAgIGNvbGtleSA9IGdldENvbEtleShjb2x1bm1OYW1lLCBjb2Zmc2V0LCBjbGVuZ3RoKTsKKyAgICAgIGJ5dGUgW10gZmlsdGVyVmFsdWUgPSBlcXVhbHNNYXAuZ2V0KGNvbGtleSk7CisgICAgICBpZiAobnVsbCAhPSBmaWx0ZXJWYWx1ZSkgeworICAgICAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKGZpbHRlclZhbHVlLCAwLCBmaWx0ZXJWYWx1ZS5sZW5ndGgsIGNvbHVtblZhbHVlLAorICAgICAgICAgIHZvZmZzZXQsIHZsZW5ndGgpICE9IDA7CisgICAgICB9CisgICAgfQorICAgIGlmIChjb2xrZXkgPT0gbnVsbCkgeworICAgICAgY29sa2V5ID0gZ2V0Q29sS2V5KGNvbHVubU5hbWUsIGNvZmZzZXQsIGNsZW5ndGgpOworICAgIH0KKyAgICBpZiAobnVsbENvbHVtbnMuY29udGFpbnMoY29sa2V5KSkgeworICAgICAgaWYgKGNvbHVtblZhbHVlICE9IG51bGwgLyogVE9ETzogRklYISEhICYmICFITG9nRWRpdC5pc0RlbGV0ZWQoZGF0YSkqLykgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHJpdmF0ZSBieXRlIFtdIGdldENvbEtleShmaW5hbCBieXRlIFtdIGMsIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBieXRlIFtdIGNvbGtleSA9IG51bGw7CisgICAgaWYgKG9mZnNldCA9PSAwKSB7CisgICAgICBjb2xrZXkgPSBjOworICAgIH0gZWxzZSB7CisgICAgICBjb2xrZXkgPSBuZXcgYnl0ZSBbbGVuZ3RoXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYywgb2Zmc2V0LCBjb2xrZXksIDAsIGxlbmd0aCk7CisgICAgfQorICAgIHJldHVybiBjb2xrZXk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3coZmluYWwgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+IGNvbHVtbnMpIHsKKyAgICBmb3IgKEVudHJ5PGJ5dGUgW10sIENlbGw+IGNvbCA6IGNvbHVtbnMuZW50cnlTZXQoKSkgeworICAgICAgaWYgKG51bGxDb2x1bW5zLmNvbnRhaW5zKGNvbC5nZXRLZXkoKSkKKyAgICAgICAgICAvKiBERUxFVEUgSVMgSU4gS0VZIE5PVyAmJiAhSExvZ0VkaXQuaXNEZWxldGVkKGNvbC5nZXRWYWx1ZSgpLmdldFZhbHVlKCkpKi8pIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIGZvciAoYnl0ZSBbXSBjb2wgOiBlcXVhbHNNYXAua2V5U2V0KCkpIHsKKyAgICAgIGlmICghY29sdW1ucy5jb250YWluc0tleShjb2wpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBUSElTIE1FVEhPRCBJUyBIT1JSSURMWSBFWFBFTlNJVkUgVE8gUlVOLiAgTkVFRFMgRklYVVAuCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhMaXN0PEtleVZhbHVlPiBrdnMpIHsKKyAgICBmb3IgKEtleVZhbHVlIGt2OiBrdnMpIHsKKyAgICAgIGJ5dGUgW10gY29sdW1uID0ga3YuZ2V0Q29sdW1uKCk7CisgICAgICBpZiAobnVsbENvbHVtbnMuY29udGFpbnMoY29sdW1uKSAmJiAha3YuaXNEZWxldGVUeXBlKCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAoIWVxdWFsc01hcC5jb250YWluc0tleShjb2x1bW4pKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gZmlsdGVyc0J5Q29sdW1uVmFsdWUoKSB7CisgICAgcmV0dXJuIGVxdWFsc01hcCAhPSBudWxsICYmIGVxdWFsc01hcC5zaXplKCkgPiAwOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGZpbHRlcnNCeVJvd0tleSgpIHsKKyAgICByZXR1cm4gbnVsbCAhPSByb3dLZXlQYXR0ZXJuIHx8IG51bGwgIT0gcm93S2V5UmVnRXhwOworICB9CisKKyAgcHJpdmF0ZSBTdHJpbmcgZ2V0Um93S2V5UmVnRXhwKCkgeworICAgIGlmIChudWxsID09IHJvd0tleVJlZ0V4cCAmJiByb3dLZXlQYXR0ZXJuICE9IG51bGwpIHsKKyAgICAgIHJvd0tleVJlZ0V4cCA9IHJvd0tleVBhdHRlcm4udG9TdHJpbmcoKTsKKyAgICB9CisgICAgcmV0dXJuIHJvd0tleVJlZ0V4cDsKKyAgfQorCisgIHByaXZhdGUgUGF0dGVybiBnZXRSb3dLZXlQYXR0ZXJuKCkgeworICAgIGlmIChyb3dLZXlQYXR0ZXJuID09IG51bGwgJiYgcm93S2V5UmVnRXhwICE9IG51bGwpIHsKKyAgICAgIHJvd0tleVBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUocm93S2V5UmVnRXhwKTsKKyAgICB9CisgICAgcmV0dXJuIHJvd0tleVBhdHRlcm47CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKGZpbmFsIERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBib29sZWFuIGhhc1Jvd0tleVBhdHRlcm4gPSBpbi5yZWFkQm9vbGVhbigpOworICAgIGlmIChoYXNSb3dLZXlQYXR0ZXJuKSB7CisgICAgICByb3dLZXlSZWdFeHAgPSBpbi5yZWFkVVRGKCk7CisgICAgfQorICAgIC8vIGVxdWFscyBtYXAKKyAgICBlcXVhbHNNYXAuY2xlYXIoKTsKKyAgICBpbnQgc2l6ZSA9IGluLnJlYWRJbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgYnl0ZSBbXSBrZXkgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICAgIGludCBsZW4gPSBpbi5yZWFkSW50KCk7CisgICAgICBieXRlW10gdmFsdWUgPSBudWxsOworICAgICAgaWYgKGxlbiA+PSAwKSB7CisgICAgICAgIHZhbHVlID0gbmV3IGJ5dGVbbGVuXTsKKyAgICAgICAgaW4ucmVhZEZ1bGx5KHZhbHVlKTsKKyAgICAgIH0KKyAgICAgIHNldENvbHVtbkZpbHRlcihrZXksIHZhbHVlKTsKKyAgICB9CisgICAgLy8gbnVsbENvbHVtbnMKKyAgICBudWxsQ29sdW1ucy5jbGVhcigpOworICAgIHNpemUgPSBpbi5yZWFkSW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgIHNldENvbHVtbkZpbHRlcihCeXRlcy5yZWFkQnl0ZUFycmF5KGluKSwgbnVsbCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMpIHsKKyAgICBTZXQ8Ynl0ZSBbXT4gaW52YWxpZHMgPSBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICBmb3IgKGJ5dGUgW10gY29sS2V5IDogZ2V0RmlsdGVyQ29sdW1ucygpKSB7CisgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CisgICAgICBmb3IgKGJ5dGUgW10gY29sIDogY29sdW1ucykgeworICAgICAgICBpZiAoQnl0ZXMuZXF1YWxzKGNvbCwgY29sS2V5KSkgeworICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKCFmb3VuZCkgeworICAgICAgICBpbnZhbGlkcy5hZGQoY29sS2V5KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoaW52YWxpZHMuc2l6ZSgpID4gMCkgeworICAgICAgdGhyb3cgbmV3IEludmFsaWRSb3dGaWx0ZXJFeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAiUm93RmlsdGVyIGNvbnRhaW5zIGNyaXRlcmlhIG9uIGNvbHVtbnMgJXMgbm90IGluICVzIiwgaW52YWxpZHMsCisgICAgICAgICAgQXJyYXlzLnRvU3RyaW5nKGNvbHVtbnMpKSk7CisgICAgfQorICB9CisKKyAgQERlcHJlY2F0ZWQKKyAgcHJpdmF0ZSBTZXQ8Ynl0ZSBbXT4gZ2V0RmlsdGVyQ29sdW1ucygpIHsKKyAgICBTZXQ8Ynl0ZSBbXT4gY29scyA9IG5ldyBUcmVlU2V0PGJ5dGUgW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgIGNvbHMuYWRkQWxsKGVxdWFsc01hcC5rZXlTZXQoKSk7CisgICAgY29scy5hZGRBbGwobnVsbENvbHVtbnMpOworICAgIHJldHVybiBjb2xzOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCFmaWx0ZXJzQnlSb3dLZXkoKSkgeworICAgICAgb3V0LndyaXRlQm9vbGVhbihmYWxzZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIG91dC53cml0ZUJvb2xlYW4odHJ1ZSk7CisgICAgICBvdXQud3JpdGVVVEYoZ2V0Um93S2V5UmVnRXhwKCkpOworICAgIH0KKworICAgIC8vIGVxdWFsc01hcAorICAgIG91dC53cml0ZUludChlcXVhbHNNYXAuc2l6ZSgpKTsKKyAgICBmb3IgKEVudHJ5PGJ5dGUgW10sIGJ5dGVbXT4gZW50cnkgOiBlcXVhbHNNYXAuZW50cnlTZXQoKSkgeworICAgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCBlbnRyeS5nZXRLZXkoKSk7CisgICAgICBieXRlW10gdmFsdWUgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgb3V0LndyaXRlSW50KHZhbHVlLmxlbmd0aCk7CisgICAgICBvdXQud3JpdGUodmFsdWUpOworICAgIH0KKworICAgIC8vIG51bGwgY29sdW1ucworICAgIG91dC53cml0ZUludChudWxsQ29sdW1ucy5zaXplKCkpOworICAgIGZvciAoYnl0ZSBbXSBjb2wgOiBudWxsQ29sdW1ucykgeworICAgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCBjb2wpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9SZWdleFN0cmluZ0NvbXBhcmF0b3IuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9SZWdleFN0cmluZ0NvbXBhcmF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMmJkZmZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1JlZ2V4U3RyaW5nQ29tcGFyYXRvci5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGhpcyBjb21wYXJhdG9yIGlzIGZvciB1c2Ugd2l0aCBDb2x1bW5WYWx1ZUZpbHRlciwgZm9yIGZpbHRlcmluZyBiYXNlZCBvbgorICogdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gY29sdW1uLiBVc2UgaXQgdG8gdGVzdCBpZiBhIGdpdmVuIHJlZ3VsYXIgZXhwcmVzc2lvbgorICogbWF0Y2hlcyBhIGNlbGwgdmFsdWUgaW4gdGhlIGNvbHVtbi4KKyAqIDxwPgorICogT25seSBFUVVBTCBvciBOT1RfRVFVQUwgdGVzdHMgYXJlIHZhbGlkIHdpdGggdGhpcyBjb21wYXJhdG9yLiAKKyAqIDxwPgorICogRm9yIGV4YW1wbGU6CisgKiA8cD4KKyAqIDxwcmU+CisgKiBDb2x1bW5WYWx1ZUZpbHRlciBjdmYgPQorICogICBuZXcgQ29sdW1uVmFsdWVGaWx0ZXIoImNvbCIsCisgKiAgICAgQ29sdW1uVmFsdWVGaWx0ZXIuQ29tcGFyZU9wLkVRVUFMLAorICogICAgIG5ldyBSZWdleFN0cmluZ0NvbXBhcmF0b3IoCisgKiAgICAgICAvLyB2NCBJUCBhZGRyZXNzCisgKiAgICAgICAiKCgoMjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/KVxcLil7MywzfSIgKworICogICAgICAgICAiKDI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPykpKFxcL1swLTldKyk/IiArCisgKiAgICAgICAgICJ8IiArCisgKiAgICAgICAvLyB2NiBJUCBhZGRyZXNzCisgKiAgICAgICAiKCgoW1xcZEEtRmEtZl17MSw0fTopezd9W1xcZEEtRmEtZl17MSw0fSkoOihbXFxkXXsxLDN9LikiICsKKyAqICAgICAgICAgInszfVtcXGRdezEsM30pPykoXFwvWzAtOV0rKT8iKSk7CisgKiA8L3ByZT4KKyAqLworcHVibGljIGNsYXNzIFJlZ2V4U3RyaW5nQ29tcGFyYXRvciBpbXBsZW1lbnRzIFdyaXRhYmxlQnl0ZUFycmF5Q29tcGFyYWJsZSB7CisKKyAgcHJpdmF0ZSBQYXR0ZXJuIHBhdHRlcm47CisKKyAgLyoqIE51bGxhcnkgY29uc3RydWN0b3IgZm9yIFdyaXRhYmxlICovCisgIHB1YmxpYyBSZWdleFN0cmluZ0NvbXBhcmF0b3IoKSB7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIGV4cHIgYSB2YWxpZCByZWd1bGFyIGV4cHJlc3Npb24KKyAgICovCisgIHB1YmxpYyBSZWdleFN0cmluZ0NvbXBhcmF0b3IoU3RyaW5nIGV4cHIpIHsKKyAgICB0aGlzLnBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoZXhwcik7CisgIH0KKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhieXRlW10gdmFsdWUpIHsKKyAgICAvLyBVc2UgZmluZCgpIGZvciBzdWJzZXF1ZW5jZSBtYXRjaCBpbnN0ZWFkIG9mIG1hdGNoZXMoKSAoZnVsbCBzZXF1ZW5jZQorICAgIC8vIG1hdGNoKSB0byBhZGhlcmUgdG8gdGhlIHByaW5jaXBsZSBvZiBsZWFzdCBzdXJwcmlzZS4KKyAgICByZXR1cm4gcGF0dGVybi5tYXRjaGVyKEJ5dGVzLnRvU3RyaW5nKHZhbHVlKSkuZmluZCgpID8gMCA6IDE7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLnBhdHRlcm4gPSBQYXR0ZXJuLmNvbXBpbGUoaW4ucmVhZFVURigpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG91dC53cml0ZVVURihwYXR0ZXJuLnRvU3RyaW5nKCkpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Sb3dGaWx0ZXJJbnRlcmZhY2UuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Sb3dGaWx0ZXJJbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZGI1ZjQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Jvd0ZpbHRlckludGVyZmFjZS5qYXZhCkBAIC0wLDAgKzEsMTcwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogCisgKiBJbnRlcmZhY2UgdXNlZCBmb3Igcm93LWxldmVsIGZpbHRlcnMgYXBwbGllZCB0byBIUmVnaW9uLkhTY2FubmVyIHNjYW4KKyAqIHJlc3VsdHMgZHVyaW5nIGNhbGxzIHRvIG5leHQoKS4KKyAqIFRPRE86IE1ha2UgRmlsdGVycyB1c2UgcHJvcGVyIGNvbXBhcmF0b3IgY29tcGFyaW5nIHJvd3MuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgUm93RmlsdGVySW50ZXJmYWNlIGV4dGVuZHMgV3JpdGFibGUgeworICAvKioKKyAgICogUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGUgZmlsdGVyLiBVc2VkIHByaW9yIHRvIHRoZSBzdGFydCBvZiBhIFJlZ2lvbiBzY2FuLgorICAgKiAKKyAgICovCisgIHZvaWQgcmVzZXQoKTsKKworICAvKioKKyAgICogQ2FsbGVkIHRvIGxldCBmaWx0ZXIga25vdyB0aGUgZmluYWwgZGVjaXNpb24gKHRvIHBhc3Mgb3IgZmlsdGVyKSBvbiBhIAorICAgKiBnaXZlbiByb3cuICBXaXRoIG91dCBIU2Nhbm5lciBjYWxsaW5nIHRoaXMsIHRoZSBmaWx0ZXIgZG9lcyBub3Qga25vdyBpZiBhIAorICAgKiByb3cgcGFzc2VkIGZpbHRlcmluZyBldmVuIGlmIGl0IHBhc3NlZCB0aGUgcm93IGl0c2VsZiBiZWNhdXNlIG90aGVyIAorICAgKiBmaWx0ZXJzIG1heSBoYXZlIGZhaWxlZCB0aGUgcm93LiBFLmcuIHdoZW4gdGhpcyBmaWx0ZXIgaXMgYSBtZW1iZXIgb2YgYSAKKyAgICogUm93RmlsdGVyU2V0IHdpdGggYW4gT1Igb3BlcmF0b3IuCisgICAqIAorICAgKiBAc2VlIFJvd0ZpbHRlclNldAorICAgKiBAcGFyYW0gZmlsdGVyZWQKKyAgICogQHBhcmFtIGtleQorICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNyb3dQcm9jZXNzZWQoYm9vbGVhbiwgYnl0ZVtdLCBpbnQsIGludCl9IGluc3RlYWQuCisgICAqLworICB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlIFtdIGtleSk7CisKKyAgLyoqCisgICAqIENhbGxlZCB0byBsZXQgZmlsdGVyIGtub3cgdGhlIGZpbmFsIGRlY2lzaW9uICh0byBwYXNzIG9yIGZpbHRlcikgb24gYSAKKyAgICogZ2l2ZW4gcm93LiAgV2l0aCBvdXQgSFNjYW5uZXIgY2FsbGluZyB0aGlzLCB0aGUgZmlsdGVyIGRvZXMgbm90IGtub3cgaWYgYSAKKyAgICogcm93IHBhc3NlZCBmaWx0ZXJpbmcgZXZlbiBpZiBpdCBwYXNzZWQgdGhlIHJvdyBpdHNlbGYgYmVjYXVzZSBvdGhlciAKKyAgICogZmlsdGVycyBtYXkgaGF2ZSBmYWlsZWQgdGhlIHJvdy4gRS5nLiB3aGVuIHRoaXMgZmlsdGVyIGlzIGEgbWVtYmVyIG9mIGEgCisgICAqIFJvd0ZpbHRlclNldCB3aXRoIGFuIE9SIG9wZXJhdG9yLgorICAgKiAKKyAgICogQHNlZSBSb3dGaWx0ZXJTZXQKKyAgICogQHBhcmFtIGZpbHRlcmVkCisgICAqIEBwYXJhbSBrZXkKKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqLworICB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlIFtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCk7CisKKyAgLyoqCisgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGZpbHRlciBzaG91bGQgYWx3YXlzIGJlIHByb2Nlc3NlZCBpbiBhbnkgCisgICAqIGZpbHRlcmluZyBjYWxsLiAgVGhpcyBwcmVjYXV0aW9uIGlzIG5lY2Vzc2FyeSBmb3IgZmlsdGVycyB0aGF0IG1haW50YWluIAorICAgKiBzdGF0ZSBhbmQgbmVlZCB0byBiZSB1cGRhdGVkIGFjY29yZGluZyB0byB0aGVpciByZXNwb25zZSB0byBmaWx0ZXJpbmcgCisgICAqIGNhbGxzIChzZWUgV2hpbGVNYXRjaFJvd0ZpbHRlciBmb3IgYW4gZXhhbXBsZSkuICBBdCB0aW1lcywgZmlsdGVycyBuZXN0ZWQgCisgICAqIGluIFJvd0ZpbHRlclNldHMgbWF5IG9yIG1heSBub3QgYmUgY2FsbGVkIGJlY2F1c2UgdGhlIFJvd0ZpbHRlclNldCAKKyAgICogZGV0ZXJtaW5lcyBhIHJlc3VsdCBhcyBmYXN0IGFzIHBvc3NpYmxlLiAgUmV0dXJuaW5nIHRydWUgZm9yIAorICAgKiBwcm9jZXNzQWx3YXlzKCkgZW5zdXJlcyB0aGF0IHRoZSBmaWx0ZXIgd2lsbCBhbHdheXMgYmUgY2FsbGVkLgorICAgKiAKKyAgICogQHJldHVybiB3aGV0aGVyIG9yIG5vdCB0byBhbHdheXMgcHJvY2VzcyB0aGUgZmlsdGVyCisgICAqLworICBib29sZWFuIHByb2Nlc3NBbHdheXMoKTsKKyAgCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBmaWx0ZXIgaGFzIGRlY2lkZWQgdGhhdCBhbGwgcmVtYWluaW5nIHJlc3VsdHMgc2hvdWxkIGJlCisgICAqIGZpbHRlcmVkIChza2lwcGVkKS4gVGhpcyBpcyB1c2VkIHRvIHByZXZlbnQgdGhlIHNjYW5uZXIgZnJvbSBzY2FubmluZyBhCisgICAqIHRoZSByZXN0IG9mIHRoZSBIUmVnaW9uIHdoZW4gZm9yIHN1cmUgdGhlIGZpbHRlciB3aWxsIGV4Y2x1ZGUgYWxsCisgICAqIHJlbWFpbmluZyByb3dzLgorICAgKiAKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaWx0ZXIgaW50ZW5kcyB0byBmaWx0ZXIgYWxsIHJlbWFpbmluZyByb3dzLgorICAgKi8KKyAgYm9vbGVhbiBmaWx0ZXJBbGxSZW1haW5pbmcoKTsKKworICAvKioKKyAgICogRmlsdGVycyBvbiBqdXN0IGEgcm93IGtleS4gVGhpcyBpcyB0aGUgZmlyc3QgY2hhbmNlIHRvIHN0b3AgYSByb3cuCisgICAqIAorICAgKiBAcGFyYW0gcm93S2V5CisgICAqIEByZXR1cm4gdHJ1ZSBpZiBnaXZlbiByb3cga2V5IGlzIGZpbHRlcmVkIGFuZCByb3cgc2hvdWxkIG5vdCBiZSBwcm9jZXNzZWQuCisgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2ZpbHRlclJvd0tleShieXRlW10sIGludCwgaW50KX0gaW5zdGVhZC4KKyAgICovCisgIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGUgW10gcm93S2V5KTsKKworICAvKioKKyAgICogRmlsdGVycyBvbiBqdXN0IGEgcm93IGtleS4gVGhpcyBpcyB0aGUgZmlyc3QgY2hhbmNlIHRvIHN0b3AgYSByb3cuCisgICAqIAorICAgKiBAcGFyYW0gcm93S2V5CisgICAqIEBwYXJhbSBvZmZzZXQKKyAgICogQHBhcmFtIGxlbmd0aAorICAgKiBAcmV0dXJuIHRydWUgaWYgZ2l2ZW4gcm93IGtleSBpcyBmaWx0ZXJlZCBhbmQgcm93IHNob3VsZCBub3QgYmUgcHJvY2Vzc2VkLgorICAgKi8KKyAgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoZmluYWwgYnl0ZSBbXSByb3dLZXksIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpOworCisgIC8qKgorICAgKiBGaWx0ZXJzIG9uIHJvdyBrZXksIGNvbHVtbiBuYW1lLCBhbmQgY29sdW1uIHZhbHVlLiBUaGlzIHdpbGwgdGFrZSBpbmRpdmlkdWFsIGNvbHVtbnMgb3V0IG9mIGEgcm93LCAKKyAgICogYnV0IHRoZSByZXN0IG9mIHRoZSByb3cgd2lsbCBzdGlsbCBnZXQgdGhyb3VnaC4KKyAgICogCisgICAqIEBwYXJhbSByb3dLZXkgcm93IGtleSB0byBmaWx0ZXIgb24uCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lIGNvbHVtbiBuYW1lIHRvIGZpbHRlciBvbgorICAgKiBAcGFyYW0gY29sdW1uVmFsdWUgY29sdW1uIHZhbHVlIHRvIGZpbHRlciBvbgorICAgKiBAcmV0dXJuIHRydWUgaWYgcm93IGZpbHRlcmVkIGFuZCBzaG91bGQgbm90IGJlIHByb2Nlc3NlZC4KKyAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZmlsdGVyQ29sdW1uKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50LCBpbnQpfQorICAgKiBpbnN0ZWFkLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgYm9vbGVhbiBmaWx0ZXJDb2x1bW4oZmluYWwgYnl0ZSBbXSByb3dLZXksIGZpbmFsIGJ5dGUgW10gY29sdW1uTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uVmFsdWUpOworCisgIC8qKgorICAgKiBGaWx0ZXJzIG9uIHJvdyBrZXksIGNvbHVtbiBuYW1lLCBhbmQgY29sdW1uIHZhbHVlLiBUaGlzIHdpbGwgdGFrZSBpbmRpdmlkdWFsIGNvbHVtbnMgb3V0IG9mIGEgcm93LCAKKyAgICogYnV0IHRoZSByZXN0IG9mIHRoZSByb3cgd2lsbCBzdGlsbCBnZXQgdGhyb3VnaC4KKyAgICogCisgICAqIEBwYXJhbSByb3dLZXkgcm93IGtleSB0byBmaWx0ZXIgb24uCisgICAqIEBwYXJhbSBjb2x1bm1OYW1lIGNvbHVtbiBuYW1lIHRvIGZpbHRlciBvbgorICAgKiBAcGFyYW0gY29sdW1uVmFsdWUgY29sdW1uIHZhbHVlIHRvIGZpbHRlciBvbgorICAgKiBAcmV0dXJuIHRydWUgaWYgcm93IGZpbHRlcmVkIGFuZCBzaG91bGQgbm90IGJlIHByb2Nlc3NlZC4KKyAgICovCisgIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGZpbmFsIGJ5dGUgW10gcm93S2V5LCBmaW5hbCBpbnQgcm9mZnNldCwKKyAgICAgIGZpbmFsIGludCBybGVuZ3RoLCBmaW5hbCBieXRlIFtdIGNvbHVubU5hbWUsIGZpbmFsIGludCBjb2Zmc2V0LAorICAgICAgZmluYWwgaW50IGNsZW5ndGgsIGZpbmFsIGJ5dGUgW10gY29sdW1uVmFsdWUsIGZpbmFsIGludCB2b2Zmc2V0LAorICAgICAgZmluYWwgaW50IHZsZW5ndGgpOworCisgIC8qKgorICAgKiBGaWx0ZXIgb24gdGhlIGZ1bGx5IGFzc2VtYmxlZCByb3cuIFRoaXMgaXMgdGhlIGxhc3QgY2hhbmNlIHRvIHN0b3AgYSByb3cuIAorICAgKiAKKyAgICogQHBhcmFtIGNvbHVtbnMKKyAgICogQHJldHVybiB0cnVlIGlmIHJvdyBmaWx0ZXJlZCBhbmQgc2hvdWxkIG5vdCBiZSBwcm9jZXNzZWQuCisgICAqLworICBib29sZWFuIGZpbHRlclJvdyhmaW5hbCBTb3J0ZWRNYXA8Ynl0ZSBbXSwgQ2VsbD4gY29sdW1ucyk7CisKKyAgLyoqCisgICAqIEZpbHRlciBvbiB0aGUgZnVsbHkgYXNzZW1ibGVkIHJvdy4gVGhpcyBpcyB0aGUgbGFzdCBjaGFuY2UgdG8gc3RvcCBhIHJvdy4gCisgICAqIAorICAgKiBAcGFyYW0gcmVzdWx0cworICAgKiBAcmV0dXJuIHRydWUgaWYgcm93IGZpbHRlcmVkIGFuZCBzaG91bGQgbm90IGJlIHByb2Nlc3NlZC4KKyAgICovCisgIGJvb2xlYW4gZmlsdGVyUm93KGZpbmFsIExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpOworCisgIC8qKgorICAgKiBWYWxpZGF0ZXMgdGhhdCB0aGlzIGZpbHRlciBhcHBsaWVzIG9ubHkgdG8gYSBzdWJzZXQgb2YgdGhlIGdpdmVuIGNvbHVtbnMuCisgICAqIFRoaXMgY2hlY2sgaXMgZG9uZSBwcmlvciB0byBvcGVuaW5nIG9mIHNjYW5uZXIgZHVlIHRvIHRoZSBsaW1pdGF0aW9uIHRoYXQKKyAgICogZmlsdGVyaW5nIG9mIGNvbHVtbnMgaXMgZGVwZW5kZW50IG9uIHRoZSByZXRyaWV2YWwgb2YgdGhvc2UgY29sdW1ucyB3aXRoaW4KKyAgICogdGhlIEhSZWdpb24uIENyaXRlcmlhIG9uIGNvbHVtbnMgdGhhdCBhcmUgbm90IHBhcnQgb2YgYSBzY2FubmVyJ3MgY29sdW1uCisgICAqIGxpc3Qgd2lsbCBiZSBpZ25vcmVkLiBJbiB0aGUgY2FzZSBvZiBudWxsIHZhbHVlIGZpbHRlcnMsIGFsbCByb3dzIHdpbGwgcGFzcworICAgKiB0aGUgZmlsdGVyLiBUaGlzIGJlaGF2aW9yIHNob3VsZCBiZSAndW5kZWZpbmVkJyBmb3IgdGhlIHVzZXIgYW5kIHRoZXJlZm9yZQorICAgKiBub3QgcGVybWl0dGVkLgorICAgKiAKKyAgICogQHBhcmFtIGNvbHVtbnMKKyAgICovCisgIHZvaWQgdmFsaWRhdGUoZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMpOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Sb3dGaWx0ZXJTZXQuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Sb3dGaWx0ZXJTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ODE2ODQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Jvd0ZpbHRlclNldC5qYXZhCkBAIC0wLDAgKzEsMjkxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLk9iamVjdFdyaXRhYmxlOworCisvKioKKyAqIEltcGxlbWVudGF0aW9uIG9mIFJvd0ZpbHRlckludGVyZmFjZSB0aGF0IHJlcHJlc2VudHMgYSBzZXQgb2YgUm93RmlsdGVycworICogd2hpY2ggd2lsbCBiZSBldmFsdWF0ZWQgd2l0aCBhIHNwZWNpZmllZCBib29sZWFuIG9wZXJhdG9yIE1VU1RfUEFTU19BTEwgCisgKiAoIUFORCkgb3IgTVVTVF9QQVNTX09ORSAoIU9SKS4gIFNpbmNlIHlvdSBjYW4gdXNlIFJvd0ZpbHRlclNldHMgYXMgY2hpbGRyZW4gCisgKiBvZiBSb3dGaWx0ZXJTZXQsIHlvdSBjYW4gY3JlYXRlIGEgaGllcmFyY2h5IG9mIGZpbHRlcnMgdG8gYmUgZXZhbHVhdGVkLgorICovCitwdWJsaWMgY2xhc3MgUm93RmlsdGVyU2V0IGltcGxlbWVudHMgUm93RmlsdGVySW50ZXJmYWNlIHsKKworICAvKiogc2V0IG9wZXJhdG9yICovCisgIHB1YmxpYyBzdGF0aWMgZW51bSBPcGVyYXRvciB7CisgICAgLyoqICFBTkQgKi8KKyAgICBNVVNUX1BBU1NfQUxMLAorICAgIC8qKiAhT1IgKi8KKyAgICBNVVNUX1BBU1NfT05FCisgIH0KKworICBwcml2YXRlIE9wZXJhdG9yIG9wZXJhdG9yID0gT3BlcmF0b3IuTVVTVF9QQVNTX0FMTDsKKyAgcHJpdmF0ZSBTZXQ8Um93RmlsdGVySW50ZXJmYWNlPiBmaWx0ZXJzID0gbmV3IEhhc2hTZXQ8Um93RmlsdGVySW50ZXJmYWNlPigpOworCisgIC8qKgorICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLCBmaWx0ZXJzIG5vdGhpbmcuIFJlcXVpcmVkIHRob3VnaCBmb3IgUlBDCisgICAqIGRlc2VyaWFsaXphdGlvbi4KKyAgICovCisgIHB1YmxpYyBSb3dGaWx0ZXJTZXQoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgc2V0IG9mIFJvd0ZpbHRlcnMuIFRoZSBkZWZhdWx0IG9wZXJhdG9yIAorICAgKiBNVVNUX1BBU1NfQUxMIGlzIGFzc3VtZWQuCisgICAqIAorICAgKiBAcGFyYW0gcm93RmlsdGVycworICAgKi8KKyAgcHVibGljIFJvd0ZpbHRlclNldChmaW5hbCBTZXQ8Um93RmlsdGVySW50ZXJmYWNlPiByb3dGaWx0ZXJzKSB7CisgICAgdGhpcy5maWx0ZXJzID0gcm93RmlsdGVyczsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgc2V0IG9mIFJvd0ZpbHRlcnMgYW5kIGFuIG9wZXJhdG9yLgorICAgKiAKKyAgICogQHBhcmFtIG9wZXJhdG9yIE9wZXJhdG9yIHRvIHByb2Nlc3MgZmlsdGVyIHNldCB3aXRoLgorICAgKiBAcGFyYW0gcm93RmlsdGVycyBTZXQgb2Ygcm93IGZpbHRlcnMuCisgICAqLworICBwdWJsaWMgUm93RmlsdGVyU2V0KGZpbmFsIE9wZXJhdG9yIG9wZXJhdG9yLAorICAgICAgZmluYWwgU2V0PFJvd0ZpbHRlckludGVyZmFjZT4gcm93RmlsdGVycykgeworICAgIHRoaXMuZmlsdGVycyA9IHJvd0ZpbHRlcnM7CisgICAgdGhpcy5vcGVyYXRvciA9IG9wZXJhdG9yOworICB9CisKKyAgLyoqIEdldCB0aGUgb3BlcmF0b3IuCisgICAqIAorICAgKiBAcmV0dXJuIG9wZXJhdG9yCisgICAqLworICBwdWJsaWMgT3BlcmF0b3IgZ2V0T3BlcmF0b3IoKSB7CisgICAgcmV0dXJuIG9wZXJhdG9yOworICB9CisgIAorICAvKiogR2V0IHRoZSBmaWx0ZXJzLgorICAgKiAKKyAgICogQHJldHVybiBmaWx0ZXJzCisgICAqLworICBwdWJsaWMgU2V0PFJvd0ZpbHRlckludGVyZmFjZT4gZ2V0RmlsdGVycygpIHsKKyAgICByZXR1cm4gZmlsdGVyczsKKyAgfQorICAKKyAgLyoqIEFkZCBhIGZpbHRlci4KKyAgICogCisgICAqIEBwYXJhbSBmaWx0ZXIKKyAgICovCisgIHB1YmxpYyB2b2lkIGFkZEZpbHRlcihSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB7CisgICAgdGhpcy5maWx0ZXJzLmFkZChmaWx0ZXIpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShmaW5hbCBieXRlIFtdW10gY29sdW1ucykgeworICAgIGZvciAoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlciA6IGZpbHRlcnMpIHsKKyAgICAgIGZpbHRlci52YWxpZGF0ZShjb2x1bW5zKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICBmb3IgKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIgOiBmaWx0ZXJzKSB7CisgICAgICBmaWx0ZXIucmVzZXQoKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZSBbXSByb3dLZXkpIHsKKyAgICByb3dQcm9jZXNzZWQoZmlsdGVyZWQsIHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIGZvciAoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlciA6IGZpbHRlcnMpIHsKKyAgICAgIGZpbHRlci5yb3dQcm9jZXNzZWQoZmlsdGVyZWQsIGtleSwgb2Zmc2V0LCBsZW5ndGgpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NBbHdheXMoKSB7CisgICAgZm9yIChSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyIDogZmlsdGVycykgeworICAgICAgaWYgKGZpbHRlci5wcm9jZXNzQWx3YXlzKCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQWxsUmVtYWluaW5nKCkgeworICAgIGJvb2xlYW4gcmVzdWx0ID0gb3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORTsKKyAgICBmb3IgKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIgOiBmaWx0ZXJzKSB7CisgICAgICBpZiAob3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX0FMTCkgeworICAgICAgICBpZiAoZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKSB7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAob3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORSkgeworICAgICAgICBpZiAoIWZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGUgW10gcm93S2V5KSB7CisgICAgcmV0dXJuIGZpbHRlclJvd0tleShyb3dLZXksIDAsIHJvd0tleS5sZW5ndGgpOworICB9CisKKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoYnl0ZVtdIHJvd0tleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIGJvb2xlYW4gcmVzdWx0Rm91bmQgPSBmYWxzZTsKKyAgICBib29sZWFuIHJlc3VsdCA9IG9wZXJhdG9yID09IE9wZXJhdG9yLk1VU1RfUEFTU19PTkU7CisgICAgZm9yIChSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyIDogZmlsdGVycykgeworICAgICAgaWYgKCFyZXN1bHRGb3VuZCkgeworICAgICAgICBpZiAob3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX0FMTCkgeworICAgICAgICAgIGlmIChmaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkgfHwKKyAgICAgICAgICAgICAgZmlsdGVyLmZpbHRlclJvd0tleShyb3dLZXksIG9mZnNldCwgbGVuZ3RoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIHJlc3VsdEZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAob3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORSkgeworICAgICAgICAgIGlmICghZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpICYmCisgICAgICAgICAgICAgICFmaWx0ZXIuZmlsdGVyUm93S2V5KHJvd0tleSwgb2Zmc2V0LCBsZW5ndGgpKSB7CisgICAgICAgICAgICByZXN1bHQgPSBmYWxzZTsKKyAgICAgICAgICAgIHJlc3VsdEZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAoZmlsdGVyLnByb2Nlc3NBbHdheXMoKSkgeworICAgICAgICBmaWx0ZXIuZmlsdGVyUm93S2V5KHJvd0tleSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGZpbmFsIGJ5dGUgW10gcm93S2V5LCBmaW5hbCBieXRlIFtdIGNvbEtleSwgCisgICAgZmluYWwgYnl0ZVtdIGRhdGEpIHsKKyAgICByZXR1cm4gZmlsdGVyQ29sdW1uKHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCwgY29sS2V5LCAwLCBjb2xLZXkubGVuZ3RoLAorICAgICAgICBkYXRhLCAwLCBkYXRhLmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJDb2x1bW4oYnl0ZVtdIHJvd0tleSwgaW50IHJvZmZzZXQsIGludCBybGVuZ3RoLAorICAgICAgYnl0ZVtdIGNvbHVtbk5hbWUsIGludCBjb2Zmc2V0LCBpbnQgY2xlbmd0aCwgYnl0ZVtdIGNvbHVtblZhbHVlLAorICAgICAgaW50IHZvZmZzZXQsIGludCB2bGVuZ3RoKSB7CisgICAgYm9vbGVhbiByZXN1bHRGb3VuZCA9IGZhbHNlOworICAgIGJvb2xlYW4gcmVzdWx0ID0gb3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORTsKKyAgICBmb3IgKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIgOiBmaWx0ZXJzKSB7CisgICAgICBpZiAoIXJlc3VsdEZvdW5kKSB7CisgICAgICAgIGlmIChvcGVyYXRvciA9PSBPcGVyYXRvci5NVVNUX1BBU1NfQUxMKSB7CisgICAgICAgICAgaWYgKGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSB8fCAKKyAgICAgICAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4ocm93S2V5LCByb2Zmc2V0LCBybGVuZ3RoLCBjb2x1bW5OYW1lLCBjb2Zmc2V0LAorICAgICAgICAgICAgICAgIGNsZW5ndGgsIGNvbHVtblZhbHVlLCB2b2Zmc2V0LCB2bGVuZ3RoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICAgIHJlc3VsdEZvdW5kID0gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAob3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORSkgeworICAgICAgICAgIGlmICghZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpICYmIAorICAgICAgICAgICAgIWZpbHRlci5maWx0ZXJDb2x1bW4ocm93S2V5LCByb2Zmc2V0LCBybGVuZ3RoLCBjb2x1bW5OYW1lLCBjb2Zmc2V0LAorICAgICAgICAgICAgICAgIGNsZW5ndGgsIGNvbHVtblZhbHVlLCB2b2Zmc2V0LCB2bGVuZ3RoKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICByZXN1bHRGb3VuZCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKGZpbHRlci5wcm9jZXNzQWx3YXlzKCkpIHsKKyAgICAgICAgZmlsdGVyLmZpbHRlckNvbHVtbihyb3dLZXksIHJvZmZzZXQsIHJsZW5ndGgsIGNvbHVtbk5hbWUsIGNvZmZzZXQsCisgICAgICAgICAgICBjbGVuZ3RoLCBjb2x1bW5WYWx1ZSwgdm9mZnNldCwgdmxlbmd0aCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3coZmluYWwgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+IGNvbHVtbnMpIHsKKyAgICBib29sZWFuIHJlc3VsdEZvdW5kID0gZmFsc2U7CisgICAgYm9vbGVhbiByZXN1bHQgPSBvcGVyYXRvciA9PSBPcGVyYXRvci5NVVNUX1BBU1NfT05FOworICAgIGZvciAoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlciA6IGZpbHRlcnMpIHsKKyAgICAgIGlmICghcmVzdWx0Rm91bmQpIHsKKyAgICAgICAgaWYgKG9wZXJhdG9yID09IE9wZXJhdG9yLk1VU1RfUEFTU19BTEwpIHsKKyAgICAgICAgICBpZiAoZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpIHx8IGZpbHRlci5maWx0ZXJSb3coY29sdW1ucykpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICAgICAgICByZXN1bHRGb3VuZCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdG9yID09IE9wZXJhdG9yLk1VU1RfUEFTU19PTkUpIHsKKyAgICAgICAgICBpZiAoIWZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSAmJiAhZmlsdGVyLmZpbHRlclJvdyhjb2x1bW5zKSkgeworICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICByZXN1bHRGb3VuZCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKGZpbHRlci5wcm9jZXNzQWx3YXlzKCkpIHsKKyAgICAgICAgZmlsdGVyLmZpbHRlclJvdyhjb2x1bW5zKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhMaXN0PEtleVZhbHVlPiByZXN1bHRzKSB7CisgICAgYm9vbGVhbiByZXN1bHRGb3VuZCA9IGZhbHNlOworICAgIGJvb2xlYW4gcmVzdWx0ID0gb3BlcmF0b3IgPT0gT3BlcmF0b3IuTVVTVF9QQVNTX09ORTsKKyAgICBmb3IgKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIgOiBmaWx0ZXJzKSB7CisgICAgICBpZiAoIXJlc3VsdEZvdW5kKSB7CisgICAgICAgIGlmIChvcGVyYXRvciA9PSBPcGVyYXRvci5NVVNUX1BBU1NfQUxMKSB7CisgICAgICAgICAgaWYgKGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSB8fCBmaWx0ZXIuZmlsdGVyUm93KHJlc3VsdHMpKSB7CisgICAgICAgICAgICByZXN1bHQgPSB0cnVlOworICAgICAgICAgICAgcmVzdWx0Rm91bmQgPSB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRvciA9PSBPcGVyYXRvci5NVVNUX1BBU1NfT05FKSB7CisgICAgICAgICAgaWYgKCFmaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkgJiYgIWZpbHRlci5maWx0ZXJSb3cocmVzdWx0cykpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlOworICAgICAgICAgICAgcmVzdWx0Rm91bmQgPSB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChmaWx0ZXIucHJvY2Vzc0Fsd2F5cygpKSB7CisgICAgICAgIGZpbHRlci5maWx0ZXJSb3cocmVzdWx0cyk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKGZpbmFsIERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgYnl0ZSBvcEJ5dGUgPSBpbi5yZWFkQnl0ZSgpOworICAgIG9wZXJhdG9yID0gT3BlcmF0b3IudmFsdWVzKClbb3BCeXRlXTsKKyAgICBpbnQgc2l6ZSA9IGluLnJlYWRJbnQoKTsKKyAgICBpZiAoc2l6ZSA+IDApIHsKKyAgICAgIGZpbHRlcnMgPSBuZXcgSGFzaFNldDxSb3dGaWx0ZXJJbnRlcmZhY2U+KCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworCVJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIgPSAoUm93RmlsdGVySW50ZXJmYWNlKSBPYmplY3RXcml0YWJsZQorCSAgICAucmVhZE9iamVjdChpbiwgY29uZik7CisJZmlsdGVycy5hZGQoZmlsdGVyKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgb3V0LndyaXRlQnl0ZShvcGVyYXRvci5vcmRpbmFsKCkpOworICAgIG91dC53cml0ZUludChmaWx0ZXJzLnNpemUoKSk7CisgICAgZm9yIChSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyIDogZmlsdGVycykgeworICAgICAgT2JqZWN0V3JpdGFibGUud3JpdGVPYmplY3Qob3V0LCBmaWx0ZXIsIFJvd0ZpbHRlckludGVyZmFjZS5jbGFzcywgY29uZik7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1N0b3BSb3dGaWx0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9TdG9wUm93RmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTc0NzE3OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9TdG9wUm93RmlsdGVyLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEltcGxlbWVudGF0aW9uIG9mIFJvd0ZpbHRlckludGVyZmFjZSB0aGF0IGZpbHRlcnMgb3V0IHJvd3MgZ3JlYXRlciB0aGFuIG9yIAorICogZXF1YWwgdG8gYSBzcGVjaWZpZWQgcm93S2V5LgorICovCitwdWJsaWMgY2xhc3MgU3RvcFJvd0ZpbHRlciBpbXBsZW1lbnRzIFJvd0ZpbHRlckludGVyZmFjZSB7CisgIHByaXZhdGUgYnl0ZSBbXSBzdG9wUm93S2V5OworICAKKyAgLyoqCisgICAqIERlZmF1bHQgY29uc3RydWN0b3IsIGZpbHRlcnMgbm90aGluZy4gUmVxdWlyZWQgdGhvdWdoIGZvciBSUEMKKyAgICogZGVzZXJpYWxpemF0aW9uLgorICAgKi8KKyAgcHVibGljIFN0b3BSb3dGaWx0ZXIoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgc3RvcFJvd0tleSBvbiB3aGljaCB0byBmaWx0ZXIKKyAgICogCisgICAqIEBwYXJhbSBzdG9wUm93S2V5IHJvd0tleSB0byBmaWx0ZXIgb24uCisgICAqLworICBwdWJsaWMgU3RvcFJvd0ZpbHRlcihmaW5hbCBieXRlIFtdIHN0b3BSb3dLZXkpIHsKKyAgICB0aGlzLnN0b3BSb3dLZXkgPSBzdG9wUm93S2V5OworICB9CisgIAorICAvKioKKyAgICogQW4gYWNjZXNzb3IgZm9yIHRoZSBzdG9wUm93S2V5CisgICAqIAorICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXIncyBzdG9wUm93S2V5CisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRTdG9wUm93S2V5KCkgeworICAgIHJldHVybiB0aGlzLnN0b3BSb3dLZXk7CisgIH0KKworICBwdWJsaWMgdm9pZCB2YWxpZGF0ZShmaW5hbCBieXRlIFtdW10gY29sdW1ucykgeworICAgIC8vIERvZXNuJ3QgZmlsdGVyIGNvbHVtbnMKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIC8vIE5vdGhpbmcgdG8gcmVzZXQKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJvd1Byb2Nlc3NlZChib29sZWFuIGZpbHRlcmVkLCBieXRlIFtdIHJvd0tleSkgeworICAgIC8vIERvZXNuJ3QgY2FyZQorICB9CisKKyAgcHVibGljIHZvaWQgcm93UHJvY2Vzc2VkKGJvb2xlYW4gZmlsdGVyZWQsIGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAvLyBEb2Vzbid0IGNhcmUKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NBbHdheXMoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJBbGxSZW1haW5pbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGZpbmFsIGJ5dGUgW10gcm93S2V5KSB7CisgICAgcmV0dXJuIGZpbHRlclJvd0tleShyb3dLZXksIDAsIHJvd0tleS5sZW5ndGgpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93S2V5KGJ5dGVbXSByb3dLZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICBpZiAocm93S2V5ID09IG51bGwpIHsKKyAgICAgIGlmICh0aGlzLnN0b3BSb3dLZXkgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhzdG9wUm93S2V5LCAwLCBzdG9wUm93S2V5Lmxlbmd0aCwgcm93S2V5LCBvZmZzZXQsCisgICAgICBsZW5ndGgpIDw9IDA7CisgIH0KKworICAvKioKKyAgICogQmVjYXVzZSBTdG9wUm93RmlsdGVyIGRvZXMgbm90IGV4YW1pbmUgY29sdW1uIGluZm9ybWF0aW9uLCB0aGlzIG1ldGhvZCAKKyAgICogZGVmYXVsdHMgdG8gY2FsbGluZyB0aGUgcm93S2V5LW9ubHkgdmVyc2lvbiBvZiBmaWx0ZXIuCisgICAqIEBwYXJhbSByb3dLZXkgCisgICAqIEBwYXJhbSBjb2xLZXkgCisgICAqIEBwYXJhbSBkYXRhIAorICAgKiBAcmV0dXJuIGJvb2xlYW4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGZpbHRlckNvbHVtbihmaW5hbCBieXRlIFtdIHJvd0tleSwgZmluYWwgYnl0ZSBbXSBjb2xLZXksCisgICAgICBmaW5hbCBieXRlW10gZGF0YSkgeworICAgIHJldHVybiBmaWx0ZXJSb3dLZXkocm93S2V5KTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlckNvbHVtbihieXRlW10gcm93S2V5LCBpbnQgcm9mZnNldCwgaW50IHJsZW5ndGgsCisgICAgICBieXRlW10gY29sdW5tTmFtZSwgaW50IGNvZmZzZXQsIGludCBjbGVuZ3RoLCBieXRlW10gY29sdW1uVmFsdWUsCisgICAgICBpbnQgdm9mZnNldCwgaW50IHZsZW5ndGgpIHsKKyAgICByZXR1cm4gZmlsdGVyUm93S2V5KHJvd0tleSwgcm9mZnNldCwgcmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogQmVjYXVzZSBTdG9wUm93RmlsdGVyIGRvZXMgbm90IGV4YW1pbmUgY29sdW1uIGluZm9ybWF0aW9uLCB0aGlzIG1ldGhvZCAKKyAgICogZGVmYXVsdHMgdG8gY2FsbGluZyBmaWx0ZXJBbGxSZW1haW5pbmcoKS4KKyAgICogQHBhcmFtIGNvbHVtbnMgCisgICAqIEByZXR1cm4gYm9vbGVhbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93KGZpbmFsIFNvcnRlZE1hcDxieXRlIFtdLCBDZWxsPiBjb2x1bW5zKSB7CisgICAgcmV0dXJuIGZpbHRlckFsbFJlbWFpbmluZygpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyUm93KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpIHsKKyAgICByZXR1cm4gZmlsdGVyQWxsUmVtYWluaW5nKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLnN0b3BSb3dLZXkgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5zdG9wUm93S2V5KTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9TdWJzdHJpbmdDb21wYXJhdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvU3Vic3RyaW5nQ29tcGFyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiYjc2ZjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvU3Vic3RyaW5nQ29tcGFyYXRvci5qYXZhCkBAIC0wLDAgKzEsNzEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGhpcyBjb21wYXJhdG9yIGlzIGZvciB1c2Ugd2l0aCBDb2x1bW5WYWx1ZUZpbHRlciwgZm9yIGZpbHRlcmluZyBiYXNlZCBvbgorICogdGhlIHZhbHVlIG9mIGEgZ2l2ZW4gY29sdW1uLiBVc2UgaXQgdG8gdGVzdCBpZiBhIGdpdmVuIHN1YnN0cmluZyBhcHBlYXJzCisgKiBpbiBhIGNlbGwgdmFsdWUgaW4gdGhlIGNvbHVtbi4gVGhlIGNvbXBhcmlzb24gaXMgY2FzZSBpbnNlbnNpdGl2ZS4KKyAqIDxwPgorICogT25seSBFUVVBTCBvciBOT1RfRVFVQUwgdGVzdHMgYXJlIHZhbGlkIHdpdGggdGhpcyBjb21wYXJhdG9yLiAKKyAqIDxwPgorICogRm9yIGV4YW1wbGU6CisgKiA8cD4KKyAqIDxwcmU+CisgKiBDb2x1bW5WYWx1ZUZpbHRlciBjdmYgPQorICogICBuZXcgQ29sdW1uVmFsdWVGaWx0ZXIoImNvbCIsIENvbHVtblZhbHVlRmlsdGVyLkNvbXBhcmVPcC5FUVVBTCwKKyAqICAgICBuZXcgU3Vic3RyaW5nQ29tcGFyYXRvcigic3Vic3RyIikpOworICogPC9wcmU+CisgKi8KK3B1YmxpYyBjbGFzcyBTdWJzdHJpbmdDb21wYXJhdG9yIGltcGxlbWVudHMgV3JpdGFibGVCeXRlQXJyYXlDb21wYXJhYmxlIHsKKworICBwcml2YXRlIFN0cmluZyBzdWJzdHI7CisKKyAgLyoqIE51bGxhcnkgY29uc3RydWN0b3IgZm9yIFdyaXRhYmxlICovCisgIHB1YmxpYyBTdWJzdHJpbmdDb21wYXJhdG9yKCkgeworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBzdWJzdHIgdGhlIHN1YnN0cmluZworICAgKi8KKyAgcHVibGljIFN1YnN0cmluZ0NvbXBhcmF0b3IoU3RyaW5nIHN1YnN0cikgeworICAgIHRoaXMuc3Vic3RyID0gc3Vic3RyLnRvTG93ZXJDYXNlKCk7CisgIH0KKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhieXRlW10gdmFsdWUpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcodmFsdWUpLnRvTG93ZXJDYXNlKCkuY29udGFpbnMoc3Vic3RyKSA/IDAgOiAxOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3Vic3RyID0gaW4ucmVhZFVURigpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlVVRGKHN1YnN0cik7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1doaWxlTWF0Y2hSb3dGaWx0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9XaGlsZU1hdGNoUm93RmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg0Yjc4MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9XaGlsZU1hdGNoUm93RmlsdGVyLmphdmEKQEAgLTAsMCArMSwxNjUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKKworLyoqCisgKiBXaGlsZU1hdGNoUm93RmlsdGVyIGlzIGEgd3JhcHBlciBmaWx0ZXIgdGhhdCBmaWx0ZXJzIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIAorICogZmlyc3QgZmlsdGVyZWQgcm93LiAgT25jZSB0aGUgbmVzdGVkIGZpbHRlciByZXR1cm5zIHRydWUgZm9yIGVpdGhlciBvZiBpdCdzIAorICogZmlsdGVyKC4uKSBtZXRob2RzIG9yIGZpbHRlck5vdE51bGwoU29ydGVkTWFwPFRleHQsIGJ5dGVbXT4pLCB0aGlzIHdyYXBwZXIncyAKKyAqIGZpbHRlckFsbFJlbWFpbmluZygpIHdpbGwgcmV0dXJuIHRydWUuICBBbGwgZmlsdGVyaW5nIG1ldGhvZHMgd2lsbCAKKyAqIHRoZXJlYWZ0ZXIgZGVmZXIgdG8gdGhlIHJlc3VsdCBvZiBmaWx0ZXJBbGxSZW1haW5pbmcoKS4KKyAqLworcHVibGljIGNsYXNzIFdoaWxlTWF0Y2hSb3dGaWx0ZXIgaW1wbGVtZW50cyBSb3dGaWx0ZXJJbnRlcmZhY2UgeworICBwcml2YXRlIGJvb2xlYW4gZmlsdGVyQWxsUmVtYWluaW5nID0gZmFsc2U7CisgIHByaXZhdGUgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcjsKKworICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciwgZmlsdGVycyBub3RoaW5nLiBSZXF1aXJlZCB0aG91Z2ggZm9yIFJQQworICAgKiBkZXNlcmlhbGl6YXRpb24uCisgICAqLworICBwdWJsaWMgV2hpbGVNYXRjaFJvd0ZpbHRlcigpIHsKKyAgICBzdXBlcigpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIGZpbHRlcgorICAgKi8KKyAgcHVibGljIFdoaWxlTWF0Y2hSb3dGaWx0ZXIoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgeworICAgIHRoaXMuZmlsdGVyID0gZmlsdGVyOworICB9CisgIAorICAvKioKKyAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgZmlsdGVyIGJlaW5nIHdyYXBwZWQKKyAgICogCisgICAqIEByZXR1cm4gdGhlIGludGVybmFsIGZpbHRlcgorICAgKi8KKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRJbnRlcm5hbEZpbHRlcigpIHsKKyAgICByZXR1cm4gdGhpcy5maWx0ZXI7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIHRoaXMuZmlsdGVyQWxsUmVtYWluaW5nID0gZmFsc2U7CisgICAgdGhpcy5maWx0ZXIucmVzZXQoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NBbHdheXMoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgb25jZSB0aGUgbmVzdGVkIGZpbHRlciBoYXMgZmlsdGVyZWQgb3V0IGEgcm93IChyZXR1cm5lZCB0cnVlIAorICAgKiBvbiBhIGNhbGwgdG8gb25lIG9mIGl0J3MgZmlsdGVyaW5nIG1ldGhvZHMpLiAgVW50aWwgdGhlbiBpdCByZXR1cm5zIGZhbHNlLgorICAgKiAKKyAgICogQHJldHVybiB0cnVlL2ZhbHNlIHdoZXRoZXIgdGhlIG5lc3RlZCBmaWx0ZXIgaGFzIHJldHVybmVkIHRydWUgb24gYSBmaWx0ZXIgCisgICAqIGNhbGwuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJBbGxSZW1haW5pbmcoKSB7CisgICAgcmV0dXJuIHRoaXMuZmlsdGVyQWxsUmVtYWluaW5nIHx8IHRoaXMuZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpOworICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBmaWx0ZXJSb3dLZXkoZmluYWwgYnl0ZSBbXSByb3dLZXkpIHsKKyAgICBjaGFuZ2VGQVIodGhpcy5maWx0ZXIuZmlsdGVyUm93S2V5KHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCkpOworICAgIHJldHVybiBmaWx0ZXJBbGxSZW1haW5pbmcoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvd0tleShieXRlW10gcm93S2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgY2hhbmdlRkFSKHRoaXMuZmlsdGVyLmZpbHRlclJvd0tleShyb3dLZXksIG9mZnNldCwgbGVuZ3RoKSk7CisgICAgcmV0dXJuIGZpbHRlckFsbFJlbWFpbmluZygpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGZpbmFsIGJ5dGUgW10gcm93S2V5LCBmaW5hbCBieXRlIFtdIGNvbEtleSwKKyAgICBmaW5hbCBieXRlW10gZGF0YSkgeworICAgIGNoYW5nZUZBUih0aGlzLmZpbHRlci5maWx0ZXJDb2x1bW4ocm93S2V5LCBjb2xLZXksIGRhdGEpKTsKKyAgICByZXR1cm4gZmlsdGVyQWxsUmVtYWluaW5nKCk7CisgIH0KKyAgCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhmaW5hbCBTb3J0ZWRNYXA8Ynl0ZSBbXSwgQ2VsbD4gY29sdW1ucykgeworICAgIGNoYW5nZUZBUih0aGlzLmZpbHRlci5maWx0ZXJSb3coY29sdW1ucykpOworICAgIHJldHVybiBmaWx0ZXJBbGxSZW1haW5pbmcoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGZpbHRlclJvdyhMaXN0PEtleVZhbHVlPiByZXN1bHRzKSB7CisgICAgY2hhbmdlRkFSKHRoaXMuZmlsdGVyLmZpbHRlclJvdyhyZXN1bHRzKSk7CisgICAgcmV0dXJuIGZpbHRlckFsbFJlbWFpbmluZygpOworICB9CisKKyAgLyoqCisgICAqIENoYW5nZSBmaWx0ZXJBbGxSZW1haW5pbmcgZnJvbSBmYWxzZSB0byB0cnVlIGlmIHZhbHVlIGlzIHRydWUsIG90aGVyd2lzZSAKKyAgICogbGVhdmUgYXMgaXMuCisgICAqIAorICAgKiBAcGFyYW0gdmFsdWUKKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGFuZ2VGQVIoYm9vbGVhbiB2YWx1ZSkgeworICAgIHRoaXMuZmlsdGVyQWxsUmVtYWluaW5nID0gdGhpcy5maWx0ZXJBbGxSZW1haW5pbmcgfHwgdmFsdWU7CisgIH0KKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZSBbXSByb3dLZXkpIHsKKyAgICB0aGlzLmZpbHRlci5yb3dQcm9jZXNzZWQoZmlsdGVyZWQsIHJvd0tleSwgMCwgcm93S2V5Lmxlbmd0aCk7CisgIH0KKworICBwdWJsaWMgdm9pZCByb3dQcm9jZXNzZWQoYm9vbGVhbiBmaWx0ZXJlZCwgYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkgeworICAgIHRoaXMuZmlsdGVyLnJvd1Byb2Nlc3NlZChmaWx0ZXJlZCwga2V5LCBvZmZzZXQsIGxlbmd0aCk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zKSB7CisgICAgdGhpcy5maWx0ZXIudmFsaWRhdGUoY29sdW1ucyk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN0cmluZyBjbGFzc05hbWUgPSBpbi5yZWFkVVRGKCk7CisgICAgCisgICAgdHJ5IHsKKyAgICAgIHRoaXMuZmlsdGVyID0gKFJvd0ZpbHRlckludGVyZmFjZSkoQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpLgorICAgICAgICBuZXdJbnN0YW5jZSgpKTsKKyAgICAgIHRoaXMuZmlsdGVyLnJlYWRGaWVsZHMoaW4pOworICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBXaGlsZU1hdGNoUm93RmlsdGVyLiIsCisgICAgICAgICAgZSk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIHRvIGRlc2VyaWFsaXplIFdoaWxlTWF0Y2hSb3dGaWx0ZXIuIiwKKyAgICAgICAgICBlKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJGYWlsZWQgdG8gZGVzZXJpYWxpemUgV2hpbGVNYXRjaFJvd0ZpbHRlci4iLAorICAgICAgICAgIGUpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlVVRGKHRoaXMuZmlsdGVyLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgICB0aGlzLmZpbHRlci53cml0ZShvdXQpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZmlsdGVyQ29sdW1uKGJ5dGVbXSByb3dLZXksIGludCByb2Zmc2V0LCBpbnQgcmxlbmd0aCwKKyAgICAgIGJ5dGVbXSBjb2x1bm1OYW1lLCBpbnQgY29mZnNldCwgaW50IGNsZW5ndGgsIGJ5dGVbXSBjb2x1bW5WYWx1ZSwKKyAgICAgIGludCB2b2Zmc2V0LCBpbnQgdmxlbmd0aCkgeworICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Xcml0YWJsZUJ5dGVBcnJheUNvbXBhcmFibGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9Xcml0YWJsZUJ5dGVBcnJheUNvbXBhcmFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWYxMGY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1dyaXRhYmxlQnl0ZUFycmF5Q29tcGFyYWJsZS5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKKworLyoqIEludGVyZmFjZSBmb3IgYm90aCBDb21wYXJhYmxlPGJ5dGUgW10+IGFuZCBXcml0YWJsZS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgV3JpdGFibGVCeXRlQXJyYXlDb21wYXJhYmxlIGV4dGVuZHMgV3JpdGFibGUsCisgICAgQ29tcGFyYWJsZTxieXRlW10+IHsKKyAgLy8gTm90IG1ldGhvZHMsIGp1c3QgdGllIHRoZSB0d28gaW50ZXJmYWNlcyB0b2dldGhlci4KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9wYWNrYWdlLWluZm8uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9wYWNrYWdlLWluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MWRjMDMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL3BhY2thZ2UtaW5mby5qYXZhCkBAIC0wLDAgKzEsMjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKipQcm92aWRlcyByb3ctbGV2ZWwgZmlsdGVycyBhcHBsaWVkIHRvIEhSZWdpb24gc2NhbiByZXN1bHRzIGR1cmluZyBjYWxscyB0byB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXIjbmV4dCgpfS4gCisKKzxwPlVzZSB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlN0b3BSb3dGaWx0ZXJ9IHRvIHN0b3AgdGhlIHNjYW4gb25jZSByb3dzIGV4Y2VlZCB0aGUgc3VwcGxpZWQgcm93IGtleS4KK0ZpbHRlcnMgd2lsbCBub3Qgc3RvcCB0aGUgc2NhbiB1bmxlc3MgaG9zdGVkIGluc2lkZSBvZiBhIHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuV2hpbGVNYXRjaFJvd0ZpbHRlcn0uCitTdXBwbHkgYSBzZXQgb2YgZmlsdGVycyB0byBhcHBseSB1c2luZyB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlclNldH0uICAKKzwvcD4KKyovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlcjsKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0JhdGNoT3BlcmF0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9CYXRjaE9wZXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2YzA3YWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9CYXRjaE9wZXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTQ5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW87CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogQmF0Y2ggdXBkYXRlIG9wZXJhdGlvbi4KKyAqIAorICogSWYgdmFsdWUgaXMgbnVsbCwgaXRzIGEgREVMRVRFIG9wZXJhdGlvbi4gIElmIGl0cyBub24tbnVsbCwgaXRzIGEgUFVULgorICogVGhpcyBvYmplY3QgaXMgcHVycG9zZWx5IGJhcmUtYm9uZXMgYmVjYXVzZSBtYW55IGluc3RhbmNlcyBhcmUgY3JlYXRlZAorICogZHVyaW5nIGJ1bGsgdXBsb2Fkcy4gIFdlIGhhdmUgb25lIGNsYXNzIGZvciBERUxFVEVzIGFuZCBQVVRzIHJhdGhlciB0aGFuCisgKiBhIGNsYXNzIHBlciB0eXBlIGJlY2F1c2UgaXQgbWFrZXMgdGhlIHNlcmlhbGl6YXRpb24gZWFzaWVyLgorICogQHNlZSBCYXRjaFVwZGF0ZSAKKyAqLworcHVibGljIGNsYXNzIEJhdGNoT3BlcmF0aW9uIGltcGxlbWVudHMgV3JpdGFibGUsIEhlYXBTaXplIHsKKyAgLyoqCisgICAqIEVzdGltYXRlZCBzaXplIG9mIHRoaXMgb2JqZWN0LgorICAgKi8KKyAgLy8gSkhhdCBzYXlzIHRoaXMgaXMgMzIgYnl0ZXMuCisgIHB1YmxpYyBmaW5hbCBpbnQgRVNUSU1BVEVEX0hFQVBfVEFYID0gMzY7CisgIAorICBwcml2YXRlIGJ5dGUgW10gY29sdW1uID0gbnVsbDsKKyAgCisgIC8vIEEgbnVsbCB2YWx1ZSBkZWZpbmVzIERFTEVURSBvcGVyYXRpb25zLgorICBwcml2YXRlIGJ5dGUgW10gdmFsdWUgPSBudWxsOworICAKKyAgLyoqCisgICAqIERlZmF1bHQgY29uc3RydWN0b3IKKyAgICovCisgIHB1YmxpYyBCYXRjaE9wZXJhdGlvbigpIHsKKyAgICB0aGlzKChieXRlIFtdKW51bGwpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBERUxFVEUgYmF0Y2ggb3BlcmF0aW9uLgorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAqLworICBwdWJsaWMgQmF0Y2hPcGVyYXRpb24oZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICB0aGlzKGNvbHVtbiwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIERFTEVURSBiYXRjaCBvcGVyYXRpb24uCisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICovCisgIHB1YmxpYyBCYXRjaE9wZXJhdGlvbihmaW5hbCBTdHJpbmcgY29sdW1uKSB7CisgICAgdGhpcyhCeXRlcy50b0J5dGVzKGNvbHVtbiksIG51bGwpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIGJhdGNoIG9wZXJhdGlvbi4KKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gbmFtZQorICAgKiBAcGFyYW0gdmFsdWUgY29sdW1uIHZhbHVlLiAgSWYgbm9uLW51bGwsIHRoaXMgaXMgYSBQVVQgb3BlcmF0aW9uLgorICAgKi8KKyAgcHVibGljIEJhdGNoT3BlcmF0aW9uKGZpbmFsIFN0cmluZyBjb2x1bW4sIFN0cmluZyB2YWx1ZSkgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhjb2x1bW4pLCBCeXRlcy50b0J5dGVzKHZhbHVlKSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgYmF0Y2ggb3BlcmF0aW9uLgorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAqIEBwYXJhbSB2YWx1ZSBjb2x1bW4gdmFsdWUuICBJZiBub24tbnVsbCwgdGhpcyBpcyBhIFBVVCBvcGVyYXRpb24uCisgICAqLworICBwdWJsaWMgQmF0Y2hPcGVyYXRpb24oZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGJ5dGUgW10gdmFsdWUpIHsKKyAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgY29sdW1uCisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRDb2x1bW4oKSB7CisgICAgcmV0dXJuIHRoaXMuY29sdW1uOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIHZhbHVlCisgICAqLworICBwdWJsaWMgYnl0ZVtdIGdldFZhbHVlKCkgeworICAgIHJldHVybiB0aGlzLnZhbHVlOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIGlzIGEgUFVUIG9wZXJhdGlvbiAodGhpcy52YWx1ZSBpcyBub3QgbnVsbCkuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1B1dCgpIHsKKyAgICByZXR1cm4gdGhpcy52YWx1ZSAhPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gImNvbHVtbiA9PiAiICsgQnl0ZXMudG9TdHJpbmcodGhpcy5jb2x1bW4pICsgIiwgdmFsdWUgPT4gJy4uLiciOworICB9CisgIAorICAvLyBXcml0YWJsZSBtZXRob2RzCisKKyAgLy8gVGhpcyBpcyBhIGhvdHNwb3Qgd2hlbiB1cGRhdGluZyBkZXNlcmlhbGl6aW5nIGluY29taW5nIGNsaWVudCBzdWJtaXNzaW9ucy4KKyAgLy8gSW4gUGVyZm9ybWFuY2UgRXZhbHVhdGlvbiBzZXF1ZW50aWFsV3JpdGUsIDcwJSBvZiBvYmplY3QgYWxsb2NhdGlvbnMgYXJlCisgIC8vIGRvbmUgaW4gaGVyZS4KKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhmaW5hbCBEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5jb2x1bW4gPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICAvLyBJcyB0aGVyZSBhIHZhbHVlIHRvIHJlYWQ/CisgICAgaWYgKGluLnJlYWRCb29sZWFuKCkpIHsKKyAgICAgIHRoaXMudmFsdWUgPSBuZXcgYnl0ZVtpbi5yZWFkSW50KCldOworICAgICAgaW4ucmVhZEZ1bGx5KHRoaXMudmFsdWUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5jb2x1bW4pOworICAgIGJvb2xlYW4gcCA9IGlzUHV0KCk7CisgICAgb3V0LndyaXRlQm9vbGVhbihwKTsKKyAgICBpZiAocCkgeworICAgICAgb3V0LndyaXRlSW50KHZhbHVlLmxlbmd0aCk7CisgICAgICBvdXQud3JpdGUodmFsdWUpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIGxvbmcgaGVhcFNpemUoKSB7CisgICAgcmV0dXJuIEJ5dGVzLkVTVElNQVRFRF9IRUFQX1RBWCAqIDIgKyB0aGlzLmNvbHVtbi5sZW5ndGggKworICAgICAgdGhpcy52YWx1ZS5sZW5ndGggKyBFU1RJTUFURURfSEVBUF9UQVg7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9CYXRjaFVwZGF0ZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vQmF0Y2hVcGRhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzdhZDBlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vQmF0Y2hVcGRhdGUuamF2YQpAQCAtMCwwICsxLDQwNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuTWFuYWdlbWVudEZhY3Rvcnk7CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuUnVudGltZU1YQmVhbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKKworLyoqCisgKiBBIFdyaXRhYmxlIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgc2VyaWVzIG9mIEJhdGNoT3BlcmF0aW9ucworICogCisgKiBUaGVyZSBpcyBvbmUgQmF0Y2hVcGRhdGUgb2JqZWN0IHBlciBzZXJ2ZXIsIHNvIGEgc2VyaWVzIG9mIGJhdGNoIG9wZXJhdGlvbnMKKyAqIGNhbiByZXN1bHQgaW4gbXVsdGlwbGUgQmF0Y2hVcGRhdGUgb2JqZWN0cyBpZiB0aGUgYmF0Y2ggY29udGFpbnMgcm93cyB0aGF0CisgKiBhcmUgc2VydmVkIGJ5IG11bHRpcGxlIHJlZ2lvbiBzZXJ2ZXJzLgorICovCitwdWJsaWMgY2xhc3MgQmF0Y2hVcGRhdGUKK2ltcGxlbWVudHMgV3JpdGFibGVDb21wYXJhYmxlPEJhdGNoVXBkYXRlPiwgSXRlcmFibGU8QmF0Y2hPcGVyYXRpb24+LCBIZWFwU2l6ZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhCYXRjaFVwZGF0ZS5jbGFzcyk7CisgIAorICAvKioKKyAgICogRXN0aW1hdGVkICdzaGFsbG93IHNpemUnIG9mIHRoaXMgb2JqZWN0IG5vdCBjb3VudGluZyBwYXlsb2FkLgorICAgKi8KKyAgLy8gU2hhbGxvdyBzaXplIGlzIDU2LiAgQWRkIDMyIGZvciB0aGUgYXJyYXlsaXN0IGJlbG93LgorICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFU1RJTUFURURfSEVBUF9UQVggPSA1NiArIDMyOworICAKKyAgLy8gdGhlIHJvdyBiZWluZyB1cGRhdGVkCisgIHByaXZhdGUgYnl0ZSBbXSByb3cgPSBudWxsOworICBwcml2YXRlIGxvbmcgc2l6ZSA9IDA7CisgICAgCisgIC8vIHRoZSBiYXRjaGVkIG9wZXJhdGlvbnMKKyAgcHJpdmF0ZSBBcnJheUxpc3Q8QmF0Y2hPcGVyYXRpb24+IG9wZXJhdGlvbnMgPQorICAgIG5ldyBBcnJheUxpc3Q8QmF0Y2hPcGVyYXRpb24+KCk7CisgIAorICBwcml2YXRlIGxvbmcgdGltZXN0YW1wID0gSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QOworICAKKyAgcHJpdmF0ZSBsb25nIHJvd0xvY2sgPSAtMWw7CisgIAorICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciB1c2VkIHNlcmlhbGl6aW5nLiAgRG8gbm90IHVzZSBkaXJlY3RseS4KKyAgICovCisgIHB1YmxpYyBCYXRjaFVwZGF0ZSgpIHsKKyAgICB0aGlzICgoYnl0ZSBbXSludWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBJbml0aWFsaXplIGEgQmF0Y2hVcGRhdGUgb3BlcmF0aW9uIG9uIGEgcm93LiBUaW1lc3RhbXAgaXMgYXNzdW1lZCB0byBiZQorICAgKiBub3cuCisgICAqIAorICAgKiBAcGFyYW0gcm93CisgICAqLworICBwdWJsaWMgQmF0Y2hVcGRhdGUoZmluYWwgU3RyaW5nIHJvdykgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlcyhyb3cpLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIEluaXRpYWxpemUgYSBCYXRjaFVwZGF0ZSBvcGVyYXRpb24gb24gYSByb3cuIFRpbWVzdGFtcCBpcyBhc3N1bWVkIHRvIGJlCisgICAqIG5vdy4KKyAgICogCisgICAqIEBwYXJhbSByb3cKKyAgICovCisgIHB1YmxpYyBCYXRjaFVwZGF0ZShmaW5hbCBieXRlIFtdIHJvdykgeworICAgIHRoaXMocm93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIEluaXRpYWxpemUgYSBCYXRjaFVwZGF0ZSBvcGVyYXRpb24gb24gYSByb3cgd2l0aCBhIHNwZWNpZmljIHRpbWVzdGFtcC4KKyAgICogCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIEJhdGNoVXBkYXRlKGZpbmFsIFN0cmluZyByb3csIGxvbmcgdGltZXN0YW1wKXsKKyAgICB0aGlzKEJ5dGVzLnRvQnl0ZXMocm93KSwgdGltZXN0YW1wKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFJlY29weSBjb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gYnVUb0NvcHkgQmF0Y2hVcGRhdGUgdG8gY29weQorICAgKi8KKyAgcHVibGljIEJhdGNoVXBkYXRlKEJhdGNoVXBkYXRlIGJ1VG9Db3B5KSB7CisgICAgdGhpcyhidVRvQ29weS5nZXRSb3coKSwgYnVUb0NvcHkuZ2V0VGltZXN0YW1wKCkpOworICAgIGZvcihCYXRjaE9wZXJhdGlvbiBibyA6IGJ1VG9Db3B5KSB7CisgICAgICBieXRlIFtdIHZhbCA9IGJvLmdldFZhbHVlKCk7CisgICAgICBpZiAodmFsID09IG51bGwpIHsKKyAgICAgICAgLy8gUHJlc3VtZSBhIGRlbGV0ZSBpcyBpbnRlbmRlZC4KKyAgICAgICAgdGhpcy5kZWxldGUoYm8uZ2V0Q29sdW1uKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhpcy5wdXQoYm8uZ2V0Q29sdW1uKCksIHZhbCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEluaXRpYWxpemUgYSBCYXRjaFVwZGF0ZSBvcGVyYXRpb24gb24gYSByb3cgd2l0aCBhIHNwZWNpZmljIHRpbWVzdGFtcC4KKyAgICogCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIEJhdGNoVXBkYXRlKGZpbmFsIGJ5dGUgW10gcm93LCBsb25nIHRpbWVzdGFtcCl7CisgICAgdGhpcy5yb3cgPSByb3c7CisgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgdGhpcy5vcGVyYXRpb25zID0gbmV3IEFycmF5TGlzdDxCYXRjaE9wZXJhdGlvbj4oKTsKKyAgICB0aGlzLnNpemUgPSAocm93ID09IG51bGwpPyAwOiByb3cubGVuZ3RoOworICB9CisgIAorICAvKioKKyAgICogQ3JlYXRlIGEgYmF0Y2ggb3BlcmF0aW9uLgorICAgKiBAcGFyYW0gcnIgdGhlIFJvd1Jlc3VsdAorICAgKi8KKyAgcHVibGljIEJhdGNoVXBkYXRlKGZpbmFsIFJvd1Jlc3VsdCBycikgeworICAgIHRoaXMocnIuZ2V0Um93KCkpOworICAgIGZvcihNYXAuRW50cnk8Ynl0ZVtdLCBDZWxsPiBlbnRyeSA6IHJyLmVudHJ5U2V0KCkpeworICAgICAgdGhpcy5wdXQoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkuZ2V0VmFsdWUoKSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSByb3cgbG9jayBhc3NvY2lhdGVkIHdpdGggdGhpcyB1cGRhdGUKKyAgICogQHJldHVybiB0aGUgcm93IGxvY2sKKyAgICovCisgIHB1YmxpYyBsb25nIGdldFJvd0xvY2soKSB7CisgICAgcmV0dXJuIHJvd0xvY2s7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBsb2NrIHRvIGJlIHVzZWQgZm9yIHRoaXMgdXBkYXRlCisgICAqIEBwYXJhbSByb3dMb2NrIHRoZSByb3cgbG9jaworICAgKi8KKyAgcHVibGljIHZvaWQgc2V0Um93TG9jayhsb25nIHJvd0xvY2spIHsKKyAgICB0aGlzLnJvd0xvY2sgPSByb3dMb2NrOworICB9CisKKworICAvKiogQHJldHVybiB0aGUgcm93ICovCisgIHB1YmxpYyBieXRlIFtdIGdldFJvdygpIHsKKyAgICByZXR1cm4gcm93OworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIHRpbWVzdGFtcCB0aGlzIEJhdGNoVXBkYXRlIHdpbGwgYmUgY29tbWl0dGVkIHdpdGguCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgcmV0dXJuIHRpbWVzdGFtcDsKKyAgfQorICAKKyAgLyoqCisgICAqIFNldCB0aGlzIEJhdGNoVXBkYXRlJ3MgdGltZXN0YW1wLgorICAgKiAKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKi8gIAorICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbgorICAgKiAKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gbmFtZQorICAgKiBAcmV0dXJuIGJ5dGVbXSB0aGUgY2VsbCB2YWx1ZSwgcmV0dXJucyBudWxsIGlmIHRoZSBjb2x1bW4gZG9lcyBub3QgZXhpc3QuCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIGJ5dGVbXSBnZXQoZmluYWwgU3RyaW5nIGNvbHVtbikgeworICAgIHJldHVybiBnZXQoQnl0ZXMudG9CeXRlcyhjb2x1bW4pKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiAKKyAgICogCisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICogQHJldHVybiBieXRlW10gdGhlIGNlbGwgdmFsdWUsIHJldHVybnMgbnVsbCBpZiB0aGUgY29sdW1uIGRvZXMgbm90IGV4aXN0LgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBieXRlW10gZ2V0KGZpbmFsIGJ5dGVbXSBjb2x1bW4pIHsKKyAgICBmb3IgKEJhdGNoT3BlcmF0aW9uIG9wZXJhdGlvbjogb3BlcmF0aW9ucykgeworICAgICAgaWYgKEFycmF5cy5lcXVhbHMoY29sdW1uLCBvcGVyYXRpb24uZ2V0Q29sdW1uKCkpKSB7CisgICAgICAgIHJldHVybiBvcGVyYXRpb24uZ2V0VmFsdWUoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBjdXJyZW50IGNvbHVtbnMKKyAgICogCisgICAqIEByZXR1cm4gYnl0ZVtdW10gYW4gYXJyYXkgb2YgYnl0ZVtdIGNvbHVtbnMKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYnl0ZVtdW10gZ2V0Q29sdW1ucygpIHsKKyAgICBieXRlW11bXSBjb2x1bW5zID0gbmV3IGJ5dGVbb3BlcmF0aW9ucy5zaXplKCldW107CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcGVyYXRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgICBjb2x1bW5zW2ldID0gb3BlcmF0aW9ucy5nZXQoaSkuZ2V0Q29sdW1uKCk7CisgICAgfQorICAgIHJldHVybiBjb2x1bW5zOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIGlmIHRoZSBzcGVjaWZpZWQgY29sdW1uIGlzIGN1cnJlbnRseSBhc3NpZ25lZCBhIHZhbHVlCisgICAqIAorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiB0byBjaGVjayBmb3IKKyAgICogQHJldHVybiBib29sZWFuIHRydWUgaWYgdGhlIGdpdmVuIGNvbHVtbiBleGlzdHMKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBoYXNDb2x1bW4oU3RyaW5nIGNvbHVtbikgeworICAgIHJldHVybiBoYXNDb2x1bW4oQnl0ZXMudG9CeXRlcyhjb2x1bW4pKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENoZWNrIGlmIHRoZSBzcGVjaWZpZWQgY29sdW1uIGlzIGN1cnJlbnRseSBhc3NpZ25lZCBhIHZhbHVlCisgICAqIAorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiB0byBjaGVjayBmb3IKKyAgICogQHJldHVybiBib29sZWFuIHRydWUgaWYgdGhlIGdpdmVuIGNvbHVtbiBleGlzdHMKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBoYXNDb2x1bW4oYnl0ZVtdIGNvbHVtbikgeworICAgIGJ5dGVbXSBnZXRDb2x1bW4gPSBnZXQoY29sdW1uKTsKKyAgICBpZiAoZ2V0Q29sdW1uID09IG51bGwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgCisgIC8qKiAKKyAgICogQ2hhbmdlIGEgdmFsdWUgZm9yIHRoZSBzcGVjaWZpZWQgY29sdW1uCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIHdob3NlIHZhbHVlIGlzIGJlaW5nIHNldAorICAgKiBAcGFyYW0gdmFsIG5ldyB2YWx1ZSBmb3IgY29sdW1uLiAgQ2Fubm90IGJlIG51bGwgKGNhbiBiZSBlbXB0eSkuCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHV0KGZpbmFsIFN0cmluZyBjb2x1bW4sIGZpbmFsIGJ5dGUgdmFsW10pIHsKKyAgICBwdXQoQnl0ZXMudG9CeXRlcyhjb2x1bW4pLCB2YWwpOworICB9CisKKyAgLyoqIAorICAgKiBDaGFuZ2UgYSB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBjb2x1bW4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4gd2hvc2UgdmFsdWUgaXMgYmVpbmcgc2V0CisgICAqIEBwYXJhbSB2YWwgbmV3IHZhbHVlIGZvciBjb2x1bW4uICBDYW5ub3QgYmUgbnVsbCAoY2FuIGJlIGVtcHR5KS4KKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBwdXQoZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGJ5dGUgdmFsW10pIHsKKyAgICBpZiAodmFsID09IG51bGwpIHsKKyAgICAgIC8vIElmIG51bGwsIHRoZSBQVVQgYmVjb21lcyBhIERFTEVURSBvcGVyYXRpb24uCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJQYXNzZWQgdmFsdWUgY2Fubm90IGJlIG51bGwiKTsKKyAgICB9CisgICAgQmF0Y2hPcGVyYXRpb24gYm8gPSBuZXcgQmF0Y2hPcGVyYXRpb24oY29sdW1uLCB2YWwpOworICAgIHRoaXMuc2l6ZSArPSBiby5oZWFwU2l6ZSgpOworICAgIG9wZXJhdGlvbnMuYWRkKGJvKTsKKyAgfQorCisgIC8qKiAKKyAgICogRGVsZXRlIHRoZSB2YWx1ZSBmb3IgYSBjb2x1bW4KKyAgICogRGVsZXRlcyB0aGUgY2VsbCB3aG9zZSByb3cvY29sdW1uL2NvbW1pdC10aW1lc3RhbXAgbWF0Y2ggdGhvc2Ugb2YgdGhlCisgICAqIGRlbGV0ZS4KKyAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBkZWxldGVkCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGUoZmluYWwgU3RyaW5nIGNvbHVtbikgeworICAgIGRlbGV0ZShCeXRlcy50b0J5dGVzKGNvbHVtbikpOworICB9CisKKyAgLyoqIAorICAgKiBEZWxldGUgdGhlIHZhbHVlIGZvciBhIGNvbHVtbgorICAgKiBEZWxldGVzIHRoZSBjZWxsIHdob3NlIHJvdy9jb2x1bW4vY29tbWl0LXRpbWVzdGFtcCBtYXRjaCB0aG9zZSBvZiB0aGUKKyAgICogZGVsZXRlLgorICAgKiBAcGFyYW0gY29sdW1uIG5hbWUgb2YgY29sdW1uIHdob3NlIHZhbHVlIGlzIHRvIGJlIGRlbGV0ZWQKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBkZWxldGUoZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICBvcGVyYXRpb25zLmFkZChuZXcgQmF0Y2hPcGVyYXRpb24oY29sdW1uKSk7CisgIH0KKworICAvLworICAvLyBJdGVyYWJsZQorICAvLworICAKKyAgLyoqCisgICAqIEByZXR1cm4gSXRlcmF0b3I8QmF0Y2hPcGVyYXRpb24+CisgICAqLworICBwdWJsaWMgSXRlcmF0b3I8QmF0Y2hPcGVyYXRpb24+IGl0ZXJhdG9yKCkgeworICAgIHJldHVybiBvcGVyYXRpb25zLml0ZXJhdG9yKCk7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIHNiLmFwcGVuZCgicm93ID0+ICIpOworICAgIHNiLmFwcGVuZChyb3cgPT0gbnVsbD8gIiI6IEJ5dGVzLnRvU3RyaW5nKHJvdykpOworICAgIHNiLmFwcGVuZCgiLCB7Iik7CisgICAgYm9vbGVhbiBtb3JldGhhbm9uZSA9IGZhbHNlOworICAgIGZvciAoQmF0Y2hPcGVyYXRpb24gYm86IHRoaXMub3BlcmF0aW9ucykgeworICAgICAgaWYgKG1vcmV0aGFub25lKSB7CisgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIH0KKyAgICAgIG1vcmV0aGFub25lID0gdHJ1ZTsKKyAgICAgIHNiLmFwcGVuZChiby50b1N0cmluZygpKTsKKyAgICB9CisgICAgc2IuYXBwZW5kKCJ9Iik7CisgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgIH0KKworICAvLworICAvLyBXcml0YWJsZQorICAvLworCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoZmluYWwgRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIENsZWFyIGFueSBleGlzdGluZyBvcGVyYXRpb25zOyBtYXkgYmUgaGFuZ292ZXJzIGZyb20gcHJldmlvdXMgdXNlIG9mCisgICAgLy8gdGhpcyBpbnN0YW5jZS4KKyAgICBpZiAodGhpcy5vcGVyYXRpb25zLnNpemUoKSAhPSAwKSB7CisgICAgICB0aGlzLm9wZXJhdGlvbnMuY2xlYXIoKTsKKyAgICB9CisgICAgdGhpcy5yb3cgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICB0aW1lc3RhbXAgPSBpbi5yZWFkTG9uZygpOworICAgIHRoaXMuc2l6ZSA9IGluLnJlYWRMb25nKCk7CisgICAgaW50IG5PcHMgPSBpbi5yZWFkSW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuT3BzOyBpKyspIHsKKyAgICAgIEJhdGNoT3BlcmF0aW9uIG9wID0gbmV3IEJhdGNoT3BlcmF0aW9uKCk7CisgICAgICBvcC5yZWFkRmllbGRzKGluKTsKKyAgICAgIHRoaXMub3BlcmF0aW9ucy5hZGQob3ApOworICAgIH0KKyAgICB0aGlzLnJvd0xvY2sgPSBpbi5yZWFkTG9uZygpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoZmluYWwgRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCB0aGlzLnJvdyk7CisgICAgb3V0LndyaXRlTG9uZyh0aW1lc3RhbXApOworICAgIG91dC53cml0ZUxvbmcodGhpcy5zaXplKTsKKyAgICBvdXQud3JpdGVJbnQob3BlcmF0aW9ucy5zaXplKCkpOworICAgIGZvciAoQmF0Y2hPcGVyYXRpb24gb3A6IG9wZXJhdGlvbnMpIHsKKyAgICAgIG9wLndyaXRlKG91dCk7CisgICAgfQorICAgIG91dC53cml0ZUxvbmcodGhpcy5yb3dMb2NrKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgY29tcGFyZVRvKEJhdGNoVXBkYXRlIG8pIHsKKyAgICByZXR1cm4gQnl0ZXMuY29tcGFyZVRvKHRoaXMucm93LCBvLmdldFJvdygpKTsKKyAgfQorCisgIHB1YmxpYyBsb25nIGhlYXBTaXplKCkgeworICAgIHJldHVybiB0aGlzLnJvdy5sZW5ndGggKyBCeXRlcy5FU1RJTUFURURfSEVBUF9UQVggKyB0aGlzLnNpemUgKworICAgICAgRVNUSU1BVEVEX0hFQVBfVEFYOworICB9CisgIAorICAvKioKKyAgICogQ29kZSB0byB0ZXN0IHNpemVzIG9mIEJhdGNoVXBkYXRlIGFycmF5cy4KKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBSdW50aW1lTVhCZWFuIHJ1bnRpbWUgPSBNYW5hZ2VtZW50RmFjdG9yeS5nZXRSdW50aW1lTVhCZWFuKCk7CisgICAgTE9HLmluZm8oInZtTmFtZT0iICsgcnVudGltZS5nZXRWbU5hbWUoKSArICIsIHZtVmVuZG9yPSIKKyAgICAgICAgKyBydW50aW1lLmdldFZtVmVuZG9yKCkgKyAiLCB2bVZlcnNpb249IiArIHJ1bnRpbWUuZ2V0Vm1WZXJzaW9uKCkpOworICAgIExPRy5pbmZvKCJ2bUlucHV0QXJndW1lbnRzPSIgKyBydW50aW1lLmdldElucHV0QXJndW1lbnRzKCkpOworICAgIGZpbmFsIGludCBjb3VudCA9IDEwMDAwOworICAgIEJhdGNoVXBkYXRlW10gYmF0Y2gxID0gbmV3IEJhdGNoVXBkYXRlW2NvdW50XTsKKyAgICAvLyBUT0RPOiB4MzIgdnMgeDY0CisgICAgbG9uZyBzaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIGJ1ID0gbmV3IEJhdGNoVXBkYXRlKEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSk7CisgICAgICBidS5wdXQoSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZLCBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVkpOworICAgICAgYmF0Y2gxW2ldID0gYnU7CisgICAgICBzaXplICs9IGJ1LmhlYXBTaXplKCk7CisgICAgfQorICAgIExPRy5pbmZvKCJiYXRjaDEgZXN0aW1hdGVkIHNpemU9IiArIHNpemUpOworICAgIC8vIE1ha2UgYSB2YXJpYWJseSBzaXplZCBtZW1jYWNoZS4KKyAgICBzaXplID0gMDsKKyAgICBCYXRjaFVwZGF0ZVtdIGJhdGNoMiA9IG5ldyBCYXRjaFVwZGF0ZVtjb3VudF07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICBCYXRjaFVwZGF0ZSBidSA9IG5ldyBCYXRjaFVwZGF0ZShCeXRlcy50b0J5dGVzKGkpKTsKKyAgICAgIGJ1LnB1dChCeXRlcy50b0J5dGVzKGkpLCBuZXcgYnl0ZVtpXSk7CisgICAgICBiYXRjaDJbaV0gPSBidTsKKyAgICAgIHNpemUgKz0gYnUuaGVhcFNpemUoKTsKKyAgICB9CisgICAgTE9HLmluZm8oImJhdGNoMiBlc3RpbWF0ZWQgc2l6ZT0iICsgc2l6ZSk7CisgICAgZmluYWwgaW50IHNlY29uZHMgPSAzMDsKKyAgICBMT0cuaW5mbygiV2FpdGluZyAiICsgc2Vjb25kcyArICIgc2Vjb25kcyB3aGlsZSBoZWFwIGR1bXAgaXMgdGFrZW4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlY29uZHM7IGkrKykgeworICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgIH0KKyAgICBMT0cuaW5mbygiRXhpdGluZy4iKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0Jsb2NrRlNJbnB1dFN0cmVhbS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vQmxvY2tGU0lucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTIwYWQzYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0Jsb2NrRlNJbnB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsMjg0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRGdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkRmFjdG9yeTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUG9zaXRpb25lZFJlYWRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlNlZWthYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuU29mdFZhbHVlTWFwOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLkRhdGFJbnB1dEJ1ZmZlcjsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgRlNJbnB1dFN0cmVhbX0gdGhhdCByZWFkcyB0aGUgc3RyZWFtIGluIGJsb2NrcworICogb2YgYSBmaXhlZCwgY29uZmlndXJhYmxlIHNpemUuIFRoZSBibG9ja3MgYXJlIHN0b3JlZCBpbiBhIG1lbW9yeS1zZW5zaXRpdmUKKyAqIGNhY2hlLiAgSW1wbGVtZW50cyBSdW5uYWJsZS4gIFJ1biBpdCBvbiBhIHBlcmlvZCBzbyB3ZSBjbGVhbiB1cCBzb2Z0CisgKiByZWZlcmVuY2VzIGZyb20gdGhlIHJlZmVyZW5jZSBxdWV1ZS4KKyAqLworcHVibGljIGNsYXNzIEJsb2NrRlNJbnB1dFN0cmVhbSBleHRlbmRzIEZTSW5wdXRTdHJlYW0geworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEJsb2NrRlNJbnB1dFN0cmVhbS5jbGFzcyk7CisgIC8qCisgICAqIFNldCB1cCBzY2hlZHVsZWQgZXhlY3V0aW9uIG9mIGNsZWFudXAgb2Ygc29mdCByZWZlcmVuY2VzLiAgUnVuIHdpdGggb25lCisgICAqIHRocmVhZCBmb3Igbm93LiAgTWF5IG5lZWQgbW9yZSB3aGVuIG1hbnkgZmlsZXMuICBTaG91bGQgYmUgYW4gb3B0aW9uIGJ1dAorICAgKiBhbHNvIHdhbnQgQmxvY2tGU0lucHV0U3RyZWFtIHRvIGJlIHNlbGYtY29udGFpbmVkLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIEVYRUNVVE9SID0KKyAgICBFeGVjdXRvcnMubmV3U2luZ2xlVGhyZWFkU2NoZWR1bGVkRXhlY3V0b3IobmV3IFRocmVhZEZhY3RvcnkoKSB7CisgICAgICBwdWJsaWMgVGhyZWFkIG5ld1RocmVhZChSdW5uYWJsZSByKSB7CisgICAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZChyKTsKKyAgICAgICAgdC5zZXREYWVtb24odHJ1ZSk7CisgICAgICAgIHQuc2V0TmFtZSgiQmxvY2tGU0lucHV0U3RyZWFtUmVmZXJlbmNlUXVldWVDaGVja2VyIik7CisgICAgICAgIHJldHVybiB0OworICAgICAgfQorICAgIH0pOworICAKKyAgLyoKKyAgICogVGhlIHJlZ2lzdHJhdGlvbiBvZiB0aGlzIG9iamVjdCBpbiBFWEVDVVRPUi4KKyAgICovCisgIHByaXZhdGUgZmluYWwgU2NoZWR1bGVkRnV0dXJlPD8+IHJlZ2lzdHJhdGlvbjsKKworICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGluOworCisgIHByaXZhdGUgZmluYWwgbG9uZyBmaWxlTGVuZ3RoOworCisgIHByaXZhdGUgZmluYWwgaW50IGJsb2NrU2l6ZTsKKyAgcHJpdmF0ZSBmaW5hbCBTb2Z0VmFsdWVNYXA8TG9uZywgYnl0ZVtdPiBibG9ja3M7CisKKyAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZDsKKworICBwcml2YXRlIERhdGFJbnB1dEJ1ZmZlciBibG9ja1N0cmVhbSA9IG5ldyBEYXRhSW5wdXRCdWZmZXIoKTsKKworICBwcml2YXRlIGxvbmcgYmxvY2tFbmQgPSAtMTsKKworICBwcml2YXRlIGxvbmcgcG9zID0gMDsKKworICAvKioKKyAgICogQHBhcmFtIGluCisgICAqIEBwYXJhbSBmaWxlTGVuZ3RoCisgICAqIEBwYXJhbSBibG9ja1NpemUgdGhlIHNpemUgb2YgZWFjaCBibG9jayBpbiBieXRlcy4KKyAgICovCisgIHB1YmxpYyBCbG9ja0ZTSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIGxvbmcgZmlsZUxlbmd0aCwgaW50IGJsb2NrU2l6ZSkgeworICAgIHRoaXMuaW4gPSBpbjsKKyAgICBpZiAoIShpbiBpbnN0YW5jZW9mIFNlZWthYmxlKSB8fCAhKGluIGluc3RhbmNlb2YgUG9zaXRpb25lZFJlYWRhYmxlKSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAiSW4gaXMgbm90IGFuIGluc3RhbmNlIG9mIFNlZWthYmxlIG9yIFBvc2l0aW9uZWRSZWFkYWJsZSIpOworICAgIH0KKyAgICB0aGlzLmZpbGVMZW5ndGggPSBmaWxlTGVuZ3RoOworICAgIHRoaXMuYmxvY2tTaXplID0gYmxvY2tTaXplOworICAgIC8vIEEgbWVtb3J5LXNlbnNpdGl2ZSBtYXAgdGhhdCBoYXMgc29mdCByZWZlcmVuY2VzIHRvIHZhbHVlcworICAgIHRoaXMuYmxvY2tzID0gbmV3IFNvZnRWYWx1ZU1hcDxMb25nLCBieXRlIFtdPigpIHsKKyAgICAgIHByaXZhdGUgbG9uZyBoaXRzLCBtaXNzZXM7CisgICAgICAKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIGJ5dGUgW10gZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgYnl0ZSBbXSB2YWx1ZSA9IHN1cGVyLmdldChrZXkpOworICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIG1pc3NlcysrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGhpdHMrKzsKKyAgICAgICAgfQorICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkgJiYgKChoaXRzICsgbWlzc2VzKSAlIDEwMDAwKSA9PSAwKSB7CisgICAgICAgICAgbG9uZyBoaXRSYXRlID0gKDEwMCAqIGhpdHMpIC8gKGhpdHMgKyBtaXNzZXMpOworICAgICAgICAgIExPRy5kZWJ1ZygiSGl0IHJhdGUgZm9yIGNhY2hlICIgKyBoYXNoQ29kZSgpICsgIjogIiArIGhpdFJhdGUgKyAiJSIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgIH0KKyAgICB9OworICAgIC8vIFJlZ2lzdGVyIGEgUnVubmFibGUgdGhhdCBydW5zIGNoZWNrUmVmZXJlbmNlcyBvbiBhIHBlcmlvZC4KKyAgICBmaW5hbCBpbnQgaGFzaGNvZGUgPSBoYXNoQ29kZSgpOworICAgIHRoaXMucmVnaXN0cmF0aW9uID0gRVhFQ1VUT1Iuc2NoZWR1bGVXaXRoRml4ZWREZWxheShuZXcgUnVubmFibGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIGludCBjbGVhcmVkID0gY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSAmJiBjbGVhcmVkID4gMCkgeworICAgICAgICAgIExPRy5kZWJ1ZygiQ2hlY2tlciBjbGVhcmVkICIgKyBjbGVhcmVkICsgIiBpbiAiICsgaGFzaGNvZGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSwgMSwgMSwgVGltZVVuaXQuU0VDT05EUyk7CisgIH0KKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0lucHV0U3RyZWFtI2dldFBvcygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldFBvcygpIHsKKyAgICByZXR1cm4gcG9zOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNhdmFpbGFibGUoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGF2YWlsYWJsZSgpIHsKKyAgICByZXR1cm4gKGludCkgKGZpbGVMZW5ndGggLSBwb3MpOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNJbnB1dFN0cmVhbSNzZWVrKGxvbmcpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNlZWsobG9uZyB0YXJnZXRQb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRhcmdldFBvcyA+IGZpbGVMZW5ndGgpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IHNlZWsgYWZ0ZXIgRU9GIik7CisgICAgfQorICAgIHBvcyA9IHRhcmdldFBvczsKKyAgICBibG9ja0VuZCA9IC0xOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNJbnB1dFN0cmVhbSNzZWVrVG9OZXdTb3VyY2UobG9uZykKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gc2Vla1RvTmV3U291cmNlKGxvbmcgdGFyZ2V0UG9zKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI3JlYWQoKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjbG9zZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGNsb3NlZCIpOworICAgIH0KKyAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgaWYgKHBvcyA8IGZpbGVMZW5ndGgpIHsKKyAgICAgIGlmIChwb3MgPiBibG9ja0VuZCkgeworICAgICAgICBibG9ja1NlZWtUbyhwb3MpOworICAgICAgfQorICAgICAgcmVzdWx0ID0gYmxvY2tTdHJlYW0ucmVhZCgpOworICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CisgICAgICAgIHBvcysrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNyZWFkKGJ5dGVbXSwgaW50LCBpbnQpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgcmVhZChieXRlIGJ1ZltdLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjbG9zZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGNsb3NlZCIpOworICAgIH0KKyAgICBpZiAocG9zIDwgZmlsZUxlbmd0aCkgeworICAgICAgaWYgKHBvcyA+IGJsb2NrRW5kKSB7CisgICAgICAgIGJsb2NrU2Vla1RvKHBvcyk7CisgICAgICB9CisgICAgICBpbnQgcmVhbExlbiA9IE1hdGgubWluKGxlbiwgKGludCkgKGJsb2NrRW5kIC0gcG9zICsgMSkpOworICAgICAgaW50IHJlc3VsdCA9IGJsb2NrU3RyZWFtLnJlYWQoYnVmLCBvZmYsIHJlYWxMZW4pOworICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CisgICAgICAgIHBvcyArPSByZXN1bHQ7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICByZXR1cm4gLTE7CisgIH0KKworICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGJsb2NrU2Vla1RvKGxvbmcgdGFyZ2V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgdGFyZ2V0QmxvY2sgPSB0YXJnZXQvYmxvY2tTaXplOworICAgIGxvbmcgdGFyZ2V0QmxvY2tTdGFydCA9IHRhcmdldEJsb2NrICogYmxvY2tTaXplOworICAgIGxvbmcgdGFyZ2V0QmxvY2tFbmQgPSBNYXRoLm1pbih0YXJnZXRCbG9ja1N0YXJ0ICsgYmxvY2tTaXplLCBmaWxlTGVuZ3RoKSAtIDE7CisgICAgbG9uZyBibG9ja0xlbmd0aCA9IHRhcmdldEJsb2NrRW5kIC0gdGFyZ2V0QmxvY2tTdGFydCArIDE7CisgICAgbG9uZyBvZmZzZXRJbnRvQmxvY2sgPSB0YXJnZXQgLSB0YXJnZXRCbG9ja1N0YXJ0OworCisgICAgYnl0ZVtdIGJsb2NrID0gYmxvY2tzLmdldChMb25nLnZhbHVlT2YodGFyZ2V0QmxvY2tTdGFydCkpOworICAgIGlmIChibG9jayA9PSBudWxsKSB7CisgICAgICBibG9jayA9IG5ldyBieXRlW2Jsb2NrU2l6ZV07CisgICAgICAoKFBvc2l0aW9uZWRSZWFkYWJsZSkgaW4pLnJlYWRGdWxseSh0YXJnZXRCbG9ja1N0YXJ0LCBibG9jaywgMCwKKyAgICAgICAgICAoaW50KSBibG9ja0xlbmd0aCk7CisgICAgICBibG9ja3MucHV0KExvbmcudmFsdWVPZih0YXJnZXRCbG9ja1N0YXJ0KSwgYmxvY2spOworICAgIH0KKyAgICAKKyAgICB0aGlzLnBvcyA9IHRhcmdldDsKKyAgICB0aGlzLmJsb2NrRW5kID0gdGFyZ2V0QmxvY2tFbmQ7CisgICAgdGhpcy5ibG9ja1N0cmVhbS5yZXNldChibG9jaywgKGludCkgb2Zmc2V0SW50b0Jsb2NrLAorICAgICAgICAoaW50KSAoYmxvY2tMZW5ndGggLSBvZmZzZXRJbnRvQmxvY2spKTsKKworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNjbG9zZSgpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjbG9zZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RyZWFtIGNsb3NlZCIpOworICAgIH0KKyAgICBpZiAoIXRoaXMucmVnaXN0cmF0aW9uLmNhbmNlbChmYWxzZSkpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgY2FuY2VsIG9mICIgKyB0aGlzLnJlZ2lzdHJhdGlvbik7CisgICAgfQorICAgIGludCBjbGVhcmVkID0gY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpICYmIGNsZWFyZWQgPiAwKSB7CisgICAgICBMT0cuZGVidWcoIkNsb3NlIGNsZWFyZWQgIiArIGNsZWFyZWQgKyAiIGluICIgKyBoYXNoQ29kZSgpKTsKKyAgICB9CisgICAgaWYgKGJsb2NrU3RyZWFtICE9IG51bGwpIHsKKyAgICAgIGJsb2NrU3RyZWFtLmNsb3NlKCk7CisgICAgICBibG9ja1N0cmVhbSA9IG51bGw7CisgICAgfQorICAgIHN1cGVyLmNsb3NlKCk7CisgICAgY2xvc2VkID0gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBXZSBkb24ndCBzdXBwb3J0IG1hcmtzLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIG1hcmtTdXBwb3J0ZWQoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5pby5JbnB1dFN0cmVhbSNtYXJrKGludCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkTGltaXQpIHsKKyAgICAvLyBEbyBub3RoaW5nCisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmlvLklucHV0U3RyZWFtI3Jlc2V0KCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCByZXNldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNYXJrIG5vdCBzdXBwb3J0ZWQiKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxsIGZyZXF1ZW50bHkgdG8gY2xlYXIgU29mdCBSZWZlcmVuY2UgUmVmZXJlbmNlIFF1ZXVlLgorICAgKiBAcmV0dXJuIENvdW50IG9mIHJlZmVyZW5jZXMgY2xlYXJlZC4KKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGNoZWNrUmVmZXJlbmNlcygpIHsKKyAgICBpZiAodGhpcy5jbG9zZWQpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5ibG9ja3MuY2hlY2tSZWZlcmVuY2VzKCk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9DZWxsLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9DZWxsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTNkYWNjYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0NlbGwuamF2YQpAQCAtMCwwICsxLDI3OCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JU2VyaWFsaXphYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKK2ltcG9ydCBhZ2lsZWpzb24uVE9KU09OOworCisvKioKKyAqIENlbGwgLSBVc2VkIHRvIHRyYW5zcG9ydCBhIGNlbGwgdmFsdWUgKGJ5dGVbXSkgYW5kIHRoZSB0aW1lc3RhbXAgaXQgd2FzCisgKiBzdG9yZWQgd2l0aCB0b2dldGhlciBhcyBhIHJlc3VsdCBmb3IgZ2V0IGFuZCBnZXRSb3cgbWV0aG9kcy4gVGhpcyBwcm9tb3RlcworICogdGhlIHRpbWVzdGFtcCBvZiBhIGNlbGwgdG8gYSBmaXJzdC1jbGFzcyB2YWx1ZSwgbWFraW5nIGl0IGVhc3kgdG8gdGFrZSBub3RlCisgKiBvZiB0ZW1wb3JhbCBkYXRhLiBDZWxsIGlzIHVzZWQgYWxsIHRoZSB3YXkgZnJvbSBIU3RvcmUgdXAgdG8gSFRhYmxlLgorICovCitwdWJsaWMgY2xhc3MgQ2VsbCBpbXBsZW1lbnRzIFdyaXRhYmxlLCBJdGVyYWJsZTxNYXAuRW50cnk8TG9uZywgYnl0ZVtdPj4sCisgICAgSVNlcmlhbGl6YWJsZSB7CisgIHByb3RlY3RlZCBmaW5hbCBTb3J0ZWRNYXA8TG9uZywgYnl0ZVtdPiB2YWx1ZU1hcCA9IG5ldyBUcmVlTWFwPExvbmcsIGJ5dGVbXT4oCisgICAgICBuZXcgQ29tcGFyYXRvcjxMb25nPigpIHsKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKExvbmcgbDEsIExvbmcgbDIpIHsKKyAgICAgICAgICByZXR1cm4gbDIuY29tcGFyZVRvKGwxKTsKKyAgICAgICAgfQorICAgICAgfSk7CisKKyAgLyoqIEZvciBXcml0YWJsZSBjb21wYXRpYmlsaXR5ICovCisgIHB1YmxpYyBDZWxsKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgbmV3IENlbGwgd2l0aCBhIGdpdmVuIHZhbHVlIGFuZCB0aW1lc3RhbXAuIFVzZWQgYnkgSFN0b3JlLgorICAgKiAKKyAgICogQHBhcmFtIHZhbHVlCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICovCisgIHB1YmxpYyBDZWxsKFN0cmluZyB2YWx1ZSwgbG9uZyB0aW1lc3RhbXApIHsKKyAgICB0aGlzKEJ5dGVzLnRvQnl0ZXModmFsdWUpLCB0aW1lc3RhbXApOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBDZWxsIHdpdGggYSBnaXZlbiB2YWx1ZSBhbmQgdGltZXN0YW1wLiBVc2VkIGJ5IEhTdG9yZS4KKyAgICogCisgICAqIEBwYXJhbSB2YWx1ZQorICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqLworICBwdWJsaWMgQ2VsbChieXRlW10gdmFsdWUsIGxvbmcgdGltZXN0YW1wKSB7CisgICAgdmFsdWVNYXAucHV0KHRpbWVzdGFtcCwgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBDZWxsIHdpdGggYSBnaXZlbiB2YWx1ZSBhbmQgdGltZXN0YW1wLiBVc2VkIGJ5IEhTdG9yZS4KKyAgICogCisgICAqIEBwYXJhbSBiYgorICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqLworICBwdWJsaWMgQ2VsbChmaW5hbCBCeXRlQnVmZmVyIGJiLCBsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMudmFsdWVNYXAucHV0KHRpbWVzdGFtcCwgQnl0ZXMudG9CeXRlcyhiYikpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB2YWxzCisgICAqICAgICAgICAgIGFycmF5IG9mIHZhbHVlcworICAgKiBAcGFyYW0gdHMKKyAgICogICAgICAgICAgYXJyYXkgb2YgdGltZXN0YW1wcworICAgKi8KKyAgcHVibGljIENlbGwoU3RyaW5nIFtdIHZhbHMsIGxvbmdbXSB0cykgeworICAgIHRoaXMoQnl0ZXMudG9CeXRlQXJyYXlzKHZhbHMpLCB0cyk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHZhbHMKKyAgICogICAgICAgICAgYXJyYXkgb2YgdmFsdWVzCisgICAqIEBwYXJhbSB0cworICAgKiAgICAgICAgICBhcnJheSBvZiB0aW1lc3RhbXBzCisgICAqLworICBwdWJsaWMgQ2VsbChieXRlW11bXSB2YWxzLCBsb25nW10gdHMpIHsKKyAgICBpZiAodmFscy5sZW5ndGggIT0gdHMubGVuZ3RoKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICJudW1iZXIgb2YgdmFsdWVzIG11c3QgYmUgdGhlIHNhbWUgYXMgdGhlIG51bWJlciBvZiB0aW1lc3RhbXBzIik7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFscy5sZW5ndGg7IGkrKykgeworICAgICAgdmFsdWVNYXAucHV0KHRzW2ldLCB2YWxzW2ldKTsKKyAgICB9CisgIH0KKworICAvKiogQHJldHVybiB0aGUgY3VycmVudCBjZWxsJ3MgdmFsdWUgKi8KKyAgQFRPSlNPTihiYXNlNjQ9dHJ1ZSkKKyAgcHVibGljIGJ5dGVbXSBnZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHZhbHVlTWFwLmZpcnN0S2V5KCkpOworICB9CisKKyAgLyoqIEByZXR1cm4gdGhlIGN1cnJlbnQgY2VsbCdzIHRpbWVzdGFtcCAqLworICBAVE9KU09OCisgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICByZXR1cm4gdmFsdWVNYXAuZmlyc3RLZXkoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgdmFsdWVzIHRoaXMgY2VsbCBob2xkcyAqLworICBwdWJsaWMgaW50IGdldE51bVZhbHVlcygpIHsKKyAgICByZXR1cm4gdmFsdWVNYXAuc2l6ZSgpOworICB9CisKKyAgLyoqCisgICAqIEFkZCBhIG5ldyB0aW1lc3RhbXAgYW5kIHZhbHVlIHRvIHRoaXMgY2VsbCBwcm92aWRlZCB0aW1lc3RhbXAgZG9lcyBub3QKKyAgICogYWxyZWFkeSBleGlzdAorICAgKiAKKyAgICogQHBhcmFtIHZhbAorICAgKiBAcGFyYW0gdHMKKyAgICovCisgIHB1YmxpYyB2b2lkIGFkZChieXRlW10gdmFsLCBsb25nIHRzKSB7CisgICAgaWYgKCF2YWx1ZU1hcC5jb250YWluc0tleSh0cykpIHsKKyAgICAgIHZhbHVlTWFwLnB1dCh0cywgdmFsKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIGlmICh2YWx1ZU1hcC5zaXplKCkgPT0gMSkgeworICAgICAgcmV0dXJuICJ0aW1lc3RhbXA9IiArIGdldFRpbWVzdGFtcCgpICsgIiwgdmFsdWU9IgorICAgICAgICAgICsgQnl0ZXMudG9TdHJpbmcoZ2V0VmFsdWUoKSk7CisgICAgfQorICAgIFN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCJ7ICIpOworICAgIGludCBpID0gMDsKKyAgICBmb3IgKE1hcC5FbnRyeTxMb25nLCBieXRlW10+IGVudHJ5IDogdmFsdWVNYXAuZW50cnlTZXQoKSkgeworICAgICAgaWYgKGkgPiAwKSB7CisgICAgICAgIHMuYXBwZW5kKCIsICIpOworICAgICAgfQorICAgICAgcy5hcHBlbmQoIlt0aW1lc3RhbXA9Iik7CisgICAgICBzLmFwcGVuZChlbnRyeS5nZXRLZXkoKSk7CisgICAgICBzLmFwcGVuZCgiLCB2YWx1ZT0iKTsKKyAgICAgIHMuYXBwZW5kKEJ5dGVzLnRvU3RyaW5nKGVudHJ5LmdldFZhbHVlKCkpKTsKKyAgICAgIHMuYXBwZW5kKCJdIik7CisgICAgICBpKys7CisgICAgfQorICAgIHMuYXBwZW5kKCIgfSIpOworICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CisgIH0KKworICAvLworICAvLyBXcml0YWJsZQorICAvLworCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoZmluYWwgRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCBudmFsdWVzID0gaW4ucmVhZEludCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnZhbHVlczsgaSsrKSB7CisgICAgICBsb25nIHRpbWVzdGFtcCA9IGluLnJlYWRMb25nKCk7CisgICAgICBieXRlW10gdmFsdWUgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICAgIHZhbHVlTWFwLnB1dCh0aW1lc3RhbXAsIHZhbHVlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGVJbnQodmFsdWVNYXAuc2l6ZSgpKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxMb25nLCBieXRlW10+IGVudHJ5IDogdmFsdWVNYXAuZW50cnlTZXQoKSkgeworICAgICAgb3V0LndyaXRlTG9uZyhlbnRyeS5nZXRLZXkoKSk7CisgICAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGVudHJ5LmdldFZhbHVlKCkpOworICAgIH0KKyAgfQorCisgIC8vCisgIC8vIEl0ZXJhYmxlCisgIC8vCisKKyAgcHVibGljIEl0ZXJhdG9yPEVudHJ5PExvbmcsIGJ5dGVbXT4+IGl0ZXJhdG9yKCkgeworICAgIHJldHVybiBuZXcgQ2VsbEl0ZXJhdG9yKCk7CisgIH0KKworICBwcml2YXRlIGNsYXNzIENlbGxJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPEVudHJ5PExvbmcsIGJ5dGVbXT4+IHsKKyAgICBwcml2YXRlIEl0ZXJhdG9yPEVudHJ5PExvbmcsIGJ5dGVbXT4+IGl0OworCisgICAgQ2VsbEl0ZXJhdG9yKCkgeworICAgICAgaXQgPSB2YWx1ZU1hcC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKKyAgICAgIHJldHVybiBpdC5oYXNOZXh0KCk7CisgICAgfQorCisgICAgcHVibGljIEVudHJ5PExvbmcsIGJ5dGVbXT4gbmV4dCgpIHsKKyAgICAgIHJldHVybiBpdC5uZXh0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigicmVtb3ZlIGlzIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJlc3VsdHMKKyAgICogQHJldHVybgorICAgKiBUT0RPOiBUaGlzIGlzIHRoZSBnbHVlIGJldHdlZW4gb2xkIHdheSBvZiBkb2luZyB0aGluZ3MgYW5kIHRoZSBuZXcuCisgICAqIEhlcmVpbiB3ZSBhcmUgY29udmVydGluZyBvdXIgY2xlYW4gS2V5VmFsdWVzIHRvIE1hcCBvZiBDZWxscy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPiBjcmVhdGVDZWxscyhmaW5hbCBMaXN0PEtleVZhbHVlPiByZXN1bHRzKSB7CisgICAgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPiBjZWxscyA9CisgICAgICBuZXcgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPigpOworICAgIC8vIFdhbGtpbmcgYmFja3dhcmQgdGhyb3VnaCB0aGUgbGlzdCBvZiByZXN1bHRzIHRob3VnaCBpdCBoYXMgbm8gZWZmZWN0CisgICAgLy8gYmVjYXVzZSB3ZSdyZSBpbnNlcnRpbmcgaW50byBhIHNvcnRlZCBtYXAuCisgICAgZm9yIChMaXN0SXRlcmF0b3I8S2V5VmFsdWU+IGkgPSByZXN1bHRzLmxpc3RJdGVyYXRvcihyZXN1bHRzLnNpemUoKSk7CisgICAgICAgIGkuaGFzUHJldmlvdXMoKTspIHsKKyAgICAgIEtleVZhbHVlIGt2ID0gaS5wcmV2aW91cygpOworICAgICAgYnl0ZSBbXSBjb2x1bW4gPSBrdi5nZXRDb2x1bW4oKTsKKyAgICAgIENlbGwgYyA9IGNlbGxzLmdldChjb2x1bW4pOworICAgICAgaWYgKGMgPT0gbnVsbCkgeworICAgICAgICBjID0gbmV3IENlbGwoa3YuZ2V0VmFsdWUoKSwga3YuZ2V0VGltZXN0YW1wKCkpOworICAgICAgICBjZWxscy5wdXQoY29sdW1uLCBjKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGMuYWRkKGt2LmdldFZhbHVlKCksIGt2LmdldFRpbWVzdGFtcCgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGNlbGxzOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByZXN1bHRzCisgICAqIEByZXR1cm4gQXJyYXkgb2YgQ2VsbHMuCisgICAqIFRPRE86IFRoaXMgaXMgdGhlIGdsdWUgYmV0d2VlbiBvbGQgd2F5IG9mIGRvaW5nIHRoaW5ncyBhbmQgdGhlIG5ldy4KKyAgICogSGVyZWluIHdlIGFyZSBjb252ZXJ0aW5nIG91ciBjbGVhbiBLZXlWYWx1ZXMgdG8gTWFwIG9mIENlbGxzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBDZWxsIFtdIGNyZWF0ZVNpbmdsZUNlbGxBcnJheShmaW5hbCBMaXN0PEtleVZhbHVlPiByZXN1bHRzKSB7CisgICAgaWYgKHJlc3VsdHMgPT0gbnVsbCkgcmV0dXJuIG51bGw7CisgICAgaW50IGluZGV4ID0gMDsKKyAgICBDZWxsIFtdIGNlbGxzID0gbmV3IENlbGxbcmVzdWx0cy5zaXplKCldOworICAgIGZvciAoS2V5VmFsdWUga3Y6IHJlc3VsdHMpIHsKKyAgICAgIGNlbGxzW2luZGV4KytdID0gbmV3IENlbGwoa3YuZ2V0VmFsdWUoKSwga3YuZ2V0VGltZXN0YW1wKCkpOworICAgIH0KKyAgICByZXR1cm4gY2VsbHM7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JU2VyaWFsaXphYmxlI3Jlc3RTZXJpYWxpemUob3JnCisgICAqIC5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIpCisgICAqLworICBwdWJsaWMgdm9pZCByZXN0U2VyaWFsaXplKElSZXN0U2VyaWFsaXplciBzZXJpYWxpemVyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgc2VyaWFsaXplci5zZXJpYWxpemVDZWxsKHRoaXMpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9Db2RlVG9DbGFzc0FuZEJhY2suamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0NvZGVUb0NsYXNzQW5kQmFjay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5OTk3YTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9Db2RlVG9DbGFzc0FuZEJhY2suamF2YQpAQCAtMCwwICsxLDcxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEudXRpbC4qOworCisvKioKKyAqIEEgU3RhdGljIEludGVyZmFjZS4KKyAqIEluc3RlYWQgb2YgaGF2aW5nIHRoaXMgY29kZSBpbiB0aGUgdGhlIEhiYXNlTWFwV3JpdGFibGUgY29kZSwgd2hlcmUgaXQKKyAqIGJsb2NrcyB0aGUgcG9zc2liaWxpdHkgb2YgYWx0ZXJpbmcgdGhlIHZhcmlhYmxlcyBhbmQgY2hhbmdpbmcgdGhlaXIgdHlwZXMsCisgKiBpdCBpcyBwdXQgaGVyZSBpbiB0aGlzIHN0YXRpYyBpbnRlcmZhY2Ugd2hlcmUgdGhlIHN0YXRpYyBmaW5hbCBNYXBzIGFyZQorICogbG9hZGVkIG9uZSB0aW1lLiBPbmx5IGJ5dGVbXSBhbmQgQ2VsbCBhcmUgc3VwcG9ydGVkIGF0IHRoaXMgdGltZS4KKyAqLworcHVibGljIGludGVyZmFjZSBDb2RlVG9DbGFzc0FuZEJhY2sgeworICAvKioKKyAgICogU3RhdGljIG1hcCB0aGF0IGNvbnRhaW5zIG1hcHBpbmcgZnJvbSBjb2RlIHRvIGNsYXNzCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxCeXRlLCBDbGFzczw/Pj4gQ09ERV9UT19DTEFTUyA9CisgICAgbmV3IEhhc2hNYXA8Qnl0ZSwgQ2xhc3M8Pz4+KCk7CisKKyAgLyoqCisgICAqIFN0YXRpYyBtYXAgdGhhdCBjb250YWlucyBtYXBwaW5nIGZyb20gY2xhc3MgdG8gY29kZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8Q2xhc3M8Pz4sIEJ5dGU+IENMQVNTX1RPX0NPREUgPQorICAgIG5ldyBIYXNoTWFwPENsYXNzPD8+LCBCeXRlPigpOworICAKKyAgLyoqCisgICAqIENsYXNzIGxpc3QgZm9yIHN1cHBvcnRlZCBjbGFzc2VzCisgICAqLworICBwdWJsaWMgQ2xhc3NbXSBjbGFzc0xpc3QgPSB7Ynl0ZVtdLmNsYXNzLCBDZWxsLmNsYXNzfTsKKyAgCisgIC8qKgorICAgKiBUaGUgc3RhdGljIGxvYWRlciB0aGF0IGlzIHVzZWQgaW5zdGVhZCBvZiB0aGUgc3RhdGljIGNvbnN0cnVjdG9yIGluCisgICAqIEhiYXNlTWFwV3JpdGFibGUuCisgICAqLworICBwdWJsaWMgSW50ZXJuYWxTdGF0aWNMb2FkZXIgc2wgPQorICAgIG5ldyBJbnRlcm5hbFN0YXRpY0xvYWRlcihjbGFzc0xpc3QsIENPREVfVE9fQ0xBU1MsIENMQVNTX1RPX0NPREUpOworCisgIC8qKgorICAgKiBDbGFzcyB0aGF0IGxvYWRzIHRoZSBzdGF0aWMgbWFwcyB3aXRoIHRoZWlyIHZhbHVlcy4gCisgICAqLworICBwdWJsaWMgY2xhc3MgSW50ZXJuYWxTdGF0aWNMb2FkZXJ7CisgICAgSW50ZXJuYWxTdGF0aWNMb2FkZXIoQ2xhc3NbXSBjbGFzc0xpc3QsIE1hcDxCeXRlLCBDbGFzczw/Pj4gQ09ERV9UT19DTEFTUywKKyAgICBNYXA8Q2xhc3M8Pz4sIEJ5dGU+IENMQVNTX1RPX0NPREUpeworICAgICAgYnl0ZSBjb2RlID0gMTsKKyAgICAgIGZvcihpbnQgaT0wOyBpPGNsYXNzTGlzdC5sZW5ndGg7IGkrKyl7CisgICAgICAgIENMQVNTX1RPX0NPREUucHV0KGNsYXNzTGlzdFtpXSwgY29kZSk7CisgICAgICAgIENPREVfVE9fQ0xBU1MucHV0KGNvZGUsIGNsYXNzTGlzdFtpXSk7CisgICAgICAgIGNvZGUrKzsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0RhdGFPdXRwdXRCdWZmZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0RhdGFPdXRwdXRCdWZmZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2JkNzQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vRGF0YU91dHB1dEJ1ZmZlci5qYXZhCkBAIC0wLDAgKzEsMTM1IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uKjsKKworLyoqIEEgcmV1c2FibGUge0BsaW5rIERhdGFPdXRwdXR9IGltcGxlbWVudGF0aW9uIHRoYXQgd3JpdGVzIHRvIGFuIGluLW1lbW9yeQorICogYnVmZmVyLgorICogCisgKiA8cD5UaGlzIGlzIGNvcHkgb2YgSGFkb29wIFNlcXVlbmNlRmlsZSBicm91Z2h0IGxvY2FsIHNvIHdlIGNhbiBmaXggYnVnczsKKyAqIGUuZy4gaGJhc2UtMTA5NzwvcD4KKyAqCisgKiA8cD5UaGlzIHNhdmVzIG1lbW9yeSBvdmVyIGNyZWF0aW5nIGEgbmV3IERhdGFPdXRwdXRTdHJlYW0gYW5kCisgKiBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gZWFjaCB0aW1lIGRhdGEgaXMgd3JpdHRlbi4KKyAqCisgKiA8cD5UeXBpY2FsIHVzYWdlIGlzIHNvbWV0aGluZyBsaWtlIHRoZSBmb2xsb3dpbmc6PHByZT4KKyAqCisgKiBEYXRhT3V0cHV0QnVmZmVyIGJ1ZmZlciA9IG5ldyBEYXRhT3V0cHV0QnVmZmVyKCk7CisgKiB3aGlsZSAoLi4uIGxvb3AgY29uZGl0aW9uIC4uLikgeworICogICBidWZmZXIucmVzZXQoKTsKKyAqICAgLi4uIHdyaXRlIGJ1ZmZlciB1c2luZyBEYXRhT3V0cHV0IG1ldGhvZHMgLi4uCisgKiAgIGJ5dGVbXSBkYXRhID0gYnVmZmVyLmdldERhdGEoKTsKKyAqICAgaW50IGRhdGFMZW5ndGggPSBidWZmZXIuZ2V0TGVuZ3RoKCk7CisgKiAgIC4uLiB3cml0ZSBkYXRhIHRvIGl0cyB1bHRpbWF0ZSBkZXN0aW5hdGlvbiAuLi4KKyAqIH0KKyAqIDwvcHJlPgorICogIAorICovCitwdWJsaWMgY2xhc3MgRGF0YU91dHB1dEJ1ZmZlciBleHRlbmRzIERhdGFPdXRwdXRTdHJlYW0geworCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ1ZmZlciBleHRlbmRzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB7CisgICAgcHVibGljIGJ5dGVbXSBnZXREYXRhKCkgeyByZXR1cm4gYnVmOyB9CisgICAgcHVibGljIGludCBnZXRMZW5ndGgoKSB7IHJldHVybiBjb3VudDsgfQorICAgIC8vIEtlZXAgdGhlIGluaXRpYWwgYnVmZmVyIGFyb3VuZCBzbyBjYW4gcHV0IGl0IGJhY2sgaW4gcGxhY2Ugb24gcmVzZXQuCisgICAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdIGluaXRpYWxCdWZmZXI7CisKKyAgICBwdWJsaWMgQnVmZmVyKCkgeworICAgICAgc3VwZXIoKTsKKyAgICAgIHRoaXMuaW5pdGlhbEJ1ZmZlciA9IHRoaXMuYnVmOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgQnVmZmVyKGludCBzaXplKSB7CisgICAgICBzdXBlcihzaXplKTsKKyAgICAgIHRoaXMuaW5pdGlhbEJ1ZmZlciA9IHRoaXMuYnVmOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhSW5wdXQgaW4sIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpbnQgbmV3Y291bnQgPSBjb3VudCArIGxlbjsKKyAgICAgIGlmIChuZXdjb3VudCA+IGJ1Zi5sZW5ndGgpIHsKKyAgICAgICAgYnl0ZSBuZXdidWZbXSA9IG5ldyBieXRlW01hdGgubWF4KGJ1Zi5sZW5ndGggPDwgMSwgbmV3Y291bnQpXTsKKyAgICAgICAgU3lzdGVtLmFycmF5Y29weShidWYsIDAsIG5ld2J1ZiwgMCwgY291bnQpOworICAgICAgICBidWYgPSBuZXdidWY7CisgICAgICB9CisgICAgICBpbi5yZWFkRnVsbHkoYnVmLCBjb3VudCwgbGVuKTsKKyAgICAgIGNvdW50ID0gbmV3Y291bnQ7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZXNldCgpIHsKKyAgICAgIC8vIFJlc3QgdGhlIGJ1ZmZlciBzbyB3ZSBkb24ndCBrZWVwIGFyb3VuZCB0aGUgc2hhcGUgb2YgdGhlIGJpZ2dlc3QKKyAgICAgIC8vIHZhbHVlIGV2ZXIgcmVhZC4KKyAgICAgIHRoaXMuYnVmID0gdGhpcy5pbml0aWFsQnVmZmVyOworICAgICAgc3VwZXIucmVzZXQoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEJ1ZmZlciBidWZmZXI7CisgIAorICAvKiogQ29uc3RydWN0cyBhIG5ldyBlbXB0eSBidWZmZXIuICovCisgIHB1YmxpYyBEYXRhT3V0cHV0QnVmZmVyKCkgeworICAgIHRoaXMobmV3IEJ1ZmZlcigpKTsKKyAgfQorICAKKyAgcHVibGljIERhdGFPdXRwdXRCdWZmZXIoaW50IHNpemUpIHsKKyAgICB0aGlzKG5ldyBCdWZmZXIoc2l6ZSkpOworICB9CisgIAorICBwcml2YXRlIERhdGFPdXRwdXRCdWZmZXIoQnVmZmVyIGJ1ZmZlcikgeworICAgIHN1cGVyKGJ1ZmZlcik7CisgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7CisgIH0KKworICAvKiogUmV0dXJucyB0aGUgY3VycmVudCBjb250ZW50cyBvZiB0aGUgYnVmZmVyLgorICAgKiAgRGF0YSBpcyBvbmx5IHZhbGlkIHRvIHtAbGluayAjZ2V0TGVuZ3RoKCl9LgorICAgKiBAcmV0dXJuIGJ5dGVbXSAKKyAgICovCisgIHB1YmxpYyBieXRlW10gZ2V0RGF0YSgpIHsgcmV0dXJuIGJ1ZmZlci5nZXREYXRhKCk7IH0KKworICAvKiogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSB2YWxpZCBkYXRhIGN1cnJlbnRseSBpbiB0aGUgYnVmZmVyLiAKKyAgICogQHJldHVybiBpbnQKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0TGVuZ3RoKCkgeyByZXR1cm4gYnVmZmVyLmdldExlbmd0aCgpOyB9CisKKyAgLyoqIFJlc2V0cyB0aGUgYnVmZmVyIHRvIGVtcHR5LiAKKyAgICogQHJldHVybiBEYXRhT3V0cHV0QnVmZmVyCisgICAqLworICBwdWJsaWMgRGF0YU91dHB1dEJ1ZmZlciByZXNldCgpIHsKKyAgICB0aGlzLndyaXR0ZW4gPSAwOworICAgIGJ1ZmZlci5yZXNldCgpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIFdyaXRlcyBieXRlcyBmcm9tIGEgRGF0YUlucHV0IGRpcmVjdGx5IGludG8gdGhlIGJ1ZmZlci4gCisgICAqIEBwYXJhbSBpbiAKKyAgICogQHBhcmFtIGxlbmd0aCAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YUlucHV0IGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ1ZmZlci53cml0ZShpbiwgbGVuZ3RoKTsKKyAgfQorCisgIC8qKiBXcml0ZSB0byBhIGZpbGUgc3RyZWFtIAorICAgKiBAcGFyYW0gb3V0IAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZVRvKE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnVmZmVyLndyaXRlVG8ob3V0KTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hCYXNlTWFwRmlsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSEJhc2VNYXBGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzNhZDUzNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hCYXNlTWFwRmlsZS5qYXZhCkBAIC0wLDAgKzEsMTMyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU3RvcmVLZXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogSEJhc2UgY3VzdG9taXphdGlvbnMgb2YgTWFwRmlsZS4KKyAqLworcHVibGljIGNsYXNzIEhCYXNlTWFwRmlsZSBleHRlbmRzIE1hcEZpbGUgeworICAvLyBUT0RPIG5vdCB1c2VkLiByZW1vdmU/IQorICAvLyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhCYXNlTWFwRmlsZS5jbGFzcyk7CisgIAorICAvKioKKyAgICogVmFsdWVzIGFyZSBpbnN0YW5jZXMgb2YgdGhpcyBjbGFzcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2xhc3M8PyBleHRlbmRzIFdyaXRhYmxlPiAgVkFMVUVfQ0xBU1MgPQorICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3M7CisKKyAgLyoqCisgICAqIEEgcmVhZGVyIGNhcGFibGUgb2YgcmVhZGluZyBhbmQgY2FjaGluZyBibG9ja3Mgb2YgdGhlIGRhdGEgZmlsZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSEJhc2VSZWFkZXIgZXh0ZW5kcyBNYXBGaWxlLlJlYWRlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGJsb2NrQ2FjaGVFbmFibGVkOworCisgICAgLyoqCisgICAgICogQHBhcmFtIGZzCisgICAgICogQHBhcmFtIGRpck5hbWUKKyAgICAgKiBAcGFyYW0gY29uZgorICAgICAqIEBwYXJhbSBocmkKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIEhCYXNlUmVhZGVyKEZpbGVTeXN0ZW0gZnMsIFN0cmluZyBkaXJOYW1lLCBDb25maWd1cmF0aW9uIGNvbmYsCisgICAgICBIUmVnaW9uSW5mbyBocmkpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMoZnMsIGRpck5hbWUsIGNvbmYsIGZhbHNlLCBocmkpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gZnMKKyAgICAgKiBAcGFyYW0gZGlyTmFtZQorICAgICAqIEBwYXJhbSBjb25mCisgICAgICogQHBhcmFtIGJsb2NrQ2FjaGVFbmFibGVkCisgICAgICogQHBhcmFtIGhyaQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgSEJhc2VSZWFkZXIoRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsIENvbmZpZ3VyYXRpb24gY29uZiwKKyAgICAgICAgYm9vbGVhbiBibG9ja0NhY2hlRW5hYmxlZCwgSFJlZ2lvbkluZm8gaHJpKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmcywgZGlyTmFtZSwgbmV3IEhTdG9yZUtleS5IU3RvcmVLZXlDb21wYXJhdG9yKCksIAorICAgICAgICAgIGNvbmYsIGZhbHNlKTsgLy8gZGVmZXIgb3BlbmluZyBzdHJlYW1zCisgICAgICB0aGlzLmJsb2NrQ2FjaGVFbmFibGVkID0gYmxvY2tDYWNoZUVuYWJsZWQ7CisgICAgICBvcGVuKGZzLCBkaXJOYW1lLCBuZXcgSFN0b3JlS2V5LkhTdG9yZUtleUNvbXBhcmF0b3IoKSwgY29uZik7CisgICAgICAKKyAgICAgIC8vIEZvcmNlIHJlYWRpbmcgb2YgdGhlIG1hcGZpbGUgaW5kZXggYnkgY2FsbGluZyBtaWRLZXkuIFJlYWRpbmcgdGhlCisgICAgICAvLyBpbmRleCB3aWxsIGJyaW5nIHRoZSBpbmRleCBpbnRvIG1lbW9yeSBvdmVyIGhlcmUgb24gdGhlIGNsaWVudCBhbmQKKyAgICAgIC8vIHRoZW4gY2xvc2UgdGhlIGluZGV4IGZpbGUgZnJlZWluZyB1cCBzb2NrZXQgY29ubmVjdGlvbiBhbmQgcmVzb3VyY2VzCisgICAgICAvLyBpbiB0aGUgZGF0YW5vZGUuIFVzdWFsbHksIHRoZSBmaXJzdCBhY2Nlc3Mgb24gYSBNYXBGaWxlLlJlYWRlciB3aWxsCisgICAgICAvLyBsb2FkIHRoZSBpbmRleCBmb3JjZSB0aGUgaXNzdWUgaW4gSFN0b3JlRmlsZSBNYXBGaWxlcyBiZWNhdXNlIGFuCisgICAgICAvLyBhY2Nlc3MgbWF5IG5vdCBoYXBwZW4gZm9yIHNvbWUgdGltZTsgbWVhbnRpbWUgd2UncmUgdXNpbmcgdXAgZGF0YW5vZGUKKyAgICAgIC8vIHJlc291cmNlcyAoU2VlIEhBRE9PUC0yMzQxKS4gbWlkS2V5KCkgZ29lcyB0byBpbmRleC4gRG9lcyBub3Qgc2Vlay4KKyAgICAgIG1pZEtleSgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TZXF1ZW5jZUZpbGUuUmVhZGVyIGNyZWF0ZURhdGFGaWxlUmVhZGVyKAorICAgICAgICBGaWxlU3lzdGVtIGZzLCBQYXRoIGRhdGFGaWxlLCBDb25maWd1cmF0aW9uIGNvbmYpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghYmxvY2tDYWNoZUVuYWJsZWQpIHsKKyAgICAgICAgcmV0dXJuIHN1cGVyLmNyZWF0ZURhdGFGaWxlUmVhZGVyKGZzLCBkYXRhRmlsZSwgY29uZik7CisgICAgICB9CisgICAgICBmaW5hbCBpbnQgYmxvY2tTaXplID0gY29uZi5nZXRJbnQoImhiYXNlLmhzdG9yZS5ibG9ja0NhY2hlLmJsb2NrU2l6ZSIsCisgICAgICAgIDY0ICogMTAyNCk7CisgICAgICByZXR1cm4gbmV3IFNlcXVlbmNlRmlsZS5SZWFkZXIoZnMsIGRhdGFGaWxlLCAgY29uZikgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHJvdGVjdGVkIEZTRGF0YUlucHV0U3RyZWFtIG9wZW5GaWxlKEZpbGVTeXN0ZW0gZnMsIFBhdGggZmlsZSwKKyAgICAgICAgICBpbnQgYnVmZmVyU2l6ZSwgbG9uZyBsZW5ndGgpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgcmV0dXJuIG5ldyBGU0RhdGFJbnB1dFN0cmVhbShuZXcgQmxvY2tGU0lucHV0U3RyZWFtKAorICAgICAgICAgICAgICAgICAgc3VwZXIub3BlbkZpbGUoZnMsIGZpbGUsIGJ1ZmZlclNpemUsIGxlbmd0aCksIGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgIGJsb2NrU2l6ZSkpOworICAgICAgICB9CisgICAgICB9OworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBIQmFzZVdyaXRlciBleHRlbmRzIE1hcEZpbGUuV3JpdGVyIHsKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gY29uZgorICAgICAqIEBwYXJhbSBmcworICAgICAqIEBwYXJhbSBkaXJOYW1lCisgICAgICogQHBhcmFtIGNvbXByZXNzaW9uCisgICAgICogQHBhcmFtIGhyaQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgSEJhc2VXcml0ZXIoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBTdHJpbmcgZGlyTmFtZSwKKyAgICAgICAgU2VxdWVuY2VGaWxlLkNvbXByZXNzaW9uVHlwZSBjb21wcmVzc2lvbiwgZmluYWwgSFJlZ2lvbkluZm8gaHJpKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzdXBlcihjb25mLCBmcywgZGlyTmFtZSwgbmV3IEhTdG9yZUtleS5IU3RvcmVLZXlDb21wYXJhdG9yKCksCisgICAgICAgICBWQUxVRV9DTEFTUywgY29tcHJlc3Npb24pOworICAgICAgLy8gRGVmYXVsdCBmb3IgbWFwZmlsZXMgaXMgMTI4LiAgTWFrZXMgcmFuZG9tIHJlYWRzIGZhc3RlciBpZiB3ZQorICAgICAgLy8gaGF2ZSBtb3JlIGtleXMgaW5kZXhlZCBhbmQgd2UncmUgbm90ICduZXh0Jy1pbmcgYXJvdW5kIGluIHRoZQorICAgICAgLy8gbWFwZmlsZS4KKyAgICAgIHNldEluZGV4SW50ZXJ2YWwoY29uZi5nZXRJbnQoImhiYXNlLmlvLmluZGV4LmludGVydmFsIiwgMTI4KSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9IYWxmSEZpbGVSZWFkZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hhbGZIRmlsZVJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiMTU0NzcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9IYWxmSEZpbGVSZWFkZXIuamF2YQpAQCAtMCwwICsxLDIyMiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkJsb2NrQ2FjaGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGVTY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlLlJlYWRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEEgZmFjYWRlIGZvciBhIHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZS5SZWFkZXJ9IHRoYXQgc2VydmVzIHVwCisgKiBlaXRoZXIgdGhlIHRvcCBvciBib3R0b20gaGFsZiBvZiBhIEhGaWxlIHdoZXJlICdib3R0b20nIGlzIHRoZSBmaXJzdCBoYWxmCisgKiBvZiB0aGUgZmlsZSBjb250YWluaW5nIHRoZSBrZXlzIHRoYXQgc29ydCBsb3dlc3QgYW5kICd0b3AnIGlzIHRoZSBzZWNvbmQgaGFsZgorICogb2YgdGhlIGZpbGUgd2l0aCBrZXlzIHRoYXQgc29ydCBncmVhdGVyIHRoYW4gdGhvc2Ugb2YgdGhlIGJvdHRvbSBoYWxmLgorICogVGhlIHRvcCBpbmNsdWRlcyB0aGUgc3BsaXQgZmlsZXMgbWlka2V5LCBvZiB0aGUga2V5IHRoYXQgZm9sbG93cyBpZiBpdCBkb2VzCisgKiBub3QgZXhpc3QgaW4gdGhlIGZpbGUuCisgKiAKKyAqIDxwPlRoaXMgdHlwZSB3b3JrcyBpbiB0YW5kZW0gd2l0aCB0aGUge0BsaW5rIFJlZmVyZW5jZX0gdHlwZS4gIFRoaXMgY2xhc3MKKyAqIGlzIHVzZWQgcmVhZGluZyB3aGlsZSBSZWZlcmVuY2UgaXMgdXNlZCB3cml0aW5nLgorICogCisgKiA8cD5UaGlzIGZpbGUgaXMgbm90IHNwbGl0YWJsZS4gIENhbGxzIHRvIHtAbGluayAjbWlka2V5KCl9IHJldHVybiBudWxsLgorICovCitwdWJsaWMgY2xhc3MgSGFsZkhGaWxlUmVhZGVyIGV4dGVuZHMgSEZpbGUuUmVhZGVyIHsKKyAgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhhbGZIRmlsZVJlYWRlci5jbGFzcyk7CisgIGZpbmFsIGJvb2xlYW4gdG9wOworICAvLyBUaGlzIGlzIHRoZSBrZXkgd2Ugc3BsaXQgYXJvdW5kLiAgSXRzIHRoZSBmaXJzdCBwb3NzaWJsZSBlbnRyeSBvbiBhIHJvdzoKKyAgLy8gaS5lLiBlbXB0eSBjb2x1bW4gYW5kIGEgdGltZXN0YW1wIG9mIExBVEVTVF9USU1FU1RBTVAuCisgIGZpbmFsIGJ5dGUgW10gc3BsaXRrZXk7CisKKyAgLyoqCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gcAorICAgKiBAcGFyYW0gYworICAgKiBAcGFyYW0gcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSGFsZkhGaWxlUmVhZGVyKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggcCwgZmluYWwgQmxvY2tDYWNoZSBjLAorICAgIGZpbmFsIFJlZmVyZW5jZSByKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKGZzLCBwLCBjKTsKKyAgICAvLyBUaGlzIGlzIG5vdCBhY3R1YWwgbWlka2V5IGZvciB0aGlzIGhhbGYtZmlsZTsgaXRzIGp1c3QgYm9yZGVyCisgICAgLy8gYXJvdW5kIHdoaWNoIHdlIHNwbGl0IHRvcCBhbmQgYm90dG9tLiAgSGF2ZSB0byBsb29rIGluIGZpbGVzIHRvIGZpbmQKKyAgICAvLyBhY3R1YWwgbGFzdCBhbmQgZmlyc3Qga2V5cyBmb3IgYm90dG9tIGFuZCB0b3AgaGFsdmVzLiAgSGFsZi1maWxlcyBkb24ndAorICAgIC8vIGhhdmUgYW4gYWN0dWFsIG1pZGtleSB0aGVtc2VsdmVzLiBObyBtaWRrZXkgaXMgaG93IHdlIGluZGljYXRlIGZpbGUgaXMKKyAgICAvLyBub3Qgc3BsaXR0YWJsZS4KKyAgICB0aGlzLnNwbGl0a2V5ID0gci5nZXRTcGxpdEtleSgpOworICAgIC8vIElzIGl0IHRvcCBvciBib3R0b20gaGFsZj8KKyAgICB0aGlzLnRvcCA9IFJlZmVyZW5jZS5pc1RvcEZpbGVSZWdpb24oci5nZXRGaWxlUmVnaW9uKCkpOworICB9CisKKyAgcHJvdGVjdGVkIGJvb2xlYW4gaXNUb3AoKSB7CisgICAgcmV0dXJuIHRoaXMudG9wOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBIRmlsZVNjYW5uZXIgZ2V0U2Nhbm5lcigpIHsKKyAgICBmaW5hbCBIRmlsZVNjYW5uZXIgcyA9IHN1cGVyLmdldFNjYW5uZXIoKTsKKyAgICByZXR1cm4gbmV3IEhGaWxlU2Nhbm5lcigpIHsKKyAgICAgIGZpbmFsIEhGaWxlU2Nhbm5lciBkZWxlZ2F0ZSA9IHM7CisKKyAgICAgIHB1YmxpYyBCeXRlQnVmZmVyIGdldEtleSgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEtleSgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgU3RyaW5nIGdldEtleVN0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldEtleVN0cmluZygpOworICAgICAgfQorCisgICAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBnZXRWYWx1ZSgpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmdldFZhbHVlKCk7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWVTdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRWYWx1ZVN0cmluZygpOworICAgICAgfQorCisgICAgICBwdWJsaWMgS2V5VmFsdWUgZ2V0S2V5VmFsdWUoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRLZXlWYWx1ZSgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYm9vbGVhbiBiID0gZGVsZWdhdGUubmV4dCgpOworICAgICAgICBpZiAoIWIpIHsKKyAgICAgICAgICByZXR1cm4gYjsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXRvcCkgeworICAgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBnZXRLZXkoKTsKKyAgICAgICAgICBpZiAoZ2V0Q29tcGFyYXRvcigpLmNvbXBhcmUoYmIuYXJyYXkoKSwgYmIuYXJyYXlPZmZzZXQoKSwgYmIubGltaXQoKSwKKyAgICAgICAgICAgICAgc3BsaXRrZXksIDAsIHNwbGl0a2V5Lmxlbmd0aCkgPj0gMCkgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgcHVibGljIGJvb2xlYW4gc2Vla0JlZm9yZShieXRlW10ga2V5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICByZXR1cm4gc2Vla0JlZm9yZShrZXksIDAsIGtleS5sZW5ndGgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBzZWVrQmVmb3JlKGJ5dGUgW10ga2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHRvcCkgeworICAgICAgICAgIGlmIChnZXRDb21wYXJhdG9yKCkuY29tcGFyZShrZXksIG9mZnNldCwgbGVuZ3RoLCBzcGxpdGtleSwgMCwKKyAgICAgICAgICAgICAgc3BsaXRrZXkubGVuZ3RoKSA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKGdldENvbXBhcmF0b3IoKS5jb21wYXJlKGtleSwgb2Zmc2V0LCBsZW5ndGgsIHNwbGl0a2V5LCAwLAorICAgICAgICAgICAgICBzcGxpdGtleS5sZW5ndGgpID49IDApIHsKKyAgICAgICAgICAgIHJldHVybiBzZWVrQmVmb3JlKHNwbGl0a2V5LCAwLCBzcGxpdGtleS5sZW5ndGgpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZS5zZWVrQmVmb3JlKGtleSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBzZWVrVG8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodG9wKSB7CisgICAgICAgICAgaW50IHIgPSB0aGlzLmRlbGVnYXRlLnNlZWtUbyhzcGxpdGtleSk7CisgICAgICAgICAgaWYgKHIgPCAwKSB7CisgICAgICAgICAgICAvLyBtaWRrZXkgaXMgPCBmaXJzdCBrZXkgaW4gZmlsZQorICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUuc2Vla1RvKCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChyID4gMCkgeworICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUubmV4dCgpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgYm9vbGVhbiBiID0gZGVsZWdhdGUuc2Vla1RvKCk7CisgICAgICAgIGlmICghYikgeworICAgICAgICAgIHJldHVybiBiOworICAgICAgICB9CisgICAgICAgIC8vIENoZWNrIGtleS4KKyAgICAgICAgQnl0ZUJ1ZmZlciBrID0gdGhpcy5kZWxlZ2F0ZS5nZXRLZXkoKTsKKyAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUuZ2V0UmVhZGVyKCkuZ2V0Q29tcGFyYXRvcigpLgorICAgICAgICAgIGNvbXBhcmUoay5hcnJheSgpLCBrLmFycmF5T2Zmc2V0KCksIGsubGltaXQoKSwKKyAgICAgICAgICAgIHNwbGl0a2V5LCAwLCBzcGxpdGtleS5sZW5ndGgpIDwgMDsKKyAgICAgIH0KKworICAgICAgcHVibGljIGludCBzZWVrVG8oYnl0ZVtdIGtleSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNlZWtUbyhrZXksIDAsIGtleS5sZW5ndGgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgaW50IHNlZWtUbyhieXRlW10ga2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodG9wKSB7CisgICAgICAgICAgaWYgKGdldENvbXBhcmF0b3IoKS5jb21wYXJlKGtleSwgb2Zmc2V0LCBsZW5ndGgsIHNwbGl0a2V5LCAwLAorICAgICAgICAgICAgICBzcGxpdGtleS5sZW5ndGgpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoZ2V0Q29tcGFyYXRvcigpLmNvbXBhcmUoa2V5LCBvZmZzZXQsIGxlbmd0aCwgc3BsaXRrZXksIDAsCisgICAgICAgICAgICAgIHNwbGl0a2V5Lmxlbmd0aCkgPj0gMCkgeworICAgICAgICAgICAgLy8gd2Ugd291bGQgcGxhY2UgdGhlIHNjYW5uZXIgaW4gdGhlIHNlY29uZCBoYWxmLgorICAgICAgICAgICAgLy8gaXQgbWlnaHQgYmUgYW4gZXJyb3IgdG8gcmV0dXJuIGZhbHNlIGhlcmUgZXZlci4uLgorICAgICAgICAgICAgYm9vbGVhbiByZXMgPSBkZWxlZ2F0ZS5zZWVrQmVmb3JlKHNwbGl0a2V5LCAwLCBzcGxpdGtleS5sZW5ndGgpOworICAgICAgICAgICAgaWYgKCFyZXMpIHsKKyAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTZWVraW5nIGZvciBhIGtleSBpbiBib3R0b20gb2YgZmlsZSwgYnV0IGtleSBleGlzdHMgaW4gdG9wIG9mIGZpbGUsIGZhaWxlZCBvbiBzZWVrQmVmb3JlKG1pZGtleSkiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZGVsZWdhdGUuc2Vla1RvKGtleSwgb2Zmc2V0LCBsZW5ndGgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgUmVhZGVyIGdldFJlYWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUuZ2V0UmVhZGVyKCk7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBib29sZWFuIGlzU2Vla2VkKCkgeworICAgICAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZS5pc1NlZWtlZCgpOworICAgICAgfQorICAgIH07CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJ5dGVbXSBnZXRMYXN0S2V5KCkgeworICAgIGlmICh0b3ApIHsKKyAgICAgIHJldHVybiBzdXBlci5nZXRMYXN0S2V5KCk7IAorICAgIH0KKyAgICBIRmlsZVNjYW5uZXIgc2Nhbm5lciA9IGdldFNjYW5uZXIoKTsKKyAgICB0cnkgeworICAgICAgaWYgKHNjYW5uZXIuc2Vla0JlZm9yZSh0aGlzLnNwbGl0a2V5KSkgeworICAgICAgICByZXR1cm4gQnl0ZXMudG9CeXRlcyhzY2FubmVyLmdldEtleSgpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHNlZWtCZWZvcmUgIiArIEJ5dGVzLnRvU3RyaW5nKHRoaXMuc3BsaXRrZXkpLCBlKTsKKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJ5dGVbXSBtaWRrZXkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFJldHVybnMgbnVsbCB0byBpbmRpY2F0ZSBmaWxlIGlzIG5vdCBzcGxpdGFibGUuCisgICAgcmV0dXJuIG51bGw7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hhbGZNYXBGaWxlUmVhZGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9IYWxmTWFwRmlsZVJlYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmZjNmYzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9IYWxmTWFwRmlsZVJlYWRlci5qYXZhCkBAIC0wLDAgKzEsMjEzIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW87CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFN0b3JlS2V5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJlZmVyZW5jZS5SYW5nZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CisKKy8qKgorICogQSBmYWNhZGUgZm9yIGEge0BsaW5rIG9yZy5hcGFjaGUuaGFkb29wLmlvLk1hcEZpbGUuUmVhZGVyfSB0aGF0IHNlcnZlcyB1cAorICogZWl0aGVyIHRoZSB0b3Agb3IgYm90dG9tIGhhbGYgb2YgYSBNYXBGaWxlIHdoZXJlICdib3R0b20nIGlzIHRoZSBmaXJzdCBoYWxmCisgKiBvZiB0aGUgZmlsZSBjb250YWluaW5nIHRoZSBrZXlzIHRoYXQgc29ydCBsb3dlc3QgYW5kICd0b3AnIGlzIHRoZSBzZWNvbmQgaGFsZgorICogb2YgdGhlIGZpbGUgd2l0aCBrZXlzIHRoYXQgc29ydCBncmVhdGVyIHRoYW4gdGhvc2Ugb2YgdGhlIGJvdHRvbSBoYWxmLgorICogVGhlIHRvcCBpbmNsdWRlcyB0aGUgc3BsaXQgZmlsZXMgbWlka2V5LCBvZiB0aGUga2V5IHRoYXQgZm9sbG93cyBpZiBpdCBkb2VzCisgKiBub3QgZXhpc3QgaW4gdGhlIGZpbGUuCisgKiAKKyAqIDxwPlRoaXMgdHlwZSB3b3JrcyBpbiB0YW5kZW0gd2l0aCB0aGUge0BsaW5rIFJlZmVyZW5jZX0gdHlwZS4gIFRoaXMgY2xhc3MKKyAqIGlzIHVzZWQgcmVhZGluZyB3aGlsZSBSZWZlcmVuY2UgaXMgdXNlZCB3cml0aW5nLgorICogCisgKiA8cD5UaGlzIGZpbGUgaXMgbm90IHNwbGl0YWJsZS4gIENhbGxzIHRvIHtAbGluayAjbWlkS2V5KCl9IHJldHVybiBudWxsLgorICovCisvL1RPRE8gc2hvdWxkIGJlIGZpeGVkIGdlbmVyaWMgd2FybmluZ3MgZnJvbSBNYXBGaWxlIG1ldGhvZHMKK3B1YmxpYyBjbGFzcyBIYWxmTWFwRmlsZVJlYWRlciBleHRlbmRzIEhCYXNlTWFwRmlsZS5IQmFzZVJlYWRlciB7CisgIHByaXZhdGUgZmluYWwgYm9vbGVhbiB0b3A7CisgIHByaXZhdGUgZmluYWwgSFN0b3JlS2V5IG1pZGtleTsKKyAgcHJpdmF0ZSBib29sZWFuIGZpcnN0TmV4dENhbGwgPSB0cnVlOworICAKKyAgLyoqCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gZGlyTmFtZQorICAgKiBAcGFyYW0gY29uZgorICAgKiBAcGFyYW0gcgorICAgKiBAcGFyYW0gbWsKKyAgICogQHBhcmFtIGhyaQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSGFsZk1hcEZpbGVSZWFkZXIoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgU3RyaW5nIGRpck5hbWUsIAorICAgICAgZmluYWwgQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBSYW5nZSByLAorICAgICAgZmluYWwgV3JpdGFibGVDb21wYXJhYmxlPEhTdG9yZUtleT4gbWssCisgICAgICBmaW5hbCBIUmVnaW9uSW5mbyBocmkpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcyhmcywgZGlyTmFtZSwgY29uZiwgciwgbWssIGZhbHNlLCBocmkpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBkaXJOYW1lCisgICAqIEBwYXJhbSBjb25mCisgICAqIEBwYXJhbSByCisgICAqIEBwYXJhbSBtaworICAgKiBAcGFyYW0gYmxvY2tDYWNoZUVuYWJsZWQKKyAgICogQHBhcmFtIGhyaQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSGFsZk1hcEZpbGVSZWFkZXIoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgU3RyaW5nIGRpck5hbWUsIAorICAgICAgZmluYWwgQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBSYW5nZSByLAorICAgICAgZmluYWwgV3JpdGFibGVDb21wYXJhYmxlPEhTdG9yZUtleT4gbWssCisgICAgICBmaW5hbCBib29sZWFuIGJsb2NrQ2FjaGVFbmFibGVkLAorICAgICAgZmluYWwgSFJlZ2lvbkluZm8gaHJpKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKGZzLCBkaXJOYW1lLCBjb25mLCBibG9ja0NhY2hlRW5hYmxlZCwgaHJpKTsKKyAgICAvLyBUaGlzIGlzIG5vdCBhY3R1YWwgbWlka2V5IGZvciB0aGlzIGhhbGYtZmlsZTsgaXRzIGp1c3QgYm9yZGVyCisgICAgLy8gYXJvdW5kIHdoaWNoIHdlIHNwbGl0IHRvcCBhbmQgYm90dG9tLiAgSGF2ZSB0byBsb29rIGluIGZpbGVzIHRvIGZpbmQKKyAgICAvLyBhY3R1YWwgbGFzdCBhbmQgZmlyc3Qga2V5cyBmb3IgYm90dG9tIGFuZCB0b3AgaGFsdmVzLiAgSGFsZi1maWxlcyBkb24ndAorICAgIC8vIGhhdmUgYW4gYWN0dWFsIG1pZGtleSB0aGVtc2VsdmVzLiBObyBtaWRrZXkgaXMgaG93IHdlIGluZGljYXRlIGZpbGUgaXMKKyAgICAvLyBub3Qgc3BsaXR0YWJsZS4KKyAgICB0aGlzLm1pZGtleSA9IG5ldyBIU3RvcmVLZXkoKEhTdG9yZUtleSltayk7CisgICAgLy8gSXMgaXQgdG9wIG9yIGJvdHRvbSBoYWxmPworICAgIHRoaXMudG9wID0gUmVmZXJlbmNlLmlzVG9wRmlsZVJlZ2lvbihyKTsKKyAgfQorICAKKyAgLyoKKyAgICogQ2hlY2sga2V5IGlzIG5vdCBibGVlZGluZyBpbnRvIHdyb25nIGhhbGYgb2YgdGhlIGZpbGUuCisgICAqIEBwYXJhbSBrZXkKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNoZWNrS2V5KGZpbmFsIFdyaXRhYmxlQ29tcGFyYWJsZTxIU3RvcmVLZXk+IGtleSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodG9wKSB7CisgICAgICBpZiAoa2V5LmNvbXBhcmVUbyhtaWRrZXkpIDwgMCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIklsbGVnYWwgQWNjZXNzOiBLZXkgaXMgbGVzcyB0aGFuIG1pZEtleSBvZiAiICsKKyAgICAgICAgImJhY2tpbmcgbWFwZmlsZSIpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoa2V5LmNvbXBhcmVUbyhtaWRrZXkpID49IDApIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSWxsZWdhbCBBY2Nlc3M6IEtleSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgIiArCisgICAgICAidG8gbWlkS2V5IG9mIGJhY2tpbmcgbWFwZmlsZSIpOworICAgIH0KKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZpbmFsS2V5KFdyaXRhYmxlQ29tcGFyYWJsZSBrZXkpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRvcCkgeworICAgICAgc3VwZXIuZmluYWxLZXkoa2V5KTsgCisgICAgfSBlbHNlIHsKKyAgICAgIFdyaXRhYmxlIHZhbHVlID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICAgIFdyaXRhYmxlQ29tcGFyYWJsZSBmb3VuZCA9IHN1cGVyLmdldENsb3Nlc3QobWlka2V5LCB2YWx1ZSwgdHJ1ZSk7CisgICAgICBXcml0YWJsZXMuY29weVdyaXRhYmxlKGZvdW5kLCBrZXkpOworICAgIH0KKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCBXcml0YWJsZSBnZXQoV3JpdGFibGVDb21wYXJhYmxlIGtleSwgV3JpdGFibGUgdmFsKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrS2V5KGtleSk7CisgICAgcmV0dXJuIHN1cGVyLmdldChrZXksIHZhbCk7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGVDb21wYXJhYmxlIGdldENsb3Nlc3QoV3JpdGFibGVDb21wYXJhYmxlIGtleSwKKyAgICBXcml0YWJsZSB2YWwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgV3JpdGFibGVDb21wYXJhYmxlIGNsb3Nlc3QgPSBudWxsOworICAgIGlmICh0b3ApIHsKKyAgICAgIC8vIElmIHRvcCwgdGhlIGxvd2VzdCBwb3NzaWJsZSBrZXkgaXMgZmlyc3Qga2V5LiAgRG8gbm90IGhhdmUgdG8gY2hlY2sKKyAgICAgIC8vIHdoYXQgY29tZXMgYmFjayBmcm9tIHN1cGVyIGdldENsb3Nlc3QuICBXaWxsIHJldHVybiBleGFjdCBtYXRjaCBvcgorICAgICAgLy8gZ3JlYXRlci4KKyAgICAgIGNsb3Nlc3QgPSAoa2V5LmNvbXBhcmVUbyh0aGlzLm1pZGtleSkgPCAwKT8KKyAgICAgICAgdGhpcy5taWRrZXk6IHN1cGVyLmdldENsb3Nlc3Qoa2V5LCB2YWwpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBXZSdyZSBzZXJ2aW5nIGJvdHRvbSBvZiB0aGUgZmlsZS4KKyAgICAgIGlmIChrZXkuY29tcGFyZVRvKHRoaXMubWlka2V5KSA8IDApIHsKKyAgICAgICAgLy8gQ2hlY2sga2V5IGlzIHdpdGhpbiByYW5nZSBmb3IgYm90dG9tLgorICAgICAgICBjbG9zZXN0ID0gc3VwZXIuZ2V0Q2xvc2VzdChrZXksIHZhbCk7CisgICAgICAgIC8vIG1pZGtleSB3YXMgbWFkZSBhZ2FpbnN0IGxhcmdlc3Qgc3RvcmUgZmlsZSBhdCB0aW1lIG9mIHNwbGl0LiBTbWFsbGVyCisgICAgICAgIC8vIHN0b3JlIGZpbGVzIGNvdWxkIGhhdmUgYW55dGhpbmcgaW4gdGhlbS4gIENoZWNrIHJldHVybiB2YWx1ZSBpcworICAgICAgICAvLyBub3QgYmV5b25kIHRoZSBtaWRrZXkgKGdldENsb3Nlc3QgcmV0dXJucyBleGFjdCBtYXRjaCBvciBuZXh0IGFmdGVyKQorICAgICAgICBpZiAoY2xvc2VzdCAhPSBudWxsICYmIGNsb3Nlc3QuY29tcGFyZVRvKHRoaXMubWlka2V5KSA+PSAwKSB7CisgICAgICAgICAgLy8gRG9uJ3QgbGV0IHRoaXMgdmFsdWUgb3V0LgorICAgICAgICAgIGNsb3Nlc3QgPSBudWxsOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBFbHNlLCBrZXkgaXMgPiBtaWRrZXkgc28gbGV0IG91dCBjbG9zZXN0ID0gbnVsbC4KKyAgICB9CisgICAgcmV0dXJuIGNsb3Nlc3Q7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGVDb21wYXJhYmxlIG1pZEtleSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gUmV0dXJucyBudWxsIHRvIGluZGljYXRlIGZpbGUgaXMgbm90IHNwbGl0YWJsZS4KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIG5leHQoV3JpdGFibGVDb21wYXJhYmxlIGtleSwgV3JpdGFibGUgdmFsKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmaXJzdE5leHRDYWxsKSB7CisgICAgICBmaXJzdE5leHRDYWxsID0gZmFsc2U7CisgICAgICBpZiAodGhpcy50b3ApIHsKKyAgICAgICAgLy8gU2VlayB0byBtaWRrZXkuICBNaWRrZXkgbWF5IG5vdCBleGlzdCBpbiB0aGlzIGZpbGUuICBUaGF0IHNob3VsZCBiZQorICAgICAgICAvLyBmaW5lLiAgVGhlbiB3ZSdsbCBlaXRoZXIgYmUgcG9zaXRpb25lZCBhdCBlbmQgb3Igc3RhcnQgb2YgZmlsZS4KKyAgICAgICAgV3JpdGFibGVDb21wYXJhYmxlIG5lYXJlc3QgPSBnZXRDbG9zZXN0KHRoaXMubWlka2V5LCB2YWwpOworICAgICAgICAvLyBOb3cgY29weSB0aGUgbWlka2V5IGludG8gdGhlIHBhc3NlZCBrZXkuCisgICAgICAgIGlmIChuZWFyZXN0ICE9IG51bGwpIHsKKyAgICAgICAgICBXcml0YWJsZXMuY29weVdyaXRhYmxlKG5lYXJlc3QsIGtleSk7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOyAKKyAgICAgIH0KKyAgICB9CisgICAgYm9vbGVhbiByZXN1bHQgPSBzdXBlci5uZXh0KGtleSwgdmFsKTsKKyAgICBpZiAoIXRvcCAmJiBrZXkuY29tcGFyZVRvKG1pZGtleSkgPj0gMCkgeworICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0b3ApIHsKKyAgICAgIGZpcnN0TmV4dENhbGwgPSB0cnVlOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBzdXBlci5yZXNldCgpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIEBPdmVycmlkZQorICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gc2VlayhXcml0YWJsZUNvbXBhcmFibGUga2V5KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrS2V5KGtleSk7CisgICAgcmV0dXJuIHN1cGVyLnNlZWsoa2V5KTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSGJhc2VNYXBXcml0YWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSGJhc2VNYXBXcml0YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1NDk5MTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9IYmFzZU1hcFdyaXRhYmxlLmphdmEKQEAgLTAsMCArMSwyMjEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNSZWZlcmVuY2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlJlZmxlY3Rpb25VdGlsczsKKworLyoqCisgKiBBIFdyaXRhYmxlIE1hcC4KKyAqIExpa2Uge0BsaW5rIG9yZy5hcGFjaGUuaGFkb29wLmlvLk1hcFdyaXRhYmxlfSBidXQgZHVtYi4gSXQgd2lsbCBmYWlsCisgKiBpZiBwYXNzZWQgYSB2YWx1ZSB0eXBlIHRoYXQgaXQgaGFzIG5vdCBhbHJlYWR5IGJlZW4gdG9sZCBhYm91dC4gSXRzICBiZWVuCisgKiBwcmltZWQgd2l0aCBoYmFzZSBXcml0YWJsZXMgYW5kIGJ5dGUgW10uICBLZXlzIGFyZSBhbHdheXMgYnl0ZSBhcnJheXMuCisgKgorICogQHBhcmFtIDxLPiA8Ynl0ZSBbXT4ga2V5ICBUT0RPOiBQYXJhbWV0ZXIgSyBpcyBuZXZlciB1c2VkLCBjb3VsZCBiZSByZW1vdmVkLgorICogQHBhcmFtIDxWPiB2YWx1ZSBFeHBlY3RzIGEgV3JpdGFibGUgb3IgYnl0ZSBbXS4KKyAqLworcHVibGljIGNsYXNzIEhiYXNlTWFwV3JpdGFibGUgPEssVj4KK2ltcGxlbWVudHMgU29ydGVkTWFwPGJ5dGVbXSxWPiwgQ29uZmlndXJhYmxlLCBXcml0YWJsZSwgQ29kZVRvQ2xhc3NBbmRCYWNreworICBwcml2YXRlIEF0b21pY1JlZmVyZW5jZTxDb25maWd1cmF0aW9uPiBjb25mID0gbnVsbDsKKyAgcHJvdGVjdGVkIFNvcnRlZE1hcDxieXRlIFtdLCBWPiBpbnN0YW5jZSA9IG51bGw7CisKKyAgLyoqCisgICAqIFRoZSBkZWZhdWx0IGNvbnRydWN0b3Igd2hlcmUgYSBUcmVlTWFwIGlzIHVzZWQKKyAgICoqLworICAgcHVibGljIEhiYXNlTWFwV3JpdGFibGUoKXsKKyAgICAgdGhpcyAobmV3IFRyZWVNYXA8Ynl0ZSBbXSwgVj4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUikpOworICAgfQorCisgIC8qKgorICAgKiBDb250cnVjdG9yIHdoZXJlIGFub3RoZXIgU29ydGVkTWFwIGNhbiBiZSB1c2VkCisgICAqIAorICAgKiBAcGFyYW0gbWFwIHRoZSBTb3J0ZWRNYXAgdG8gYmUgdXNlZCAKKyAgICovCisgIHB1YmxpYyBIYmFzZU1hcFdyaXRhYmxlKFNvcnRlZE1hcDxieXRlW10sIFY+IG1hcCl7CisgICAgY29uZiA9IG5ldyBBdG9taWNSZWZlcmVuY2U8Q29uZmlndXJhdGlvbj4oKTsKKyAgICBpbnN0YW5jZSA9IG1hcDsKKyAgfQorICAKKyAgCisgIC8qKiBAcmV0dXJuIHRoZSBjb25mICovCisgIHB1YmxpYyBDb25maWd1cmF0aW9uIGdldENvbmYoKSB7CisgICAgcmV0dXJuIGNvbmYuZ2V0KCk7CisgIH0KKworICAvKiogQHBhcmFtIGNvbmYgdGhlIGNvbmYgdG8gc2V0ICovCisgIHB1YmxpYyB2b2lkIHNldENvbmYoQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgdGhpcy5jb25mLnNldChjb25mKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGNsZWFyKCkgeworICAgIGluc3RhbmNlLmNsZWFyKCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgcmV0dXJuIGluc3RhbmNlLmNvbnRhaW5zS2V5KGtleSk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgIHJldHVybiBpbnN0YW5jZS5jb250YWluc1ZhbHVlKHZhbHVlKTsKKyAgfQorCisgIHB1YmxpYyBTZXQ8RW50cnk8Ynl0ZSBbXSwgVj4+IGVudHJ5U2V0KCkgeworICAgIHJldHVybiBpbnN0YW5jZS5lbnRyeVNldCgpOworICB9CisKKyAgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICByZXR1cm4gaW5zdGFuY2UuZ2V0KGtleSk7CisgIH0KKyAgCisgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgcmV0dXJuIGluc3RhbmNlLmlzRW1wdHkoKTsKKyAgfQorCisgIHB1YmxpYyBTZXQ8Ynl0ZSBbXT4ga2V5U2V0KCkgeworICAgIHJldHVybiBpbnN0YW5jZS5rZXlTZXQoKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gaW5zdGFuY2Uuc2l6ZSgpOworICB9CisKKyAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgIHJldHVybiBpbnN0YW5jZS52YWx1ZXMoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHB1dEFsbChNYXA8PyBleHRlbmRzIGJ5dGUgW10sID8gZXh0ZW5kcyBWPiBtKSB7CisgICAgdGhpcy5pbnN0YW5jZS5wdXRBbGwobSk7CisgIH0KKworICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgIHJldHVybiB0aGlzLmluc3RhbmNlLnJlbW92ZShrZXkpOworICB9CisKKyAgcHVibGljIFYgcHV0KGJ5dGUgW10ga2V5LCBWIHZhbHVlKSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2UucHV0KGtleSwgdmFsdWUpOworICB9CisKKyAgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBieXRlW10+IGNvbXBhcmF0b3IoKSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2UuY29tcGFyYXRvcigpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBmaXJzdEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5pbnN0YW5jZS5maXJzdEtleSgpOworICB9CisKKyAgcHVibGljIFNvcnRlZE1hcDxieXRlW10sIFY+IGhlYWRNYXAoYnl0ZVtdIHRvS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2UuaGVhZE1hcCh0b0tleSk7CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGxhc3RLZXkoKSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2UubGFzdEtleSgpOworICB9CisKKyAgcHVibGljIFNvcnRlZE1hcDxieXRlW10sIFY+IHN1Yk1hcChieXRlW10gZnJvbUtleSwgYnl0ZVtdIHRvS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2Uuc3ViTWFwKGZyb21LZXksIHRvS2V5KTsKKyAgfQorCisgIHB1YmxpYyBTb3J0ZWRNYXA8Ynl0ZVtdLCBWPiB0YWlsTWFwKGJ5dGVbXSBmcm9tS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2UudGFpbE1hcChmcm9tS2V5KTsKKyAgfQorICAKKyAgLy8gV3JpdGFibGUKKworICAvKiogQHJldHVybiB0aGUgQ2xhc3MgY2xhc3MgZm9yIHRoZSBzcGVjaWZpZWQgaWQgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgIHByb3RlY3RlZCBDbGFzczw/PiBnZXRDbGFzcyhieXRlIGlkKSB7CisgICAgcmV0dXJuIENPREVfVE9fQ0xBU1MuZ2V0KGlkKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBpZCBmb3IgdGhlIHNwZWNpZmllZCBDbGFzcyAqLworICBAU3VwcHJlc3NXYXJuaW5ncygiYm94aW5nIikKKyAgcHJvdGVjdGVkIGJ5dGUgZ2V0SWQoQ2xhc3M8Pz4gY2xhenopIHsKKyAgICBCeXRlIGIgPSBDTEFTU19UT19DT0RFLmdldChjbGF6eik7CisgICAgaWYgKGIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJOb3RoaW5nIGZvciA6ICIgKyBjbGF6eik7CisgICAgfQorICAgIHJldHVybiBiOworICB9CisgIAorICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiB0aGlzLmluc3RhbmNlLnRvU3RyaW5nKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSBvdXQgdGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSBtYXAKKyAgICBvdXQud3JpdGVJbnQodGhpcy5pbnN0YW5jZS5zaXplKCkpOworICAgIC8vIFRoZW4gd3JpdGUgb3V0IGVhY2gga2V5L3ZhbHVlIHBhaXIKKyAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBWPiBlOiBpbnN0YW5jZS5lbnRyeVNldCgpKSB7CisgICAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIGUuZ2V0S2V5KCkpOworICAgICAgQnl0ZSBpZCA9IGdldElkKGUuZ2V0VmFsdWUoKS5nZXRDbGFzcygpKTsKKyAgICAgIG91dC53cml0ZUJ5dGUoaWQpOworICAgICAgT2JqZWN0IHZhbHVlID0gZS5nZXRWYWx1ZSgpOworICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgYnl0ZSBbXSkgeworICAgICAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIChieXRlIFtdKXZhbHVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgICgoV3JpdGFibGUpdmFsdWUpLndyaXRlKG91dCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIEZpcnN0IGNsZWFyIHRoZSBtYXAuICBPdGhlcndpc2Ugd2Ugd2lsbCBqdXN0IGFjY3VtdWxhdGUKKyAgICAvLyBlbnRyaWVzIGV2ZXJ5IHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgorICAgIHRoaXMuaW5zdGFuY2UuY2xlYXIoKTsKKyAgICAvLyBSZWFkIHRoZSBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgbWFwCisgICAgaW50IGVudHJpZXMgPSBpbi5yZWFkSW50KCk7CisgICAgLy8gVGhlbiByZWFkIGVhY2gga2V5L3ZhbHVlIHBhaXIKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGVudHJpZXM7IGkrKykgeworICAgICAgYnl0ZSBbXSBrZXkgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICAgIGJ5dGUgaWQgPSBpbi5yZWFkQnl0ZSgpOworICAgICAgQ2xhc3MgY2xhenogPSBnZXRDbGFzcyhpZCk7CisgICAgICBWIHZhbHVlID0gbnVsbDsKKyAgICAgIGlmIChjbGF6ei5lcXVhbHMoYnl0ZSBbXS5jbGFzcykpIHsKKyAgICAgICAgYnl0ZSBbXSBieXRlcyA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgICAgICB2YWx1ZSA9IChWKWJ5dGVzOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgV3JpdGFibGUgdyA9IChXcml0YWJsZSlSZWZsZWN0aW9uVXRpbHMuCisgICAgICAgICAgbmV3SW5zdGFuY2UoY2xhenosIGdldENvbmYoKSk7CisgICAgICAgIHcucmVhZEZpZWxkcyhpbik7CisgICAgICAgIHZhbHVlID0gKFYpdzsKKyAgICAgIH0KKyAgICAgIHRoaXMuaW5zdGFuY2UucHV0KGtleSwgdmFsdWUpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hiYXNlT2JqZWN0V3JpdGFibGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hiYXNlT2JqZWN0V3JpdGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMmEzZDRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSGJhc2VPYmplY3RXcml0YWJsZS5qYXZhCkBAIC0wLDAgKzEsNDE2IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmVkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhNc2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJTZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGJhc2VNYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5NYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5PYmplY3RXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlRmFjdG9yaWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKiAKKyAqIFRoaXMgaXMgYSBjdXN0b21pemVkIHZlcnNpb24gb2YgdGhlIHBvbHltb3JwaGljIGhhZG9vcAorICoge0BsaW5rIE9iamVjdFdyaXRhYmxlfS4gIEl0IHJlbW92ZXMgVVRGOCAoSEFET09QLTQxNCkuCisgKiBVc2luZyB7QGxpbmsgVGV4dH0gaW50ZWFkIG9mIFVURi04IHNhdmVzIH4yJSBDUFUgYmV0d2VlbiByZWFkaW5nIGFuZCB3cml0aW5nCisgKiBvYmplY3RzIHJ1bm5pbmcgYSBzaG9ydCBzZXF1ZW50aWFsV3JpdGUgUGVyZm9ybWFuY2UgRXZhbHVhdGlvbiB0ZXN0IGp1c3QgaW4KKyAqIE9iamVjdFdyaXRhYmxlIGFsb25lOyBtb3JlIHdoZW4gd2UncmUgZG9pbmcgcmFuZG9tUmVhZC1pbmcuICBPdGhlcgorICogb3B0aW1pemF0aW9ucyBpbmNsdWRlIG91ciBwYXNzaW5nIGNvZGVzIGZvciBjbGFzc2VzIGluc3RlYWQgb2YgdGhlCisgKiBhY3R1YWwgY2xhc3MgbmFtZXMgdGhlbXNlbHZlcy4gIFRoaXMgbWFrZXMgaXQgc28gdGhpcyBjbGFzcyBuZWVkcyBhbWVuZG1lbnQKKyAqIGlmIG5vbi1Xcml0YWJsZSBjbGFzc2VzIGFyZSBpbnRyb2R1Y2VkIC0tIGlmIHBhc3NlZCBhIFdyaXRhYmxlIGZvciB3aGljaCB3ZQorICogaGF2ZSBubyBjb2RlLCB3ZSBqdXN0IGRvIHRoZSBvbGQtc2Nob29sIHBhc3Npbmcgb2YgdGhlIGNsYXNzIG5hbWUsIGV0Yy4gLS0KKyAqIGJ1dCBwYXNzaW5nIGNvZGVzIHRoZSAgc2F2aW5ncyBhcmUgbGFyZ2UgcGFydGljdWxhcmx5IHdoZW4gY2VsbAorICogZGF0YSBpcyBzbWFsbCAoSWYgPCBhIGNvdXBsZSBvZiBraWxvYnl0ZXMsIHRoZSBlbmNvZGluZy9kZWNvZGluZyBvZiBjbGFzcworICogbmFtZSBhbmQgcmVmbGVjdGlvbiB0byBpbnN0YW50aWF0ZSBjbGFzcyB3YXMgY29zdGluZyBpbiBleGNlc3Mgb2YgdGhlIGNlbGwKKyAqIGhhbmRsaW5nKS4KKyAqLworcHVibGljIGNsYXNzIEhiYXNlT2JqZWN0V3JpdGFibGUgaW1wbGVtZW50cyBXcml0YWJsZSwgQ29uZmlndXJhYmxlIHsKKyAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coSGJhc2VPYmplY3RXcml0YWJsZS5jbGFzcyk7CisgIAorICAvLyBIZXJlIHdlIG1haW50YWluIHR3byBzdGF0aWMgbWFwcyBvZiBjbGFzc2VzIHRvIGNvZGUgYW5kIHZpY2UgdmVyc2EuCisgIC8vIEFkZCBuZXcgY2xhc3Nlcytjb2RlcyBhcyB3YW50ZWQgb3IgZmlndXJlIHdheSB0byBhdXRvLWdlbmVyYXRlIHRoZXNlCisgIC8vIG1hcHMgZnJvbSB0aGUgSE1hc3RlckludGVyZmFjZS4KKyAgc3RhdGljIGZpbmFsIE1hcDxCeXRlLCBDbGFzczw/Pj4gQ09ERV9UT19DTEFTUyA9CisgICAgbmV3IEhhc2hNYXA8Qnl0ZSwgQ2xhc3M8Pz4+KCk7CisgIHN0YXRpYyBmaW5hbCBNYXA8Q2xhc3M8Pz4sIEJ5dGU+IENMQVNTX1RPX0NPREUgPQorICAgIG5ldyBIYXNoTWFwPENsYXNzPD8+LCBCeXRlPigpOworICAvLyBTcGVjaWFsIGNvZGUgdGhhdCBtZWFucyAnbm90LWVuY29kZWQnOyBpbiB0aGlzIGNhc2Ugd2UgZG8gb2xkIHNjaG9vbAorICAvLyBzZW5kaW5nIG9mIHRoZSBjbGFzcyBuYW1lIHVzaW5nIHJlZmxlY3Rpb24sIGV0Yy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBOT1RfRU5DT0RFRCA9IDA7CisgIHN0YXRpYyB7CisgICAgYnl0ZSBjb2RlID0gTk9UX0VOQ09ERUQgKyAxOworICAgIC8vIFByaW1pdGl2ZSB0eXBlcy4KKyAgICBhZGRUb01hcChCb29sZWFuLlRZUEUsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoQnl0ZS5UWVBFLCBjb2RlKyspOworICAgIGFkZFRvTWFwKENoYXJhY3Rlci5UWVBFLCBjb2RlKyspOworICAgIGFkZFRvTWFwKFNob3J0LlRZUEUsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoSW50ZWdlci5UWVBFLCBjb2RlKyspOworICAgIGFkZFRvTWFwKExvbmcuVFlQRSwgY29kZSsrKTsKKyAgICBhZGRUb01hcChGbG9hdC5UWVBFLCBjb2RlKyspOworICAgIGFkZFRvTWFwKERvdWJsZS5UWVBFLCBjb2RlKyspOworICAgIGFkZFRvTWFwKFZvaWQuVFlQRSwgY29kZSsrKTsKKyAgICAvLyBPdGhlciBqYXZhIHR5cGVzCisgICAgYWRkVG9NYXAoU3RyaW5nLmNsYXNzLCBjb2RlKyspOworICAgIGFkZFRvTWFwKGJ5dGUgW10uY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoYnl0ZSBbXVtdLmNsYXNzLCBjb2RlKyspOworICAgIC8vIEhhZG9vcCB0eXBlcworICAgIGFkZFRvTWFwKFRleHQuY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoV3JpdGFibGUuY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoV3JpdGFibGUgW10uY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoSGJhc2VNYXBXcml0YWJsZS5jbGFzcywgY29kZSsrKTsKKyAgICBhZGRUb01hcChOdWxsSW5zdGFuY2UuY2xhc3MsIGNvZGUrKyk7CisgICAgdHJ5IHsKKyAgICAgIGFkZFRvTWFwKENsYXNzLmZvck5hbWUoIltMb3JnLmFwYWNoZS5oYWRvb3AuaW8uVGV4dDsiKSwgY29kZSsrKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorICAgIC8vIEhiYXNlIHR5cGVzCisgICAgYWRkVG9NYXAoSFNlcnZlckluZm8uY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoSE1zZy5jbGFzcywgY29kZSsrKTsKKyAgICBhZGRUb01hcChIVGFibGVEZXNjcmlwdG9yLmNsYXNzLCBjb2RlKyspOworICAgIGFkZFRvTWFwKEhDb2x1bW5EZXNjcmlwdG9yLmNsYXNzLCBjb2RlKyspOworICAgIGFkZFRvTWFwKFJvd0ZpbHRlckludGVyZmFjZS5jbGFzcywgY29kZSsrKTsKKyAgICBhZGRUb01hcChSb3dGaWx0ZXJTZXQuY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoSFJlZ2lvbkluZm8uY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoQmF0Y2hVcGRhdGUuY2xhc3MsIGNvZGUrKyk7CisgICAgYWRkVG9NYXAoSFNlcnZlckFkZHJlc3MuY2xhc3MsIGNvZGUrKyk7CisgICAgdHJ5IHsKKyAgICAgIGFkZFRvTWFwKENsYXNzLmZvck5hbWUoIltMb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZzsiKSwgY29kZSsrKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorICAgIGFkZFRvTWFwKENlbGwuY2xhc3MsIGNvZGUrKyk7CisgICAgdHJ5IHsKKyAgICAgIGFkZFRvTWFwKENsYXNzLmZvck5hbWUoIltMb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsiKSwgY29kZSsrKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorICAgIGFkZFRvTWFwKFJvd1Jlc3VsdC5jbGFzcywgY29kZSsrKTsKKyAgICBhZGRUb01hcChIUmVnaW9uSW5mb1tdLmNsYXNzLCBjb2RlKyspOworICAgIGFkZFRvTWFwKE1hcFdyaXRhYmxlLmNsYXNzLCBjb2RlKyspOworICAgIHRyeSB7CisgICAgICBhZGRUb01hcChDbGFzcy5mb3JOYW1lKCJbTG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsiKSwgY29kZSsrKTsKKyAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorICAgIGFkZFRvTWFwKEJhdGNoVXBkYXRlW10uY2xhc3MsIGNvZGUrKyk7CisgIH0KKyAgCisgIHByaXZhdGUgQ2xhc3M8Pz4gZGVjbGFyZWRDbGFzczsKKyAgcHJpdmF0ZSBPYmplY3QgaW5zdGFuY2U7CisgIHByaXZhdGUgQ29uZmlndXJhdGlvbiBjb25mOworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yIGZvciB3cml0YWJsZSAqLworICBwdWJsaWMgSGJhc2VPYmplY3RXcml0YWJsZSgpIHsKKyAgICBzdXBlcigpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGluc3RhbmNlCisgICAqLworICBwdWJsaWMgSGJhc2VPYmplY3RXcml0YWJsZShPYmplY3QgaW5zdGFuY2UpIHsKKyAgICBzZXQoaW5zdGFuY2UpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBkZWNsYXJlZENsYXNzCisgICAqIEBwYXJhbSBpbnN0YW5jZQorICAgKi8KKyAgcHVibGljIEhiYXNlT2JqZWN0V3JpdGFibGUoQ2xhc3M8Pz4gZGVjbGFyZWRDbGFzcywgT2JqZWN0IGluc3RhbmNlKSB7CisgICAgdGhpcy5kZWNsYXJlZENsYXNzID0gZGVjbGFyZWRDbGFzczsKKyAgICB0aGlzLmluc3RhbmNlID0gaW5zdGFuY2U7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgaW5zdGFuY2UsIG9yIG51bGwgaWYgbm9uZS4gKi8KKyAgcHVibGljIE9iamVjdCBnZXQoKSB7IHJldHVybiBpbnN0YW5jZTsgfQorICAKKyAgLyoqIEByZXR1cm4gdGhlIGNsYXNzIHRoaXMgaXMgbWVhbnQgdG8gYmUuICovCisgIHB1YmxpYyBDbGFzczw/PiBnZXREZWNsYXJlZENsYXNzKCkgeyByZXR1cm4gZGVjbGFyZWRDbGFzczsgfQorICAKKyAgLyoqCisgICAqIFJlc2V0IHRoZSBpbnN0YW5jZS4KKyAgICogQHBhcmFtIGluc3RhbmNlCisgICAqLworICBwdWJsaWMgdm9pZCBzZXQoT2JqZWN0IGluc3RhbmNlKSB7CisgICAgdGhpcy5kZWNsYXJlZENsYXNzID0gaW5zdGFuY2UuZ2V0Q2xhc3MoKTsKKyAgICB0aGlzLmluc3RhbmNlID0gaW5zdGFuY2U7CisgIH0KKworICAvKioKKyAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiT1dbY2xhc3M9IiArIGRlY2xhcmVkQ2xhc3MgKyAiLHZhbHVlPSIgKyBpbnN0YW5jZSArICJdIjsKKyAgfQorCisgIAorICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZWFkT2JqZWN0KGluLCB0aGlzLCB0aGlzLmNvbmYpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZU9iamVjdChvdXQsIGluc3RhbmNlLCBkZWNsYXJlZENsYXNzLCBjb25mKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIE51bGxJbnN0YW5jZSBleHRlbmRzIENvbmZpZ3VyZWQgaW1wbGVtZW50cyBXcml0YWJsZSB7CisgICAgQ2xhc3M8Pz4gZGVjbGFyZWRDbGFzczsKKyAgICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciBmb3Igd3JpdGFibGUgKi8KKyAgICBwdWJsaWMgTnVsbEluc3RhbmNlKCkgeyBzdXBlcihudWxsKTsgfQorICAgIAorICAgIC8qKgorICAgICAqIEBwYXJhbSBkZWNsYXJlZENsYXNzCisgICAgICogQHBhcmFtIGNvbmYKKyAgICAgKi8KKyAgICBwdWJsaWMgTnVsbEluc3RhbmNlKENsYXNzPD8+IGRlY2xhcmVkQ2xhc3MsIENvbmZpZ3VyYXRpb24gY29uZikgeworICAgICAgc3VwZXIoY29uZik7CisgICAgICB0aGlzLmRlY2xhcmVkQ2xhc3MgPSBkZWNsYXJlZENsYXNzOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuZGVjbGFyZWRDbGFzcyA9IENPREVfVE9fQ0xBU1MuZ2V0KGluLnJlYWRCeXRlKCkpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHdyaXRlQ2xhc3NDb2RlKG91dCwgdGhpcy5kZWNsYXJlZENsYXNzKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBXcml0ZSBvdXQgdGhlIGNvZGUgYnl0ZSBmb3IgcGFzc2VkIENsYXNzLgorICAgKiBAcGFyYW0gb3V0CisgICAqIEBwYXJhbSBjCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHN0YXRpYyB2b2lkIHdyaXRlQ2xhc3NDb2RlKGZpbmFsIERhdGFPdXRwdXQgb3V0LCBmaW5hbCBDbGFzczw/PiBjKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGUgY29kZSA9IENMQVNTX1RPX0NPREUuZ2V0KGMpOworICAgIGlmIChjb2RlID09IG51bGwpIHsKKyAgICAgIExPRy5lcnJvcigiVW5zdXBwb3J0ZWQgdHlwZSAiICsgYyk7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vIGNvZGUgZm9yIHVuZXhwZWN0ZWQgIiArIGMpOworICAgIH0KKyAgICBvdXQud3JpdGVCeXRlKGNvZGUpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIGEge0BsaW5rIFdyaXRhYmxlfSwge0BsaW5rIFN0cmluZ30sIHByaW1pdGl2ZSB0eXBlLCBvciBhbiBhcnJheSBvZgorICAgKiB0aGUgcHJlY2VkaW5nLgorICAgKiBAcGFyYW0gb3V0CisgICAqIEBwYXJhbSBpbnN0YW5jZQorICAgKiBAcGFyYW0gZGVjbGFyZWRDbGFzcworICAgKiBAcGFyYW0gY29uZgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlT2JqZWN0KERhdGFPdXRwdXQgb3V0LCBPYmplY3QgaW5zdGFuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBkZWNsYXJlZENsYXNzLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gY29uZikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIE9iamVjdCBpbnN0YW5jZU9iaiA9IGluc3RhbmNlOworICAgIENsYXNzIGRlY2xDbGFzcyA9IGRlY2xhcmVkQ2xhc3M7CisgICAgCisgICAgaWYgKGluc3RhbmNlT2JqID09IG51bGwpIHsgICAgICAgICAgICAgICAgICAgICAgIC8vIG51bGwKKyAgICAgIGluc3RhbmNlT2JqID0gbmV3IE51bGxJbnN0YW5jZShkZWNsQ2xhc3MsIGNvbmYpOworICAgICAgZGVjbENsYXNzID0gV3JpdGFibGUuY2xhc3M7CisgICAgfQorICAgIHdyaXRlQ2xhc3NDb2RlKG91dCwgZGVjbENsYXNzKTsKKyAgICBpZiAoZGVjbENsYXNzLmlzQXJyYXkoKSkgeyAgICAgICAgICAgICAgICAvLyBhcnJheQorICAgICAgLy8gSWYgYnl0ZWFycmF5LCBqdXN0IGR1bXAgaXQgb3V0IC0tIGF2b2lkIHRoZSByZWN1cnNpb24gYW5kCisgICAgICAvLyBieXRlLWF0LWEtdGltZSB3ZSB3ZXJlIHByZXZpb3VzbHkgZG9pbmcuCisgICAgICBpZiAoZGVjbENsYXNzLmVxdWFscyhieXRlIFtdLmNsYXNzKSkgeworICAgICAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIChieXRlIFtdKWluc3RhbmNlT2JqKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGludCBsZW5ndGggPSBBcnJheS5nZXRMZW5ndGgoaW5zdGFuY2VPYmopOworICAgICAgICBvdXQud3JpdGVJbnQobGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgIHdyaXRlT2JqZWN0KG91dCwgQXJyYXkuZ2V0KGluc3RhbmNlT2JqLCBpKSwKKyAgICAgICAgICAgICAgICAgICAgZGVjbENsYXNzLmdldENvbXBvbmVudFR5cGUoKSwgY29uZik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGRlY2xDbGFzcyA9PSBTdHJpbmcuY2xhc3MpIHsgICAvLyBTdHJpbmcKKyAgICAgIFRleHQud3JpdGVTdHJpbmcob3V0LCAoU3RyaW5nKWluc3RhbmNlT2JqKTsKKyAgICB9IGVsc2UgaWYgKGRlY2xDbGFzcy5pc1ByaW1pdGl2ZSgpKSB7ICAgICAvLyBwcmltaXRpdmUgdHlwZQorICAgICAgaWYgKGRlY2xDbGFzcyA9PSBCb29sZWFuLlRZUEUpIHsgICAgICAgIC8vIGJvb2xlYW4KKyAgICAgICAgb3V0LndyaXRlQm9vbGVhbigoKEJvb2xlYW4paW5zdGFuY2VPYmopLmJvb2xlYW5WYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbENsYXNzID09IENoYXJhY3Rlci5UWVBFKSB7IC8vIGNoYXIKKyAgICAgICAgb3V0LndyaXRlQ2hhcigoKENoYXJhY3RlcilpbnN0YW5jZU9iaikuY2hhclZhbHVlKCkpOworICAgICAgfSBlbHNlIGlmIChkZWNsQ2xhc3MgPT0gQnl0ZS5UWVBFKSB7ICAgIC8vIGJ5dGUKKyAgICAgICAgb3V0LndyaXRlQnl0ZSgoKEJ5dGUpaW5zdGFuY2VPYmopLmJ5dGVWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbENsYXNzID09IFNob3J0LlRZUEUpIHsgICAvLyBzaG9ydAorICAgICAgICBvdXQud3JpdGVTaG9ydCgoKFNob3J0KWluc3RhbmNlT2JqKS5zaG9ydFZhbHVlKCkpOworICAgICAgfSBlbHNlIGlmIChkZWNsQ2xhc3MgPT0gSW50ZWdlci5UWVBFKSB7IC8vIGludAorICAgICAgICBvdXQud3JpdGVJbnQoKChJbnRlZ2VyKWluc3RhbmNlT2JqKS5pbnRWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbENsYXNzID09IExvbmcuVFlQRSkgeyAgICAvLyBsb25nCisgICAgICAgIG91dC53cml0ZUxvbmcoKChMb25nKWluc3RhbmNlT2JqKS5sb25nVmFsdWUoKSk7CisgICAgICB9IGVsc2UgaWYgKGRlY2xDbGFzcyA9PSBGbG9hdC5UWVBFKSB7ICAgLy8gZmxvYXQKKyAgICAgICAgb3V0LndyaXRlRmxvYXQoKChGbG9hdClpbnN0YW5jZU9iaikuZmxvYXRWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbENsYXNzID09IERvdWJsZS5UWVBFKSB7ICAvLyBkb3VibGUKKyAgICAgICAgb3V0LndyaXRlRG91YmxlKCgoRG91YmxlKWluc3RhbmNlT2JqKS5kb3VibGVWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbENsYXNzID09IFZvaWQuVFlQRSkgeyAgICAvLyB2b2lkCisgICAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYSBwcmltaXRpdmU6ICIrZGVjbENsYXNzKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGRlY2xDbGFzcy5pc0VudW0oKSkgeyAgICAgICAgIC8vIGVudW0KKyAgICAgIFRleHQud3JpdGVTdHJpbmcob3V0LCAoKEVudW0paW5zdGFuY2VPYmopLm5hbWUoKSk7CisgICAgfSBlbHNlIGlmIChXcml0YWJsZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGRlY2xDbGFzcykpIHsgLy8gV3JpdGFibGUKKyAgICAgIENsYXNzIDw/PiBjID0gaW5zdGFuY2VPYmouZ2V0Q2xhc3MoKTsKKyAgICAgIEJ5dGUgY29kZSA9IENMQVNTX1RPX0NPREUuZ2V0KGMpOworICAgICAgaWYgKGNvZGUgPT0gbnVsbCkgeworICAgICAgICBvdXQud3JpdGVCeXRlKE5PVF9FTkNPREVEKTsKKyAgICAgICAgVGV4dC53cml0ZVN0cmluZyhvdXQsIGMuZ2V0TmFtZSgpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdyaXRlQ2xhc3NDb2RlKG91dCwgYyk7CisgICAgICB9CisgICAgICAoKFdyaXRhYmxlKWluc3RhbmNlT2JqKS53cml0ZShvdXQpOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbid0IHdyaXRlOiAiK2luc3RhbmNlT2JqKyIgYXMgIitkZWNsQ2xhc3MpOworICAgIH0KKyAgfQorICAKKyAgCisgIC8qKgorICAgKiBSZWFkIGEge0BsaW5rIFdyaXRhYmxlfSwge0BsaW5rIFN0cmluZ30sIHByaW1pdGl2ZSB0eXBlLCBvciBhbiBhcnJheSBvZgorICAgKiB0aGUgcHJlY2VkaW5nLgorICAgKiBAcGFyYW0gaW4KKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHJldHVybiB0aGUgb2JqZWN0CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgT2JqZWN0IHJlYWRPYmplY3QoRGF0YUlucHV0IGluLCBDb25maWd1cmF0aW9uIGNvbmYpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZE9iamVjdChpbiwgbnVsbCwgY29uZik7CisgIH0KKyAgICAKKyAgLyoqCisgICAqIFJlYWQgYSB7QGxpbmsgV3JpdGFibGV9LCB7QGxpbmsgU3RyaW5nfSwgcHJpbWl0aXZlIHR5cGUsIG9yIGFuIGFycmF5IG9mCisgICAqIHRoZSBwcmVjZWRpbmcuCisgICAqIEBwYXJhbSBpbgorICAgKiBAcGFyYW0gb2JqZWN0V3JpdGFibGUKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHJldHVybiB0aGUgb2JqZWN0CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgc3RhdGljIE9iamVjdCByZWFkT2JqZWN0KERhdGFJbnB1dCBpbiwKKyAgICAgIEhiYXNlT2JqZWN0V3JpdGFibGUgb2JqZWN0V3JpdGFibGUsIENvbmZpZ3VyYXRpb24gY29uZikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDbGFzczw/PiBkZWNsYXJlZENsYXNzID0gQ09ERV9UT19DTEFTUy5nZXQoaW4ucmVhZEJ5dGUoKSk7CisgICAgT2JqZWN0IGluc3RhbmNlOworICAgIGlmIChkZWNsYXJlZENsYXNzLmlzUHJpbWl0aXZlKCkpIHsgICAgICAgICAgICAvLyBwcmltaXRpdmUgdHlwZXMKKyAgICAgIGlmIChkZWNsYXJlZENsYXNzID09IEJvb2xlYW4uVFlQRSkgeyAgICAgICAgICAgICAvLyBib29sZWFuCisgICAgICAgIGluc3RhbmNlID0gQm9vbGVhbi52YWx1ZU9mKGluLnJlYWRCb29sZWFuKCkpOworICAgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzID09IENoYXJhY3Rlci5UWVBFKSB7ICAgIC8vIGNoYXIKKyAgICAgICAgaW5zdGFuY2UgPSBDaGFyYWN0ZXIudmFsdWVPZihpbi5yZWFkQ2hhcigpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbGFyZWRDbGFzcyA9PSBCeXRlLlRZUEUpIHsgICAgICAgICAvLyBieXRlCisgICAgICAgIGluc3RhbmNlID0gQnl0ZS52YWx1ZU9mKGluLnJlYWRCeXRlKCkpOworICAgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzID09IFNob3J0LlRZUEUpIHsgICAgICAgIC8vIHNob3J0CisgICAgICAgIGluc3RhbmNlID0gU2hvcnQudmFsdWVPZihpbi5yZWFkU2hvcnQoKSk7CisgICAgICB9IGVsc2UgaWYgKGRlY2xhcmVkQ2xhc3MgPT0gSW50ZWdlci5UWVBFKSB7ICAgICAgLy8gaW50CisgICAgICAgIGluc3RhbmNlID0gSW50ZWdlci52YWx1ZU9mKGluLnJlYWRJbnQoKSk7CisgICAgICB9IGVsc2UgaWYgKGRlY2xhcmVkQ2xhc3MgPT0gTG9uZy5UWVBFKSB7ICAgICAgICAgLy8gbG9uZworICAgICAgICBpbnN0YW5jZSA9IExvbmcudmFsdWVPZihpbi5yZWFkTG9uZygpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGVjbGFyZWRDbGFzcyA9PSBGbG9hdC5UWVBFKSB7ICAgICAgICAvLyBmbG9hdAorICAgICAgICBpbnN0YW5jZSA9IEZsb2F0LnZhbHVlT2YoaW4ucmVhZEZsb2F0KCkpOworICAgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzID09IERvdWJsZS5UWVBFKSB7ICAgICAgIC8vIGRvdWJsZQorICAgICAgICBpbnN0YW5jZSA9IERvdWJsZS52YWx1ZU9mKGluLnJlYWREb3VibGUoKSk7CisgICAgICB9IGVsc2UgaWYgKGRlY2xhcmVkQ2xhc3MgPT0gVm9pZC5UWVBFKSB7ICAgICAgICAgLy8gdm9pZAorICAgICAgICBpbnN0YW5jZSA9IG51bGw7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYSBwcmltaXRpdmU6ICIrZGVjbGFyZWRDbGFzcyk7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzLmlzQXJyYXkoKSkgeyAgICAgICAgICAgICAgLy8gYXJyYXkKKyAgICAgIGlmIChkZWNsYXJlZENsYXNzLmVxdWFscyhieXRlIFtdLmNsYXNzKSkgeworICAgICAgICBpbnN0YW5jZSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaW50IGxlbmd0aCA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaW5zdGFuY2UgPSBBcnJheS5uZXdJbnN0YW5jZShkZWNsYXJlZENsYXNzLmdldENvbXBvbmVudFR5cGUoKSwgbGVuZ3RoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgICAgIEFycmF5LnNldChpbnN0YW5jZSwgaSwgcmVhZE9iamVjdChpbiwgY29uZikpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzID09IFN0cmluZy5jbGFzcykgeyAgICAgICAgLy8gU3RyaW5nCisgICAgICBpbnN0YW5jZSA9IFRleHQucmVhZFN0cmluZyhpbik7CisgICAgfSBlbHNlIGlmIChkZWNsYXJlZENsYXNzLmlzRW51bSgpKSB7ICAgICAgICAgLy8gZW51bQorICAgICAgaW5zdGFuY2UgPSBFbnVtLnZhbHVlT2YoKENsYXNzPD8gZXh0ZW5kcyBFbnVtPikgZGVjbGFyZWRDbGFzcywKKyAgICAgICAgVGV4dC5yZWFkU3RyaW5nKGluKSk7CisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdyaXRhYmxlCisgICAgICBDbGFzcyBpbnN0YW5jZUNsYXNzID0gbnVsbDsKKyAgICAgIEJ5dGUgYiA9IGluLnJlYWRCeXRlKCk7CisgICAgICBpZiAoYi5ieXRlVmFsdWUoKSA9PSBOT1RfRU5DT0RFRCkgeworICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gVGV4dC5yZWFkU3RyaW5nKGluKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBpbnN0YW5jZUNsYXNzID0gY29uZi5nZXRDbGFzc0J5TmFtZShjbGFzc05hbWUpOworICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQ2FuJ3QgZmluZCBjbGFzcyAiICsgY2xhc3NOYW1lKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaW5zdGFuY2VDbGFzcyA9IENPREVfVE9fQ0xBU1MuZ2V0KGIpOworICAgICAgfQorICAgICAgV3JpdGFibGUgd3JpdGFibGUgPSBXcml0YWJsZUZhY3Rvcmllcy5uZXdJbnN0YW5jZShpbnN0YW5jZUNsYXNzLCBjb25mKTsKKyAgICAgIHdyaXRhYmxlLnJlYWRGaWVsZHMoaW4pOworICAgICAgaW5zdGFuY2UgPSB3cml0YWJsZTsKKyAgICAgIGlmIChpbnN0YW5jZUNsYXNzID09IE51bGxJbnN0YW5jZS5jbGFzcykgeyAgLy8gbnVsbAorICAgICAgICBkZWNsYXJlZENsYXNzID0gKChOdWxsSW5zdGFuY2UpaW5zdGFuY2UpLmRlY2xhcmVkQ2xhc3M7CisgICAgICAgIGluc3RhbmNlID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKG9iamVjdFdyaXRhYmxlICE9IG51bGwpIHsgICAgICAgICAgICAgICAgIC8vIHN0b3JlIHZhbHVlcworICAgICAgb2JqZWN0V3JpdGFibGUuZGVjbGFyZWRDbGFzcyA9IGRlY2xhcmVkQ2xhc3M7CisgICAgICBvYmplY3RXcml0YWJsZS5pbnN0YW5jZSA9IGluc3RhbmNlOworICAgIH0KKyAgICByZXR1cm4gaW5zdGFuY2U7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGFkZFRvTWFwKGZpbmFsIENsYXNzPD8+IGNsYXp6LCBmaW5hbCBieXRlIGNvZGUpIHsKKyAgICBDTEFTU19UT19DT0RFLnB1dChjbGF6eiwgY29kZSk7CisgICAgQ09ERV9UT19DTEFTUy5wdXQoY29kZSwgY2xhenopOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Q29uZihDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICB0aGlzLmNvbmYgPSBjb25mOworICB9CisKKyAgcHVibGljIENvbmZpZ3VyYXRpb24gZ2V0Q29uZigpIHsKKyAgICByZXR1cm4gdGhpcy5jb25mOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSGVhcFNpemUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hlYXBTaXplLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTM4NThlOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL0hlYXBTaXplLmphdmEKQEAgLTAsMCArMSw2NSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCisvKioKKyAqIEltcGxlbWVudGF0aW9ucyBjYW4gYmUgYXNrZWQgZm9yIGFuIGVzdGltYXRlIG9mIHRoZWlyIHNpemUgaW4gYnl0ZXMuCisgKiBVc2VmdWwgZm9yIHNpemluZyBjYWNoZXMuICBJdHMgYSBnaXZlbiB0aGF0IGltcGxlbWVudGF0aW9uIGFwcHJveGltYXRpb25zCisgKiBwcm9iYWJseSBkbyBub3QgYWNjb3VudCBmb3IgMzIgdnMgNjQgYml0IG5vciBmb3IgZGlmZmVyZW50IFZNIGltcGxlbWVuYXRpb25zLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEhlYXBTaXplIHsKKyAgCisgIC8qKiBSZWZlcmVuY2Ugc2l6ZSBpcyA4IGJ5dGVzIG9uIDY0LWJpdCwgNCBieXRlcyBvbiAzMi1iaXQgKi8KKyAgc3RhdGljIGZpbmFsIGludCBSRUZFUkVOQ0UgPSA4OworICAKKyAgLyoqIE9iamVjdCBvdmVyaGVhZCBpcyBtaW5pbXVtIDIgKiByZWZlcmVuY2Ugc2l6ZSAoOCBieXRlcyBvbiA2NC1iaXQpICovCisgIHN0YXRpYyBmaW5hbCBpbnQgT0JKRUNUID0gMiAqIFJFRkVSRU5DRTsKKyAgCisgIC8qKgorICAgKiBUaGUgZm9sbG93aW5nIHR5cGVzIGFyZSBhbHdheXMgYWxsb2NhdGVkIGluIGJsb2NrcyBvZiA4IGJ5dGVzIChvbiA2NGJpdCkKKyAgICogRm9yIGV4YW1wbGUsIGlmIHlvdSBoYXZlIHR3byBpbnRzIGluIGEgY2xhc3MsIGl0IHdpbGwgdXNlIDggYnl0ZXMuCisgICAqIElmIHlvdSBoYXZlIHRocmVlIGludHMgaW4gYSBjbGFzcywgaXQgd2lsbCB1c2UgMTYgYnl0ZXMuCisgICAqLworICBzdGF0aWMgZmluYWwgaW50IFNIT1JUID0gNDsKKyAgc3RhdGljIGZpbmFsIGludCBJTlQgPSA0OworICBzdGF0aWMgZmluYWwgaW50IEZMT0FUID0gNDsKKyAgc3RhdGljIGZpbmFsIGludCBCT09MRUFOID0gNDsKKyAgc3RhdGljIGZpbmFsIGludCBDSEFSID0gNDsKKyAgc3RhdGljIGZpbmFsIGludCBCWVRFID0gMTsKKyAgCisgIC8qKiBUaGVzZSB0eXBlcyBhcmUgYWx3YXlzIDggYnl0ZXMgKi8KKyAgc3RhdGljIGZpbmFsIGludCBET1VCTEUgPSA4OworICBzdGF0aWMgZmluYWwgaW50IExPTkcgPSA4OworICAKKyAgLyoqIEFycmF5IG92ZXJoZWFkICovCisgIHN0YXRpYyBmaW5hbCBpbnQgQllURV9BUlJBWSA9IFJFRkVSRU5DRTsKKyAgc3RhdGljIGZpbmFsIGludCBBUlJBWSA9IDMgKiBSRUZFUkVOQ0U7CisgIHN0YXRpYyBmaW5hbCBpbnQgTVVMVElfQVJSQVkgPSAoNCAqIFJFRkVSRU5DRSkgKyBBUlJBWTsKKyAgCisgIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0tfU0laRV9UQVggPSA4OworCisgIAorICAKKyAgLyoqCisgICAqIEByZXR1cm4gQXBwcm94aW1hdGUgJ2V4Y2x1c2l2ZSBkZWVwIHNpemUnIG9mIGltcGxlbWVudGluZyBvYmplY3QuICBJbmNsdWRlcworICAgKiBjb3VudCBvZiBwYXlsb2FkIGFuZCBob3N0aW5nIG9iamVjdCBzaXppbmdzLgorICAqLworICBwdWJsaWMgbG9uZyBoZWFwU2l6ZSgpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSW1tdXRhYmxlQnl0ZXNXcml0YWJsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vSW1tdXRhYmxlQnl0ZXNXcml0YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2MjM1ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9JbW11dGFibGVCeXRlc1dyaXRhYmxlLmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5CeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmF0b3I7CisKKy8qKiAKKyAqIEEgYnl0ZSBzZXF1ZW5jZSB0aGF0IGlzIHVzYWJsZSBhcyBhIGtleSBvciB2YWx1ZS4gIEJhc2VkIG9uCisgKiB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaW8uQnl0ZXNXcml0YWJsZX0gb25seSB0aGlzIGNsYXNzIGlzIE5PVCByZXNpemFibGUKKyAqIGFuZCBET0VTIE5PVCBkaXN0aW5ndWlzaCBiZXR3ZWVuIHRoZSBzaXplIG9mIHRoZSBzZXFldW5jZSBhbmQgdGhlIGN1cnJlbnQKKyAqIGNhcGFjaXR5IGFzIHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5pby5CeXRlc1dyaXRhYmxlfSBkb2VzLiBIZW5jZSBpdHMKKyAqIGNvbXBhcmF0aXZlbHkgJ2ltbXV0YWJsZScuIFdoZW4gY3JlYXRpbmcgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcywKKyAqIHRoZSB1bmRlcmx5aW5nIGJ5dGUgW10gaXMgbm90IGNvcGllZCwganVzdCByZWZlcmVuY2VkLiAgVGhlIGJhY2tpbmcKKyAqIGJ1ZmZlciBpcyBhY2Nlc3NlZCB3aGVuIHdlIGdvIHRvIHNlcmlhbGl6ZS4KKyAqLworcHVibGljIGNsYXNzIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUKK2ltcGxlbWVudHMgV3JpdGFibGVDb21wYXJhYmxlPEltbXV0YWJsZUJ5dGVzV3JpdGFibGU+IHsKKyAgcHJpdmF0ZSBieXRlW10gYnl0ZXM7CisgIHByaXZhdGUgaW50IG9mZnNldDsKKyAgcHJpdmF0ZSBpbnQgbGVuZ3RoOworICAKKyAgLyoqCisgICAqIENyZWF0ZSBhIHplcm8tc2l6ZSBzZXF1ZW5jZS4KKyAgICovCisgIHB1YmxpYyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKCkgeworICAgIHN1cGVyKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDcmVhdGUgYSBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHVzaW5nIHRoZSBieXRlIGFycmF5IGFzIHRoZSBpbml0aWFsIHZhbHVlLgorICAgKiBAcGFyYW0gYnl0ZXMgVGhpcyBhcnJheSBiZWNvbWVzIHRoZSBiYWNraW5nIHN0b3JhZ2UgZm9yIHRoZSBvYmplY3QuCisgICAqLworICBwdWJsaWMgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShieXRlW10gYnl0ZXMpIHsKKyAgICB0aGlzKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOworICB9CisgIAorICAvKioKKyAgICogU2V0IHRoZSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSB0byB0aGUgY29udGVudHMgb2YgdGhlIHBhc3NlZAorICAgKiA8Y29kZT5pYnc8L2NvZGU+LgorICAgKiBAcGFyYW0gaWJ3IHRoZSB2YWx1ZSB0byBzZXQgdGhpcyBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHRvLgorICAgKi8KKyAgcHVibGljIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoZmluYWwgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBpYncpIHsKKyAgICB0aGlzKGlidy5nZXQoKSwgMCwgaWJ3LmdldFNpemUoKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTZXQgdGhlIHZhbHVlIHRvIGEgZ2l2ZW4gYnl0ZSByYW5nZQorICAgKiBAcGFyYW0gYnl0ZXMgdGhlIG5ldyBieXRlIHJhbmdlIHRvIHNldCB0bworICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgaW4gbmV3RGF0YSB0byBzdGFydCBhdAorICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIHJhbmdlCisgICAqLworICBwdWJsaWMgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShmaW5hbCBieXRlW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQsCisgICAgICBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgdGhpcy5ieXRlcyA9IGJ5dGVzOworICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OworICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoOworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSBkYXRhIGZyb20gdGhlIEJ5dGVzV3JpdGFibGUuCisgICAqIEByZXR1cm4gVGhlIGRhdGEgaXMgb25seSB2YWxpZCBiZXR3ZWVuIDAgYW5kIGdldFNpemUoKSAtIDEuCisgICAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXQoKSB7CisgICAgaWYgKHRoaXMuYnl0ZXMgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5pbml0aWFsaWl6ZWQuIE51bGwgY29uc3RydWN0b3IgIiArCisgICAgICAgICJjYWxsZWQgdy9vIGFjY29tcGF5aW5nIHJlYWRGaWVsZHMgaW52b2NhdGlvbiIpOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5ieXRlczsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBiIFVzZSBwYXNzZWQgYnl0ZXMgYXMgYmFja2luZyBhcnJheSBmb3IgdGhpcyBpbnN0YW5jZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldChmaW5hbCBieXRlIFtdIGIpIHsKKyAgICBzZXQoYiwgMCwgYi5sZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiIFVzZSBwYXNzZWQgYnl0ZXMgYXMgYmFja2luZyBhcnJheSBmb3IgdGhpcyBpbnN0YW5jZS4KKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqLworICBwdWJsaWMgdm9pZCBzZXQoZmluYWwgYnl0ZSBbXSBiLCBmaW5hbCBpbnQgb2Zmc2V0LCBmaW5hbCBpbnQgbGVuZ3RoKSB7CisgICAgdGhpcy5ieXRlcyA9IGI7CisgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7CisgICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIGJ1ZmZlci4KKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKKyAgICBpZiAodGhpcy5ieXRlcyA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJVbmluaXRpYWxpaXplZC4gTnVsbCBjb25zdHJ1Y3RvciAiICsKKyAgICAgICAgImNhbGxlZCB3L28gYWNjb21wYXlpbmcgcmVhZEZpZWxkcyBpbnZvY2F0aW9uIik7CisgICAgfQorICAgIHJldHVybiB0aGlzLmxlbmd0aDsKKyAgfQorIAorICBwdWJsaWMgaW50IGdldExlbmd0aCgpIHsKKyAgICByZXR1cm4gZ2V0U2l6ZSgpOworICB9CisKKyAgcHVibGljIGludCBnZXRPZmZzZXQoKXsKKyAgICByZXR1cm4gdGhpcy5vZmZzZXQ7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKGZpbmFsIERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmxlbmd0aCA9IGluLnJlYWRJbnQoKTsKKyAgICB0aGlzLmJ5dGVzID0gbmV3IGJ5dGVbdGhpcy5sZW5ndGhdOworICAgIGluLnJlYWRGdWxseSh0aGlzLmJ5dGVzLCAwLCB0aGlzLmxlbmd0aCk7CisgICAgdGhpcy5vZmZzZXQgPSAwOworICB9CisgIAorICBwdWJsaWMgdm9pZCB3cml0ZShmaW5hbCBEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGVJbnQodGhpcy5sZW5ndGgpOworICAgIG91dC53cml0ZSh0aGlzLmJ5dGVzLCB0aGlzLm9mZnNldCwgdGhpcy5sZW5ndGgpOworICB9CisgIAorICAvLyBCZWxvdyBtZXRob2RzIGNvcGllZCBmcm9tIEJ5dGVzV3JpdGFibGUKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gV3JpdGFibGVDb21wYXJhdG9yLmhhc2hCeXRlcyhieXRlcywgdGhpcy5sZW5ndGgpOworICB9CisgIAorICAvKioKKyAgICogRGVmaW5lIHRoZSBzb3J0IG9yZGVyIG9mIHRoZSBCeXRlc1dyaXRhYmxlLgorICAgKiBAcGFyYW0gcmlnaHRfb2JqIFRoZSBvdGhlciBieXRlcyB3cml0YWJsZQorICAgKiBAcmV0dXJuIFBvc2l0aXZlIGlmIGxlZnQgaXMgYmlnZ2VyIHRoYW4gcmlnaHQsIDAgaWYgdGhleSBhcmUgZXF1YWwsIGFuZAorICAgKiAgICAgICAgIG5lZ2F0aXZlIGlmIGxlZnQgaXMgc21hbGxlciB0aGFuIHJpZ2h0LgorICAgKi8KKyAgcHVibGljIGludCBjb21wYXJlVG8oSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSByaWdodF9vYmopIHsKKyAgICByZXR1cm4gY29tcGFyZVRvKHJpZ2h0X29iai5nZXQoKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21wYXJlcyB0aGUgYnl0ZXMgaW4gdGhpcyBvYmplY3QgdG8gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5CisgICAqIEBwYXJhbSB0aGF0CisgICAqIEByZXR1cm4gUG9zaXRpdmUgaWYgbGVmdCBpcyBiaWdnZXIgdGhhbiByaWdodCwgMCBpZiB0aGV5IGFyZSBlcXVhbCwgYW5kCisgICAqICAgICAgICAgbmVnYXRpdmUgaWYgbGVmdCBpcyBzbWFsbGVyIHRoYW4gcmlnaHQuCisgICAqLworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhmaW5hbCBieXRlIFtdIHRoYXQpIHsKKyAgICBpbnQgZGlmZiA9IHRoaXMubGVuZ3RoIC0gdGhhdC5sZW5ndGg7CisgICAgcmV0dXJuIChkaWZmICE9IDApPworICAgICAgZGlmZjoKKyAgICAgIFdyaXRhYmxlQ29tcGFyYXRvci5jb21wYXJlQnl0ZXModGhpcy5ieXRlcywgMCwgdGhpcy5sZW5ndGgsIHRoYXQsCisgICAgICAgIDAsIHRoYXQubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCByaWdodF9vYmopIHsKKyAgICBpZiAocmlnaHRfb2JqIGluc3RhbmNlb2YgYnl0ZSBbXSkgeworICAgICAgcmV0dXJuIGNvbXBhcmVUbygoYnl0ZSBbXSlyaWdodF9vYmopID09IDA7CisgICAgfQorICAgIGlmIChyaWdodF9vYmogaW5zdGFuY2VvZiBJbW11dGFibGVCeXRlc1dyaXRhYmxlKSB7CisgICAgICByZXR1cm4gY29tcGFyZVRvKChJbW11dGFibGVCeXRlc1dyaXRhYmxlKXJpZ2h0X29iaikgPT0gMDsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgCisgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigzKnRoaXMuYnl0ZXMubGVuZ3RoKTsKKyAgICBmb3IgKGludCBpZHggPSAwOyBpZHggPCB0aGlzLmJ5dGVzLmxlbmd0aDsgaWR4KyspIHsKKyAgICAgIC8vIGlmIG5vdCB0aGUgZmlyc3QsIHB1dCBhIGJsYW5rIHNlcGFyYXRvciBpbgorICAgICAgaWYgKGlkeCAhPSAwKSB7CisgICAgICAgIHNiLmFwcGVuZCgnICcpOworICAgICAgfQorICAgICAgU3RyaW5nIG51bSA9IEludGVnZXIudG9IZXhTdHJpbmcoYnl0ZXNbaWR4XSk7CisgICAgICAvLyBpZiBpdCBpcyBvbmx5IG9uZSBkaWdpdCwgYWRkIGEgbGVhZGluZyAwLgorICAgICAgaWYgKG51bS5sZW5ndGgoKSA8IDIpIHsKKyAgICAgICAgc2IuYXBwZW5kKCcwJyk7CisgICAgICB9CisgICAgICBzYi5hcHBlbmQobnVtKTsKKyAgICB9CisgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgIH0KKworICAvKiogQSBDb21wYXJhdG9yIG9wdGltaXplZCBmb3IgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZS4KKyAgICovIAorICBwdWJsaWMgc3RhdGljIGNsYXNzIENvbXBhcmF0b3IgZXh0ZW5kcyBXcml0YWJsZUNvbXBhcmF0b3IgeworICAgIHByaXZhdGUgQnl0ZXNXcml0YWJsZS5Db21wYXJhdG9yIGNvbXBhcmF0b3IgPQorICAgICAgbmV3IEJ5dGVzV3JpdGFibGUuQ29tcGFyYXRvcigpOworCisgICAgLyoqIGNvbnN0cnVjdG9yICovCisgICAgcHVibGljIENvbXBhcmF0b3IoKSB7CisgICAgICBzdXBlcihJbW11dGFibGVCeXRlc1dyaXRhYmxlLmNsYXNzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYXRvciNjb21wYXJlKGJ5dGVbXSwgaW50LCBpbnQsIGJ5dGVbXSwgaW50LCBpbnQpCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBjb21wYXJlKGJ5dGVbXSBiMSwgaW50IHMxLCBpbnQgbDEsIGJ5dGVbXSBiMiwgaW50IHMyLCBpbnQgbDIpIHsKKyAgICAgIHJldHVybiBjb21wYXJhdG9yLmNvbXBhcmUoYjEsIHMxLCBsMSwgYjIsIHMyLCBsMik7CisgICAgfQorICB9CisgIAorICBzdGF0aWMgeyAvLyByZWdpc3RlciB0aGlzIGNvbXBhcmF0b3IKKyAgICBXcml0YWJsZUNvbXBhcmF0b3IuZGVmaW5lKEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MsIG5ldyBDb21wYXJhdG9yKCkpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGFycmF5IExpc3Qgb2YgYnl0ZSBbXS4KKyAgICogQHJldHVybiBBcnJheSBvZiBieXRlIFtdLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdW10gdG9BcnJheShmaW5hbCBMaXN0PGJ5dGUgW10+IGFycmF5KSB7CisgICAgLy8gTGlzdCN0b0FycmF5IGRvZXNuJ3Qgd29yayBvbiBsaXN0cyBvZiBieXRlIFtdLgorICAgIGJ5dGVbXVtdIHJlc3VsdHMgPSBuZXcgYnl0ZVthcnJheS5zaXplKCldW107CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5zaXplKCk7IGkrKykgeworICAgICAgcmVzdWx0c1tpXSA9IGFycmF5LmdldChpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL01hcEZpbGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL01hcEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmM3NTJkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vTWFwRmlsZS5qYXZhCkBAIC0wLDAgKzEsNzgxIEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uKjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLio7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi4qOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJvZ3Jlc3NhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUmVmbGVjdGlvblV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlNlcXVlbmNlRmlsZS5Db21wcmVzc2lvblR5cGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uRGF0YUlucHV0QnVmZmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLkxvbmdXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkNvbXByZXNzaW9uQ29kZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuRGVmYXVsdENvZGVjOworCisvKiogQSBmaWxlLWJhc2VkIG1hcCBmcm9tIGtleXMgdG8gdmFsdWVzLgorICoKKyAqIDxwPlRoaXMgaXMgY29weSBvZiBIYWRvb3AgU2VxdWVuY2VGaWxlIGJyb3VnaHQgbG9jYWwgc28gd2UgY2FuIGZpeCBidWdzOworICogZS5nLiBoYmFzZS0xMDk3PC9wPgorICogCisgKiA8cD5BIG1hcCBpcyBhIGRpcmVjdG9yeSBjb250YWluaW5nIHR3byBmaWxlcywgdGhlIDxjb2RlPmRhdGE8L2NvZGU+IGZpbGUsCisgKiBjb250YWluaW5nIGFsbCBrZXlzIGFuZCB2YWx1ZXMgaW4gdGhlIG1hcCwgYW5kIGEgc21hbGxlciA8Y29kZT5pbmRleDwvY29kZT4KKyAqIGZpbGUsIGNvbnRhaW5pbmcgYSBmcmFjdGlvbiBvZiB0aGUga2V5cy4gIFRoZSBmcmFjdGlvbiBpcyBkZXRlcm1pbmVkIGJ5CisgKiB7QGxpbmsgV3JpdGVyI2dldEluZGV4SW50ZXJ2YWwoKX0uCisgKgorICogPHA+VGhlIGluZGV4IGZpbGUgaXMgcmVhZCBlbnRpcmVseSBpbnRvIG1lbW9yeS4gIFRodXMga2V5IGltcGxlbWVudGF0aW9ucworICogc2hvdWxkIHRyeSB0byBrZWVwIHRoZW1zZWx2ZXMgc21hbGwuCisgKgorICogPHA+TWFwIGZpbGVzIGFyZSBjcmVhdGVkIGJ5IGFkZGluZyBlbnRyaWVzIGluLW9yZGVyLiAgVG8gbWFpbnRhaW4gYSBsYXJnZQorICogZGF0YWJhc2UsIHBlcmZvcm0gdXBkYXRlcyBieSBjb3B5aW5nIHRoZSBwcmV2aW91cyB2ZXJzaW9uIG9mIGEgZGF0YWJhc2UgYW5kCisgKiBtZXJnaW5nIGluIGEgc29ydGVkIGNoYW5nZSBsaXN0LCB0byBjcmVhdGUgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZGF0YWJhc2UgaW4KKyAqIGEgbmV3IGZpbGUuICBTb3J0aW5nIGxhcmdlIGNoYW5nZSBsaXN0cyBjYW4gYmUgZG9uZSB3aXRoIHtAbGluaworICogU2VxdWVuY2VGaWxlLlNvcnRlcn0uCisgKi8KK3B1YmxpYyBjbGFzcyBNYXBGaWxlIHsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWFwRmlsZS5jbGFzcyk7CisKKyAgLyoqIFRoZSBuYW1lIG9mIHRoZSBpbmRleCBmaWxlLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBJTkRFWF9GSUxFX05BTUUgPSAiaW5kZXgiOworCisgIC8qKiBUaGUgbmFtZSBvZiB0aGUgZGF0YSBmaWxlLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBEQVRBX0ZJTEVfTkFNRSA9ICJkYXRhIjsKKworICBwcm90ZWN0ZWQgTWFwRmlsZSgpIHt9ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBwdWJsaWMgY3RvcgorCisgIC8qKiBXcml0ZXMgYSBuZXcgbWFwLiAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFdyaXRlciBpbXBsZW1lbnRzIGphdmEuaW8uQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIFNlcXVlbmNlRmlsZS5Xcml0ZXIgZGF0YTsKKyAgICBwcml2YXRlIFNlcXVlbmNlRmlsZS5Xcml0ZXIgaW5kZXg7CisKKyAgICBmaW5hbCBwcml2YXRlIHN0YXRpYyBTdHJpbmcgSU5ERVhfSU5URVJWQUwgPSAiaW8ubWFwLmluZGV4LmludGVydmFsIjsKKyAgICBwcml2YXRlIGludCBpbmRleEludGVydmFsID0gMTI4OworCisgICAgcHJpdmF0ZSBsb25nIHNpemU7CisgICAgcHJpdmF0ZSBMb25nV3JpdGFibGUgcG9zaXRpb24gPSBuZXcgTG9uZ1dyaXRhYmxlKCk7CisKKyAgICAvLyB0aGUgZm9sbG93aW5nIGZpZWxkcyBhcmUgdXNlZCBvbmx5IGZvciBjaGVja2luZyBrZXkgb3JkZXIKKyAgICBwcml2YXRlIFdyaXRhYmxlQ29tcGFyYXRvciBjb21wYXJhdG9yOworICAgIHByaXZhdGUgRGF0YUlucHV0QnVmZmVyIGluQnVmID0gbmV3IERhdGFJbnB1dEJ1ZmZlcigpOworICAgIHByaXZhdGUgRGF0YU91dHB1dEJ1ZmZlciBvdXRCdWYgPSBuZXcgRGF0YU91dHB1dEJ1ZmZlcigpOworICAgIHByaXZhdGUgV3JpdGFibGVDb21wYXJhYmxlIGxhc3RLZXk7CisKKworICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIG1hcCBmb3Iga2V5cyBvZiB0aGUgbmFtZWQgY2xhc3MuIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gZGlyTmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsCisgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGVDb21wYXJhYmxlPiBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhjb25mLCBmcywgZGlyTmFtZSwKKyAgICAgICAgICAgV3JpdGFibGVDb21wYXJhdG9yLmdldChrZXlDbGFzcyksIHZhbENsYXNzLAorICAgICAgICAgICBTZXF1ZW5jZUZpbGUuZ2V0Q29tcHJlc3Npb25UeXBlKGNvbmYpKTsKKyAgICB9CisKKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBtYXAgZm9yIGtleXMgb2YgdGhlIG5hbWVkIGNsYXNzLiAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGtleUNsYXNzIAorICAgICAqIEBwYXJhbSB2YWxDbGFzcyAKKyAgICAgKiBAcGFyYW0gY29tcHJlc3MgCisgICAgICogQHBhcmFtIHByb2dyZXNzIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsCisgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGVDb21wYXJhYmxlPiBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MsCisgICAgICAgICAgICAgICAgICBDb21wcmVzc2lvblR5cGUgY29tcHJlc3MsIFByb2dyZXNzYWJsZSBwcm9ncmVzcykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGNvbmYsIGZzLCBkaXJOYW1lLCBXcml0YWJsZUNvbXBhcmF0b3IuZ2V0KGtleUNsYXNzKSwgdmFsQ2xhc3MsCisgICAgICAgICAgIGNvbXByZXNzLCBwcm9ncmVzcyk7CisgICAgfQorCisgICAgLyoqIENyZWF0ZSB0aGUgbmFtZWQgbWFwIGZvciBrZXlzIG9mIHRoZSBuYW1lZCBjbGFzcy4gKi8KKyAgICBwdWJsaWMgV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsCisgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGVDb21wYXJhYmxlPiBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MsCisgICAgICAgICAgICAgICAgICBDb21wcmVzc2lvblR5cGUgY29tcHJlc3MsIENvbXByZXNzaW9uQ29kZWMgY29kZWMsCisgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhjb25mLCBmcywgZGlyTmFtZSwgV3JpdGFibGVDb21wYXJhdG9yLmdldChrZXlDbGFzcyksIHZhbENsYXNzLAorICAgICAgICAgICBjb21wcmVzcywgY29kZWMsIHByb2dyZXNzKTsKKyAgICB9CisKKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBtYXAgZm9yIGtleXMgb2YgdGhlIG5hbWVkIGNsYXNzLiAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGtleUNsYXNzIAorICAgICAqIEBwYXJhbSB2YWxDbGFzcyAKKyAgICAgKiBAcGFyYW0gY29tcHJlc3MgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBTdHJpbmcgZGlyTmFtZSwKKyAgICAgICAgICAgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZUNvbXBhcmFibGU+IGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgIENvbXByZXNzaW9uVHlwZSBjb21wcmVzcykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGNvbmYsIGZzLCBkaXJOYW1lLCBXcml0YWJsZUNvbXBhcmF0b3IuZ2V0KGtleUNsYXNzKSwgdmFsQ2xhc3MsIGNvbXByZXNzKTsKKyAgICB9CisKKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBtYXAgdXNpbmcgdGhlIG5hbWVkIGtleSBjb21wYXJhdG9yLiAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsCisgICAgICAgICAgICAgICAgICBXcml0YWJsZUNvbXBhcmF0b3IgY29tcGFyYXRvciwgQ2xhc3MgdmFsQ2xhc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhjb25mLCBmcywgZGlyTmFtZSwgY29tcGFyYXRvciwgdmFsQ2xhc3MsCisgICAgICAgICAgIFNlcXVlbmNlRmlsZS5nZXRDb21wcmVzc2lvblR5cGUoY29uZikpOworICAgIH0KKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBtYXAgdXNpbmcgdGhlIG5hbWVkIGtleSBjb21wYXJhdG9yLiAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb21wcmVzcyAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFdyaXRlcihDb25maWd1cmF0aW9uIGNvbmYsIEZpbGVTeXN0ZW0gZnMsIFN0cmluZyBkaXJOYW1lLAorICAgICAgICAgICAgICAgICAgV3JpdGFibGVDb21wYXJhdG9yIGNvbXBhcmF0b3IsIENsYXNzIHZhbENsYXNzLAorICAgICAgICAgICAgICAgICAgU2VxdWVuY2VGaWxlLkNvbXByZXNzaW9uVHlwZSBjb21wcmVzcykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGNvbmYsIGZzLCBkaXJOYW1lLCBjb21wYXJhdG9yLCB2YWxDbGFzcywgY29tcHJlc3MsIG51bGwpOworICAgIH0KKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBtYXAgdXNpbmcgdGhlIG5hbWVkIGtleSBjb21wYXJhdG9yLiAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb21wcmVzcyAKKyAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBTdHJpbmcgZGlyTmFtZSwKKyAgICAgICAgICAgICAgICAgIFdyaXRhYmxlQ29tcGFyYXRvciBjb21wYXJhdG9yLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgIFNlcXVlbmNlRmlsZS5Db21wcmVzc2lvblR5cGUgY29tcHJlc3MsCisgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhjb25mLCBmcywgZGlyTmFtZSwgY29tcGFyYXRvciwgdmFsQ2xhc3MsIAorICAgICAgICAgICBjb21wcmVzcywgbmV3IERlZmF1bHRDb2RlYygpLCBwcm9ncmVzcyk7CisgICAgfQorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIG1hcCB1c2luZyB0aGUgbmFtZWQga2V5IGNvbXBhcmF0b3IuIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gZGlyTmFtZSAKKyAgICAgKiBAcGFyYW0gY29tcGFyYXRvciAKKyAgICAgKiBAcGFyYW0gdmFsQ2xhc3MgCisgICAgICogQHBhcmFtIGNvbXByZXNzIAorICAgICAqIEBwYXJhbSBjb2RlYyAKKyAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBTdHJpbmcgZGlyTmFtZSwKKyAgICAgICAgICAgICAgICAgIFdyaXRhYmxlQ29tcGFyYXRvciBjb21wYXJhdG9yLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgIFNlcXVlbmNlRmlsZS5Db21wcmVzc2lvblR5cGUgY29tcHJlc3MsIENvbXByZXNzaW9uQ29kZWMgY29kZWMsCisgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICB0aGlzLmluZGV4SW50ZXJ2YWwgPSBjb25mLmdldEludChJTkRFWF9JTlRFUlZBTCwgdGhpcy5pbmRleEludGVydmFsKTsKKworICAgICAgdGhpcy5jb21wYXJhdG9yID0gY29tcGFyYXRvcjsKKyAgICAgIHRoaXMubGFzdEtleSA9IGNvbXBhcmF0b3IubmV3S2V5KCk7CisKKyAgICAgIFBhdGggZGlyID0gbmV3IFBhdGgoZGlyTmFtZSk7CisgICAgICBpZiAoIWZzLm1rZGlycyhkaXIpKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTWtkaXJzIGZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICIgKyBkaXIudG9TdHJpbmcoKSk7CisgICAgICB9CisgICAgICBQYXRoIGRhdGFGaWxlID0gbmV3IFBhdGgoZGlyLCBEQVRBX0ZJTEVfTkFNRSk7CisgICAgICBQYXRoIGluZGV4RmlsZSA9IG5ldyBQYXRoKGRpciwgSU5ERVhfRklMRV9OQU1FKTsKKworICAgICAgQ2xhc3Mga2V5Q2xhc3MgPSBjb21wYXJhdG9yLmdldEtleUNsYXNzKCk7CisgICAgICB0aGlzLmRhdGEgPQorICAgICAgICBTZXF1ZW5jZUZpbGUuY3JlYXRlV3JpdGVyCisgICAgICAgIChmcywgY29uZiwgZGF0YUZpbGUsIGtleUNsYXNzLCB2YWxDbGFzcywgY29tcHJlc3MsIGNvZGVjLCBwcm9ncmVzcyk7CisgICAgICB0aGlzLmluZGV4ID0KKyAgICAgICAgU2VxdWVuY2VGaWxlLmNyZWF0ZVdyaXRlcgorICAgICAgICAoZnMsIGNvbmYsIGluZGV4RmlsZSwga2V5Q2xhc3MsIExvbmdXcml0YWJsZS5jbGFzcywKKyAgICAgICAgICAgIENvbXByZXNzaW9uVHlwZS5CTE9DSywgcHJvZ3Jlc3MpOworICAgIH0KKyAgICAKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVXcml0ZXIjZ2V0SW5kZXhJbnRlcnZhbCgpCisgICAgICovCisgICAgcHVibGljIGludCBnZXRJbmRleEludGVydmFsKCkgeyByZXR1cm4gaW5kZXhJbnRlcnZhbDsgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uU3RvcmVGaWxlV3JpdGVyI3NldEluZGV4SW50ZXJ2YWwoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEluZGV4SW50ZXJ2YWwoaW50IGludGVydmFsKSB7IGluZGV4SW50ZXJ2YWwgPSBpbnRlcnZhbDsgfQorCisgICAgLyoqIFNldHMgdGhlIGluZGV4IGludGVydmFsIGFuZCBzdG9yZXMgaXQgaW4gY29uZgorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBpbnRlcnZhbCAKKyAgICAgKiBAc2VlICNnZXRJbmRleEludGVydmFsKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0SW5kZXhJbnRlcnZhbChDb25maWd1cmF0aW9uIGNvbmYsIGludCBpbnRlcnZhbCkgeworICAgICAgY29uZi5zZXRJbnQoSU5ERVhfSU5URVJWQUwsIGludGVydmFsKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVXcml0ZXIjY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBkYXRhLmNsb3NlKCk7CisgICAgICBpbmRleC5jbG9zZSgpOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlN0b3JlRmlsZVdyaXRlciNhcHBlbmQob3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlLCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXBwZW5kKFdyaXRhYmxlQ29tcGFyYWJsZSBrZXksIFdyaXRhYmxlIHZhbCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgIGNoZWNrS2V5KGtleSk7CisgICAgICAKKyAgICAgIGlmIChzaXplICUgaW5kZXhJbnRlcnZhbCA9PSAwKSB7ICAgICAgICAgICAgLy8gYWRkIGFuIGluZGV4IGVudHJ5CisgICAgICAgIHBvc2l0aW9uLnNldChkYXRhLmdldExlbmd0aCgpKTsgICAgICAgICAgIC8vIHBvaW50IHRvIGN1cnJlbnQgZW9mCisgICAgICAgIGluZGV4LmFwcGVuZChrZXksIHBvc2l0aW9uKTsKKyAgICAgIH0KKworICAgICAgZGF0YS5hcHBlbmQoa2V5LCB2YWwpOyAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQga2V5L3ZhbHVlIHRvIGRhdGEKKyAgICAgIHNpemUrKzsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2hlY2tLZXkoV3JpdGFibGVDb21wYXJhYmxlIGtleSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIHRoYXQga2V5cyBhcmUgd2VsbC1vcmRlcmVkCisgICAgICBpZiAoc2l6ZSAhPSAwICYmIGNvbXBhcmF0b3IuY29tcGFyZShsYXN0S2V5LCBrZXkpID4gMCkKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJrZXkgb3V0IG9mIG9yZGVyOiAiK2tleSsiIGFmdGVyICIrbGFzdEtleSk7CisgICAgICAgICAgCisgICAgICAvLyB1cGRhdGUgbGFzdEtleSB3aXRoIGEgY29weSBvZiBrZXkgYnkgd3JpdGluZyBhbmQgcmVhZGluZworICAgICAgb3V0QnVmLnJlc2V0KCk7CisgICAgICBrZXkud3JpdGUob3V0QnVmKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdyaXRlIG5ldyBrZXkKKworICAgICAgaW5CdWYucmVzZXQob3V0QnVmLmdldERhdGEoKSwgb3V0QnVmLmdldExlbmd0aCgpKTsKKyAgICAgIGxhc3RLZXkucmVhZEZpZWxkcyhpbkJ1Zik7ICAgICAgICAgICAgICAgICAgLy8gcmVhZCBpbnRvIGxhc3RLZXkKKyAgICB9CisKKyAgfQorICAKKyAgLyoqIFByb3ZpZGUgYWNjZXNzIHRvIGFuIGV4aXN0aW5nIG1hcC4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBSZWFkZXIgaW1wbGVtZW50cyBqYXZhLmlvLkNsb3NlYWJsZSB7CisgICAgICAKKyAgICAvKiogTnVtYmVyIG9mIGluZGV4IGVudHJpZXMgdG8gc2tpcCBiZXR3ZWVuIGVhY2ggZW50cnkuICBaZXJvIGJ5IGRlZmF1bHQuCisgICAgICogU2V0dGluZyB0aGlzIHRvIHZhbHVlcyBsYXJnZXIgdGhhbiB6ZXJvIGNhbiBmYWNpbGl0YXRlIG9wZW5pbmcgbGFyZ2UgbWFwCisgICAgICogZmlsZXMgdXNpbmcgbGVzcyBtZW1vcnkuICovCisgICAgcHJpdmF0ZSBpbnQgSU5ERVhfU0tJUCA9IDA7CisgICAgICAKKyAgICBwcml2YXRlIFdyaXRhYmxlQ29tcGFyYXRvciBjb21wYXJhdG9yOworCisgICAgcHJpdmF0ZSBXcml0YWJsZUNvbXBhcmFibGUgbmV4dEtleTsKKyAgICBwcml2YXRlIGxvbmcgc2Vla1Bvc2l0aW9uID0gLTE7CisgICAgcHJpdmF0ZSBpbnQgc2Vla0luZGV4ID0gLTE7CisgICAgcHJpdmF0ZSBsb25nIGZpcnN0UG9zaXRpb247CisKKyAgICAvLyB0aGUgZGF0YSwgb24gZGlzaworICAgIHByaXZhdGUgU2VxdWVuY2VGaWxlLlJlYWRlciBkYXRhOworICAgIHByaXZhdGUgU2VxdWVuY2VGaWxlLlJlYWRlciBpbmRleDsKKworICAgIC8vIHdoZXRoZXIgdGhlIGluZGV4IFJlYWRlciB3YXMgY2xvc2VkCisgICAgcHJpdmF0ZSBib29sZWFuIGluZGV4Q2xvc2VkID0gZmFsc2U7CisKKyAgICAvLyB0aGUgaW5kZXgsIGluIG1lbW9yeQorICAgIHByaXZhdGUgaW50IGNvdW50ID0gLTE7CisgICAgcHJpdmF0ZSBXcml0YWJsZUNvbXBhcmFibGVbXSBrZXlzOworICAgIHByaXZhdGUgbG9uZ1tdIHBvc2l0aW9uczsKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlN0b3JlRmlsZVJlYWRlciNnZXRLZXlDbGFzcygpCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldEtleUNsYXNzKCkgeyByZXR1cm4gZGF0YS5nZXRLZXlDbGFzcygpOyB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVSZWFkZXIjZ2V0VmFsdWVDbGFzcygpCisgICAgICovCisgICAgcHVibGljIENsYXNzPD8+IGdldFZhbHVlQ2xhc3MoKSB7IHJldHVybiBkYXRhLmdldFZhbHVlQ2xhc3MoKTsgfQorCisgICAgLyoqIENvbnN0cnVjdCBhIG1hcCByZWFkZXIgZm9yIHRoZSBuYW1lZCBtYXAuCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBkaXJOYW1lIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyKEZpbGVTeXN0ZW0gZnMsIFN0cmluZyBkaXJOYW1lLCBDb25maWd1cmF0aW9uIGNvbmYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGZzLCBkaXJOYW1lLCBudWxsLCBjb25mKTsKKyAgICAgIElOREVYX1NLSVAgPSBjb25mLmdldEludCgiaW8ubWFwLmluZGV4LnNraXAiLCAwKTsKKyAgICB9CisKKyAgICAvKiogQ29uc3RydWN0IGEgbWFwIHJlYWRlciBmb3IgdGhlIG5hbWVkIG1hcCB1c2luZyB0aGUgbmFtZWQgY29tcGFyYXRvci4KKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGRpck5hbWUgCisgICAgICogQHBhcmFtIGNvbXBhcmF0b3IgCisgICAgICogQHBhcmFtIGNvbmYgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSZWFkZXIoRmlsZVN5c3RlbSBmcywgU3RyaW5nIGRpck5hbWUsIFdyaXRhYmxlQ29tcGFyYXRvciBjb21wYXJhdG9yLCBDb25maWd1cmF0aW9uIGNvbmYpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgZGlyTmFtZSwgY29tcGFyYXRvciwgY29uZiwgdHJ1ZSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEhvb2sgdG8gYWxsb3cgc3ViY2xhc3NlcyB0byBkZWZlciBvcGVuaW5nIHN0cmVhbXMgdW50aWwgZnVydGhlcgorICAgICAqIGluaXRpYWxpemF0aW9uIGlzIGNvbXBsZXRlLgorICAgICAqIEBzZWUgI2NyZWF0ZURhdGFGaWxlUmVhZGVyKEZpbGVTeXN0ZW0sIFBhdGgsIENvbmZpZ3VyYXRpb24pCisgICAgICovCisgICAgcHJvdGVjdGVkIFJlYWRlcihGaWxlU3lzdGVtIGZzLCBTdHJpbmcgZGlyTmFtZSwKKyAgICAgICAgV3JpdGFibGVDb21wYXJhdG9yIGNvbXBhcmF0b3IsIENvbmZpZ3VyYXRpb24gY29uZiwgYm9vbGVhbiBvcGVuKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIAorICAgICAgaWYgKG9wZW4pIHsKKyAgICAgICAgb3BlbihmcywgZGlyTmFtZSwgY29tcGFyYXRvciwgY29uZik7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBvcGVuKEZpbGVTeXN0ZW0gZnMsIFN0cmluZyBkaXJOYW1lLAorICAgICAgICBXcml0YWJsZUNvbXBhcmF0b3IgY29tcGFyYXRvciwgQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgUGF0aCBkaXIgPSBuZXcgUGF0aChkaXJOYW1lKTsKKyAgICAgIFBhdGggZGF0YUZpbGUgPSBuZXcgUGF0aChkaXIsIERBVEFfRklMRV9OQU1FKTsKKyAgICAgIFBhdGggaW5kZXhGaWxlID0gbmV3IFBhdGgoZGlyLCBJTkRFWF9GSUxFX05BTUUpOworCisgICAgICAvLyBvcGVuIHRoZSBkYXRhCisgICAgICB0aGlzLmRhdGEgPSBjcmVhdGVEYXRhRmlsZVJlYWRlcihmcywgZGF0YUZpbGUsIGNvbmYpOworICAgICAgdGhpcy5maXJzdFBvc2l0aW9uID0gZGF0YS5nZXRQb3NpdGlvbigpOworCisgICAgICBpZiAoY29tcGFyYXRvciA9PSBudWxsKQorICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBXcml0YWJsZUNvbXBhcmF0b3IuZ2V0KGRhdGEuZ2V0S2V5Q2xhc3MoKS5hc1N1YmNsYXNzKFdyaXRhYmxlQ29tcGFyYWJsZS5jbGFzcykpOworICAgICAgZWxzZQorICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBjb21wYXJhdG9yOworCisgICAgICAvLyBvcGVuIHRoZSBpbmRleAorICAgICAgdGhpcy5pbmRleCA9IG5ldyBTZXF1ZW5jZUZpbGUuUmVhZGVyKGZzLCBpbmRleEZpbGUsIGNvbmYpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHNwZWNpYWxpemUgdGhlIHR5cGUgb2YKKyAgICAgKiB7QGxpbmsgU2VxdWVuY2VGaWxlLlJlYWRlcn0gcmV0dXJuZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIFNlcXVlbmNlRmlsZS5SZWFkZXIgY3JlYXRlRGF0YUZpbGVSZWFkZXIoRmlsZVN5c3RlbSBmcywKKyAgICAgICAgUGF0aCBkYXRhRmlsZSwgQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIG5ldyBTZXF1ZW5jZUZpbGUuUmVhZGVyKGZzLCBkYXRhRmlsZSwgIGNvbmYpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZWFkSW5kZXgoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gcmVhZCB0aGUgaW5kZXggZW50aXJlbHkgaW50byBtZW1vcnkKKyAgICAgIGlmICh0aGlzLmtleXMgIT0gbnVsbCkKKyAgICAgICAgcmV0dXJuOworICAgICAgdGhpcy5jb3VudCA9IDA7CisgICAgICB0aGlzLmtleXMgPSBuZXcgV3JpdGFibGVDb21wYXJhYmxlWzEwMjRdOworICAgICAgdGhpcy5wb3NpdGlvbnMgPSBuZXcgbG9uZ1sxMDI0XTsKKyAgICAgIHRyeSB7CisgICAgICAgIGludCBza2lwID0gSU5ERVhfU0tJUDsKKyAgICAgICAgTG9uZ1dyaXRhYmxlIHBvc2l0aW9uID0gbmV3IExvbmdXcml0YWJsZSgpOworICAgICAgICBXcml0YWJsZUNvbXBhcmFibGUgbGFzdEtleSA9IG51bGw7CisgICAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgICAgV3JpdGFibGVDb21wYXJhYmxlIGsgPSBjb21wYXJhdG9yLm5ld0tleSgpOworCisgICAgICAgICAgaWYgKCFpbmRleC5uZXh0KGssIHBvc2l0aW9uKSkKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgLy8gY2hlY2sgb3JkZXIgdG8gbWFrZSBzdXJlIGNvbXBhcmF0b3IgaXMgY29tcGF0aWJsZQorICAgICAgICAgIGlmIChsYXN0S2V5ICE9IG51bGwgJiYgY29tcGFyYXRvci5jb21wYXJlKGxhc3RLZXksIGspID4gMCkKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigia2V5IG91dCBvZiBvcmRlcjogIitrKyIgYWZ0ZXIgIitsYXN0S2V5KTsKKyAgICAgICAgICBsYXN0S2V5ID0gazsKKyAgICAgICAgICAKKyAgICAgICAgICBpZiAoc2tpcCA+IDApIHsKKyAgICAgICAgICAgIHNraXAtLTsKKyAgICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCB0aGlzIGVudHJ5CisgICAgICAgICAgfQorICAgICAgICAgIHNraXAgPSBJTkRFWF9TS0lQOyAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgc2tpcAorCisgICAgICAgICAgaWYgKGNvdW50ID09IGtleXMubGVuZ3RoKSB7ICAgICAgICAgICAgICAgIC8vIHRpbWUgdG8gZ3JvdyBhcnJheXMKKyAgICAgICAgICAgIGludCBuZXdMZW5ndGggPSAoa2V5cy5sZW5ndGgqMykvMjsKKyAgICAgICAgICAgIFdyaXRhYmxlQ29tcGFyYWJsZVtdIG5ld0tleXMgPSBuZXcgV3JpdGFibGVDb21wYXJhYmxlW25ld0xlbmd0aF07CisgICAgICAgICAgICBsb25nW10gbmV3UG9zaXRpb25zID0gbmV3IGxvbmdbbmV3TGVuZ3RoXTsKKyAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5cywgMCwgbmV3S2V5cywgMCwgY291bnQpOworICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShwb3NpdGlvbnMsIDAsIG5ld1Bvc2l0aW9ucywgMCwgY291bnQpOworICAgICAgICAgICAga2V5cyA9IG5ld0tleXM7CisgICAgICAgICAgICBwb3NpdGlvbnMgPSBuZXdQb3NpdGlvbnM7CisgICAgICAgICAgfQorCisgICAgICAgICAga2V5c1tjb3VudF0gPSBrOworICAgICAgICAgIHBvc2l0aW9uc1tjb3VudF0gPSBwb3NpdGlvbi5nZXQoKTsKKyAgICAgICAgICBjb3VudCsrOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgICBMT0cud2FybigiVW5leHBlY3RlZCBFT0YgcmVhZGluZyAiICsgaW5kZXggKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBhdCBlbnRyeSAjIiArIGNvdW50ICsgIi4gIElnbm9yaW5nLiIpOworICAgICAgfSBmaW5hbGx5IHsKKwlpbmRleENsb3NlZCA9IHRydWU7CisgICAgICAgIGluZGV4LmNsb3NlKCk7CisgICAgICB9CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uU3RvcmVGaWxlUmVhZGVyI3Jlc2V0KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZGF0YS5zZWVrKGZpcnN0UG9zaXRpb24pOworICAgIH0KKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlN0b3JlRmlsZVJlYWRlciNtaWRLZXkoKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGVDb21wYXJhYmxlIG1pZEtleSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgIHJlYWRJbmRleCgpOworICAgICAgaW50IHBvcyA9ICgoY291bnQgLSAxKSAvIDIpOyAgICAgICAgICAgICAgLy8gbWlkZGxlIG9mIHRoZSBpbmRleAorICAgICAgaWYgKHBvcyA8IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNYXBGaWxlIGVtcHR5Iik7CisgICAgICB9CisgICAgICAKKyAgICAgIHJldHVybiBrZXlzW3Bvc107CisgICAgfQorICAgIAorICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlN0b3JlRmlsZVJlYWRlciNmaW5hbEtleShvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGUpCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGZpbmFsS2V5KFdyaXRhYmxlQ29tcGFyYWJsZSBrZXkpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICBsb25nIG9yaWdpbmFsUG9zaXRpb24gPSBkYXRhLmdldFBvc2l0aW9uKCk7IC8vIHNhdmUgcG9zaXRpb24KKyAgICAgIHRyeSB7CisgICAgICAgIHJlYWRJbmRleCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBpbmRleCBpcyB2YWxpZAorICAgICAgICBpZiAoY291bnQgPiAwKSB7CisgICAgICAgICAgZGF0YS5zZWVrKHBvc2l0aW9uc1tjb3VudC0xXSk7ICAgICAgICAgIC8vIHNraXAgdG8gbGFzdCBpbmRleGVkIGVudHJ5CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzZXQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoZGF0YS5uZXh0KGtleSkpIHt9ICAgICAgICAgICAgICAgICAvLyBzY2FuIHRvIGVvZgorCisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBkYXRhLnNlZWsob3JpZ2luYWxQb3NpdGlvbik7ICAgICAgICAgICAgICAvLyByZXN0b3JlIHBvc2l0aW9uCisgICAgICB9CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uU3RvcmVGaWxlUmVhZGVyI3NlZWsob3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBzZWVrKFdyaXRhYmxlQ29tcGFyYWJsZSBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc2Vla0ludGVybmFsKGtleSkgPT0gMDsKKyAgICB9CisKKyAgICAvKiogCisgICAgICogUG9zaXRpb25zIHRoZSByZWFkZXIgYXQgdGhlIG5hbWVkIGtleSwgb3IgaWYgbm9uZSBzdWNoIGV4aXN0cywgYXQgdGhlCisgICAgICogZmlyc3QgZW50cnkgYWZ0ZXIgdGhlIG5hbWVkIGtleS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gIDAgICAtIGV4YWN0IG1hdGNoIGZvdW5kCisgICAgICogICAgICAgICAgPCAwIC0gcG9zaXRpb25lZCBhdCBuZXh0IHJlY29yZAorICAgICAqICAgICAgICAgIDEgICAtIG5vIG1vcmUgcmVjb3JkcyBpbiBmaWxlCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgaW50IHNlZWtJbnRlcm5hbChXcml0YWJsZUNvbXBhcmFibGUga2V5KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBzZWVrSW50ZXJuYWwoa2V5LCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqIAorICAgICAqIFBvc2l0aW9ucyB0aGUgcmVhZGVyIGF0IHRoZSBuYW1lZCBrZXksIG9yIGlmIG5vbmUgc3VjaCBleGlzdHMsIGF0IHRoZQorICAgICAqIGtleSB0aGF0IGZhbGxzIGp1c3QgYmVmb3JlIG9yIGp1c3QgYWZ0ZXIgZGVwZW5kZW50IG9uIGhvdyB0aGUKKyAgICAgKiA8Y29kZT5iZWZvcmU8L2NvZGU+IHBhcmFtZXRlciBpcyBzZXQuCisgICAgICogCisgICAgICogQHBhcmFtIGJlZm9yZSAtIElGIHRydWUsIGFuZCA8Y29kZT5rZXk8L2NvZGU+IGRvZXMgbm90IGV4aXN0LCBwb3NpdGlvbgorICAgICAqIGZpbGUgYXQgZW50cnkgdGhhdCBmYWxscyBqdXN0IGJlZm9yZSA8Y29kZT5rZXk8L2NvZGU+LiAgT3RoZXJ3aXNlLAorICAgICAqIHBvc2l0aW9uIGZpbGUgYXQgcmVjb3JkIHRoYXQgc29ydHMganVzdCBhZnRlci4KKyAgICAgKiBAcmV0dXJuICAwICAgLSBleGFjdCBtYXRjaCBmb3VuZAorICAgICAqICAgICAgICAgIDwgMCAtIHBvc2l0aW9uZWQgYXQgbmV4dCByZWNvcmQKKyAgICAgKiAgICAgICAgICAxICAgLSBubyBtb3JlIHJlY29yZHMgaW4gZmlsZQorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIGludCBzZWVrSW50ZXJuYWwoV3JpdGFibGVDb21wYXJhYmxlIGtleSwKKyAgICAgICAgZmluYWwgYm9vbGVhbiBiZWZvcmUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmVhZEluZGV4KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgaW5kZXggaXMgcmVhZAorCisgICAgICBpZiAoc2Vla0luZGV4ICE9IC0xICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZWtlZCBiZWZvcmUKKyAgICAgICAgICAmJiBzZWVrSW5kZXgrMSA8IGNvdW50ICAgICAgICAgICAKKyAgICAgICAgICAmJiBjb21wYXJhdG9yLmNvbXBhcmUoa2V5LCBrZXlzW3NlZWtJbmRleCsxXSk8MCAvLyBiZWZvcmUgbmV4dCBpbmRleGVkCisgICAgICAgICAgJiYgY29tcGFyYXRvci5jb21wYXJlKGtleSwgbmV4dEtleSkKKyAgICAgICAgICA+PSAwKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGFmdGVyIGxhc3Qgc2Vla2VkCisgICAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNlZWtJbmRleCA9IGJpbmFyeVNlYXJjaChrZXkpOworICAgICAgICBpZiAoc2Vla0luZGV4IDwgMCkgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWNvZGUgaW5zZXJ0aW9uIHBvaW50CisgICAgICAgICAgc2Vla0luZGV4ID0gLXNlZWtJbmRleC0yOworCisgICAgICAgIGlmIChzZWVrSW5kZXggPT0gLTEpICAgICAgICAgICAgICAgICAgICAgIC8vIGJlbG9uZ3MgYmVmb3JlIGZpcnN0IGVudHJ5CisgICAgICAgICAgc2Vla1Bvc2l0aW9uID0gZmlyc3RQb3NpdGlvbjsgICAgICAgICAgIC8vIHVzZSBiZWdpbm5pbmcgb2YgZmlsZQorICAgICAgICBlbHNlCisgICAgICAgICAgc2Vla1Bvc2l0aW9uID0gcG9zaXRpb25zW3NlZWtJbmRleF07ICAgIC8vIGVsc2UgdXNlIGluZGV4CisgICAgICB9CisgICAgICBkYXRhLnNlZWsoc2Vla1Bvc2l0aW9uKTsKKyAgICAgIAorICAgICAgaWYgKG5leHRLZXkgPT0gbnVsbCkKKyAgICAgICAgbmV4dEtleSA9IGNvbXBhcmF0b3IubmV3S2V5KCk7CisgICAgIAorICAgICAgLy8gSWYgd2UncmUgbG9va2luZyBmb3IgdGhlIGtleSBiZWZvcmUsIHdlIG5lZWQgdG8ga2VlcCB0cmFjaworICAgICAgLy8gb2YgdGhlIHBvc2l0aW9uIHdlIGdvdCB0aGUgY3VycmVudCBrZXkgYXMgd2VsbCBhcyB0aGUgcG9zaXRpb24KKyAgICAgIC8vIG9mIHRoZSBrZXkgYmVmb3JlIGl0LgorICAgICAgbG9uZyBwcmV2UG9zaXRpb24gPSAtMTsKKyAgICAgIGxvbmcgY3VyUG9zaXRpb24gPSBzZWVrUG9zaXRpb247CisKKyAgICAgIHdoaWxlIChkYXRhLm5leHQobmV4dEtleSkpIHsKKyAgICAgICAgaW50IGMgPSBjb21wYXJhdG9yLmNvbXBhcmUoa2V5LCBuZXh0S2V5KTsKKyAgICAgICAgaWYgKGMgPD0gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXQgb3IgYmV5b25kIGRlc2lyZWQKKyAgICAgICAgICBpZiAoYmVmb3JlICYmIGMgIT0gMCkgeworICAgICAgICAgICAgaWYgKHByZXZQb3NpdGlvbiA9PSAtMSkgeworICAgICAgICAgICAgICAvLyBXZSdyZSBvbiB0aGUgZmlyc3QgcmVjb3JkIG9mIHRoaXMgaW5kZXggYmxvY2sKKyAgICAgICAgICAgICAgLy8gYW5kIHdlJ3ZlIGFscmVhZHkgcGFzc2VkIHRoZSBzZWFyY2gga2V5LiBUaGVyZWZvcmUKKyAgICAgICAgICAgICAgLy8gd2UgbXVzdCBiZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlLCBzbyBzZWVrCisgICAgICAgICAgICAgIC8vIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBibG9jayBhbmQgcmV0dXJuIGMKKyAgICAgICAgICAgICAgZGF0YS5zZWVrKGN1clBvc2l0aW9uKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIC8vIFdlIGhhdmUgYSBwcmV2aW91cyByZWNvcmQgdG8gYmFjayB1cCB0bworICAgICAgICAgICAgICBkYXRhLnNlZWsocHJldlBvc2l0aW9uKTsKKyAgICAgICAgICAgICAgZGF0YS5uZXh0KG5leHRLZXkpOworICAgICAgICAgICAgICAvLyBub3cgdGhhdCB3ZSd2ZSByZXdvdW5kLCB0aGUgc2VhcmNoIGtleSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGlzIGtleQorICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJlZm9yZSkgeworICAgICAgICAgIHByZXZQb3NpdGlvbiA9IGN1clBvc2l0aW9uOworICAgICAgICAgIGN1clBvc2l0aW9uID0gZGF0YS5nZXRQb3NpdGlvbigpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIHByaXZhdGUgaW50IGJpbmFyeVNlYXJjaChXcml0YWJsZUNvbXBhcmFibGUga2V5KSB7CisgICAgICBpbnQgbG93ID0gMDsKKyAgICAgIGludCBoaWdoID0gY291bnQtMTsKKworICAgICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7CisgICAgICAgIGludCBtaWQgPSAobG93ICsgaGlnaCkgPj4+IDE7CisgICAgICAgIFdyaXRhYmxlQ29tcGFyYWJsZSBtaWRWYWwgPSBrZXlzW21pZF07CisgICAgICAgIGludCBjbXAgPSBjb21wYXJhdG9yLmNvbXBhcmUobWlkVmFsLCBrZXkpOworCisgICAgICAgIGlmIChjbXAgPCAwKQorICAgICAgICAgIGxvdyA9IG1pZCArIDE7CisgICAgICAgIGVsc2UgaWYgKGNtcCA+IDApCisgICAgICAgICAgaGlnaCA9IG1pZCAtIDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICByZXR1cm4gbWlkOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2V5IGZvdW5kCisgICAgICB9CisgICAgICByZXR1cm4gLShsb3cgKyAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGtleSBub3QgZm91bmQuCisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uU3RvcmVGaWxlUmVhZGVyI25leHQob3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlLCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gbmV4dChXcml0YWJsZUNvbXBhcmFibGUga2V5LCBXcml0YWJsZSB2YWwpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIGRhdGEubmV4dChrZXksIHZhbCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uU3RvcmVGaWxlUmVhZGVyI2dldChvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGUsIG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGUgZ2V0KFdyaXRhYmxlQ29tcGFyYWJsZSBrZXksIFdyaXRhYmxlIHZhbCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoc2VlayhrZXkpKSB7CisgICAgICAgIGRhdGEuZ2V0Q3VycmVudFZhbHVlKHZhbCk7CisgICAgICAgIHJldHVybiB2YWw7CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVSZWFkZXIjZ2V0Q2xvc2VzdChvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGUsIG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGVDb21wYXJhYmxlIGdldENsb3Nlc3QoV3JpdGFibGVDb21wYXJhYmxlIGtleSwKKyAgICAgIFdyaXRhYmxlIHZhbCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIGdldENsb3Nlc3Qoa2V5LCB2YWwsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVSZWFkZXIjZ2V0Q2xvc2VzdChvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGUsIG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlLCBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgV3JpdGFibGVDb21wYXJhYmxlIGdldENsb3Nlc3QoV3JpdGFibGVDb21wYXJhYmxlIGtleSwKKyAgICAgICAgV3JpdGFibGUgdmFsLCBmaW5hbCBib29sZWFuIGJlZm9yZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgIAorICAgICAgaW50IGMgPSBzZWVrSW50ZXJuYWwoa2V5LCBiZWZvcmUpOworCisgICAgICAvLyBJZiB3ZSBkaWRuJ3QgZ2V0IGFuIGV4YWN0IG1hdGNoLCBhbmQgd2UgZW5kZWQgdXAgaW4gdGhlIHdyb25nCisgICAgICAvLyBkaXJlY3Rpb24gcmVsYXRpdmUgdG8gdGhlIHF1ZXJ5IGtleSwgcmV0dXJuIG51bGwgc2luY2Ugd2UKKyAgICAgIC8vIG11c3QgYmUgYXQgdGhlIGJlZ2lubmluZyBvciBlbmQgb2YgdGhlIGZpbGUuCisgICAgICBpZiAoKCFiZWZvcmUgJiYgYyA+IDApIHx8CisgICAgICAgICAgKGJlZm9yZSAmJiBjIDwgMCkpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisKKyAgICAgIGRhdGEuZ2V0Q3VycmVudFZhbHVlKHZhbCk7CisgICAgICByZXR1cm4gbmV4dEtleTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5TdG9yZUZpbGVSZWFkZXIjY2xvc2UoKQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoIWluZGV4Q2xvc2VkKSB7CisgICAgICAgIGluZGV4LmNsb3NlKCk7CisgICAgICB9CisgICAgICBkYXRhLmNsb3NlKCk7CisgICAgfQorCisgIH0KKworICAvKiogUmVuYW1lcyBhbiBleGlzdGluZyBtYXAgZGlyZWN0b3J5LiAKKyAgICogQHBhcmFtIGZzIAorICAgKiBAcGFyYW0gb2xkTmFtZSAKKyAgICogQHBhcmFtIG5ld05hbWUgCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCByZW5hbWUoRmlsZVN5c3RlbSBmcywgU3RyaW5nIG9sZE5hbWUsIFN0cmluZyBuZXdOYW1lKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBvbGREaXIgPSBuZXcgUGF0aChvbGROYW1lKTsKKyAgICBQYXRoIG5ld0RpciA9IG5ldyBQYXRoKG5ld05hbWUpOworICAgIGlmICghZnMucmVuYW1lKG9sZERpciwgbmV3RGlyKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVuYW1lICIgKyBvbGREaXIgKyAiIHRvICIgKyBuZXdEaXIpOworICAgIH0KKyAgfQorCisgIC8qKiBEZWxldGVzIHRoZSBuYW1lZCBtYXAgZmlsZS4gCisgICAqIEBwYXJhbSBmcyAKKyAgICogQHBhcmFtIG5hbWUgCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBkZWxldGUoRmlsZVN5c3RlbSBmcywgU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBkaXIgPSBuZXcgUGF0aChuYW1lKTsKKyAgICBQYXRoIGRhdGEgPSBuZXcgUGF0aChkaXIsIERBVEFfRklMRV9OQU1FKTsKKyAgICBQYXRoIGluZGV4ID0gbmV3IFBhdGgoZGlyLCBJTkRFWF9GSUxFX05BTUUpOworCisgICAgZnMuZGVsZXRlKGRhdGEsIHRydWUpOworICAgIGZzLmRlbGV0ZShpbmRleCwgdHJ1ZSk7CisgICAgZnMuZGVsZXRlKGRpciwgdHJ1ZSk7CisgIH0KKworICAvKioKKyAgICogVGhpcyBtZXRob2QgYXR0ZW1wdHMgdG8gZml4IGEgY29ycnVwdCBNYXBGaWxlIGJ5IHJlLWNyZWF0aW5nIGl0cyBpbmRleC4KKyAgICogQHBhcmFtIGZzIGZpbGVzeXN0ZW0KKyAgICogQHBhcmFtIGRpciBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgTWFwRmlsZSBkYXRhIGFuZCBpbmRleAorICAgKiBAcGFyYW0ga2V5Q2xhc3Mga2V5IGNsYXNzIChoYXMgdG8gYmUgYSBzdWJjbGFzcyBvZiBXcml0YWJsZSkKKyAgICogQHBhcmFtIHZhbHVlQ2xhc3MgdmFsdWUgY2xhc3MgKGhhcyB0byBiZSBhIHN1YmNsYXNzIG9mIFdyaXRhYmxlKQorICAgKiBAcGFyYW0gZHJ5cnVuIGRvIG5vdCBwZXJmb3JtIGFueSBjaGFuZ2VzLCBqdXN0IHJlcG9ydCB3aGF0IG5lZWRzIHRvIGJlIGRvbmUKKyAgICogQHBhcmFtIGNvbmYgCisgICAqIEByZXR1cm4gbnVtYmVyIG9mIHZhbGlkIGVudHJpZXMgaW4gdGhpcyBNYXBGaWxlLCBvciAtMSBpZiBubyBmaXhpbmcgd2FzIG5lZWRlZAorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGZpeChGaWxlU3lzdGVtIGZzLCBQYXRoIGRpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGU+IGtleUNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZT4gdmFsdWVDbGFzcywgYm9vbGVhbiBkcnlydW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgZHIgPSAoZHJ5cnVuID8gIltEUlkgUlVOIF0gIiA6ICIiKTsKKyAgICBQYXRoIGRhdGEgPSBuZXcgUGF0aChkaXIsIERBVEFfRklMRV9OQU1FKTsKKyAgICBQYXRoIGluZGV4ID0gbmV3IFBhdGgoZGlyLCBJTkRFWF9GSUxFX05BTUUpOworICAgIGludCBpbmRleEludGVydmFsID0gMTI4OworICAgIGlmICghZnMuZXhpc3RzKGRhdGEpKSB7CisgICAgICAvLyB0aGVyZSdzIG5vdGhpbmcgd2UgY2FuIGRvIHRvIGZpeCB0aGlzIQorICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihkciArICJNaXNzaW5nIGRhdGEgZmlsZSBpbiAiICsgZGlyICsgIiwgaW1wb3NzaWJsZSB0byBmaXggdGhpcy4iKTsKKyAgICB9CisgICAgaWYgKGZzLmV4aXN0cyhpbmRleCkpIHsKKyAgICAgIC8vIG5vIGZpeGluZyBuZWVkZWQKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgU2VxdWVuY2VGaWxlLlJlYWRlciBkYXRhUmVhZGVyID0gbmV3IFNlcXVlbmNlRmlsZS5SZWFkZXIoZnMsIGRhdGEsIGNvbmYpOworICAgIGlmICghZGF0YVJlYWRlci5nZXRLZXlDbGFzcygpLmVxdWFscyhrZXlDbGFzcykpIHsKKyAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oZHIgKyAiV3Jvbmcga2V5IGNsYXNzIGluICIgKyBkaXIgKyAiLCBleHBlY3RlZCIgKyBrZXlDbGFzcy5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBnb3QgIiArIGRhdGFSZWFkZXIuZ2V0S2V5Q2xhc3MoKS5nZXROYW1lKCkpOworICAgIH0KKyAgICBpZiAoIWRhdGFSZWFkZXIuZ2V0VmFsdWVDbGFzcygpLmVxdWFscyh2YWx1ZUNsYXNzKSkgeworICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihkciArICJXcm9uZyB2YWx1ZSBjbGFzcyBpbiAiICsgZGlyICsgIiwgZXhwZWN0ZWQiICsgdmFsdWVDbGFzcy5nZXROYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBnb3QgIiArIGRhdGFSZWFkZXIuZ2V0VmFsdWVDbGFzcygpLmdldE5hbWUoKSk7CisgICAgfQorICAgIGxvbmcgY250ID0gMEw7CisgICAgV3JpdGFibGUga2V5ID0gKFdyaXRhYmxlKSBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2Uoa2V5Q2xhc3MsIGNvbmYpOworICAgIFdyaXRhYmxlIHZhbHVlID0gKFdyaXRhYmxlKSBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2UodmFsdWVDbGFzcywgY29uZik7CisgICAgU2VxdWVuY2VGaWxlLldyaXRlciBpbmRleFdyaXRlciA9IG51bGw7CisgICAgaWYgKCFkcnlydW4pIGluZGV4V3JpdGVyID0gU2VxdWVuY2VGaWxlLmNyZWF0ZVdyaXRlcihmcywgY29uZiwgaW5kZXgsIGtleUNsYXNzLCBMb25nV3JpdGFibGUuY2xhc3MpOworICAgIHRyeSB7CisgICAgICBsb25nIHBvcyA9IDBMOworICAgICAgTG9uZ1dyaXRhYmxlIHBvc2l0aW9uID0gbmV3IExvbmdXcml0YWJsZSgpOworICAgICAgd2hpbGUoZGF0YVJlYWRlci5uZXh0KGtleSwgdmFsdWUpKSB7CisgICAgICAgIGNudCsrOworICAgICAgICBpZiAoY250ICUgaW5kZXhJbnRlcnZhbCA9PSAwKSB7CisgICAgICAgICAgcG9zaXRpb24uc2V0KHBvcyk7CisgICAgICAgICAgaWYgKCFkcnlydW4pIGluZGV4V3JpdGVyLmFwcGVuZChrZXksIHBvc2l0aW9uKTsKKyAgICAgICAgfQorICAgICAgICBwb3MgPSBkYXRhUmVhZGVyLmdldFBvc2l0aW9uKCk7CisgICAgICB9CisgICAgfSBjYXRjaChUaHJvd2FibGUgdCkgeworICAgICAgLy8gdHJ1bmNhdGVkIGRhdGEgZmlsZS4gc3dhbGxvdyBpdC4KKyAgICB9CisgICAgZGF0YVJlYWRlci5jbG9zZSgpOworICAgIGlmICghZHJ5cnVuKSBpbmRleFdyaXRlci5jbG9zZSgpOworICAgIHJldHVybiBjbnQ7CisgIH0KKworCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyB1c2FnZSA9ICJVc2FnZTogTWFwRmlsZSBpbkZpbGUgb3V0RmlsZSI7CisgICAgICAKKyAgICBpZiAoYXJncy5sZW5ndGggIT0gMikgeworICAgICAgU3lzdGVtLmVyci5wcmludGxuKHVzYWdlKTsKKyAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICB9CisgICAgICAKKyAgICBTdHJpbmcgaW4gPSBhcmdzWzBdOworICAgIFN0cmluZyBvdXQgPSBhcmdzWzFdOworCisgICAgQ29uZmlndXJhdGlvbiBjb25mID0gbmV3IENvbmZpZ3VyYXRpb24oKTsKKyAgICBGaWxlU3lzdGVtIGZzID0gRmlsZVN5c3RlbS5nZXRMb2NhbChjb25mKTsKKyAgICBNYXBGaWxlLlJlYWRlciByZWFkZXIgPSBuZXcgTWFwRmlsZS5SZWFkZXIoZnMsIGluLCBjb25mKTsKKyAgICBNYXBGaWxlLldyaXRlciB3cml0ZXIgPQorICAgICAgbmV3IE1hcEZpbGUuV3JpdGVyKGNvbmYsIGZzLCBvdXQsCisgICAgICAgICAgcmVhZGVyLmdldEtleUNsYXNzKCkuYXNTdWJjbGFzcyhXcml0YWJsZUNvbXBhcmFibGUuY2xhc3MpLAorICAgICAgICAgIHJlYWRlci5nZXRWYWx1ZUNsYXNzKCkpOworCisgICAgV3JpdGFibGVDb21wYXJhYmxlIGtleSA9IChXcml0YWJsZUNvbXBhcmFibGUpCisgICAgICBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2UocmVhZGVyLmdldEtleUNsYXNzKCkuYXNTdWJjbGFzcyhXcml0YWJsZUNvbXBhcmFibGUuY2xhc3MpLCBjb25mKTsKKyAgICBXcml0YWJsZSB2YWx1ZSA9IChXcml0YWJsZSkKKyAgICAgIFJlZmxlY3Rpb25VdGlscy5uZXdJbnN0YW5jZShyZWFkZXIuZ2V0VmFsdWVDbGFzcygpLmFzU3ViY2xhc3MoV3JpdGFibGUuY2xhc3MpLCBjb25mKTsKKworICAgIHdoaWxlIChyZWFkZXIubmV4dChrZXksIHZhbHVlKSkgICAgICAgICAgICAgICAvLyBjb3B5IGFsbCBlbnRyaWVzCisgICAgICB3cml0ZXIuYXBwZW5kKGtleSwgdmFsdWUpOworCisgICAgd3JpdGVyLmNsb3NlKCk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vUmVmZXJlbmNlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9SZWZlcmVuY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kN2QzMmNjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vUmVmZXJlbmNlLmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qKgorICogCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW87CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkZTVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogQSByZWZlcmVuY2UgdG8gdGhlIHRvcCBvciBib3R0b20gaGFsZiBvZiBhIHN0b3JlIGZpbGUuICBUaGUgZmlsZSByZWZlcmVuY2VkCisgKiBsaXZlcyB1bmRlciBhIGRpZmZlcmVudCByZWdpb24uICBSZWZlcmVuY2VzIGFyZSBtYWRlIGF0IHJlZ2lvbiBzcGxpdCB0aW1lLgorICogCisgKiA8cD5SZWZlcmVuY2VzIHdvcmsgd2l0aCBhIHNwZWNpYWwgaGFsZiBzdG9yZSBmaWxlIHR5cGUuICBSZWZlcmVuY2VzIGtub3cgaG93CisgKiB0byB3cml0ZSBvdXQgdGhlIHJlZmVyZW5jZSBmb3JtYXQgaW4gdGhlIGZpbGUgc3lzdGVtIGFuZCBhcmUgd2hhdHMganVnZ2xlZAorICogd2hlbiByZWZlcmVuY2VzIGFyZSBtaXhlZCBpbiB3aXRoIGRpcmVjdCBzdG9yZSBmaWxlcy4gIFRoZSBoYWxmIHN0b3JlIGZpbGUKKyAqIHR5cGUgaXMgdXNlZCByZWFkaW5nIHRoZSByZWZlcnJlZCB0byBmaWxlLgorICoKKyAqIDxwPlJlZmVyZW5jZXMgdG8gc3RvcmUgZmlsZXMgbG9jYXRlZCBvdmVyIGluIHNvbWUgb3RoZXIgcmVnaW9uIGxvb2sgbGlrZQorICogdGhpcyBpbiB0aGUgZmlsZSBzeXN0ZW0KKyAqIDxjb2RlPjEyNzg0Mzc4NTYwMDk5MjU0NDUuMzMyMzIyMzMyMzwvY29kZT46CisgKiBpLmUuIGFuIGlkIGZvbGxvd2VkIGJ5IGhhc2ggb2YgdGhlIHJlZmVyZW5jZWQgcmVnaW9uLgorICogTm90ZSwgYSByZWdpb24gaXMgaXRzZWxmIG5vdCBzcGxpdGFibGUgaWYgaXQgaGFzIGluc3RhbmNlcyBvZiBzdG9yZSBmaWxlCisgKiByZWZlcmVuY2VzLiAgUmVmZXJlbmNlcyBhcmUgY2xlYW5lZCB1cCBieSBjb21wYWN0aW9ucy4KKyAqLworcHVibGljIGNsYXNzIFJlZmVyZW5jZSBpbXBsZW1lbnRzIFdyaXRhYmxlIHsKKyAgcHJpdmF0ZSBieXRlIFtdIHNwbGl0a2V5OworICBwcml2YXRlIFJhbmdlIHJlZ2lvbjsKKworICAvKiogCisgICAqIEZvciBzcGxpdCBIU3RvcmVGaWxlcywgaXQgc3BlY2lmaWVzIGlmIHRoZSBmaWxlIGNvdmVycyB0aGUgbG93ZXIgaGFsZiBvcgorICAgKiB0aGUgdXBwZXIgaGFsZiBvZiB0aGUga2V5IHJhbmdlCisgICAqLworICBwdWJsaWMgc3RhdGljIGVudW0gUmFuZ2UgeworICAgIC8qKiBIU3RvcmVGaWxlIGNvbnRhaW5zIHVwcGVyIGhhbGYgb2Yga2V5IHJhbmdlICovCisgICAgdG9wLAorICAgIC8qKiBIU3RvcmVGaWxlIGNvbnRhaW5zIGxvd2VyIGhhbGYgb2Yga2V5IHJhbmdlICovCisgICAgYm90dG9tCisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIHNwbGl0Um93IFRoaXMgaXMgcm93IHdlIGFyZSBzcGxpdHRpbmcgYXJvdW5kLgorICAgKiBAcGFyYW0gZnIKKyAgICovCisgIHB1YmxpYyBSZWZlcmVuY2UoZmluYWwgYnl0ZSBbXSBzcGxpdFJvdywgZmluYWwgUmFuZ2UgZnIpIHsKKyAgICB0aGlzLnNwbGl0a2V5ID0gc3BsaXRSb3cgPT0gbnVsbD8KKyAgICAgIG51bGw6IEtleVZhbHVlLmNyZWF0ZUZpcnN0T25Sb3coc3BsaXRSb3cpLmdldEtleSgpOworICAgIHRoaXMucmVnaW9uID0gZnI7CisgIH0KKworICAvKioKKyAgICogVXNlZCBieSBzZXJpYWxpemF0aW9ucy4KKyAgICovCisgIHB1YmxpYyBSZWZlcmVuY2UoKSB7CisgICAgdGhpcyhudWxsLCBSYW5nZS5ib3R0b20pOworICB9CisKKyAgcHVibGljIFJhbmdlIGdldEZpbGVSZWdpb24oKSB7CisgICAgcmV0dXJuIHRoaXMucmVnaW9uOworICB9CisKKyAgcHVibGljIGJ5dGUgW10gZ2V0U3BsaXRLZXkoKSB7CisgICAgcmV0dXJuIHNwbGl0a2V5OworICB9CisKKyAgLyoqCisgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gIiIgKyB0aGlzLnJlZ2lvbjsKKyAgfQorCisgIC8vIE1ha2UgaXQgc2VyaWFsaXphYmxlLgorCisgIHB1YmxpYyB2b2lkIHdyaXRlKERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFdyaXRlIHRydWUgaWYgd2UncmUgZG9pbmcgdG9wIG9mIHRoZSBmaWxlLgorICAgIG91dC53cml0ZUJvb2xlYW4oaXNUb3BGaWxlUmVnaW9uKHRoaXMucmVnaW9uKSk7CisgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCB0aGlzLnNwbGl0a2V5KTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJvb2xlYW4gdG1wID0gaW4ucmVhZEJvb2xlYW4oKTsKKyAgICAvLyBJZiB0cnVlLCBzZXQgcmVnaW9uIHRvIHRvcC4KKyAgICB0aGlzLnJlZ2lvbiA9IHRtcD8gUmFuZ2UudG9wOiBSYW5nZS5ib3R0b207CisgICAgdGhpcy5zcGxpdGtleSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICB9CisKKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVG9wRmlsZVJlZ2lvbihmaW5hbCBSYW5nZSByKSB7CisgICAgcmV0dXJuIHIuZXF1YWxzKFJhbmdlLnRvcCk7CisgIH0KKworICBwdWJsaWMgUGF0aCB3cml0ZShmaW5hbCBGaWxlU3lzdGVtIGZzLCBmaW5hbCBQYXRoIHApCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRlNVdGlscy5jcmVhdGUoZnMsIHApOworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBmcy5jcmVhdGUocCk7CisgICAgdHJ5IHsKKyAgICAgIHdyaXRlKG91dCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG91dC5jbG9zZSgpOworICAgIH0KKyAgICByZXR1cm4gcDsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIGEgUmVmZXJlbmNlIGZyb20gRmlsZVN5c3RlbS4KKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBwCisgICAqIEByZXR1cm4gTmV3IFJlZmVyZW5jZSBtYWRlIGZyb20gcGFzc2VkIDxjb2RlPnA8L2NvZGU+CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUmVmZXJlbmNlIHJlYWQoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgUGF0aCBwKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZTRGF0YUlucHV0U3RyZWFtIGluID0gZnMub3BlbihwKTsKKyAgICB0cnkgeworICAgICAgUmVmZXJlbmNlIHIgPSBuZXcgUmVmZXJlbmNlKCk7CisgICAgICByLnJlYWRGaWVsZHMoaW4pOworICAgICAgcmV0dXJuIHI7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGluLmNsb3NlKCk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vUm93UmVzdWx0LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9Sb3dSZXN1bHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjFiZDA4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vUm93UmVzdWx0LmphdmEKQEAgLTAsMCArMSwzMjYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlJlc3RDZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JU2VyaWFsaXphYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKK2ltcG9ydCBhZ2lsZWpzb24uVE9KU09OOworCisvKioKKyAqIEhvbGRzIHJvdyBuYW1lIGFuZCB0aGVuIGEgbWFwIG9mIGNvbHVtbnMgdG8gY2VsbHMuCisgKi8KK3B1YmxpYyBjbGFzcyBSb3dSZXN1bHQgaW1wbGVtZW50cyBXcml0YWJsZSwgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+LAorICBDb21wYXJhYmxlPFJvd1Jlc3VsdD4sIElTZXJpYWxpemFibGUgeworICBwcml2YXRlIGJ5dGUgW10gcm93ID0gbnVsbDsKKyAgcHJpdmF0ZSBmaW5hbCBIYmFzZU1hcFdyaXRhYmxlPGJ5dGUgW10sIENlbGw+IGNlbGxzOworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yIGZvciB3cml0YWJsZSAqLworICBwdWJsaWMgUm93UmVzdWx0KCkgeworICAgIHRoaXMobnVsbCwgbmV3IEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgQ2VsbD4oKSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEgUm93UmVzdWx0IGZyb20gYSByb3cgYW5kIENlbGwgbWFwCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIG0KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgKGZpbmFsIGJ5dGUgW10gcm93LAorICAgICAgZmluYWwgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPiBtKSB7CisgICAgdGhpcy5yb3cgPSByb3c7CisgICAgdGhpcy5jZWxscyA9IG07CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHJvdyBmb3IgdGhpcyBSb3dSZXN1bHQKKyAgICogQHJldHVybiB0aGUgcm93CisgICAqLworICBAVE9KU09OKGJhc2U2ND10cnVlKQorICBwdWJsaWMgYnl0ZSBbXSBnZXRSb3coKSB7CisgICAgcmV0dXJuIHJvdzsKKyAgfQorCisgIC8vIAorICAvLyBNYXAgaW50ZXJmYWNlCisgIC8vIAorICBwdWJsaWMgQ2VsbCBwdXQoYnl0ZSBbXSBrZXksCisgICAgQ2VsbCB2YWx1ZSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiUm93UmVzdWx0IGlzIHJlYWQtb25seSEiKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwIG1hcCkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiUm93UmVzdWx0IGlzIHJlYWQtb25seSEiKTsKKyAgfQorCisgIHB1YmxpYyBDZWxsIGdldChPYmplY3Qga2V5KSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMuZ2V0KGtleSk7CisgIH0KKworICBwdWJsaWMgQ2VsbCByZW1vdmUoT2JqZWN0IGtleSkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiUm93UmVzdWx0IGlzIHJlYWQtb25seSEiKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICByZXR1cm4gY2VsbHMuY29udGFpbnNLZXkoa2V5KTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNLZXkoU3RyaW5nIGtleSkgeworICAgIHJldHVybiBjZWxscy5jb250YWluc0tleShCeXRlcy50b0J5dGVzKGtleSkpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIkRvbid0IHN1cHBvcnQgY29udGFpbnNWYWx1ZSEiKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgcmV0dXJuIGNlbGxzLmlzRW1wdHkoKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICByZXR1cm4gY2VsbHMuc2l6ZSgpOworICB9CisKKyAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJSb3dSZXN1bHQgaXMgcmVhZC1vbmx5ISIpOworICB9CisKKyAgcHVibGljIFNldDxieXRlIFtdPiBrZXlTZXQoKSB7CisgICAgU2V0PGJ5dGUgW10+IHJlc3VsdCA9IG5ldyBUcmVlU2V0PGJ5dGUgW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgIGZvciAoYnl0ZSBbXSB3IDogY2VsbHMua2V5U2V0KCkpIHsKKyAgICAgIHJlc3VsdC5hZGQodyk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwdWJsaWMgU2V0PE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPj4gZW50cnlTZXQoKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldCh0aGlzLmNlbGxzLmVudHJ5U2V0KCkpOworICB9CisgIAorICAvKioKKyAgICogVGhpcyBtZXRob2QgdXNlZCBzb2xlbHkgZm9yIHRoZSBSRVNUIHNlcmlhbGl6YXRpb24KKyAgICogCisgICAqIEByZXR1cm4gQ2VsbHMKKyAgICovCisgIEBUT0pTT04KKyAgcHVibGljIFJlc3RDZWxsW10gZ2V0Q2VsbHMoKSB7CisgICAgUmVzdENlbGxbXSByZXN0Q2VsbHMgPSBuZXcgUmVzdENlbGxbdGhpcy5jZWxscy5zaXplKCldOworICAgIGludCBpID0gMDsKKyAgICBmb3IgKE1hcC5FbnRyeTxieXRlW10sIENlbGw+IGVudHJ5IDogdGhpcy5jZWxscy5lbnRyeVNldCgpKSB7CisgICAgICByZXN0Q2VsbHNbaV0gPSBuZXcgUmVzdENlbGwoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgaSsrOworICAgIH0KKyAgICByZXR1cm4gcmVzdENlbGxzOworICB9CisKKyAgcHVibGljIENvbGxlY3Rpb248Q2VsbD4gdmFsdWVzKCkgeworICAgIEFycmF5TGlzdDxDZWxsPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PENlbGw+KCk7CisgICAgZm9yIChXcml0YWJsZSB3IDogY2VsbHMudmFsdWVzKCkpIHsKKyAgICAgIHJlc3VsdC5hZGQoKENlbGwpdyk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIENlbGwgdGhhdCBjb3JyZXNwb25kcyB0byBjb2x1bW4KKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcmV0dXJuIHRoZSBDZWxsCisgICAqLworICBwdWJsaWMgQ2VsbCBnZXQoYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICByZXR1cm4gdGhpcy5jZWxscy5nZXQoY29sdW1uKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgQ2VsbCB0aGF0IGNvcnJlc3BvbmRzIHRvIGNvbHVtbiwgdXNpbmcgYSBTdHJpbmcga2V5CisgICAqIEBwYXJhbSBrZXkKKyAgICogQHJldHVybiB0aGUgQ2VsbAorICAgKi8KKyAgcHVibGljIENlbGwgZ2V0KFN0cmluZyBrZXkpIHsKKyAgICByZXR1cm4gZ2V0KEJ5dGVzLnRvQnl0ZXMoa2V5KSk7CisgIH0KKyAgCisKKyAgcHVibGljIENvbXBhcmF0b3I8PyBzdXBlciBieXRlW10+IGNvbXBhcmF0b3IoKSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMuY29tcGFyYXRvcigpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBmaXJzdEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5jZWxscy5maXJzdEtleSgpOworICB9CisKKyAgcHVibGljIFNvcnRlZE1hcDxieXRlW10sIENlbGw+IGhlYWRNYXAoYnl0ZVtdIHRvS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMuaGVhZE1hcCh0b0tleSk7CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGxhc3RLZXkoKSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMubGFzdEtleSgpOworICB9CisKKyAgcHVibGljIFNvcnRlZE1hcDxieXRlW10sIENlbGw+IHN1Yk1hcChieXRlW10gZnJvbUtleSwgYnl0ZVtdIHRvS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMuc3ViTWFwKGZyb21LZXksIHRvS2V5KTsKKyAgfQorCisgIHB1YmxpYyBTb3J0ZWRNYXA8Ynl0ZVtdLCBDZWxsPiB0YWlsTWFwKGJ5dGVbXSBmcm9tS2V5KSB7CisgICAgcmV0dXJuIHRoaXMuY2VsbHMudGFpbE1hcChmcm9tS2V5KTsKKyAgfQorCisgIC8qKgorICAgKiBSb3cgZW50cnkuCisgICAqLworICBwdWJsaWMgY2xhc3MgRW50cnkgaW1wbGVtZW50cyBNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4geworICAgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBjb2x1bW47CisgICAgcHJpdmF0ZSBmaW5hbCBDZWxsIGNlbGw7CisgICAgCisgICAgRW50cnkoYnl0ZSBbXSByb3csIENlbGwgY2VsbCkgeworICAgICAgdGhpcy5jb2x1bW4gPSByb3c7CisgICAgICB0aGlzLmNlbGwgPSBjZWxsOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgQ2VsbCBzZXRWYWx1ZShDZWxsIGMpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiUm93UmVzdWx0IGlzIHJlYWQtb25seSEiKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIGJ5dGUgW10gZ2V0S2V5KCkgeworICAgICAgcmV0dXJuIGNvbHVtbjsKKyAgICB9CisgICAgCisgICAgcHVibGljIENlbGwgZ2V0VmFsdWUoKSB7CisgICAgICByZXR1cm4gY2VsbDsKKyAgICB9CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIHNiLmFwcGVuZCgicm93PSIpOworICAgIHNiLmFwcGVuZChCeXRlcy50b1N0cmluZyh0aGlzLnJvdykpOworICAgIHNiLmFwcGVuZCgiLCBjZWxscz17Iik7CisgICAgYm9vbGVhbiBtb3JlVGhhbk9uZSA9IGZhbHNlOworICAgIGZvciAoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGU6IHRoaXMuY2VsbHMuZW50cnlTZXQoKSkgeworICAgICAgaWYgKG1vcmVUaGFuT25lKSB7CisgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIG1vcmVUaGFuT25lID0gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHNiLmFwcGVuZCgiKGNvbHVtbj0iKTsKKyAgICAgIHNiLmFwcGVuZChCeXRlcy50b1N0cmluZyhlLmdldEtleSgpKSk7CisgICAgICBzYi5hcHBlbmQoIiwgdGltZXN0YW1wPSIpOworICAgICAgc2IuYXBwZW5kKExvbmcudG9TdHJpbmcoZS5nZXRWYWx1ZSgpLmdldFRpbWVzdGFtcCgpKSk7CisgICAgICBzYi5hcHBlbmQoIiwgdmFsdWU9Iik7CisgICAgICBieXRlIFtdIHYgPSBlLmdldFZhbHVlKCkuZ2V0VmFsdWUoKTsKKyAgICAgIGlmIChCeXRlcy5lcXVhbHMoZS5nZXRLZXkoKSwgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTykpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBzYi5hcHBlbmQoV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKHYpLnRvU3RyaW5nKCkpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgICAgICBzYi5hcHBlbmQoaW9lLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodik7IAorICAgICAgfQorICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgfQorICAgIHNiLmFwcGVuZCgifSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisgIAorICAvKiAobm9uLUphdmFkb2MpCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC54bWwuSU91dHB1dFhNTCN0b1hNTCgpCisgICAqLworICBwdWJsaWMgdm9pZCByZXN0U2VyaWFsaXplKElSZXN0U2VyaWFsaXplciBzZXJpYWxpemVyKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzZXJpYWxpemVyLnNlcmlhbGl6ZVJvd1Jlc3VsdCh0aGlzKTsKKyAgfSAgCisKKyAgLyoqCisgICAqIEBwYXJhbSBsCisgICAqIEByZXR1cm4KKyAgICogVE9ETzogVGhpcyBpcyB0aGUgZ2x1ZSBiZXR3ZWVuIG9sZCB3YXkgb2YgZG9pbmcgdGhpbmdzIGFuZCB0aGUgbmV3LgorICAgKiBIZXJlaW4gd2UgYXJlIGNvbnZlcnRpbmcgb3VyIGNsZWFuIEtleVZhbHVlcyB0byBvbGQgUm93UmVzdWx0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBSb3dSZXN1bHQgW10gY3JlYXRlUm93UmVzdWx0QXJyYXkoZmluYWwgTGlzdDxMaXN0PEtleVZhbHVlPj4gbCkgeworICAgIFJvd1Jlc3VsdCBbXSByZXN1bHRzID0gbmV3IFJvd1Jlc3VsdFtsLnNpemUoKV07CisgICAgaW50IGkgPSAwOworICAgIGZvciAoTGlzdDxLZXlWYWx1ZT4ga3ZsOiBsKSB7CisgICAgICByZXN1bHRzW2krK10gPSBjcmVhdGVSb3dSZXN1bHQoa3ZsKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdHM7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJlc3VsdHMKKyAgICogQHJldHVybgorICAgKiBUT0RPOiBUaGlzIGlzIHRoZSBnbHVlIGJldHdlZW4gb2xkIHdheSBvZiBkb2luZyB0aGluZ3MgYW5kIHRoZSBuZXcuCisgICAqIEhlcmVpbiB3ZSBhcmUgY29udmVydGluZyBvdXIgY2xlYW4gS2V5VmFsdWVzIHRvIG9sZCBSb3dSZXN1bHQuCisgICAqLworICBwdWJsaWMgc3RhdGljIFJvd1Jlc3VsdCBjcmVhdGVSb3dSZXN1bHQoZmluYWwgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cykgeworICAgIGlmIChyZXN1bHRzLmlzRW1wdHkoKSkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgQ2VsbD4gY2VsbHMgPSBDZWxsLmNyZWF0ZUNlbGxzKHJlc3VsdHMpOworICAgIGJ5dGUgW10gcm93ID0gcmVzdWx0cy5nZXQoMCkuZ2V0Um93KCk7CisgICAgcmV0dXJuIG5ldyBSb3dSZXN1bHQocm93LCBjZWxscyk7CisgIH0KKworICAvLworICAvLyBXcml0YWJsZQorICAvLworCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoZmluYWwgRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMucm93ID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgdGhpcy5jZWxscy5yZWFkRmllbGRzKGluKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKGZpbmFsIERhdGFPdXRwdXQgb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5yb3cpOworICAgIHRoaXMuY2VsbHMud3JpdGUob3V0KTsKKyAgfQorICAKKyAgLy8KKyAgLy8gQ29tcGFyYWJsZQorICAvLworICAvKioKKyAgICogIENvbXBhcmluZyB0aGlzIFJvd1Jlc3VsdCB3aXRoIGFub3RoZXIgb25lIGJ5CisgICAqICBjb21wYXJpbmcgdGhlIHJvdyBpbiBpdC4KKyAgICogIEBwYXJhbSBvIHRoZSBSb3dSZXN1bHQgT2JqZWN0IHRvIGNvbXBhcmUgdG8KKyAgICogIEByZXR1cm4gdGhlIGNvbXBhcmUgbnVtYmVyCisgICAqLworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhSb3dSZXN1bHQgbyl7CisgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyh0aGlzLnJvdywgby5nZXRSb3coKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9TZXF1ZW5jZUZpbGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL1NlcXVlbmNlRmlsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmM2FhZWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9TZXF1ZW5jZUZpbGUuamF2YQpAQCAtMCwwICsxLDMzNjcgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvOworCitpbXBvcnQgamF2YS5pby4qOworaW1wb3J0IGphdmEudXRpbC4qOworaW1wb3J0IGphdmEucm1pLnNlcnZlci5VSUQ7CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLio7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5EYXRhSW5wdXRCdWZmZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uSW50V3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uUmF3Q29tcGFyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlVURjg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uVmVyc2lvbk1pc21hdGNoRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVOYW1lOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuQ29kZWNQb29sOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkNvbXByZXNzaW9uQ29kZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuQ29tcHJlc3Npb25JbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5Db21wcmVzc2lvbk91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5Db21wcmVzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkRlY29tcHJlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5EZWZhdWx0Q29kZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuR3ppcENvZGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLnpsaWIuWmxpYkZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uc2VyaWFsaXplci5EZXNlcmlhbGl6ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uc2VyaWFsaXplci5TZXJpYWxpemF0aW9uRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5zZXJpYWxpemVyLlNlcmlhbGl6ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi4qOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJvZ3Jlc3NhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJvZ3Jlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5SZWZsZWN0aW9uVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5OYXRpdmVDb2RlTG9hZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuTWVyZ2VTb3J0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJpb3JpdHlRdWV1ZTsKKworLyoqIAorICogPGNvZGU+U2VxdWVuY2VGaWxlPC9jb2RlPnMgYXJlIGZsYXQgZmlsZXMgY29uc2lzdGluZyBvZiBiaW5hcnkga2V5L3ZhbHVlIAorICogcGFpcnMuCisgKiAKKyAqIDxwPlRoaXMgaXMgY29weSBvZiBIYWRvb3AgU2VxdWVuY2VGaWxlIGJyb3VnaHQgbG9jYWwgc28gd2UgY2FuIGZpeCBidWdzOworICogZS5nLiBoYmFzZS0xMDk3PC9wPgorICogCisgKiA8cD48Y29kZT5TZXF1ZW5jZUZpbGU8L2NvZGU+IHByb3ZpZGVzIHtAbGluayBXcml0ZXJ9LCB7QGxpbmsgUmVhZGVyfSBhbmQKKyAqIHtAbGluayBTb3J0ZXJ9IGNsYXNzZXMgZm9yIHdyaXRpbmcsIHJlYWRpbmcgYW5kIHNvcnRpbmcgcmVzcGVjdGl2ZWx5LjwvcD4KKyAqIAorICogVGhlcmUgYXJlIHRocmVlIDxjb2RlPlNlcXVlbmNlRmlsZTwvY29kZT4gPGNvZGU+V3JpdGVyPC9jb2RlPnMgYmFzZWQgb24gdGhlIAorICoge0BsaW5rIENvbXByZXNzaW9uVHlwZX0gdXNlZCB0byBjb21wcmVzcyBrZXkvdmFsdWUgcGFpcnM6CisgKiA8b2w+CisgKiAgIDxsaT4KKyAqICAgPGNvZGU+V3JpdGVyPC9jb2RlPiA6IFVuY29tcHJlc3NlZCByZWNvcmRzLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgIDxjb2RlPlJlY29yZENvbXByZXNzV3JpdGVyPC9jb2RlPiA6IFJlY29yZC1jb21wcmVzc2VkIGZpbGVzLCBvbmx5IGNvbXByZXNzIAorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMuCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgPGNvZGU+QmxvY2tDb21wcmVzc1dyaXRlcjwvY29kZT4gOiBCbG9jay1jb21wcmVzc2VkIGZpbGVzLCBib3RoIGtleXMgJiAKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgYXJlIGNvbGxlY3RlZCBpbiAnYmxvY2tzJyAKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0ZWx5IGFuZCBjb21wcmVzc2VkLiBUaGUgc2l6ZSBvZiAKKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgJ2Jsb2NrJyBpcyBjb25maWd1cmFibGUuCisgKiA8L29sPgorICogCisgKiA8cD5UaGUgYWN0dWFsIGNvbXByZXNzaW9uIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIGtleSBhbmQvb3IgdmFsdWVzIGNhbiBiZQorICogc3BlY2lmaWVkIGJ5IHVzaW5nIHRoZSBhcHByb3ByaWF0ZSB7QGxpbmsgQ29tcHJlc3Npb25Db2RlY30uPC9wPgorICogCisgKiA8cD5UaGUgcmVjb21tZW5kZWQgd2F5IGlzIHRvIHVzZSB0aGUgc3RhdGljIDx0dD5jcmVhdGVXcml0ZXI8L3R0PiBtZXRob2RzCisgKiBwcm92aWRlZCBieSB0aGUgPGNvZGU+U2VxdWVuY2VGaWxlPC9jb2RlPiB0byBjaG9zZSB0aGUgcHJlZmVycmVkIGZvcm1hdC48L3A+CisgKgorICogPHA+VGhlIHtAbGluayBSZWFkZXJ9IGFjdHMgYXMgdGhlIGJyaWRnZSBhbmQgY2FuIHJlYWQgYW55IG9mIHRoZSBhYm92ZSAKKyAqIDxjb2RlPlNlcXVlbmNlRmlsZTwvY29kZT4gZm9ybWF0cy48L3A+CisgKgorICogPGg0IGlkPSJGb3JtYXRzIj5TZXF1ZW5jZUZpbGUgRm9ybWF0czwvaDQ+CisgKiAKKyAqIDxwPkVzc2VudGlhbGx5IHRoZXJlIGFyZSAzIGRpZmZlcmVudCBmb3JtYXRzIGZvciA8Y29kZT5TZXF1ZW5jZUZpbGU8L2NvZGU+cworICogZGVwZW5kaW5nIG9uIHRoZSA8Y29kZT5Db21wcmVzc2lvblR5cGU8L2NvZGU+IHNwZWNpZmllZC4gQWxsIG9mIHRoZW0gc2hhcmUgYQorICogPGEgaHJlZj0iI0hlYWRlciI+Y29tbW9uIGhlYWRlcjwvYT4gZGVzY3JpYmVkIGJlbG93LgorICogCisgKiA8aDUgaWQ9IkhlYWRlciI+U2VxdWVuY2VGaWxlIEhlYWRlcjwvaDU+CisgKiA8dWw+CisgKiAgIDxsaT4KKyAqICAgdmVyc2lvbiAtIDMgYnl0ZXMgb2YgbWFnaWMgaGVhZGVyIDxiPlNFUTwvYj4sIGZvbGxvd2VkIGJ5IDEgYnl0ZSBvZiBhY3R1YWwgCisgKiAgICAgICAgICAgICB2ZXJzaW9uIG51bWJlciAoZS5nLiBTRVE0IG9yIFNFUTYpCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAga2V5Q2xhc3NOYW1lIC1rZXkgY2xhc3MKKyAqICAgPC9saT4KKyAqICAgPGxpPgorICogICB2YWx1ZUNsYXNzTmFtZSAtIHZhbHVlIGNsYXNzCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgY29tcHJlc3Npb24gLSBBIGJvb2xlYW4gd2hpY2ggc3BlY2lmaWVzIGlmIGNvbXByZXNzaW9uIGlzIHR1cm5lZCBvbiBmb3IgCisgKiAgICAgICAgICAgICAgICAga2V5cy92YWx1ZXMgaW4gdGhpcyBmaWxlLgorICogICA8L2xpPgorICogICA8bGk+CisgKiAgIGJsb2NrQ29tcHJlc3Npb24gLSBBIGJvb2xlYW4gd2hpY2ggc3BlY2lmaWVzIGlmIGJsb2NrLWNvbXByZXNzaW9uIGlzIAorICogICAgICAgICAgICAgICAgICAgICAgdHVybmVkIG9uIGZvciBrZXlzL3ZhbHVlcyBpbiB0aGlzIGZpbGUuCisgKiAgIDwvbGk+CisgKiAgIDxsaT4KKyAqICAgY29tcHJlc3Npb24gY29kZWMgLSA8Y29kZT5Db21wcmVzc2lvbkNvZGVjPC9jb2RlPiBjbGFzcyB3aGljaCBpcyB1c2VkIGZvciAgCisgKiAgICAgICAgICAgICAgICAgICAgICAgY29tcHJlc3Npb24gb2Yga2V5cyBhbmQvb3IgdmFsdWVzIChpZiBjb21wcmVzc2lvbiBpcyAKKyAqICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkKS4KKyAqICAgPC9saT4KKyAqICAgPGxpPgorICogICBtZXRhZGF0YSAtIHtAbGluayBNZXRhZGF0YX0gZm9yIHRoaXMgZmlsZS4KKyAqICAgPC9saT4KKyAqICAgPGxpPgorICogICBzeW5jIC0gQSBzeW5jIG1hcmtlciB0byBkZW5vdGUgZW5kIG9mIHRoZSBoZWFkZXIuCisgKiAgIDwvbGk+CisgKiA8L3VsPgorICogCisgKiA8aDUgaWQ9IiNVbmNvbXByZXNzZWRGb3JtYXQiPlVuY29tcHJlc3NlZCBTZXF1ZW5jZUZpbGUgRm9ybWF0PC9oNT4KKyAqIDx1bD4KKyAqIDxsaT4KKyAqIDxhIGhyZWY9IiNIZWFkZXIiPkhlYWRlcjwvYT4KKyAqIDwvbGk+CisgKiA8bGk+CisgKiBSZWNvcmQKKyAqICAgPHVsPgorICogICAgIDxsaT5SZWNvcmQgbGVuZ3RoPC9saT4KKyAqICAgICA8bGk+S2V5IGxlbmd0aDwvbGk+CisgKiAgICAgPGxpPktleTwvbGk+CisgKiAgICAgPGxpPlZhbHVlPC9saT4KKyAqICAgPC91bD4KKyAqIDwvbGk+CisgKiA8bGk+CisgKiBBIHN5bmMtbWFya2VyIGV2ZXJ5IGZldyA8Y29kZT4xMDA8L2NvZGU+IGJ5dGVzIG9yIHNvLgorICogPC9saT4KKyAqIDwvdWw+CisgKgorICogPGg1IGlkPSIjUmVjb3JkQ29tcHJlc3NlZEZvcm1hdCI+UmVjb3JkLUNvbXByZXNzZWQgU2VxdWVuY2VGaWxlIEZvcm1hdDwvaDU+CisgKiA8dWw+CisgKiA8bGk+CisgKiA8YSBocmVmPSIjSGVhZGVyIj5IZWFkZXI8L2E+CisgKiA8L2xpPgorICogPGxpPgorICogUmVjb3JkCisgKiAgIDx1bD4KKyAqICAgICA8bGk+UmVjb3JkIGxlbmd0aDwvbGk+CisgKiAgICAgPGxpPktleSBsZW5ndGg8L2xpPgorICogICAgIDxsaT5LZXk8L2xpPgorICogICAgIDxsaT48aT5Db21wcmVzc2VkPC9pPiBWYWx1ZTwvbGk+CisgKiAgIDwvdWw+CisgKiA8L2xpPgorICogPGxpPgorICogQSBzeW5jLW1hcmtlciBldmVyeSBmZXcgPGNvZGU+MTAwPC9jb2RlPiBieXRlcyBvciBzby4KKyAqIDwvbGk+CisgKiA8L3VsPgorICogCisgKiA8aDUgaWQ9IiNCbG9ja0NvbXByZXNzZWRGb3JtYXQiPkJsb2NrLUNvbXByZXNzZWQgU2VxdWVuY2VGaWxlIEZvcm1hdDwvaDU+CisgKiA8dWw+CisgKiA8bGk+CisgKiA8YSBocmVmPSIjSGVhZGVyIj5IZWFkZXI8L2E+CisgKiA8L2xpPgorICogPGxpPgorICogUmVjb3JkIDxpPkJsb2NrPC9pPgorICogICA8dWw+CisgKiAgICAgPGxpPkNvbXByZXNzZWQga2V5LWxlbmd0aHMgYmxvY2stc2l6ZTwvbGk+CisgKiAgICAgPGxpPkNvbXByZXNzZWQga2V5LWxlbmd0aHMgYmxvY2s8L2xpPgorICogICAgIDxsaT5Db21wcmVzc2VkIGtleXMgYmxvY2stc2l6ZTwvbGk+CisgKiAgICAgPGxpPkNvbXByZXNzZWQga2V5cyBibG9jazwvbGk+CisgKiAgICAgPGxpPkNvbXByZXNzZWQgdmFsdWUtbGVuZ3RocyBibG9jay1zaXplPC9saT4KKyAqICAgICA8bGk+Q29tcHJlc3NlZCB2YWx1ZS1sZW5ndGhzIGJsb2NrPC9saT4KKyAqICAgICA8bGk+Q29tcHJlc3NlZCB2YWx1ZXMgYmxvY2stc2l6ZTwvbGk+CisgKiAgICAgPGxpPkNvbXByZXNzZWQgdmFsdWVzIGJsb2NrPC9saT4KKyAqICAgPC91bD4KKyAqIDwvbGk+CisgKiA8bGk+CisgKiBBIHN5bmMtbWFya2VyIGV2ZXJ5IGZldyA8Y29kZT4xMDA8L2NvZGU+IGJ5dGVzIG9yIHNvLgorICogPC9saT4KKyAqIDwvdWw+CisgKiAKKyAqIDxwPlRoZSBjb21wcmVzc2VkIGJsb2NrcyBvZiBrZXkgbGVuZ3RocyBhbmQgdmFsdWUgbGVuZ3RocyBjb25zaXN0IG9mIHRoZSAKKyAqIGFjdHVhbCBsZW5ndGhzIG9mIGluZGl2aWR1YWwga2V5cy92YWx1ZXMgZW5jb2RlZCBpbiBaZXJvQ29tcHJlc3NlZEludGVnZXIgCisgKiBmb3JtYXQuPC9wPgorICogCisgKiBAc2VlIENvbXByZXNzaW9uQ29kZWMKKyAqLworcHVibGljIGNsYXNzIFNlcXVlbmNlRmlsZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhTZXF1ZW5jZUZpbGUuY2xhc3MpOworCisgIHByaXZhdGUgU2VxdWVuY2VGaWxlKCkge30gICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gcHVibGljIGN0b3IKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIEJMT0NLX0NPTVBSRVNTX1ZFUlNJT04gPSAoYnl0ZSk0OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIENVU1RPTV9DT01QUkVTU19WRVJTSU9OID0gKGJ5dGUpNTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBWRVJTSU9OX1dJVEhfTUVUQURBVEEgPSAoYnl0ZSk2OworICBwcm90ZWN0ZWQgc3RhdGljIGJ5dGVbXSBWRVJTSU9OID0gbmV3IGJ5dGVbXSB7CisgICAgKGJ5dGUpJ1MnLCAoYnl0ZSknRScsIChieXRlKSdRJywgVkVSU0lPTl9XSVRIX01FVEFEQVRBCisgIH07CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNZTkNfRVNDQVBFID0gLTE7ICAgICAgLy8gImxlbmd0aCIgb2Ygc3luYyBlbnRyaWVzCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTWU5DX0hBU0hfU0laRSA9IDE2OyAgIC8vIG51bWJlciBvZiBieXRlcyBpbiBoYXNoIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1lOQ19TSVpFID0gNCtTWU5DX0hBU0hfU0laRTsgLy8gZXNjYXBlICsgaGFzaAorCisgIC8qKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGJldHdlZW4gc3luYyBwb2ludHMuKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1lOQ19JTlRFUlZBTCA9IDEwMCpTWU5DX1NJWkU7IAorCisgIC8qKiAKKyAgICogVGhlIGNvbXByZXNzaW9uIHR5cGUgdXNlZCB0byBjb21wcmVzcyBrZXkvdmFsdWUgcGFpcnMgaW4gdGhlIAorICAgKiB7QGxpbmsgU2VxdWVuY2VGaWxlfS4KKyAgICogCisgICAqIEBzZWUgU2VxdWVuY2VGaWxlLldyaXRlcgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBlbnVtIENvbXByZXNzaW9uVHlwZSB7CisgICAgLyoqIERvIG5vdCBjb21wcmVzcyByZWNvcmRzLiAqLworICAgIE5PTkUsIAorICAgIC8qKiBDb21wcmVzcyB2YWx1ZXMgb25seSwgZWFjaCBzZXBhcmF0ZWx5LiAqLworICAgIFJFQ09SRCwKKyAgICAvKiogQ29tcHJlc3Mgc2VxdWVuY2VzIG9mIHJlY29yZHMgdG9nZXRoZXIgaW4gYmxvY2tzLiAqLworICAgIEJMT0NLCisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBjb21wcmVzc2lvbiB0eXBlIGZvciB0aGUgcmVkdWNlIG91dHB1dHMKKyAgICogQHBhcmFtIGpvYiB0aGUgam9iIGNvbmZpZyB0byBsb29rIGluCisgICAqIEByZXR1cm4gdGhlIGtpbmQgb2YgY29tcHJlc3Npb24gdG8gdXNlCisgICAqIEBkZXByZWNhdGVkIFVzZSAKKyAgICogICAgICAgICAgICAge0BsaW5rIG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5TZXF1ZW5jZUZpbGVPdXRwdXRGb3JtYXQjZ2V0T3V0cHV0Q29tcHJlc3Npb25UeXBlKG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDb25mKX0gCisgICAqICAgICAgICAgICAgIHRvIGdldCB7QGxpbmsgQ29tcHJlc3Npb25UeXBlfSBmb3Igam9iLW91dHB1dHMuCisgICAqLworICBARGVwcmVjYXRlZAorICBzdGF0aWMgcHVibGljIENvbXByZXNzaW9uVHlwZSBnZXRDb21wcmVzc2lvblR5cGUoQ29uZmlndXJhdGlvbiBqb2IpIHsKKyAgICBTdHJpbmcgbmFtZSA9IGpvYi5nZXQoImlvLnNlcWZpbGUuY29tcHJlc3Npb24udHlwZSIpOworICAgIHJldHVybiBuYW1lID09IG51bGwgPyBDb21wcmVzc2lvblR5cGUuUkVDT1JEIDogCisgICAgICBDb21wcmVzc2lvblR5cGUudmFsdWVPZihuYW1lKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFNldCB0aGUgY29tcHJlc3Npb24gdHlwZSBmb3Igc2VxdWVuY2UgZmlsZXMuCisgICAqIEBwYXJhbSBqb2IgdGhlIGNvbmZpZ3VyYXRpb24gdG8gbW9kaWZ5CisgICAqIEBwYXJhbSB2YWwgdGhlIG5ldyBjb21wcmVzc2lvbiB0eXBlIChub25lLCBibG9jaywgcmVjb3JkKQorICAgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIG9uZSBvZiB0aGUgbWFueSBTZXF1ZW5jZUZpbGUuY3JlYXRlV3JpdGVyIG1ldGhvZHMgdG8gc3BlY2lmeQorICAgKiAgICAgICAgICAgICB0aGUge0BsaW5rIENvbXByZXNzaW9uVHlwZX0gd2hpbGUgY3JlYXRpbmcgdGhlIHtAbGluayBTZXF1ZW5jZUZpbGV9IG9yCisgICAqICAgICAgICAgICAgIHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuU2VxdWVuY2VGaWxlT3V0cHV0Rm9ybWF0I3NldE91dHB1dENvbXByZXNzaW9uVHlwZShvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ29uZiwgb3JnLmFwYWNoZS5oYWRvb3AuaW8uU2VxdWVuY2VGaWxlLkNvbXByZXNzaW9uVHlwZSl9CisgICAqICAgICAgICAgICAgIHRvIHNwZWNpZnkgdGhlIHtAbGluayBDb21wcmVzc2lvblR5cGV9IGZvciBqb2Itb3V0cHV0cy4gCisgICAqIG9yIAorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgc3RhdGljIHB1YmxpYyB2b2lkIHNldENvbXByZXNzaW9uVHlwZShDb25maWd1cmF0aW9uIGpvYiwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25UeXBlIHZhbCkgeworICAgIGpvYi5zZXQoImlvLnNlcWZpbGUuY29tcHJlc3Npb24udHlwZSIsIHZhbC50b1N0cmluZygpKTsKKyAgfQorICAgIAorICAvKioKKyAgICogQ29uc3RydWN0IHRoZSBwcmVmZXJyZWQgdHlwZSBvZiBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAcGFyYW0gZnMgVGhlIGNvbmZpZ3VyZWQgZmlsZXN5c3RlbS4gCisgICAqIEBwYXJhbSBjb25mIFRoZSBjb25maWd1cmF0aW9uLgorICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmlsZS4gCisgICAqIEBwYXJhbSBrZXlDbGFzcyBUaGUgJ2tleScgdHlwZS4KKyAgICogQHBhcmFtIHZhbENsYXNzIFRoZSAndmFsdWUnIHR5cGUuCisgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgaGFuZGxlIHRvIHRoZSBjb25zdHJ1Y3RlZCBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIFdyaXRlciAKKyAgICBjcmVhdGVXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsIAorICAgICAgICAgICAgICAgICBDbGFzcyBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MpIAorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNyZWF0ZVdyaXRlcihmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29tcHJlc3Npb25UeXBlKGNvbmYpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgcHJlZmVycmVkIHR5cGUgb2YgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHBhcmFtIGZzIFRoZSBjb25maWd1cmVkIGZpbGVzeXN0ZW0uIAorICAgKiBAcGFyYW0gY29uZiBUaGUgY29uZmlndXJhdGlvbi4KKyAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpbGUuIAorICAgKiBAcGFyYW0ga2V5Q2xhc3MgVGhlICdrZXknIHR5cGUuCisgICAqIEBwYXJhbSB2YWxDbGFzcyBUaGUgJ3ZhbHVlJyB0eXBlLgorICAgKiBAcGFyYW0gY29tcHJlc3Npb25UeXBlIFRoZSBjb21wcmVzc2lvbiB0eXBlLgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGhhbmRsZSB0byB0aGUgY29uc3RydWN0ZWQgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0ZXIgCisgICAgY3JlYXRlV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCBDb21wcmVzc2lvblR5cGUgY29tcHJlc3Npb25UeXBlKSAKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjcmVhdGVXcml0ZXIoZnMsIGNvbmYsIG5hbWUsIGtleUNsYXNzLCB2YWxDbGFzcywKKyAgICAgICAgICAgIGZzLmdldENvbmYoKS5nZXRJbnQoImlvLmZpbGUuYnVmZmVyLnNpemUiLCA0MDk2KSwKKyAgICAgICAgICAgIGZzLmdldERlZmF1bHRSZXBsaWNhdGlvbigpLCBmcy5nZXREZWZhdWx0QmxvY2tTaXplKCksCisgICAgICAgICAgICBjb21wcmVzc2lvblR5cGUsIG5ldyBEZWZhdWx0Q29kZWMoKSwgbnVsbCwgbmV3IE1ldGFkYXRhKCkpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0IHRoZSBwcmVmZXJyZWQgdHlwZSBvZiBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAcGFyYW0gZnMgVGhlIGNvbmZpZ3VyZWQgZmlsZXN5c3RlbS4gCisgICAqIEBwYXJhbSBjb25mIFRoZSBjb25maWd1cmF0aW9uLgorICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmlsZS4gCisgICAqIEBwYXJhbSBrZXlDbGFzcyBUaGUgJ2tleScgdHlwZS4KKyAgICogQHBhcmFtIHZhbENsYXNzIFRoZSAndmFsdWUnIHR5cGUuCisgICAqIEBwYXJhbSBjb21wcmVzc2lvblR5cGUgVGhlIGNvbXByZXNzaW9uIHR5cGUuCisgICAqIEBwYXJhbSBwcm9ncmVzcyBUaGUgUHJvZ3Jlc3NhYmxlIG9iamVjdCB0byB0cmFjayBwcm9ncmVzcy4KKyAgICogQHJldHVybiBSZXR1cm5zIHRoZSBoYW5kbGUgdG8gdGhlIGNvbnN0cnVjdGVkIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgV3JpdGVyCisgICAgY3JlYXRlV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCBDb21wcmVzc2lvblR5cGUgY29tcHJlc3Npb25UeXBlLAorICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNyZWF0ZVdyaXRlcihmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLAorICAgICAgICAgICAgZnMuZ2V0Q29uZigpLmdldEludCgiaW8uZmlsZS5idWZmZXIuc2l6ZSIsIDQwOTYpLAorICAgICAgICAgICAgZnMuZ2V0RGVmYXVsdFJlcGxpY2F0aW9uKCksIGZzLmdldERlZmF1bHRCbG9ja1NpemUoKSwKKyAgICAgICAgICAgIGNvbXByZXNzaW9uVHlwZSwgbmV3IERlZmF1bHRDb2RlYygpLCBwcm9ncmVzcywgbmV3IE1ldGFkYXRhKCkpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgcHJlZmVycmVkIHR5cGUgb2YgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHBhcmFtIGZzIFRoZSBjb25maWd1cmVkIGZpbGVzeXN0ZW0uIAorICAgKiBAcGFyYW0gY29uZiBUaGUgY29uZmlndXJhdGlvbi4KKyAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpbGUuIAorICAgKiBAcGFyYW0ga2V5Q2xhc3MgVGhlICdrZXknIHR5cGUuCisgICAqIEBwYXJhbSB2YWxDbGFzcyBUaGUgJ3ZhbHVlJyB0eXBlLgorICAgKiBAcGFyYW0gY29tcHJlc3Npb25UeXBlIFRoZSBjb21wcmVzc2lvbiB0eXBlLgorICAgKiBAcGFyYW0gY29kZWMgVGhlIGNvbXByZXNzaW9uIGNvZGVjLgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGhhbmRsZSB0byB0aGUgY29uc3RydWN0ZWQgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0ZXIgCisgICAgY3JlYXRlV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCAKKyAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25UeXBlIGNvbXByZXNzaW9uVHlwZSwgQ29tcHJlc3Npb25Db2RlYyBjb2RlYykgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY3JlYXRlV3JpdGVyKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsCisgICAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgICBmcy5nZXREZWZhdWx0UmVwbGljYXRpb24oKSwgZnMuZ2V0RGVmYXVsdEJsb2NrU2l6ZSgpLAorICAgICAgICAgICAgY29tcHJlc3Npb25UeXBlLCBjb2RlYywgbnVsbCwgbmV3IE1ldGFkYXRhKCkpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0IHRoZSBwcmVmZXJyZWQgdHlwZSBvZiBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAcGFyYW0gZnMgVGhlIGNvbmZpZ3VyZWQgZmlsZXN5c3RlbS4gCisgICAqIEBwYXJhbSBjb25mIFRoZSBjb25maWd1cmF0aW9uLgorICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmlsZS4gCisgICAqIEBwYXJhbSBrZXlDbGFzcyBUaGUgJ2tleScgdHlwZS4KKyAgICogQHBhcmFtIHZhbENsYXNzIFRoZSAndmFsdWUnIHR5cGUuCisgICAqIEBwYXJhbSBjb21wcmVzc2lvblR5cGUgVGhlIGNvbXByZXNzaW9uIHR5cGUuCisgICAqIEBwYXJhbSBjb2RlYyBUaGUgY29tcHJlc3Npb24gY29kZWMuCisgICAqIEBwYXJhbSBwcm9ncmVzcyBUaGUgUHJvZ3Jlc3NhYmxlIG9iamVjdCB0byB0cmFjayBwcm9ncmVzcy4KKyAgICogQHBhcmFtIG1ldGFkYXRhIFRoZSBtZXRhZGF0YSBvZiB0aGUgZmlsZS4KKyAgICogQHJldHVybiBSZXR1cm5zIHRoZSBoYW5kbGUgdG8gdGhlIGNvbnN0cnVjdGVkIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgV3JpdGVyCisgICAgY3JlYXRlV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCAKKyAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25UeXBlIGNvbXByZXNzaW9uVHlwZSwgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywKKyAgICAgICAgICAgICAgICAgUHJvZ3Jlc3NhYmxlIHByb2dyZXNzLCBNZXRhZGF0YSBtZXRhZGF0YSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gY3JlYXRlV3JpdGVyKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsCisgICAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgICBmcy5nZXREZWZhdWx0UmVwbGljYXRpb24oKSwgZnMuZ2V0RGVmYXVsdEJsb2NrU2l6ZSgpLAorICAgICAgICAgICAgY29tcHJlc3Npb25UeXBlLCBjb2RlYywgcHJvZ3Jlc3MsIG1ldGFkYXRhKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgdGhlIHByZWZlcnJlZCB0eXBlIG9mIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEBwYXJhbSBmcyBUaGUgY29uZmlndXJlZCBmaWxlc3lzdGVtLgorICAgKiBAcGFyYW0gY29uZiBUaGUgY29uZmlndXJhdGlvbi4KKyAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpbGUuCisgICAqIEBwYXJhbSBrZXlDbGFzcyBUaGUgJ2tleScgdHlwZS4KKyAgICogQHBhcmFtIHZhbENsYXNzIFRoZSAndmFsdWUnIHR5cGUuCisgICAqIEBwYXJhbSBidWZmZXJTaXplIGJ1ZmZlciBzaXplIGZvciB0aGUgdW5kZXJsYXlpbmcgb3V0cHV0c3RyZWFtLgorICAgKiBAcGFyYW0gcmVwbGljYXRpb24gcmVwbGljYXRpb24gZmFjdG9yIGZvciB0aGUgZmlsZS4KKyAgICogQHBhcmFtIGJsb2NrU2l6ZSBibG9jayBzaXplIGZvciB0aGUgZmlsZS4KKyAgICogQHBhcmFtIGNvbXByZXNzaW9uVHlwZSBUaGUgY29tcHJlc3Npb24gdHlwZS4KKyAgICogQHBhcmFtIGNvZGVjIFRoZSBjb21wcmVzc2lvbiBjb2RlYy4KKyAgICogQHBhcmFtIHByb2dyZXNzIFRoZSBQcm9ncmVzc2FibGUgb2JqZWN0IHRvIHRyYWNrIHByb2dyZXNzLgorICAgKiBAcGFyYW0gbWV0YWRhdGEgVGhlIG1ldGFkYXRhIG9mIHRoZSBmaWxlLgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGhhbmRsZSB0byB0aGUgY29uc3RydWN0ZWQgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0ZXIKKyAgICBjcmVhdGVXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsCisgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgaW50IGJ1ZmZlclNpemUsCisgICAgICAgICAgICAgICAgIHNob3J0IHJlcGxpY2F0aW9uLCBsb25nIGJsb2NrU2l6ZSwKKyAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25UeXBlIGNvbXByZXNzaW9uVHlwZSwgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywKKyAgICAgICAgICAgICAgICAgUHJvZ3Jlc3NhYmxlIHByb2dyZXNzLCBNZXRhZGF0YSBtZXRhZGF0YSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoKGNvZGVjIGluc3RhbmNlb2YgR3ppcENvZGVjKSAmJgorICAgICAgICAhTmF0aXZlQ29kZUxvYWRlci5pc05hdGl2ZUNvZGVMb2FkZWQoKSAmJgorICAgICAgICAhWmxpYkZhY3RvcnkuaXNOYXRpdmVabGliTG9hZGVkKGNvbmYpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTZXF1ZW5jZUZpbGUgZG9lc24ndCB3b3JrIHdpdGggIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHemlwQ29kZWMgd2l0aG91dCBuYXRpdmUtaGFkb29wIGNvZGUhIik7CisgICAgfQorCisgICAgV3JpdGVyIHdyaXRlciA9IG51bGw7CisKKyAgICBpZiAoY29tcHJlc3Npb25UeXBlID09IENvbXByZXNzaW9uVHlwZS5OT05FKSB7CisgICAgICB3cml0ZXIgPSBuZXcgV3JpdGVyKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclNpemUsIHJlcGxpY2F0aW9uLCBibG9ja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzLCBtZXRhZGF0YSk7CisgICAgfSBlbHNlIGlmIChjb21wcmVzc2lvblR5cGUgPT0gQ29tcHJlc3Npb25UeXBlLlJFQ09SRCkgeworICAgICAgd3JpdGVyID0gbmV3IFJlY29yZENvbXByZXNzV3JpdGVyKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyU2l6ZSwgcmVwbGljYXRpb24sIGJsb2NrU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlYywgcHJvZ3Jlc3MsIG1ldGFkYXRhKTsKKyAgICB9IGVsc2UgaWYgKGNvbXByZXNzaW9uVHlwZSA9PSBDb21wcmVzc2lvblR5cGUuQkxPQ0speworICAgICAgd3JpdGVyID0gbmV3IEJsb2NrQ29tcHJlc3NXcml0ZXIoZnMsIGNvbmYsIG5hbWUsIGtleUNsYXNzLCB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclNpemUsIHJlcGxpY2F0aW9uLCBibG9ja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlYywgcHJvZ3Jlc3MsIG1ldGFkYXRhKTsKKyAgICB9CisKKyAgICByZXR1cm4gd3JpdGVyOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgcHJlZmVycmVkIHR5cGUgb2YgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHBhcmFtIGZzIFRoZSBjb25maWd1cmVkIGZpbGVzeXN0ZW0uIAorICAgKiBAcGFyYW0gY29uZiBUaGUgY29uZmlndXJhdGlvbi4KKyAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpbGUuIAorICAgKiBAcGFyYW0ga2V5Q2xhc3MgVGhlICdrZXknIHR5cGUuCisgICAqIEBwYXJhbSB2YWxDbGFzcyBUaGUgJ3ZhbHVlJyB0eXBlLgorICAgKiBAcGFyYW0gY29tcHJlc3Npb25UeXBlIFRoZSBjb21wcmVzc2lvbiB0eXBlLgorICAgKiBAcGFyYW0gY29kZWMgVGhlIGNvbXByZXNzaW9uIGNvZGVjLgorICAgKiBAcGFyYW0gcHJvZ3Jlc3MgVGhlIFByb2dyZXNzYWJsZSBvYmplY3QgdG8gdHJhY2sgcHJvZ3Jlc3MuCisgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgaGFuZGxlIHRvIHRoZSBjb25zdHJ1Y3RlZCBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIFdyaXRlcgorICAgIGNyZWF0ZVdyaXRlcihGaWxlU3lzdGVtIGZzLCBDb25maWd1cmF0aW9uIGNvbmYsIFBhdGggbmFtZSwgCisgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgCisgICAgICAgICAgICAgICAgIENvbXByZXNzaW9uVHlwZSBjb21wcmVzc2lvblR5cGUsIENvbXByZXNzaW9uQ29kZWMgY29kZWMsCisgICAgICAgICAgICAgICAgIFByb2dyZXNzYWJsZSBwcm9ncmVzcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBXcml0ZXIgd3JpdGVyID0gY3JlYXRlV3JpdGVyKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcHJlc3Npb25UeXBlLCBjb2RlYywgcHJvZ3Jlc3MsIG5ldyBNZXRhZGF0YSgpKTsKKyAgICByZXR1cm4gd3JpdGVyOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgcHJlZmVycmVkIHR5cGUgb2YgJ3JhdycgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHBhcmFtIG91dCBUaGUgc3RyZWFtIG9uIHRvcCB3aGljaCB0aGUgd3JpdGVyIGlzIHRvIGJlIGNvbnN0cnVjdGVkLgorICAgKiBAcGFyYW0ga2V5Q2xhc3MgVGhlICdrZXknIHR5cGUuCisgICAqIEBwYXJhbSB2YWxDbGFzcyBUaGUgJ3ZhbHVlJyB0eXBlLgorICAgKiBAcGFyYW0gY29tcHJlc3MgQ29tcHJlc3MgZGF0YT8KKyAgICogQHBhcmFtIGJsb2NrQ29tcHJlc3MgQ29tcHJlc3MgYmxvY2tzPworICAgKiBAcGFyYW0gbWV0YWRhdGEgVGhlIG1ldGFkYXRhIG9mIHRoZSBmaWxlLgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIGhhbmRsZSB0byB0aGUgY29uc3RydWN0ZWQgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgV3JpdGVyCisgICAgY3JlYXRlV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRlNEYXRhT3V0cHV0U3RyZWFtIG91dCwgCisgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgYm9vbGVhbiBjb21wcmVzcywgYm9vbGVhbiBibG9ja0NvbXByZXNzLAorICAgICAgICAgICAgICAgICBDb21wcmVzc2lvbkNvZGVjIGNvZGVjLCBNZXRhZGF0YSBtZXRhZGF0YSkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjb2RlYyAhPSBudWxsICYmIChjb2RlYyBpbnN0YW5jZW9mIEd6aXBDb2RlYykgJiYgCisgICAgICAgICFOYXRpdmVDb2RlTG9hZGVyLmlzTmF0aXZlQ29kZUxvYWRlZCgpICYmIAorICAgICAgICAhWmxpYkZhY3RvcnkuaXNOYXRpdmVabGliTG9hZGVkKGNvbmYpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTZXF1ZW5jZUZpbGUgZG9lc24ndCB3b3JrIHdpdGggIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHemlwQ29kZWMgd2l0aG91dCBuYXRpdmUtaGFkb29wIGNvZGUhIik7CisgICAgfQorCisgICAgV3JpdGVyIHdyaXRlciA9IG51bGw7CisKKyAgICBpZiAoIWNvbXByZXNzKSB7CisgICAgICB3cml0ZXIgPSBuZXcgV3JpdGVyKGNvbmYsIG91dCwga2V5Q2xhc3MsIHZhbENsYXNzLCBtZXRhZGF0YSk7CisgICAgfSBlbHNlIGlmIChjb21wcmVzcyAmJiAhYmxvY2tDb21wcmVzcykgeworICAgICAgd3JpdGVyID0gbmV3IFJlY29yZENvbXByZXNzV3JpdGVyKGNvbmYsIG91dCwga2V5Q2xhc3MsIHZhbENsYXNzLCBjb2RlYywgbWV0YWRhdGEpOworICAgIH0gZWxzZSB7CisgICAgICB3cml0ZXIgPSBuZXcgQmxvY2tDb21wcmVzc1dyaXRlcihjb25mLCBvdXQsIGtleUNsYXNzLCB2YWxDbGFzcywgY29kZWMsIG1ldGFkYXRhKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHdyaXRlcjsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgdGhlIHByZWZlcnJlZCB0eXBlIG9mICdyYXcnIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEBwYXJhbSBmcyBUaGUgY29uZmlndXJlZCBmaWxlc3lzdGVtLiAKKyAgICogQHBhcmFtIGNvbmYgVGhlIGNvbmZpZ3VyYXRpb24uCisgICAqIEBwYXJhbSBmaWxlIFRoZSBuYW1lIG9mIHRoZSBmaWxlLiAKKyAgICogQHBhcmFtIGtleUNsYXNzIFRoZSAna2V5JyB0eXBlLgorICAgKiBAcGFyYW0gdmFsQ2xhc3MgVGhlICd2YWx1ZScgdHlwZS4KKyAgICogQHBhcmFtIGNvbXByZXNzIENvbXByZXNzIGRhdGE/CisgICAqIEBwYXJhbSBibG9ja0NvbXByZXNzIENvbXByZXNzIGJsb2Nrcz8KKyAgICogQHBhcmFtIGNvZGVjIFRoZSBjb21wcmVzc2lvbiBjb2RlYy4KKyAgICogQHBhcmFtIHByb2dyZXNzCisgICAqIEBwYXJhbSBtZXRhZGF0YSBUaGUgbWV0YWRhdGEgb2YgdGhlIGZpbGUuCisgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgaGFuZGxlIHRvIHRoZSBjb25zdHJ1Y3RlZCBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHN0YXRpYyBXcml0ZXIKKyAgY3JlYXRlV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBmaWxlLCAKKyAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgCisgICAgICAgICAgICAgICBib29sZWFuIGNvbXByZXNzLCBib29sZWFuIGJsb2NrQ29tcHJlc3MsCisgICAgICAgICAgICAgICBDb21wcmVzc2lvbkNvZGVjIGNvZGVjLCBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MsIE1ldGFkYXRhIG1ldGFkYXRhKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICBpZiAoY29kZWMgIT0gbnVsbCAmJiAoY29kZWMgaW5zdGFuY2VvZiBHemlwQ29kZWMpICYmIAorICAgICAgIU5hdGl2ZUNvZGVMb2FkZXIuaXNOYXRpdmVDb2RlTG9hZGVkKCkgJiYgCisgICAgICAhWmxpYkZhY3RvcnkuaXNOYXRpdmVabGliTG9hZGVkKGNvbmYpKSB7CisgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiU2VxdWVuY2VGaWxlIGRvZXNuJ3Qgd29yayB3aXRoICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkd6aXBDb2RlYyB3aXRob3V0IG5hdGl2ZS1oYWRvb3AgY29kZSEiKTsKKyAgfQorCisgIFdyaXRlciB3cml0ZXIgPSBudWxsOworCisgIGlmICghY29tcHJlc3MpIHsKKyAgICB3cml0ZXIgPSBuZXcgV3JpdGVyKGZzLCBjb25mLCBmaWxlLCBrZXlDbGFzcywgdmFsQ2xhc3MsIHByb2dyZXNzLCBtZXRhZGF0YSk7CisgIH0gZWxzZSBpZiAoY29tcHJlc3MgJiYgIWJsb2NrQ29tcHJlc3MpIHsKKyAgICB3cml0ZXIgPSBuZXcgUmVjb3JkQ29tcHJlc3NXcml0ZXIoZnMsIGNvbmYsIGZpbGUsIGtleUNsYXNzLCB2YWxDbGFzcywgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVjLCBwcm9ncmVzcywgbWV0YWRhdGEpOworICB9IGVsc2UgeworICAgIHdyaXRlciA9IG5ldyBCbG9ja0NvbXByZXNzV3JpdGVyKGZzLCBjb25mLCBmaWxlLCBrZXlDbGFzcywgdmFsQ2xhc3MsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVjLCBwcm9ncmVzcywgbWV0YWRhdGEpOworICB9CisgIAorICByZXR1cm4gd3JpdGVyOworfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgdGhlIHByZWZlcnJlZCB0eXBlIG9mICdyYXcnIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEBwYXJhbSBjb25mIFRoZSBjb25maWd1cmF0aW9uLgorICAgKiBAcGFyYW0gb3V0IFRoZSBzdHJlYW0gb24gdG9wIHdoaWNoIHRoZSB3cml0ZXIgaXMgdG8gYmUgY29uc3RydWN0ZWQuCisgICAqIEBwYXJhbSBrZXlDbGFzcyBUaGUgJ2tleScgdHlwZS4KKyAgICogQHBhcmFtIHZhbENsYXNzIFRoZSAndmFsdWUnIHR5cGUuCisgICAqIEBwYXJhbSBjb21wcmVzc2lvblR5cGUgVGhlIGNvbXByZXNzaW9uIHR5cGUuCisgICAqIEBwYXJhbSBjb2RlYyBUaGUgY29tcHJlc3Npb24gY29kZWMuCisgICAqIEBwYXJhbSBtZXRhZGF0YSBUaGUgbWV0YWRhdGEgb2YgdGhlIGZpbGUuCisgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgaGFuZGxlIHRvIHRoZSBjb25zdHJ1Y3RlZCBTZXF1ZW5jZUZpbGUgV3JpdGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIFdyaXRlcgorICAgIGNyZWF0ZVdyaXRlcihDb25maWd1cmF0aW9uIGNvbmYsIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQsIAorICAgICAgICAgICAgICAgICBDbGFzcyBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MsIENvbXByZXNzaW9uVHlwZSBjb21wcmVzc2lvblR5cGUsCisgICAgICAgICAgICAgICAgIENvbXByZXNzaW9uQ29kZWMgY29kZWMsIE1ldGFkYXRhIG1ldGFkYXRhKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKChjb2RlYyBpbnN0YW5jZW9mIEd6aXBDb2RlYykgJiYgCisgICAgICAgICFOYXRpdmVDb2RlTG9hZGVyLmlzTmF0aXZlQ29kZUxvYWRlZCgpICYmIAorICAgICAgICAhWmxpYkZhY3RvcnkuaXNOYXRpdmVabGliTG9hZGVkKGNvbmYpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJTZXF1ZW5jZUZpbGUgZG9lc24ndCB3b3JrIHdpdGggIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHemlwQ29kZWMgd2l0aG91dCBuYXRpdmUtaGFkb29wIGNvZGUhIik7CisgICAgfQorCisgICAgV3JpdGVyIHdyaXRlciA9IG51bGw7CisKKyAgICBpZiAoY29tcHJlc3Npb25UeXBlID09IENvbXByZXNzaW9uVHlwZS5OT05FKSB7CisgICAgICB3cml0ZXIgPSBuZXcgV3JpdGVyKGNvbmYsIG91dCwga2V5Q2xhc3MsIHZhbENsYXNzLCBtZXRhZGF0YSk7CisgICAgfSBlbHNlIGlmIChjb21wcmVzc2lvblR5cGUgPT0gQ29tcHJlc3Npb25UeXBlLlJFQ09SRCkgeworICAgICAgd3JpdGVyID0gbmV3IFJlY29yZENvbXByZXNzV3JpdGVyKGNvbmYsIG91dCwga2V5Q2xhc3MsIHZhbENsYXNzLCBjb2RlYywgbWV0YWRhdGEpOworICAgIH0gZWxzZSBpZiAoY29tcHJlc3Npb25UeXBlID09IENvbXByZXNzaW9uVHlwZS5CTE9DSyl7CisgICAgICB3cml0ZXIgPSBuZXcgQmxvY2tDb21wcmVzc1dyaXRlcihjb25mLCBvdXQsIGtleUNsYXNzLCB2YWxDbGFzcywgY29kZWMsIG1ldGFkYXRhKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIHdyaXRlcjsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgcHJlZmVycmVkIHR5cGUgb2YgJ3JhdycgU2VxdWVuY2VGaWxlIFdyaXRlci4KKyAgICogQHBhcmFtIGNvbmYgVGhlIGNvbmZpZ3VyYXRpb24uCisgICAqIEBwYXJhbSBvdXQgVGhlIHN0cmVhbSBvbiB0b3Agd2hpY2ggdGhlIHdyaXRlciBpcyB0byBiZSBjb25zdHJ1Y3RlZC4KKyAgICogQHBhcmFtIGtleUNsYXNzIFRoZSAna2V5JyB0eXBlLgorICAgKiBAcGFyYW0gdmFsQ2xhc3MgVGhlICd2YWx1ZScgdHlwZS4KKyAgICogQHBhcmFtIGNvbXByZXNzaW9uVHlwZSBUaGUgY29tcHJlc3Npb24gdHlwZS4KKyAgICogQHBhcmFtIGNvZGVjIFRoZSBjb21wcmVzc2lvbiBjb2RlYy4KKyAgICogQHJldHVybiBSZXR1cm5zIHRoZSBoYW5kbGUgdG8gdGhlIGNvbnN0cnVjdGVkIFNlcXVlbmNlRmlsZSBXcml0ZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgV3JpdGVyCisgICAgY3JlYXRlV3JpdGVyKENvbmZpZ3VyYXRpb24gY29uZiwgRlNEYXRhT3V0cHV0U3RyZWFtIG91dCwgCisgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25UeXBlIGNvbXByZXNzaW9uVHlwZSwKKyAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25Db2RlYyBjb2RlYykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFdyaXRlciB3cml0ZXIgPSBjcmVhdGVXcml0ZXIoY29uZiwgb3V0LCBrZXlDbGFzcywgdmFsQ2xhc3MsIGNvbXByZXNzaW9uVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVjLCBuZXcgTWV0YWRhdGEoKSk7CisgICAgcmV0dXJuIHdyaXRlcjsKKyAgfQorICAKKworICAvKiogVGhlIGludGVyZmFjZSB0byAncmF3JyB2YWx1ZXMgb2YgU2VxdWVuY2VGaWxlcy4gKi8KKyAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgVmFsdWVCeXRlcyB7CisKKyAgICAvKiogV3JpdGVzIHRoZSB1bmNvbXByZXNzZWQgYnl0ZXMgdG8gdGhlIG91dFN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb3V0U3RyZWFtIDogU3RyZWFtIHRvIHdyaXRlIHVuY29tcHJlc3NlZCBieXRlcyBpbnRvLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB3cml0ZVVuY29tcHJlc3NlZEJ5dGVzKERhdGFPdXRwdXRTdHJlYW0gb3V0U3RyZWFtKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgICAgLyoqIFdyaXRlIGNvbXByZXNzZWQgYnl0ZXMgdG8gb3V0U3RyZWFtLiAKKyAgICAgKiBOb3RlOiB0aGF0IGl0IHdpbGwgTk9UIGNvbXByZXNzIHRoZSBieXRlcyBpZiB0aGV5IGFyZSBub3QgY29tcHJlc3NlZC4KKyAgICAgKiBAcGFyYW0gb3V0U3RyZWFtIDogU3RyZWFtIHRvIHdyaXRlIGNvbXByZXNzZWQgYnl0ZXMgaW50by4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHdyaXRlQ29tcHJlc3NlZEJ5dGVzKERhdGFPdXRwdXRTdHJlYW0gb3V0U3RyZWFtKSAKKyAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElPRXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogU2l6ZSBvZiBzdG9yZWQgZGF0YS4KKyAgICAgKiBAcmV0dXJuIGludAorICAgICAqLworICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbmNvbXByZXNzZWRCeXRlcyBpbXBsZW1lbnRzIFZhbHVlQnl0ZXMgeworICAgIHByaXZhdGUgaW50IGRhdGFTaXplOworICAgIHByaXZhdGUgYnl0ZVtdIGRhdGE7CisgICAgCisgICAgcHJpdmF0ZSBVbmNvbXByZXNzZWRCeXRlcygpIHsKKyAgICAgIGRhdGEgPSBudWxsOworICAgICAgZGF0YVNpemUgPSAwOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHZvaWQgcmVzZXQoRGF0YUlucHV0U3RyZWFtIGluLCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgZGF0YSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgICBkYXRhU2l6ZSA9IC0xOworICAgICAgCisgICAgICBpbi5yZWFkRnVsbHkoZGF0YSk7CisgICAgICBkYXRhU2l6ZSA9IGRhdGEubGVuZ3RoOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgaW50IGdldFNpemUoKSB7CisgICAgICByZXR1cm4gZGF0YVNpemU7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIHdyaXRlVW5jb21wcmVzc2VkQnl0ZXMoRGF0YU91dHB1dFN0cmVhbSBvdXRTdHJlYW0pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgb3V0U3RyZWFtLndyaXRlKGRhdGEsIDAsIGRhdGFTaXplKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZUNvbXByZXNzZWRCeXRlcyhEYXRhT3V0cHV0U3RyZWFtIG91dFN0cmVhbSkgCisgICAgICB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CisgICAgICB0aHJvdyAKKyAgICAgICAgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5jb21wcmVzc2VkQnl0ZXMgY2Fubm90IGJlIGNvbXByZXNzZWQhIik7CisgICAgfQorCisgIH0gLy8gVW5jb21wcmVzc2VkQnl0ZXMKKyAgCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIENvbXByZXNzZWRCeXRlcyBpbXBsZW1lbnRzIFZhbHVlQnl0ZXMgeworICAgIHByaXZhdGUgaW50IGRhdGFTaXplOworICAgIHByaXZhdGUgYnl0ZVtdIGRhdGE7CisgICAgRGF0YUlucHV0QnVmZmVyIHJhd0RhdGEgPSBudWxsOworICAgIENvbXByZXNzaW9uQ29kZWMgY29kZWMgPSBudWxsOworICAgIENvbXByZXNzaW9uSW5wdXRTdHJlYW0gZGVjb21wcmVzc2VkU3RyZWFtID0gbnVsbDsKKworICAgIHByaXZhdGUgQ29tcHJlc3NlZEJ5dGVzKENvbXByZXNzaW9uQ29kZWMgY29kZWMpIHsKKyAgICAgIGRhdGEgPSBudWxsOworICAgICAgZGF0YVNpemUgPSAwOworICAgICAgdGhpcy5jb2RlYyA9IGNvZGVjOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCByZXNldChEYXRhSW5wdXRTdHJlYW0gaW4sIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBkYXRhID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgIGRhdGFTaXplID0gLTE7CisKKyAgICAgIGluLnJlYWRGdWxseShkYXRhKTsKKyAgICAgIGRhdGFTaXplID0gZGF0YS5sZW5ndGg7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBpbnQgZ2V0U2l6ZSgpIHsKKyAgICAgIHJldHVybiBkYXRhU2l6ZTsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgd3JpdGVVbmNvbXByZXNzZWRCeXRlcyhEYXRhT3V0cHV0U3RyZWFtIG91dFN0cmVhbSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoZGVjb21wcmVzc2VkU3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgcmF3RGF0YSA9IG5ldyBEYXRhSW5wdXRCdWZmZXIoKTsKKyAgICAgICAgZGVjb21wcmVzc2VkU3RyZWFtID0gY29kZWMuY3JlYXRlSW5wdXRTdHJlYW0ocmF3RGF0YSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBkZWNvbXByZXNzZWRTdHJlYW0ucmVzZXRTdGF0ZSgpOworICAgICAgfQorICAgICAgcmF3RGF0YS5yZXNldChkYXRhLCAwLCBkYXRhU2l6ZSk7CisKKyAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs4MTkyXTsKKyAgICAgIGludCBieXRlc1JlYWQgPSAwOworICAgICAgd2hpbGUgKChieXRlc1JlYWQgPSBkZWNvbXByZXNzZWRTdHJlYW0ucmVhZChidWZmZXIsIDAsIDgxOTIpKSAhPSAtMSkgeworICAgICAgICBvdXRTdHJlYW0ud3JpdGUoYnVmZmVyLCAwLCBieXRlc1JlYWQpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlQ29tcHJlc3NlZEJ5dGVzKERhdGFPdXRwdXRTdHJlYW0gb3V0U3RyZWFtKSAKKyAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAgIG91dFN0cmVhbS53cml0ZShkYXRhLCAwLCBkYXRhU2l6ZSk7CisgICAgfQorCisgIH0gLy8gQ29tcHJlc3NlZEJ5dGVzCisgIAorICAvKioKKyAgICogVGhlIGNsYXNzIGVuY2Fwc3VsYXRpbmcgd2l0aCB0aGUgbWV0YWRhdGEgb2YgYSBmaWxlLgorICAgKiBUaGUgbWV0YWRhdGEgb2YgYSBmaWxlIGlzIGEgbGlzdCBvZiBhdHRyaWJ1dGUgbmFtZS92YWx1ZQorICAgKiBwYWlycyBvZiBUZXh0IHR5cGUuCisgICAqCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIE1ldGFkYXRhIGltcGxlbWVudHMgV3JpdGFibGUgeworCisgICAgcHJpdmF0ZSBUcmVlTWFwPFRleHQsIFRleHQ+IHRoZU1ldGFkYXRhOworICAgIAorICAgIHB1YmxpYyBNZXRhZGF0YSgpIHsKKyAgICAgIHRoaXMobmV3IFRyZWVNYXA8VGV4dCwgVGV4dD4oKSk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBNZXRhZGF0YShUcmVlTWFwPFRleHQsIFRleHQ+IGFyZykgeworICAgICAgaWYgKGFyZyA9PSBudWxsKSB7CisgICAgICAgIHRoaXMudGhlTWV0YWRhdGEgPSBuZXcgVHJlZU1hcDxUZXh0LCBUZXh0PigpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhpcy50aGVNZXRhZGF0YSA9IGFyZzsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIFRleHQgZ2V0KFRleHQgbmFtZSkgeworICAgICAgcmV0dXJuIHRoaXMudGhlTWV0YWRhdGEuZ2V0KG5hbWUpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBzZXQoVGV4dCBuYW1lLCBUZXh0IHZhbHVlKSB7CisgICAgICB0aGlzLnRoZU1ldGFkYXRhLnB1dChuYW1lLCB2YWx1ZSk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBUcmVlTWFwPFRleHQsIFRleHQ+IGdldE1ldGFkYXRhKCkgeworICAgICAgcmV0dXJuIG5ldyBUcmVlTWFwPFRleHQsIFRleHQ+KHRoaXMudGhlTWV0YWRhdGEpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIG91dC53cml0ZUludCh0aGlzLnRoZU1ldGFkYXRhLnNpemUoKSk7CisgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8VGV4dCwgVGV4dD4+IGl0ZXIgPQorICAgICAgICB0aGlzLnRoZU1ldGFkYXRhLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICBNYXAuRW50cnk8VGV4dCwgVGV4dD4gZW4gPSBpdGVyLm5leHQoKTsKKyAgICAgICAgZW4uZ2V0S2V5KCkud3JpdGUob3V0KTsKKyAgICAgICAgZW4uZ2V0VmFsdWUoKS53cml0ZShvdXQpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaW50IHN6ID0gaW4ucmVhZEludCgpOworICAgICAgaWYgKHN6IDwgMCkgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIHNpemU6ICIgKyBzeiArICIgZm9yIGZpbGUgbWV0YWRhdGEgb2JqZWN0Iik7CisgICAgICB0aGlzLnRoZU1ldGFkYXRhID0gbmV3IFRyZWVNYXA8VGV4dCwgVGV4dD4oKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3o7IGkrKykgeworICAgICAgICBUZXh0IGtleSA9IG5ldyBUZXh0KCk7CisgICAgICAgIFRleHQgdmFsID0gbmV3IFRleHQoKTsKKyAgICAgICAga2V5LnJlYWRGaWVsZHMoaW4pOworICAgICAgICB2YWwucmVhZEZpZWxkcyhpbik7CisgICAgICAgIHRoaXMudGhlTWV0YWRhdGEucHV0KGtleSwgdmFsKTsKKyAgICAgIH0gICAgCisgICAgfQorICAgIAorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhNZXRhZGF0YSBvdGhlcikgeworICAgICAgaWYgKG90aGVyID09IG51bGwpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGlzLnRoZU1ldGFkYXRhLnNpemUoKSAhPSBvdGhlci50aGVNZXRhZGF0YS5zaXplKCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFRleHQsIFRleHQ+PiBpdGVyMSA9CisgICAgICAgIHRoaXMudGhlTWV0YWRhdGEuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgSXRlcmF0b3I8TWFwLkVudHJ5PFRleHQsIFRleHQ+PiBpdGVyMiA9CisgICAgICAgIG90aGVyLnRoZU1ldGFkYXRhLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgIHdoaWxlIChpdGVyMS5oYXNOZXh0KCkgJiYgaXRlcjIuaGFzTmV4dCgpKSB7CisgICAgICAgIE1hcC5FbnRyeTxUZXh0LCBUZXh0PiBlbjEgPSBpdGVyMS5uZXh0KCk7CisgICAgICAgIE1hcC5FbnRyeTxUZXh0LCBUZXh0PiBlbjIgPSBpdGVyMi5uZXh0KCk7CisgICAgICAgIGlmICghZW4xLmdldEtleSgpLmVxdWFscyhlbjIuZ2V0S2V5KCkpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIGlmICghZW4xLmdldFZhbHVlKCkuZXF1YWxzKGVuMi5nZXRWYWx1ZSgpKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKGl0ZXIxLmhhc05leHQoKSB8fCBpdGVyMi5oYXNOZXh0KCkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIGFzc2VydCBmYWxzZSA6ICJoYXNoQ29kZSBub3QgZGVzaWduZWQiOworICAgICAgcmV0dXJuIDQyOyAvLyBhbnkgYXJiaXRyYXJ5IGNvbnN0YW50IHdpbGwgZG8gCisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1ZmZlciBzYiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgIHNiLmFwcGVuZCgic2l6ZTogIikuYXBwZW5kKHRoaXMudGhlTWV0YWRhdGEuc2l6ZSgpKS5hcHBlbmQoIlxuIik7CisgICAgICBJdGVyYXRvcjxNYXAuRW50cnk8VGV4dCwgVGV4dD4+IGl0ZXIgPQorICAgICAgICB0aGlzLnRoZU1ldGFkYXRhLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICBNYXAuRW50cnk8VGV4dCwgVGV4dD4gZW4gPSBpdGVyLm5leHQoKTsKKyAgICAgICAgc2IuYXBwZW5kKCJcdCIpLmFwcGVuZChlbi5nZXRLZXkoKS50b1N0cmluZygpKS5hcHBlbmQoIlx0IikuYXBwZW5kKGVuLmdldFZhbHVlKCkudG9TdHJpbmcoKSk7CisgICAgICAgIHNiLmFwcGVuZCgiXG4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKyAgfQorICAKKyAgLyoqIFdyaXRlIGtleS92YWx1ZSBwYWlycyB0byBhIHNlcXVlbmNlLWZvcm1hdCBmaWxlLiAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFdyaXRlciBpbXBsZW1lbnRzIGphdmEuaW8uQ2xvc2VhYmxlIHsKKyAgICBDb25maWd1cmF0aW9uIGNvbmY7CisgICAgRlNEYXRhT3V0cHV0U3RyZWFtIG91dDsKKyAgICBib29sZWFuIG93bk91dHB1dFN0cmVhbSA9IHRydWU7CisgICAgRGF0YU91dHB1dEJ1ZmZlciBidWZmZXIgPSBuZXcgRGF0YU91dHB1dEJ1ZmZlcigpOworCisgICAgQ2xhc3Mga2V5Q2xhc3M7CisgICAgQ2xhc3MgdmFsQ2xhc3M7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gY29tcHJlc3M7CisgICAgQ29tcHJlc3Npb25Db2RlYyBjb2RlYyA9IG51bGw7CisgICAgQ29tcHJlc3Npb25PdXRwdXRTdHJlYW0gZGVmbGF0ZUZpbHRlciA9IG51bGw7CisgICAgRGF0YU91dHB1dFN0cmVhbSBkZWZsYXRlT3V0ID0gbnVsbDsKKyAgICBNZXRhZGF0YSBtZXRhZGF0YSA9IG51bGw7CisgICAgQ29tcHJlc3NvciBjb21wcmVzc29yID0gbnVsbDsKKyAgICAKKyAgICBwcm90ZWN0ZWQgU2VyaWFsaXplciBrZXlTZXJpYWxpemVyOworICAgIHByb3RlY3RlZCBTZXJpYWxpemVyIHVuY29tcHJlc3NlZFZhbFNlcmlhbGl6ZXI7CisgICAgcHJvdGVjdGVkIFNlcmlhbGl6ZXIgY29tcHJlc3NlZFZhbFNlcmlhbGl6ZXI7CisgICAgCisgICAgLy8gSW5zZXJ0IGEgZ2xvYmFsbHkgdW5pcXVlIDE2LWJ5dGUgdmFsdWUgZXZlcnkgZmV3IGVudHJpZXMsIHNvIHRoYXQgb25lCisgICAgLy8gY2FuIHNlZWsgaW50byB0aGUgbWlkZGxlIG9mIGEgZmlsZSBhbmQgdGhlbiBzeW5jaHJvbml6ZSB3aXRoIHJlY29yZAorICAgIC8vIHN0YXJ0cyBhbmQgZW5kcyBieSBzY2FubmluZyBmb3IgdGhpcyB2YWx1ZS4KKyAgICBsb25nIGxhc3RTeW5jUG9zOyAgICAgICAgICAgICAgICAgICAgIC8vIHBvc2l0aW9uIG9mIGxhc3Qgc3luYworICAgIGJ5dGVbXSBzeW5jOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMTYgcmFuZG9tIGJ5dGVzCisgICAgeworICAgICAgdHJ5IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3RlciA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIk1ENSIpOworICAgICAgICBsb25nIHRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZGlnZXN0ZXIudXBkYXRlKChuZXcgVUlEKCkrIkAiK3RpbWUpLmdldEJ5dGVzKCkpOworICAgICAgICBzeW5jID0gZGlnZXN0ZXIuZGlnZXN0KCk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogSW1wbGljaXQgY29uc3RydWN0b3I6IG5lZWRlZCBmb3IgdGhlIHBlcmlvZCBvZiB0cmFuc2l0aW9uISovCisgICAgV3JpdGVyKCkKKyAgICB7fQorICAgIAorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUuIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gbmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsIG51bGwsIG5ldyBNZXRhZGF0YSgpKTsKKyAgICB9CisgICAgCisgICAgLyoqIENyZWF0ZSB0aGUgbmFtZWQgZmlsZSB3aXRoIHdyaXRlLXByb2dyZXNzIHJlcG9ydGVyLiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGNvbmYgCisgICAgICogQHBhcmFtIG5hbWUgCisgICAgICogQHBhcmFtIGtleUNsYXNzIAorICAgICAqIEBwYXJhbSB2YWxDbGFzcyAKKyAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgCisgICAgICogQHBhcmFtIG1ldGFkYXRhIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgIFByb2dyZXNzYWJsZSBwcm9ncmVzcywgTWV0YWRhdGEgbWV0YWRhdGEpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLAorICAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgIGZzLmdldERlZmF1bHRSZXBsaWNhdGlvbigpLCBmcy5nZXREZWZhdWx0QmxvY2tTaXplKCksCisgICAgICAgICAgIHByb2dyZXNzLCBtZXRhZGF0YSk7CisgICAgfQorICAgIAorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUgd2l0aCB3cml0ZS1wcm9ncmVzcyByZXBvcnRlci4gCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBuYW1lIAorICAgICAqIEBwYXJhbSBrZXlDbGFzcyAKKyAgICAgKiBAcGFyYW0gdmFsQ2xhc3MgCisgICAgICogQHBhcmFtIGJ1ZmZlclNpemUgCisgICAgICogQHBhcmFtIHJlcGxpY2F0aW9uIAorICAgICAqIEBwYXJhbSBibG9ja1NpemUgCisgICAgICogQHBhcmFtIHByb2dyZXNzIAorICAgICAqIEBwYXJhbSBtZXRhZGF0YSAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFdyaXRlcihGaWxlU3lzdGVtIGZzLCBDb25maWd1cmF0aW9uIGNvbmYsIFBhdGggbmFtZSwKKyAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgICAgIGludCBidWZmZXJTaXplLCBzaG9ydCByZXBsaWNhdGlvbiwgbG9uZyBibG9ja1NpemUsCisgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MsIE1ldGFkYXRhIG1ldGFkYXRhKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGluaXQoY29uZiwKKyAgICAgICAgICAgZnMuY3JlYXRlKG5hbWUsIHRydWUsIGJ1ZmZlclNpemUsIHJlcGxpY2F0aW9uLCBibG9ja1NpemUsIHByb2dyZXNzKSwKKyAgICAgICAgICAgICAga2V5Q2xhc3MsIHZhbENsYXNzLCBmYWxzZSwgbnVsbCwgbWV0YWRhdGEpOworICAgICAgaW5pdGlhbGl6ZUZpbGVIZWFkZXIoKTsKKyAgICAgIHdyaXRlRmlsZUhlYWRlcigpOworICAgICAgZmluYWxpemVGaWxlSGVhZGVyKCk7CisgICAgfQorCisgICAgLyoqIFdyaXRlIHRvIGFuIGFyYml0cmFyeSBzdHJlYW0gdXNpbmcgYSBzcGVjaWZpZWQgYnVmZmVyIHNpemUuICovCisgICAgcHJvdGVjdGVkIFdyaXRlcihDb25maWd1cmF0aW9uIGNvbmYsIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQsIAorICAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCBNZXRhZGF0YSBtZXRhZGF0YSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLm93bk91dHB1dFN0cmVhbSA9IGZhbHNlOworICAgICAgaW5pdChjb25mLCBvdXQsIGtleUNsYXNzLCB2YWxDbGFzcywgZmFsc2UsIG51bGwsIG1ldGFkYXRhKTsKKyAgICAgIAorICAgICAgaW5pdGlhbGl6ZUZpbGVIZWFkZXIoKTsKKyAgICAgIHdyaXRlRmlsZUhlYWRlcigpOworICAgICAgZmluYWxpemVGaWxlSGVhZGVyKCk7CisgICAgfQorCisgICAgLyoqIFdyaXRlIHRoZSBpbml0aWFsIHBhcnQgb2YgZmlsZSBoZWFkZXIuICovCisgICAgdm9pZCBpbml0aWFsaXplRmlsZUhlYWRlcigpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgb3V0LndyaXRlKFZFUlNJT04pOworICAgIH0KKworICAgIC8qKiBXcml0ZSB0aGUgZmluYWwgcGFydCBvZiBmaWxlIGhlYWRlci4gKi8KKyAgICB2b2lkIGZpbmFsaXplRmlsZUhlYWRlcigpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgICAgb3V0LndyaXRlKHN5bmMpOyAgICAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgdGhlIHN5bmMgYnl0ZXMKKyAgICAgIG91dC5mbHVzaCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZsdXNoIGhlYWRlcgorICAgIH0KKyAgICAKKyAgICBib29sZWFuIGlzQ29tcHJlc3NlZCgpIHsgcmV0dXJuIGNvbXByZXNzOyB9CisgICAgYm9vbGVhbiBpc0Jsb2NrQ29tcHJlc3NlZCgpIHsgcmV0dXJuIGZhbHNlOyB9CisgICAgCisgICAgLyoqIFdyaXRlIGFuZCBmbHVzaCB0aGUgZmlsZSBoZWFkZXIuICovCisgICAgdm9pZCB3cml0ZUZpbGVIZWFkZXIoKSAKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBUZXh0LndyaXRlU3RyaW5nKG91dCwga2V5Q2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgIFRleHQud3JpdGVTdHJpbmcob3V0LCB2YWxDbGFzcy5nZXROYW1lKCkpOworICAgICAgCisgICAgICBvdXQud3JpdGVCb29sZWFuKHRoaXMuaXNDb21wcmVzc2VkKCkpOworICAgICAgb3V0LndyaXRlQm9vbGVhbih0aGlzLmlzQmxvY2tDb21wcmVzc2VkKCkpOworICAgICAgCisgICAgICBpZiAodGhpcy5pc0NvbXByZXNzZWQoKSkgeworICAgICAgICBUZXh0LndyaXRlU3RyaW5nKG91dCwgKGNvZGVjLmdldENsYXNzKCkpLmdldE5hbWUoKSk7CisgICAgICB9CisgICAgICB0aGlzLm1ldGFkYXRhLndyaXRlKG91dCk7CisgICAgfQorICAgIAorICAgIC8qKiBJbml0aWFsaXplLiAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHZvaWQgaW5pdChDb25maWd1cmF0aW9uIGNvbmYsIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQsCisgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywKKyAgICAgICAgICAgICAgYm9vbGVhbiBjb21wcmVzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywgTWV0YWRhdGEgbWV0YWRhdGEpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgICB0aGlzLm91dCA9IG91dDsKKyAgICAgIHRoaXMua2V5Q2xhc3MgPSBrZXlDbGFzczsKKyAgICAgIHRoaXMudmFsQ2xhc3MgPSB2YWxDbGFzczsKKyAgICAgIHRoaXMuY29tcHJlc3MgPSBjb21wcmVzczsKKyAgICAgIHRoaXMuY29kZWMgPSBjb2RlYzsKKyAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKKyAgICAgIFNlcmlhbGl6YXRpb25GYWN0b3J5IHNlcmlhbGl6YXRpb25GYWN0b3J5ID0gbmV3IFNlcmlhbGl6YXRpb25GYWN0b3J5KGNvbmYpOworICAgICAgdGhpcy5rZXlTZXJpYWxpemVyID0gc2VyaWFsaXphdGlvbkZhY3RvcnkuZ2V0U2VyaWFsaXplcihrZXlDbGFzcyk7CisgICAgICB0aGlzLmtleVNlcmlhbGl6ZXIub3BlbihidWZmZXIpOworICAgICAgdGhpcy51bmNvbXByZXNzZWRWYWxTZXJpYWxpemVyID0gc2VyaWFsaXphdGlvbkZhY3RvcnkuZ2V0U2VyaWFsaXplcih2YWxDbGFzcyk7CisgICAgICB0aGlzLnVuY29tcHJlc3NlZFZhbFNlcmlhbGl6ZXIub3BlbihidWZmZXIpOworICAgICAgaWYgKHRoaXMuY29kZWMgIT0gbnVsbCkgeworICAgICAgICBSZWZsZWN0aW9uVXRpbHMuc2V0Q29uZih0aGlzLmNvZGVjLCB0aGlzLmNvbmYpOworICAgICAgICB0aGlzLmNvbXByZXNzb3IgPSBDb2RlY1Bvb2wuZ2V0Q29tcHJlc3Nvcih0aGlzLmNvZGVjKTsKKyAgICAgICAgdGhpcy5kZWZsYXRlRmlsdGVyID0gdGhpcy5jb2RlYy5jcmVhdGVPdXRwdXRTdHJlYW0oYnVmZmVyLCBjb21wcmVzc29yKTsKKyAgICAgICAgdGhpcy5kZWZsYXRlT3V0ID0gCisgICAgICAgICAgbmV3IERhdGFPdXRwdXRTdHJlYW0obmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGRlZmxhdGVGaWx0ZXIpKTsKKyAgICAgICAgdGhpcy5jb21wcmVzc2VkVmFsU2VyaWFsaXplciA9IHNlcmlhbGl6YXRpb25GYWN0b3J5LmdldFNlcmlhbGl6ZXIodmFsQ2xhc3MpOworICAgICAgICB0aGlzLmNvbXByZXNzZWRWYWxTZXJpYWxpemVyLm9wZW4oZGVmbGF0ZU91dCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKiBSZXR1cm5zIHRoZSBjbGFzcyBvZiBrZXlzIGluIHRoaXMgZmlsZS4gCisgICAgICogQHJldHVybiBDbGFzcworICAgICAqLworICAgIHB1YmxpYyBDbGFzcyBnZXRLZXlDbGFzcygpIHsgcmV0dXJuIGtleUNsYXNzOyB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgY2xhc3Mgb2YgdmFsdWVzIGluIHRoaXMgZmlsZS4gCisgICAgICogQHJldHVybiBDbGFzcworICAgICAqLworICAgIHB1YmxpYyBDbGFzcyBnZXRWYWx1ZUNsYXNzKCkgeyByZXR1cm4gdmFsQ2xhc3M7IH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBjb21wcmVzc2lvbiBjb2RlYyBvZiBkYXRhIGluIHRoaXMgZmlsZS4gCisgICAgICogQHJldHVybiBDb21wcmVzc2lvbkNvZGVjCisgICAgICovCisgICAgcHVibGljIENvbXByZXNzaW9uQ29kZWMgZ2V0Q29tcHJlc3Npb25Db2RlYygpIHsgcmV0dXJuIGNvZGVjOyB9CisgICAgCisgICAgLyoqIGNyZWF0ZSBhIHN5bmMgcG9pbnQgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN5bmMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHN5bmMgIT0gbnVsbCAmJiBsYXN0U3luY1BvcyAhPSBvdXQuZ2V0UG9zKCkpIHsKKyAgICAgICAgb3V0LndyaXRlSW50KFNZTkNfRVNDQVBFKTsgICAgICAgICAgICAgICAgLy8gbWFyayB0aGUgc3RhcnQgb2YgdGhlIHN5bmMKKyAgICAgICAgb3V0LndyaXRlKHN5bmMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgc3luYworICAgICAgICBsYXN0U3luY1BvcyA9IG91dC5nZXRQb3MoKTsgICAgICAgICAgICAgICAvLyB1cGRhdGUgbGFzdFN5bmNQb3MKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGlzIGZpbGUuICovCisgICAgQ29uZmlndXJhdGlvbiBnZXRDb25mKCkgeyByZXR1cm4gY29uZjsgfQorICAgIAorICAgIC8qKiBDbG9zZSB0aGUgZmlsZS4gCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBrZXlTZXJpYWxpemVyLmNsb3NlKCk7CisgICAgICB1bmNvbXByZXNzZWRWYWxTZXJpYWxpemVyLmNsb3NlKCk7CisgICAgICBpZiAoY29tcHJlc3NlZFZhbFNlcmlhbGl6ZXIgIT0gbnVsbCkgeworICAgICAgICBjb21wcmVzc2VkVmFsU2VyaWFsaXplci5jbG9zZSgpOworICAgICAgfQorCisgICAgICBDb2RlY1Bvb2wucmV0dXJuQ29tcHJlc3Nvcihjb21wcmVzc29yKTsKKyAgICAgIGNvbXByZXNzb3IgPSBudWxsOworICAgICAgCisgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgCisgICAgICAgIC8vIENsb3NlIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBpZmYgd2Ugb3duIGl0Li4uCisgICAgICAgIGlmIChvd25PdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgfQorICAgICAgICBvdXQgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIGNoZWNrQW5kV3JpdGVTeW5jKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChzeW5jICE9IG51bGwgJiYKKyAgICAgICAgICBvdXQuZ2V0UG9zKCkgPj0gbGFzdFN5bmNQb3MrU1lOQ19JTlRFUlZBTCkgeyAvLyB0aW1lIHRvIGVtaXQgc3luYworICAgICAgICBzeW5jKCk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIEFwcGVuZCBhIGtleS92YWx1ZSBwYWlyLiAKKyAgICAgKiBAcGFyYW0ga2V5IAorICAgICAqIEBwYXJhbSB2YWwgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhcHBlbmQoV3JpdGFibGUga2V5LCBXcml0YWJsZSB2YWwpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYXBwZW5kKChPYmplY3QpIGtleSwgKE9iamVjdCkgdmFsKTsKKyAgICB9CisKKyAgICAvKiogQXBwZW5kIGEga2V5L3ZhbHVlIHBhaXIuIAorICAgICAqIEBwYXJhbSBrZXkgCisgICAgICogQHBhcmFtIHZhbCAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFwcGVuZChPYmplY3Qga2V5LCBPYmplY3QgdmFsKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChrZXkuZ2V0Q2xhc3MoKSAhPSBrZXlDbGFzcykKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ3cm9uZyBrZXkgY2xhc3M6ICIra2V5LmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBpcyBub3QgIitrZXlDbGFzcyk7CisgICAgICBpZiAodmFsLmdldENsYXNzKCkgIT0gdmFsQ2xhc3MpCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigid3JvbmcgdmFsdWUgY2xhc3M6ICIrdmFsLmdldENsYXNzKCkuZ2V0TmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBpcyBub3QgIit2YWxDbGFzcyk7CisKKyAgICAgIGJ1ZmZlci5yZXNldCgpOworCisgICAgICAvLyBBcHBlbmQgdGhlICdrZXknCisgICAgICBrZXlTZXJpYWxpemVyLnNlcmlhbGl6ZShrZXkpOworICAgICAgaW50IGtleUxlbmd0aCA9IGJ1ZmZlci5nZXRMZW5ndGgoKTsKKyAgICAgIGlmIChrZXlMZW5ndGggPCAwKQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm5lZ2F0aXZlIGxlbmd0aCBrZXlzIG5vdCBhbGxvd2VkOiAiICsga2V5KTsKKworICAgICAgLy8gQXBwZW5kIHRoZSAndmFsdWUnCisgICAgICBpZiAoY29tcHJlc3MpIHsKKyAgICAgICAgZGVmbGF0ZUZpbHRlci5yZXNldFN0YXRlKCk7CisgICAgICAgIGNvbXByZXNzZWRWYWxTZXJpYWxpemVyLnNlcmlhbGl6ZSh2YWwpOworICAgICAgICBkZWZsYXRlT3V0LmZsdXNoKCk7CisgICAgICAgIGRlZmxhdGVGaWx0ZXIuZmluaXNoKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICB1bmNvbXByZXNzZWRWYWxTZXJpYWxpemVyLnNlcmlhbGl6ZSh2YWwpOworICAgICAgfQorCisgICAgICAvLyBXcml0ZSB0aGUgcmVjb3JkIG91dAorICAgICAgY2hlY2tBbmRXcml0ZVN5bmMoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN5bmMKKyAgICAgIG91dC53cml0ZUludChidWZmZXIuZ2V0TGVuZ3RoKCkpOyAgICAgICAgICAgICAgICAgICAvLyB0b3RhbCByZWNvcmQgbGVuZ3RoCisgICAgICBvdXQud3JpdGVJbnQoa2V5TGVuZ3RoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2V5IHBvcnRpb24gbGVuZ3RoCisgICAgICBvdXQud3JpdGUoYnVmZmVyLmdldERhdGEoKSwgMCwgYnVmZmVyLmdldExlbmd0aCgpKTsgLy8gZGF0YQorICAgIH0KKworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhcHBlbmRSYXcoYnl0ZVtdIGtleURhdGEsIGludCBrZXlPZmZzZXQsCisgICAgICAgIGludCBrZXlMZW5ndGgsIFZhbHVlQnl0ZXMgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGtleUxlbmd0aCA8IDApCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibmVnYXRpdmUgbGVuZ3RoIGtleXMgbm90IGFsbG93ZWQ6ICIgKyBrZXlMZW5ndGgpOworCisgICAgICBpbnQgdmFsTGVuZ3RoID0gdmFsLmdldFNpemUoKTsKKworICAgICAgY2hlY2tBbmRXcml0ZVN5bmMoKTsKKyAgICAgIAorICAgICAgb3V0LndyaXRlSW50KGtleUxlbmd0aCt2YWxMZW5ndGgpOyAgICAgICAgICAvLyB0b3RhbCByZWNvcmQgbGVuZ3RoCisgICAgICBvdXQud3JpdGVJbnQoa2V5TGVuZ3RoKTsgICAgICAgICAgICAgICAgICAgIC8vIGtleSBwb3J0aW9uIGxlbmd0aAorICAgICAgb3V0LndyaXRlKGtleURhdGEsIGtleU9mZnNldCwga2V5TGVuZ3RoKTsgICAvLyBrZXkKKyAgICAgIHZhbC53cml0ZVVuY29tcHJlc3NlZEJ5dGVzKG91dCk7ICAgICAgICAgICAgLy8gdmFsdWUKKyAgICB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgY3VycmVudCBsZW5ndGggb2YgdGhlIG91dHB1dCBmaWxlLgorICAgICAqCisgICAgICogPHA+VGhpcyBhbHdheXMgcmV0dXJucyBhIHN5bmNocm9uaXplZCBwb3NpdGlvbi4gIEluIG90aGVyIHdvcmRzLAorICAgICAqIGltbWVkaWF0ZWx5IGFmdGVyIGNhbGxpbmcge0BsaW5rIFNlcXVlbmNlRmlsZS5SZWFkZXIjc2Vlayhsb25nKX0gd2l0aCBhIHBvc2l0aW9uCisgICAgICogcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QsIHtAbGluayBTZXF1ZW5jZUZpbGUuUmVhZGVyI25leHQoV3JpdGFibGUpfSBtYXkgYmUgY2FsbGVkLiAgSG93ZXZlcgorICAgICAqIHRoZSBrZXkgbWF5IGJlIGVhcmxpZXIgaW4gdGhlIGZpbGUgdGhhbiBrZXkgbGFzdCB3cml0dGVuIHdoZW4gdGhpcworICAgICAqIG1ldGhvZCB3YXMgY2FsbGVkIChlLmcuLCB3aXRoIGJsb2NrLWNvbXByZXNzaW9uLCBpdCBtYXkgYmUgdGhlIGZpcnN0IGtleQorICAgICAqIGluIHRoZSBibG9jayB0aGF0IHdhcyBiZWluZyB3cml0dGVuIHdoZW4gdGhpcyBtZXRob2Qgd2FzIGNhbGxlZCkuCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldExlbmd0aCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gb3V0LmdldFBvcygpOworICAgIH0KKworICB9IC8vIGNsYXNzIFdyaXRlcgorCisgIC8qKiBXcml0ZSBrZXkvY29tcHJlc3NlZC12YWx1ZSBwYWlycyB0byBhIHNlcXVlbmNlLWZvcm1hdCBmaWxlLiAqLworICBzdGF0aWMgY2xhc3MgUmVjb3JkQ29tcHJlc3NXcml0ZXIgZXh0ZW5kcyBXcml0ZXIgeworICAgIAorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUuIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gbmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb2RlYyAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJlY29yZENvbXByZXNzV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLCBDb21wcmVzc2lvbkNvZGVjIGNvZGVjKSAKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGNvbmYsIGZzLmNyZWF0ZShuYW1lKSwga2V5Q2xhc3MsIHZhbENsYXNzLCBjb2RlYywgbmV3IE1ldGFkYXRhKCkpOworICAgIH0KKyAgICAKKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBmaWxlIHdpdGggd3JpdGUtcHJvZ3Jlc3MgcmVwb3J0ZXIuIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gbmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb2RlYyAKKyAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgCisgICAgICogQHBhcmFtIG1ldGFkYXRhIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVjb3JkQ29tcHJlc3NXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MsIENvbXByZXNzaW9uQ29kZWMgY29kZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb2dyZXNzYWJsZSBwcm9ncmVzcywgTWV0YWRhdGEgbWV0YWRhdGEpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLAorICAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgIGZzLmdldERlZmF1bHRSZXBsaWNhdGlvbigpLCBmcy5nZXREZWZhdWx0QmxvY2tTaXplKCksIGNvZGVjLAorICAgICAgICAgICBwcm9ncmVzcywgbWV0YWRhdGEpOworICAgIH0KKworICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUgd2l0aCB3cml0ZS1wcm9ncmVzcyByZXBvcnRlci4gCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBuYW1lIAorICAgICAqIEBwYXJhbSBrZXlDbGFzcyAKKyAgICAgKiBAcGFyYW0gdmFsQ2xhc3MgCisgICAgICogQHBhcmFtIGJ1ZmZlclNpemUgCisgICAgICogQHBhcmFtIHJlcGxpY2F0aW9uIAorICAgICAqIEBwYXJhbSBibG9ja1NpemUgCisgICAgICogQHBhcmFtIGNvZGVjIAorICAgICAqIEBwYXJhbSBwcm9ncmVzcyAKKyAgICAgKiBAcGFyYW0gbWV0YWRhdGEgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSZWNvcmRDb21wcmVzc1dyaXRlcihGaWxlU3lzdGVtIGZzLCBDb25maWd1cmF0aW9uIGNvbmYsIFBhdGggbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVmZmVyU2l6ZSwgc2hvcnQgcmVwbGljYXRpb24sIGxvbmcgYmxvY2tTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21wcmVzc2lvbkNvZGVjIGNvZGVjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MsIE1ldGFkYXRhIG1ldGFkYXRhKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyLmluaXQoY29uZiwKKyAgICAgICAgICAgICAgICAgZnMuY3JlYXRlKG5hbWUsIHRydWUsIGJ1ZmZlclNpemUsIHJlcGxpY2F0aW9uLCBibG9ja1NpemUsIHByb2dyZXNzKSwKKyAgICAgICAgICAgICAgICAga2V5Q2xhc3MsIHZhbENsYXNzLCB0cnVlLCBjb2RlYywgbWV0YWRhdGEpOworCisgICAgICBpbml0aWFsaXplRmlsZUhlYWRlcigpOworICAgICAgd3JpdGVGaWxlSGVhZGVyKCk7CisgICAgICBmaW5hbGl6ZUZpbGVIZWFkZXIoKTsKKyAgICB9CisKKyAgICAvKiogQ3JlYXRlIHRoZSBuYW1lZCBmaWxlIHdpdGggd3JpdGUtcHJvZ3Jlc3MgcmVwb3J0ZXIuIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gbmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb2RlYyAKKyAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSZWNvcmRDb21wcmVzc1dyaXRlcihGaWxlU3lzdGVtIGZzLCBDb25maWd1cmF0aW9uIGNvbmYsIFBhdGggbmFtZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvZ3Jlc3NhYmxlIHByb2dyZXNzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMoZnMsIGNvbmYsIG5hbWUsIGtleUNsYXNzLCB2YWxDbGFzcywgY29kZWMsIHByb2dyZXNzLCBuZXcgTWV0YWRhdGEoKSk7CisgICAgfQorICAgIAorICAgIC8qKiBXcml0ZSB0byBhbiBhcmJpdHJhcnkgc3RyZWFtIHVzaW5nIGEgc3BlY2lmaWVkIGJ1ZmZlciBzaXplLiAqLworICAgIHByb3RlY3RlZCBSZWNvcmRDb21wcmVzc1dyaXRlcihDb25maWd1cmF0aW9uIGNvbmYsIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywgTWV0YWRhdGEgbWV0YWRhdGEpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy5vd25PdXRwdXRTdHJlYW0gPSBmYWxzZTsKKyAgICAgIHN1cGVyLmluaXQoY29uZiwgb3V0LCBrZXlDbGFzcywgdmFsQ2xhc3MsIHRydWUsIGNvZGVjLCBtZXRhZGF0YSk7CisgICAgICAKKyAgICAgIGluaXRpYWxpemVGaWxlSGVhZGVyKCk7CisgICAgICB3cml0ZUZpbGVIZWFkZXIoKTsKKyAgICAgIGZpbmFsaXplRmlsZUhlYWRlcigpOworICAgICAgCisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIGJvb2xlYW4gaXNDb21wcmVzc2VkKCkgeyByZXR1cm4gdHJ1ZTsgfQorICAgIEBPdmVycmlkZQorICAgIGJvb2xlYW4gaXNCbG9ja0NvbXByZXNzZWQoKSB7IHJldHVybiBmYWxzZTsgfQorCisgICAgLyoqIEFwcGVuZCBhIGtleS92YWx1ZSBwYWlyLiAqLworICAgIEBPdmVycmlkZQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhcHBlbmQoT2JqZWN0IGtleSwgT2JqZWN0IHZhbCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoa2V5LmdldENsYXNzKCkgIT0ga2V5Q2xhc3MpCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigid3Jvbmcga2V5IGNsYXNzOiAiK2tleS5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIgaXMgbm90ICIra2V5Q2xhc3MpOworICAgICAgaWYgKHZhbC5nZXRDbGFzcygpICE9IHZhbENsYXNzKQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIndyb25nIHZhbHVlIGNsYXNzOiAiK3ZhbC5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIgaXMgbm90ICIrdmFsQ2xhc3MpOworCisgICAgICBidWZmZXIucmVzZXQoKTsKKworICAgICAgLy8gQXBwZW5kIHRoZSAna2V5JworICAgICAga2V5U2VyaWFsaXplci5zZXJpYWxpemUoa2V5KTsKKyAgICAgIGludCBrZXlMZW5ndGggPSBidWZmZXIuZ2V0TGVuZ3RoKCk7CisgICAgICBpZiAoa2V5TGVuZ3RoIDwgMCkKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJuZWdhdGl2ZSBsZW5ndGgga2V5cyBub3QgYWxsb3dlZDogIiArIGtleSk7CisKKyAgICAgIC8vIENvbXByZXNzICd2YWx1ZScgYW5kIGFwcGVuZCBpdAorICAgICAgZGVmbGF0ZUZpbHRlci5yZXNldFN0YXRlKCk7CisgICAgICBjb21wcmVzc2VkVmFsU2VyaWFsaXplci5zZXJpYWxpemUodmFsKTsKKyAgICAgIGRlZmxhdGVPdXQuZmx1c2goKTsKKyAgICAgIGRlZmxhdGVGaWx0ZXIuZmluaXNoKCk7CisKKyAgICAgIC8vIFdyaXRlIHRoZSByZWNvcmQgb3V0CisgICAgICBjaGVja0FuZFdyaXRlU3luYygpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3luYworICAgICAgb3V0LndyaXRlSW50KGJ1ZmZlci5nZXRMZW5ndGgoKSk7ICAgICAgICAgICAgICAgICAgIC8vIHRvdGFsIHJlY29yZCBsZW5ndGgKKyAgICAgIG91dC53cml0ZUludChrZXlMZW5ndGgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBrZXkgcG9ydGlvbiBsZW5ndGgKKyAgICAgIG91dC53cml0ZShidWZmZXIuZ2V0RGF0YSgpLCAwLCBidWZmZXIuZ2V0TGVuZ3RoKCkpOyAvLyBkYXRhCisgICAgfQorCisgICAgLyoqIEFwcGVuZCBhIGtleS92YWx1ZSBwYWlyLiAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhcHBlbmRSYXcoYnl0ZVtdIGtleURhdGEsIGludCBrZXlPZmZzZXQsCisgICAgICAgIGludCBrZXlMZW5ndGgsIFZhbHVlQnl0ZXMgdmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgICBpZiAoa2V5TGVuZ3RoIDwgMCkKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJuZWdhdGl2ZSBsZW5ndGgga2V5cyBub3QgYWxsb3dlZDogIiArIGtleUxlbmd0aCk7CisKKyAgICAgIGludCB2YWxMZW5ndGggPSB2YWwuZ2V0U2l6ZSgpOworICAgICAgCisgICAgICBjaGVja0FuZFdyaXRlU3luYygpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN5bmMKKyAgICAgIG91dC53cml0ZUludChrZXlMZW5ndGgrdmFsTGVuZ3RoKTsgICAgICAgICAgLy8gdG90YWwgcmVjb3JkIGxlbmd0aAorICAgICAgb3V0LndyaXRlSW50KGtleUxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAvLyBrZXkgcG9ydGlvbiBsZW5ndGgKKyAgICAgIG91dC53cml0ZShrZXlEYXRhLCBrZXlPZmZzZXQsIGtleUxlbmd0aCk7ICAgLy8gJ2tleScgZGF0YQorICAgICAgdmFsLndyaXRlQ29tcHJlc3NlZEJ5dGVzKG91dCk7ICAgICAgICAgICAgICAvLyAndmFsdWUnIGRhdGEKKyAgICB9CisgICAgCisgIH0gLy8gUmVjb3JkQ29tcHJlc3Npb25Xcml0ZXIKKworICAvKiogV3JpdGUgY29tcHJlc3NlZCBrZXkvdmFsdWUgYmxvY2tzIHRvIGEgc2VxdWVuY2UtZm9ybWF0IGZpbGUuICovCisgIHN0YXRpYyBjbGFzcyBCbG9ja0NvbXByZXNzV3JpdGVyIGV4dGVuZHMgV3JpdGVyIHsKKyAgICAKKyAgICBwcml2YXRlIGludCBub0J1ZmZlcmVkUmVjb3JkcyA9IDA7CisgICAgCisgICAgcHJpdmF0ZSBEYXRhT3V0cHV0QnVmZmVyIGtleUxlbkJ1ZmZlciA9IG5ldyBEYXRhT3V0cHV0QnVmZmVyKCk7CisgICAgcHJpdmF0ZSBEYXRhT3V0cHV0QnVmZmVyIGtleUJ1ZmZlciA9IG5ldyBEYXRhT3V0cHV0QnVmZmVyKCk7CisKKyAgICBwcml2YXRlIERhdGFPdXRwdXRCdWZmZXIgdmFsTGVuQnVmZmVyID0gbmV3IERhdGFPdXRwdXRCdWZmZXIoKTsKKyAgICBwcml2YXRlIERhdGFPdXRwdXRCdWZmZXIgdmFsQnVmZmVyID0gbmV3IERhdGFPdXRwdXRCdWZmZXIoKTsKKworICAgIHByaXZhdGUgaW50IGNvbXByZXNzaW9uQmxvY2tTaXplOworICAgIAorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUuIAorICAgICAqIEBwYXJhbSBmcyAKKyAgICAgKiBAcGFyYW0gY29uZiAKKyAgICAgKiBAcGFyYW0gbmFtZSAKKyAgICAgKiBAcGFyYW0ga2V5Q2xhc3MgCisgICAgICogQHBhcmFtIHZhbENsYXNzIAorICAgICAqIEBwYXJhbSBjb2RlYyAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIEJsb2NrQ29tcHJlc3NXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYykgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLAorICAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgIGZzLmdldERlZmF1bHRSZXBsaWNhdGlvbigpLCBmcy5nZXREZWZhdWx0QmxvY2tTaXplKCksIGNvZGVjLAorICAgICAgICAgICBudWxsLCBuZXcgTWV0YWRhdGEoKSk7CisgICAgfQorICAgIAorICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUgd2l0aCB3cml0ZS1wcm9ncmVzcyByZXBvcnRlci4gCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBuYW1lIAorICAgICAqIEBwYXJhbSBrZXlDbGFzcyAKKyAgICAgKiBAcGFyYW0gdmFsQ2xhc3MgCisgICAgICogQHBhcmFtIGNvZGVjIAorICAgICAqIEBwYXJhbSBwcm9ncmVzcyAKKyAgICAgKiBAcGFyYW0gbWV0YWRhdGEgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBCbG9ja0NvbXByZXNzV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIENvbmZpZ3VyYXRpb24gY29uZiwgUGF0aCBuYW1lLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyBrZXlDbGFzcywgQ2xhc3MgdmFsQ2xhc3MsIENvbXByZXNzaW9uQ29kZWMgY29kZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvZ3Jlc3NhYmxlIHByb2dyZXNzLCBNZXRhZGF0YSBtZXRhZGF0YSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGZzLCBjb25mLCBuYW1lLCBrZXlDbGFzcywgdmFsQ2xhc3MsCisgICAgICAgICAgIGZzLmdldENvbmYoKS5nZXRJbnQoImlvLmZpbGUuYnVmZmVyLnNpemUiLCA0MDk2KSwKKyAgICAgICAgICAgZnMuZ2V0RGVmYXVsdFJlcGxpY2F0aW9uKCksIGZzLmdldERlZmF1bHRCbG9ja1NpemUoKSwgY29kZWMsCisgICAgICAgICAgIHByb2dyZXNzLCBtZXRhZGF0YSk7CisgICAgfQorCisgICAgLyoqIENyZWF0ZSB0aGUgbmFtZWQgZmlsZSB3aXRoIHdyaXRlLXByb2dyZXNzIHJlcG9ydGVyLiAKKyAgICAgKiBAcGFyYW0gZnMgCisgICAgICogQHBhcmFtIGNvbmYgCisgICAgICogQHBhcmFtIG5hbWUgCisgICAgICogQHBhcmFtIGtleUNsYXNzIAorICAgICAqIEBwYXJhbSB2YWxDbGFzcyAKKyAgICAgKiBAcGFyYW0gYnVmZmVyU2l6ZSAKKyAgICAgKiBAcGFyYW0gcmVwbGljYXRpb24gCisgICAgICogQHBhcmFtIGJsb2NrU2l6ZSAKKyAgICAgKiBAcGFyYW0gY29kZWMgCisgICAgICogQHBhcmFtIHByb2dyZXNzIAorICAgICAqIEBwYXJhbSBtZXRhZGF0YSAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIEJsb2NrQ29tcHJlc3NXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3Mga2V5Q2xhc3MsIENsYXNzIHZhbENsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWZmZXJTaXplLCBzaG9ydCByZXBsaWNhdGlvbiwgbG9uZyBibG9ja1NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MsIE1ldGFkYXRhIG1ldGFkYXRhKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyLmluaXQoY29uZiwKKyAgICAgICAgICAgICAgICAgZnMuY3JlYXRlKG5hbWUsIHRydWUsIGJ1ZmZlclNpemUsIHJlcGxpY2F0aW9uLCBibG9ja1NpemUsIHByb2dyZXNzKSwKKyAgICAgICAgICAgICAgICAga2V5Q2xhc3MsIHZhbENsYXNzLCB0cnVlLCBjb2RlYywgbWV0YWRhdGEpOworICAgICAgaW5pdChjb25mLmdldEludCgiaW8uc2VxZmlsZS5jb21wcmVzcy5ibG9ja3NpemUiLCAxMDAwMDAwKSk7CisKKyAgICAgIGluaXRpYWxpemVGaWxlSGVhZGVyKCk7CisgICAgICB3cml0ZUZpbGVIZWFkZXIoKTsKKyAgICAgIGZpbmFsaXplRmlsZUhlYWRlcigpOworICAgIH0KKworICAgIC8qKiBDcmVhdGUgdGhlIG5hbWVkIGZpbGUgd2l0aCB3cml0ZS1wcm9ncmVzcyByZXBvcnRlci4gCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEBwYXJhbSBuYW1lIAorICAgICAqIEBwYXJhbSBrZXlDbGFzcyAKKyAgICAgKiBAcGFyYW0gdmFsQ2xhc3MgCisgICAgICogQHBhcmFtIGNvZGVjIAorICAgICAqIEBwYXJhbSBwcm9ncmVzcyAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIEJsb2NrQ29tcHJlc3NXcml0ZXIoRmlsZVN5c3RlbSBmcywgQ29uZmlndXJhdGlvbiBjb25mLCBQYXRoIG5hbWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgY29uZiwgbmFtZSwga2V5Q2xhc3MsIHZhbENsYXNzLCBjb2RlYywgcHJvZ3Jlc3MsIG5ldyBNZXRhZGF0YSgpKTsKKyAgICB9CisgICAgCisgICAgLyoqIFdyaXRlIHRvIGFuIGFyYml0cmFyeSBzdHJlYW0gdXNpbmcgYSBzcGVjaWZpZWQgYnVmZmVyIHNpemUuICovCisgICAgcHJvdGVjdGVkIEJsb2NrQ29tcHJlc3NXcml0ZXIoQ29uZmlndXJhdGlvbiBjb25mLCBGU0RhdGFPdXRwdXRTdHJlYW0gb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzIGtleUNsYXNzLCBDbGFzcyB2YWxDbGFzcywgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywgTWV0YWRhdGEgbWV0YWRhdGEpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy5vd25PdXRwdXRTdHJlYW0gPSBmYWxzZTsKKyAgICAgIHN1cGVyLmluaXQoY29uZiwgb3V0LCBrZXlDbGFzcywgdmFsQ2xhc3MsIHRydWUsIGNvZGVjLCBtZXRhZGF0YSk7CisgICAgICBpbml0KDEwMDAwMDApOworICAgICAgCisgICAgICBpbml0aWFsaXplRmlsZUhlYWRlcigpOworICAgICAgd3JpdGVGaWxlSGVhZGVyKCk7CisgICAgICBmaW5hbGl6ZUZpbGVIZWFkZXIoKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgYm9vbGVhbiBpc0NvbXByZXNzZWQoKSB7IHJldHVybiB0cnVlOyB9CisgICAgQE92ZXJyaWRlCisgICAgYm9vbGVhbiBpc0Jsb2NrQ29tcHJlc3NlZCgpIHsgcmV0dXJuIHRydWU7IH0KKworICAgIC8qKiBJbml0aWFsaXplICovCisgICAgdm9pZCBpbml0KGludCBjb21wcmVzc2lvbkJsb2NrU2l6ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuY29tcHJlc3Npb25CbG9ja1NpemUgPSBjb21wcmVzc2lvbkJsb2NrU2l6ZTsKKyAgICAgIGtleVNlcmlhbGl6ZXIuY2xvc2UoKTsKKyAgICAgIGtleVNlcmlhbGl6ZXIub3BlbihrZXlCdWZmZXIpOworICAgICAgdW5jb21wcmVzc2VkVmFsU2VyaWFsaXplci5jbG9zZSgpOworICAgICAgdW5jb21wcmVzc2VkVmFsU2VyaWFsaXplci5vcGVuKHZhbEJ1ZmZlcik7CisgICAgfQorICAgIAorICAgIC8qKiBXb3JraG9yc2UgdG8gY2hlY2sgYW5kIHdyaXRlIG91dCBjb21wcmVzc2VkIGRhdGEvbGVuZ3RocyAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIAorICAgICAgdm9pZCB3cml0ZUJ1ZmZlcihEYXRhT3V0cHV0QnVmZmVyIHVuY29tcHJlc3NlZERhdGFCdWZmZXIpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGRlZmxhdGVGaWx0ZXIucmVzZXRTdGF0ZSgpOworICAgICAgYnVmZmVyLnJlc2V0KCk7CisgICAgICBkZWZsYXRlT3V0LndyaXRlKHVuY29tcHJlc3NlZERhdGFCdWZmZXIuZ2V0RGF0YSgpLCAwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgdW5jb21wcmVzc2VkRGF0YUJ1ZmZlci5nZXRMZW5ndGgoKSk7CisgICAgICBkZWZsYXRlT3V0LmZsdXNoKCk7CisgICAgICBkZWZsYXRlRmlsdGVyLmZpbmlzaCgpOworICAgICAgCisgICAgICBXcml0YWJsZVV0aWxzLndyaXRlVkludChvdXQsIGJ1ZmZlci5nZXRMZW5ndGgoKSk7CisgICAgICBvdXQud3JpdGUoYnVmZmVyLmdldERhdGEoKSwgMCwgYnVmZmVyLmdldExlbmd0aCgpKTsKKyAgICB9CisgICAgCisgICAgLyoqIENvbXByZXNzIGFuZCBmbHVzaCBjb250ZW50cyB0byBkZnMgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3luYygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAobm9CdWZmZXJlZFJlY29yZHMgPiAwKSB7CisgICAgICAgIHN1cGVyLnN5bmMoKTsKKyAgICAgICAgCisgICAgICAgIC8vIE5vLiBvZiByZWNvcmRzCisgICAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVWSW50KG91dCwgbm9CdWZmZXJlZFJlY29yZHMpOworICAgICAgICAKKyAgICAgICAgLy8gV3JpdGUgJ2tleXMnIGFuZCBsZW5ndGhzCisgICAgICAgIHdyaXRlQnVmZmVyKGtleUxlbkJ1ZmZlcik7CisgICAgICAgIHdyaXRlQnVmZmVyKGtleUJ1ZmZlcik7CisgICAgICAgIAorICAgICAgICAvLyBXcml0ZSAndmFsdWVzJyBhbmQgbGVuZ3RocworICAgICAgICB3cml0ZUJ1ZmZlcih2YWxMZW5CdWZmZXIpOworICAgICAgICB3cml0ZUJ1ZmZlcih2YWxCdWZmZXIpOworICAgICAgICAKKyAgICAgICAgLy8gRmx1c2ggdGhlIGZpbGUtc3RyZWFtCisgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAKKyAgICAgICAgLy8gUmVzZXQgaW50ZXJuYWwgc3RhdGVzCisgICAgICAgIGtleUxlbkJ1ZmZlci5yZXNldCgpOworICAgICAgICBrZXlCdWZmZXIucmVzZXQoKTsKKyAgICAgICAgdmFsTGVuQnVmZmVyLnJlc2V0KCk7CisgICAgICAgIHZhbEJ1ZmZlci5yZXNldCgpOworICAgICAgICBub0J1ZmZlcmVkUmVjb3JkcyA9IDA7CisgICAgICB9CisgICAgICAKKyAgICB9CisgICAgCisgICAgLyoqIENsb3NlIHRoZSBmaWxlLiAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAob3V0ICE9IG51bGwpIHsKKyAgICAgICAgc3luYygpOworICAgICAgfQorICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICAvKiogQXBwZW5kIGEga2V5L3ZhbHVlIHBhaXIuICovCisgICAgQE92ZXJyaWRlCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFwcGVuZChPYmplY3Qga2V5LCBPYmplY3QgdmFsKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChrZXkuZ2V0Q2xhc3MoKSAhPSBrZXlDbGFzcykKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ3cm9uZyBrZXkgY2xhc3M6ICIra2V5KyIgaXMgbm90ICIra2V5Q2xhc3MpOworICAgICAgaWYgKHZhbC5nZXRDbGFzcygpICE9IHZhbENsYXNzKQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIndyb25nIHZhbHVlIGNsYXNzOiAiK3ZhbCsiIGlzIG5vdCAiK3ZhbENsYXNzKTsKKworICAgICAgLy8gU2F2ZSBrZXkvdmFsdWUgaW50byByZXNwZWN0aXZlIGJ1ZmZlcnMgCisgICAgICBpbnQgb2xkS2V5TGVuZ3RoID0ga2V5QnVmZmVyLmdldExlbmd0aCgpOworICAgICAga2V5U2VyaWFsaXplci5zZXJpYWxpemUoa2V5KTsKKyAgICAgIGludCBrZXlMZW5ndGggPSBrZXlCdWZmZXIuZ2V0TGVuZ3RoKCkgLSBvbGRLZXlMZW5ndGg7CisgICAgICBpZiAoa2V5TGVuZ3RoIDwgMCkKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJuZWdhdGl2ZSBsZW5ndGgga2V5cyBub3QgYWxsb3dlZDogIiArIGtleSk7CisgICAgICBXcml0YWJsZVV0aWxzLndyaXRlVkludChrZXlMZW5CdWZmZXIsIGtleUxlbmd0aCk7CisKKyAgICAgIGludCBvbGRWYWxMZW5ndGggPSB2YWxCdWZmZXIuZ2V0TGVuZ3RoKCk7CisgICAgICB1bmNvbXByZXNzZWRWYWxTZXJpYWxpemVyLnNlcmlhbGl6ZSh2YWwpOworICAgICAgaW50IHZhbExlbmd0aCA9IHZhbEJ1ZmZlci5nZXRMZW5ndGgoKSAtIG9sZFZhbExlbmd0aDsKKyAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVWSW50KHZhbExlbkJ1ZmZlciwgdmFsTGVuZ3RoKTsKKyAgICAgIAorICAgICAgLy8gQWRkZWQgYW5vdGhlciBrZXkvdmFsdWUgcGFpcgorICAgICAgKytub0J1ZmZlcmVkUmVjb3JkczsKKyAgICAgIAorICAgICAgLy8gQ29tcHJlc3MgYW5kIGZsdXNoPworICAgICAgaW50IGN1cnJlbnRCbG9ja1NpemUgPSBrZXlCdWZmZXIuZ2V0TGVuZ3RoKCkgKyB2YWxCdWZmZXIuZ2V0TGVuZ3RoKCk7CisgICAgICBpZiAoY3VycmVudEJsb2NrU2l6ZSA+PSBjb21wcmVzc2lvbkJsb2NrU2l6ZSkgeworICAgICAgICBzeW5jKCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKiBBcHBlbmQgYSBrZXkvdmFsdWUgcGFpci4gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYXBwZW5kUmF3KGJ5dGVbXSBrZXlEYXRhLCBpbnQga2V5T2Zmc2V0LAorICAgICAgICBpbnQga2V5TGVuZ3RoLCBWYWx1ZUJ5dGVzIHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIAorICAgICAgaWYgKGtleUxlbmd0aCA8IDApCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibmVnYXRpdmUgbGVuZ3RoIGtleXMgbm90IGFsbG93ZWQiKTsKKworICAgICAgaW50IHZhbExlbmd0aCA9IHZhbC5nZXRTaXplKCk7CisgICAgICAKKyAgICAgIC8vIFNhdmUga2V5L3ZhbHVlIGRhdGEgaW4gcmVsZXZhbnQgYnVmZmVycworICAgICAgV3JpdGFibGVVdGlscy53cml0ZVZJbnQoa2V5TGVuQnVmZmVyLCBrZXlMZW5ndGgpOworICAgICAga2V5QnVmZmVyLndyaXRlKGtleURhdGEsIGtleU9mZnNldCwga2V5TGVuZ3RoKTsKKyAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVWSW50KHZhbExlbkJ1ZmZlciwgdmFsTGVuZ3RoKTsKKyAgICAgIHZhbC53cml0ZVVuY29tcHJlc3NlZEJ5dGVzKHZhbEJ1ZmZlcik7CisKKyAgICAgIC8vIEFkZGVkIGFub3RoZXIga2V5L3ZhbHVlIHBhaXIKKyAgICAgICsrbm9CdWZmZXJlZFJlY29yZHM7CisKKyAgICAgIC8vIENvbXByZXNzIGFuZCBmbHVzaD8KKyAgICAgIGludCBjdXJyZW50QmxvY2tTaXplID0ga2V5QnVmZmVyLmdldExlbmd0aCgpICsgdmFsQnVmZmVyLmdldExlbmd0aCgpOyAKKyAgICAgIGlmIChjdXJyZW50QmxvY2tTaXplID49IGNvbXByZXNzaW9uQmxvY2tTaXplKSB7CisgICAgICAgIHN5bmMoKTsKKyAgICAgIH0KKyAgICB9CisgIAorICB9IC8vIEJsb2NrQ29tcHJlc3Npb25Xcml0ZXIKKyAgCisgIC8qKiBSZWFkcyBrZXkvdmFsdWUgcGFpcnMgZnJvbSBhIHNlcXVlbmNlLWZvcm1hdCBmaWxlLiAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlYWRlciBpbXBsZW1lbnRzIGphdmEuaW8uQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIFBhdGggZmlsZTsKKyAgICBwcml2YXRlIEZTRGF0YUlucHV0U3RyZWFtIGluOworICAgIHByaXZhdGUgRGF0YU91dHB1dEJ1ZmZlciBvdXRCdWYgPSBuZXcgRGF0YU91dHB1dEJ1ZmZlcigzMik7CisKKyAgICBwcml2YXRlIGJ5dGUgdmVyc2lvbjsKKworICAgIHByaXZhdGUgU3RyaW5nIGtleUNsYXNzTmFtZTsKKyAgICBwcml2YXRlIFN0cmluZyB2YWxDbGFzc05hbWU7CisgICAgcHJpdmF0ZSBDbGFzcyBrZXlDbGFzczsKKyAgICBwcml2YXRlIENsYXNzIHZhbENsYXNzOworCisgICAgcHJpdmF0ZSBDb21wcmVzc2lvbkNvZGVjIGNvZGVjID0gbnVsbDsKKyAgICBwcml2YXRlIE1ldGFkYXRhIG1ldGFkYXRhID0gbnVsbDsKKyAgICAKKyAgICBwcml2YXRlIGJ5dGVbXSBzeW5jID0gbmV3IGJ5dGVbU1lOQ19IQVNIX1NJWkVdOworICAgIHByaXZhdGUgYnl0ZVtdIHN5bmNDaGVjayA9IG5ldyBieXRlW1NZTkNfSEFTSF9TSVpFXTsKKyAgICBwcml2YXRlIGJvb2xlYW4gc3luY1NlZW47CisKKyAgICBwcml2YXRlIGxvbmcgZW5kOworICAgIHByaXZhdGUgaW50IGtleUxlbmd0aDsKKyAgICBwcml2YXRlIGludCByZWNvcmRMZW5ndGg7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZGVjb21wcmVzczsKKyAgICBwcml2YXRlIGJvb2xlYW4gYmxvY2tDb21wcmVzc2VkOworICAgIAorICAgIHByaXZhdGUgQ29uZmlndXJhdGlvbiBjb25mOworCisgICAgcHJpdmF0ZSBpbnQgbm9CdWZmZXJlZFJlY29yZHMgPSAwOworICAgIHByaXZhdGUgYm9vbGVhbiBsYXp5RGVjb21wcmVzcyA9IHRydWU7CisgICAgcHJpdmF0ZSBib29sZWFuIHZhbHVlc0RlY29tcHJlc3NlZCA9IHRydWU7CisgICAgCisgICAgcHJpdmF0ZSBpbnQgbm9CdWZmZXJlZEtleXMgPSAwOworICAgIHByaXZhdGUgaW50IG5vQnVmZmVyZWRWYWx1ZXMgPSAwOworICAgIAorICAgIHByaXZhdGUgRGF0YUlucHV0QnVmZmVyIGtleUxlbkJ1ZmZlciA9IG51bGw7CisgICAgcHJpdmF0ZSBDb21wcmVzc2lvbklucHV0U3RyZWFtIGtleUxlbkluRmlsdGVyID0gbnVsbDsKKyAgICBwcml2YXRlIERhdGFJbnB1dFN0cmVhbSBrZXlMZW5JbiA9IG51bGw7CisgICAgcHJpdmF0ZSBEZWNvbXByZXNzb3Iga2V5TGVuRGVjb21wcmVzc29yID0gbnVsbDsKKyAgICBwcml2YXRlIERhdGFJbnB1dEJ1ZmZlciBrZXlCdWZmZXIgPSBudWxsOworICAgIHByaXZhdGUgQ29tcHJlc3Npb25JbnB1dFN0cmVhbSBrZXlJbkZpbHRlciA9IG51bGw7CisgICAgcHJpdmF0ZSBEYXRhSW5wdXRTdHJlYW0ga2V5SW4gPSBudWxsOworICAgIHByaXZhdGUgRGVjb21wcmVzc29yIGtleURlY29tcHJlc3NvciA9IG51bGw7CisKKyAgICBwcml2YXRlIERhdGFJbnB1dEJ1ZmZlciB2YWxMZW5CdWZmZXIgPSBudWxsOworICAgIHByaXZhdGUgQ29tcHJlc3Npb25JbnB1dFN0cmVhbSB2YWxMZW5JbkZpbHRlciA9IG51bGw7CisgICAgcHJpdmF0ZSBEYXRhSW5wdXRTdHJlYW0gdmFsTGVuSW4gPSBudWxsOworICAgIHByaXZhdGUgRGVjb21wcmVzc29yIHZhbExlbkRlY29tcHJlc3NvciA9IG51bGw7CisgICAgcHJpdmF0ZSBEYXRhSW5wdXRCdWZmZXIgdmFsQnVmZmVyID0gbnVsbDsKKyAgICBwcml2YXRlIENvbXByZXNzaW9uSW5wdXRTdHJlYW0gdmFsSW5GaWx0ZXIgPSBudWxsOworICAgIHByaXZhdGUgRGF0YUlucHV0U3RyZWFtIHZhbEluID0gbnVsbDsKKyAgICBwcml2YXRlIERlY29tcHJlc3NvciB2YWxEZWNvbXByZXNzb3IgPSBudWxsOworICAgIAorICAgIHByaXZhdGUgRGVzZXJpYWxpemVyIGtleURlc2VyaWFsaXplcjsKKyAgICBwcml2YXRlIERlc2VyaWFsaXplciB2YWxEZXNlcmlhbGl6ZXI7CisKKyAgICAvKiogT3BlbiB0aGUgbmFtZWQgZmlsZS4gCisgICAgICogQHBhcmFtIGZzIAorICAgICAqIEBwYXJhbSBmaWxlIAorICAgICAqIEBwYXJhbSBjb25mIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgUmVhZGVyKEZpbGVTeXN0ZW0gZnMsIFBhdGggZmlsZSwgQ29uZmlndXJhdGlvbiBjb25mKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMoZnMsIGZpbGUsIGNvbmYuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksIGNvbmYsIGZhbHNlKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFJlYWRlcihGaWxlU3lzdGVtIGZzLCBQYXRoIGZpbGUsIGludCBidWZmZXJTaXplLAorICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gY29uZiwgYm9vbGVhbiB0ZW1wUmVhZGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgZmlsZSwgYnVmZmVyU2l6ZSwgMCwgZnMuZ2V0TGVuZ3RoKGZpbGUpLCBjb25mLCB0ZW1wUmVhZGVyKTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBSZWFkZXIoRmlsZVN5c3RlbSBmcywgUGF0aCBmaWxlLCBpbnQgYnVmZmVyU2l6ZSwgbG9uZyBzdGFydCwKKyAgICAgICAgICAgICAgICAgICBsb25nIGxlbmd0aCwgQ29uZmlndXJhdGlvbiBjb25mLCBib29sZWFuIHRlbXBSZWFkZXIpIAorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgdGhpcy5pbiA9IG9wZW5GaWxlKGZzLCBmaWxlLCBidWZmZXJTaXplLCBsZW5ndGgpOworICAgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICAgIHNlZWsoc3RhcnQpOworICAgICAgdGhpcy5lbmQgPSBpbi5nZXRQb3MoKSArIGxlbmd0aDsKKyAgICAgIGluaXQodGVtcFJlYWRlcik7CisgICAgfQorCisgICAgLyoqCisgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gc3BlY2lhbGl6ZSB0aGUgdHlwZSBvZgorICAgICAqIHtAbGluayBGU0RhdGFJbnB1dFN0cmVhbX0gcmV0dXJuZWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIEZTRGF0YUlucHV0U3RyZWFtIG9wZW5GaWxlKEZpbGVTeXN0ZW0gZnMsIFBhdGggZmlsZSwKKyAgICAgICAgaW50IGJ1ZmZlclNpemUsIGxvbmcgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIGZzLm9wZW4oZmlsZSwgYnVmZmVyU2l6ZSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEluaXRpYWxpemUgdGhlIHtAbGluayBSZWFkZXJ9CisgICAgICogQHBhcmFtIHRtcFJlYWRlciA8Y29kZT50cnVlPC9jb2RlPiBpZiB3ZSBhcmUgY29uc3RydWN0aW5nIGEgdGVtcG9yYXJ5CisgICAgICogICAgICAgICAgICAgICAgICByZWFkZXIge0BsaW5rIFNlcXVlbmNlRmlsZS5Tb3J0ZXIuY2xvbmVGaWxlQXR0cmlidXRlc30sIAorICAgICAqICAgICAgICAgICAgICAgICAgYW5kIGhlbmNlIGRvIG5vdCBpbml0aWFsaXplIGV2ZXJ5IGNvbXBvbmVudDsgCisgICAgICogICAgICAgICAgICAgICAgICA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaW5pdChib29sZWFuIHRlbXBSZWFkZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBieXRlW10gdmVyc2lvbkJsb2NrID0gbmV3IGJ5dGVbVkVSU0lPTi5sZW5ndGhdOworICAgICAgaW4ucmVhZEZ1bGx5KHZlcnNpb25CbG9jayk7CisKKyAgICAgIGlmICgodmVyc2lvbkJsb2NrWzBdICE9IFZFUlNJT05bMF0pIHx8CisgICAgICAgICAgKHZlcnNpb25CbG9ja1sxXSAhPSBWRVJTSU9OWzFdKSB8fAorICAgICAgICAgICh2ZXJzaW9uQmxvY2tbMl0gIT0gVkVSU0lPTlsyXSkpCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihmaWxlICsgIiBub3QgYSBTZXF1ZW5jZUZpbGUiKTsKKworICAgICAgLy8gU2V0ICd2ZXJzaW9uJworICAgICAgdmVyc2lvbiA9IHZlcnNpb25CbG9ja1szXTsKKyAgICAgIGlmICh2ZXJzaW9uID4gVkVSU0lPTlszXSkKKyAgICAgICAgdGhyb3cgbmV3IFZlcnNpb25NaXNtYXRjaEV4Y2VwdGlvbihWRVJTSU9OWzNdLCB2ZXJzaW9uKTsKKworICAgICAgaWYgKHZlcnNpb24gPCBCTE9DS19DT01QUkVTU19WRVJTSU9OKSB7CisgICAgICAgIFVURjggY2xhc3NOYW1lID0gbmV3IFVURjgoKTsKKworICAgICAgICBjbGFzc05hbWUucmVhZEZpZWxkcyhpbik7CisgICAgICAgIGtleUNsYXNzTmFtZSA9IGNsYXNzTmFtZS50b1N0cmluZygpOyAvLyBrZXkgY2xhc3MgbmFtZQorCisgICAgICAgIGNsYXNzTmFtZS5yZWFkRmllbGRzKGluKTsKKyAgICAgICAgdmFsQ2xhc3NOYW1lID0gY2xhc3NOYW1lLnRvU3RyaW5nKCk7IC8vIHZhbCBjbGFzcyBuYW1lCisgICAgICB9IGVsc2UgeworICAgICAgICBrZXlDbGFzc05hbWUgPSBUZXh0LnJlYWRTdHJpbmcoaW4pOworICAgICAgICB2YWxDbGFzc05hbWUgPSBUZXh0LnJlYWRTdHJpbmcoaW4pOworICAgICAgfQorCisgICAgICBpZiAodmVyc2lvbiA+IDIpIHsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHZlcnNpb24gPiAyCisgICAgICAgIHRoaXMuZGVjb21wcmVzcyA9IGluLnJlYWRCb29sZWFuKCk7ICAgICAgIC8vIGlzIGNvbXByZXNzZWQ/CisgICAgICB9IGVsc2UgeworICAgICAgICBkZWNvbXByZXNzID0gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGlmICh2ZXJzaW9uID49IEJMT0NLX0NPTVBSRVNTX1ZFUlNJT04pIHsgICAgLy8gaWYgdmVyc2lvbiA+PSA0CisgICAgICAgIHRoaXMuYmxvY2tDb21wcmVzc2VkID0gaW4ucmVhZEJvb2xlYW4oKTsgIC8vIGlzIGJsb2NrLWNvbXByZXNzZWQ/CisgICAgICB9IGVsc2UgeworICAgICAgICBibG9ja0NvbXByZXNzZWQgPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLy8gaWYgdmVyc2lvbiA+PSA1CisgICAgICAvLyBzZXR1cCB0aGUgY29tcHJlc3Npb24gY29kZWMKKyAgICAgIGlmIChkZWNvbXByZXNzKSB7CisgICAgICAgIGlmICh2ZXJzaW9uID49IENVU1RPTV9DT01QUkVTU19WRVJTSU9OKSB7CisgICAgICAgICAgU3RyaW5nIGNvZGVjQ2xhc3NuYW1lID0gVGV4dC5yZWFkU3RyaW5nKGluKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIENvbXByZXNzaW9uQ29kZWM+IGNvZGVjQ2xhc3MKKyAgICAgICAgICAgICAgPSBjb25mLmdldENsYXNzQnlOYW1lKGNvZGVjQ2xhc3NuYW1lKS5hc1N1YmNsYXNzKENvbXByZXNzaW9uQ29kZWMuY2xhc3MpOworICAgICAgICAgICAgdGhpcy5jb2RlYyA9IChDb21wcmVzc2lvbkNvZGVjKSBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2UoY29kZWNDbGFzcywgY29uZik7CisgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIGNvZGVjOiAiICsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGVjQ2xhc3NuYW1lLCBjbmZlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY29kZWMgPSBuZXcgRGVmYXVsdENvZGVjKCk7CisgICAgICAgICAgKChDb25maWd1cmFibGUpY29kZWMpLnNldENvbmYoY29uZik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIAorICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBNZXRhZGF0YSgpOworICAgICAgaWYgKHZlcnNpb24gPj0gVkVSU0lPTl9XSVRIX01FVEFEQVRBKSB7ICAgIC8vIGlmIHZlcnNpb24gPj0gNgorICAgICAgICB0aGlzLm1ldGFkYXRhLnJlYWRGaWVsZHMoaW4pOworICAgICAgfQorICAgICAgCisgICAgICBpZiAodmVyc2lvbiA+IDEpIHsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHZlcnNpb24gPiAxCisgICAgICAgIGluLnJlYWRGdWxseShzeW5jKTsgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlYWQgc3luYyBieXRlcworICAgICAgfQorICAgICAgCisgICAgICAvLyBJbml0aWFsaXplLi4uICpub3QqIGlmIHRoaXMgd2UgYXJlIGNvbnN0cnVjdGluZyBhIHRlbXBvcmFyeSBSZWFkZXIKKyAgICAgIGlmICghdGVtcFJlYWRlcikgeworICAgICAgICB2YWxCdWZmZXIgPSBuZXcgRGF0YUlucHV0QnVmZmVyKCk7CisgICAgICAgIGlmIChkZWNvbXByZXNzKSB7CisgICAgICAgICAgdmFsRGVjb21wcmVzc29yID0gQ29kZWNQb29sLmdldERlY29tcHJlc3Nvcihjb2RlYyk7CisgICAgICAgICAgdmFsSW5GaWx0ZXIgPSBjb2RlYy5jcmVhdGVJbnB1dFN0cmVhbSh2YWxCdWZmZXIsIHZhbERlY29tcHJlc3Nvcik7CisgICAgICAgICAgdmFsSW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKHZhbEluRmlsdGVyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB2YWxJbiA9IHZhbEJ1ZmZlcjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChibG9ja0NvbXByZXNzZWQpIHsKKyAgICAgICAgICBrZXlMZW5CdWZmZXIgPSBuZXcgRGF0YUlucHV0QnVmZmVyKCk7CisgICAgICAgICAga2V5QnVmZmVyID0gbmV3IERhdGFJbnB1dEJ1ZmZlcigpOworICAgICAgICAgIHZhbExlbkJ1ZmZlciA9IG5ldyBEYXRhSW5wdXRCdWZmZXIoKTsKKworICAgICAgICAgIGtleUxlbkRlY29tcHJlc3NvciA9IENvZGVjUG9vbC5nZXREZWNvbXByZXNzb3IoY29kZWMpOworICAgICAgICAgIGtleUxlbkluRmlsdGVyID0gY29kZWMuY3JlYXRlSW5wdXRTdHJlYW0oa2V5TGVuQnVmZmVyLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleUxlbkRlY29tcHJlc3Nvcik7CisgICAgICAgICAga2V5TGVuSW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKGtleUxlbkluRmlsdGVyKTsKKworICAgICAgICAgIGtleURlY29tcHJlc3NvciA9IENvZGVjUG9vbC5nZXREZWNvbXByZXNzb3IoY29kZWMpOworICAgICAgICAgIGtleUluRmlsdGVyID0gY29kZWMuY3JlYXRlSW5wdXRTdHJlYW0oa2V5QnVmZmVyLCBrZXlEZWNvbXByZXNzb3IpOworICAgICAgICAgIGtleUluID0gbmV3IERhdGFJbnB1dFN0cmVhbShrZXlJbkZpbHRlcik7CisKKyAgICAgICAgICB2YWxMZW5EZWNvbXByZXNzb3IgPSBDb2RlY1Bvb2wuZ2V0RGVjb21wcmVzc29yKGNvZGVjKTsKKyAgICAgICAgICB2YWxMZW5JbkZpbHRlciA9IGNvZGVjLmNyZWF0ZUlucHV0U3RyZWFtKHZhbExlbkJ1ZmZlciwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxMZW5EZWNvbXByZXNzb3IpOworICAgICAgICAgIHZhbExlbkluID0gbmV3IERhdGFJbnB1dFN0cmVhbSh2YWxMZW5JbkZpbHRlcik7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIFNlcmlhbGl6YXRpb25GYWN0b3J5IHNlcmlhbGl6YXRpb25GYWN0b3J5ID0KKyAgICAgICAgICBuZXcgU2VyaWFsaXphdGlvbkZhY3RvcnkoY29uZik7CisgICAgICAgIHRoaXMua2V5RGVzZXJpYWxpemVyID0KKyAgICAgICAgICBnZXREZXNlcmlhbGl6ZXIoc2VyaWFsaXphdGlvbkZhY3RvcnksIGdldEtleUNsYXNzKCkpOworICAgICAgICBpZiAoIWJsb2NrQ29tcHJlc3NlZCkgeworICAgICAgICAgIHRoaXMua2V5RGVzZXJpYWxpemVyLm9wZW4odmFsQnVmZmVyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aGlzLmtleURlc2VyaWFsaXplci5vcGVuKGtleUluKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnZhbERlc2VyaWFsaXplciA9CisgICAgICAgICAgZ2V0RGVzZXJpYWxpemVyKHNlcmlhbGl6YXRpb25GYWN0b3J5LCBnZXRWYWx1ZUNsYXNzKCkpOworICAgICAgICB0aGlzLnZhbERlc2VyaWFsaXplci5vcGVuKHZhbEluKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHJpdmF0ZSBEZXNlcmlhbGl6ZXIgZ2V0RGVzZXJpYWxpemVyKFNlcmlhbGl6YXRpb25GYWN0b3J5IHNmLCBDbGFzcyBjKSB7CisgICAgICByZXR1cm4gc2YuZ2V0RGVzZXJpYWxpemVyKGMpOworICAgIH0KKyAgICAKKyAgICAvKiogQ2xvc2UgdGhlIGZpbGUuIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gUmV0dXJuIHRoZSBkZWNvbXByZXNzb3JzIHRvIHRoZSBwb29sCisgICAgICBDb2RlY1Bvb2wucmV0dXJuRGVjb21wcmVzc29yKGtleUxlbkRlY29tcHJlc3Nvcik7CisgICAgICBDb2RlY1Bvb2wucmV0dXJuRGVjb21wcmVzc29yKGtleURlY29tcHJlc3Nvcik7CisgICAgICBDb2RlY1Bvb2wucmV0dXJuRGVjb21wcmVzc29yKHZhbExlbkRlY29tcHJlc3Nvcik7CisgICAgICBDb2RlY1Bvb2wucmV0dXJuRGVjb21wcmVzc29yKHZhbERlY29tcHJlc3Nvcik7CisgICAgICBrZXlMZW5EZWNvbXByZXNzb3IgPSBrZXlEZWNvbXByZXNzb3IgPSBudWxsOworICAgICAgdmFsTGVuRGVjb21wcmVzc29yID0gdmFsRGVjb21wcmVzc29yID0gbnVsbDsKKyAgICAgIAorICAgICAgaWYgKGtleURlc2VyaWFsaXplciAhPSBudWxsKSB7CisgICAgCWtleURlc2VyaWFsaXplci5jbG9zZSgpOworICAgICAgfQorICAgICAgaWYgKHZhbERlc2VyaWFsaXplciAhPSBudWxsKSB7CisgICAgICAgIHZhbERlc2VyaWFsaXplci5jbG9zZSgpOworICAgICAgfQorICAgICAgCisgICAgICAvLyBDbG9zZSB0aGUgaW5wdXQtc3RyZWFtCisgICAgICBpbi5jbG9zZSgpOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBrZXkgY2xhc3MuIAorICAgICAqIEByZXR1cm4gU3RyaW5nCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRLZXlDbGFzc05hbWUoKSB7CisgICAgICByZXR1cm4ga2V5Q2xhc3NOYW1lOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBjbGFzcyBvZiBrZXlzIGluIHRoaXMgZmlsZS4gCisgICAgICogQHJldHVybiBDbGFzcworICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQ2xhc3M8Pz4gZ2V0S2V5Q2xhc3MoKSB7CisgICAgICBpZiAobnVsbCA9PSBrZXlDbGFzcykgeworICAgICAgICB0cnkgeworICAgICAgICAgIGtleUNsYXNzID0gV3JpdGFibGVOYW1lLmdldENsYXNzKGdldEtleUNsYXNzTmFtZSgpLCBjb25mKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4ga2V5Q2xhc3M7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHZhbHVlIGNsYXNzLiAKKyAgICAgKiBAcmV0dXJuIFN0cmluZworICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWVDbGFzc05hbWUoKSB7CisgICAgICByZXR1cm4gdmFsQ2xhc3NOYW1lOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBjbGFzcyBvZiB2YWx1ZXMgaW4gdGhpcyBmaWxlLiAKKyAgICAgKiBAcmV0dXJuIENsYXNzCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBDbGFzczw/PiBnZXRWYWx1ZUNsYXNzKCkgeworICAgICAgaWYgKG51bGwgPT0gdmFsQ2xhc3MpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICB2YWxDbGFzcyA9IFdyaXRhYmxlTmFtZS5nZXRDbGFzcyhnZXRWYWx1ZUNsYXNzTmFtZSgpLCBjb25mKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdmFsQ2xhc3M7CisgICAgfQorCisgICAgLyoqIEByZXR1cm4gdHJ1ZSBpZiB2YWx1ZXMgYXJlIGNvbXByZXNzZWQuICovCisgICAgcHVibGljIGJvb2xlYW4gaXNDb21wcmVzc2VkKCkgeyByZXR1cm4gZGVjb21wcmVzczsgfQorICAgIAorICAgIC8qKiBAcmV0dXJuIHRydWUgaWYgcmVjb3JkcyBhcmUgYmxvY2stY29tcHJlc3NlZC4gKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBpc0Jsb2NrQ29tcHJlc3NlZCgpIHsgcmV0dXJuIGJsb2NrQ29tcHJlc3NlZDsgfQorICAgIAorICAgIC8qKiBAcmV0dXJuIHRoZSBjb21wcmVzc2lvbiBjb2RlYyBvZiBkYXRhIGluIHRoaXMgZmlsZS4gKi8KKyAgICBwdWJsaWMgQ29tcHJlc3Npb25Db2RlYyBnZXRDb21wcmVzc2lvbkNvZGVjKCkgeyByZXR1cm4gY29kZWM7IH0KKworICAgIC8qKiBAcmV0dXJuIHRoZSBtZXRhZGF0YSBvYmplY3Qgb2YgdGhlIGZpbGUgKi8KKyAgICBwdWJsaWMgTWV0YWRhdGEgZ2V0TWV0YWRhdGEoKSB7CisgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YTsKKyAgICB9CisgICAgCisgICAgLyoqIFJldHVybnMgdGhlIGNvbmZpZ3VyYXRpb24gdXNlZCBmb3IgdGhpcyBmaWxlLiAqLworICAgIENvbmZpZ3VyYXRpb24gZ2V0Q29uZigpIHsgcmV0dXJuIGNvbmY7IH0KKyAgICAKKyAgICAvKiogUmVhZCBhIGNvbXByZXNzZWQgYnVmZmVyICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCByZWFkQnVmZmVyKERhdGFJbnB1dEJ1ZmZlciBidWZmZXIsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21wcmVzc2lvbklucHV0U3RyZWFtIGZpbHRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIFJlYWQgZGF0YSBpbnRvIGEgdGVtcG9yYXJ5IGJ1ZmZlcgorICAgICAgRGF0YU91dHB1dEJ1ZmZlciBkYXRhQnVmZmVyID0gbmV3IERhdGFPdXRwdXRCdWZmZXIoKTsKKworICAgICAgdHJ5IHsKKyAgICAgICAgaW50IGRhdGFCdWZmZXJMZW5ndGggPSBXcml0YWJsZVV0aWxzLnJlYWRWSW50KGluKTsKKyAgICAgICAgZGF0YUJ1ZmZlci53cml0ZShpbiwgZGF0YUJ1ZmZlckxlbmd0aCk7CisgICAgICAKKyAgICAgICAgLy8gU2V0IHVwICdidWZmZXInIGNvbm5lY3RlZCB0byB0aGUgaW5wdXQtc3RyZWFtCisgICAgICAgIGJ1ZmZlci5yZXNldChkYXRhQnVmZmVyLmdldERhdGEoKSwgMCwgZGF0YUJ1ZmZlci5nZXRMZW5ndGgoKSk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBkYXRhQnVmZmVyLmNsb3NlKCk7CisgICAgICB9CisKKyAgICAgIC8vIFJlc2V0IHRoZSBjb2RlYworICAgICAgZmlsdGVyLnJlc2V0U3RhdGUoKTsKKyAgICB9CisgICAgCisgICAgLyoqIFJlYWQgdGhlIG5leHQgJ2NvbXByZXNzZWQnIGJsb2NrICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCByZWFkQmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byB0aHJvdyBhd2F5IGEgd2hvbGUgYmxvY2sgb2YgCisgICAgICAvLyAndmFsdWVzJyBkdWUgdG8gJ2xhenkgZGVjb21wcmVzc2lvbicgCisgICAgICBpZiAobGF6eURlY29tcHJlc3MgJiYgIXZhbHVlc0RlY29tcHJlc3NlZCkgeworICAgICAgICBpbi5zZWVrKFdyaXRhYmxlVXRpbHMucmVhZFZJbnQoaW4pK2luLmdldFBvcygpKTsKKyAgICAgICAgaW4uc2VlayhXcml0YWJsZVV0aWxzLnJlYWRWSW50KGluKStpbi5nZXRQb3MoKSk7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIFJlc2V0IGludGVybmFsIHN0YXRlcworICAgICAgbm9CdWZmZXJlZEtleXMgPSAwOyBub0J1ZmZlcmVkVmFsdWVzID0gMDsgbm9CdWZmZXJlZFJlY29yZHMgPSAwOworICAgICAgdmFsdWVzRGVjb21wcmVzc2VkID0gZmFsc2U7CisKKyAgICAgIC8vUHJvY2VzcyBzeW5jCisgICAgICBpZiAoc3luYyAhPSBudWxsKSB7CisgICAgICAgIGluLnJlYWRJbnQoKTsKKyAgICAgICAgaW4ucmVhZEZ1bGx5KHN5bmNDaGVjayk7ICAgICAgICAgICAgICAgIC8vIHJlYWQgc3luY0NoZWNrCisgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhzeW5jLCBzeW5jQ2hlY2spKSAgICAvLyBjaGVjayBpdAorICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmlsZSBpcyBjb3JydXB0ISIpOworICAgICAgfQorICAgICAgc3luY1NlZW4gPSB0cnVlOworCisgICAgICAvLyBSZWFkIG51bWJlciBvZiByZWNvcmRzIGluIHRoaXMgYmxvY2sKKyAgICAgIG5vQnVmZmVyZWRSZWNvcmRzID0gV3JpdGFibGVVdGlscy5yZWFkVkludChpbik7CisgICAgICAKKyAgICAgIC8vIFJlYWQga2V5IGxlbmd0aHMgYW5kIGtleXMKKyAgICAgIHJlYWRCdWZmZXIoa2V5TGVuQnVmZmVyLCBrZXlMZW5JbkZpbHRlcik7CisgICAgICByZWFkQnVmZmVyKGtleUJ1ZmZlciwga2V5SW5GaWx0ZXIpOworICAgICAgbm9CdWZmZXJlZEtleXMgPSBub0J1ZmZlcmVkUmVjb3JkczsKKyAgICAgIAorICAgICAgLy8gUmVhZCB2YWx1ZSBsZW5ndGhzIGFuZCB2YWx1ZXMKKyAgICAgIGlmICghbGF6eURlY29tcHJlc3MpIHsKKyAgICAgICAgcmVhZEJ1ZmZlcih2YWxMZW5CdWZmZXIsIHZhbExlbkluRmlsdGVyKTsKKyAgICAgICAgcmVhZEJ1ZmZlcih2YWxCdWZmZXIsIHZhbEluRmlsdGVyKTsKKyAgICAgICAgbm9CdWZmZXJlZFZhbHVlcyA9IG5vQnVmZmVyZWRSZWNvcmRzOworICAgICAgICB2YWx1ZXNEZWNvbXByZXNzZWQgPSB0cnVlOworICAgICAgfQorICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBQb3NpdGlvbiB2YWxMZW5Jbi92YWxJbiB0byB0aGUgJ3ZhbHVlJyAKKyAgICAgKiBjb3JyZXNwb25kaW5nIHRvIHRoZSAnY3VycmVudCcga2V5IAorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgc2Vla1RvQ3VycmVudFZhbHVlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIGlmIChkZWNvbXByZXNzKSB7CisgICAgICAgICAgdmFsSW5GaWx0ZXIucmVzZXRTdGF0ZSgpOworICAgICAgICB9CisgICAgICAgIHZhbEJ1ZmZlci5yZXNldCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlICdibG9jaycgdG8gYmUgcmVhZAorICAgICAgICBpZiAobGF6eURlY29tcHJlc3MgJiYgIXZhbHVlc0RlY29tcHJlc3NlZCkgeworICAgICAgICAgIC8vIFJlYWQgdGhlIHZhbHVlIGxlbmd0aHMgYW5kIHZhbHVlcworICAgICAgICAgIHJlYWRCdWZmZXIodmFsTGVuQnVmZmVyLCB2YWxMZW5JbkZpbHRlcik7CisgICAgICAgICAgcmVhZEJ1ZmZlcih2YWxCdWZmZXIsIHZhbEluRmlsdGVyKTsKKyAgICAgICAgICBub0J1ZmZlcmVkVmFsdWVzID0gbm9CdWZmZXJlZFJlY29yZHM7CisgICAgICAgICAgdmFsdWVzRGVjb21wcmVzc2VkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuby4gb2YgYnl0ZXMgdG8gc2tpcAorICAgICAgICAvLyBOb3RlOiAnY3VycmVudCcga2V5IGhhcyBhbHJlYWR5IGJlZW4gcmVhZCEKKyAgICAgICAgaW50IHNraXBWYWxCeXRlcyA9IDA7CisgICAgICAgIGludCBjdXJyZW50S2V5ID0gbm9CdWZmZXJlZEtleXMgKyAxOyAgICAgICAgICAKKyAgICAgICAgZm9yIChpbnQgaT1ub0J1ZmZlcmVkVmFsdWVzOyBpID4gY3VycmVudEtleTsgLS1pKSB7CisgICAgICAgICAgc2tpcFZhbEJ5dGVzICs9IFdyaXRhYmxlVXRpbHMucmVhZFZJbnQodmFsTGVuSW4pOworICAgICAgICAgIC0tbm9CdWZmZXJlZFZhbHVlczsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gU2tpcCB0byB0aGUgJ3ZhbCcgY29ycmVzcG9uZGluZyB0byAnY3VycmVudCcga2V5CisgICAgICAgIGlmIChza2lwVmFsQnl0ZXMgPiAwKSB7CisgICAgICAgICAgaWYgKHZhbEluLnNraXBCeXRlcyhza2lwVmFsQnl0ZXMpICE9IHNraXBWYWxCeXRlcykgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gc2VlayB0byAiICsgY3VycmVudEtleSArIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIodGgpIHZhbHVlISIpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgJ3ZhbHVlJyBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXN0IHJlYWQgJ2tleScuCisgICAgICogQHBhcmFtIHZhbCA6IFRoZSAndmFsdWUnIHRvIGJlIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBnZXRDdXJyZW50VmFsdWUoV3JpdGFibGUgdmFsKSAKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQ29uZmlndXJhYmxlKSB7CisgICAgICAgICgoQ29uZmlndXJhYmxlKSB2YWwpLnNldENvbmYodGhpcy5jb25mKTsKKyAgICAgIH0KKworICAgICAgLy8gUG9zaXRpb24gc3RyZWFtIHRvICdjdXJyZW50JyB2YWx1ZQorICAgICAgc2Vla1RvQ3VycmVudFZhbHVlKCk7CisKKyAgICAgIGlmICghYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIHZhbC5yZWFkRmllbGRzKHZhbEluKTsKKyAgICAgICAgCisgICAgICAgIGlmICh2YWxJbi5yZWFkKCkgPiAwKSB7CisgICAgICAgICAgTE9HLmluZm8oImF2YWlsYWJsZSBieXRlczogIiArIHZhbEluLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24odmFsKyIgcmVhZCAiKyh2YWxCdWZmZXIuZ2V0UG9zaXRpb24oKS1rZXlMZW5ndGgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBieXRlcywgc2hvdWxkIHJlYWQgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWxCdWZmZXIuZ2V0TGVuZ3RoKCkta2V5TGVuZ3RoKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIEdldCB0aGUgdmFsdWUKKyAgICAgICAgaW50IHZhbExlbmd0aCA9IFdyaXRhYmxlVXRpbHMucmVhZFZJbnQodmFsTGVuSW4pOworICAgICAgICB2YWwucmVhZEZpZWxkcyh2YWxJbik7CisgICAgICAgIAorICAgICAgICAvLyBSZWFkIGFub3RoZXIgY29tcHJlc3NlZCAndmFsdWUnCisgICAgICAgIC0tbm9CdWZmZXJlZFZhbHVlczsKKyAgICAgICAgCisgICAgICAgIC8vIFNhbml0eSBjaGVjaworICAgICAgICBpZiAodmFsTGVuZ3RoIDwgMCkgeworICAgICAgICAgIExPRy5kZWJ1Zyh2YWwgKyAiIGlzIGEgemVyby1sZW5ndGggdmFsdWUiKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEdldCB0aGUgJ3ZhbHVlJyBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXN0IHJlYWQgJ2tleScuCisgICAgICogQHBhcmFtIHZhbCA6IFRoZSAndmFsdWUnIHRvIGJlIHJlYWQuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgT2JqZWN0IGdldEN1cnJlbnRWYWx1ZShPYmplY3QgdmFsKSAKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodmFsIGluc3RhbmNlb2YgQ29uZmlndXJhYmxlKSB7CisgICAgICAgICgoQ29uZmlndXJhYmxlKSB2YWwpLnNldENvbmYodGhpcy5jb25mKTsKKyAgICAgIH0KKworICAgICAgLy8gUG9zaXRpb24gc3RyZWFtIHRvICdjdXJyZW50JyB2YWx1ZQorICAgICAgc2Vla1RvQ3VycmVudFZhbHVlKCk7CisKKyAgICAgIGlmICghYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIHZhbCA9IGRlc2VyaWFsaXplVmFsdWUodmFsKTsKKyAgICAgICAgCisgICAgICAgIGlmICh2YWxJbi5yZWFkKCkgPiAwKSB7CisgICAgICAgICAgTE9HLmluZm8oImF2YWlsYWJsZSBieXRlczogIiArIHZhbEluLmF2YWlsYWJsZSgpKTsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24odmFsKyIgcmVhZCAiKyh2YWxCdWZmZXIuZ2V0UG9zaXRpb24oKS1rZXlMZW5ndGgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBieXRlcywgc2hvdWxkIHJlYWQgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWxCdWZmZXIuZ2V0TGVuZ3RoKCkta2V5TGVuZ3RoKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIEdldCB0aGUgdmFsdWUKKyAgICAgICAgaW50IHZhbExlbmd0aCA9IFdyaXRhYmxlVXRpbHMucmVhZFZJbnQodmFsTGVuSW4pOworICAgICAgICB2YWwgPSBkZXNlcmlhbGl6ZVZhbHVlKHZhbCk7CisgICAgICAgIAorICAgICAgICAvLyBSZWFkIGFub3RoZXIgY29tcHJlc3NlZCAndmFsdWUnCisgICAgICAgIC0tbm9CdWZmZXJlZFZhbHVlczsKKyAgICAgICAgCisgICAgICAgIC8vIFNhbml0eSBjaGVjaworICAgICAgICBpZiAodmFsTGVuZ3RoIDwgMCkgeworICAgICAgICAgIExPRy5kZWJ1Zyh2YWwgKyAiIGlzIGEgemVyby1sZW5ndGggdmFsdWUiKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHZhbDsKKworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgT2JqZWN0IGRlc2VyaWFsaXplVmFsdWUoT2JqZWN0IHZhbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiB2YWxEZXNlcmlhbGl6ZXIuZGVzZXJpYWxpemUodmFsKTsKKyAgICB9CisgICAgCisgICAgLyoqIFJlYWQgdGhlIG5leHQga2V5IGluIHRoZSBmaWxlIGludG8gPGNvZGU+a2V5PC9jb2RlPiwgc2tpcHBpbmcgaXRzCisgICAgICogdmFsdWUuICBUcnVlIGlmIGFub3RoZXIgZW50cnkgZXhpc3RzLCBhbmQgZmFsc2UgYXQgZW5kIG9mIGZpbGUuICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIG5leHQoV3JpdGFibGUga2V5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGtleS5nZXRDbGFzcygpICE9IGdldEtleUNsYXNzKCkpCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigid3Jvbmcga2V5IGNsYXNzOiAiK2tleS5nZXRDbGFzcygpLmdldE5hbWUoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIgaXMgbm90ICIra2V5Q2xhc3MpOworCisgICAgICBpZiAoIWJsb2NrQ29tcHJlc3NlZCkgeworICAgICAgICBvdXRCdWYucmVzZXQoKTsKKyAgICAgICAgCisgICAgICAgIGtleUxlbmd0aCA9IG5leHQob3V0QnVmKTsKKyAgICAgICAgaWYgKGtleUxlbmd0aCA8IDApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAKKyAgICAgICAgdmFsQnVmZmVyLnJlc2V0KG91dEJ1Zi5nZXREYXRhKCksIG91dEJ1Zi5nZXRMZW5ndGgoKSk7CisgICAgICAgIAorICAgICAgICBrZXkucmVhZEZpZWxkcyh2YWxCdWZmZXIpOworICAgICAgICB2YWxCdWZmZXIubWFyaygwKTsKKyAgICAgICAgaWYgKHZhbEJ1ZmZlci5nZXRQb3NpdGlvbigpICE9IGtleUxlbmd0aCkKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oa2V5ICsgIiByZWFkICIgKyB2YWxCdWZmZXIuZ2V0UG9zaXRpb24oKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYnl0ZXMsIHNob3VsZCByZWFkICIgKyBrZXlMZW5ndGgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy9SZXNldCBzeW5jU2VlbgorICAgICAgICBzeW5jU2VlbiA9IGZhbHNlOworICAgICAgICAKKyAgICAgICAgaWYgKG5vQnVmZmVyZWRLZXlzID09IDApIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZEJsb2NrKCk7CisgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVvZikgeworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaW50IGtleUxlbmd0aCA9IFdyaXRhYmxlVXRpbHMucmVhZFZJbnQoa2V5TGVuSW4pOworICAgICAgICAKKyAgICAgICAgLy8gU2FuaXR5IGNoZWNrCisgICAgICAgIGlmIChrZXlMZW5ndGggPCAwKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICAvL1JlYWQgYW5vdGhlciBjb21wcmVzc2VkICdrZXknCisgICAgICAgIGtleS5yZWFkRmllbGRzKGtleUluKTsKKyAgICAgICAgLS1ub0J1ZmZlcmVkS2V5czsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqIFJlYWQgdGhlIG5leHQga2V5L3ZhbHVlIHBhaXIgaW4gdGhlIGZpbGUgaW50byA8Y29kZT5rZXk8L2NvZGU+IGFuZAorICAgICAqIDxjb2RlPnZhbDwvY29kZT4uICBSZXR1cm5zIHRydWUgaWYgc3VjaCBhIHBhaXIgZXhpc3RzIGFuZCBmYWxzZSB3aGVuIGF0CisgICAgICogZW5kIG9mIGZpbGUgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gbmV4dChXcml0YWJsZSBrZXksIFdyaXRhYmxlIHZhbCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodmFsLmdldENsYXNzKCkgIT0gZ2V0VmFsdWVDbGFzcygpKQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIndyb25nIHZhbHVlIGNsYXNzOiAiK3ZhbCsiIGlzIG5vdCAiK3ZhbENsYXNzKTsKKworICAgICAgYm9vbGVhbiBtb3JlID0gbmV4dChrZXkpOworICAgICAgCisgICAgICBpZiAobW9yZSkgeworICAgICAgICBnZXRDdXJyZW50VmFsdWUodmFsKTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIG1vcmU7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJlYWQgYW5kIHJldHVybiB0aGUgbmV4dCByZWNvcmQgbGVuZ3RoLCBwb3RlbnRpYWxseSBza2lwcGluZyBvdmVyIAorICAgICAqIGEgc3luYyBibG9jay4KKyAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIG5leHQgcmVjb3JkIG9yIC0xIGlmIHRoZXJlIGlzIG5vIG5leHQgcmVjb3JkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgc3luY2hyb25pemVkIGludCByZWFkUmVjb3JkTGVuZ3RoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChpbi5nZXRQb3MoKSA+PSBlbmQpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgICAgfSAgICAgIAorICAgICAgaW50IGxlbmd0aCA9IGluLnJlYWRJbnQoKTsKKyAgICAgIGlmICh2ZXJzaW9uID4gMSAmJiBzeW5jICE9IG51bGwgJiYKKyAgICAgICAgICBsZW5ndGggPT0gU1lOQ19FU0NBUEUpIHsgICAgICAgICAgICAgIC8vIHByb2Nlc3MgYSBzeW5jIGVudHJ5CisgICAgICAgIGluLnJlYWRGdWxseShzeW5jQ2hlY2spOyAgICAgICAgICAgICAgICAvLyByZWFkIHN5bmNDaGVjaworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMoc3luYywgc3luY0NoZWNrKSkgICAgLy8gY2hlY2sgaXQKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZpbGUgaXMgY29ycnVwdCEiKTsKKyAgICAgICAgc3luY1NlZW4gPSB0cnVlOworICAgICAgICBpZiAoaW4uZ2V0UG9zKCkgPj0gZW5kKSB7CisgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGxlbmd0aCA9IGluLnJlYWRJbnQoKTsgICAgICAgICAgICAgICAgICAvLyByZS1yZWFkIGxlbmd0aAorICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3luY1NlZW4gPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICB9CisgICAgCisgICAgLyoqIFJlYWQgdGhlIG5leHQga2V5L3ZhbHVlIHBhaXIgaW4gdGhlIGZpbGUgaW50byA8Y29kZT5idWZmZXI8L2NvZGU+LgorICAgICAqIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUga2V5IHJlYWQsIG9yIC0xIGlmIGF0IGVuZCBvZiBmaWxlLiAgVGhlIGxlbmd0aAorICAgICAqIG9mIHRoZSB2YWx1ZSBtYXkgYmUgY29tcHV0ZWQgYnkgY2FsbGluZyBidWZmZXIuZ2V0TGVuZ3RoKCkgYmVmb3JlIGFuZAorICAgICAqIGFmdGVyIGNhbGxzIHRvIHRoaXMgbWV0aG9kLiAqLworICAgIC8qKiBAZGVwcmVjYXRlZCBDYWxsIHtAbGluayAjbmV4dFJhdyhEYXRhT3V0cHV0QnVmZmVyLFNlcXVlbmNlRmlsZS5WYWx1ZUJ5dGVzKX0uICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgbmV4dChEYXRhT3V0cHV0QnVmZmVyIGJ1ZmZlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIFVuc3VwcG9ydGVkIGZvciBibG9jay1jb21wcmVzc2VkIHNlcXVlbmNlIGZpbGVzCisgICAgICBpZiAoYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgY2FsbCBmb3IgYmxvY2stY29tcHJlc3NlZCIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBTZXF1ZW5jZUZpbGVzIC0gdXNlIFNlcXVlbmNlRmlsZS5SZWFkZXIubmV4dChEYXRhT3V0cHV0U3RyZWFtLCBWYWx1ZUJ5dGVzKSIpOworICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgaW50IGxlbmd0aCA9IHJlYWRSZWNvcmRMZW5ndGgoKTsKKyAgICAgICAgaWYgKGxlbmd0aCA9PSAtMSkgeworICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbnQga2V5TGVuZ3RoID0gaW4ucmVhZEludCgpOworICAgICAgICBidWZmZXIud3JpdGUoaW4sIGxlbmd0aCk7CisgICAgICAgIHJldHVybiBrZXlMZW5ndGg7CisgICAgICB9IGNhdGNoIChDaGVja3N1bUV4Y2VwdGlvbiBlKSB7ICAgICAgICAgICAgIC8vIGNoZWNrc3VtIGZhaWx1cmUKKyAgICAgICAgaGFuZGxlQ2hlY2tzdW1FeGNlcHRpb24oZSk7CisgICAgICAgIHJldHVybiBuZXh0KGJ1ZmZlcik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFZhbHVlQnl0ZXMgY3JlYXRlVmFsdWVCeXRlcygpIHsKKyAgICAgIFZhbHVlQnl0ZXMgdmFsID0gbnVsbDsKKyAgICAgIGlmICghZGVjb21wcmVzcyB8fCBibG9ja0NvbXByZXNzZWQpIHsKKyAgICAgICAgdmFsID0gbmV3IFVuY29tcHJlc3NlZEJ5dGVzKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICB2YWwgPSBuZXcgQ29tcHJlc3NlZEJ5dGVzKGNvZGVjKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB2YWw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCAncmF3JyByZWNvcmRzLgorICAgICAqIEBwYXJhbSBrZXkgLSBUaGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGtleSBpcyByZWFkCisgICAgICogQHBhcmFtIHZhbCAtIFRoZSAncmF3JyB2YWx1ZQorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdG90YWwgcmVjb3JkIGxlbmd0aCBvciAtMSBmb3IgZW5kIG9mIGZpbGUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBpbnQgbmV4dFJhdyhEYXRhT3V0cHV0QnVmZmVyIGtleSwgVmFsdWVCeXRlcyB2YWwpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIGludCBsZW5ndGggPSByZWFkUmVjb3JkTGVuZ3RoKCk7CisgICAgICAgIGlmIChsZW5ndGggPT0gLTEpIHsKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaW50IGtleUxlbmd0aCA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgaW50IHZhbExlbmd0aCA9IGxlbmd0aCAtIGtleUxlbmd0aDsKKyAgICAgICAga2V5LndyaXRlKGluLCBrZXlMZW5ndGgpOworICAgICAgICBpZiAoZGVjb21wcmVzcykgeworICAgICAgICAgIENvbXByZXNzZWRCeXRlcyB2YWx1ZSA9IChDb21wcmVzc2VkQnl0ZXMpdmFsOworICAgICAgICAgIHZhbHVlLnJlc2V0KGluLCB2YWxMZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFVuY29tcHJlc3NlZEJ5dGVzIHZhbHVlID0gKFVuY29tcHJlc3NlZEJ5dGVzKXZhbDsKKyAgICAgICAgICB2YWx1ZS5yZXNldChpbiwgdmFsTGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcmV0dXJuIGxlbmd0aDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vUmVzZXQgc3luY1NlZW4KKyAgICAgICAgc3luY1NlZW4gPSBmYWxzZTsKKyAgICAgICAgCisgICAgICAgIC8vIFJlYWQgJ2tleScKKyAgICAgICAgaWYgKG5vQnVmZmVyZWRLZXlzID09IDApIHsKKyAgICAgICAgICBpZiAoaW4uZ2V0UG9zKCkgPj0gZW5kKSAKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICAgIHRyeSB7IAorICAgICAgICAgICAgcmVhZEJsb2NrKCk7CisgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVvZikgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQga2V5TGVuZ3RoID0gV3JpdGFibGVVdGlscy5yZWFkVkludChrZXlMZW5Jbik7CisgICAgICAgIGlmIChrZXlMZW5ndGggPCAwKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ6ZXJvIGxlbmd0aCBrZXkgZm91bmQhIik7CisgICAgICAgIH0KKyAgICAgICAga2V5LndyaXRlKGtleUluLCBrZXlMZW5ndGgpOworICAgICAgICAtLW5vQnVmZmVyZWRLZXlzOworICAgICAgICAKKyAgICAgICAgLy8gUmVhZCByYXcgJ3ZhbHVlJworICAgICAgICBzZWVrVG9DdXJyZW50VmFsdWUoKTsKKyAgICAgICAgaW50IHZhbExlbmd0aCA9IFdyaXRhYmxlVXRpbHMucmVhZFZJbnQodmFsTGVuSW4pOworICAgICAgICBVbmNvbXByZXNzZWRCeXRlcyByYXdWYWx1ZSA9IChVbmNvbXByZXNzZWRCeXRlcyl2YWw7CisgICAgICAgIHJhd1ZhbHVlLnJlc2V0KHZhbEluLCB2YWxMZW5ndGgpOworICAgICAgICAtLW5vQnVmZmVyZWRWYWx1ZXM7CisgICAgICAgIAorICAgICAgICByZXR1cm4gKGtleUxlbmd0aCt2YWxMZW5ndGgpOworICAgICAgfQorICAgICAgCisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCAncmF3JyBrZXlzLgorICAgICAqIEBwYXJhbSBrZXkgLSBUaGUgYnVmZmVyIGludG8gd2hpY2ggdGhlIGtleSBpcyByZWFkCisgICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBrZXkgbGVuZ3RoIG9yIC0xIGZvciBlbmQgb2YgZmlsZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IG5leHRSYXdLZXkoRGF0YU91dHB1dEJ1ZmZlciBrZXkpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghYmxvY2tDb21wcmVzc2VkKSB7CisgICAgICAgIHJlY29yZExlbmd0aCA9IHJlYWRSZWNvcmRMZW5ndGgoKTsKKyAgICAgICAgaWYgKHJlY29yZExlbmd0aCA9PSAtMSkgeworICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBrZXlMZW5ndGggPSBpbi5yZWFkSW50KCk7CisgICAgICAgIGtleS53cml0ZShpbiwga2V5TGVuZ3RoKTsKKyAgICAgICAgcmV0dXJuIGtleUxlbmd0aDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vUmVzZXQgc3luY1NlZW4KKyAgICAgICAgc3luY1NlZW4gPSBmYWxzZTsKKyAgICAgICAgCisgICAgICAgIC8vIFJlYWQgJ2tleScKKyAgICAgICAgaWYgKG5vQnVmZmVyZWRLZXlzID09IDApIHsKKyAgICAgICAgICBpZiAoaW4uZ2V0UG9zKCkgPj0gZW5kKSAKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICAgIHRyeSB7IAorICAgICAgICAgICAgcmVhZEJsb2NrKCk7CisgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVvZikgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQga2V5TGVuZ3RoID0gV3JpdGFibGVVdGlscy5yZWFkVkludChrZXlMZW5Jbik7CisgICAgICAgIGlmIChrZXlMZW5ndGggPCAwKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ6ZXJvIGxlbmd0aCBrZXkgZm91bmQhIik7CisgICAgICAgIH0KKyAgICAgICAga2V5LndyaXRlKGtleUluLCBrZXlMZW5ndGgpOworICAgICAgICAtLW5vQnVmZmVyZWRLZXlzOworICAgICAgICAKKyAgICAgICAgcmV0dXJuIGtleUxlbmd0aDsKKyAgICAgIH0KKyAgICAgIAorICAgIH0KKworICAgIC8qKiBSZWFkIHRoZSBuZXh0IGtleSBpbiB0aGUgZmlsZSwgc2tpcHBpbmcgaXRzCisgICAgICogdmFsdWUuICBSZXR1cm4gbnVsbCBhdCBlbmQgb2YgZmlsZS4gKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCBuZXh0KE9iamVjdCBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5LmdldENsYXNzKCkgIT0gZ2V0S2V5Q2xhc3MoKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIndyb25nIGtleSBjbGFzczogIitrZXkuZ2V0Q2xhc3MoKS5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiIGlzIG5vdCAiK2tleUNsYXNzKTsKKyAgICAgIH0KKworICAgICAgaWYgKCFibG9ja0NvbXByZXNzZWQpIHsKKyAgICAgICAgb3V0QnVmLnJlc2V0KCk7CisgICAgICAgIAorICAgICAgICBrZXlMZW5ndGggPSBuZXh0KG91dEJ1Zik7CisgICAgICAgIGlmIChrZXlMZW5ndGggPCAwKQorICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAKKyAgICAgICAgdmFsQnVmZmVyLnJlc2V0KG91dEJ1Zi5nZXREYXRhKCksIG91dEJ1Zi5nZXRMZW5ndGgoKSk7CisgICAgICAgIAorICAgICAgICBrZXkgPSBkZXNlcmlhbGl6ZUtleShrZXkpOworICAgICAgICB2YWxCdWZmZXIubWFyaygwKTsKKyAgICAgICAgaWYgKHZhbEJ1ZmZlci5nZXRQb3NpdGlvbigpICE9IGtleUxlbmd0aCkKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oa2V5ICsgIiByZWFkICIgKyB2YWxCdWZmZXIuZ2V0UG9zaXRpb24oKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYnl0ZXMsIHNob3VsZCByZWFkICIgKyBrZXlMZW5ndGgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy9SZXNldCBzeW5jU2VlbgorICAgICAgICBzeW5jU2VlbiA9IGZhbHNlOworICAgICAgICAKKyAgICAgICAgaWYgKG5vQnVmZmVyZWRLZXlzID09IDApIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmVhZEJsb2NrKCk7CisgICAgICAgICAgfSBjYXRjaCAoRU9GRXhjZXB0aW9uIGVvZikgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpbnQga2V5TGVuZ3RoID0gV3JpdGFibGVVdGlscy5yZWFkVkludChrZXlMZW5Jbik7CisgICAgICAgIAorICAgICAgICAvLyBTYW5pdHkgY2hlY2sKKyAgICAgICAgaWYgKGtleUxlbmd0aCA8IDApIHsKKyAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy9SZWFkIGFub3RoZXIgY29tcHJlc3NlZCAna2V5JworICAgICAgICBrZXkgPSBkZXNlcmlhbGl6ZUtleShrZXkpOworICAgICAgICAtLW5vQnVmZmVyZWRLZXlzOworICAgICAgfQorCisgICAgICByZXR1cm4ga2V5OworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgT2JqZWN0IGRlc2VyaWFsaXplS2V5KE9iamVjdCBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4ga2V5RGVzZXJpYWxpemVyLmRlc2VyaWFsaXplKGtleSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmVhZCAncmF3JyB2YWx1ZXMuCisgICAgICogQHBhcmFtIHZhbCAtIFRoZSAncmF3JyB2YWx1ZQorICAgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgdmFsdWUgbGVuZ3RoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IG5leHRSYXdWYWx1ZShWYWx1ZUJ5dGVzIHZhbCkgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgCisgICAgICAvLyBQb3NpdGlvbiBzdHJlYW0gdG8gY3VycmVudCB2YWx1ZQorICAgICAgc2Vla1RvQ3VycmVudFZhbHVlKCk7CisgCisgICAgICBpZiAoIWJsb2NrQ29tcHJlc3NlZCkgeworICAgICAgICBpbnQgdmFsTGVuZ3RoID0gcmVjb3JkTGVuZ3RoIC0ga2V5TGVuZ3RoOworICAgICAgICBpZiAoZGVjb21wcmVzcykgeworICAgICAgICAgIENvbXByZXNzZWRCeXRlcyB2YWx1ZSA9IChDb21wcmVzc2VkQnl0ZXMpdmFsOworICAgICAgICAgIHZhbHVlLnJlc2V0KGluLCB2YWxMZW5ndGgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFVuY29tcHJlc3NlZEJ5dGVzIHZhbHVlID0gKFVuY29tcHJlc3NlZEJ5dGVzKXZhbDsKKyAgICAgICAgICB2YWx1ZS5yZXNldChpbiwgdmFsTGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICAgCisgICAgICAgIHJldHVybiB2YWxMZW5ndGg7CisgICAgICB9IGVsc2UgeworICAgICAgICBpbnQgdmFsTGVuZ3RoID0gV3JpdGFibGVVdGlscy5yZWFkVkludCh2YWxMZW5Jbik7CisgICAgICAgIFVuY29tcHJlc3NlZEJ5dGVzIHJhd1ZhbHVlID0gKFVuY29tcHJlc3NlZEJ5dGVzKXZhbDsKKyAgICAgICAgcmF3VmFsdWUucmVzZXQodmFsSW4sIHZhbExlbmd0aCk7CisgICAgICAgIC0tbm9CdWZmZXJlZFZhbHVlczsKKyAgICAgICAgcmV0dXJuIHZhbExlbmd0aDsKKyAgICAgIH0KKyAgICAgIAorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBoYW5kbGVDaGVja3N1bUV4Y2VwdGlvbihDaGVja3N1bUV4Y2VwdGlvbiBlKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0aGlzLmNvbmYuZ2V0Qm9vbGVhbigiaW8uc2tpcC5jaGVja3N1bS5lcnJvcnMiLCBmYWxzZSkpIHsKKyAgICAgICAgTE9HLndhcm4oIkJhZCBjaGVja3N1bSBhdCAiK2dldFBvc2l0aW9uKCkrIi4gU2tpcHBpbmcgZW50cmllcy4iKTsKKyAgICAgICAgc3luYyhnZXRQb3NpdGlvbigpK3RoaXMuY29uZi5nZXRJbnQoImlvLmJ5dGVzLnBlci5jaGVja3N1bSIsIDUxMikpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogU2V0IHRoZSBjdXJyZW50IGJ5dGUgcG9zaXRpb24gaW4gdGhlIGlucHV0IGZpbGUuCisgICAgICoKKyAgICAgKiA8cD5UaGUgcG9zaXRpb24gcGFzc2VkIG11c3QgYmUgYSBwb3NpdGlvbiByZXR1cm5lZCBieSB7QGxpbmsKKyAgICAgKiBTZXF1ZW5jZUZpbGUuV3JpdGVyI2dldExlbmd0aCgpfSB3aGVuIHdyaXRpbmcgdGhpcyBmaWxlLiAgVG8gc2VlayB0byBhbiBhcmJpdHJhcnkKKyAgICAgKiBwb3NpdGlvbiwgdXNlIHtAbGluayBTZXF1ZW5jZUZpbGUuUmVhZGVyI3N5bmMobG9uZyl9LgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZWVrKGxvbmcgcG9zaXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpbi5zZWVrKHBvc2l0aW9uKTsKKyAgICAgIGlmIChibG9ja0NvbXByZXNzZWQpIHsgICAgICAgICAgICAgICAgICAgICAgLy8gdHJpZ2dlciBibG9jayByZWFkCisgICAgICAgIG5vQnVmZmVyZWRLZXlzID0gMDsKKyAgICAgICAgdmFsdWVzRGVjb21wcmVzc2VkID0gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogU2VlayB0byB0aGUgbmV4dCBzeW5jIG1hcmsgcGFzdCBhIGdpdmVuIHBvc2l0aW9uLiovCisgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN5bmMobG9uZyBwb3NpdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChwb3NpdGlvbitTWU5DX1NJWkUgPj0gZW5kKSB7CisgICAgICAgIHNlZWsoZW5kKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICB0cnkgeworICAgICAgICBzZWVrKHBvc2l0aW9uKzQpOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGVzY2FwZQorICAgICAgICBpbi5yZWFkRnVsbHkoc3luY0NoZWNrKTsKKyAgICAgICAgaW50IHN5bmNMZW4gPSBzeW5jLmxlbmd0aDsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGluLmdldFBvcygpIDwgZW5kOyBpKyspIHsKKyAgICAgICAgICBpbnQgaiA9IDA7CisgICAgICAgICAgZm9yICg7IGogPCBzeW5jTGVuOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChzeW5jW2pdICE9IHN5bmNDaGVja1soaStqKSVzeW5jTGVuXSkKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChqID09IHN5bmNMZW4pIHsKKyAgICAgICAgICAgIGluLnNlZWsoaW4uZ2V0UG9zKCkgLSBTWU5DX1NJWkUpOyAgICAgLy8gcG9zaXRpb24gYmVmb3JlIHN5bmMKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgc3luY0NoZWNrW2klc3luY0xlbl0gPSBpbi5yZWFkQnl0ZSgpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChDaGVja3N1bUV4Y2VwdGlvbiBlKSB7ICAgICAgICAgICAgIC8vIGNoZWNrc3VtIGZhaWx1cmUKKyAgICAgICAgaGFuZGxlQ2hlY2tzdW1FeGNlcHRpb24oZSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqIFJldHVybnMgdHJ1ZSBpZmYgdGhlIHByZXZpb3VzIGNhbGwgdG8gbmV4dCBwYXNzZWQgYSBzeW5jIG1hcmsuKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzeW5jU2VlbigpIHsgcmV0dXJuIHN5bmNTZWVuOyB9CisKKyAgICAvKiogUmV0dXJuIHRoZSBjdXJyZW50IGJ5dGUgcG9zaXRpb24gaW4gdGhlIGlucHV0IGZpbGUuICovCisgICAgcHVibGljIHN5bmNocm9uaXplZCBsb25nIGdldFBvc2l0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBpbi5nZXRQb3MoKTsKKyAgICB9CisKKyAgICAvKiogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZmlsZS4gKi8KKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgcmV0dXJuIGZpbGUudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgfQorCisgIC8qKiBTb3J0cyBrZXkvdmFsdWUgcGFpcnMgaW4gYSBzZXF1ZW5jZS1mb3JtYXQgZmlsZS4KKyAgICoKKyAgICogPHA+Rm9yIGJlc3QgcGVyZm9ybWFuY2UsIGFwcGxpY2F0aW9ucyBzaG91bGQgbWFrZSBzdXJlIHRoYXQgdGhlIHtAbGluaworICAgKiBXcml0YWJsZSNyZWFkRmllbGRzKERhdGFJbnB1dCl9IGltcGxlbWVudGF0aW9uIG9mIHRoZWlyIGtleXMgaXMKKyAgICogdmVyeSBlZmZpY2llbnQuICBJbiBwYXJ0aWN1bGFyLCBpdCBzaG91bGQgYXZvaWQgYWxsb2NhdGluZyBtZW1vcnkuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIFNvcnRlciB7CisKKyAgICBwcml2YXRlIFJhd0NvbXBhcmF0b3IgY29tcGFyYXRvcjsKKworICAgIHByaXZhdGUgTWVyZ2VTb3J0IG1lcmdlU29ydDsgLy90aGUgaW1wbGVtZW50YXRpb24gb2YgbWVyZ2Ugc29ydAorICAgIAorICAgIHByaXZhdGUgUGF0aFtdIGluRmlsZXM7ICAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiBtZXJnaW5nIG9yIHNvcnRpbmcKKworICAgIHByaXZhdGUgUGF0aCBvdXRGaWxlOworCisgICAgcHJpdmF0ZSBpbnQgbWVtb3J5OyAvLyBieXRlcworICAgIHByaXZhdGUgaW50IGZhY3RvcjsgLy8gbWVyZ2VkIHBlciBwYXNzCisKKyAgICBwcml2YXRlIEZpbGVTeXN0ZW0gZnMgPSBudWxsOworCisgICAgcHJpdmF0ZSBDbGFzcyBrZXlDbGFzczsKKyAgICBwcml2YXRlIENsYXNzIHZhbENsYXNzOworCisgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uIGNvbmY7CisgICAgCisgICAgcHJpdmF0ZSBQcm9ncmVzc2FibGUgcHJvZ3Jlc3NhYmxlID0gbnVsbDsKKworICAgIC8qKiBTb3J0IGFuZCBtZXJnZSBmaWxlcyBjb250YWluaW5nIHRoZSBuYW1lZCBjbGFzc2VzLiAqLworICAgIHB1YmxpYyBTb3J0ZXIoRmlsZVN5c3RlbSBmcywgQ2xhc3M8PyBleHRlbmRzIFdyaXRhYmxlQ29tcGFyYWJsZT4ga2V5Q2xhc3MsCisgICAgICAgICAgICAgICAgICBDbGFzcyB2YWxDbGFzcywgQ29uZmlndXJhdGlvbiBjb25mKSAgeworICAgICAgdGhpcyhmcywgV3JpdGFibGVDb21wYXJhdG9yLmdldChrZXlDbGFzcyksIGtleUNsYXNzLCB2YWxDbGFzcywgY29uZik7CisgICAgfQorCisgICAgLyoqIFNvcnQgYW5kIG1lcmdlIHVzaW5nIGFuIGFyYml0cmFyeSB7QGxpbmsgUmF3Q29tcGFyYXRvcn0uICovCisgICAgcHVibGljIFNvcnRlcihGaWxlU3lzdGVtIGZzLCBSYXdDb21wYXJhdG9yIGNvbXBhcmF0b3IsIENsYXNzIGtleUNsYXNzLCAKKyAgICAgICAgICAgICAgICAgIENsYXNzIHZhbENsYXNzLCBDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICAgIHRoaXMuZnMgPSBmczsKKyAgICAgIHRoaXMuY29tcGFyYXRvciA9IGNvbXBhcmF0b3I7CisgICAgICB0aGlzLmtleUNsYXNzID0ga2V5Q2xhc3M7CisgICAgICB0aGlzLnZhbENsYXNzID0gdmFsQ2xhc3M7CisgICAgICB0aGlzLm1lbW9yeSA9IGNvbmYuZ2V0SW50KCJpby5zb3J0Lm1iIiwgMTAwKSAqIDEwMjQgKiAxMDI0OworICAgICAgdGhpcy5mYWN0b3IgPSBjb25mLmdldEludCgiaW8uc29ydC5mYWN0b3IiLCAxMDApOworICAgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB9CisKKyAgICAvKiogU2V0IHRoZSBudW1iZXIgb2Ygc3RyZWFtcyB0byBtZXJnZSBhdCBvbmNlLiovCisgICAgcHVibGljIHZvaWQgc2V0RmFjdG9yKGludCBmYWN0b3IpIHsgdGhpcy5mYWN0b3IgPSBmYWN0b3I7IH0KKworICAgIC8qKiBHZXQgdGhlIG51bWJlciBvZiBzdHJlYW1zIHRvIG1lcmdlIGF0IG9uY2UuKi8KKyAgICBwdWJsaWMgaW50IGdldEZhY3RvcigpIHsgcmV0dXJuIGZhY3RvcjsgfQorCisgICAgLyoqIFNldCB0aGUgdG90YWwgYW1vdW50IG9mIGJ1ZmZlciBtZW1vcnksIGluIGJ5dGVzLiovCisgICAgcHVibGljIHZvaWQgc2V0TWVtb3J5KGludCBtZW1vcnkpIHsgdGhpcy5tZW1vcnkgPSBtZW1vcnk7IH0KKworICAgIC8qKiBHZXQgdGhlIHRvdGFsIGFtb3VudCBvZiBidWZmZXIgbWVtb3J5LCBpbiBieXRlcy4qLworICAgIHB1YmxpYyBpbnQgZ2V0TWVtb3J5KCkgeyByZXR1cm4gbWVtb3J5OyB9CisKKyAgICAvKiogU2V0IHRoZSBwcm9ncmVzc2FibGUgb2JqZWN0IGluIG9yZGVyIHRvIHJlcG9ydCBwcm9ncmVzcy4gKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRQcm9ncmVzc2FibGUoUHJvZ3Jlc3NhYmxlIHByb2dyZXNzYWJsZSkgeworICAgICAgdGhpcy5wcm9ncmVzc2FibGUgPSBwcm9ncmVzc2FibGU7CisgICAgfQorICAgIAorICAgIC8qKiAKKyAgICAgKiBQZXJmb3JtIGEgZmlsZSBzb3J0IGZyb20gYSBzZXQgb2YgaW5wdXQgZmlsZXMgaW50byBhbiBvdXRwdXQgZmlsZS4KKyAgICAgKiBAcGFyYW0gaW5GaWxlcyB0aGUgZmlsZXMgdG8gYmUgc29ydGVkCisgICAgICogQHBhcmFtIG91dEZpbGUgdGhlIHNvcnRlZCBvdXRwdXQgZmlsZQorICAgICAqIEBwYXJhbSBkZWxldGVJbnB1dCBzaG91bGQgdGhlIGlucHV0IGZpbGVzIGJlIGRlbGV0ZWQgYXMgdGhleSBhcmUgcmVhZD8KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzb3J0KFBhdGhbXSBpbkZpbGVzLCBQYXRoIG91dEZpbGUsCisgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGRlbGV0ZUlucHV0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGZzLmV4aXN0cyhvdXRGaWxlKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImFscmVhZHkgZXhpc3RzOiAiICsgb3V0RmlsZSk7CisgICAgICB9CisKKyAgICAgIHRoaXMuaW5GaWxlcyA9IGluRmlsZXM7CisgICAgICB0aGlzLm91dEZpbGUgPSBvdXRGaWxlOworCisgICAgICBpbnQgc2VnbWVudHMgPSBzb3J0UGFzcyhkZWxldGVJbnB1dCk7CisgICAgICBpZiAoc2VnbWVudHMgPiAxKSB7CisgICAgICAgIG1lcmdlUGFzcyhvdXRGaWxlLmdldFBhcmVudCgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogCisgICAgICogUGVyZm9ybSBhIGZpbGUgc29ydCBmcm9tIGEgc2V0IG9mIGlucHV0IGZpbGVzIGFuZCByZXR1cm4gYW4gaXRlcmF0b3IuCisgICAgICogQHBhcmFtIGluRmlsZXMgdGhlIGZpbGVzIHRvIGJlIHNvcnRlZAorICAgICAqIEBwYXJhbSB0ZW1wRGlyIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGVtcCBmaWxlcyBhcmUgY3JlYXRlZCBkdXJpbmcgc29ydAorICAgICAqIEBwYXJhbSBkZWxldGVJbnB1dCBzaG91bGQgdGhlIGlucHV0IGZpbGVzIGJlIGRlbGV0ZWQgYXMgdGhleSBhcmUgcmVhZD8KKyAgICAgKiBAcmV0dXJuIGl0ZXJhdG9yIHRoZSBSYXdLZXlWYWx1ZUl0ZXJhdG9yCisgICAgICovCisgICAgcHVibGljIFJhd0tleVZhbHVlSXRlcmF0b3Igc29ydEFuZEl0ZXJhdGUoUGF0aFtdIGluRmlsZXMsIFBhdGggdGVtcERpciwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkZWxldGVJbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIFBhdGggb3V0RmlsZSA9IG5ldyBQYXRoKHRlbXBEaXIgKyBQYXRoLlNFUEFSQVRPUiArICJhbGwuMiIpOworICAgICAgaWYgKGZzLmV4aXN0cyhvdXRGaWxlKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImFscmVhZHkgZXhpc3RzOiAiICsgb3V0RmlsZSk7CisgICAgICB9CisgICAgICB0aGlzLmluRmlsZXMgPSBpbkZpbGVzOworICAgICAgLy9vdXRGaWxlIHdpbGwgYmFzaWNhbGx5IGJlIHVzZWQgYXMgcHJlZml4IGZvciB0ZW1wIGZpbGVzIGluIHRoZSBjYXNlcworICAgICAgLy93aGVyZSBzb3J0IG91dHB1dHMgbXVsdGlwbGUgc29ydGVkIHNlZ21lbnRzLiBGb3IgdGhlIHNpbmdsZSBzZWdtZW50CisgICAgICAvL2Nhc2UsIHRoZSBvdXRwdXRGaWxlIGl0c2VsZiB3aWxsIGNvbnRhaW4gdGhlIHNvcnRlZCBkYXRhIGZvciB0aGF0CisgICAgICAvL3NlZ21lbnQKKyAgICAgIHRoaXMub3V0RmlsZSA9IG91dEZpbGU7CisKKyAgICAgIGludCBzZWdtZW50cyA9IHNvcnRQYXNzKGRlbGV0ZUlucHV0KTsKKyAgICAgIGlmIChzZWdtZW50cyA+IDEpCisgICAgICAgIHJldHVybiBtZXJnZShvdXRGaWxlLnN1ZmZpeCgiLjAiKSwgb3V0RmlsZS5zdWZmaXgoIi4wLmluZGV4IiksIAorICAgICAgICAgICAgICAgICAgICAgdGVtcERpcik7CisgICAgICBlbHNlIGlmIChzZWdtZW50cyA9PSAxKQorICAgICAgICByZXR1cm4gbWVyZ2UobmV3IFBhdGhbXXtvdXRGaWxlfSwgdHJ1ZSwgdGVtcERpcik7CisgICAgICBlbHNlIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoZSBiYWNrd2FyZHMgY29tcGF0aWJsZSBpbnRlcmZhY2UgdG8gc29ydC4KKyAgICAgKiBAcGFyYW0gaW5GaWxlIHRoZSBpbnB1dCBmaWxlIHRvIHNvcnQKKyAgICAgKiBAcGFyYW0gb3V0RmlsZSB0aGUgc29ydGVkIG91dHB1dCBmaWxlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc29ydChQYXRoIGluRmlsZSwgUGF0aCBvdXRGaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgc29ydChuZXcgUGF0aFtde2luRmlsZX0sIG91dEZpbGUsIGZhbHNlKTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBpbnQgc29ydFBhc3MoYm9vbGVhbiBkZWxldGVJbnB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIExPRy5kZWJ1ZygicnVubmluZyBzb3J0IHBhc3MiKTsKKyAgICAgIFNvcnRQYXNzIHNvcnRQYXNzID0gbmV3IFNvcnRQYXNzKCk7ICAgICAgICAgLy8gbWFrZSB0aGUgU29ydFBhc3MKKyAgICAgIHNvcnRQYXNzLnNldFByb2dyZXNzYWJsZShwcm9ncmVzc2FibGUpOworICAgICAgbWVyZ2VTb3J0ID0gbmV3IE1lcmdlU29ydChzb3J0UGFzcy5uZXcgU2VxRmlsZUNvbXBhcmF0b3IoKSk7CisgICAgICB0cnkgeworICAgICAgICByZXR1cm4gc29ydFBhc3MucnVuKGRlbGV0ZUlucHV0KTsgICAgICAgICAvLyBydW4gaXQKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHNvcnRQYXNzLmNsb3NlKCk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsb3NlIGl0CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBTb3J0UGFzcyB7CisgICAgICBwcml2YXRlIGludCBtZW1vcnlMaW1pdCA9IG1lbW9yeS80OworICAgICAgcHJpdmF0ZSBpbnQgcmVjb3JkTGltaXQgPSAxMDAwMDAwOworICAgICAgCisgICAgICBwcml2YXRlIERhdGFPdXRwdXRCdWZmZXIgcmF3S2V5cyA9IG5ldyBEYXRhT3V0cHV0QnVmZmVyKCk7CisgICAgICBwcml2YXRlIGJ5dGVbXSByYXdCdWZmZXI7CisKKyAgICAgIHByaXZhdGUgaW50W10ga2V5T2Zmc2V0cyA9IG5ldyBpbnRbMTAyNF07CisgICAgICBwcml2YXRlIGludFtdIHBvaW50ZXJzID0gbmV3IGludFtrZXlPZmZzZXRzLmxlbmd0aF07CisgICAgICBwcml2YXRlIGludFtdIHBvaW50ZXJzQ29weSA9IG5ldyBpbnRba2V5T2Zmc2V0cy5sZW5ndGhdOworICAgICAgcHJpdmF0ZSBpbnRbXSBrZXlMZW5ndGhzID0gbmV3IGludFtrZXlPZmZzZXRzLmxlbmd0aF07CisgICAgICBwcml2YXRlIFZhbHVlQnl0ZXNbXSByYXdWYWx1ZXMgPSBuZXcgVmFsdWVCeXRlc1trZXlPZmZzZXRzLmxlbmd0aF07CisgICAgICAKKyAgICAgIHByaXZhdGUgQXJyYXlMaXN0IHNlZ21lbnRMZW5ndGhzID0gbmV3IEFycmF5TGlzdCgpOworICAgICAgCisgICAgICBwcml2YXRlIFJlYWRlciBpbiA9IG51bGw7CisgICAgICBwcml2YXRlIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgcHJpdmF0ZSBGU0RhdGFPdXRwdXRTdHJlYW0gaW5kZXhPdXQgPSBudWxsOworICAgICAgcHJpdmF0ZSBQYXRoIG91dE5hbWU7CisKKyAgICAgIHByaXZhdGUgUHJvZ3Jlc3NhYmxlIHByb2dyZXNzYWJsZSA9IG51bGw7CisKKyAgICAgIHB1YmxpYyBpbnQgcnVuKGJvb2xlYW4gZGVsZXRlSW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBzZWdtZW50cyA9IDA7CisgICAgICAgIGludCBjdXJyZW50RmlsZSA9IDA7CisgICAgICAgIGJvb2xlYW4gYXRFb2YgPSAoY3VycmVudEZpbGUgPj0gaW5GaWxlcy5sZW5ndGgpOworICAgICAgICBib29sZWFuIGlzQ29tcHJlc3NlZCA9IGZhbHNlOworICAgICAgICBib29sZWFuIGlzQmxvY2tDb21wcmVzc2VkID0gZmFsc2U7CisgICAgICAgIENvbXByZXNzaW9uQ29kZWMgY29kZWMgPSBudWxsOworICAgICAgICBzZWdtZW50TGVuZ3Rocy5jbGVhcigpOworICAgICAgICBpZiAoYXRFb2YpIHsKKyAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gSW5pdGlhbGl6ZQorICAgICAgICBpbiA9IG5ldyBSZWFkZXIoZnMsIGluRmlsZXNbY3VycmVudEZpbGVdLCBjb25mKTsKKyAgICAgICAgaXNDb21wcmVzc2VkID0gaW4uaXNDb21wcmVzc2VkKCk7CisgICAgICAgIGlzQmxvY2tDb21wcmVzc2VkID0gaW4uaXNCbG9ja0NvbXByZXNzZWQoKTsKKyAgICAgICAgY29kZWMgPSBpbi5nZXRDb21wcmVzc2lvbkNvZGVjKCk7CisgICAgICAgIAorICAgICAgICBmb3IgKGludCBpPTA7IGkgPCByYXdWYWx1ZXMubGVuZ3RoOyArK2kpIHsKKyAgICAgICAgICByYXdWYWx1ZXNbaV0gPSBudWxsOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICB3aGlsZSAoIWF0RW9mKSB7CisgICAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgICBpbnQgYnl0ZXNQcm9jZXNzZWQgPSAwOworICAgICAgICAgIHJhd0tleXMucmVzZXQoKTsKKyAgICAgICAgICB3aGlsZSAoIWF0RW9mICYmIAorICAgICAgICAgICAgICAgICBieXRlc1Byb2Nlc3NlZCA8IG1lbW9yeUxpbWl0ICYmIGNvdW50IDwgcmVjb3JkTGltaXQpIHsKKworICAgICAgICAgICAgLy8gUmVhZCBhIHJlY29yZCBpbnRvIGJ1ZmZlcgorICAgICAgICAgICAgLy8gTm90ZTogQXR0ZW1wdCB0byByZS11c2UgJ3Jhd1ZhbHVlJyBhcyBmYXIgYXMgcG9zc2libGUKKyAgICAgICAgICAgIGludCBrZXlPZmZzZXQgPSByYXdLZXlzLmdldExlbmd0aCgpOyAgICAgICAKKyAgICAgICAgICAgIFZhbHVlQnl0ZXMgcmF3VmFsdWUgPSAKKyAgICAgICAgICAgICAgKGNvdW50ID09IGtleU9mZnNldHMubGVuZ3RoIHx8IHJhd1ZhbHVlc1tjb3VudF0gPT0gbnVsbCkgPyAKKyAgICAgICAgICAgICAgaW4uY3JlYXRlVmFsdWVCeXRlcygpIDogCisgICAgICAgICAgICAgIHJhd1ZhbHVlc1tjb3VudF07CisgICAgICAgICAgICBpbnQgcmVjb3JkTGVuZ3RoID0gaW4ubmV4dFJhdyhyYXdLZXlzLCByYXdWYWx1ZSk7CisgICAgICAgICAgICBpZiAocmVjb3JkTGVuZ3RoID09IC0xKSB7CisgICAgICAgICAgICAgIGluLmNsb3NlKCk7CisgICAgICAgICAgICAgIGlmIChkZWxldGVJbnB1dCkgeworICAgICAgICAgICAgICAgIGZzLmRlbGV0ZShpbkZpbGVzW2N1cnJlbnRGaWxlXSwgdHJ1ZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgY3VycmVudEZpbGUgKz0gMTsKKyAgICAgICAgICAgICAgYXRFb2YgPSBjdXJyZW50RmlsZSA+PSBpbkZpbGVzLmxlbmd0aDsKKyAgICAgICAgICAgICAgaWYgKCFhdEVvZikgeworICAgICAgICAgICAgICAgIGluID0gbmV3IFJlYWRlcihmcywgaW5GaWxlc1tjdXJyZW50RmlsZV0sIGNvbmYpOworICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGluID0gbnVsbDsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaW50IGtleUxlbmd0aCA9IHJhd0tleXMuZ2V0TGVuZ3RoKCkgLSBrZXlPZmZzZXQ7CisKKyAgICAgICAgICAgIGlmIChjb3VudCA9PSBrZXlPZmZzZXRzLmxlbmd0aCkKKyAgICAgICAgICAgICAgZ3JvdygpOworCisgICAgICAgICAgICBrZXlPZmZzZXRzW2NvdW50XSA9IGtleU9mZnNldDsgICAgICAgICAgICAgICAgLy8gdXBkYXRlIHBvaW50ZXJzCisgICAgICAgICAgICBwb2ludGVyc1tjb3VudF0gPSBjb3VudDsKKyAgICAgICAgICAgIGtleUxlbmd0aHNbY291bnRdID0ga2V5TGVuZ3RoOworICAgICAgICAgICAgcmF3VmFsdWVzW2NvdW50XSA9IHJhd1ZhbHVlOworCisgICAgICAgICAgICBieXRlc1Byb2Nlc3NlZCArPSByZWNvcmRMZW5ndGg7IAorICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBidWZmZXIgaXMgZnVsbCAtLSBzb3J0ICYgZmx1c2ggaXQKKyAgICAgICAgICBMT0cuZGVidWcoImZsdXNoaW5nIHNlZ21lbnQgIiArIHNlZ21lbnRzKTsKKyAgICAgICAgICByYXdCdWZmZXIgPSByYXdLZXlzLmdldERhdGEoKTsKKyAgICAgICAgICBzb3J0KGNvdW50KTsKKyAgICAgICAgICAvLyBpbmRpY2F0ZSB3ZSdyZSBtYWtpbmcgcHJvZ3Jlc3MKKyAgICAgICAgICBpZiAocHJvZ3Jlc3NhYmxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByb2dyZXNzYWJsZS5wcm9ncmVzcygpOworICAgICAgICAgIH0KKyAgICAgICAgICBmbHVzaChjb3VudCwgYnl0ZXNQcm9jZXNzZWQsIGlzQ29tcHJlc3NlZCwgaXNCbG9ja0NvbXByZXNzZWQsIGNvZGVjLCAKKyAgICAgICAgICAgICAgICBzZWdtZW50cz09MCAmJiBhdEVvZik7CisgICAgICAgICAgc2VnbWVudHMrKzsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc2VnbWVudHM7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9CisgICAgICAgIGlmIChpbmRleE91dCAhPSBudWxsKSB7CisgICAgICAgICAgaW5kZXhPdXQuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBwcml2YXRlIHZvaWQgZ3JvdygpIHsKKyAgICAgICAgaW50IG5ld0xlbmd0aCA9IGtleU9mZnNldHMubGVuZ3RoICogMyAvIDI7CisgICAgICAgIGtleU9mZnNldHMgPSBncm93KGtleU9mZnNldHMsIG5ld0xlbmd0aCk7CisgICAgICAgIHBvaW50ZXJzID0gZ3Jvdyhwb2ludGVycywgbmV3TGVuZ3RoKTsKKyAgICAgICAgcG9pbnRlcnNDb3B5ID0gbmV3IGludFtuZXdMZW5ndGhdOworICAgICAgICBrZXlMZW5ndGhzID0gZ3JvdyhrZXlMZW5ndGhzLCBuZXdMZW5ndGgpOworICAgICAgICByYXdWYWx1ZXMgPSBncm93KHJhd1ZhbHVlcywgbmV3TGVuZ3RoKTsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSBpbnRbXSBncm93KGludFtdIG9sZCwgaW50IG5ld0xlbmd0aCkgeworICAgICAgICBpbnRbXSByZXN1bHQgPSBuZXcgaW50W25ld0xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2xkLCAwLCByZXN1bHQsIDAsIG9sZC5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgICAgCisgICAgICBwcml2YXRlIFZhbHVlQnl0ZXNbXSBncm93KFZhbHVlQnl0ZXNbXSBvbGQsIGludCBuZXdMZW5ndGgpIHsKKyAgICAgICAgVmFsdWVCeXRlc1tdIHJlc3VsdCA9IG5ldyBWYWx1ZUJ5dGVzW25ld0xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2xkLCAwLCByZXN1bHQsIDAsIG9sZC5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpPW9sZC5sZW5ndGg7IGkgPCBuZXdMZW5ndGg7ICsraSkgeworICAgICAgICAgIHJlc3VsdFtpXSA9IG51bGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSB2b2lkIGZsdXNoKGludCBjb3VudCwgaW50IGJ5dGVzUHJvY2Vzc2VkLCBib29sZWFuIGlzQ29tcHJlc3NlZCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0Jsb2NrQ29tcHJlc3NlZCwgQ29tcHJlc3Npb25Db2RlYyBjb2RlYywgYm9vbGVhbiBkb25lKSAKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKG91dCA9PSBudWxsKSB7CisgICAgICAgICAgb3V0TmFtZSA9IGRvbmUgPyBvdXRGaWxlIDogb3V0RmlsZS5zdWZmaXgoIi4wIik7CisgICAgICAgICAgb3V0ID0gZnMuY3JlYXRlKG91dE5hbWUpOworICAgICAgICAgIGlmICghZG9uZSkgeworICAgICAgICAgICAgaW5kZXhPdXQgPSBmcy5jcmVhdGUob3V0TmFtZS5zdWZmaXgoIi5pbmRleCIpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBsb25nIHNlZ21lbnRTdGFydCA9IG91dC5nZXRQb3MoKTsKKyAgICAgICAgV3JpdGVyIHdyaXRlciA9IGNyZWF0ZVdyaXRlcihjb25mLCBvdXQsIGtleUNsYXNzLCB2YWxDbGFzcywgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDb21wcmVzc2VkLCBpc0Jsb2NrQ29tcHJlc3NlZCwgY29kZWMsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRhZGF0YSgpKTsKKyAgICAgICAgCisgICAgICAgIGlmICghZG9uZSkgeworICAgICAgICAgIHdyaXRlci5zeW5jID0gbnVsbDsgICAgICAgICAgICAgICAgICAgICAvLyBkaXNhYmxlIHN5bmMgb24gdGVtcCBmaWxlcworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7ICAgICAgICAgLy8gd3JpdGUgaW4gc29ydGVkIG9yZGVyCisgICAgICAgICAgaW50IHAgPSBwb2ludGVyc1tpXTsKKyAgICAgICAgICB3cml0ZXIuYXBwZW5kUmF3KHJhd0J1ZmZlciwga2V5T2Zmc2V0c1twXSwga2V5TGVuZ3Roc1twXSwgcmF3VmFsdWVzW3BdKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgCisgICAgICAgIGlmICghZG9uZSkgeworICAgICAgICAgIC8vIFNhdmUgdGhlIHNlZ21lbnQgbGVuZ3RoCisgICAgICAgICAgV3JpdGFibGVVdGlscy53cml0ZVZMb25nKGluZGV4T3V0LCBzZWdtZW50U3RhcnQpOworICAgICAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVWTG9uZyhpbmRleE91dCwgKG91dC5nZXRQb3MoKS1zZWdtZW50U3RhcnQpKTsKKyAgICAgICAgICBpbmRleE91dC5mbHVzaCgpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHByaXZhdGUgdm9pZCBzb3J0KGludCBjb3VudCkgeworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBvaW50ZXJzLCAwLCBwb2ludGVyc0NvcHksIDAsIGNvdW50KTsKKyAgICAgICAgbWVyZ2VTb3J0Lm1lcmdlU29ydChwb2ludGVyc0NvcHksIHBvaW50ZXJzLCAwLCBjb3VudCk7CisgICAgICB9CisgICAgICBjbGFzcyBTZXFGaWxlQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3I8SW50V3JpdGFibGU+IHsKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKEludFdyaXRhYmxlIEksIEludFdyaXRhYmxlIEopIHsKKyAgICAgICAgICByZXR1cm4gY29tcGFyYXRvci5jb21wYXJlKHJhd0J1ZmZlciwga2V5T2Zmc2V0c1tJLmdldCgpXSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlMZW5ndGhzW0kuZ2V0KCldLCByYXdCdWZmZXIsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5T2Zmc2V0c1tKLmdldCgpXSwga2V5TGVuZ3Roc1tKLmdldCgpXSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIAorICAgICAgLyoqIHNldCB0aGUgcHJvZ3Jlc3NhYmxlIG9iamVjdCBpbiBvcmRlciB0byByZXBvcnQgcHJvZ3Jlc3MgKi8KKyAgICAgIHB1YmxpYyB2b2lkIHNldFByb2dyZXNzYWJsZShQcm9ncmVzc2FibGUgcHJvZ3Jlc3NhYmxlKQorICAgICAgeworICAgICAgICB0aGlzLnByb2dyZXNzYWJsZSA9IHByb2dyZXNzYWJsZTsKKyAgICAgIH0KKyAgICAgIAorICAgIH0gLy8gU2VxdWVuY2VGaWxlLlNvcnRlci5Tb3J0UGFzcworCisgICAgLyoqIFRoZSBpbnRlcmZhY2UgdG8gaXRlcmF0ZSBvdmVyIHJhdyBrZXlzL3ZhbHVlcyBvZiBTZXF1ZW5jZUZpbGVzLiAqLworICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIFJhd0tleVZhbHVlSXRlcmF0b3IgeworICAgICAgLyoqIEdldHMgdGhlIGN1cnJlbnQgcmF3IGtleQorICAgICAgICogQHJldHVybiBEYXRhT3V0cHV0QnVmZmVyCisgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICAgKi8KKyAgICAgIERhdGFPdXRwdXRCdWZmZXIgZ2V0S2V5KCkgdGhyb3dzIElPRXhjZXB0aW9uOyAKKyAgICAgIC8qKiBHZXRzIHRoZSBjdXJyZW50IHJhdyB2YWx1ZQorICAgICAgICogQHJldHVybiBWYWx1ZUJ5dGVzIAorICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICovCisgICAgICBWYWx1ZUJ5dGVzIGdldFZhbHVlKCkgdGhyb3dzIElPRXhjZXB0aW9uOyAKKyAgICAgIC8qKiBTZXRzIHVwIHRoZSBjdXJyZW50IGtleSBhbmQgdmFsdWUgKGZvciBnZXRLZXkgYW5kIGdldFZhbHVlKQorICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoZXJlIGV4aXN0cyBhIGtleS92YWx1ZSwgZmFsc2Ugb3RoZXJ3aXNlIAorICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICovCisgICAgICBib29sZWFuIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgICAvKiogY2xvc2VzIHRoZSBpdGVyYXRvciBzbyB0aGF0IHRoZSB1bmRlcmx5aW5nIHN0cmVhbXMgY2FuIGJlIGNsb3NlZAorICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICovCisgICAgICB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgICAgLyoqIEdldHMgdGhlIFByb2dyZXNzIG9iamVjdDsgdGhpcyBoYXMgYSBmbG9hdCAoMC4wIC0gMS4wKSAKKyAgICAgICAqIGluZGljYXRpbmcgdGhlIGJ5dGVzIHByb2Nlc3NlZCBieSB0aGUgaXRlcmF0b3Igc28gZmFyCisgICAgICAgKi8KKyAgICAgIFByb2dyZXNzIGdldFByb2dyZXNzKCk7CisgICAgfSAgICAKKyAgICAKKyAgICAvKioKKyAgICAgKiBNZXJnZXMgdGhlIGxpc3Qgb2Ygc2VnbWVudHMgb2YgdHlwZSA8Y29kZT5TZWdtZW50RGVzY3JpcHRvcjwvY29kZT4KKyAgICAgKiBAcGFyYW0gc2VnbWVudHMgdGhlIGxpc3Qgb2YgU2VnbWVudERlc2NyaXB0b3JzCisgICAgICogQHBhcmFtIHRtcERpciB0aGUgZGlyZWN0b3J5IHRvIHdyaXRlIHRlbXBvcmFyeSBmaWxlcyBpbnRvCisgICAgICogQHJldHVybiBSYXdLZXlWYWx1ZUl0ZXJhdG9yCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSYXdLZXlWYWx1ZUl0ZXJhdG9yIG1lcmdlKExpc3QgPFNlZ21lbnREZXNjcmlwdG9yPiBzZWdtZW50cywgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGF0aCB0bXBEaXIpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIHBhc3MgaW4gb2JqZWN0IHRvIHJlcG9ydCBwcm9ncmVzcywgaWYgcHJlc2VudAorICAgICAgTWVyZ2VRdWV1ZSBtUXVldWUgPSBuZXcgTWVyZ2VRdWV1ZShzZWdtZW50cywgdG1wRGlyLCBwcm9ncmVzc2FibGUpOworICAgICAgcmV0dXJuIG1RdWV1ZS5tZXJnZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0aGUgY29udGVudHMgb2YgZmlsZXMgcGFzc2VkIGluIFBhdGhbXSB1c2luZyBhIG1heCBmYWN0b3IgdmFsdWUKKyAgICAgKiB0aGF0IGlzIGFscmVhZHkgc2V0CisgICAgICogQHBhcmFtIGluTmFtZXMgdGhlIGFycmF5IG9mIHBhdGggbmFtZXMKKyAgICAgKiBAcGFyYW0gZGVsZXRlSW5wdXRzIHRydWUgaWYgdGhlIGlucHV0IGZpbGVzIHNob3VsZCBiZSBkZWxldGVkIHdoZW4gCisgICAgICogdW5uZWNlc3NhcnkKKyAgICAgKiBAcGFyYW0gdG1wRGlyIHRoZSBkaXJlY3RvcnkgdG8gd3JpdGUgdGVtcG9yYXJ5IGZpbGVzIGludG8KKyAgICAgKiBAcmV0dXJuIFJhd0tleVZhbHVlSXRlcmF0b3JNZXJnZVF1ZXVlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBSYXdLZXlWYWx1ZUl0ZXJhdG9yIG1lcmdlKFBhdGggW10gaW5OYW1lcywgYm9vbGVhbiBkZWxldGVJbnB1dHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGF0aCB0bXBEaXIpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiBtZXJnZShpbk5hbWVzLCBkZWxldGVJbnB1dHMsIAorICAgICAgICAgICAgICAgICAgIChpbk5hbWVzLmxlbmd0aCA8IGZhY3RvcikgPyBpbk5hbWVzLmxlbmd0aCA6IGZhY3RvciwKKyAgICAgICAgICAgICAgICAgICB0bXBEaXIpOworICAgIH0KKworICAgIC8qKgorICAgICAqIE1lcmdlcyB0aGUgY29udGVudHMgb2YgZmlsZXMgcGFzc2VkIGluIFBhdGhbXQorICAgICAqIEBwYXJhbSBpbk5hbWVzIHRoZSBhcnJheSBvZiBwYXRoIG5hbWVzCisgICAgICogQHBhcmFtIGRlbGV0ZUlucHV0cyB0cnVlIGlmIHRoZSBpbnB1dCBmaWxlcyBzaG91bGQgYmUgZGVsZXRlZCB3aGVuIAorICAgICAqIHVubmVjZXNzYXJ5CisgICAgICogQHBhcmFtIGZhY3RvciB0aGUgZmFjdG9yIHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBtYXhpbXVtIG1lcmdlIGZhbi1pbgorICAgICAqIEBwYXJhbSB0bXBEaXIgdGhlIGRpcmVjdG9yeSB0byB3cml0ZSB0ZW1wb3JhcnkgZmlsZXMgaW50bworICAgICAqIEByZXR1cm4gUmF3S2V5VmFsdWVJdGVyYXRvck1lcmdlUXVldWUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJhd0tleVZhbHVlSXRlcmF0b3IgbWVyZ2UoUGF0aCBbXSBpbk5hbWVzLCBib29sZWFuIGRlbGV0ZUlucHV0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmFjdG9yLCBQYXRoIHRtcERpcikgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy9nZXQgdGhlIHNlZ21lbnRzIGZyb20gaW5OYW1lcworICAgICAgQXJyYXlMaXN0IDxTZWdtZW50RGVzY3JpcHRvcj4gYSA9IG5ldyBBcnJheUxpc3QgPFNlZ21lbnREZXNjcmlwdG9yPigpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbk5hbWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIFNlZ21lbnREZXNjcmlwdG9yIHMgPSBuZXcgU2VnbWVudERlc2NyaXB0b3IoMCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMuZ2V0TGVuZ3RoKGluTmFtZXNbaV0pLCBpbk5hbWVzW2ldKTsKKyAgICAgICAgcy5wcmVzZXJ2ZUlucHV0KCFkZWxldGVJbnB1dHMpOworICAgICAgICBzLmRvU3luYygpOworICAgICAgICBhLmFkZChzKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuZmFjdG9yID0gZmFjdG9yOworICAgICAgTWVyZ2VRdWV1ZSBtUXVldWUgPSBuZXcgTWVyZ2VRdWV1ZShhLCB0bXBEaXIsIHByb2dyZXNzYWJsZSk7CisgICAgICByZXR1cm4gbVF1ZXVlLm1lcmdlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogTWVyZ2VzIHRoZSBjb250ZW50cyBvZiBmaWxlcyBwYXNzZWQgaW4gUGF0aFtdCisgICAgICogQHBhcmFtIGluTmFtZXMgdGhlIGFycmF5IG9mIHBhdGggbmFtZXMKKyAgICAgKiBAcGFyYW0gdGVtcERpciB0aGUgZGlyZWN0b3J5IGZvciBjcmVhdGluZyB0ZW1wIGZpbGVzIGR1cmluZyBtZXJnZQorICAgICAqIEBwYXJhbSBkZWxldGVJbnB1dHMgdHJ1ZSBpZiB0aGUgaW5wdXQgZmlsZXMgc2hvdWxkIGJlIGRlbGV0ZWQgd2hlbiAKKyAgICAgKiB1bm5lY2Vzc2FyeQorICAgICAqIEByZXR1cm4gUmF3S2V5VmFsdWVJdGVyYXRvck1lcmdlUXVldWUKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJhd0tleVZhbHVlSXRlcmF0b3IgbWVyZ2UoUGF0aCBbXSBpbk5hbWVzLCBQYXRoIHRlbXBEaXIsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZGVsZXRlSW5wdXRzKSAKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAvL291dEZpbGUgd2lsbCBiYXNpY2FsbHkgYmUgdXNlZCBhcyBwcmVmaXggZm9yIHRlbXAgZmlsZXMgZm9yIHRoZQorICAgICAgLy9pbnRlcm1lZGlhdGUgbWVyZ2Ugb3V0cHV0cyAgICAgICAgICAgCisgICAgICB0aGlzLm91dEZpbGUgPSBuZXcgUGF0aCh0ZW1wRGlyICsgUGF0aC5TRVBBUkFUT1IgKyAibWVyZ2VkIik7CisgICAgICAvL2dldCB0aGUgc2VnbWVudHMgZnJvbSBpbk5hbWVzCisgICAgICBBcnJheUxpc3QgPFNlZ21lbnREZXNjcmlwdG9yPiBhID0gbmV3IEFycmF5TGlzdCA8U2VnbWVudERlc2NyaXB0b3I+KCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGluTmFtZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU2VnbWVudERlc2NyaXB0b3IgcyA9IG5ldyBTZWdtZW50RGVzY3JpcHRvcigwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcy5nZXRMZW5ndGgoaW5OYW1lc1tpXSksIGluTmFtZXNbaV0pOworICAgICAgICBzLnByZXNlcnZlSW5wdXQoIWRlbGV0ZUlucHV0cyk7CisgICAgICAgIHMuZG9TeW5jKCk7CisgICAgICAgIGEuYWRkKHMpOworICAgICAgfQorICAgICAgZmFjdG9yID0gKGluTmFtZXMubGVuZ3RoIDwgZmFjdG9yKSA/IGluTmFtZXMubGVuZ3RoIDogZmFjdG9yOworICAgICAgLy8gcGFzcyBpbiBvYmplY3QgdG8gcmVwb3J0IHByb2dyZXNzLCBpZiBwcmVzZW50CisgICAgICBNZXJnZVF1ZXVlIG1RdWV1ZSA9IG5ldyBNZXJnZVF1ZXVlKGEsIHRlbXBEaXIsIHByb2dyZXNzYWJsZSk7CisgICAgICByZXR1cm4gbVF1ZXVlLm1lcmdlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2xvbmVzIHRoZSBhdHRyaWJ1dGVzIChsaWtlIGNvbXByZXNzaW9uIG9mIHRoZSBpbnB1dCBmaWxlIGFuZCBjcmVhdGVzIGEgCisgICAgICogY29ycmVzcG9uZGluZyBXcml0ZXIKKyAgICAgKiBAcGFyYW0gaW5wdXRGaWxlIHRoZSBwYXRoIG9mIHRoZSBpbnB1dCBmaWxlIHdob3NlIGF0dHJpYnV0ZXMgc2hvdWxkIGJlIAorICAgICAqIGNsb25lZAorICAgICAqIEBwYXJhbSBvdXRwdXRGaWxlIHRoZSBwYXRoIG9mIHRoZSBvdXRwdXQgZmlsZSAKKyAgICAgKiBAcGFyYW0gcHJvZyB0aGUgUHJvZ3Jlc3NhYmxlIHRvIHJlcG9ydCBzdGF0dXMgZHVyaW5nIHRoZSBmaWxlIHdyaXRlCisgICAgICogQHJldHVybiBXcml0ZXIKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFdyaXRlciBjbG9uZUZpbGVBdHRyaWJ1dGVzKFBhdGggaW5wdXRGaWxlLCBQYXRoIG91dHB1dEZpbGUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9ncmVzc2FibGUgcHJvZykgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIEZpbGVTeXN0ZW0gc3JjRmlsZVN5cyA9IGlucHV0RmlsZS5nZXRGaWxlU3lzdGVtKGNvbmYpOworICAgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBSZWFkZXIoc3JjRmlsZVN5cywgaW5wdXRGaWxlLCA0MDk2LCBjb25mLCB0cnVlKTsKKyAgICAgIGJvb2xlYW4gY29tcHJlc3MgPSByZWFkZXIuaXNDb21wcmVzc2VkKCk7CisgICAgICBib29sZWFuIGJsb2NrQ29tcHJlc3MgPSByZWFkZXIuaXNCbG9ja0NvbXByZXNzZWQoKTsKKyAgICAgIENvbXByZXNzaW9uQ29kZWMgY29kZWMgPSByZWFkZXIuZ2V0Q29tcHJlc3Npb25Db2RlYygpOworICAgICAgcmVhZGVyLmNsb3NlKCk7CisKKyAgICAgIFdyaXRlciB3cml0ZXIgPSBjcmVhdGVXcml0ZXIob3V0cHV0RmlsZS5nZXRGaWxlU3lzdGVtKGNvbmYpLCBjb25mLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0RmlsZSwga2V5Q2xhc3MsIHZhbENsYXNzLCBjb21wcmVzcywgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrQ29tcHJlc3MsIGNvZGVjLCBwcm9nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTWV0YWRhdGEoKSk7CisgICAgICByZXR1cm4gd3JpdGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFdyaXRlcyByZWNvcmRzIGZyb20gUmF3S2V5VmFsdWVJdGVyYXRvciBpbnRvIGEgZmlsZSByZXByZXNlbnRlZCBieSB0aGUgCisgICAgICogcGFzc2VkIHdyaXRlcgorICAgICAqIEBwYXJhbSByZWNvcmRzIHRoZSBSYXdLZXlWYWx1ZUl0ZXJhdG9yCisgICAgICogQHBhcmFtIHdyaXRlciB0aGUgV3JpdGVyIGNyZWF0ZWQgZWFybGllciAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgd3JpdGVGaWxlKFJhd0tleVZhbHVlSXRlcmF0b3IgcmVjb3JkcywgV3JpdGVyIHdyaXRlcikgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgd2hpbGUocmVjb3Jkcy5uZXh0KCkpIHsKKyAgICAgICAgd3JpdGVyLmFwcGVuZFJhdyhyZWNvcmRzLmdldEtleSgpLmdldERhdGEoKSwgMCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3Jkcy5nZXRLZXkoKS5nZXRMZW5ndGgoKSwgcmVjb3Jkcy5nZXRWYWx1ZSgpKTsKKyAgICAgIH0KKyAgICAgIHdyaXRlci5zeW5jKCk7CisgICAgfQorICAgICAgICAKKyAgICAvKiogTWVyZ2UgdGhlIHByb3ZpZGVkIGZpbGVzLgorICAgICAqIEBwYXJhbSBpbkZpbGVzIHRoZSBhcnJheSBvZiBpbnB1dCBwYXRoIG5hbWVzCisgICAgICogQHBhcmFtIG91dEZpbGUgdGhlIGZpbmFsIG91dHB1dCBmaWxlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1lcmdlKFBhdGhbXSBpbkZpbGVzLCBQYXRoIG91dEZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoZnMuZXhpc3RzKG91dEZpbGUpKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiYWxyZWFkeSBleGlzdHM6ICIgKyBvdXRGaWxlKTsKKyAgICAgIH0KKyAgICAgIFJhd0tleVZhbHVlSXRlcmF0b3IgciA9IG1lcmdlKGluRmlsZXMsIGZhbHNlLCBvdXRGaWxlLmdldFBhcmVudCgpKTsKKyAgICAgIFdyaXRlciB3cml0ZXIgPSBjbG9uZUZpbGVBdHRyaWJ1dGVzKGluRmlsZXNbMF0sIG91dEZpbGUsIG51bGwpOworICAgICAgCisgICAgICB3cml0ZUZpbGUociwgd3JpdGVyKTsKKworICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqIHNvcnQgY2FsbHMgdGhpcyB0byBnZW5lcmF0ZSB0aGUgZmluYWwgbWVyZ2VkIG91dHB1dCAqLworICAgIHByaXZhdGUgaW50IG1lcmdlUGFzcyhQYXRoIHRtcERpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIExPRy5kZWJ1ZygicnVubmluZyBtZXJnZSBwYXNzIik7CisgICAgICBXcml0ZXIgd3JpdGVyID0gY2xvbmVGaWxlQXR0cmlidXRlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dEZpbGUuc3VmZml4KCIuMCIpLCBvdXRGaWxlLCBudWxsKTsKKyAgICAgIFJhd0tleVZhbHVlSXRlcmF0b3IgciA9IG1lcmdlKG91dEZpbGUuc3VmZml4KCIuMCIpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dEZpbGUuc3VmZml4KCIuMC5pbmRleCIpLCB0bXBEaXIpOworICAgICAgd3JpdGVGaWxlKHIsIHdyaXRlcik7CisKKyAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyoqIFVzZWQgYnkgbWVyZ2VQYXNzIHRvIG1lcmdlIHRoZSBvdXRwdXQgb2YgdGhlIHNvcnQKKyAgICAgKiBAcGFyYW0gaW5OYW1lIHRoZSBuYW1lIG9mIHRoZSBpbnB1dCBmaWxlIGNvbnRhaW5pbmcgc29ydGVkIHNlZ21lbnRzCisgICAgICogQHBhcmFtIGluZGV4SW4gdGhlIG9mZnNldHMgb2YgdGhlIHNvcnRlZCBzZWdtZW50cworICAgICAqIEBwYXJhbSB0bXBEaXIgdGhlIHJlbGF0aXZlIGRpcmVjdG9yeSB0byBzdG9yZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBpbgorICAgICAqIEByZXR1cm4gUmF3S2V5VmFsdWVJdGVyYXRvcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIFJhd0tleVZhbHVlSXRlcmF0b3IgbWVyZ2UoUGF0aCBpbk5hbWUsIFBhdGggaW5kZXhJbiwgUGF0aCB0bXBEaXIpIAorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vZ2V0IHRoZSBzZWdtZW50cyBmcm9tIGluZGV4SW4KKyAgICAgIC8vd2UgY3JlYXRlIGEgU2VnbWVudENvbnRhaW5lciBzbyB0aGF0IHdlIGNhbiB0cmFjayBzZWdtZW50cyBiZWxvbmdpbmcgdG8KKyAgICAgIC8vaW5OYW1lIGFuZCBkZWxldGUgaW5OYW1lIGFzIHNvb24gYXMgd2Ugc2VlIHRoYXQgd2UgaGF2ZSBsb29rZWQgYXQgYWxsCisgICAgICAvL3RoZSBjb250YWluZWQgc2VnbWVudHMgZHVyaW5nIHRoZSBtZXJnZSBwcm9jZXNzICYgaGVuY2UgZG9uJ3QgbmVlZCAKKyAgICAgIC8vdGhlbSBhbnltb3JlCisgICAgICBTZWdtZW50Q29udGFpbmVyIGNvbnRhaW5lciA9IG5ldyBTZWdtZW50Q29udGFpbmVyKGluTmFtZSwgaW5kZXhJbik7CisgICAgICBNZXJnZVF1ZXVlIG1RdWV1ZSA9IG5ldyBNZXJnZVF1ZXVlKGNvbnRhaW5lci5nZXRTZWdtZW50TGlzdCgpLCB0bXBEaXIsIHByb2dyZXNzYWJsZSk7CisgICAgICByZXR1cm4gbVF1ZXVlLm1lcmdlKCk7CisgICAgfQorICAgIAorICAgIC8qKiBUaGlzIGNsYXNzIGltcGxlbWVudHMgdGhlIGNvcmUgb2YgdGhlIG1lcmdlIGxvZ2ljICovCisgICAgcHJpdmF0ZSBjbGFzcyBNZXJnZVF1ZXVlIGV4dGVuZHMgUHJpb3JpdHlRdWV1ZSAKKyAgICAgIGltcGxlbWVudHMgUmF3S2V5VmFsdWVJdGVyYXRvciB7CisgICAgICBwcml2YXRlIGJvb2xlYW4gY29tcHJlc3M7CisgICAgICBwcml2YXRlIGJvb2xlYW4gYmxvY2tDb21wcmVzczsKKyAgICAgIHByaXZhdGUgRGF0YU91dHB1dEJ1ZmZlciByYXdLZXkgPSBuZXcgRGF0YU91dHB1dEJ1ZmZlcigpOworICAgICAgcHJpdmF0ZSBWYWx1ZUJ5dGVzIHJhd1ZhbHVlOworICAgICAgcHJpdmF0ZSBsb25nIHRvdGFsQnl0ZXNQcm9jZXNzZWQ7CisgICAgICBwcml2YXRlIGZsb2F0IHByb2dQZXJCeXRlOworICAgICAgcHJpdmF0ZSBQcm9ncmVzcyBtZXJnZVByb2dyZXNzID0gbmV3IFByb2dyZXNzKCk7CisgICAgICBwcml2YXRlIFBhdGggdG1wRGlyOworICAgICAgcHJpdmF0ZSBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MgPSBudWxsOyAvL2hhbmRsZSB0byB0aGUgcHJvZ3Jlc3MgcmVwb3J0aW5nIG9iamVjdAorICAgICAgcHJpdmF0ZSBTZWdtZW50RGVzY3JpcHRvciBtaW5TZWdtZW50OworICAgICAgCisgICAgICAvL2EgVHJlZU1hcCB1c2VkIHRvIHN0b3JlIHRoZSBzZWdtZW50cyBzb3J0ZWQgYnkgc2l6ZSAoc2VnbWVudCBvZmZzZXQgYW5kCisgICAgICAvL3NlZ21lbnQgcGF0aCBuYW1lIGlzIHVzZWQgdG8gYnJlYWsgdGllcyBiZXR3ZWVuIHNlZ21lbnRzIG9mIHNhbWUgc2l6ZXMpCisgICAgICBwcml2YXRlIE1hcDxTZWdtZW50RGVzY3JpcHRvciwgVm9pZD4gc29ydGVkU2VnbWVudFNpemVzID0KKyAgICAgICAgbmV3IFRyZWVNYXA8U2VnbWVudERlc2NyaXB0b3IsIFZvaWQ+KCk7CisgICAgICAgICAgICAKKyAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgcHVibGljIHZvaWQgcHV0KFNlZ21lbnREZXNjcmlwdG9yIHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNpemUoKSA9PSAwKSB7CisgICAgICAgICAgY29tcHJlc3MgPSBzdHJlYW0uaW4uaXNDb21wcmVzc2VkKCk7CisgICAgICAgICAgYmxvY2tDb21wcmVzcyA9IHN0cmVhbS5pbi5pc0Jsb2NrQ29tcHJlc3NlZCgpOworICAgICAgICB9IGVsc2UgaWYgKGNvbXByZXNzICE9IHN0cmVhbS5pbi5pc0NvbXByZXNzZWQoKSB8fCAKKyAgICAgICAgICAgICAgICAgICBibG9ja0NvbXByZXNzICE9IHN0cmVhbS5pbi5pc0Jsb2NrQ29tcHJlc3NlZCgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJBbGwgbWVyZ2VkIGZpbGVzIG11c3QgYmUgY29tcHJlc3NlZCBvciBub3QuIik7CisgICAgICAgIH0gCisgICAgICAgIHN1cGVyLnB1dChzdHJlYW0pOworICAgICAgfQorICAgICAgCisgICAgICAvKioKKyAgICAgICAqIEEgcXVldWUgb2YgZmlsZSBzZWdtZW50cyB0byBtZXJnZQorICAgICAgICogQHBhcmFtIHNlZ21lbnRzIHRoZSBmaWxlIHNlZ21lbnRzIHRvIG1lcmdlCisgICAgICAgKiBAcGFyYW0gdG1wRGlyIGEgcmVsYXRpdmUgbG9jYWwgZGlyZWN0b3J5IHRvIHNhdmUgaW50ZXJtZWRpYXRlIGZpbGVzIGluCisgICAgICAgKiBAcGFyYW0gcHJvZ3Jlc3MgdGhlIHJlZmVyZW5jZSB0byB0aGUgUHJvZ3Jlc3NhYmxlIG9iamVjdAorICAgICAgICovCisgICAgICBwdWJsaWMgTWVyZ2VRdWV1ZShMaXN0IDxTZWdtZW50RGVzY3JpcHRvcj4gc2VnbWVudHMsCisgICAgICAgICAgUGF0aCB0bXBEaXIsIFByb2dyZXNzYWJsZSBwcm9ncmVzcykgeworICAgICAgICBpbnQgc2l6ZSA9IHNlZ21lbnRzLnNpemUoKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKKyAgICAgICAgICBzb3J0ZWRTZWdtZW50U2l6ZXMucHV0KHNlZ21lbnRzLmdldChpKSwgbnVsbCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy50bXBEaXIgPSB0bXBEaXI7CisgICAgICAgIHRoaXMucHJvZ3Jlc3MgPSBwcm9ncmVzczsKKyAgICAgIH0KKyAgICAgIHByb3RlY3RlZCBib29sZWFuIGxlc3NUaGFuKE9iamVjdCBhLCBPYmplY3QgYikgeworICAgICAgICAvLyBpbmRpY2F0ZSB3ZSdyZSBtYWtpbmcgcHJvZ3Jlc3MKKyAgICAgICAgaWYgKHByb2dyZXNzICE9IG51bGwpIHsKKyAgICAgICAgICBwcm9ncmVzcy5wcm9ncmVzcygpOworICAgICAgICB9CisgICAgICAgIFNlZ21lbnREZXNjcmlwdG9yIG1zYSA9IChTZWdtZW50RGVzY3JpcHRvcilhOworICAgICAgICBTZWdtZW50RGVzY3JpcHRvciBtc2IgPSAoU2VnbWVudERlc2NyaXB0b3IpYjsKKyAgICAgICAgcmV0dXJuIGNvbXBhcmF0b3IuY29tcGFyZShtc2EuZ2V0S2V5KCkuZ2V0RGF0YSgpLCAwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2EuZ2V0S2V5KCkuZ2V0TGVuZ3RoKCksIG1zYi5nZXRLZXkoKS5nZXREYXRhKCksIDAsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zYi5nZXRLZXkoKS5nZXRMZW5ndGgoKSkgPCAwOworICAgICAgfQorICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTZWdtZW50RGVzY3JpcHRvciBtczsgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbG9zZSBpbnB1dHMKKyAgICAgICAgd2hpbGUgKChtcyA9IChTZWdtZW50RGVzY3JpcHRvcilwb3AoKSkgIT0gbnVsbCkgeworICAgICAgICAgIG1zLmNsZWFudXAoKTsKKyAgICAgICAgfQorICAgICAgICBtaW5TZWdtZW50ID0gbnVsbDsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBEYXRhT3V0cHV0QnVmZmVyIGdldEtleSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByYXdLZXk7CisgICAgICB9CisgICAgICBwdWJsaWMgVmFsdWVCeXRlcyBnZXRWYWx1ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiByYXdWYWx1ZTsKKyAgICAgIH0KKyAgICAgIHB1YmxpYyBib29sZWFuIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoc2l6ZSgpID09IDApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAobWluU2VnbWVudCAhPSBudWxsKSB7CisgICAgICAgICAgLy9taW5TZWdtZW50IGlzIG5vbi1udWxsIGZvciBhbGwgaW52b2NhdGlvbnMgb2YgbmV4dCBleGNlcHQgdGhlIGZpcnN0CisgICAgICAgICAgLy9vbmUuIEZvciB0aGUgZmlyc3QgaW52b2NhdGlvbiwgdGhlIHByaW9yaXR5IHF1ZXVlIGlzIHJlYWR5IGZvciB1c2UKKyAgICAgICAgICAvL2J1dCBmb3IgdGhlIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMsIGZpcnN0IGFkanVzdCB0aGUgcXVldWUgCisgICAgICAgICAgYWRqdXN0UHJpb3JpdHlRdWV1ZShtaW5TZWdtZW50KTsKKyAgICAgICAgICBpZiAoc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIG1pblNlZ21lbnQgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBtaW5TZWdtZW50ID0gKFNlZ21lbnREZXNjcmlwdG9yKXRvcCgpOworICAgICAgICBsb25nIHN0YXJ0UG9zID0gbWluU2VnbWVudC5pbi5nZXRQb3NpdGlvbigpOyAvLyBDdXJyZW50IHBvc2l0aW9uIGluIHN0cmVhbQorICAgICAgICAvL3NhdmUgdGhlIHJhdyBrZXkgcmVmZXJlbmNlCisgICAgICAgIHJhd0tleSA9IG1pblNlZ21lbnQuZ2V0S2V5KCk7CisgICAgICAgIC8vbG9hZCB0aGUgcmF3IHZhbHVlLiBSZS11c2UgdGhlIGV4aXN0aW5nIHJhd1ZhbHVlIGJ1ZmZlcgorICAgICAgICBpZiAocmF3VmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHJhd1ZhbHVlID0gbWluU2VnbWVudC5pbi5jcmVhdGVWYWx1ZUJ5dGVzKCk7CisgICAgICAgIH0KKyAgICAgICAgbWluU2VnbWVudC5uZXh0UmF3VmFsdWUocmF3VmFsdWUpOworICAgICAgICBsb25nIGVuZFBvcyA9IG1pblNlZ21lbnQuaW4uZ2V0UG9zaXRpb24oKTsgLy8gRW5kIHBvc2l0aW9uIGFmdGVyIHJlYWRpbmcgdmFsdWUKKyAgICAgICAgdXBkYXRlUHJvZ3Jlc3MoZW5kUG9zIC0gc3RhcnRQb3MpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcHVibGljIFByb2dyZXNzIGdldFByb2dyZXNzKCkgeworICAgICAgICByZXR1cm4gbWVyZ2VQcm9ncmVzczsgCisgICAgICB9CisKKyAgICAgIHByaXZhdGUgdm9pZCBhZGp1c3RQcmlvcml0eVF1ZXVlKFNlZ21lbnREZXNjcmlwdG9yIG1zKSB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgICAgIGxvbmcgc3RhcnRQb3MgPSBtcy5pbi5nZXRQb3NpdGlvbigpOyAvLyBDdXJyZW50IHBvc2l0aW9uIGluIHN0cmVhbQorICAgICAgICBib29sZWFuIGhhc05leHQgPSBtcy5uZXh0UmF3S2V5KCk7CisgICAgICAgIGxvbmcgZW5kUG9zID0gbXMuaW4uZ2V0UG9zaXRpb24oKTsgLy8gRW5kIHBvc2l0aW9uIGFmdGVyIHJlYWRpbmcga2V5CisgICAgICAgIHVwZGF0ZVByb2dyZXNzKGVuZFBvcyAtIHN0YXJ0UG9zKTsKKyAgICAgICAgaWYgKGhhc05leHQpIHsKKyAgICAgICAgICBhZGp1c3RUb3AoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBwb3AoKTsKKyAgICAgICAgICBtcy5jbGVhbnVwKCk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgcHJpdmF0ZSB2b2lkIHVwZGF0ZVByb2dyZXNzKGxvbmcgYnl0ZXNQcm9jZXNzZWQpIHsKKyAgICAgICAgdG90YWxCeXRlc1Byb2Nlc3NlZCArPSBieXRlc1Byb2Nlc3NlZDsKKyAgICAgICAgaWYgKHByb2dQZXJCeXRlID4gMCkgeworICAgICAgICAgIG1lcmdlUHJvZ3Jlc3Muc2V0KHRvdGFsQnl0ZXNQcm9jZXNzZWQgKiBwcm9nUGVyQnl0ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIAorICAgICAgLyoqIFRoaXMgaXMgdGhlIHNpbmdsZSBsZXZlbCBtZXJnZSB0aGF0IGlzIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyAKKyAgICAgICAqIGRlcGVuZGluZyBvbiB0aGUgZmFjdG9yIHNpemUgYW5kIHRoZSBudW1iZXIgb2Ygc2VnbWVudHMKKyAgICAgICAqIEByZXR1cm4gUmF3S2V5VmFsdWVJdGVyYXRvcgorICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICovCisgICAgICBwdWJsaWMgUmF3S2V5VmFsdWVJdGVyYXRvciBtZXJnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIC8vY3JlYXRlIHRoZSBNZXJnZVN0cmVhbXMgZnJvbSB0aGUgc29ydGVkIG1hcCBjcmVhdGVkIGluIHRoZSBjb25zdHJ1Y3RvcgorICAgICAgICAvL2FuZCBkdW1wIHRoZSBmaW5hbCBvdXRwdXQgdG8gYSBmaWxlCisgICAgICAgIGludCBudW1TZWdtZW50cyA9IHNvcnRlZFNlZ21lbnRTaXplcy5zaXplKCk7CisgICAgICAgIGludCBvcmlnRmFjdG9yID0gZmFjdG9yOworICAgICAgICBpbnQgcGFzc05vID0gMTsKKyAgICAgICAgTG9jYWxEaXJBbGxvY2F0b3IgbERpckFsbG9jID0gbmV3IExvY2FsRGlyQWxsb2NhdG9yKCJtYXByZWQubG9jYWwuZGlyIik7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAvL2dldCB0aGUgZmFjdG9yIGZvciB0aGlzIHBhc3Mgb2YgbWVyZ2UKKyAgICAgICAgICBmYWN0b3IgPSBnZXRQYXNzRmFjdG9yKHBhc3NObywgbnVtU2VnbWVudHMpOworICAgICAgICAgIExpc3Q8U2VnbWVudERlc2NyaXB0b3I+IHNlZ21lbnRzVG9NZXJnZSA9CisgICAgICAgICAgICBuZXcgQXJyYXlMaXN0PFNlZ21lbnREZXNjcmlwdG9yPigpOworICAgICAgICAgIGludCBzZWdtZW50c0NvbnNpZGVyZWQgPSAwOworICAgICAgICAgIGludCBudW1TZWdtZW50c1RvQ29uc2lkZXIgPSBmYWN0b3I7CisgICAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICAgIC8vZXh0cmFjdCB0aGUgc21hbGxlc3QgJ2ZhY3RvcicgbnVtYmVyIG9mIHNlZ21lbnQgcG9pbnRlcnMgZnJvbSB0aGUgCisgICAgICAgICAgICAvL1RyZWVNYXAuIENhbGwgY2xlYW51cCBvbiB0aGUgZW1wdHkgc2VnbWVudHMgKG5vIGtleS92YWx1ZSBkYXRhKQorICAgICAgICAgICAgU2VnbWVudERlc2NyaXB0b3JbXSBtU3RyZWFtID0gCisgICAgICAgICAgICAgIGdldFNlZ21lbnREZXNjcmlwdG9ycyhudW1TZWdtZW50c1RvQ29uc2lkZXIpOworICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtU3RyZWFtLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgICAgIGlmIChtU3RyZWFtW2ldLm5leHRSYXdLZXkoKSkgeworICAgICAgICAgICAgICAgIHNlZ21lbnRzVG9NZXJnZS5hZGQobVN0cmVhbVtpXSk7CisgICAgICAgICAgICAgICAgc2VnbWVudHNDb25zaWRlcmVkKys7CisgICAgICAgICAgICAgICAgLy8gQ291bnQgdGhlIGZhY3QgdGhhdCB3ZSByZWFkIHNvbWUgYnl0ZXMgaW4gY2FsbGluZyBuZXh0UmF3S2V5KCkKKyAgICAgICAgICAgICAgICB1cGRhdGVQcm9ncmVzcyhtU3RyZWFtW2ldLmluLmdldFBvc2l0aW9uKCkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIG1TdHJlYW1baV0uY2xlYW51cCgpOworICAgICAgICAgICAgICAgIG51bVNlZ21lbnRzLS07IC8vd2UgaWdub3JlIHRoaXMgc2VnbWVudCBmb3IgdGhlIG1lcmdlCisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vaWYgd2UgaGF2ZSB0aGUgZGVzaXJlZCBudW1iZXIgb2Ygc2VnbWVudHMKKyAgICAgICAgICAgIC8vb3IgbG9va2VkIGF0IGFsbCBhdmFpbGFibGUgc2VnbWVudHMsIHdlIGJyZWFrCisgICAgICAgICAgICBpZiAoc2VnbWVudHNDb25zaWRlcmVkID09IGZhY3RvciB8fCAKKyAgICAgICAgICAgICAgICBzb3J0ZWRTZWdtZW50U2l6ZXMuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAgIAorICAgICAgICAgICAgbnVtU2VnbWVudHNUb0NvbnNpZGVyID0gZmFjdG9yIC0gc2VnbWVudHNDb25zaWRlcmVkOworICAgICAgICAgIH0KKyAgICAgICAgICAvL2ZlZWQgdGhlIHN0cmVhbXMgdG8gdGhlIHByaW9yaXR5IHF1ZXVlCisgICAgICAgICAgaW5pdGlhbGl6ZShzZWdtZW50c1RvTWVyZ2Uuc2l6ZSgpKTsgY2xlYXIoKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzVG9NZXJnZS5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgcHV0KHNlZ21lbnRzVG9NZXJnZS5nZXQoaSkpOworICAgICAgICAgIH0KKyAgICAgICAgICAvL2lmIHdlIGhhdmUgbGVzc2VyIG51bWJlciBvZiBzZWdtZW50cyByZW1haW5pbmcsIHRoZW4ganVzdCByZXR1cm4gdGhlCisgICAgICAgICAgLy9pdGVyYXRvciwgZWxzZSBkbyBhbm90aGVyIHNpbmdsZSBsZXZlbCBtZXJnZQorICAgICAgICAgIGlmIChudW1TZWdtZW50cyA8PSBmYWN0b3IpIHsKKyAgICAgICAgICAgIC8vY2FsY3VsYXRlIHRoZSBsZW5ndGggb2YgdGhlIHJlbWFpbmluZyBzZWdtZW50cy4gUmVxdWlyZWQgZm9yIAorICAgICAgICAgICAgLy9jYWxjdWxhdGluZyB0aGUgbWVyZ2UgcHJvZ3Jlc3MKKyAgICAgICAgICAgIGxvbmcgdG90YWxCeXRlcyA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlZ21lbnRzVG9NZXJnZS5zaXplKCk7IGkrKykgeworICAgICAgICAgICAgICB0b3RhbEJ5dGVzICs9IHNlZ21lbnRzVG9NZXJnZS5nZXQoaSkuc2VnbWVudExlbmd0aDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0b3RhbEJ5dGVzICE9IDApIC8vYmVpbmcgcGFyYW5vaWQKKyAgICAgICAgICAgICAgcHJvZ1BlckJ5dGUgPSAxLjBmIC8gKGZsb2F0KXRvdGFsQnl0ZXM7CisgICAgICAgICAgICAvL3Jlc2V0IGZhY3RvciB0byB3aGF0IGl0IG9yaWdpbmFsbHkgd2FzCisgICAgICAgICAgICBmYWN0b3IgPSBvcmlnRmFjdG9yOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vd2Ugd2FudCB0byBzcHJlYWQgdGhlIGNyZWF0aW9uIG9mIHRlbXAgZmlsZXMgb24gbXVsdGlwbGUgZGlza3MgaWYgCisgICAgICAgICAgICAvL2F2YWlsYWJsZSB1bmRlciB0aGUgc3BhY2UgY29uc3RyYWludHMKKyAgICAgICAgICAgIGxvbmcgYXBwcm94T3V0cHV0U2l6ZSA9IDA7IAorICAgICAgICAgICAgZm9yIChTZWdtZW50RGVzY3JpcHRvciBzIDogc2VnbWVudHNUb01lcmdlKSB7CisgICAgICAgICAgICAgIGFwcHJveE91dHB1dFNpemUgKz0gcy5zZWdtZW50TGVuZ3RoICsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2tzdW1GaWxlU3lzdGVtLmdldEFwcHJveENoa1N1bUxlbmd0aCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLnNlZ21lbnRMZW5ndGgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUGF0aCB0bXBGaWxlbmFtZSA9IAorICAgICAgICAgICAgICBuZXcgUGF0aCh0bXBEaXIsICJpbnRlcm1lZGlhdGUiKS5zdWZmaXgoIi4iICsgcGFzc05vKTsKKworICAgICAgICAgICAgUGF0aCBvdXRwdXRGaWxlID0gIGxEaXJBbGxvYy5nZXRMb2NhbFBhdGhGb3JXcml0ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcEZpbGVuYW1lLnRvU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHByb3hPdXRwdXRTaXplLCBjb25mKTsKKyAgICAgICAgICAgIExPRy5kZWJ1Zygid3JpdGluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cyB0byAiICsgb3V0cHV0RmlsZSk7CisgICAgICAgICAgICBXcml0ZXIgd3JpdGVyID0gY2xvbmVGaWxlQXR0cmlidXRlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzLm1ha2VRdWFsaWZpZWQoc2VnbWVudHNUb01lcmdlLmdldCgwKS5zZWdtZW50UGF0aE5hbWUpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzLm1ha2VRdWFsaWZpZWQob3V0cHV0RmlsZSksIG51bGwpOworICAgICAgICAgICAgd3JpdGVyLnN5bmMgPSBudWxsOyAvL2Rpc2FibGUgc3luYyBmb3IgdGVtcCBmaWxlcworICAgICAgICAgICAgd3JpdGVGaWxlKHRoaXMsIHdyaXRlcik7CisgICAgICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgLy93ZSBmaW5pc2hlZCBvbmUgc2luZ2xlIGxldmVsIG1lcmdlOyBub3cgY2xlYW4gdXAgdGhlIHByaW9yaXR5IAorICAgICAgICAgICAgLy9xdWV1ZQorICAgICAgICAgICAgdGhpcy5jbG9zZSgpOworICAgICAgICAgICAgCisgICAgICAgICAgICBTZWdtZW50RGVzY3JpcHRvciB0ZW1wU2VnbWVudCA9IAorICAgICAgICAgICAgICBuZXcgU2VnbWVudERlc2NyaXB0b3IoMCwgZnMuZ2V0TGVuZ3RoKG91dHB1dEZpbGUpLCBvdXRwdXRGaWxlKTsKKyAgICAgICAgICAgIC8vcHV0IHRoZSBzZWdtZW50IGJhY2sgaW4gdGhlIFRyZWVNYXAKKyAgICAgICAgICAgIHNvcnRlZFNlZ21lbnRTaXplcy5wdXQodGVtcFNlZ21lbnQsIG51bGwpOworICAgICAgICAgICAgbnVtU2VnbWVudHMgPSBzb3J0ZWRTZWdtZW50U2l6ZXMuc2l6ZSgpOworICAgICAgICAgICAgcGFzc05vKys7CisgICAgICAgICAgfQorICAgICAgICAgIC8vd2UgYXJlIHdvcnJpZWQgYWJvdXQgb25seSB0aGUgZmlyc3QgcGFzcyBtZXJnZSBmYWN0b3IuIFNvIHJlc2V0IHRoZSAKKyAgICAgICAgICAvL2ZhY3RvciB0byB3aGF0IGl0IG9yaWdpbmFsbHkgd2FzCisgICAgICAgICAgZmFjdG9yID0gb3JpZ0ZhY3RvcjsKKyAgICAgICAgfSB3aGlsZSh0cnVlKTsKKyAgICAgIH0KKyAgCisgICAgICAvL0hhZG9vcC01OTEKKyAgICAgIHB1YmxpYyBpbnQgZ2V0UGFzc0ZhY3RvcihpbnQgcGFzc05vLCBpbnQgbnVtU2VnbWVudHMpIHsKKyAgICAgICAgaWYgKHBhc3NObyA+IDEgfHwgbnVtU2VnbWVudHMgPD0gZmFjdG9yIHx8IGZhY3RvciA9PSAxKSAKKyAgICAgICAgICByZXR1cm4gZmFjdG9yOworICAgICAgICBpbnQgbW9kID0gKG51bVNlZ21lbnRzIC0gMSkgJSAoZmFjdG9yIC0gMSk7CisgICAgICAgIGlmIChtb2QgPT0gMCkKKyAgICAgICAgICByZXR1cm4gZmFjdG9yOworICAgICAgICByZXR1cm4gbW9kICsgMTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLyoqIFJldHVybiAoJiByZW1vdmUpIHRoZSByZXF1ZXN0ZWQgbnVtYmVyIG9mIHNlZ21lbnQgZGVzY3JpcHRvcnMgZnJvbSB0aGUKKyAgICAgICAqIHNvcnRlZCBtYXAuCisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBTZWdtZW50RGVzY3JpcHRvcltdIGdldFNlZ21lbnREZXNjcmlwdG9ycyhpbnQgbnVtRGVzY3JpcHRvcnMpIHsKKyAgICAgICAgaWYgKG51bURlc2NyaXB0b3JzID4gc29ydGVkU2VnbWVudFNpemVzLnNpemUoKSkKKyAgICAgICAgICBudW1EZXNjcmlwdG9ycyA9IHNvcnRlZFNlZ21lbnRTaXplcy5zaXplKCk7CisgICAgICAgIFNlZ21lbnREZXNjcmlwdG9yW10gU2VnbWVudERlc2NyaXB0b3JzID0gCisgICAgICAgICAgbmV3IFNlZ21lbnREZXNjcmlwdG9yW251bURlc2NyaXB0b3JzXTsKKyAgICAgICAgSXRlcmF0b3IgaXRlciA9IHNvcnRlZFNlZ21lbnRTaXplcy5rZXlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgIHdoaWxlIChpIDwgbnVtRGVzY3JpcHRvcnMpIHsKKyAgICAgICAgICBTZWdtZW50RGVzY3JpcHRvcnNbaSsrXSA9IChTZWdtZW50RGVzY3JpcHRvcilpdGVyLm5leHQoKTsKKyAgICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBTZWdtZW50RGVzY3JpcHRvcnM7CisgICAgICB9CisgICAgfSAvLyBTZXF1ZW5jZUZpbGUuU29ydGVyLk1lcmdlUXVldWUKKworICAgIC8qKiBUaGlzIGNsYXNzIGRlZmluZXMgYSBtZXJnZSBzZWdtZW50LiBUaGlzIGNsYXNzIGNhbiBiZSBzdWJjbGFzc2VkIHRvIAorICAgICAqIHByb3ZpZGUgYSBjdXN0b21pemVkIGNsZWFudXAgbWV0aG9kIGltcGxlbWVudGF0aW9uLiBJbiB0aGlzIAorICAgICAqIGltcGxlbWVudGF0aW9uLCBjbGVhbnVwIGNsb3NlcyB0aGUgZmlsZSBoYW5kbGUgYW5kIGRlbGV0ZXMgdGhlIGZpbGUgCisgICAgICovCisgICAgcHVibGljIGNsYXNzIFNlZ21lbnREZXNjcmlwdG9yIGltcGxlbWVudHMgQ29tcGFyYWJsZSB7CisgICAgICAKKyAgICAgIGxvbmcgc2VnbWVudE9mZnNldDsgLy90aGUgc3RhcnQgb2YgdGhlIHNlZ21lbnQgaW4gdGhlIGZpbGUKKyAgICAgIGxvbmcgc2VnbWVudExlbmd0aDsgLy90aGUgbGVuZ3RoIG9mIHRoZSBzZWdtZW50CisgICAgICBQYXRoIHNlZ21lbnRQYXRoTmFtZTsgLy90aGUgcGF0aCBuYW1lIG9mIHRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIHNlZ21lbnQKKyAgICAgIGJvb2xlYW4gaWdub3JlU3luYyA9IHRydWU7IC8vc2V0IHRvIHRydWUgZm9yIHRlbXAgZmlsZXMKKyAgICAgIHByaXZhdGUgUmVhZGVyIGluID0gbnVsbDsgCisgICAgICBwcml2YXRlIERhdGFPdXRwdXRCdWZmZXIgcmF3S2V5ID0gbnVsbDsgLy90aGlzIHdpbGwgaG9sZCB0aGUgY3VycmVudCBrZXkKKyAgICAgIHByaXZhdGUgYm9vbGVhbiBwcmVzZXJ2ZUlucHV0ID0gZmFsc2U7IC8vZGVsZXRlIGlucHV0IHNlZ21lbnQgZmlsZXM/CisgICAgICAKKyAgICAgIC8qKiBDb25zdHJ1Y3RzIGEgc2VnbWVudAorICAgICAgICogQHBhcmFtIHNlZ21lbnRPZmZzZXQgdGhlIG9mZnNldCBvZiB0aGUgc2VnbWVudCBpbiB0aGUgZmlsZQorICAgICAgICogQHBhcmFtIHNlZ21lbnRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgc2VnbWVudAorICAgICAgICogQHBhcmFtIHNlZ21lbnRQYXRoTmFtZSB0aGUgcGF0aCBuYW1lIG9mIHRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIHNlZ21lbnQKKyAgICAgICAqLworICAgICAgcHVibGljIFNlZ21lbnREZXNjcmlwdG9yIChsb25nIHNlZ21lbnRPZmZzZXQsIGxvbmcgc2VnbWVudExlbmd0aCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggc2VnbWVudFBhdGhOYW1lKSB7CisgICAgICAgIHRoaXMuc2VnbWVudE9mZnNldCA9IHNlZ21lbnRPZmZzZXQ7CisgICAgICAgIHRoaXMuc2VnbWVudExlbmd0aCA9IHNlZ21lbnRMZW5ndGg7CisgICAgICAgIHRoaXMuc2VnbWVudFBhdGhOYW1lID0gc2VnbWVudFBhdGhOYW1lOworICAgICAgfQorICAgICAgCisgICAgICAvKiogRG8gdGhlIHN5bmMgY2hlY2tzICovCisgICAgICBwdWJsaWMgdm9pZCBkb1N5bmMoKSB7aWdub3JlU3luYyA9IGZhbHNlO30KKyAgICAgIAorICAgICAgLyoqIFdoZXRoZXIgdG8gZGVsZXRlIHRoZSBmaWxlcyB3aGVuIG5vIGxvbmdlciBuZWVkZWQgKi8KKyAgICAgIHB1YmxpYyB2b2lkIHByZXNlcnZlSW5wdXQoYm9vbGVhbiBwcmVzZXJ2ZSkgeworICAgICAgICBwcmVzZXJ2ZUlucHV0ID0gcHJlc2VydmU7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBib29sZWFuIHNob3VsZFByZXNlcnZlSW5wdXQoKSB7CisgICAgICAgIHJldHVybiBwcmVzZXJ2ZUlucHV0OworICAgICAgfQorICAgICAgCisgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhPYmplY3QgbykgeworICAgICAgICBTZWdtZW50RGVzY3JpcHRvciB0aGF0ID0gKFNlZ21lbnREZXNjcmlwdG9yKW87CisgICAgICAgIGlmICh0aGlzLnNlZ21lbnRMZW5ndGggIT0gdGhhdC5zZWdtZW50TGVuZ3RoKSB7CisgICAgICAgICAgcmV0dXJuICh0aGlzLnNlZ21lbnRMZW5ndGggPCB0aGF0LnNlZ21lbnRMZW5ndGggPyAtMSA6IDEpOworICAgICAgICB9CisgICAgICAgIGlmICh0aGlzLnNlZ21lbnRPZmZzZXQgIT0gdGhhdC5zZWdtZW50T2Zmc2V0KSB7CisgICAgICAgICAgcmV0dXJuICh0aGlzLnNlZ21lbnRPZmZzZXQgPCB0aGF0LnNlZ21lbnRPZmZzZXQgPyAtMSA6IDEpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAodGhpcy5zZWdtZW50UGF0aE5hbWUudG9TdHJpbmcoKSkuCisgICAgICAgICAgY29tcGFyZVRvKHRoYXQuc2VnbWVudFBhdGhOYW1lLnRvU3RyaW5nKCkpOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIFNlZ21lbnREZXNjcmlwdG9yKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBTZWdtZW50RGVzY3JpcHRvciB0aGF0ID0gKFNlZ21lbnREZXNjcmlwdG9yKW87CisgICAgICAgIGlmICh0aGlzLnNlZ21lbnRMZW5ndGggPT0gdGhhdC5zZWdtZW50TGVuZ3RoICYmCisgICAgICAgICAgICB0aGlzLnNlZ21lbnRPZmZzZXQgPT0gdGhhdC5zZWdtZW50T2Zmc2V0ICYmCisgICAgICAgICAgICB0aGlzLnNlZ21lbnRQYXRoTmFtZS50b1N0cmluZygpLmVxdWFscygKKyAgICAgICAgICAgICAgdGhhdC5zZWdtZW50UGF0aE5hbWUudG9TdHJpbmcoKSkpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiAzNyAqIDE3ICsgKGludCkgKHNlZ21lbnRPZmZzZXReKHNlZ21lbnRPZmZzZXQ+Pj4zMikpOworICAgICAgfQorCisgICAgICAvKiogRmlsbHMgdXAgdGhlIHJhd0tleSBvYmplY3Qgd2l0aCB0aGUga2V5IHJldHVybmVkIGJ5IHRoZSBSZWFkZXIKKyAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGVyZSBpcyBhIGtleSByZXR1cm5lZDsgZmFsc2UsIG90aGVyd2lzZQorICAgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAgICovCisgICAgICBwdWJsaWMgYm9vbGVhbiBuZXh0UmF3S2V5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGluID09IG51bGwpIHsKKyAgICAgICAgICBpbnQgYnVmZmVyU2l6ZSA9IGNvbmYuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5Nik7IAorICAgICAgICAgIGlmIChmcy5nZXRVcmkoKS5nZXRTY2hlbWUoKS5zdGFydHNXaXRoKCJyYW1mcyIpKSB7CisgICAgICAgICAgICBidWZmZXJTaXplID0gY29uZi5nZXRJbnQoImlvLmJ5dGVzLnBlci5jaGVja3N1bSIsIDUxMik7CisgICAgICAgICAgfQorICAgICAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgUmVhZGVyKGZzLCBzZWdtZW50UGF0aE5hbWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclNpemUsIHNlZ21lbnRPZmZzZXQsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRMZW5ndGgsIGNvbmYsIGZhbHNlKTsKKyAgICAgICAgCisgICAgICAgICAgLy9zb21ldGltZXMgd2UgaWdub3JlIHN5bmNzIGVzcGVjaWFsbHkgZm9yIHRlbXAgbWVyZ2UgZmlsZXMKKyAgICAgICAgICBpZiAoaWdub3JlU3luYykgcmVhZGVyLnN5bmMgPSBudWxsOworCisgICAgICAgICAgaWYgKHJlYWRlci5nZXRLZXlDbGFzcygpICE9IGtleUNsYXNzKQorICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ3cm9uZyBrZXkgY2xhc3M6ICIgKyByZWFkZXIuZ2V0S2V5Q2xhc3MoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBpcyBub3QgIiArIGtleUNsYXNzKTsKKyAgICAgICAgICBpZiAocmVhZGVyLmdldFZhbHVlQ2xhc3MoKSAhPSB2YWxDbGFzcykKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigid3JvbmcgdmFsdWUgY2xhc3M6ICIrcmVhZGVyLmdldFZhbHVlQ2xhc3MoKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGlzIG5vdCAiICsgdmFsQ2xhc3MpOworICAgICAgICAgIHRoaXMuaW4gPSByZWFkZXI7CisgICAgICAgICAgcmF3S2V5ID0gbmV3IERhdGFPdXRwdXRCdWZmZXIoKTsKKyAgICAgICAgfQorICAgICAgICByYXdLZXkucmVzZXQoKTsKKyAgICAgICAgaW50IGtleUxlbmd0aCA9IAorICAgICAgICAgIGluLm5leHRSYXdLZXkocmF3S2V5KTsKKyAgICAgICAgcmV0dXJuIChrZXlMZW5ndGggPj0gMCk7CisgICAgICB9CisKKyAgICAgIC8qKiBGaWxscyB1cCB0aGUgcGFzc2VkIHJhd1ZhbHVlIHdpdGggdGhlIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGtleQorICAgICAgICogcmVhZCBlYXJsaWVyCisgICAgICAgKiBAcGFyYW0gcmF3VmFsdWUKKyAgICAgICAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgdmFsdWUKKyAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgICAqLworICAgICAgcHVibGljIGludCBuZXh0UmF3VmFsdWUoVmFsdWVCeXRlcyByYXdWYWx1ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaW50IHZhbExlbmd0aCA9IGluLm5leHRSYXdWYWx1ZShyYXdWYWx1ZSk7CisgICAgICAgIHJldHVybiB2YWxMZW5ndGg7CisgICAgICB9CisgICAgICAKKyAgICAgIC8qKiBSZXR1cm5zIHRoZSBzdG9yZWQgcmF3S2V5ICovCisgICAgICBwdWJsaWMgRGF0YU91dHB1dEJ1ZmZlciBnZXRLZXkoKSB7CisgICAgICAgIHJldHVybiByYXdLZXk7CisgICAgICB9CisgICAgICAKKyAgICAgIC8qKiBjbG9zZXMgdGhlIHVuZGVybHlpbmcgcmVhZGVyICovCisgICAgICBwcml2YXRlIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aGlzLmluLmNsb3NlKCk7CisgICAgICAgIHRoaXMuaW4gPSBudWxsOworICAgICAgfQorCisgICAgICAvKiogVGhlIGRlZmF1bHQgY2xlYW51cC4gU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyB3aXRoIGEgY3VzdG9tIAorICAgICAgICogY2xlYW51cCAKKyAgICAgICAqLworICAgICAgcHVibGljIHZvaWQgY2xlYW51cCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGNsb3NlKCk7CisgICAgICAgIGlmICghcHJlc2VydmVJbnB1dCkgeworICAgICAgICAgIGZzLmRlbGV0ZShzZWdtZW50UGF0aE5hbWUsIHRydWUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSAvLyBTZXF1ZW5jZUZpbGUuU29ydGVyLlNlZ21lbnREZXNjcmlwdG9yCisgICAgCisgICAgLyoqIFRoaXMgY2xhc3MgcHJvdmlzaW9ucyBtdWx0aXBsZSBzZWdtZW50cyBjb250YWluZWQgd2l0aGluIGEgc2luZ2xlCisgICAgICogIGZpbGUKKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIExpbmtlZFNlZ21lbnRzRGVzY3JpcHRvciBleHRlbmRzIFNlZ21lbnREZXNjcmlwdG9yIHsKKworICAgICAgU2VnbWVudENvbnRhaW5lciBwYXJlbnRDb250YWluZXIgPSBudWxsOworCisgICAgICAvKiogQ29uc3RydWN0cyBhIHNlZ21lbnQKKyAgICAgICAqIEBwYXJhbSBzZWdtZW50T2Zmc2V0IHRoZSBvZmZzZXQgb2YgdGhlIHNlZ21lbnQgaW4gdGhlIGZpbGUKKyAgICAgICAqIEBwYXJhbSBzZWdtZW50TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHNlZ21lbnQKKyAgICAgICAqIEBwYXJhbSBzZWdtZW50UGF0aE5hbWUgdGhlIHBhdGggbmFtZSBvZiB0aGUgZmlsZSBjb250YWluaW5nIHRoZSBzZWdtZW50CisgICAgICAgKiBAcGFyYW0gcGFyZW50IHRoZSBwYXJlbnQgU2VnbWVudENvbnRhaW5lciB0aGF0IGhvbGRzIHRoZSBzZWdtZW50CisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBMaW5rZWRTZWdtZW50c0Rlc2NyaXB0b3IgKGxvbmcgc2VnbWVudE9mZnNldCwgbG9uZyBzZWdtZW50TGVuZ3RoLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggc2VnbWVudFBhdGhOYW1lLCBTZWdtZW50Q29udGFpbmVyIHBhcmVudCkgeworICAgICAgICBzdXBlcihzZWdtZW50T2Zmc2V0LCBzZWdtZW50TGVuZ3RoLCBzZWdtZW50UGF0aE5hbWUpOworICAgICAgICB0aGlzLnBhcmVudENvbnRhaW5lciA9IHBhcmVudDsKKyAgICAgIH0KKyAgICAgIC8qKiBUaGUgZGVmYXVsdCBjbGVhbnVwLiBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIHdpdGggYSBjdXN0b20gCisgICAgICAgKiBjbGVhbnVwIAorICAgICAgICovCisgICAgICBwdWJsaWMgdm9pZCBjbGVhbnVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgICAgaWYgKHN1cGVyLnNob3VsZFByZXNlcnZlSW5wdXQoKSkgcmV0dXJuOworICAgICAgICBwYXJlbnRDb250YWluZXIuY2xlYW51cCgpOworICAgICAgfQorICAgIH0gLy9TZXF1ZW5jZUZpbGUuU29ydGVyLkxpbmtlZFNlZ21lbnRzRGVzY3JpcHRvcgorCisgICAgLyoqIFRoZSBjbGFzcyB0aGF0IGRlZmluZXMgYSBjb250YWluZXIgZm9yIHNlZ21lbnRzIHRvIGJlIG1lcmdlZC4gUHJpbWFyaWx5CisgICAgICogcmVxdWlyZWQgdG8gZGVsZXRlIHRlbXAgZmlsZXMgYXMgc29vbiBhcyBhbGwgdGhlIGNvbnRhaW5lZCBzZWdtZW50cworICAgICAqIGhhdmUgYmVlbiBsb29rZWQgYXQgKi8KKyAgICBwcml2YXRlIGNsYXNzIFNlZ21lbnRDb250YWluZXIgeworICAgICAgcHJpdmF0ZSBpbnQgbnVtU2VnbWVudHNDbGVhbmVkVXAgPSAwOyAvL3RyYWNrIHRoZSBuby4gb2Ygc2VnbWVudCBjbGVhbnVwcworICAgICAgcHJpdmF0ZSBpbnQgbnVtU2VnbWVudHNDb250YWluZWQ7IC8vIyBvZiBzZWdtZW50cyBjb250YWluZWQKKyAgICAgIHByaXZhdGUgUGF0aCBpbk5hbWU7IC8vaW5wdXQgZmlsZSBmcm9tIHdoZXJlIHNlZ21lbnRzIGFyZSBjcmVhdGVkCisgICAgICAKKyAgICAgIC8vdGhlIGxpc3Qgb2Ygc2VnbWVudHMgcmVhZCBmcm9tIHRoZSBmaWxlCisgICAgICBwcml2YXRlIEFycmF5TGlzdCA8U2VnbWVudERlc2NyaXB0b3I+IHNlZ21lbnRzID0gCisgICAgICAgIG5ldyBBcnJheUxpc3QgPFNlZ21lbnREZXNjcmlwdG9yPigpOworICAgICAgLyoqIFRoaXMgY29uc3RydWN0b3IgaXMgdGhlcmUgcHJpbWFyaWx5IHRvIHNlcnZlIHRoZSBzb3J0IHJvdXRpbmUgdGhhdCAKKyAgICAgICAqIGdlbmVyYXRlcyBhIHNpbmdsZSBvdXRwdXQgZmlsZSB3aXRoIGFuIGFzc29jaWF0ZWQgaW5kZXggZmlsZSAqLworICAgICAgcHVibGljIFNlZ21lbnRDb250YWluZXIoUGF0aCBpbk5hbWUsIFBhdGggaW5kZXhJbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy9nZXQgdGhlIHNlZ21lbnRzIGZyb20gaW5kZXhJbgorICAgICAgICBGU0RhdGFJbnB1dFN0cmVhbSBmc0luZGV4SW4gPSBmcy5vcGVuKGluZGV4SW4pOworICAgICAgICBsb25nIGVuZCA9IGZzLmdldExlbmd0aChpbmRleEluKTsKKyAgICAgICAgd2hpbGUgKGZzSW5kZXhJbi5nZXRQb3MoKSA8IGVuZCkgeworICAgICAgICAgIGxvbmcgc2VnbWVudE9mZnNldCA9IFdyaXRhYmxlVXRpbHMucmVhZFZMb25nKGZzSW5kZXhJbik7CisgICAgICAgICAgbG9uZyBzZWdtZW50TGVuZ3RoID0gV3JpdGFibGVVdGlscy5yZWFkVkxvbmcoZnNJbmRleEluKTsKKyAgICAgICAgICBQYXRoIHNlZ21lbnROYW1lID0gaW5OYW1lOworICAgICAgICAgIHNlZ21lbnRzLmFkZChuZXcgTGlua2VkU2VnbWVudHNEZXNjcmlwdG9yKHNlZ21lbnRPZmZzZXQsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRMZW5ndGgsIHNlZ21lbnROYW1lLCB0aGlzKSk7CisgICAgICAgIH0KKyAgICAgICAgZnNJbmRleEluLmNsb3NlKCk7CisgICAgICAgIGZzLmRlbGV0ZShpbmRleEluLCB0cnVlKTsKKyAgICAgICAgbnVtU2VnbWVudHNDb250YWluZWQgPSBzZWdtZW50cy5zaXplKCk7CisgICAgICAgIHRoaXMuaW5OYW1lID0gaW5OYW1lOworICAgICAgfQorCisgICAgICBwdWJsaWMgTGlzdCA8U2VnbWVudERlc2NyaXB0b3I+IGdldFNlZ21lbnRMaXN0KCkgeworICAgICAgICByZXR1cm4gc2VnbWVudHM7CisgICAgICB9CisgICAgICBwdWJsaWMgdm9pZCBjbGVhbnVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgbnVtU2VnbWVudHNDbGVhbmVkVXArKzsKKyAgICAgICAgaWYgKG51bVNlZ21lbnRzQ2xlYW5lZFVwID09IG51bVNlZ21lbnRzQ29udGFpbmVkKSB7CisgICAgICAgICAgZnMuZGVsZXRlKGluTmFtZSwgdHJ1ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IC8vU2VxdWVuY2VGaWxlLlNvcnRlci5TZWdtZW50Q29udGFpbmVyCisKKyAgfSAvLyBTZXF1ZW5jZUZpbGUuU29ydGVyCisKK30gLy8gU2VxdWVuY2VGaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9CbG9ja0NhY2hlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9CbG9ja0NhY2hlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjJlZDg2NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL0Jsb2NrQ2FjaGUuamF2YQpAQCAtMCwwICsxLDQyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGU7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCisvKioKKyAqIEJsb2NrIGNhY2hlIGludGVyZmFjZS4KKyAqIFRPRE86IEFkZCBmaWxlbmFtZSBvciBoYXNoIG9mIGZpbGVuYW1lIHRvIGJsb2NrIGNhY2hlIGtleS4KKyAqLworcHVibGljIGludGVyZmFjZSBCbG9ja0NhY2hlIHsKKyAgLyoqCisgICAqIEFkZCBibG9jayB0byBjYWNoZS4KKyAgICogQHBhcmFtIGJsb2NrTmFtZSBaZXJvLWJhc2VkIGZpbGUgYmxvY2sgbnVtYmVyLgorICAgKiBAcGFyYW0gYnVmIFRoZSBibG9jayBjb250ZW50cyB3cmFwcGVkIGluIGEgQnl0ZUJ1ZmZlci4KKyAgICovCisgIHB1YmxpYyB2b2lkIGNhY2hlQmxvY2soU3RyaW5nIGJsb2NrTmFtZSwgQnl0ZUJ1ZmZlciBidWYpOworICAKKyAgLyoqCisgICAqIEZldGNoIGJsb2NrIGZyb20gY2FjaGUuCisgICAqIEBwYXJhbSBibG9ja05hbWUgQmxvY2sgbnVtYmVyIHRvIGZldGNoLgorICAgKiBAcmV0dXJuIEJsb2NrIG9yIG51bGwgaWYgYmxvY2sgaXMgbm90IGluIHRoZSBjYWNoZS4KKyAgICovCisgIHB1YmxpYyBCeXRlQnVmZmVyIGdldEJsb2NrKFN0cmluZyBibG9ja05hbWUpOyAgCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvQm91bmRlZFJhbmdlRmlsZUlucHV0U3RyZWFtLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9Cb3VuZGVkUmFuZ2VGaWxlSW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTc3MzRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvQm91bmRlZFJhbmdlRmlsZUlucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVAorICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlCisgKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgorICogdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YUlucHV0U3RyZWFtOworCisvKioKKyAqIEJvdW5kZWRSYW5nZUZJbGVJbnB1dFN0cmVhbSBhYnN0cmFjdHMgYSBjb250aWd1b3VzIHJlZ2lvbiBvZiBhIEhhZG9vcAorICogRlNEYXRhSW5wdXRTdHJlYW0gYXMgYSByZWd1bGFyIGlucHV0IHN0cmVhbS4gT25lIGNhbiBjcmVhdGUgbXVsdGlwbGUKKyAqIEJvdW5kZWRSYW5nZUZpbGVJbnB1dFN0cmVhbSBvbiB0b3Agb2YgdGhlIHNhbWUgRlNEYXRhSW5wdXRTdHJlYW0gYW5kIHRoZXkKKyAqIHdvdWxkIG5vdCBpbnRlcmZlcmUgd2l0aCBlYWNoIG90aGVyLgorICogQ29waWVkIGZyb20gaGFkb29wLTMzNSB0ZmlsZS4KKyAqLworY2xhc3MgQm91bmRlZFJhbmdlRmlsZUlucHV0U3RyZWFtICBleHRlbmRzIElucHV0U3RyZWFtIHsKKworICBwcml2YXRlIEZTRGF0YUlucHV0U3RyZWFtIGluOworICBwcml2YXRlIGxvbmcgcG9zOworICBwcml2YXRlIGxvbmcgZW5kOworICBwcml2YXRlIGxvbmcgbWFyazsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlW10gb25lQnl0ZSA9IG5ldyBieXRlWzFdOworCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKgorICAgKiBAcGFyYW0gaW4KKyAgICogICAgICAgICAgVGhlIEZTRGF0YUlucHV0U3RyZWFtIHdlIGNvbm5lY3QgdG8uCisgICAqIEBwYXJhbSBvZmZzZXQKKyAgICogICAgICAgICAgQmVnaW5uaW5nIG9mZnNldCBvZiB0aGUgcmVnaW9uLgorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqICAgICAgICAgIExlbmd0aCBvZiB0aGUgcmVnaW9uLgorICAgKgorICAgKiAgICAgICAgICBUaGUgYWN0dWFsIGxlbmd0aCBvZiB0aGUgcmVnaW9uIG1heSBiZSBzbWFsbGVyIGlmIChvZmZfYmVnaW4gKworICAgKiAgICAgICAgICBsZW5ndGgpIGdvZXMgYmV5b25kIHRoZSBlbmQgb2YgRlMgaW5wdXQgc3RyZWFtLgorICAgKi8KKyAgcHVibGljIEJvdW5kZWRSYW5nZUZpbGVJbnB1dFN0cmVhbShGU0RhdGFJbnB1dFN0cmVhbSBpbiwgbG9uZyBvZmZzZXQsCisgICAgICBsb25nIGxlbmd0aCkgeworICAgIGlmIChvZmZzZXQgPCAwIHx8IGxlbmd0aCA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCJJbnZhbGlkIG9mZnNldC9sZW5ndGg6ICIgKyBvZmZzZXQKKyAgICAgICAgICArICIvIiArIGxlbmd0aCk7CisgICAgfQorCisgICAgdGhpcy5pbiA9IGluOworICAgIHRoaXMucG9zID0gb2Zmc2V0OworICAgIHRoaXMuZW5kID0gb2Zmc2V0ICsgbGVuZ3RoOworICAgIHRoaXMubWFyayA9IC0xOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgYXZhaWwgPSBpbi5hdmFpbGFibGUoKTsKKyAgICBpZiAocG9zICsgYXZhaWwgPiBlbmQpIHsKKyAgICAgIGF2YWlsID0gKGludCkgKGVuZCAtIHBvcyk7CisgICAgfQorCisgICAgcmV0dXJuIGF2YWlsOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IHJldCA9IHJlYWQob25lQnl0ZSk7CisgICAgaWYgKHJldCA9PSAxKSByZXR1cm4gb25lQnl0ZVswXSAmIDB4ZmY7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gcmVhZChiLCAwLCBiLmxlbmd0aCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICgob2ZmIHwgbGVuIHwgKG9mZiArIGxlbikgfCAoYi5sZW5ndGggLSAob2ZmICsgbGVuKSkpIDwgMCkgeworICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBpbnQgbiA9IChpbnQpIE1hdGgubWluKEludGVnZXIuTUFYX1ZBTFVFLCBNYXRoLm1pbihsZW4sIChlbmQgLSBwb3MpKSk7CisgICAgaWYgKG4gPT0gMCkgcmV0dXJuIC0xOworICAgIGludCByZXQgPSAwOworICAgIHN5bmNocm9uaXplZCAoaW4pIHsKKyAgICAgIGluLnNlZWsocG9zKTsKKyAgICAgIHJldCA9IGluLnJlYWQoYiwgb2ZmLCBuKTsKKyAgICB9CisgICAgLy8gLyByZXQgPSBpbi5yZWFkKHBvcywgYiwgb2ZmLCBuKTsKKyAgICBpZiAocmV0IDwgMCkgeworICAgICAgZW5kID0gcG9zOworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBwb3MgKz0gcmV0OworICAgIHJldHVybiByZXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgLyoKKyAgICogV2UgbWF5IHNraXAgYmV5b25kIHRoZSBlbmQgb2YgdGhlIGZpbGUuCisgICAqLworICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIGxlbiA9IE1hdGgubWluKG4sIGVuZCAtIHBvcyk7CisgICAgcG9zICs9IGxlbjsKKyAgICByZXR1cm4gbGVuOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIG1hcmsoaW50IHJlYWRsaW1pdCkgeworICAgIG1hcmsgPSBwb3M7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcmVzZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChtYXJrIDwgMCkgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZXNldHRpbmcgdG8gaW52YWxpZCBtYXJrIik7CisgICAgcG9zID0gbWFyazsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgIC8vIEludmFsaWRhdGUgdGhlIHN0YXRlIG9mIHRoZSBzdHJlYW0uCisgICAgaW4gPSBudWxsOworICAgIHBvcyA9IGVuZDsKKyAgICBtYXJrID0gLTE7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9Db21wcmVzc2lvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvQ29tcHJlc3Npb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMjcyNjFkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvQ29tcHJlc3Npb24uamF2YQpAQCAtMCwwICsxLDI3NyBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqIAorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWx0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkNvZGVjUG9vbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5Db21wcmVzc2lvbkNvZGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkNvbXByZXNzaW9uSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuQ29tcHJlc3Npb25PdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuQ29tcHJlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5EZWNvbXByZXNzb3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuR3ppcENvZGVjOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkRlZmF1bHRDb2RlYzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlJlZmxlY3Rpb25VdGlsczsKKworLyoqCisgKiBDb21wcmVzc2lvbiByZWxhdGVkIHN0dWZmLgorICogQ29waWVkIGZyb20gaGFkb29wLTMzMTUgdGZpbGUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb21wcmVzc2lvbiB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coQ29tcHJlc3Npb24uY2xhc3MpOworCisgIC8qKgorICAgKiBQcmV2ZW50IHRoZSBpbnN0YW50aWF0aW9uIG9mIGNsYXNzLgorICAgKi8KKyAgcHJpdmF0ZSBDb21wcmVzc2lvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgc3RhdGljIGNsYXNzIEZpbmlzaE9uRmx1c2hDb21wcmVzc2lvblN0cmVhbSBleHRlbmRzIEZpbHRlck91dHB1dFN0cmVhbSB7CisgICAgcHVibGljIEZpbmlzaE9uRmx1c2hDb21wcmVzc2lvblN0cmVhbShDb21wcmVzc2lvbk91dHB1dFN0cmVhbSBjb3V0KSB7CisgICAgICBzdXBlcihjb3V0KTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlIGJbXSwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIG91dC53cml0ZShiLCBvZmYsIGxlbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgQ29tcHJlc3Npb25PdXRwdXRTdHJlYW0gY291dCA9IChDb21wcmVzc2lvbk91dHB1dFN0cmVhbSkgb3V0OworICAgICAgY291dC5maW5pc2goKTsKKyAgICAgIGNvdXQuZmx1c2goKTsKKyAgICAgIGNvdXQucmVzZXRTdGF0ZSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wcmVzc2lvbiBhbGdvcml0aG1zLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBlbnVtIEFsZ29yaXRobSB7CisgICAgTFpPKCJsem8iKSB7CisgICAgICAvLyBVc2UgYmFzZSB0eXBlIHRvIGF2b2lkIGNvbXBpbGUtdGltZSBkZXBlbmRlbmNpZXMuCisgICAgICBwcml2YXRlIENvbXByZXNzaW9uQ29kZWMgbHpvQ29kZWM7CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgQ29tcHJlc3Npb25Db2RlYyBnZXRDb2RlYygpIHsKKyAgICAgICAgaWYgKGx6b0NvZGVjID09IG51bGwpIHsKKyAgICAgICAgICBDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgQ29uZmlndXJhdGlvbigpOworICAgICAgICAgIGNvbmYuc2V0Qm9vbGVhbigiaGFkb29wLm5hdGl2ZS5saWIiLCB0cnVlKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgQ2xhc3M8Pz4gZXh0ZXJuYWxDb2RlYyA9CisgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtQ2xhc3NMb2FkZXIoKS5sb2FkQ2xhc3MoImNvbS5oYWRvb3AuY29tcHJlc3Npb24ubHpvLkx6b0NvZGVjIik7CisgICAgICAgICAgICBsem9Db2RlYyA9IChDb21wcmVzc2lvbkNvZGVjKSBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2UoZXh0ZXJuYWxDb2RlYywgY29uZik7CisgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGx6b0NvZGVjOworICAgICAgfQorICAgIH0sCisgICAgR1ooImd6IikgeworICAgICAgcHJpdmF0ZSBHemlwQ29kZWMgY29kZWM7CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgRGVmYXVsdENvZGVjIGdldENvZGVjKCkgeworICAgICAgICBpZiAoY29kZWMgPT0gbnVsbCkgeworICAgICAgICAgIENvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBDb25maWd1cmF0aW9uKCk7CisgICAgICAgICAgY29uZi5zZXRCb29sZWFuKCJoYWRvb3AubmF0aXZlLmxpYiIsIHRydWUpOworICAgICAgICAgIGNvZGVjID0gbmV3IEd6aXBDb2RlYygpOworICAgICAgICAgIGNvZGVjLnNldENvbmYoY29uZik7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gY29kZWM7CisgICAgICB9CisgICAgfSwKKworICAgIE5PTkUoIm5vbmUiKSB7CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIERlZmF1bHRDb2RlYyBnZXRDb2RlYygpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHN5bmNocm9uaXplZCBJbnB1dFN0cmVhbSBjcmVhdGVEZWNvbXByZXNzaW9uU3RyZWFtKAorICAgICAgICAgIElucHV0U3RyZWFtIGRvd25TdHJlYW0sIERlY29tcHJlc3NvciBkZWNvbXByZXNzb3IsCisgICAgICAgICAgaW50IGRvd25TdHJlYW1CdWZmZXJTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAoZG93blN0cmVhbUJ1ZmZlclNpemUgPiAwKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGRvd25TdHJlYW0sIGRvd25TdHJlYW1CdWZmZXJTaXplKTsKKyAgICAgICAgfQorICAgICAgICAvLyBlbHNlIHsKKyAgICAgICAgICAvLyBNYWtlIHN1cmUgd2UgYnlwYXNzIEZTSW5wdXRDaGVja2VyIGJ1ZmZlci4KKyAgICAgICAgLy8gcmV0dXJuIG5ldyBCdWZmZXJlZElucHV0U3RyZWFtKGRvd25TdHJlYW0sIDEwMjQpOworICAgICAgICAvLyB9CisgICAgICAgIC8vIH0KKyAgICAgICAgcmV0dXJuIGRvd25TdHJlYW07CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHN5bmNocm9uaXplZCBPdXRwdXRTdHJlYW0gY3JlYXRlQ29tcHJlc3Npb25TdHJlYW0oCisgICAgICAgICAgT3V0cHV0U3RyZWFtIGRvd25TdHJlYW0sIENvbXByZXNzb3IgY29tcHJlc3NvciwKKyAgICAgICAgICBpbnQgZG93blN0cmVhbUJ1ZmZlclNpemUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGlmIChkb3duU3RyZWFtQnVmZmVyU2l6ZSA+IDApIHsKKyAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKGRvd25TdHJlYW0sIGRvd25TdHJlYW1CdWZmZXJTaXplKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBkb3duU3RyZWFtOworICAgICAgfQorICAgIH07CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBjb21wcmVzc05hbWU7CisJLy8gZGF0YSBpbnB1dCBidWZmZXIgc2l6ZSB0byBhYnNvcmIgc21hbGwgcmVhZHMgZnJvbSBhcHBsaWNhdGlvbi4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREFUQV9JQlVGX1NJWkUgPSAxICogMTAyNDsKKwkvLyBkYXRhIG91dHB1dCBidWZmZXIgc2l6ZSB0byBhYnNvcmIgc21hbGwgd3JpdGVzIGZyb20gYXBwbGljYXRpb24uCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERBVEFfT0JVRl9TSVpFID0gNCAqIDEwMjQ7CisKKyAgICBBbGdvcml0aG0oU3RyaW5nIG5hbWUpIHsKKyAgICAgIHRoaXMuY29tcHJlc3NOYW1lID0gbmFtZTsKKyAgICB9CisKKyAgICBhYnN0cmFjdCBDb21wcmVzc2lvbkNvZGVjIGdldENvZGVjKCk7CisKKyAgICBwdWJsaWMgSW5wdXRTdHJlYW0gY3JlYXRlRGVjb21wcmVzc2lvblN0cmVhbSgKKyAgICAgICAgSW5wdXRTdHJlYW0gZG93blN0cmVhbSwgRGVjb21wcmVzc29yIGRlY29tcHJlc3NvciwKKyAgICAgICAgaW50IGRvd25TdHJlYW1CdWZmZXJTaXplKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgQ29tcHJlc3Npb25Db2RlYyBjb2RlYyA9IGdldENvZGVjKCk7CisgICAgICAvLyBTZXQgdGhlIGludGVybmFsIGJ1ZmZlciBzaXplIHRvIHJlYWQgZnJvbSBkb3duIHN0cmVhbS4KKyAgICAgIGlmIChkb3duU3RyZWFtQnVmZmVyU2l6ZSA+IDApIHsKKyAgICAgICAgQ29uZmlndXJhYmxlIGMgPSAoQ29uZmlndXJhYmxlKSBjb2RlYzsKKyAgICAgICAgYy5nZXRDb25mKCkuc2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgZG93blN0cmVhbUJ1ZmZlclNpemUpOworICAgICAgfQorICAgICAgQ29tcHJlc3Npb25JbnB1dFN0cmVhbSBjaXMgPQorICAgICAgICAgIGNvZGVjLmNyZWF0ZUlucHV0U3RyZWFtKGRvd25TdHJlYW0sIGRlY29tcHJlc3Nvcik7CisgICAgICBCdWZmZXJlZElucHV0U3RyZWFtIGJpczIgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShjaXMsIERBVEFfSUJVRl9TSVpFKTsKKyAgICAgIHJldHVybiBiaXMyOworCisgICAgfQorCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBjcmVhdGVDb21wcmVzc2lvblN0cmVhbSgKKyAgICAgICAgT3V0cHV0U3RyZWFtIGRvd25TdHJlYW0sIENvbXByZXNzb3IgY29tcHJlc3NvciwgaW50IGRvd25TdHJlYW1CdWZmZXJTaXplKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgQ29tcHJlc3Npb25Db2RlYyBjb2RlYyA9IGdldENvZGVjKCk7CisgICAgICBPdXRwdXRTdHJlYW0gYm9zMSA9IG51bGw7CisgICAgICBpZiAoZG93blN0cmVhbUJ1ZmZlclNpemUgPiAwKSB7CisgICAgICAgIGJvczEgPSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oZG93blN0cmVhbSwgZG93blN0cmVhbUJ1ZmZlclNpemUpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIGJvczEgPSBkb3duU3RyZWFtOworICAgICAgfQorICAgICAgQ29uZmlndXJhYmxlIGMgPSAoQ29uZmlndXJhYmxlKSBjb2RlYzsKKyAgICAgIGMuZ2V0Q29uZigpLnNldEludCgiaW8uZmlsZS5idWZmZXIuc2l6ZSIsIDMyICogMTAyNCk7CisgICAgICBDb21wcmVzc2lvbk91dHB1dFN0cmVhbSBjb3MgPQorICAgICAgICAgIGNvZGVjLmNyZWF0ZU91dHB1dFN0cmVhbShib3MxLCBjb21wcmVzc29yKTsKKyAgICAgIEJ1ZmZlcmVkT3V0cHV0U3RyZWFtIGJvczIgPQorICAgICAgICAgIG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmluaXNoT25GbHVzaENvbXByZXNzaW9uU3RyZWFtKGNvcyksCisgICAgICAgICAgICAgIERBVEFfT0JVRl9TSVpFKTsKKyAgICAgIHJldHVybiBib3MyOworICAgIH0KKworICAgIHB1YmxpYyBDb21wcmVzc29yIGdldENvbXByZXNzb3IoKSB7CisgICAgICBDb21wcmVzc2lvbkNvZGVjIGNvZGVjID0gZ2V0Q29kZWMoKTsKKyAgICAgIGlmIChjb2RlYyAhPSBudWxsKSB7CisgICAgICAgIENvbXByZXNzb3IgY29tcHJlc3NvciA9IENvZGVjUG9vbC5nZXRDb21wcmVzc29yKGNvZGVjKTsKKyAgICAgICAgaWYgKGNvbXByZXNzb3IgIT0gbnVsbCkgeworICAgICAgICAgIGlmIChjb21wcmVzc29yLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIC8vIFNvbWVib2R5IHJldHVybnMgdGhlIGNvbXByZXNzb3IgdG8gQ29kZWNQb29sIGJ1dCBpcyBzdGlsbCB1c2luZworICAgICAgICAgICAgLy8gaXQuCisgICAgICAgICAgICBMT0cKKyAgICAgICAgICAgICAgICAud2FybigiQ29tcHJlc3NvciBvYnRhaW5lZCBmcm9tIENvZGVjUG9vbCBpcyBhbHJlYWR5IGZpbmlzaGVkKCkiKTsKKyAgICAgICAgICAgIC8vIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigKKyAgICAgICAgICAgIC8vICJDb21wcmVzc29yIG9idGFpbmVkIGZyb20gQ29kZWNQb29sIGlzIGFscmVhZHkgZmluaXNoZWQoKSIpOworICAgICAgICAgIH0KKyAgICAgICAgICBjb21wcmVzc29yLnJlc2V0KCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGNvbXByZXNzb3I7CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXR1cm5Db21wcmVzc29yKENvbXByZXNzb3IgY29tcHJlc3NvcikgeworICAgICAgaWYgKGNvbXByZXNzb3IgIT0gbnVsbCkgeworICAgICAgICBDb2RlY1Bvb2wucmV0dXJuQ29tcHJlc3Nvcihjb21wcmVzc29yKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgRGVjb21wcmVzc29yIGdldERlY29tcHJlc3NvcigpIHsKKyAgICAgIENvbXByZXNzaW9uQ29kZWMgY29kZWMgPSBnZXRDb2RlYygpOworICAgICAgaWYgKGNvZGVjICE9IG51bGwpIHsKKyAgICAgICAgRGVjb21wcmVzc29yIGRlY29tcHJlc3NvciA9IENvZGVjUG9vbC5nZXREZWNvbXByZXNzb3IoY29kZWMpOworICAgICAgICBpZiAoZGVjb21wcmVzc29yICE9IG51bGwpIHsKKyAgICAgICAgICBpZiAoZGVjb21wcmVzc29yLmZpbmlzaGVkKCkpIHsKKyAgICAgICAgICAgIC8vIFNvbWVib2R5IHJldHVybnMgdGhlIGRlY29tcHJlc3NvciB0byBDb2RlY1Bvb2wgYnV0IGlzIHN0aWxsIHVzaW5nCisgICAgICAgICAgICAvLyBpdC4KKyAgICAgICAgICAgIExPRworICAgICAgICAgICAgICAgIC53YXJuKCJEZW9tcHJlc3NvciBvYnRhaW5lZCBmcm9tIENvZGVjUG9vbCBpcyBhbHJlYWR5IGZpbmlzaGVkKCkiKTsKKyAgICAgICAgICAgIC8vIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigKKyAgICAgICAgICAgIC8vICJEZWNvbXByZXNzb3Igb2J0YWluZWQgZnJvbSBDb2RlY1Bvb2wgaXMgYWxyZWFkeSBmaW5pc2hlZCgpIik7CisgICAgICAgICAgfQorICAgICAgICAgIGRlY29tcHJlc3Nvci5yZXNldCgpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBkZWNvbXByZXNzb3I7CisgICAgICB9CisKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJldHVybkRlY29tcHJlc3NvcihEZWNvbXByZXNzb3IgZGVjb21wcmVzc29yKSB7CisgICAgICBpZiAoZGVjb21wcmVzc29yICE9IG51bGwpIHsKKyAgICAgICAgQ29kZWNQb29sLnJldHVybkRlY29tcHJlc3NvcihkZWNvbXByZXNzb3IpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgIHJldHVybiBjb21wcmVzc05hbWU7CisgICAgfQorICB9CisKKyAgcHVibGljIHN0YXRpYyBBbGdvcml0aG0gZ2V0Q29tcHJlc3Npb25BbGdvcml0aG1CeU5hbWUoU3RyaW5nIGNvbXByZXNzTmFtZSkgeworICAgIEFsZ29yaXRobVtdIGFsZ29zID0gQWxnb3JpdGhtLmNsYXNzLmdldEVudW1Db25zdGFudHMoKTsKKworICAgIGZvciAoQWxnb3JpdGhtIGEgOiBhbGdvcykgeworICAgICAgaWYgKGEuZ2V0TmFtZSgpLmVxdWFscyhjb21wcmVzc05hbWUpKSB7CisgICAgICAgIHJldHVybiBhOworICAgICAgfQorICAgIH0KKworICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICJVbnN1cHBvcnRlZCBjb21wcmVzc2lvbiBhbGdvcml0aG0gbmFtZTogIiArIGNvbXByZXNzTmFtZSk7CisgIH0KKworICBzdGF0aWMgU3RyaW5nW10gZ2V0U3VwcG9ydGVkQWxnb3JpdGhtcygpIHsKKyAgICBBbGdvcml0aG1bXSBhbGdvcyA9IEFsZ29yaXRobS5jbGFzcy5nZXRFbnVtQ29uc3RhbnRzKCk7CisKKyAgICBTdHJpbmdbXSByZXQgPSBuZXcgU3RyaW5nW2FsZ29zLmxlbmd0aF07CisgICAgaW50IGkgPSAwOworICAgIGZvciAoQWxnb3JpdGhtIGEgOiBhbGdvcykgeworICAgICAgcmV0W2krK10gPSBhLmdldE5hbWUoKTsKKyAgICB9CisKKyAgICByZXR1cm4gcmV0OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9IRmlsZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvSEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMmNkMTI0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvSEZpbGUuamF2YQpAQCAtMCwwICsxLDE1NDQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZTsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGJhc2VNYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5IZWFwU2l6ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uUmF3Q29tcGFyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5jb21wcmVzcy5Db21wcmVzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkRlY29tcHJlc3NvcjsKKworLyoqCisgKiBGaWxlIGZvcm1hdCBmb3IgaGJhc2UuCisgKiBBIGZpbGUgb2Ygc29ydGVkIGtleS92YWx1ZSBwYWlycy4gQm90aCBrZXlzIGFuZCB2YWx1ZXMgYXJlIGJ5dGUgYXJyYXlzLgorICogPHA+CisgKiBUaGUgbWVtb3J5IGZvb3RwcmludCBvZiBhIEhGaWxlIGluY2x1ZGVzIHRoZSBmb2xsb3dpbmcgKGJlbG93IGlzIHRha2VuIGZyb20KKyAqIDxhCisgKiBocmVmPWh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEFET09QLTMzMTU+SGFkb29wLTMzMTUgdGZpbGU8L2E+CisgKiBidXQgYXBwbGllcyBhbHNvIHRvIEhGaWxlKToKKyAqIDx1bD4KKyAqIDxsaT5Tb21lIGNvbnN0YW50IG92ZXJoZWFkIG9mIHJlYWRpbmcgb3Igd3JpdGluZyBhIGNvbXByZXNzZWQgYmxvY2suCisgKiA8dWw+CisgKiA8bGk+RWFjaCBjb21wcmVzc2VkIGJsb2NrIHJlcXVpcmVzIG9uZSBjb21wcmVzc2lvbi9kZWNvbXByZXNzaW9uIGNvZGVjIGZvcgorICogSS9PLgorICogPGxpPlRlbXBvcmFyeSBzcGFjZSB0byBidWZmZXIgdGhlIGtleS4KKyAqIDxsaT5UZW1wb3Jhcnkgc3BhY2UgdG8gYnVmZmVyIHRoZSB2YWx1ZS4KKyAqIDwvdWw+CisgKiA8bGk+SEZpbGUgaW5kZXgsIHdoaWNoIGlzIHByb3BvcnRpb25hbCB0byB0aGUgdG90YWwgbnVtYmVyIG9mIERhdGEgQmxvY2tzLgorICogVGhlIHRvdGFsIGFtb3VudCBvZiBtZW1vcnkgbmVlZGVkIHRvIGhvbGQgdGhlIGluZGV4IGNhbiBiZSBlc3RpbWF0ZWQgYXMKKyAqICg1NitBdmdLZXlTaXplKSpOdW1CbG9ja3MuCisgKiA8L3VsPgorICogU3VnZ2VzdGlvbnMgb24gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uLgorICogPHVsPgorICogPGxpPk1pbmltdW0gYmxvY2sgc2l6ZS4gV2UgcmVjb21tZW5kIGEgc2V0dGluZyBvZiBtaW5pbXVtIGJsb2NrIHNpemUgYmV0d2VlbgorICogOEtCIHRvIDFNQiBmb3IgZ2VuZXJhbCB1c2FnZS4gTGFyZ2VyIGJsb2NrIHNpemUgaXMgcHJlZmVycmVkIGlmIGZpbGVzIGFyZQorICogcHJpbWFyaWx5IGZvciBzZXF1ZW50aWFsIGFjY2Vzcy4gSG93ZXZlciwgaXQgd291bGQgbGVhZCB0byBpbmVmZmljaWVudCByYW5kb20KKyAqIGFjY2VzcyAoYmVjYXVzZSB0aGVyZSBhcmUgbW9yZSBkYXRhIHRvIGRlY29tcHJlc3MpLiBTbWFsbGVyIGJsb2NrcyBhcmUgZ29vZAorICogZm9yIHJhbmRvbSBhY2Nlc3MsIGJ1dCByZXF1aXJlIG1vcmUgbWVtb3J5IHRvIGhvbGQgdGhlIGJsb2NrIGluZGV4LCBhbmQgbWF5CisgKiBiZSBzbG93ZXIgdG8gY3JlYXRlIChiZWNhdXNlIHdlIG11c3QgZmx1c2ggdGhlIGNvbXByZXNzb3Igc3RyZWFtIGF0IHRoZQorICogY29uY2x1c2lvbiBvZiBlYWNoIGRhdGEgYmxvY2ssIHdoaWNoIGxlYWRzIHRvIGFuIEZTIEkvTyBmbHVzaCkuIEZ1cnRoZXIsIGR1ZQorICogdG8gdGhlIGludGVybmFsIGNhY2hpbmcgaW4gQ29tcHJlc3Npb24gY29kZWMsIHRoZSBzbWFsbGVzdCBwb3NzaWJsZSBibG9jaworICogc2l6ZSB3b3VsZCBiZSBhcm91bmQgMjBLQi0zMEtCLgorICogPGxpPlRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIGRvZXMgbm90IG9mZmVyIHRydWUgbXVsdGktdGhyZWFkaW5nIGZvcgorICogcmVhZGluZy4gVGhlIGltcGxlbWVudGF0aW9uIHVzZXMgRlNEYXRhSW5wdXRTdHJlYW0gc2VlaygpK3JlYWQoKSwgd2hpY2ggaXMKKyAqIHNob3duIHRvIGJlIG11Y2ggZmFzdGVyIHRoYW4gcG9zaXRpb25lZC1yZWFkIGNhbGwgaW4gc2luZ2xlIHRocmVhZCBtb2RlLgorICogSG93ZXZlciwgaXQgYWxzbyBtZWFucyB0aGF0IGlmIG11bHRpcGxlIHRocmVhZHMgYXR0ZW1wdCB0byBhY2Nlc3MgdGhlIHNhbWUKKyAqIEhGaWxlICh1c2luZyBtdWx0aXBsZSBzY2FubmVycykgc2ltdWx0YW5lb3VzbHksIHRoZSBhY3R1YWwgSS9PIGlzIGNhcnJpZWQgb3V0CisgKiBzZXF1ZW50aWFsbHkgZXZlbiBpZiB0aGV5IGFjY2VzcyBkaWZmZXJlbnQgREZTIGJsb2NrcyAoUmVleGFtaW5lISBwcmVhZCBzZWVtcworICogdG8gYmUgMTAlIGZhc3RlciB0aGFuIHNlZWsrcmVhZCBpbiBteSB0ZXN0aW5nIC0tIHN0YWNrKS4KKyAqIDxsaT5Db21wcmVzc2lvbiBjb2RlYy4gVXNlICJub25lIiBpZiB0aGUgZGF0YSBpcyBub3QgdmVyeSBjb21wcmVzc2FibGUgKGJ5CisgKiBjb21wcmVzc2FibGUsIEkgbWVhbiBhIGNvbXByZXNzaW9uIHJhdGlvIGF0IGxlYXN0IDI6MSkuIEdlbmVyYWxseSwgdXNlICJsem8iCisgKiBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIGV4cGVyaW1lbnRpbmcuICJneiIgb3ZlcnMgc2xpZ2h0bHkgYmV0dGVyCisgKiBjb21wcmVzc2lvbiByYXRpbyBvdmVyICJsem8iIGJ1dCByZXF1aXJlcyA0eCBDUFUgdG8gY29tcHJlc3MgYW5kIDJ4IENQVSB0bworICogZGVjb21wcmVzcywgY29tcGFyaW5nIHRvICJsem8iLgorICogPC91bD4KKyAqIAorICogRm9yIG1vcmUgb24gdGhlIGJhY2tncm91bmQgYmVoaW5kIEhGaWxlLCBzZWUgPGEKKyAqIGhyZWY9aHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQkFTRS0zMzE1PkhCQVNFLTYxPC9hPi4KKyAqIDxwPgorICogRmlsZSBpcyBtYWRlIG9mIGRhdGEgYmxvY2tzIGZvbGxvd2VkIGJ5IG1ldGEgZGF0YSBibG9ja3MgKGlmIGFueSksIGEgZmlsZWluZm8KKyAqIGJsb2NrLCBkYXRhIGJsb2NrIGluZGV4LCBtZXRhIGRhdGEgYmxvY2sgaW5kZXgsIGFuZCBhIGZpeGVkIHNpemUgdHJhaWxlcgorICogd2hpY2ggcmVjb3JkcyB0aGUgb2Zmc2V0cyBhdCB3aGljaCBmaWxlIGNoYW5nZXMgY29udGVudCB0eXBlLgorICogPHByZT4mbHQ7ZGF0YSBibG9ja3M+Jmx0O21ldGEgYmxvY2tzPiZsdDtmaWxlaW5mbz4mbHQ7ZGF0YSBpbmRleD4mbHQ7bWV0YSBpbmRleD4mbHQ7dHJhaWxlcj48L3ByZT4KKyAqIEVhY2ggYmxvY2sgaGFzIGEgYml0IG9mIG1hZ2ljIGF0IGl0cyBzdGFydC4gIEJsb2NrIGFyZSBjb21wcmlzZWQgb2YKKyAqIGtleS92YWx1ZXMuICBJbiBkYXRhIGJsb2NrcywgdGhleSBhcmUgYm90aCBieXRlIGFycmF5cy4gIE1ldGFkYXRhIGJsb2NrcyBhcmUKKyAqIGEgU3RyaW5nIGtleSBhbmQgYSBieXRlIGFycmF5IHZhbHVlLiAgQW4gZW1wdHkgZmlsZSBsb29rcyBsaWtlIHRoaXM6CisgKiA8cHJlPiZsdDtmaWxlaW5mbz4mbHQ7dHJhaWxlcj48L3ByZT4uICBUaGF0IGlzLCB0aGVyZSBhcmUgbm90IGRhdGEgbm9yIG1ldGEKKyAqIGJsb2NrcyBwcmVzZW50LgorICogPHA+CisgKiBUT0RPOiBCbG9vbWZpbHRlcnMuICBOZWVkIHRvIGFkZCBoYWRvb3AgMC4yMC4gZmlyc3Qgc2luY2UgaXQgaGFzIGJ1ZyBmaXhlcworICogb24gdGhlIGhhZG9vcCBiZiBwYWNrYWdlLgorICogICogVE9ETzogVVNFIG1lbWNtcCBieSBkZWZhdWx0PyAgV3JpdGUgdGhlIGtleXMgb3V0IGluIGFuIG9yZGVyIHRoYXQgYWxsb3dzCisgKiBteSB1c2luZyB0aGlzIC0tIHJldmVyc2UgdGhlIHRpbWVzdGFtcC4KKyAqIFRPRE86IEFkZCBzdXBwb3J0IGZvciBmYXN0LWd6aXAgYW5kIGZvciBsem8uCisgKiBUT0RPOiBEbyBzY2FubmVycyBuZWVkIHRvIGJlIGFibGUgdG8gdGFrZSBhIHN0YXJ0IGFuZCBlbmQgcm93PworICogVE9ETzogU2hvdWxkIEJsb2NrSW5kZXgga25vdyB0aGUgbmFtZSBvZiBpdHMgZmlsZT8gIFNob3VsZCBpdCBoYXZlIGEgUGF0aAorICogdGhhdCBwb2ludHMgYXQgaXRzIGZpbGUgc2F5IGZvciB0aGUgY2FzZSB3aGVyZSBhbiBpbmRleCBsaXZlcyBhcGFydCBmcm9tCisgKiBhbiBIRmlsZSBpbnN0YW5jZT8KKyAqLworcHVibGljIGNsYXNzIEhGaWxlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhIRmlsZS5jbGFzcyk7CisKKyAgLyogVGhlc2UgdmFsdWVzIGFyZSBtb3JlIG9yIGxlc3MgYXJiaXRyYXJ5LCBhbmQgdGhleSBhcmUgdXNlZCBhcyBhIAorICAgKiBmb3JtIG9mIGNoZWNrIHRvIG1ha2Ugc3VyZSB0aGUgZmlsZSBpc24ndCBjb21wbGV0ZWx5IGNvcnJ1cHQuCisgICAqLworICBmaW5hbCBzdGF0aWMgYnl0ZSBbXSBEQVRBQkxPQ0tNQUdJQyA9CisgICAgeydEJywgJ0EnLCAnVCcsICdBJywgJ0InLCAnTCcsICdLJywgNDIgfTsKKyAgZmluYWwgc3RhdGljIGJ5dGUgW10gSU5ERVhCTE9DS01BR0lDID0KKyAgICB7ICdJJywgJ0QnLCAnWCcsICdCJywgJ0wnLCAnSycsIDQxLCA0MyB9OworICBmaW5hbCBzdGF0aWMgYnl0ZSBbXSBNRVRBQkxPQ0tNQUdJQyA9CisgICAgeyAnTScsICdFJywgJ1QnLCAnQScsICdCJywgJ0wnLCAnSycsIDk5IH07CisgIGZpbmFsIHN0YXRpYyBieXRlIFtdIFRSQUlMRVJCTE9DS01BR0lDID0gCisgICAgeyAnVCcsICdSJywgJ0EnLCAnQicsICdMJywgJ0snLCAzNCwgMzYgfTsKKworICAvKioKKyAgICogTWF4aW11bSBsZW5ndGggb2Yga2V5IGluIEhGaWxlLgorICAgKi8KKyAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgTUFYSU1VTV9LRVlfTEVOR1RIID0gNjQgKiAxMDI0OworICAKKyAgLyoqCisgICAqIERlZmF1bHQgYmxvY2tzaXplIGZvciBoZmlsZS4KKyAgICovCisgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IERFRkFVTFRfQkxPQ0tTSVpFID0gNjQgKiAxMDI0OworCisgIC8qKgorICAgKiBEZWZhdWx0IGNvbXByZXNzaW9uOiBub25lLgorICAgKi8KKyAgcHVibGljIGZpbmFsIHN0YXRpYyBDb21wcmVzc2lvbi5BbGdvcml0aG0gREVGQVVMVF9DT01QUkVTU0lPTl9BTEdPUklUSE0gPQorICAgIENvbXByZXNzaW9uLkFsZ29yaXRobS5OT05FOworICAvKiogRGVmYXVsdCBjb21wcmVzc2lvbiBuYW1lOiBub25lLiAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBERUZBVUxUX0NPTVBSRVNTSU9OID0KKyAgICBERUZBVUxUX0NPTVBSRVNTSU9OX0FMR09SSVRITS5nZXROYW1lKCk7CisKKyAgLyoqCisgICAqIEhGaWxlIFdyaXRlci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgV3JpdGVyIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICAvLyBGaWxlU3lzdGVtIHN0cmVhbSB0byB3cml0ZSBvbi4KKyAgICBwcml2YXRlIEZTRGF0YU91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW07CisgICAgLy8gVHJ1ZSBpZiB3ZSBvcGVuZWQgdGhlIDxjb2RlPm91dHB1dFN0cmVhbTwvY29kZT4gKGFuZCBzbyB3aWxsIGNsb3NlIGl0KS4KKyAgICBwcml2YXRlIGJvb2xlYW4gY2xvc2VPdXRwdXRTdHJlYW07CisKKyAgICAvLyBOYW1lIGZvciB0aGlzIG9iamVjdCB1c2VkIHdoZW4gbG9nZ2luZyBvciBpbiB0b1N0cmluZy4gIElzIGVpdGhlcgorICAgIC8vIHRoZSByZXN1bHQgb2YgYSB0b1N0cmluZyBvbiBzdHJlYW0gb3IgZWxzZSB0b1N0cmluZyBvZiBwYXNzZWQgZmlsZSBQYXRoLgorICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CisKKyAgICAvLyBUb3RhbCB1bmNvbXByZXNzZWQgYnl0ZXMsIG1heWJlIGNhbGN1bGF0ZSBhIGNvbXByZXNzaW9uIHJhdGlvIGxhdGVyLgorICAgIHByaXZhdGUgaW50IHRvdGFsQnl0ZXMgPSAwOworCisgICAgLy8gVG90YWwgIyBvZiBrZXkvdmFsdWUgZW50cmllcywgaWU6IGhvdyBtYW55IHRpbWVzIGFkZCgpIHdhcyBjYWxsZWQuCisgICAgcHJpdmF0ZSBpbnQgZW50cnlDb3VudCA9IDA7CisKKyAgICAvLyBVc2VkIGNhbGN1bGF0aW5nIGF2ZXJhZ2Uga2V5IGFuZCB2YWx1ZSBsZW5ndGhzLgorICAgIHByaXZhdGUgbG9uZyBrZXlsZW5ndGggPSAwOworICAgIHByaXZhdGUgbG9uZyB2YWx1ZWxlbmd0aCA9IDA7CisKKyAgICAvLyBVc2VkIHRvIGVuc3VyZSB3ZSB3cml0ZSBpbiBvcmRlci4KKyAgICBwcml2YXRlIGZpbmFsIFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT4gY29tcGFyYXRvcjsKKworICAgIC8vIEEgc3RyZWFtIG1hZGUgcGVyIGJsb2NrIHdyaXR0ZW4uCisgICAgcHJpdmF0ZSBEYXRhT3V0cHV0U3RyZWFtIG91dDsKKworICAgIC8vIE51bWJlciBvZiB1bmNvbXByZXNzZWQgYnl0ZXMgcGVyIGJsb2NrLiAgUmVpbml0aWFsaXplZCB3aGVuIHdlIHN0YXJ0CisgICAgLy8gbmV3IGJsb2NrLgorICAgIHByaXZhdGUgaW50IGJsb2Nrc2l6ZTsKKworICAgIC8vIE9mZnNldCB3aGVyZSB0aGUgY3VycmVudCBibG9jayBiZWdhbi4KKyAgICBwcml2YXRlIGxvbmcgYmxvY2tCZWdpbjsKKworICAgIC8vIEZpcnN0IGtleSBpbiBhIGJsb2NrIChOb3QgZmlyc3Qga2V5IGluIGZpbGUpLgorICAgIHByaXZhdGUgYnl0ZSBbXSBmaXJzdEtleSA9IG51bGw7CisKKyAgICAvLyBLZXkgcHJldmlvdXNseSBhcHBlbmRlZC4gIEJlY29tZXMgdGhlIGxhc3Qga2V5IGluIHRoZSBmaWxlLgorICAgIHByaXZhdGUgYnl0ZSBbXSBsYXN0S2V5QnVmZmVyID0gbnVsbDsKKyAgICBwcml2YXRlIGludCBsYXN0S2V5T2Zmc2V0ID0gLTE7CisgICAgcHJpdmF0ZSBpbnQgbGFzdEtleUxlbmd0aCA9IC0xOworCisgICAgLy8gU2VlIHtAbGluayBCbG9ja0luZGV4fS4gQmVsb3cgZm91ciBmaWVsZHMgYXJlIHVzZWQgdG8gd3JpdGUgdGhlIGJsb2NrCisgICAgLy8gaW5kZXguCisgICAgQXJyYXlMaXN0PGJ5dGVbXT4gYmxvY2tLZXlzID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgLy8gQmxvY2sgb2Zmc2V0IGluIGJhY2tpbmcgc3RyZWFtLgorICAgIEFycmF5TGlzdDxMb25nPiBibG9ja09mZnNldHMgPSBuZXcgQXJyYXlMaXN0PExvbmc+KCk7CisgICAgLy8gUmF3IChkZWNvbXByZXNzZWQpIGRhdGEgc2l6ZS4KKyAgICBBcnJheUxpc3Q8SW50ZWdlcj4gYmxvY2tEYXRhU2l6ZXMgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CisKKyAgICAvLyBNZXRhIGJsb2NrIHN5c3RlbS4KKyAgICBwcml2YXRlIEFycmF5TGlzdDxieXRlIFtdPiBtZXRhTmFtZXMgPSBuZXcgQXJyYXlMaXN0PGJ5dGUgW10+KCk7CisgICAgcHJpdmF0ZSBBcnJheUxpc3Q8Ynl0ZSBbXT4gbWV0YURhdGEgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oKTsKKworICAgIC8vIFVzZWQgY29tcHJlc3Npb24uICBVc2VkIGV2ZW4gaWYgbm8gY29tcHJlc3Npb24gLS0gJ25vbmUnLgorICAgIHByaXZhdGUgZmluYWwgQ29tcHJlc3Npb24uQWxnb3JpdGhtIGNvbXByZXNzQWxnbzsKKyAgICBwcml2YXRlIENvbXByZXNzb3IgY29tcHJlc3NvcjsKKworICAgIC8vIFNwZWNpYWwgZGF0YXN0cnVjdHVyZSB0byBob2xkIGZpbGVpbmZvLgorICAgIHByaXZhdGUgRmlsZUluZm8gZmlsZWluZm8gPSBuZXcgRmlsZUluZm8oKTsKKworICAgIC8vIE1heSBiZSBudWxsIGlmIHdlIHdlcmUgcGFzc2VkIGEgc3RyZWFtLgorICAgIHByaXZhdGUgUGF0aCBwYXRoID0gbnVsbDsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdXNlcyBhbGwgZGVmYXVsdHMgZm9yIGNvbXByZXNzaW9uIGFuZCBibG9jayBzaXplLgorICAgICAqIEBwYXJhbSBmcworICAgICAqIEBwYXJhbSBwYXRoCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyBXcml0ZXIoRmlsZVN5c3RlbSBmcywgUGF0aCBwYXRoKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKGZzLCBwYXRoLCBERUZBVUxUX0JMT0NLU0laRSwgbnVsbCwgbnVsbCwgZmFsc2UpOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYSBQYXRoLgorICAgICAqIEBwYXJhbSBmcworICAgICAqIEBwYXJhbSBwYXRoCisgICAgICogQHBhcmFtIGJsb2Nrc2l6ZQorICAgICAqIEBwYXJhbSBjb21wcmVzcworICAgICAqIEBwYXJhbSBjb21wYXJhdG9yCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFdyaXRlcihGaWxlU3lzdGVtIGZzLCBQYXRoIHBhdGgsIGludCBibG9ja3NpemUsCisgICAgICBTdHJpbmcgY29tcHJlc3MsIGZpbmFsIFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT4gY29tcGFyYXRvcikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhmcywgcGF0aCwgYmxvY2tzaXplLAorICAgICAgICBjb21wcmVzcyA9PSBudWxsPyBERUZBVUxUX0NPTVBSRVNTSU9OX0FMR09SSVRITToKKyAgICAgICAgICBDb21wcmVzc2lvbi5nZXRDb21wcmVzc2lvbkFsZ29yaXRobUJ5TmFtZShjb21wcmVzcyksCisgICAgICAgIGNvbXBhcmF0b3IsIGZhbHNlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgUGF0aC4KKyAgICAgKiBAcGFyYW0gZnMKKyAgICAgKiBAcGFyYW0gcGF0aAorICAgICAqIEBwYXJhbSBibG9ja3NpemUKKyAgICAgKiBAcGFyYW0gY29tcHJlc3MKKyAgICAgKiBAcGFyYW0gY29tcGFyYXRvcgorICAgICAqIEBwYXJhbSBibG9vbWZpbHRlcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKEZpbGVTeXN0ZW0gZnMsIFBhdGggcGF0aCwgaW50IGJsb2Nrc2l6ZSwKKyAgICAgIENvbXByZXNzaW9uLkFsZ29yaXRobSBjb21wcmVzcywKKyAgICAgIGZpbmFsIFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT4gY29tcGFyYXRvciwKKyAgICAgIGZpbmFsIGJvb2xlYW4gYmxvb21maWx0ZXIpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMoZnMuY3JlYXRlKHBhdGgpLCBibG9ja3NpemUsIGNvbXByZXNzLCBjb21wYXJhdG9yLCBibG9vbWZpbHRlcik7CisgICAgICB0aGlzLmNsb3NlT3V0cHV0U3RyZWFtID0gdHJ1ZTsKKyAgICAgIHRoaXMubmFtZSA9IHBhdGgudG9TdHJpbmcoKTsKKyAgICAgIHRoaXMucGF0aCA9IHBhdGg7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb3N0cmVhbSBTdHJlYW0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBibG9ja3NpemUKKyAgICAgKiBAcGFyYW0gY29tcHJlc3MKKyAgICAgKiBAcGFyYW0gYyBSYXdDb21wYXJhdG9yIHRvIHVzZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFdyaXRlcihmaW5hbCBGU0RhdGFPdXRwdXRTdHJlYW0gb3N0cmVhbSwgZmluYWwgaW50IGJsb2Nrc2l6ZSwKKyAgICAgICAgZmluYWwgU3RyaW5nICBjb21wcmVzcywgZmluYWwgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBjKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKG9zdHJlYW0sIGJsb2Nrc2l6ZSwKKyAgICAgICAgY29tcHJlc3MgPT0gbnVsbD8gREVGQVVMVF9DT01QUkVTU0lPTl9BTEdPUklUSE06CisgICAgICAgICAgQ29tcHJlc3Npb24uZ2V0Q29tcHJlc3Npb25BbGdvcml0aG1CeU5hbWUoY29tcHJlc3MpLCBjLCBmYWxzZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IgdGhhdCB0YWtlcyBhIHN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb3N0cmVhbSBTdHJlYW0gdG8gdXNlLgorICAgICAqIEBwYXJhbSBibG9ja3NpemUKKyAgICAgKiBAcGFyYW0gY29tcHJlc3MKKyAgICAgKiBAcGFyYW0gYworICAgICAqIEBwYXJhbSBibG9vbWZpbHRlcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgV3JpdGVyKGZpbmFsIEZTRGF0YU91dHB1dFN0cmVhbSBvc3RyZWFtLCBmaW5hbCBpbnQgYmxvY2tzaXplLAorICAgICAgICBmaW5hbCBDb21wcmVzc2lvbi5BbGdvcml0aG0gIGNvbXByZXNzLAorICAgICAgICBmaW5hbCBSYXdDb21wYXJhdG9yPGJ5dGUgW10+IGMsCisgICAgICAgIGZpbmFsIGJvb2xlYW4gYmxvb21maWx0ZXIpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMub3V0cHV0U3RyZWFtID0gb3N0cmVhbTsKKyAgICAgIHRoaXMuY2xvc2VPdXRwdXRTdHJlYW0gPSBmYWxzZTsKKyAgICAgIHRoaXMuYmxvY2tzaXplID0gYmxvY2tzaXplOworICAgICAgdGhpcy5jb21wYXJhdG9yID0gYyA9PSBudWxsPyBCeXRlcy5CWVRFU19SQVdDT01QQVJBVE9SOiBjOworICAgICAgdGhpcy5uYW1lID0gdGhpcy5vdXRwdXRTdHJlYW0udG9TdHJpbmcoKTsKKyAgICAgIHRoaXMuY29tcHJlc3NBbGdvID0gY29tcHJlc3MgPT0gbnVsbD8KKyAgICAgICAgREVGQVVMVF9DT01QUkVTU0lPTl9BTEdPUklUSE06IGNvbXByZXNzOworICAgIH0KKworICAgIC8qCisgICAgICogSWYgYXQgYmxvY2sgYm91bmRhcnksIG9wZW5zIG5ldyBibG9jay4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQmxvY2tCb3VuZGFyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodGhpcy5vdXQgIT0gbnVsbCAmJiB0aGlzLm91dC5zaXplKCkgPCBibG9ja3NpemUpIHJldHVybjsKKyAgICAgIGZpbmlzaEJsb2NrKCk7CisgICAgICBuZXdCbG9jaygpOworICAgIH0KKworICAgIC8qCisgICAgICogRG8gdGhlIGNsZWFudXAgaWYgYSBjdXJyZW50IGJsb2NrLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgZmluaXNoQmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHRoaXMub3V0ID09IG51bGwpIHJldHVybjsKKyAgICAgIGxvbmcgc2l6ZSA9IHJlbGVhc2VDb21wcmVzc2luZ1N0cmVhbSh0aGlzLm91dCk7CisgICAgICB0aGlzLm91dCA9IG51bGw7CisgICAgICBibG9ja0tleXMuYWRkKGZpcnN0S2V5KTsKKyAgICAgIGludCB3cml0dGVuID0gbG9uZ1RvSW50KHNpemUpOworICAgICAgYmxvY2tPZmZzZXRzLmFkZChMb25nLnZhbHVlT2YoYmxvY2tCZWdpbikpOworICAgICAgYmxvY2tEYXRhU2l6ZXMuYWRkKEludGVnZXIudmFsdWVPZih3cml0dGVuKSk7CisgICAgICB0aGlzLnRvdGFsQnl0ZXMgKz0gd3JpdHRlbjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlYWR5IGEgbmV3IGJsb2NrIGZvciB3cml0aW5nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbmV3QmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gVGhpcyBpcyB3aGVyZSB0aGUgbmV4dCBibG9jayBiZWdpbnMuCisgICAgICBibG9ja0JlZ2luID0gb3V0cHV0U3RyZWFtLmdldFBvcygpOworICAgICAgdGhpcy5vdXQgPSBnZXRDb21wcmVzc2luZ1N0cmVhbSgpOworICAgICAgdGhpcy5vdXQud3JpdGUoREFUQUJMT0NLTUFHSUMpOworICAgICAgZmlyc3RLZXkgPSBudWxsOworICAgIH0KKworICAgIC8qCisgICAgICogU2V0cyB1cCBhIGNvbXByZXNzb3IgYW5kIGNyZWF0ZXMgYSBjb21wcmVzc2lvbiBzdHJlYW0gb24gdG9wIG9mCisgICAgICogdGhpcy5vdXRwdXRTdHJlYW0uICBHZXQgb25lIHBlciBibG9jayB3cml0dGVuLgorICAgICAqIEByZXR1cm4gQSBjb21wcmVzc2luZyBzdHJlYW07IGlmICdub25lJyBjb21wcmVzc2lvbiwgcmV0dXJuZWQgc3RyZWFtCisgICAgICogZG9lcyBub3QgY29tcHJlc3MuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUge0BsaW5rICNyZWxlYXNlQ29tcHJlc3NpbmdTdHJlYW0oRGF0YU91dHB1dFN0cmVhbSl9CisgICAgICovCisgICAgcHJpdmF0ZSBEYXRhT3V0cHV0U3RyZWFtIGdldENvbXByZXNzaW5nU3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMuY29tcHJlc3NvciA9IGNvbXByZXNzQWxnby5nZXRDb21wcmVzc29yKCk7CisgICAgICAvLyBHZXQgbmV3IERPUyBjb21wcmVzc2lvbiBzdHJlYW0uICBJbiB0ZmlsZSwgdGhlIERPUywgaXMgbm90IGNsb3NlZCwKKyAgICAgIC8vIGp1c3QgZmluaXNoZWQsIGFuZCB0aGF0IHNlZW1zIHRvIGJlIGZpbmUgb3ZlciB0aGVyZS4gIFRPRE86IENoZWNrCisgICAgICAvLyBubyBtZW1vcnkgcmV0ZW50aW9uIG9mIHRoZSBET1MuICBTaG91bGQgSSBkaXNhYmxlIHRoZSAnZmx1c2gnIG9uIHRoZQorICAgICAgLy8gRE9TIGFzIHRoZSBCQ0ZpbGUgb3ZlciBpbiB0ZmlsZSBkb2VzPyAgSXQgd2FudHMgdG8gbWFrZSBpdCBzbyBmbHVzaGVzCisgICAgICAvLyBkb24ndCBnbyB0aHJvdWdoIHRvIHRoZSB1bmRlcmx5aW5nIGNvbXByZXNzZWQgc3RyZWFtLiAgRmx1c2ggb24gdGhlCisgICAgICAvLyBjb21wcmVzc2VkIGRvd25zdHJlYW0gc2hvdWxkIGJlIG9ubHkgd2hlbiBkb25lLiAgSSB3YXMgZ29pbmcgdG8gYnV0CisgICAgICAvLyBsb29rcyBsaWtlIHdoZW4gd2UgY2FsbCBmbHVzaCBpbiBoZXJlLCBpdHMgbGVnaXRpbWF0ZSBmbHVzaCB0aGF0CisgICAgICAvLyBzaG91bGQgZ28gdGhyb3VnaCB0byB0aGUgY29tcHJlc3Nvci4KKyAgICAgIE91dHB1dFN0cmVhbSBvcyA9CisgICAgICAgIHRoaXMuY29tcHJlc3NBbGdvLmNyZWF0ZUNvbXByZXNzaW9uU3RyZWFtKHRoaXMub3V0cHV0U3RyZWFtLAorICAgICAgICB0aGlzLmNvbXByZXNzb3IsIDApOworICAgICAgcmV0dXJuIG5ldyBEYXRhT3V0cHV0U3RyZWFtKG9zKTsKKyAgICB9CisgICAgCisgICAgLyoKKyAgICAgKiBMZXQgZ28gb2YgYmxvY2sgY29tcHJlc3NvciBhbmQgY29tcHJlc3Npbmcgc3RyZWFtIGdvdHRlbiBpbiBjYWxsCisgICAgICoge0BsaW5rICNnZXRDb21wcmVzc2luZ1N0cmVhbX0uCisgICAgICogQHBhcmFtIGRvcworICAgICAqIEByZXR1cm4gSG93IG11Y2ggd2FzIHdyaXR0ZW4gb24gdGhpcyBzdHJlYW0gc2luY2UgaXQgd2FzIHRha2VuIG91dC4KKyAgICAgKiBAc2VlICNnZXRDb21wcmVzc2luZ1N0cmVhbSgpIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIGludCByZWxlYXNlQ29tcHJlc3NpbmdTdHJlYW0oZmluYWwgRGF0YU91dHB1dFN0cmVhbSBkb3MpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGRvcy5mbHVzaCgpOworICAgICAgdGhpcy5jb21wcmVzc0FsZ28ucmV0dXJuQ29tcHJlc3Nvcih0aGlzLmNvbXByZXNzb3IpOworICAgICAgdGhpcy5jb21wcmVzc29yID0gbnVsbDsKKyAgICAgIHJldHVybiBkb3Muc2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhIG1ldGEgYmxvY2sgdG8gdGhlIGVuZCBvZiB0aGUgZmlsZS4gQ2FsbCBiZWZvcmUgY2xvc2UoKS4KKyAgICAgKiBNZXRhZGF0YSBibG9ja3MgYXJlIGV4cGVuc2l2ZS4gIEZpbGwgb25lIHdpdGggYSBidW5jaCBvZiBzZXJpYWxpemVkIGRhdGEKKyAgICAgKiByYXRoZXIgdGhhbiBkbyBhIG1ldGFkYXRhIGJsb2NrIHBlciBtZXRhZGF0YSBpbnN0YW5jZS4gIElmIG1ldGFkYXRhIGlzCisgICAgICogc21hbGwsIGNvbnNpZGVyIGFkZGluZyB0byBmaWxlIGluZm8gdXNpbmcKKyAgICAgKiB7QGxpbmsgI2FwcGVuZEZpbGVJbmZvKGJ5dGVbXSwgYnl0ZVtdKX0KKyAgICAgKiBAcGFyYW0gbWV0YUJsb2NrTmFtZSBuYW1lIG9mIHRoZSBibG9jaworICAgICAqIEBwYXJhbSBieXRlcyB1bmludGVycHJldGVkIGJ5dGVzIG9mIHRoZSBibG9jay4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRNZXRhQmxvY2soU3RyaW5nIG1ldGFCbG9ja05hbWUsIGJ5dGUgW10gYnl0ZXMpIHsKKyAgICAgIG1ldGFOYW1lcy5hZGQoQnl0ZXMudG9CeXRlcyhtZXRhQmxvY2tOYW1lKSk7CisgICAgICBtZXRhRGF0YS5hZGQoYnl0ZXMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCB0byB0aGUgZmlsZSBpbmZvLiAgQWRkZWQga2V5IHZhbHVlIGNhbiBiZSBnb3R0ZW4gb3V0IG9mIHRoZSByZXR1cm4KKyAgICAgKiBmcm9tIHtAbGluayBSZWFkZXIjbG9hZEZpbGVJbmZvKCl9LgorICAgICAqIEBwYXJhbSBrIEtleQorICAgICAqIEBwYXJhbSB2IFZhbHVlCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBlbmRGaWxlSW5mbyhmaW5hbCBieXRlIFtdIGssIGZpbmFsIGJ5dGUgW10gdikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYXBwZW5kRmlsZUluZm8odGhpcy5maWxlaW5mbywgaywgdiwgdHJ1ZSk7CisgICAgfQorCisgICAgRmlsZUluZm8gYXBwZW5kRmlsZUluZm8oRmlsZUluZm8gZmksIGZpbmFsIGJ5dGUgW10gaywgZmluYWwgYnl0ZSBbXSB2LAorICAgICAgZmluYWwgYm9vbGVhbiBjaGVja1ByZWZpeCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGsgPT0gbnVsbCB8fCB2ID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJLZXkgbm9yIHZhbHVlIG1heSBiZSBudWxsIik7CisgICAgICB9CisgICAgICBpZiAoY2hlY2tQcmVmaXggJiYKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyhrKS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoRmlsZUluZm8uUkVTRVJWRURfUFJFRklYKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIktleXMgd2l0aCBhICIgKyBGaWxlSW5mby5SRVNFUlZFRF9QUkVGSVggKworICAgICAgICAgICIgYXJlIHJlc2VydmVkIik7CisgICAgICB9CisgICAgICBmaS5wdXQoaywgdik7CisgICAgICByZXR1cm4gZmk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBQYXRoIG9yIG51bGwgaWYgd2Ugd2VyZSBwYXNzZWQgYSBzdHJlYW0gcmF0aGVyIHRoYW4gYSBQYXRoLgorICAgICAqLworICAgIHB1YmxpYyBQYXRoIGdldFBhdGgoKSB7CisgICAgICByZXR1cm4gdGhpcy5wYXRoOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gIndyaXRlcj0iICsgdGhpcy5uYW1lICsgIiwgY29tcHJlc3Npb249IiArCisgICAgICAgIHRoaXMuY29tcHJlc3NBbGdvLmdldE5hbWUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQga2V5L3ZhbHVlIHRvIGZpbGUuCisgICAgICogS2V5cyBtdXN0IGJlIGFkZGVkIGluIGFuIG9yZGVyIHRoYXQgYWdyZWVzIHdpdGggdGhlIENvbXBhcmF0b3IgcGFzc2VkCisgICAgICogb24gY29uc3RydWN0aW9uLgorICAgICAqIEBwYXJhbSBrdiBLZXlWYWx1ZSB0byBhZGQuICBDYW5ub3QgYmUgZW1wdHkgbm9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZChmaW5hbCBLZXlWYWx1ZSBrdikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYXBwZW5kKGt2LmdldEJ1ZmZlcigpLCBrdi5nZXRLZXlPZmZzZXQoKSwga3YuZ2V0S2V5TGVuZ3RoKCksCisgICAgICAgIGt2LmdldEJ1ZmZlcigpLCBrdi5nZXRWYWx1ZU9mZnNldCgpLCBrdi5nZXRWYWx1ZUxlbmd0aCgpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQga2V5L3ZhbHVlIHRvIGZpbGUuCisgICAgICogS2V5cyBtdXN0IGJlIGFkZGVkIGluIGFuIG9yZGVyIHRoYXQgYWdyZWVzIHdpdGggdGhlIENvbXBhcmF0b3IgcGFzc2VkCisgICAgICogb24gY29uc3RydWN0aW9uLgorICAgICAqIEBwYXJhbSBrZXkgS2V5IHRvIGFkZC4gIENhbm5vdCBiZSBlbXB0eSBub3IgbnVsbC4KKyAgICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gYWRkLiAgQ2Fubm90IGJlIGVtcHR5IG5vciBudWxsLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhcHBlbmQoZmluYWwgYnl0ZSBbXSBrZXksIGZpbmFsIGJ5dGUgW10gdmFsdWUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGFwcGVuZChrZXksIDAsIGtleS5sZW5ndGgsIHZhbHVlLCAwLCB2YWx1ZS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBrZXkvdmFsdWUgdG8gZmlsZS4KKyAgICAgKiBLZXlzIG11c3QgYmUgYWRkZWQgaW4gYW4gb3JkZXIgdGhhdCBhZ3JlZXMgd2l0aCB0aGUgQ29tcGFyYXRvciBwYXNzZWQKKyAgICAgKiBvbiBjb25zdHJ1Y3Rpb24uCisgICAgICogQHBhcmFtIGtleSBLZXkgdG8gYWRkLiAgQ2Fubm90IGJlIGVtcHR5IG5vciBudWxsLgorICAgICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSB0byBhZGQuICBDYW5ub3QgYmUgZW1wdHkgbm9yIG51bGwuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFwcGVuZChmaW5hbCBieXRlIFtdIGtleSwgZmluYWwgaW50IGtvZmZzZXQsIGZpbmFsIGludCBrbGVuZ3RoLAorICAgICAgICBmaW5hbCBieXRlIFtdIHZhbHVlLCBmaW5hbCBpbnQgdm9mZnNldCwgZmluYWwgaW50IHZsZW5ndGgpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGNoZWNrS2V5KGtleSwga29mZnNldCwga2xlbmd0aCk7CisgICAgICBjaGVja1ZhbHVlKHZhbHVlLCB2b2Zmc2V0LCB2bGVuZ3RoKTsKKyAgICAgIGNoZWNrQmxvY2tCb3VuZGFyeSgpOworICAgICAgLy8gV3JpdGUgbGVuZ3RoIG9mIGtleSBhbmQgdmFsdWUgYW5kIHRoZW4gYWN0dWFsIGtleSBhbmQgdmFsdWUgYnl0ZXMuCisgICAgICB0aGlzLm91dC53cml0ZUludChrbGVuZ3RoKTsKKyAgICAgIHRoaXMua2V5bGVuZ3RoICs9IGtsZW5ndGg7CisgICAgICB0aGlzLm91dC53cml0ZUludCh2bGVuZ3RoKTsKKyAgICAgIHRoaXMudmFsdWVsZW5ndGggKz0gdmxlbmd0aDsKKyAgICAgIHRoaXMub3V0LndyaXRlKGtleSwga29mZnNldCwga2xlbmd0aCk7CisgICAgICB0aGlzLm91dC53cml0ZSh2YWx1ZSwgdm9mZnNldCwgdmxlbmd0aCk7CisgICAgICAvLyBBcmUgd2UgdGhlIGZpcnN0IGtleSBpbiB0aGlzIGJsb2NrPworICAgICAgaWYgKHRoaXMuZmlyc3RLZXkgPT0gbnVsbCkgeworICAgICAgICAvLyBDb3B5IHRoZSBrZXkuCisgICAgICAgIHRoaXMuZmlyc3RLZXkgPSBuZXcgYnl0ZSBba2xlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoa2V5LCBrb2Zmc2V0LCB0aGlzLmZpcnN0S2V5LCAwLCBrbGVuZ3RoKTsKKyAgICAgIH0KKyAgICAgIHRoaXMubGFzdEtleUJ1ZmZlciA9IGtleTsKKyAgICAgIHRoaXMubGFzdEtleU9mZnNldCA9IGtvZmZzZXQ7CisgICAgICB0aGlzLmxhc3RLZXlMZW5ndGggPSBrbGVuZ3RoOworICAgICAgdGhpcy5lbnRyeUNvdW50ICsrOworICAgIH0KKworICAgIC8qCisgICAgICogQHBhcmFtIGtleSBLZXkgdG8gY2hlY2suCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBjaGVja0tleShmaW5hbCBieXRlIFtdIGtleSwgZmluYWwgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGtleSA9PSBudWxsIHx8IGxlbmd0aCA8PSAwKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiS2V5IGNhbm5vdCBiZSBudWxsIG9yIGVtcHR5Iik7CisgICAgICB9CisgICAgICBpZiAobGVuZ3RoID4gTUFYSU1VTV9LRVlfTEVOR1RIKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiS2V5IGxlbmd0aCAiICsgbGVuZ3RoICsgIiA+ICIgKworICAgICAgICAgIE1BWElNVU1fS0VZX0xFTkdUSCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5sYXN0S2V5QnVmZmVyICE9IG51bGwpIHsKKyAgICAgICAgaWYgKHRoaXMuY29tcGFyYXRvci5jb21wYXJlKHRoaXMubGFzdEtleUJ1ZmZlciwgdGhpcy5sYXN0S2V5T2Zmc2V0LAorICAgICAgICAgICAgdGhpcy5sYXN0S2V5TGVuZ3RoLCBrZXksIG9mZnNldCwgbGVuZ3RoKSA+IDApIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkFkZGVkIGEga2V5IG5vdCBsZXhpY2FsbHkgbGFyZ2VyIHRoYW4iICsKKyAgICAgICAgICAgICIgcHJldmlvdXMga2V5PSIgKyBCeXRlcy50b1N0cmluZyhrZXksIG9mZnNldCwgbGVuZ3RoKSArCisgICAgICAgICAgICAiLCBsYXN0a2V5PSIgKyBCeXRlcy50b1N0cmluZyh0aGlzLmxhc3RLZXlCdWZmZXIsIHRoaXMubGFzdEtleU9mZnNldCwKKyAgICAgICAgICAgICAgICB0aGlzLmxhc3RLZXlMZW5ndGgpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1ZhbHVlKGZpbmFsIGJ5dGUgW10gdmFsdWUsCisgICAgICAgIGZpbmFsIGludCBvZmZzZXQsCisgICAgICAgIGZpbmFsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlZhbHVlIGNhbm5vdCBiZSBudWxsIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHRoaXMub3V0cHV0U3RyZWFtID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgLy8gV3JpdGUgb3V0IHRoZSBlbmQgb2YgdGhlIGRhdGEgYmxvY2tzLCB0aGVuIHdyaXRlIG1ldGEgZGF0YSBibG9ja3MuCisgICAgICAvLyBmb2xsb3dlZCBieSBmaWxlaW5mbywgZGF0YSBibG9jayBpbmRleCBhbmQgbWV0YSBibG9jayBpbmRleC4KKworICAgICAgZmluaXNoQmxvY2soKTsKKworICAgICAgRml4ZWRGaWxlVHJhaWxlciB0cmFpbGVyID0gbmV3IEZpeGVkRmlsZVRyYWlsZXIoKTsKKyAgICAgIAorICAgICAgLy8gV3JpdGUgb3V0IHRoZSBtZXRhZGF0YSBibG9ja3MgaWYgYW55LgorICAgICAgQXJyYXlMaXN0PExvbmc+IG1ldGFPZmZzZXRzID0gbnVsbDsKKyAgICAgIEFycmF5TGlzdDxJbnRlZ2VyPiBtZXRhRGF0YVNpemVzID0gbnVsbDsKKyAgICAgIGlmIChtZXRhTmFtZXMuc2l6ZSgpID4gMCkgeworICAgICAgICBtZXRhT2Zmc2V0cyA9IG5ldyBBcnJheUxpc3Q8TG9uZz4obWV0YU5hbWVzLnNpemUoKSk7CisgICAgICAgIG1ldGFEYXRhU2l6ZXMgPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KG1ldGFOYW1lcy5zaXplKCkpOworICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBtZXRhTmFtZXMuc2l6ZSgpIDsgKysgaSApIHsKKyAgICAgICAgICBtZXRhT2Zmc2V0cy5hZGQoTG9uZy52YWx1ZU9mKG91dHB1dFN0cmVhbS5nZXRQb3MoKSkpOworICAgICAgICAgIG1ldGFEYXRhU2l6ZXMuCisgICAgICAgICAgICBhZGQoSW50ZWdlci52YWx1ZU9mKE1FVEFCTE9DS01BR0lDLmxlbmd0aCArIG1ldGFEYXRhLmdldChpKS5sZW5ndGgpKTsKKyAgICAgICAgICB3cml0ZU1ldGFCbG9jayhtZXRhRGF0YS5nZXQoaSkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIFdyaXRlIGZpbGVpbmZvLgorICAgICAgdHJhaWxlci5maWxlaW5mb09mZnNldCA9IHdyaXRlRmlsZUluZm8odGhpcy5vdXRwdXRTdHJlYW0pOworCisgICAgICAvLyBXcml0ZSB0aGUgZGF0YSBibG9jayBpbmRleC4KKyAgICAgIHRyYWlsZXIuZGF0YUluZGV4T2Zmc2V0ID0gQmxvY2tJbmRleC53cml0ZUluZGV4KHRoaXMub3V0cHV0U3RyZWFtLAorICAgICAgICB0aGlzLmJsb2NrS2V5cywgdGhpcy5ibG9ja09mZnNldHMsIHRoaXMuYmxvY2tEYXRhU2l6ZXMpOworCisgICAgICAvLyBNZXRhIGJsb2NrIGluZGV4LgorICAgICAgaWYgKG1ldGFOYW1lcy5zaXplKCkgPiAwKSB7CisgICAgICAgIHRyYWlsZXIubWV0YUluZGV4T2Zmc2V0ID0gQmxvY2tJbmRleC53cml0ZUluZGV4KHRoaXMub3V0cHV0U3RyZWFtLAorICAgICAgICAgIHRoaXMubWV0YU5hbWVzLCBtZXRhT2Zmc2V0cywgbWV0YURhdGFTaXplcyk7CisgICAgICB9CisKKyAgICAgIC8vIE5vdyBmaW5pc2ggb2ZmIHRoZSB0cmFpbGVyLgorICAgICAgdHJhaWxlci5kYXRhSW5kZXhDb3VudCA9IGJsb2NrS2V5cy5zaXplKCk7CisgICAgICB0cmFpbGVyLm1ldGFJbmRleENvdW50ID0gbWV0YU5hbWVzLnNpemUoKTsKKyAgICAgIAorICAgICAgdHJhaWxlci50b3RhbFVuY29tcHJlc3NlZEJ5dGVzID0gdG90YWxCeXRlczsKKyAgICAgIHRyYWlsZXIuZW50cnlDb3VudCA9IGVudHJ5Q291bnQ7CisgICAgICAKKyAgICAgIHRyYWlsZXIuY29tcHJlc3Npb25Db2RlYyA9IHRoaXMuY29tcHJlc3NBbGdvLm9yZGluYWwoKTsKKworICAgICAgdHJhaWxlci5zZXJpYWxpemUob3V0cHV0U3RyZWFtKTsKKworICAgICAgaWYgKHRoaXMuY2xvc2VPdXRwdXRTdHJlYW0pIHsKKyAgICAgICAgdGhpcy5vdXRwdXRTdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgdGhpcy5vdXRwdXRTdHJlYW0gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIC8qIFdyaXRlIGEgbWV0YWRhdGEgYmxvY2suCisgICAgICogQHBhcmFtIG1ldGFkYXRhCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgdm9pZCB3cml0ZU1ldGFCbG9jayhmaW5hbCBieXRlIFtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBEYXRhT3V0cHV0U3RyZWFtIGRvcyA9IGdldENvbXByZXNzaW5nU3RyZWFtKCk7CisgICAgICBkb3Mud3JpdGUoTUVUQUJMT0NLTUFHSUMpOworICAgICAgZG9zLndyaXRlKGIpOworICAgICAgcmVsZWFzZUNvbXByZXNzaW5nU3RyZWFtKGRvcyk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBBZGQgbGFzdCBiaXRzIG9mIG1ldGFkYXRhIHRvIGZpbGVpbmZvIGFuZCB0aGVuIHdyaXRlIGl0IG91dC4KKyAgICAgKiBSZWFkZXIgd2lsbCBiZSBleHBlY3RpbmcgdG8gZmluZCBhbGwgYmVsb3cuCisgICAgICogQHBhcmFtIG8gU3RyZWFtIHRvIHdyaXRlIG9uLgorICAgICAqIEByZXR1cm4gUG9zaXRpb24gYXQgd2hpY2ggd2Ugc3RhcnRlZCB3cml0aW5nLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIGxvbmcgd3JpdGVGaWxlSW5mbyhGU0RhdGFPdXRwdXRTdHJlYW0gbykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0aGlzLmxhc3RLZXlCdWZmZXIgIT0gbnVsbCkgeworICAgICAgICAvLyBNYWtlIGEgY29weS4gIFRoZSBjb3B5IGlzIHN0dWZmZWQgaW50byBITWFwV3JpdGFibGUuICBOZWVkcyBhIGNsZWFuCisgICAgICAgIC8vIGJ5dGUgYnVmZmVyLiAgV29uJ3QgdGFrZSBhIHR1cGxlLgorICAgICAgICBieXRlIFtdIGIgPSBuZXcgYnl0ZVt0aGlzLmxhc3RLZXlMZW5ndGhdOworICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRoaXMubGFzdEtleUJ1ZmZlciwgdGhpcy5sYXN0S2V5T2Zmc2V0LCBiLCAwLAorICAgICAgICAgIHRoaXMubGFzdEtleUxlbmd0aCk7CisgICAgICAgIGFwcGVuZEZpbGVJbmZvKHRoaXMuZmlsZWluZm8sIEZpbGVJbmZvLkxBU1RLRVksIGIsIGZhbHNlKTsKKyAgICAgIH0KKyAgICAgIGludCBhdmdLZXlMZW4gPSB0aGlzLmVudHJ5Q291bnQgPT0gMD8gMDoKKyAgICAgICAgKGludCkodGhpcy5rZXlsZW5ndGgvdGhpcy5lbnRyeUNvdW50KTsKKyAgICAgIGFwcGVuZEZpbGVJbmZvKHRoaXMuZmlsZWluZm8sIEZpbGVJbmZvLkFWR19LRVlfTEVOLAorICAgICAgICBCeXRlcy50b0J5dGVzKGF2Z0tleUxlbiksIGZhbHNlKTsKKyAgICAgIGludCBhdmdWYWx1ZUxlbiA9IHRoaXMuZW50cnlDb3VudCA9PSAwPyAwOgorICAgICAgICAoaW50KSh0aGlzLmtleWxlbmd0aC90aGlzLmVudHJ5Q291bnQpOworICAgICAgYXBwZW5kRmlsZUluZm8odGhpcy5maWxlaW5mbywgRmlsZUluZm8uQVZHX1ZBTFVFX0xFTiwKKyAgICAgICAgQnl0ZXMudG9CeXRlcyhhdmdWYWx1ZUxlbiksIGZhbHNlKTsKKyAgICAgIGFwcGVuZEZpbGVJbmZvKHRoaXMuZmlsZWluZm8sIEZpbGVJbmZvLkNPTVBBUkFUT1IsCisgICAgICAgIEJ5dGVzLnRvQnl0ZXModGhpcy5jb21wYXJhdG9yLmdldENsYXNzKCkuZ2V0TmFtZSgpKSwgZmFsc2UpOworICAgICAgbG9uZyBwb3MgPSBvLmdldFBvcygpOworICAgICAgdGhpcy5maWxlaW5mby53cml0ZShvKTsKKyAgICAgIHJldHVybiBwb3M7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEhGaWxlIFJlYWRlci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUmVhZGVyIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICAvLyBTdHJlYW0gdG8gcmVhZCBmcm9tLgorICAgIHByaXZhdGUgRlNEYXRhSW5wdXRTdHJlYW0gaXN0cmVhbTsKKyAgICAvLyBUcnVlIGlmIHdlIHNob3VsZCBjbG9zZSBpc3RyZWFtIHdoZW4gZG9uZS4gIFdlIGRvbid0IGNsb3NlIGl0IGlmIHdlCisgICAgLy8gZGlkbid0IG9wZW4gaXQuCisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlSVN0cmVhbTsKKworICAgIC8vIFRoZXNlIGFyZSByZWFkIGluIHdoZW4gdGhlIGZpbGUgaW5mbyBpcyBsb2FkZWQuCisgICAgSEZpbGUuQmxvY2tJbmRleCBibG9ja0luZGV4OworICAgIHByaXZhdGUgQmxvY2tJbmRleCBtZXRhSW5kZXg7CisgICAgRml4ZWRGaWxlVHJhaWxlciB0cmFpbGVyOworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBmaWxlSW5mb0xvYWRlZCA9IGZhbHNlOworICAgIAorICAgIC8vIEZpbGxlZCB3aGVuIHdlIHJlYWQgaW4gdGhlIHRyYWlsZXIuCisgICAgcHJpdmF0ZSBDb21wcmVzc2lvbi5BbGdvcml0aG0gY29tcHJlc3NBbGdvOworCisgICAgLy8gTGFzdCBrZXkgaW4gdGhlIGZpbGUuICBGaWxsZWQgaW4gd2hlbiB3ZSByZWFkIGluIHRoZSBmaWxlIGluZm8KKyAgICBwcml2YXRlIGJ5dGUgW10gbGFzdGtleSA9IG51bGw7CisgICAgLy8gU3RhdHMgcmVhZCBpbiB3aGVuIHdlIGxvYWQgZmlsZSBpbmZvLgorICAgIHByaXZhdGUgaW50IGF2Z0tleUxlbiA9IC0xOworICAgIHByaXZhdGUgaW50IGF2Z1ZhbHVlTGVuID0gLTE7CisgICAgCisgICAgLy8gVXNlZCB0byBlbnN1cmUgd2Ugc2VlayBjb3JyZWN0bHkuCisgICAgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBjb21wYXJhdG9yOworCisgICAgLy8gU2l6ZSBvZiB0aGlzIGZpbGUuCisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIGZpbGVTaXplOworCisgICAgLy8gQmxvY2sgY2FjaGUgdG8gdXNlLgorICAgIHByaXZhdGUgZmluYWwgQmxvY2tDYWNoZSBjYWNoZTsKKyAgICBwdWJsaWMgaW50IGNhY2hlSGl0cyA9IDA7CisgICAgcHVibGljIGludCBibG9ja0xvYWRzID0gMDsKKworICAgIC8vIE5hbWUgZm9yIHRoaXMgb2JqZWN0IHVzZWQgd2hlbiBsb2dnaW5nIG9yIGluIHRvU3RyaW5nLiAgSXMgZWl0aGVyCisgICAgLy8gdGhlIHJlc3VsdCBvZiBhIHRvU3RyaW5nIG9uIHRoZSBzdHJlYW0gb3IgZWxzZSBpcyB0b1N0cmluZyBvZiBwYXNzZWQKKyAgICAvLyBmaWxlIFBhdGggcGx1cyBtZXRhZGF0YSBrZXkvdmFsdWUgcGFpcnMuCisgICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKKworICAgIC8qCisgICAgICogRG8gbm90IGV4cG9zZSB0aGUgZGVmYXVsdCBjb25zdHJ1Y3Rvci4KKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIFJlYWRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzKG51bGwsIG51bGwsIG51bGwpOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBPcGVucyBhIEhGaWxlLiAgWW91IG11c3QgbG9hZCB0aGUgZmlsZSBpbmZvIGJlZm9yZSB5b3UgY2FuIAorICAgICAqIHVzZSBpdCBieSBjYWxsaW5nIHtAbGluayAjbG9hZEZpbGVJbmZvKCl9LgorICAgICAqCisgICAgICogQHBhcmFtIGZzIGZpbGVzeXN0ZW0gdG8gbG9hZCBmcm9tCisgICAgICogQHBhcmFtIHBhdGggcGF0aCB3aXRoaW4gc2FpZCBmaWxlc3lzdGVtCisgICAgICogQHBhcmFtIGNhY2hlIGJsb2NrIGNhY2hlLiBQYXNzIG51bGwgaWYgbm9uZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJlYWRlcihGaWxlU3lzdGVtIGZzLCBQYXRoIHBhdGgsIEJsb2NrQ2FjaGUgY2FjaGUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMoZnMub3BlbihwYXRoKSwgZnMuZ2V0RmlsZVN0YXR1cyhwYXRoKS5nZXRMZW4oKSwgY2FjaGUpOworICAgICAgdGhpcy5jbG9zZUlTdHJlYW0gPSB0cnVlOworICAgICAgdGhpcy5uYW1lID0gcGF0aC50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKiAKKyAgICAgKiBPcGVucyBhIEhGaWxlLiAgWW91IG11c3QgbG9hZCB0aGUgaW5kZXggYmVmb3JlIHlvdSBjYW4gCisgICAgICogdXNlIGl0IGJ5IGNhbGxpbmcge0BsaW5rICNsb2FkRmlsZUluZm8oKX0uCisgICAgICoKKyAgICAgKiBAcGFyYW0gZnNkaXMgaW5wdXQgc3RyZWFtLiAgQ2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBjbG9zaW5nIHRoZSBwYXNzZWQKKyAgICAgKiBzdHJlYW0uCisgICAgICogQHBhcmFtIHNpemUgTGVuZ3RoIG9mIHRoZSBzdHJlYW0uCisgICAgICogQHBhcmFtIGNhY2hlIGJsb2NrIGNhY2hlLiBQYXNzIG51bGwgaWYgbm9uZS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFJlYWRlcihmaW5hbCBGU0RhdGFJbnB1dFN0cmVhbSBmc2RpcywgZmluYWwgbG9uZyBzaXplLAorICAgICAgICBmaW5hbCBCbG9ja0NhY2hlIGNhY2hlKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLmNhY2hlID0gY2FjaGU7CisgICAgICB0aGlzLmZpbGVTaXplID0gc2l6ZTsKKyAgICAgIHRoaXMuaXN0cmVhbSA9IGZzZGlzOworICAgICAgdGhpcy5jbG9zZUlTdHJlYW0gPSBmYWxzZTsKKyAgICAgIHRoaXMubmFtZSA9IHRoaXMuaXN0cmVhbS50b1N0cmluZygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gInJlYWRlcj0iICsgdGhpcy5uYW1lICsKKyAgICAgICAgICAoIWlzRmlsZUluZm9Mb2FkZWQoKT8gIiI6CisgICAgICAgICAgICAiLCBjb21wcmVzc2lvbj0iICsgdGhpcy5jb21wcmVzc0FsZ28uZ2V0TmFtZSgpICsKKyAgICAgICAgICAgICIsIGZpcnN0S2V5PSIgKyB0b1N0cmluZ0ZpcnN0S2V5KCkgKworICAgICAgICAgICAgIiwgbGFzdEtleT0iICsgdG9TdHJpbmdMYXN0S2V5KCkpICsKKyAgICAgICAgICAgICIsIGF2Z0tleUxlbj0iICsgdGhpcy5hdmdLZXlMZW4gKworICAgICAgICAgICAgIiwgYXZnVmFsdWVMZW49IiArIHRoaXMuYXZnVmFsdWVMZW4gKworICAgICAgICAgICAgIiwgZW50cmllcz0iICsgdGhpcy50cmFpbGVyLmVudHJ5Q291bnQgKworICAgICAgICAgICAgIiwgbGVuZ3RoPSIgKyB0aGlzLmZpbGVTaXplOworICAgIH0KKworICAgIHByb3RlY3RlZCBTdHJpbmcgdG9TdHJpbmdGaXJzdEtleSgpIHsKKyAgICAgIHJldHVybiBCeXRlcy50b1N0cmluZyhnZXRGaXJzdEtleSgpKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvU3RyaW5nTGFzdEtleSgpIHsKKyAgICAgIHJldHVybiBCeXRlcy50b1N0cmluZyhnZXRGaXJzdEtleSgpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBsZW5ndGgoKSB7CisgICAgICByZXR1cm4gdGhpcy5maWxlU2l6ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGluIHRoZSBpbmRleCBhbmQgZmlsZSBpbmZvLgorICAgICAqIEByZXR1cm4gQSBtYXAgb2YgZmlsZWluZm8gZGF0YS4KKyAgICAgKiBTZWUge0BsaW5rIFdyaXRlciNhcHBlbmRGaWxlSW5mbyhieXRlW10sIGJ5dGVbXSl9LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPGJ5dGUgW10sIGJ5dGUgW10+IGxvYWRGaWxlSW5mbygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLnRyYWlsZXIgPSByZWFkVHJhaWxlcigpOworCisgICAgICAvLyBSZWFkIGluIHRoZSBmaWxlaW5mbyBhbmQgZ2V0IHdoYXQgd2UgbmVlZCBmcm9tIGl0LgorICAgICAgdGhpcy5pc3RyZWFtLnNlZWsodGhpcy50cmFpbGVyLmZpbGVpbmZvT2Zmc2V0KTsKKyAgICAgIEZpbGVJbmZvIGZpID0gbmV3IEZpbGVJbmZvKCk7CisgICAgICBmaS5yZWFkRmllbGRzKHRoaXMuaXN0cmVhbSk7CisgICAgICB0aGlzLmxhc3RrZXkgPSBmaS5nZXQoRmlsZUluZm8uTEFTVEtFWSk7CisgICAgICB0aGlzLmF2Z0tleUxlbiA9IEJ5dGVzLnRvSW50KGZpLmdldChGaWxlSW5mby5BVkdfS0VZX0xFTikpOworICAgICAgdGhpcy5hdmdWYWx1ZUxlbiA9IEJ5dGVzLnRvSW50KGZpLmdldChGaWxlSW5mby5BVkdfVkFMVUVfTEVOKSk7CisgICAgICBTdHJpbmcgY2xhenpOYW1lID0gQnl0ZXMudG9TdHJpbmcoZmkuZ2V0KEZpbGVJbmZvLkNPTVBBUkFUT1IpKTsKKyAgICAgIHRoaXMuY29tcGFyYXRvciA9IGdldENvbXBhcmF0b3IoY2xhenpOYW1lKTsKKworICAgICAgLy8gUmVhZCBpbiB0aGUgZGF0YSBpbmRleC4KKyAgICAgIHRoaXMuYmxvY2tJbmRleCA9IEJsb2NrSW5kZXgucmVhZEluZGV4KHRoaXMuY29tcGFyYXRvciwgdGhpcy5pc3RyZWFtLAorICAgICAgICB0aGlzLnRyYWlsZXIuZGF0YUluZGV4T2Zmc2V0LCB0aGlzLnRyYWlsZXIuZGF0YUluZGV4Q291bnQpOworCisgICAgICAvLyBSZWFkIGluIHRoZSBtZXRhZGF0YSBpbmRleC4KKyAgICAgIGlmICh0cmFpbGVyLm1ldGFJbmRleENvdW50ID4gMCkgeworICAgICAgICB0aGlzLm1ldGFJbmRleCA9IEJsb2NrSW5kZXgucmVhZEluZGV4KEJ5dGVzLkJZVEVTX1JBV0NPTVBBUkFUT1IsCisgICAgICAgICAgdGhpcy5pc3RyZWFtLCB0aGlzLnRyYWlsZXIubWV0YUluZGV4T2Zmc2V0LCB0cmFpbGVyLm1ldGFJbmRleENvdW50KTsKKyAgICAgIH0KKyAgICAgIHRoaXMuZmlsZUluZm9Mb2FkZWQgPSB0cnVlOworICAgICAgcmV0dXJuIGZpOworICAgIH0KKworICAgIGJvb2xlYW4gaXNGaWxlSW5mb0xvYWRlZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLmZpbGVJbmZvTG9hZGVkOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBnZXRDb21wYXJhdG9yKGZpbmFsIFN0cmluZyBjbGF6ek5hbWUpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChjbGF6ek5hbWUgPT0gbnVsbCB8fCBjbGF6ek5hbWUubGVuZ3RoKCkgPT0gMCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiAoUmF3Q29tcGFyYXRvcjxieXRlIFtdPilDbGFzcy5mb3JOYW1lKGNsYXp6TmFtZSkubmV3SW5zdGFuY2UoKTsKKyAgICAgIH0gY2F0Y2ggKEluc3RhbnRpYXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZSk7CisgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiBSZWFkIHRoZSB0cmFpbGVyIG9mZiB0aGUgaW5wdXQgc3RyZWFtLiAgQXMgc2lkZSBlZmZlY3QsIHNldHMgdGhlCisgICAgICogY29tcHJlc3Npb24gYWxnb3JpdGhtLgorICAgICAqIEByZXR1cm4gUG9wdWxhdGVkIEZpeGVkRmlsZVRyYWlsZXIuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgRml4ZWRGaWxlVHJhaWxlciByZWFkVHJhaWxlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBGaXhlZEZpbGVUcmFpbGVyIGZmdCA9IG5ldyBGaXhlZEZpbGVUcmFpbGVyKCk7CisgICAgICBsb25nIHNlZWtQb2ludCA9IHRoaXMuZmlsZVNpemUgLSBGaXhlZEZpbGVUcmFpbGVyLnRyYWlsZXJTaXplKCk7CisgICAgICB0aGlzLmlzdHJlYW0uc2VlayhzZWVrUG9pbnQpOworICAgICAgZmZ0LmRlc2VyaWFsaXplKHRoaXMuaXN0cmVhbSk7CisgICAgICAvLyBTZXQgdXAgdGhlIGNvZGVjLgorICAgICAgdGhpcy5jb21wcmVzc0FsZ28gPQorICAgICAgICBDb21wcmVzc2lvbi5BbGdvcml0aG0udmFsdWVzKClbZmZ0LmNvbXByZXNzaW9uQ29kZWNdOworICAgICAgcmV0dXJuIGZmdDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBTY2FubmVyIG9uIHRoaXMgZmlsZS4gIE5vIHNlZWtzIG9yIHJlYWRzIGFyZSBkb25lIG9uIGNyZWF0aW9uLgorICAgICAqIENhbGwge0BsaW5rIEhGaWxlU2Nhbm5lciNzZWVrVG8oYnl0ZVtdKX0gdG8gcG9zaXRpb24gYW4gc3RhcnQgdGhlIHJlYWQuCisgICAgICogVGhlcmUgaXMgbm90aGluZyB0byBjbGVhbiB1cCBpbiBhIFNjYW5uZXIuIExldHRpbmcgZ28gb2YgeW91ciByZWZlcmVuY2VzCisgICAgICogdG8gdGhlIHNjYW5uZXIgaXMgc3VmZmljaWVudC4KKyAgICAgKiBAcmV0dXJuIFNjYW5uZXIgb24gdGhpcyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBIRmlsZVNjYW5uZXIgZ2V0U2Nhbm5lcigpIHsKKyAgICAgIHJldHVybiBuZXcgU2Nhbm5lcih0aGlzKTsKKyAgICB9CisgICAgLyoqCisgICAgICogQHBhcmFtIGtleSBLZXkgdG8gc2VhcmNoLgorICAgICAqIEByZXR1cm4gQmxvY2sgbnVtYmVyIG9mIHRoZSBibG9jayBjb250YWluaW5nIHRoZSBrZXkgb3IgLTEgaWYgbm90IGluIHRoaXMKKyAgICAgKiBmaWxlLgorICAgICAqLworICAgIHByb3RlY3RlZCBpbnQgYmxvY2tDb250YWluaW5nS2V5KGZpbmFsIGJ5dGUgW10ga2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CisgICAgICBpZiAoYmxvY2tJbmRleCA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJCbG9jayBpbmRleCBub3QgbG9hZGVkIik7CisgICAgICB9CisgICAgICByZXR1cm4gYmxvY2tJbmRleC5ibG9ja0NvbnRhaW5pbmdLZXkoa2V5LCBvZmZzZXQsIGxlbmd0aCk7CisgICAgfQorICAgIC8qKgorICAgICAqIEBwYXJhbSBtZXRhQmxvY2tOYW1lCisgICAgICogQHJldHVybiBCbG9jayB3cmFwcGVkIGluIGEgQnl0ZUJ1ZmZlcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBnZXRNZXRhQmxvY2soU3RyaW5nIG1ldGFCbG9ja05hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodHJhaWxlci5tZXRhSW5kZXhDb3VudCA9PSAwKSB7CisgICAgICAgIHJldHVybiBudWxsOyAvLyB0aGVyZSBhcmUgbm8gbWV0YSBibG9ja3MKKyAgICAgIH0KKyAgICAgIGlmIChtZXRhSW5kZXggPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk1ldGEgaW5kZXggbm90IGxvYWRlZCIpOworICAgICAgfQorICAgICAgYnl0ZSBbXSBtYm5hbWUgPSBCeXRlcy50b0J5dGVzKG1ldGFCbG9ja05hbWUpOworICAgICAgaW50IGJsb2NrID0gbWV0YUluZGV4LmJsb2NrQ29udGFpbmluZ0tleShtYm5hbWUsIDAsIG1ibmFtZS5sZW5ndGgpOworICAgICAgaWYgKGJsb2NrID09IC0xKQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIGxvbmcgYmxvY2tTaXplOworICAgICAgaWYgKGJsb2NrID09IG1ldGFJbmRleC5jb3VudCAtIDEpIHsKKyAgICAgICAgYmxvY2tTaXplID0gdHJhaWxlci5maWxlaW5mb09mZnNldCAtIG1ldGFJbmRleC5ibG9ja09mZnNldHNbYmxvY2tdOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgYmxvY2tTaXplID0gbWV0YUluZGV4LmJsb2NrT2Zmc2V0c1tibG9jaysxXSAtIG1ldGFJbmRleC5ibG9ja09mZnNldHNbYmxvY2tdOworICAgICAgfQorICAgICAgCisgICAgICBCeXRlQnVmZmVyIGJ1ZiA9IGRlY29tcHJlc3MobWV0YUluZGV4LmJsb2NrT2Zmc2V0c1tibG9ja10sCisgICAgICAgIGxvbmdUb0ludChibG9ja1NpemUpLCBtZXRhSW5kZXguYmxvY2tEYXRhU2l6ZXNbYmxvY2tdKTsKKyAgICAgIGJ5dGUgW10gbWFnaWMgPSBuZXcgYnl0ZVtNRVRBQkxPQ0tNQUdJQy5sZW5ndGhdOworICAgICAgYnVmLmdldChtYWdpYywgMCwgbWFnaWMubGVuZ3RoKTsKKworICAgICAgaWYgKCEgQXJyYXlzLmVxdWFscyhtYWdpYywgTUVUQUJMT0NLTUFHSUMpKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTWV0YSBtYWdpYyBpcyBiYWQgaW4gYmxvY2sgIiArIGJsb2NrKTsKKyAgICAgIH0KKyAgICAgIC8vIFRvc3MgdGhlIGhlYWRlci4gTWF5IGhhdmUgdG8gcmVtb3ZlIGxhdGVyIGR1ZSB0byBwZXJmb3JtYW5jZS4KKyAgICAgIGJ1Zi5jb21wYWN0KCk7CisgICAgICBidWYubGltaXQoYnVmLmxpbWl0KCkgLSBNRVRBQkxPQ0tNQUdJQy5sZW5ndGgpOworICAgICAgYnVmLnJld2luZCgpOworICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisgICAgLyoqCisgICAgICogUmVhZCBpbiBhIGZpbGUgYmxvY2suCisgICAgICogQHBhcmFtIGJsb2NrIEluZGV4IG9mIGJsb2NrIHRvIHJlYWQuCisgICAgICogQHJldHVybiBCbG9jayB3cmFwcGVkIGluIGEgQnl0ZUJ1ZmZlci4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgQnl0ZUJ1ZmZlciByZWFkQmxvY2soaW50IGJsb2NrKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKGJsb2NrSW5kZXggPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkJsb2NrIGluZGV4IG5vdCBsb2FkZWQiKTsKKyAgICAgIH0KKyAgICAgIGlmIChibG9jayA8IDAgfHwgYmxvY2sgPiBibG9ja0luZGV4LmNvdW50KSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUmVxdWVzdGVkIGJsb2NrIGlzIG91dCBvZiByYW5nZTogIiArIGJsb2NrICsKKyAgICAgICAgICAiLCBtYXg6ICIgKyBibG9ja0luZGV4LmNvdW50KTsKKyAgICAgIH0KKworICAgICAgLy8gRm9yIGFueSBnaXZlbiBibG9jayBmcm9tIGFueSBnaXZlbiBmaWxlLCBzeW5jaHJvbml6ZSByZWFkcyBmb3Igc2FpZAorICAgICAgLy8gYmxvY2suCisgICAgICAvLyBXaXRob3V0IGEgY2FjaGUsIHRoaXMgc3luY2hyb25pemluZyBpcyBuZWVkbGVzcyBvdmVyaGVhZCwgYnV0IHJlYWxseQorICAgICAgLy8gdGhlIG90aGVyIGNob2ljZSBpcyB0byBkdXBsaWNhdGUgd29yayAod2hpY2ggdGhlIGNhY2hlIHdvdWxkIHByZXZlbnQgeW91IGZyb20gZG9pbmcpLgorICAgICAgc3luY2hyb25pemVkIChibG9ja0luZGV4LmJsb2NrS2V5c1tibG9ja10pIHsKKyAgICAgICAgYmxvY2tMb2FkcysrOworICAgICAgICAvLyBDaGVjayBjYWNoZSBmb3IgYmxvY2suICBJZiBmb3VuZCByZXR1cm4uCisgICAgICAgIGlmIChjYWNoZSAhPSBudWxsKSB7CisgICAgICAgICAgQnl0ZUJ1ZmZlciBjYWNoZWRCdWYgPSBjYWNoZS5nZXRCbG9jayhuYW1lICsgYmxvY2spOworICAgICAgICAgIGlmIChjYWNoZWRCdWYgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gUmV0dXJuIGEgZGlzdGluY3QgJ2NvcHknIG9mIHRoZSBibG9jaywgc28gcG9zIGRvZXNudCBnZXQgbWVzc2VkIGJ5CisgICAgICAgICAgICAvLyB0aGUgc2Nhbm5lcgorICAgICAgICAgICAgY2FjaGVIaXRzKys7CisgICAgICAgICAgICByZXR1cm4gY2FjaGVkQnVmLmR1cGxpY2F0ZSgpOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBDYXJyeSBvbiwgcGxlYXNlIGxvYWQuCisgICAgICAgIH0KKworICAgICAgICAvLyBMb2FkIGJsb2NrIGZyb20gZmlsZXN5c3RlbS4KKyAgICAgICAgbG9uZyBvbkRpc2tCbG9ja1NpemU7CisgICAgICAgIGlmIChibG9jayA9PSBibG9ja0luZGV4LmNvdW50IC0gMSkgeworICAgICAgICAgIC8vIGxhc3QgYmxvY2shICBUaGUgZW5kIG9mIGRhdGEgYmxvY2sgaXMgZmlyc3QgbWV0YSBibG9jayBpZiB0aGVyZSBpcworICAgICAgICAgIC8vIG9uZSBvciBpZiB0aGVyZSBpc24ndCwgdGhlIGZpbGVpbmZvIG9mZnNldC4KKyAgICAgICAgICBsb25nIG9mZnNldCA9IHRoaXMubWV0YUluZGV4ICE9IG51bGw/CisgICAgICAgICAgICB0aGlzLm1ldGFJbmRleC5ibG9ja09mZnNldHNbMF06IHRoaXMudHJhaWxlci5maWxlaW5mb09mZnNldDsKKyAgICAgICAgICBvbkRpc2tCbG9ja1NpemUgPSBvZmZzZXQgLSBibG9ja0luZGV4LmJsb2NrT2Zmc2V0c1tibG9ja107CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgb25EaXNrQmxvY2tTaXplID0gYmxvY2tJbmRleC5ibG9ja09mZnNldHNbYmxvY2srMV0gLQorICAgICAgICAgIGJsb2NrSW5kZXguYmxvY2tPZmZzZXRzW2Jsb2NrXTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQnVmZmVyIGJ1ZiA9IGRlY29tcHJlc3MoYmxvY2tJbmRleC5ibG9ja09mZnNldHNbYmxvY2tdLAorICAgICAgICAgICAgbG9uZ1RvSW50KG9uRGlza0Jsb2NrU2l6ZSksIHRoaXMuYmxvY2tJbmRleC5ibG9ja0RhdGFTaXplc1tibG9ja10pOworCisgICAgICAgIGJ5dGUgW10gbWFnaWMgPSBuZXcgYnl0ZVtEQVRBQkxPQ0tNQUdJQy5sZW5ndGhdOworICAgICAgICBidWYuZ2V0KG1hZ2ljLCAwLCBtYWdpYy5sZW5ndGgpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMobWFnaWMsIERBVEFCTE9DS01BR0lDKSkgeworICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRGF0YSBtYWdpYyBpcyBiYWQgaW4gYmxvY2sgIiArIGJsb2NrKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUb3NzIHRoZSBoZWFkZXIuIE1heSBoYXZlIHRvIHJlbW92ZSBsYXRlciBkdWUgdG8gcGVyZm9ybWFuY2UuCisgICAgICAgIGJ1Zi5jb21wYWN0KCk7CisgICAgICAgIGJ1Zi5saW1pdChidWYubGltaXQoKSAtIERBVEFCTE9DS01BR0lDLmxlbmd0aCk7CisgICAgICAgIGJ1Zi5yZXdpbmQoKTsKKworICAgICAgICAvLyBDYWNoZSBhIGNvcHksIG5vdCB0aGUgb25lIHdlIGFyZSBzZW5kaW5nIGJhY2ssIHNvIHRoZSBwb3NpdGlvbiBkb2VzbnQKKyAgICAgICAgLy8gZ2V0IG1lc3NlZC4KKyAgICAgICAgaWYgKGNhY2hlICE9IG51bGwpIHsKKyAgICAgICAgICBjYWNoZS5jYWNoZUJsb2NrKG5hbWUgKyBibG9jaywgYnVmLmR1cGxpY2F0ZSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBidWY7CisgICAgICB9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBEZWNvbXByZXNzIDxjb2RlPmNvbXByZXNzZWRTaXplPC9jb2RlPiBieXRlcyBvZmYgdGhlIGJhY2tpbmcKKyAgICAgKiBGU0RhdGFJbnB1dFN0cmVhbS4KKyAgICAgKiBAcGFyYW0gb2Zmc2V0CisgICAgICogQHBhcmFtIGNvbXByZXNzZWRTaXplCisgICAgICogQHBhcmFtIGRlY29tcHJlc3NlZFNpemUKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciBkZWNvbXByZXNzKGZpbmFsIGxvbmcgb2Zmc2V0LCBmaW5hbCBpbnQgY29tcHJlc3NlZFNpemUsCisgICAgICBmaW5hbCBpbnQgZGVjb21wcmVzc2VkU2l6ZSkgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIERlY29tcHJlc3NvciBkZWNvbXByZXNzb3IgPSB0aGlzLmNvbXByZXNzQWxnby5nZXREZWNvbXByZXNzb3IoKTsKKyAgICAgIC8vIE15IGd1ZXNzIGlzIHRoYXQgdGhlIGJvdW5kZWQgcmFuZ2UgZmlzIGlzIG5lZWRlZCB0byBzdG9wIHRoZSAKKyAgICAgIC8vIGRlY29tcHJlc3NvciByZWFkaW5nIGludG8gbmV4dCBibG9jayAtLSBJSVJDLCBpdCBqdXN0IGdyYWJzIGEKKyAgICAgIC8vIGJ1bmNoIG9mIGRhdGEgdy9vIHJlZ2FyZCB0byB3aGV0aGVyIGRlY29tcHJlc3NvciBpcyBjb21pbmcgdG8gZW5kIG9mIGEKKyAgICAgIC8vIGRlY29tcHJlc3Npb24uCisgICAgICBJbnB1dFN0cmVhbSBpcyA9IHRoaXMuY29tcHJlc3NBbGdvLmNyZWF0ZURlY29tcHJlc3Npb25TdHJlYW0oCisgICAgICAgIG5ldyBCb3VuZGVkUmFuZ2VGaWxlSW5wdXRTdHJlYW0odGhpcy5pc3RyZWFtLCBvZmZzZXQsIGNvbXByZXNzZWRTaXplKSwKKyAgICAgICAgZGVjb21wcmVzc29yLCAwKTsKKyAgICAgIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShkZWNvbXByZXNzZWRTaXplKTsKKyAgICAgIElPVXRpbHMucmVhZEZ1bGx5KGlzLCBidWYuYXJyYXkoKSwgMCwgYnVmLmNhcGFjaXR5KCkpOworICAgICAgaXMuY2xvc2UoKTsKKyAgICAgIHRoaXMuY29tcHJlc3NBbGdvLnJldHVybkRlY29tcHJlc3NvcihkZWNvbXByZXNzb3IpOworICAgICAgcmV0dXJuIGJ1ZjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIEZpcnN0IGtleSBpbiB0aGUgZmlsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYnl0ZSBbXSBnZXRGaXJzdEtleSgpIHsKKyAgICAgIGlmIChibG9ja0luZGV4ID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkJsb2NrIGluZGV4IG5vdCBsb2FkZWQiKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBibG9ja0luZGV4LmJsb2NrS2V5c1swXTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldEVudHJpZXMoKSB7CisgICAgICBpZiAoIXRoaXMuaXNGaWxlSW5mb0xvYWRlZCgpKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJGaWxlIGluZm8gbm90IGxvYWRlZCIpOworICAgICAgfQorICAgICAgcmV0dXJuIHRoaXMudHJhaWxlci5lbnRyeUNvdW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIEByZXR1cm4gTGFzdCBrZXkgaW4gdGhlIGZpbGUuCisgICAgICovCisgICAgcHVibGljIGJ5dGUgW10gZ2V0TGFzdEtleSgpIHsKKyAgICAgIGlmICghaXNGaWxlSW5mb0xvYWRlZCgpKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJMb2FkIGZpbGUgaW5mbyBmaXJzdCIpOworICAgICAgfQorICAgICAgcmV0dXJuIHRoaXMubGFzdGtleTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIENvbXBhcmF0b3IuCisgICAgICovCisgICAgcHVibGljIFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT4gZ2V0Q29tcGFyYXRvcigpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbXBhcmF0b3I7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBpbmRleCBzaXplCisgICAgICovCisgICAgcHVibGljIGxvbmcgaW5kZXhTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmJsb2NrSW5kZXggIT0gbnVsbD8gdGhpcy5ibG9ja0luZGV4LmhlYXBTaXplKCk6IDApICsKKyAgICAgICAgKCh0aGlzLm1ldGFJbmRleCAhPSBudWxsKT8gdGhpcy5tZXRhSW5kZXguaGVhcFNpemUoKTogMCk7CisgICAgfQorIAorICAgIC8qKgorICAgICAqIEByZXR1cm4gTWlka2V5IGZvciB0aGlzIGZpbGUuICBXZSB3b3JrIHdpdGggYmxvY2sgYm91bmRhcmllcyBvbmx5IHNvCisgICAgICogcmV0dXJuZWQgbWlka2V5IGlzIGFuIGFwcHJveGltYXRpb24gb25seS4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGJ5dGUgW10gbWlka2V5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghaXNGaWxlSW5mb0xvYWRlZCgpIHx8IHRoaXMuYmxvY2tJbmRleC5pc0VtcHR5KCkpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gdGhpcy5ibG9ja0luZGV4Lm1pZGtleSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0aGlzLmNsb3NlSVN0cmVhbSAmJiB0aGlzLmlzdHJlYW0gIT0gbnVsbCkgeworICAgICAgICB0aGlzLmlzdHJlYW0uY2xvc2UoKTsKKyAgICAgICAgdGhpcy5pc3RyZWFtID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEltcGxlbWVudGF0aW9uIG9mIHtAbGluayBIRmlsZVNjYW5uZXJ9IGludGVyZmFjZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTY2FubmVyIGltcGxlbWVudHMgSEZpbGVTY2FubmVyIHsKKyAgICAgIHByaXZhdGUgZmluYWwgUmVhZGVyIHJlYWRlcjsKKyAgICAgIHByaXZhdGUgQnl0ZUJ1ZmZlciBibG9jazsKKyAgICAgIHByaXZhdGUgaW50IGN1cnJCbG9jazsKKworICAgICAgcHJpdmF0ZSBpbnQgY3VycktleUxlbiA9IDA7CisgICAgICBwcml2YXRlIGludCBjdXJyVmFsdWVMZW4gPSAwOworCisgICAgICBwdWJsaWMgaW50IGJsb2NrRmV0Y2hlcyA9IDA7CisKKyAgICAgIHB1YmxpYyBTY2FubmVyKFJlYWRlciByKSB7CisgICAgICAgIHRoaXMucmVhZGVyID0gcjsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcHVibGljIEtleVZhbHVlIGdldEtleVZhbHVlKCkgeworICAgICAgICByZXR1cm4gbmV3IEtleVZhbHVlKHRoaXMuYmxvY2suYXJyYXkoKSwKKyAgICAgICAgICAgIHRoaXMuYmxvY2suYXJyYXlPZmZzZXQoKSArIHRoaXMuYmxvY2sucG9zaXRpb24oKSAtIDgpOworICAgICAgfQorCisgICAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBnZXRLZXkoKSB7CisgICAgICAgIGlmICh0aGlzLmJsb2NrID09IG51bGwgfHwgdGhpcy5jdXJyS2V5TGVuID09IDApIHsKKyAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigieW91IG5lZWQgdG8gc2Vla1RvKCkgYmVmb3JlIGNhbGxpbmcgZ2V0S2V5KCkiKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQnVmZmVyIGtleUJ1ZmYgPSB0aGlzLmJsb2NrLnNsaWNlKCk7CisgICAgICAgIGtleUJ1ZmYubGltaXQodGhpcy5jdXJyS2V5TGVuKTsKKyAgICAgICAga2V5QnVmZi5yZXdpbmQoKTsKKyAgICAgICAgLy8gRG8ga2V5QnVmZi5hc1JlYWRPbmx5KCk/CisgICAgICAgIHJldHVybiBrZXlCdWZmOworICAgICAgfQorCisgICAgICBwdWJsaWMgQnl0ZUJ1ZmZlciBnZXRWYWx1ZSgpIHsKKyAgICAgICAgaWYgKGJsb2NrID09IG51bGwgfHwgY3VycktleUxlbiA9PSAwKSB7CisgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInlvdSBuZWVkIHRvIHNlZWtUbygpIGJlZm9yZSBjYWxsaW5nIGdldFZhbHVlKCkiKTsKKyAgICAgICAgfQorICAgICAgICAvLyBUT0RPOiBDb3VsZCB0aGlzIGJlIGRvbmUgd2l0aCBvbmUgQnl0ZUJ1ZmZlciByYXRoZXIgdGhhbiBjcmVhdGUgdHdvPworICAgICAgICBCeXRlQnVmZmVyIHZhbHVlQnVmZiA9IHRoaXMuYmxvY2suc2xpY2UoKTsKKyAgICAgICAgdmFsdWVCdWZmLnBvc2l0aW9uKHRoaXMuY3VycktleUxlbik7CisgICAgICAgIHZhbHVlQnVmZiA9IHZhbHVlQnVmZi5zbGljZSgpOworICAgICAgICB2YWx1ZUJ1ZmYubGltaXQoY3VyclZhbHVlTGVuKTsKKyAgICAgICAgdmFsdWVCdWZmLnJld2luZCgpOworICAgICAgICByZXR1cm4gdmFsdWVCdWZmOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgLy8gTE9HLmRldWcoInJlbToiICsgYmxvY2sucmVtYWluaW5nKCkgKyAiIHA6IiArIGJsb2NrLnBvc2l0aW9uKCkgKworICAgICAgICAvLyAiIGtsOiAiICsgY3VycktleUxlbiArICIga3Y6ICIgKyBjdXJyVmFsdWVMZW4pOworICAgICAgICBpZiAoYmxvY2sgPT0gbnVsbCkgeworICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTmV4dCBjYWxsZWQgb24gbm9uLXNlZWtlZCBzY2FubmVyIik7CisgICAgICAgIH0KKyAgICAgICAgYmxvY2sucG9zaXRpb24oYmxvY2sucG9zaXRpb24oKSArIGN1cnJLZXlMZW4gKyBjdXJyVmFsdWVMZW4pOworICAgICAgICBpZiAoYmxvY2sucmVtYWluaW5nKCkgPD0gMCkgeworICAgICAgICAgIC8vIExPRy5kZWJ1ZygiRmV0Y2ggbmV4dCBibG9jayIpOworICAgICAgICAgIGN1cnJCbG9jaysrOworICAgICAgICAgIGlmIChjdXJyQmxvY2sgPj0gcmVhZGVyLmJsb2NrSW5kZXguY291bnQpIHsKKyAgICAgICAgICAgIC8vIGRhbW4gd2UgYXJlIGF0IHRoZSBlbmQKKyAgICAgICAgICAgIGN1cnJCbG9jayA9IDA7CisgICAgICAgICAgICBibG9jayA9IG51bGw7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIGJsb2NrID0gcmVhZGVyLnJlYWRCbG9jayhjdXJyQmxvY2spOworICAgICAgICAgIGN1cnJLZXlMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgICBjdXJyVmFsdWVMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgICBibG9ja0ZldGNoZXMrKzsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBMT0cuZGVidWcoInJlbToiICsgYmxvY2sucmVtYWluaW5nKCkgKyAiIHA6IiArIGJsb2NrLnBvc2l0aW9uKCkgKworICAgICAgICAvLyAiIGtsOiAiICsgY3VycktleUxlbiArICIga3Y6ICIgKyBjdXJyVmFsdWVMZW4pOworCisgICAgICAgIGN1cnJLZXlMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgY3VyclZhbHVlTGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgCisgICAgICBwdWJsaWMgaW50IHNlZWtUbyhieXRlIFtdIGtleSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgcmV0dXJuIHNlZWtUbyhrZXksIDAsIGtleS5sZW5ndGgpOworICAgICAgfQorICAgICAgCisKKyAgICAgIHB1YmxpYyBpbnQgc2Vla1RvKGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBiID0gcmVhZGVyLmJsb2NrQ29udGFpbmluZ0tleShrZXksIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgaWYgKGIgPCAwKSByZXR1cm4gLTE7IC8vIGZhbGxzIGJlZm9yZSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlISA6LSgKKyAgICAgICAgLy8gQXZvaWQgcmUtcmVhZGluZyB0aGUgc2FtZSBibG9jayAodGhhdCdkIGJlIGR1bWIpLgorICAgICAgICBsb2FkQmxvY2soYik7CisgICAgICAgIAorICAgICAgICByZXR1cm4gYmxvY2tTZWVrKGtleSwgb2Zmc2V0LCBsZW5ndGgsIGZhbHNlKTsKKyAgICAgIH0KKworICAgICAgLyoqCisgICAgICAgKiBXaXRoaW4gYSBsb2FkZWQgYmxvY2ssIHNlZWsgbG9va2luZyBmb3IgdGhlIGZpcnN0IGtleQorICAgICAgICogdGhhdCBpcyBzbWFsbGVyIHRoYW4gKG9yIGVxdWFsIHRvPykgdGhlIGtleSB3ZSBhcmUgaW50ZXJlc3RlZCBpbi4KKyAgICAgICAqIAorICAgICAgICogQSBub3RlIG9uIHRoZSBzZWVrQmVmb3JlIC0gaWYgeW91IGhhdmUgc2Vla0JlZm9yZSA9IHRydWUsIEFORCB0aGUKKyAgICAgICAqIGZpcnN0IGtleSBpbiB0aGUgYmxvY2sgPSBrZXksIHRoZW4geW91J2xsIGdldCB0aHJvd24gZXhjZXB0aW9ucy4KKyAgICAgICAqIEBwYXJhbSBrZXkgdG8gZmluZAorICAgICAgICogQHBhcmFtIHNlZWtCZWZvcmUgZmluZCB0aGUga2V5IGJlZm9yZSB0aGUgZXhhY3QgbWF0Y2guCisgICAgICAgKiBAcmV0dXJuCisgICAgICAgKi8KKyAgICAgIHByaXZhdGUgaW50IGJsb2NrU2VlayhieXRlW10ga2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoLCBib29sZWFuIHNlZWtCZWZvcmUpIHsKKyAgICAgICAgaW50IGtsZW4sIHZsZW47CisgICAgICAgIGludCBsYXN0TGVuID0gMDsKKyAgICAgICAgZG8geworICAgICAgICAgIGtsZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgICB2bGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgICAgaW50IGNvbXAgPSB0aGlzLnJlYWRlci5jb21wYXJhdG9yLmNvbXBhcmUoa2V5LCBvZmZzZXQsIGxlbmd0aCwKKyAgICAgICAgICAgIGJsb2NrLmFycmF5KCksIGJsb2NrLmFycmF5T2Zmc2V0KCkgKyBibG9jay5wb3NpdGlvbigpLCBrbGVuKTsKKyAgICAgICAgICBpZiAoY29tcCA9PSAwKSB7CisgICAgICAgICAgICBpZiAoc2Vla0JlZm9yZSkgeworICAgICAgICAgICAgICBibG9jay5wb3NpdGlvbihibG9jay5wb3NpdGlvbigpIC0gbGFzdExlbiAtIDE2KTsKKyAgICAgICAgICAgICAgY3VycktleUxlbiA9IGJsb2NrLmdldEludCgpOworICAgICAgICAgICAgICBjdXJyVmFsdWVMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgICAgICAgcmV0dXJuIDE7IC8vIG5vbiBleGFjdCBtYXRjaC4KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGN1cnJLZXlMZW4gPSBrbGVuOworICAgICAgICAgICAgY3VyclZhbHVlTGVuID0gdmxlbjsKKyAgICAgICAgICAgIHJldHVybiAwOyAvLyBpbmRpY2F0ZSBleGFjdCBtYXRjaAorICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoY29tcCA8IDApIHsKKyAgICAgICAgICAgIC8vIGdvIGJhY2sgb25lIGtleToKKyAgICAgICAgICAgIGJsb2NrLnBvc2l0aW9uKGJsb2NrLnBvc2l0aW9uKCkgLSBsYXN0TGVuIC0gMTYpOworICAgICAgICAgICAgY3VycktleUxlbiA9IGJsb2NrLmdldEludCgpOworICAgICAgICAgICAgY3VyclZhbHVlTGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICB9CisgICAgICAgICAgYmxvY2sucG9zaXRpb24oYmxvY2sucG9zaXRpb24oKSArIGtsZW4gKyB2bGVuKTsKKyAgICAgICAgICBsYXN0TGVuID0ga2xlbiArIHZsZW4gOworICAgICAgICB9IHdoaWxlKGJsb2NrLnJlbWFpbmluZygpID4gMCk7CisgICAgICAgIC8vIG9rIHdlIGFyZSBhdCB0aGUgZW5kLCBzbyBnbyBiYWNrIGEgbGl0dGxlZWVlZWUuLi4uCisgICAgICAgIC8vIFRoZSA4IGluIHRoZSBiZWxvdyBpcyBpbnRlbnRpb25hbGx5IGRpZmZlcmVudCB0byB0aGUgMTZzIGluIHRoZSBhYm92ZQorICAgICAgICAvLyBEbyB0aGUgbWF0aCB5b3UgeW91J2xsIGZpZ3VyZSBpdC4KKyAgICAgICAgYmxvY2sucG9zaXRpb24oYmxvY2sucG9zaXRpb24oKSAtIGxhc3RMZW4gLSA4KTsKKyAgICAgICAgY3VycktleUxlbiA9IGJsb2NrLmdldEludCgpOworICAgICAgICBjdXJyVmFsdWVMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgcmV0dXJuIDE7IC8vIGRpZG4ndCBleGFjdGx5IGZpbmQgaXQuCisgICAgICB9CisKKyAgICAgIHB1YmxpYyBib29sZWFuIHNlZWtCZWZvcmUoYnl0ZSBbXSBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBzZWVrQmVmb3JlKGtleSwgMCwga2V5Lmxlbmd0aCk7CisgICAgICB9CisgICAgICAKKyAgICAgIHB1YmxpYyBib29sZWFuIHNlZWtCZWZvcmUoYnl0ZVtdIGtleSwgaW50IG9mZnNldCwgaW50IGxlbmd0aCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGludCBiID0gcmVhZGVyLmJsb2NrQ29udGFpbmluZ0tleShrZXksIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgICAgaWYgKGIgPCAwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8ga2V5IGlzIGJlZm9yZSB0aGUgc3RhcnQgb2YgdGhlIGZpbGUuCisKKyAgICAgICAgLy8gUXVlc3Rpb246IGRvZXMgdGhpcyBibG9jayBiZWdpbiB3aXRoICdrZXknPworICAgICAgICBpZiAodGhpcy5yZWFkZXIuY29tcGFyYXRvci5jb21wYXJlKHJlYWRlci5ibG9ja0luZGV4LmJsb2NrS2V5c1tiXSwKKyAgICAgICAgICAgIDAsIHJlYWRlci5ibG9ja0luZGV4LmJsb2NrS2V5c1tiXS5sZW5ndGgsCisgICAgICAgICAgICBrZXksIG9mZnNldCwgbGVuZ3RoKSA9PSAwKSB7CisgICAgICAgICAgLy8gT2sgdGhlIGtleSB3ZSdyZSBpbnRlcmVzdGVkIGluIGlzIHRoZSBmaXJzdCBvZiB0aGUgYmxvY2ssIHNvIGdvIGJhY2sgb25lLgorICAgICAgICAgIGlmIChiID09IDApIHsKKyAgICAgICAgICAgIC8vIHdlIGhhdmUgYSAncHJvYmxlbScsIHRoZSBrZXkgd2Ugd2FudCBpcyB0aGUgZmlyc3Qgb2YgdGhlIGZpbGUuCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIGItLTsKKyAgICAgICAgICAvLyBUT0RPIHNob3J0Y3V0OiBzZWVrIGZvcndhcmQgaW4gdGhpcyBibG9jayB0byB0aGUgbGFzdCBrZXkgb2YgdGhlIGJsb2NrLgorICAgICAgICB9CisgICAgICAgIGxvYWRCbG9jayhiKTsKKyAgICAgICAgYmxvY2tTZWVrKGtleSwgb2Zmc2V0LCBsZW5ndGgsIHRydWUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgcHVibGljIFN0cmluZyBnZXRLZXlTdHJpbmcoKSB7CisgICAgICAgIHJldHVybiBCeXRlcy50b1N0cmluZyhibG9jay5hcnJheSgpLCBibG9jay5hcnJheU9mZnNldCgpICsKKyAgICAgICAgICBibG9jay5wb3NpdGlvbigpLCBjdXJyS2V5TGVuKTsKKyAgICAgIH0KKworICAgICAgcHVibGljIFN0cmluZyBnZXRWYWx1ZVN0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIEJ5dGVzLnRvU3RyaW5nKGJsb2NrLmFycmF5KCksIGJsb2NrLmFycmF5T2Zmc2V0KCkgKworICAgICAgICAgIGJsb2NrLnBvc2l0aW9uKCkgKyBjdXJyS2V5TGVuLCBjdXJyVmFsdWVMZW4pOworICAgICAgfQorCisgICAgICBwdWJsaWMgUmVhZGVyIGdldFJlYWRlcigpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVhZGVyOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBpc1NlZWtlZCgpeworICAgICAgICByZXR1cm4gdGhpcy5ibG9jayAhPSBudWxsOworICAgICAgfQorCisgICAgICBwdWJsaWMgYm9vbGVhbiBzZWVrVG8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBpZiAodGhpcy5yZWFkZXIuYmxvY2tJbmRleC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJsb2NrICE9IG51bGwgJiYgY3VyckJsb2NrID09IDApIHsKKyAgICAgICAgICBibG9jay5yZXdpbmQoKTsKKyAgICAgICAgICBjdXJyS2V5TGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgICAgY3VyclZhbHVlTGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgIH0KKyAgICAgICAgY3VyckJsb2NrID0gMDsKKyAgICAgICAgYmxvY2sgPSByZWFkZXIucmVhZEJsb2NrKGN1cnJCbG9jayk7CisgICAgICAgIGN1cnJLZXlMZW4gPSBibG9jay5nZXRJbnQoKTsKKyAgICAgICAgY3VyclZhbHVlTGVuID0gYmxvY2suZ2V0SW50KCk7CisgICAgICAgIGJsb2NrRmV0Y2hlcysrOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcHJpdmF0ZSB2b2lkIGxvYWRCbG9jayhpbnQgYmxvYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGJsb2NrID09IG51bGwpIHsKKyAgICAgICAgICBibG9jayA9IHJlYWRlci5yZWFkQmxvY2soYmxvYyk7CisgICAgICAgICAgY3VyckJsb2NrID0gYmxvYzsKKyAgICAgICAgICBibG9ja0ZldGNoZXMrKzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoYmxvYyAhPSBjdXJyQmxvY2spIHsKKyAgICAgICAgICAgIGJsb2NrID0gcmVhZGVyLnJlYWRCbG9jayhibG9jKTsKKyAgICAgICAgICAgIGN1cnJCbG9jayA9IGJsb2M7CisgICAgICAgICAgICBibG9ja0ZldGNoZXMrKzsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gd2UgYXJlIGFscmVhZHkgaW4gdGhlIHNhbWUgYmxvY2ssIGp1c3QgcmV3aW5kIHRvIHNlZWsgYWdhaW4uCisgICAgICAgICAgICBibG9jay5yZXdpbmQoKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgLyoKKyAgICogVGhlIFJGaWxlIGhhcyBhIGZpeGVkIHRyYWlsZXIgd2hpY2ggY29udGFpbnMgb2Zmc2V0cyB0byBvdGhlciB2YXJpYWJsZQorICAgKiBwYXJ0cyBvZiB0aGUgZmlsZS4gIEFsc28gaW5jbHVkZXMgYmFzaWMgbWV0YWRhdGEgb24gdGhpcyBmaWxlLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRml4ZWRGaWxlVHJhaWxlciB7CisgICAgLy8gT2Zmc2V0IHRvIHRoZSBkYXRhIGJsb2NrIGluZGV4LgorICAgIGxvbmcgZGF0YUluZGV4T2Zmc2V0OworICAgIC8vIE9mZnNldCB0byB0aGUgZmlsZWluZm8gZGF0YSwgYSBzbWFsbCBibG9jayBvZiB2aXRhbHMuLgorICAgIGxvbmcgZmlsZWluZm9PZmZzZXQ7CisgICAgLy8gSG93IG1hbnkgaW5kZXggY291bnRzIGFyZSB0aGVyZSAoYWthOiBibG9jayBjb3VudCkKKyAgICBpbnQgZGF0YUluZGV4Q291bnQ7CisgICAgLy8gT2Zmc2V0IHRvIHRoZSBtZXRhIGJsb2NrIGluZGV4LgorICAgIGxvbmcgbWV0YUluZGV4T2Zmc2V0OworICAgIC8vIEhvdyBtYW55IG1ldGEgYmxvY2sgaW5kZXggZW50cmllcyAoYWthOiBtZXRhIGJsb2NrIGNvdW50KQorICAgIGludCBtZXRhSW5kZXhDb3VudDsKKyAgICBsb25nIHRvdGFsVW5jb21wcmVzc2VkQnl0ZXM7CisgICAgaW50IGVudHJ5Q291bnQ7CisgICAgaW50IGNvbXByZXNzaW9uQ29kZWM7CisgICAgaW50IHZlcnNpb24gPSAxOworICAgIAorICAgIEZpeGVkRmlsZVRyYWlsZXIoKSB7CisgICAgICBzdXBlcigpOworICAgIH0KKworICAgIHN0YXRpYyBpbnQgdHJhaWxlclNpemUoKSB7CisgICAgICAvLyBLZWVwIHRoaXMgdXAgdG8gZGF0ZS4uLgorICAgICAgZmluYWwgaW50IGludFNpemUgPSA0OworICAgICAgZmluYWwgaW50IGxvbmdTaXplID0gODsKKyAgICAgIHJldHVybiAKKyAgICAgICggaW50U2l6ZSAqIDUgKSArCisgICAgICAoIGxvbmdTaXplICogNCApICsKKyAgICAgIFRSQUlMRVJCTE9DS01BR0lDLmxlbmd0aDsKKyAgICB9CisKKyAgICB2b2lkIHNlcmlhbGl6ZShEYXRhT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZShUUkFJTEVSQkxPQ0tNQUdJQyk7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGVMb25nKGZpbGVpbmZvT2Zmc2V0KTsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZUxvbmcoZGF0YUluZGV4T2Zmc2V0KTsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZUludChkYXRhSW5kZXhDb3VudCk7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGVMb25nKG1ldGFJbmRleE9mZnNldCk7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGVJbnQobWV0YUluZGV4Q291bnQpOworICAgICAgb3V0cHV0U3RyZWFtLndyaXRlTG9uZyh0b3RhbFVuY29tcHJlc3NlZEJ5dGVzKTsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZUludChlbnRyeUNvdW50KTsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZUludChjb21wcmVzc2lvbkNvZGVjKTsKKyAgICAgIG91dHB1dFN0cmVhbS53cml0ZUludCh2ZXJzaW9uKTsKKyAgICB9CisKKyAgICB2b2lkIGRlc2VyaWFsaXplKERhdGFJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGJ5dGUgW10gaGVhZGVyID0gbmV3IGJ5dGVbVFJBSUxFUkJMT0NLTUFHSUMubGVuZ3RoXTsKKyAgICAgIGlucHV0U3RyZWFtLnJlYWRGdWxseShoZWFkZXIpOworICAgICAgaWYgKCAhQXJyYXlzLmVxdWFscyhoZWFkZXIsIFRSQUlMRVJCTE9DS01BR0lDKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRyYWlsZXIgJ2hlYWRlcicgaXMgd3Jvbmc7IGRvZXMgdGhlIHRyYWlsZXIgIiArCisgICAgICAgICAgInNpemUgbWF0Y2ggY29udGVudD8iKTsKKyAgICAgIH0KKyAgICAgIGZpbGVpbmZvT2Zmc2V0ICAgICAgICAgPSBpbnB1dFN0cmVhbS5yZWFkTG9uZygpOworICAgICAgZGF0YUluZGV4T2Zmc2V0ICAgICAgICA9IGlucHV0U3RyZWFtLnJlYWRMb25nKCk7CisgICAgICBkYXRhSW5kZXhDb3VudCAgICAgICAgID0gaW5wdXRTdHJlYW0ucmVhZEludCgpOworCisgICAgICBtZXRhSW5kZXhPZmZzZXQgICAgICAgID0gaW5wdXRTdHJlYW0ucmVhZExvbmcoKTsKKyAgICAgIG1ldGFJbmRleENvdW50ICAgICAgICAgPSBpbnB1dFN0cmVhbS5yZWFkSW50KCk7CisgICAgICAKKyAgICAgIHRvdGFsVW5jb21wcmVzc2VkQnl0ZXMgPSBpbnB1dFN0cmVhbS5yZWFkTG9uZygpOworICAgICAgZW50cnlDb3VudCAgICAgICAgICAgICA9IGlucHV0U3RyZWFtLnJlYWRJbnQoKTsKKyAgICAgIGNvbXByZXNzaW9uQ29kZWMgICAgICAgPSBpbnB1dFN0cmVhbS5yZWFkSW50KCk7CisgICAgICB2ZXJzaW9uICAgICAgICAgICAgICAgID0gaW5wdXRTdHJlYW0ucmVhZEludCgpOworCisgICAgICBpZiAodmVyc2lvbiAhPSAxKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiV3JvbmcgdmVyc2lvbjogIiArIHZlcnNpb24pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gImZpbGVpbmZvT2Zmc2V0PSIgKyBmaWxlaW5mb09mZnNldCArCisgICAgICAiLCBkYXRhSW5kZXhPZmZzZXQ9IiArIGRhdGFJbmRleE9mZnNldCArCisgICAgICAiLCBkYXRhSW5kZXhDb3VudD0iICsgZGF0YUluZGV4Q291bnQgKworICAgICAgIiwgbWV0YUluZGV4T2Zmc2V0PSIgKyBtZXRhSW5kZXhPZmZzZXQgKworICAgICAgIiwgbWV0YUluZGV4Q291bnQ9IiArIG1ldGFJbmRleENvdW50ICsKKyAgICAgICIsIHRvdGFsQnl0ZXM9IiArIHRvdGFsVW5jb21wcmVzc2VkQnl0ZXMgKworICAgICAgIiwgZW50cnlDb3VudD0iICsgZW50cnlDb3VudCArCisgICAgICAiLCB2ZXJzaW9uPSIgKyB2ZXJzaW9uOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIFRoZSBibG9jayBpbmRleCBmb3IgYSBSRmlsZS4KKyAgICogVXNlZCByZWFkaW5nLgorICAgKi8KKyAgc3RhdGljIGNsYXNzIEJsb2NrSW5kZXggaW1wbGVtZW50cyBIZWFwU2l6ZSB7CisgICAgLy8gSG93IG1hbnkgYWN0dWFsIGl0ZW1zIGFyZSB0aGVyZT8gVGhlIG5leHQgaW5zZXJ0IGxvY2F0aW9uIHRvby4KKyAgICBpbnQgY291bnQgPSAwOworICAgIGJ5dGUgW11bXSBibG9ja0tleXM7CisgICAgbG9uZyBbXSBibG9ja09mZnNldHM7CisgICAgaW50IFtdIGJsb2NrRGF0YVNpemVzOworICAgIGludCBzaXplID0gMDsKKyAgCisgICAgLyogTmVlZGVkIGRvaW5nIGxvb2t1cCBvbiBibG9ja3MuCisgICAgICovCisgICAgZmluYWwgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBjb21wYXJhdG9yOworICAKKyAgICAvKgorICAgICAqIFNodXRkb3duIGRlZmF1bHQgY29uc3RydWN0b3IKKyAgICAgKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIEJsb2NrSW5kZXgoKSB7CisgICAgICB0aGlzKG51bGwpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHBhcmFtIGMgY29tcGFyYXRvciB1c2VkIHRvIGNvbXBhcmUga2V5cy4KKyAgICAgKi8KKyAgICBCbG9ja0luZGV4KGZpbmFsIFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT5jKSB7CisgICAgICB0aGlzLmNvbXBhcmF0b3IgPSBjOworICAgICAgLy8gR3Vlc3MgdGhhdCBjb3N0IG9mIHRocmVlIGFycmF5cyArIHRoaXMgb2JqZWN0IGlzIDQgKiA4IGJ5dGVzLgorICAgICAgdGhpcy5zaXplICs9ICg0ICogOCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBUcnVlIGlmIGJsb2NrIGluZGV4IGlzIGVtcHR5LgorICAgICAqLworICAgIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICAgIHJldHVybiB0aGlzLmJsb2NrS2V5cy5sZW5ndGggPD0gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIGEgbmV3IGVudHJ5IGluIHRoZSBibG9jayBpbmRleC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0ga2V5IExhc3Qga2V5IGluIHRoZSBibG9jaworICAgICAqIEBwYXJhbSBvZmZzZXQgZmlsZSBvZmZzZXQgd2hlcmUgdGhlIGJsb2NrIGlzIHN0b3JlZAorICAgICAqIEBwYXJhbSBkYXRhU2l6ZSB0aGUgdW5jb21wcmVzc2VkIGRhdGEgc2l6ZQorICAgICAqLworICAgIHZvaWQgYWRkKGZpbmFsIGJ5dGVbXSBrZXksIGZpbmFsIGxvbmcgb2Zmc2V0LCBmaW5hbCBpbnQgZGF0YVNpemUpIHsKKyAgICAgIGJsb2NrT2Zmc2V0c1tjb3VudF0gPSBvZmZzZXQ7CisgICAgICBibG9ja0tleXNbY291bnRdID0ga2V5OworICAgICAgYmxvY2tEYXRhU2l6ZXNbY291bnRdID0gZGF0YVNpemU7CisgICAgICBjb3VudCsrOworICAgICAgdGhpcy5zaXplICs9IChCeXRlcy5TSVpFT0ZfSU5UICogMiArIGtleS5sZW5ndGgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBrZXkgS2V5IHRvIGZpbmQKKyAgICAgKiBAcmV0dXJuIE9mZnNldCBvZiBibG9jayBjb250YWluaW5nIDxjb2RlPmtleTwvY29kZT4gb3IgLTEgaWYgdGhpcyBmaWxlCisgICAgICogZG9lcyBub3QgY29udGFpbiB0aGUgcmVxdWVzdC4KKyAgICAgKi8KKyAgICBpbnQgYmxvY2tDb250YWluaW5nS2V5KGZpbmFsIGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKKyAgICAgIGludCBwb3MgPSBCeXRlcy5iaW5hcnlTZWFyY2goYmxvY2tLZXlzLCBrZXksIG9mZnNldCwgbGVuZ3RoLCB0aGlzLmNvbXBhcmF0b3IpOworICAgICAgaWYgKHBvcyA8IDApIHsKKyAgICAgICAgcG9zICsrOworICAgICAgICBwb3MgKj0gLTE7CisgICAgICAgIGlmIChwb3MgPT0gMCkgeworICAgICAgICAgIC8vIGZhbGxzIGJlZm9yZSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlLgorICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICAvLyBXaGVuIHN3aXRjaGVkIHRvICJmaXJzdCBrZXkgaW4gYmxvY2siIGluZGV4LCBiaW5hcnlTZWFyY2ggbm93IHJldHVybnMKKyAgICAgICAgLy8gdGhlIGJsb2NrIHdpdGggYSBmaXJzdEtleSA8IGtleS4gIFRoaXMgbWVhbnMgdGhlIHZhbHVlIHdlIHdhbnQgaXMgcG90ZW50aWFsbHkKKyAgICAgICAgLy8gaW4gdGhlIG5leHQgYmxvY2suCisgICAgICAgIHBvcyAtLTsgLy8gaW4gcHJldmlvdXMgYmxvY2suCisgICAgICAgIAorICAgICAgICByZXR1cm4gcG9zOworICAgICAgfQorICAgICAgLy8gd293LCBhIHBlcmZlY3QgaGl0LCBob3cgdW5saWtlbHk/CisgICAgICByZXR1cm4gcG9zOworICAgIH0KKyAgCisgICAgLyoKKyAgICAgKiBAcmV0dXJuIEZpbGUgbWlka2V5LiAgSW5leGFjdC4gIE9wZXJhdGVzIG9uIGJsb2NrIGJvdW5kYXJpZXMuICBEb2VzCisgICAgICogbm90IGdvIGludG8gYmxvY2tzLgorICAgICAqLworICAgIGJ5dGUgW10gbWlka2V5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGludCBwb3MgPSAoKHRoaXMuY291bnQgLSAxKS8yKTsgICAgICAgICAgICAgIC8vIG1pZGRsZSBvZiB0aGUgaW5kZXgKKyAgICAgIGlmIChwb3MgPCAwKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSEZpbGUgZW1wdHkiKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0aGlzLmJsb2NrS2V5c1twb3NdOworICAgIH0KKworICAgIC8qCisgICAgICogV3JpdGUgb3V0IGluZGV4LiBXaGF0ZXZlciB3ZSB3cml0ZSBoZXJlIG11c3QgamliZSB3aXRoIHdoYXQKKyAgICAgKiBCbG9ja0luZGV4I3JlYWRJbmRleCBpcyBleHBlY3RpbmcuICBNYWtlIHN1cmUgdGhlIHR3byBlbmRzIG9mIHRoZQorICAgICAqIGluZGV4IHNlcmlhbGl6YXRpb24gbWF0Y2guCisgICAgICogQHBhcmFtIG8KKyAgICAgKiBAcGFyYW0ga2V5cworICAgICAqIEBwYXJhbSBvZmZzZXRzCisgICAgICogQHBhcmFtIHNpemVzCisgICAgICogQHBhcmFtIGMKKyAgICAgKiBAcmV0dXJuIFBvc2l0aW9uIGF0IHdoaWNoIHdlIGVudGVyZWQgdGhlIGluZGV4LgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBzdGF0aWMgbG9uZyB3cml0ZUluZGV4KGZpbmFsIEZTRGF0YU91dHB1dFN0cmVhbSBvLAorICAgICAgZmluYWwgTGlzdDxieXRlIFtdPiBrZXlzLCBmaW5hbCBMaXN0PExvbmc+IG9mZnNldHMsCisgICAgICBmaW5hbCBMaXN0PEludGVnZXI+IHNpemVzKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBsb25nIHBvcyA9IG8uZ2V0UG9zKCk7CisgICAgICAvLyBEb24ndCB3cml0ZSBhbiBpbmRleCBpZiBub3RoaW5nIGluIHRoZSBpbmRleC4KKyAgICAgIGlmIChrZXlzLnNpemUoKSA+IDApIHsKKyAgICAgICAgby53cml0ZShJTkRFWEJMT0NLTUFHSUMpOworICAgICAgICAvLyBXcml0ZSB0aGUgaW5kZXguCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5cy5zaXplKCk7ICsraSkgeworICAgICAgICAgIG8ud3JpdGVMb25nKG9mZnNldHMuZ2V0KGkpLmxvbmdWYWx1ZSgpKTsKKyAgICAgICAgICBvLndyaXRlSW50KHNpemVzLmdldChpKS5pbnRWYWx1ZSgpKTsKKyAgICAgICAgICBieXRlIFtdIGtleSA9IGtleXMuZ2V0KGkpOworICAgICAgICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG8sIGtleSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBwb3M7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBSZWFkIGluIHRoZSBpbmRleCB0aGF0IGlzIGF0IDxjb2RlPmluZGV4T2Zmc2V0PC9jb2RlPgorICAgICAqIE11c3QgbWF0Y2ggd2hhdCB3YXMgd3JpdHRlbiBieSB3cml0ZUluZGV4IGluIHRoZSBXcml0ZXIuY2xvc2UuCisgICAgICogQHBhcmFtIGluCisgICAgICogQHBhcmFtIGluZGV4T2Zmc2V0CisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHN0YXRpYyBCbG9ja0luZGV4IHJlYWRJbmRleChmaW5hbCBSYXdDb21wYXJhdG9yPGJ5dGUgW10+IGMsCisgICAgICAgIGZpbmFsIEZTRGF0YUlucHV0U3RyZWFtIGluLCBmaW5hbCBsb25nIGluZGV4T2Zmc2V0LCBmaW5hbCBpbnQgaW5kZXhTaXplKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBCbG9ja0luZGV4IGJpID0gbmV3IEJsb2NrSW5kZXgoYyk7CisgICAgICBiaS5ibG9ja09mZnNldHMgPSBuZXcgbG9uZ1tpbmRleFNpemVdOworICAgICAgYmkuYmxvY2tLZXlzID0gbmV3IGJ5dGVbaW5kZXhTaXplXVtdOworICAgICAgYmkuYmxvY2tEYXRhU2l6ZXMgPSBuZXcgaW50W2luZGV4U2l6ZV07CisgICAgICAvLyBJZiBpbmRleCBzaXplIGlzIHplcm8sIG5vIGluZGV4IHdhcyB3cml0dGVuLgorICAgICAgaWYgKGluZGV4U2l6ZSA+IDApIHsKKyAgICAgICAgaW4uc2VlayhpbmRleE9mZnNldCk7CisgICAgICAgIGJ5dGUgW10gbWFnaWMgPSBuZXcgYnl0ZVtJTkRFWEJMT0NLTUFHSUMubGVuZ3RoXTsKKyAgICAgICAgSU9VdGlscy5yZWFkRnVsbHkoaW4sIG1hZ2ljLCAwLCBtYWdpYy5sZW5ndGgpOworICAgICAgICBpZiAoIUFycmF5cy5lcXVhbHMobWFnaWMsIElOREVYQkxPQ0tNQUdJQykpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkluZGV4IGJsb2NrIG1hZ2ljIGlzIHdyb25nOiAiICsKKyAgICAgICAgICAgIEFycmF5cy50b1N0cmluZyhtYWdpYykpOworICAgICAgICB9CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kZXhTaXplOyArK2kgKSB7CisgICAgICAgICAgbG9uZyBvZmZzZXQgICA9IGluLnJlYWRMb25nKCk7CisgICAgICAgICAgaW50IGRhdGFTaXplICA9IGluLnJlYWRJbnQoKTsKKyAgICAgICAgICBieXRlIFtdIGtleSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgICAgICAgIGJpLmFkZChrZXksIG9mZnNldCwgZGF0YVNpemUpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gYmk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgc2IuYXBwZW5kKCJzaXplPSIgKyBjb3VudCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50IDsgaSsrKSB7CisgICAgICAgIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgICAgc2IuYXBwZW5kKCJrZXk9IikuYXBwZW5kKEJ5dGVzLnRvU3RyaW5nKGJsb2NrS2V5c1tpXSkpLgorICAgICAgICAgIGFwcGVuZCgiLCBvZmZzZXQ9IikuYXBwZW5kKGJsb2NrT2Zmc2V0c1tpXSkuCisgICAgICAgICAgYXBwZW5kKCIsIGRhdGFTaXplPSIgKyBibG9ja0RhdGFTaXplc1tpXSk7CisgICAgICB9CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBoZWFwU2l6ZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnNpemU7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogTWV0YWRhdGEgZm9yIHRoaXMgZmlsZS4gIENvbmp1cmVkIGJ5IHRoZSB3cml0ZXIuICBSZWFkIGluIGJ5IHRoZSByZWFkZXIuCisgICAqLworICBzdGF0aWMgY2xhc3MgRmlsZUluZm8gZXh0ZW5kcyBIYmFzZU1hcFdyaXRhYmxlPGJ5dGUgW10sIGJ5dGUgW10+IHsKKyAgICBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU0VSVkVEX1BSRUZJWCA9ICJoZmlsZS4iOworICAgIHN0YXRpYyBmaW5hbCBieXRlIFtdIExBU1RLRVkgPSBCeXRlcy50b0J5dGVzKFJFU0VSVkVEX1BSRUZJWCArICJMQVNUS0VZIik7CisgICAgc3RhdGljIGZpbmFsIGJ5dGUgW10gQVZHX0tFWV9MRU4gPQorICAgICAgQnl0ZXMudG9CeXRlcyhSRVNFUlZFRF9QUkVGSVggKyAiQVZHX0tFWV9MRU4iKTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBBVkdfVkFMVUVfTEVOID0KKyAgICAgIEJ5dGVzLnRvQnl0ZXMoUkVTRVJWRURfUFJFRklYICsgIkFWR19WQUxVRV9MRU4iKTsKKyAgICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT01QQVJBVE9SID0KKyAgICAgIEJ5dGVzLnRvQnl0ZXMoUkVTRVJWRURfUFJFRklYICsgIkNPTVBBUkFUT1IiKTsKKworICAgIC8qCisgICAgICogQ29uc3RydWN0b3IuCisgICAgICovCisgICAgRmlsZUluZm8oKSB7CisgICAgICBzdXBlcigpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBHZXQgbmFtZXMgb2Ygc3VwcG9ydGVkIGNvbXByZXNzaW9uIGFsZ29yaXRobXMuIFRoZSBuYW1lcyBhcmUgYWNjZXB0YWJsZSBieQorICAgKiBIRmlsZS5Xcml0ZXIuCisgICAqIAorICAgKiBAcmV0dXJuIEFycmF5IG9mIHN0cmluZ3MsIGVhY2ggcmVwcmVzZW50cyBhIHN1cHBvcnRlZCBjb21wcmVzc2lvbgorICAgKiAgICAgICAgIGFsZ29yaXRobS4gQ3VycmVudGx5LCB0aGUgZm9sbG93aW5nIGNvbXByZXNzaW9uIGFsZ29yaXRobXMgYXJlCisgICAqICAgICAgICAgc3VwcG9ydGVkLgorICAgKiAgICAgICAgIDx1bD4KKyAgICogICAgICAgICA8bGk+Im5vbmUiIC0gTm8gY29tcHJlc3Npb24uCisgICAqICAgICAgICAgPGxpPiJneiIgLSBHWklQIGNvbXByZXNzaW9uLgorICAgKiAgICAgICAgIDwvdWw+CisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGdldFN1cHBvcnRlZENvbXByZXNzaW9uQWxnb3JpdGhtcygpIHsKKyAgICByZXR1cm4gQ29tcHJlc3Npb24uZ2V0U3VwcG9ydGVkQWxnb3JpdGhtcygpOworICB9CisKKyAgLy8gVXRpbGl0eSBtZXRob2RzLgorICAvKgorICAgKiBAcGFyYW0gbCBMb25nIHRvIGNvbnZlcnQgdG8gYW4gaW50LgorICAgKiBAcmV0dXJuIDxjb2RlPmw8L2NvZGU+IGNhc3QgYXMgYW4gaW50LgorICAgKi8KKyAgc3RhdGljIGludCBsb25nVG9JbnQoZmluYWwgbG9uZyBsKSB7CisgICAgLy8gRXhwZWN0aW5nIHRoZSBzaXplKCkgb2YgYSBibG9jayBub3QgZXhjZWVkaW5nIDRHQi4gQXNzdW1pbmcgdGhlCisgICAgLy8gc2l6ZSgpIHdpbGwgd3JhcCB0byBuZWdhdGl2ZSBpbnRlZ2VyIGlmIGl0IGV4Y2VlZHMgMkdCIChGcm9tIHRmaWxlKS4KKyAgICByZXR1cm4gKGludCkobCAmIDB4MDAwMDAwMDBmZmZmZmZmZkwpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9IRmlsZVNjYW5uZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL0hGaWxlU2Nhbm5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiOTY3M2QKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9IRmlsZVNjYW5uZXIuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CisKKy8qKgorICogQSBzY2FubmVyIGFsbG93cyB5b3UgdG8gcG9zaXRpb24geW91cnNlbGYgd2l0aGluIGEgSEZpbGUgYW5kCisgKiBzY2FuIHRocm91Z2ggaXQuICBJdCBhbGxvd3MgeW91IHRvIHJlcG9zaXRpb24geW91cnNlbGYgYXMgd2VsbC4KKyAqIAorICogPHA+QSBzY2FubmVyIGRvZXNuJ3QgYWx3YXlzIGhhdmUgYSBrZXkvdmFsdWUgdGhhdCBpdCBpcyBwb2ludGluZyB0bworICogd2hlbiBpdCBpcyBmaXJzdCBjcmVhdGVkIGFuZCBiZWZvcmUKKyAqIHtAbGluayAjc2Vla1RvKCl9L3tAbGluayAjc2Vla1RvKGJ5dGVbXSl9IGFyZSBjYWxsZWQuCisgKiBJbiB0aGlzIGNhc2UsIHtAbGluayAjZ2V0S2V5KCl9L3tAbGluayAjZ2V0VmFsdWUoKX0gcmV0dXJucyBudWxsLiAgQXQgbW9zdAorICogb3RoZXIgdGltZXMsIGEga2V5IGFuZCB2YWx1ZSB3aWxsIGJlIGF2YWlsYWJsZS4gIFRoZSBnZW5lcmFsIHBhdHRlcm4gaXMgdGhhdAorICogeW91IHBvc2l0aW9uIHRoZSBTY2FubmVyIHVzaW5nIHRoZSBzZWVrVG8gdmFyaWFudHMgYW5kIHRoZW4gZ2V0S2V5IGFuZAorICogZ2V0VmFsdWUuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSEZpbGVTY2FubmVyIHsKKyAgLyoqCisgICAqIFNlZWtUbyBvciBqdXN0IGJlZm9yZSB0aGUgcGFzc2VkIDxjb2RlPmtleTwvY29kZT4uICBFeGFtaW5lIHRoZSByZXR1cm4KKyAgICogY29kZSB0byBmaWd1cmUgd2hldGhlciB3ZSBmb3VuZCB0aGUga2V5IG9yIG5vdC4KKyAgICogQ29uc2lkZXIgdGhlIGtleSBzdHJlYW0gb2YgYWxsIHRoZSBrZXlzIGluIHRoZSBmaWxlLCAKKyAgICogPGNvZGU+a1swXSAuLiBrW25dPC9jb2RlPiwgd2hlcmUgdGhlcmUgYXJlIG4ga2V5cyBpbiB0aGUgZmlsZS4KKyAgICogQHBhcmFtIGtleSBLZXkgdG8gZmluZC4KKyAgICogQHJldHVybiAtMSwgaWYga2V5IDwga1swXSwgbm8gcG9zaXRpb247CisgICAqIDAsIHN1Y2ggdGhhdCBrW2ldID0ga2V5IGFuZCBzY2FubmVyIGlzIGxlZnQgaW4gcG9zaXRpb24gaTsgYW5kCisgICAqIDEsIHN1Y2ggdGhhdCBrW2ldIDwga2V5LCBhbmQgc2Nhbm5lciBpcyBsZWZ0IGluIHBvc2l0aW9uIGkuCisgICAqIEZ1cnRoZXJtb3JlLCB0aGVyZSBtYXkgYmUgYSBrW2krMV0sIHN1Y2ggdGhhdCBrW2ldIDwga2V5IDwga1tpKzFdCisgICAqIGJ1dCB0aGVyZSBtYXkgbm90IGJlIGEga1tpKzFdLCBhbmQgbmV4dCgpIHdpbGwgcmV0dXJuIGZhbHNlIChFT0YpLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgaW50IHNlZWtUbyhieXRlW10ga2V5KSB0aHJvd3MgSU9FeGNlcHRpb247CisgIHB1YmxpYyBpbnQgc2Vla1RvKGJ5dGVbXSBrZXksIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgLyoqCisgICAqIENvbnNpZGVyIHRoZSBrZXkgc3RyZWFtIG9mIGFsbCB0aGUga2V5cyBpbiB0aGUgZmlsZSwgCisgICAqIDxjb2RlPmtbMF0gLi4ga1tuXTwvY29kZT4sIHdoZXJlIHRoZXJlIGFyZSBuIGtleXMgaW4gdGhlIGZpbGUuCisgICAqIEBwYXJhbSBrZXkgS2V5IHRvIGZpbmQKKyAgICogQHJldHVybiBmYWxzZSBpZiBrZXkgPD0ga1swXSBvciB0cnVlIHdpdGggc2Nhbm5lciBpbiBwb3NpdGlvbiAnaScgc3VjaAorICAgKiB0aGF0OiBrW2ldIDwga2V5LiAgRnVydGhlcm1vcmU6IHRoZXJlIG1heSBiZSBhIGtbaSsxXSwgc3VjaCB0aGF0CisgICAqIGtbaV0gPCBrZXkgPD0ga1tpKzFdIGJ1dCB0aGVyZSBtYXkgYWxzbyBOT1QgYmUgYSBrW2krMV0sIGFuZCBuZXh0KCkgd2lsbAorICAgKiByZXR1cm4gZmFsc2UgKEVPRikuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHNlZWtCZWZvcmUoYnl0ZSBbXSBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgcHVibGljIGJvb2xlYW4gc2Vla0JlZm9yZShieXRlIFtda2V5LCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIC8qKgorICAgKiBQb3NpdGlvbnMgdGhpcyBzY2FubmVyIGF0IHRoZSBzdGFydCBvZiB0aGUgZmlsZS4KKyAgICogQHJldHVybiBGYWxzZSBpZiBlbXB0eSBmaWxlOyBpLmUuIGEgY2FsbCB0byBuZXh0IHdvdWxkIHJldHVybiBmYWxzZSBhbmQKKyAgICogdGhlIGN1cnJlbnQga2V5IGFuZCB2YWx1ZSBhcmUgdW5kZWZpbmVkLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBzZWVrVG8oKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIC8qKgorICAgKiBTY2FucyB0byB0aGUgbmV4dCBlbnRyeSBpbiB0aGUgZmlsZS4KKyAgICogQHJldHVybiBSZXR1cm5zIGZhbHNlIGlmIHlvdSBhcmUgYXQgdGhlIGVuZCBvdGhlcndpc2UgdHJ1ZSBpZiBtb3JlIGluIGZpbGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIC8qKgorICAgKiBHZXRzIGEgYnVmZmVyIHZpZXcgdG8gdGhlIGN1cnJlbnQga2V5LiBZb3UgbXVzdCBjYWxsCisgICAqIHtAbGluayAjc2Vla1RvKGJ5dGVbXSl9IGJlZm9yZSB0aGlzIG1ldGhvZC4KKyAgICogQHJldHVybiBieXRlIGJ1ZmZlciBmb3IgdGhlIGtleS4gVGhlIGxpbWl0IGlzIHNldCB0byB0aGUga2V5IHNpemUsIGFuZCB0aGUKKyAgICogcG9zaXRpb24gaXMgMCwgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIgdmlldy4KKyAgICovCisgIHB1YmxpYyBCeXRlQnVmZmVyIGdldEtleSgpOworICAvKioKKyAgICogR2V0cyBhIGJ1ZmZlciB2aWV3IHRvIHRoZSBjdXJyZW50IHZhbHVlLiAgWW91IG11c3QgY2FsbAorICAgKiB7QGxpbmsgI3NlZWtUbyhieXRlW10pfSBiZWZvcmUgdGhpcyBtZXRob2QuCisgICAqIAorICAgKiBAcmV0dXJuIGJ5dGUgYnVmZmVyIGZvciB0aGUgdmFsdWUuIFRoZSBsaW1pdCBpcyBzZXQgdG8gdGhlIHZhbHVlIHNpemUsIGFuZAorICAgKiB0aGUgcG9zaXRpb24gaXMgMCwgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIgdmlldy4KKyAgICovCisgIHB1YmxpYyBCeXRlQnVmZmVyIGdldFZhbHVlKCk7CisgIC8qKgorICAgKiBAcmV0dXJuIEluc3RhbmNlIG9mIHtAbGluayBLZXlWYWx1ZX0uCisgICAqLworICBwdWJsaWMgS2V5VmFsdWUgZ2V0S2V5VmFsdWUoKTsKKyAgLyoqCisgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBnZXQgYSBjb3B5IG9mIHRoZSBrZXkgYXMgYSBzdHJpbmcgLSBpbnRlcnByZXRpbmcgdGhlCisgICAqIGJ5dGVzIGFzIFVURjguIFlvdSBtdXN0IGNhbGwge0BsaW5rICNzZWVrVG8oYnl0ZVtdKX0gYmVmb3JlIHRoaXMgbWV0aG9kLgorICAgKiBAcmV0dXJuIGtleSBhcyBhIHN0cmluZworICAgKi8KKyAgcHVibGljIFN0cmluZyBnZXRLZXlTdHJpbmcoKTsKKyAgLyoqCisgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBnZXQgYSBjb3B5IG9mIHRoZSB2YWx1ZSBhcyBhIHN0cmluZyAtIGludGVycHJldGluZworICAgKiB0aGUgYnl0ZXMgYXMgVVRGOC4gWW91IG11c3QgY2FsbCB7QGxpbmsgI3NlZWtUbyhieXRlW10pfSBiZWZvcmUgdGhpcyBtZXRob2QuCisgICAqIEByZXR1cm4gdmFsdWUgYXMgYSBzdHJpbmcKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWVTdHJpbmcoKTsKKyAgLyoqCisgICAqIEByZXR1cm4gUmVhZGVyIHRoYXQgdW5kZXJsaWVzIHRoaXMgU2Nhbm5lciBpbnN0YW5jZS4KKyAgICovCisgIHB1YmxpYyBIRmlsZS5SZWFkZXIgZ2V0UmVhZGVyKCk7CisgIC8qKgorICAgKiBAcmV0dXJuIFRydWUgaXMgc2Nhbm5lciBoYXMgaGFkIG9uZSBvZiB0aGUgc2VlayBjYWxscyBpbnZva2VkOyBpLmUuCisgICAqIHtAbGluayAjc2Vla0JlZm9yZShieXRlW10pfSBvciB7QGxpbmsgI3NlZWtUbygpfSBvciB7QGxpbmsgI3NlZWtUbyhieXRlW10pfS4KKyAgICogT3RoZXJ3aXNlIHJldHVybnMgZmFsc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1NlZWtlZCgpOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1NpbXBsZUJsb2NrQ2FjaGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1NpbXBsZUJsb2NrQ2FjaGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjkzNGUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvU2ltcGxlQmxvY2tDYWNoZS5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGU7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworaW1wb3J0IGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKworLyoqCisgKiBTaW1wbGUgb25lIFJGaWxlIHNvZnQgcmVmZXJlbmNlIGNhY2hlLgorICovCitwdWJsaWMgY2xhc3MgU2ltcGxlQmxvY2tDYWNoZSBpbXBsZW1lbnRzIEJsb2NrQ2FjaGUgeworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWYgZXh0ZW5kcyBTb2Z0UmVmZXJlbmNlPEJ5dGVCdWZmZXI+IHsKKyAgICBwdWJsaWMgU3RyaW5nIGJsb2NrSWQ7CisgICAgcHVibGljIFJlZihTdHJpbmcgYmxvY2tJZCwgQnl0ZUJ1ZmZlciBidWYsIFJlZmVyZW5jZVF1ZXVlIHEpIHsKKyAgICAgIHN1cGVyKGJ1ZiwgcSk7CisgICAgICB0aGlzLmJsb2NrSWQgPSBibG9ja0lkOworICAgIH0KKyAgfQorICBwcml2YXRlIE1hcDxTdHJpbmcsUmVmPiBjYWNoZSA9IAorICAgIG5ldyBIYXNoTWFwPFN0cmluZyxSZWY+KCk7CisKKyAgcHJpdmF0ZSBSZWZlcmVuY2VRdWV1ZSBxID0gbmV3IFJlZmVyZW5jZVF1ZXVlKCk7CisgIHB1YmxpYyBpbnQgZHVtcHMgPSAwOworICAKKyAgcHVibGljIFNpbXBsZUJsb2NrQ2FjaGUoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorICAKKyAgdm9pZCBwcm9jZXNzUXVldWUoKSB7CisgICAgUmVmIHI7CisgICAgd2hpbGUgKCAociA9IChSZWYpcS5wb2xsKCkpICE9IG51bGwpIHsKKyAgICAgIGNhY2hlLnJlbW92ZShyLmJsb2NrSWQpOworICAgICAgZHVtcHMrKzsKKyAgICB9CisgIH0KKworICBwdWJsaWMgc3luY2hyb25pemVkIGludCBzaXplKCkgeworICAgIHByb2Nlc3NRdWV1ZSgpOworICAgIHJldHVybiBjYWNoZS5zaXplKCk7CisgIH0KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgQnl0ZUJ1ZmZlciBnZXRCbG9jayhTdHJpbmcgYmxvY2tOYW1lKSB7CisgICAgcHJvY2Vzc1F1ZXVlKCk7IC8vIGNsZWFyIG91dCBzb21lIGNyYXAuCisgICAgUmVmIHJlZiA9IGNhY2hlLmdldChibG9ja05hbWUpOworICAgIGlmIChyZWYgPT0gbnVsbCkKKyAgICAgIHJldHVybiBudWxsOworICAgIHJldHVybiByZWYuZ2V0KCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNhY2hlQmxvY2soU3RyaW5nIGJsb2NrTmFtZSwgQnl0ZUJ1ZmZlciBidWYpIHsKKyAgICBjYWNoZS5wdXQoYmxvY2tOYW1lLCBuZXcgUmVmKGJsb2NrTmFtZSwgYnVmLCBxKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL3BhY2thZ2UuaHRtbCBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYTkyNDRmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvcGFja2FnZS5odG1sCkBAIC0wLDAgKzEsMjUgQEAKKzwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCAzLjIgRmluYWwvL0VOIj4KKzxodG1sPgorCis8IS0tCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+CisKKzxoZWFkIC8+Cis8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+CitQcm92aWRlcyB0aGUgaGJhc2UgZGF0YStpbmRleCttZXRhZGF0YSBmaWxlLgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlQ2xpZW50LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSEJhc2VDbGllbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTRmNTBjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlQ2xpZW50LmphdmEKQEAgLTAsMCArMSw4NjYgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYzsKKworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXRUaW1lb3V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb247CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOworCitpbXBvcnQgamF2YXgubmV0LlNvY2tldEZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy4qOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLklPVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uT2JqZWN0V3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5EYXRhT3V0cHV0QnVmZmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlwYy5SZW1vdGVFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubmV0Lk5ldFV0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnNlY3VyaXR5LlVzZXJHcm91cEluZm9ybWF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUmVmbGVjdGlvblV0aWxzOworCisvKiogQSBjbGllbnQgZm9yIGFuIElQQyBzZXJ2aWNlLiAgSVBDIGNhbGxzIHRha2UgYSBzaW5nbGUge0BsaW5rIFdyaXRhYmxlfSBhcyBhCisgKiBwYXJhbWV0ZXIsIGFuZCByZXR1cm4gYSB7QGxpbmsgV3JpdGFibGV9IGFzIHRoZWlyIHZhbHVlLiAgQSBzZXJ2aWNlIHJ1bnMgb24KKyAqIGEgcG9ydCBhbmQgaXMgZGVmaW5lZCBieSBhIHBhcmFtZXRlciBjbGFzcyBhbmQgYSB2YWx1ZSBjbGFzcy4KKyAqIAorICogPHA+VGhpcyBpcyB0aGUgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLkNsaWVudCByZW5hbWVkIGFzIEhCYXNlQ2xpZW50IGFuZAorICogbW92ZWQgaW50byB0aGlzIHBhY2thZ2Ugc28gY2FuIGFjY2VzcyBwYWNrYWdlLXByaXZhdGUgbWV0aG9kcy4KKyAqIAorICogQHNlZSBIQmFzZVNlcnZlcgorICovCitwdWJsaWMgY2xhc3MgSEJhc2VDbGllbnQgeworICAKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0KKyAgICBMb2dGYWN0b3J5LmdldExvZygib3JnLmFwYWNoZS5oYWRvb3AuaXBjLkhCYXNlQ2xhc3MiKTsKKyAgcHJvdGVjdGVkIEhhc2h0YWJsZTxDb25uZWN0aW9uSWQsIENvbm5lY3Rpb24+IGNvbm5lY3Rpb25zID0KKyAgICBuZXcgSGFzaHRhYmxlPENvbm5lY3Rpb25JZCwgQ29ubmVjdGlvbj4oKTsKKworICBwcm90ZWN0ZWQgQ2xhc3M8PyBleHRlbmRzIFdyaXRhYmxlPiB2YWx1ZUNsYXNzOyAgIC8vIGNsYXNzIG9mIGNhbGwgdmFsdWVzCisgIHByb3RlY3RlZCBpbnQgY291bnRlcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY291bnRlciBmb3IgY2FsbCBpZHMKKyAgcHJvdGVjdGVkIEF0b21pY0Jvb2xlYW4gcnVubmluZyA9IG5ldyBBdG9taWNCb29sZWFuKHRydWUpOyAvLyBpZiBjbGllbnQgcnVucworICBmaW5hbCBwcm90ZWN0ZWQgQ29uZmlndXJhdGlvbiBjb25mOworICBmaW5hbCBwcm90ZWN0ZWQgaW50IG1heElkbGVUaW1lOyAvL2Nvbm5lY3Rpb25zIHdpbGwgYmUgY3VsbGVkIGlmIGl0IHdhcyBpZGxlIGZvciAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbWF4SWRsZVRpbWUgbXNlY3MKKyAgZmluYWwgcHJvdGVjdGVkIGludCBtYXhSZXRyaWVzOyAvL3RoZSBtYXguIG5vLiBvZiByZXRyaWVzIGZvciBzb2NrZXQgY29ubmVjdGlvbnMKKyAgcHJvdGVjdGVkIGJvb2xlYW4gdGNwTm9EZWxheTsgLy8gaWYgVCB0aGVuIGRpc2FibGUgTmFnbGUncyBBbGdvcml0aG0KKyAgcHJvdGVjdGVkIGludCBwaW5nSW50ZXJ2YWw7IC8vIGhvdyBvZnRlbiBzZW5kcyBwaW5nIHRvIHRoZSBzZXJ2ZXIgaW4gbXNlY3MKKworICBwcm90ZWN0ZWQgU29ja2V0RmFjdG9yeSBzb2NrZXRGYWN0b3J5OyAgICAgICAgICAgLy8gaG93IHRvIGNyZWF0ZSBzb2NrZXRzCisgIHByaXZhdGUgaW50IHJlZkNvdW50ID0gMTsKKyAgCisgIGZpbmFsIHByaXZhdGUgc3RhdGljIFN0cmluZyBQSU5HX0lOVEVSVkFMX05BTUUgPSAiaXBjLnBpbmcuaW50ZXJ2YWwiOworICBmaW5hbCBzdGF0aWMgaW50IERFRkFVTFRfUElOR19JTlRFUlZBTCA9IDYwMDAwOyAvLyAxIG1pbgorICBmaW5hbCBzdGF0aWMgaW50IFBJTkdfQ0FMTF9JRCA9IC0xOworICAKKyAgLyoqCisgICAqIHNldCB0aGUgcGluZyBpbnRlcnZhbCB2YWx1ZSBpbiBjb25maWd1cmF0aW9uCisgICAqIAorICAgKiBAcGFyYW0gY29uZiBDb25maWd1cmF0aW9uCisgICAqIEBwYXJhbSBwaW5nSW50ZXJ2YWwgdGhlIHBpbmcgaW50ZXJ2YWwKKyAgICovCisgIGZpbmFsIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQaW5nSW50ZXJ2YWwoQ29uZmlndXJhdGlvbiBjb25mLCBpbnQgcGluZ0ludGVydmFsKSB7CisgICAgY29uZi5zZXRJbnQoUElOR19JTlRFUlZBTF9OQU1FLCBwaW5nSW50ZXJ2YWwpOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgcGluZyBpbnRlcnZhbCBmcm9tIGNvbmZpZ3VyYXRpb247CisgICAqIElmIG5vdCBzZXQgaW4gdGhlIGNvbmZpZ3VyYXRpb24sIHJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICogCisgICAqIEBwYXJhbSBjb25mIENvbmZpZ3VyYXRpb24KKyAgICogQHJldHVybiB0aGUgcGluZyBpbnRlcnZhbAorICAgKi8KKyAgZmluYWwgc3RhdGljIGludCBnZXRQaW5nSW50ZXJ2YWwoQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgcmV0dXJuIGNvbmYuZ2V0SW50KFBJTkdfSU5URVJWQUxfTkFNRSwgREVGQVVMVF9QSU5HX0lOVEVSVkFMKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEluY3JlbWVudCB0aGlzIGNsaWVudCdzIHJlZmVyZW5jZSBjb3VudAorICAgKgorICAgKi8KKyAgc3luY2hyb25pemVkIHZvaWQgaW5jQ291bnQoKSB7CisgICAgcmVmQ291bnQrKzsKKyAgfQorICAKKyAgLyoqCisgICAqIERlY3JlbWVudCB0aGlzIGNsaWVudCdzIHJlZmVyZW5jZSBjb3VudAorICAgKgorICAgKi8KKyAgc3luY2hyb25pemVkIHZvaWQgZGVjQ291bnQoKSB7CisgICAgcmVmQ291bnQtLTsKKyAgfQorICAKKyAgLyoqCisgICAqIFJldHVybiBpZiB0aGlzIGNsaWVudCBoYXMgbm8gcmVmZXJlbmNlCisgICAqIAorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBjbGllbnQgaGFzIG5vIHJlZmVyZW5jZTsgZmFsc2Ugb3RoZXJ3aXNlCisgICAqLworICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc1plcm9SZWZlcmVuY2UoKSB7CisgICAgcmV0dXJuIHJlZkNvdW50PT0wOworICB9CisKKyAgLyoqIEEgY2FsbCB3YWl0aW5nIGZvciBhIHZhbHVlLiAqLworICBwcml2YXRlIGNsYXNzIENhbGwgeworICAgIGludCBpZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYWxsIGlkCisgICAgV3JpdGFibGUgcGFyYW07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhcmFtZXRlcgorICAgIFdyaXRhYmxlIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2YWx1ZSwgbnVsbCBpZiBlcnJvcgorICAgIElPRXhjZXB0aW9uIGVycm9yOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleGNlcHRpb24sIG51bGwgaWYgdmFsdWUKKyAgICBib29sZWFuIGRvbmU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ1ZSB3aGVuIGNhbGwgaXMgZG9uZQorCisgICAgcHJvdGVjdGVkIENhbGwoV3JpdGFibGUgcGFyYW0pIHsKKyAgICAgIHRoaXMucGFyYW0gPSBwYXJhbTsKKyAgICAgIHN5bmNocm9uaXplZCAoSEJhc2VDbGllbnQudGhpcykgeworICAgICAgICB0aGlzLmlkID0gY291bnRlcisrOworICAgICAgfQorICAgIH0KKworICAgIC8qKiBJbmRpY2F0ZSB3aGVuIHRoZSBjYWxsIGlzIGNvbXBsZXRlIGFuZCB0aGUKKyAgICAgKiB2YWx1ZSBvciBlcnJvciBhcmUgYXZhaWxhYmxlLiAgTm90aWZpZXMgYnkgZGVmYXVsdC4gICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGNhbGxDb21wbGV0ZSgpIHsKKyAgICAgIHRoaXMuZG9uZSA9IHRydWU7CisgICAgICBub3RpZnkoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3RpZnkgY2FsbGVyCisgICAgfQorCisgICAgLyoqIFNldCB0aGUgZXhjZXB0aW9uIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3IuCisgICAgICogTm90aWZ5IHRoZSBjYWxsZXIgdGhlIGNhbGwgaXMgZG9uZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZXJyb3IgZXhjZXB0aW9uIHRocm93biBieSB0aGUgY2FsbDsgZWl0aGVyIGxvY2FsIG9yIHJlbW90ZQorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRFeGNlcHRpb24oSU9FeGNlcHRpb24gZXJyb3IpIHsKKyAgICAgIHRoaXMuZXJyb3IgPSBlcnJvcjsKKyAgICAgIGNhbGxDb21wbGV0ZSgpOworICAgIH0KKyAgICAKKyAgICAvKiogU2V0IHRoZSByZXR1cm4gdmFsdWUgd2hlbiB0aGVyZSBpcyBubyBlcnJvci4gCisgICAgICogTm90aWZ5IHRoZSBjYWxsZXIgdGhlIGNhbGwgaXMgZG9uZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdmFsdWUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsLgorICAgICAqLworICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzZXRWYWx1ZShXcml0YWJsZSB2YWx1ZSkgeworICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgICAgY2FsbENvbXBsZXRlKCk7CisgICAgfQorICB9CisKKyAgLyoqIFRocmVhZCB0aGF0IHJlYWRzIHJlc3BvbnNlcyBhbmQgbm90aWZpZXMgY2FsbGVycy4gIEVhY2ggY29ubmVjdGlvbiBvd25zIGEKKyAgICogc29ja2V0IGNvbm5lY3RlZCB0byBhIHJlbW90ZSBhZGRyZXNzLiAgQ2FsbHMgYXJlIG11bHRpcGxleGVkIHRocm91Z2ggdGhpcworICAgKiBzb2NrZXQ6IHJlc3BvbnNlcyBtYXkgYmUgZGVsaXZlcmVkIG91dCBvZiBvcmRlci4gKi8KKyAgcHJpdmF0ZSBjbGFzcyBDb25uZWN0aW9uIGV4dGVuZHMgVGhyZWFkIHsKKyAgICBwcml2YXRlIENvbm5lY3Rpb25JZCByZW1vdGVJZDsKKyAgICBwcml2YXRlIFNvY2tldCBzb2NrZXQgPSBudWxsOyAgICAgICAgICAgICAgICAgLy8gY29ubmVjdGVkIHNvY2tldAorICAgIHByaXZhdGUgRGF0YUlucHV0U3RyZWFtIGluOworICAgIHByaXZhdGUgRGF0YU91dHB1dFN0cmVhbSBvdXQ7CisgICAgCisgICAgLy8gY3VycmVudGx5IGFjdGl2ZSBjYWxscworICAgIHByaXZhdGUgSGFzaHRhYmxlPEludGVnZXIsIENhbGw+IGNhbGxzID0gbmV3IEhhc2h0YWJsZTxJbnRlZ2VyLCBDYWxsPigpOworICAgIHByaXZhdGUgQXRvbWljTG9uZyBsYXN0QWN0aXZpdHkgPSBuZXcgQXRvbWljTG9uZygpOy8vIGxhc3QgSS9PIGFjdGl2aXR5IHRpbWUKKyAgICBwcm90ZWN0ZWQgQXRvbWljQm9vbGVhbiBzaG91bGRDbG9zZUNvbm5lY3Rpb24gPSBuZXcgQXRvbWljQm9vbGVhbigpOyAgLy8gaW5kaWNhdGUgaWYgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkCisgICAgcHJpdmF0ZSBJT0V4Y2VwdGlvbiBjbG9zZUV4Y2VwdGlvbjsgLy8gY2xvc2UgcmVhc29uCisKKyAgICBwdWJsaWMgQ29ubmVjdGlvbihJbmV0U29ja2V0QWRkcmVzcyBhZGRyZXNzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhuZXcgQ29ubmVjdGlvbklkKGFkZHJlc3MsIG51bGwpKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIENvbm5lY3Rpb24oQ29ubmVjdGlvbklkIHJlbW90ZUlkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHJlbW90ZUlkLmdldEFkZHJlc3MoKS5pc1VucmVzb2x2ZWQoKSkgeworICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkhvc3RFeGNlcHRpb24oInVua25vd24gaG9zdDogIiArIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlSWQuZ2V0QWRkcmVzcygpLmdldEhvc3ROYW1lKCkpOworICAgICAgfQorICAgICAgdGhpcy5yZW1vdGVJZCA9IHJlbW90ZUlkOworICAgICAgVXNlckdyb3VwSW5mb3JtYXRpb24gdGlja2V0ID0gcmVtb3RlSWQuZ2V0VGlja2V0KCk7CisgICAgICB0aGlzLnNldE5hbWUoIklQQyBDbGllbnQgKCIgKyBzb2NrZXRGYWN0b3J5Lmhhc2hDb2RlKCkgKyIpIGNvbm5lY3Rpb24gdG8gIiArCisgICAgICAgIHJlbW90ZUlkLmdldEFkZHJlc3MoKS50b1N0cmluZygpICsKKyAgICAgICAgKCh0aWNrZXQ9PW51bGwpPyIgZnJvbSBhbiB1bmtub3duIHVzZXIiOiAoIiBmcm9tICIgKyB0aWNrZXQuZ2V0VXNlck5hbWUoKSkpKTsKKyAgICAgIHRoaXMuc2V0RGFlbW9uKHRydWUpOworICAgIH0KKworICAgIC8qKiBVcGRhdGUgbGFzdEFjdGl2aXR5IHdpdGggdGhlIGN1cnJlbnQgdGltZS4gKi8KKyAgICBwcml2YXRlIHZvaWQgdG91Y2goKSB7CisgICAgICBsYXN0QWN0aXZpdHkuc2V0KFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgYSBjYWxsIHRvIHRoaXMgY29ubmVjdGlvbidzIGNhbGwgcXVldWUgYW5kIG5vdGlmeQorICAgICAqIGEgbGlzdGVuZXI7IHN5bmNocm9uaXplZC4KKyAgICAgKiBSZXR1cm5zIGZhbHNlIGlmIGNhbGxlZCBkdXJpbmcgc2h1dGRvd24uCisgICAgICogQHBhcmFtIGNhbGwgdG8gYWRkCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBjYWxsIHdhcyBhZGRlZC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIGJvb2xlYW4gYWRkQ2FsbChDYWxsIGNhbGwpIHsKKyAgICAgIGlmIChzaG91bGRDbG9zZUNvbm5lY3Rpb24uZ2V0KCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGNhbGxzLnB1dChjYWxsLmlkLCBjYWxsKTsKKyAgICAgIG5vdGlmeSgpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLyoqIFRoaXMgY2xhc3Mgc2VuZHMgYSBwaW5nIHRvIHRoZSByZW1vdGUgc2lkZSB3aGVuIHRpbWVvdXQgb24KKyAgICAgKiByZWFkaW5nLiBJZiBubyBmYWlsdXJlIGlzIGRldGVjdGVkLCBpdCByZXRyaWVzIHVudGlsIGF0IGxlYXN0CisgICAgICogYSBieXRlIGlzIHJlYWQuCisgICAgICovCisgICAgcHJpdmF0ZSBjbGFzcyBQaW5nSW5wdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJJbnB1dFN0cmVhbSB7CisgICAgICAvKiBjb25zdHJ1Y3RvciAqLworICAgICAgcHJvdGVjdGVkIFBpbmdJbnB1dFN0cmVhbShJbnB1dFN0cmVhbSBpbikgeworICAgICAgICBzdXBlcihpbik7CisgICAgICB9CisKKyAgICAgIC8qIFByb2Nlc3MgdGltZW91dCBleGNlcHRpb24KKyAgICAgICAqIGlmIHRoZSBjb25uZWN0aW9uIGlzIG5vdCBnb2luZyB0byBiZSBjbG9zZWQsIHNlbmQgYSBwaW5nLgorICAgICAgICogb3RoZXJ3aXNlLCB0aHJvdyB0aGUgdGltZW91dCBleGNlcHRpb24uCisgICAgICAgKi8KKyAgICAgIHByaXZhdGUgdm9pZCBoYW5kbGVUaW1lb3V0KFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKHNob3VsZENsb3NlQ29ubmVjdGlvbi5nZXQoKSB8fCAhcnVubmluZy5nZXQoKSkgeworICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICAgICAgc2VuZFBpbmcoKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLyoqIFJlYWQgYSBieXRlIGZyb20gdGhlIHN0cmVhbS4KKyAgICAgICAqIFNlbmQgYSBwaW5nIGlmIHRpbWVvdXQgb24gcmVhZC4gUmV0cmllcyBpZiBubyBmYWlsdXJlIGlzIGRldGVjdGVkCisgICAgICAgKiB1bnRpbCBhIGJ5dGUgaXMgcmVhZC4KKyAgICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gZm9yIGFueSBJTyBwcm9ibGVtIG90aGVyIHRoYW4gc29ja2V0IHRpbWVvdXQKKyAgICAgICAqLworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkbyB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5yZWFkKCk7CisgICAgICAgICAgfSBjYXRjaCAoU29ja2V0VGltZW91dEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBoYW5kbGVUaW1lb3V0KGUpOworICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAodHJ1ZSk7CisgICAgICB9CisKKyAgICAgIC8qKiBSZWFkIGJ5dGVzIGludG8gYSBidWZmZXIgc3RhcnRpbmcgZnJvbSBvZmZzZXQgPGNvZGU+b2ZmPC9jb2RlPgorICAgICAgICogU2VuZCBhIHBpbmcgaWYgdGltZW91dCBvbiByZWFkLiBSZXRyaWVzIGlmIG5vIGZhaWx1cmUgaXMgZGV0ZWN0ZWQKKyAgICAgICAqIHVudGlsIGEgYnl0ZSBpcyByZWFkLgorICAgICAgICogCisgICAgICAgKiBAcmV0dXJuIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZDsgLTEgaWYgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkLgorICAgICAgICovCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYnVmLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBkbyB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJldHVybiBzdXBlci5yZWFkKGJ1Ziwgb2ZmLCBsZW4pOworICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaGFuZGxlVGltZW91dChlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gd2hpbGUgKHRydWUpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICAvKiogQ29ubmVjdCB0byB0aGUgc2VydmVyIGFuZCBzZXQgdXAgdGhlIEkvTyBzdHJlYW1zLiBJdCB0aGVuIHNlbmRzCisgICAgICogYSBoZWFkZXIgdG8gdGhlIHNlcnZlciBhbmQgc3RhcnRzCisgICAgICogdGhlIGNvbm5lY3Rpb24gdGhyZWFkIHRoYXQgd2FpdHMgZm9yIHJlc3BvbnNlcy4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgc2V0dXBJT3N0cmVhbXMoKSB7CisgICAgICBpZiAoc29ja2V0ICE9IG51bGwgfHwgc2hvdWxkQ2xvc2VDb25uZWN0aW9uLmdldCgpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIAorICAgICAgc2hvcnQgaW9GYWlsdXJlcyA9IDA7CisgICAgICBzaG9ydCB0aW1lb3V0RmFpbHVyZXMgPSAwOworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJDb25uZWN0aW5nIHRvICIrcmVtb3RlSWQuZ2V0QWRkcmVzcygpKTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLnNvY2tldCA9IHNvY2tldEZhY3RvcnkuY3JlYXRlU29ja2V0KCk7CisgICAgICAgICAgICB0aGlzLnNvY2tldC5zZXRUY3BOb0RlbGF5KHRjcE5vRGVsYXkpOworICAgICAgICAgICAgLy8gY29ubmVjdGlvbiB0aW1lIG91dCBpcyAyMHMKKyAgICAgICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QocmVtb3RlSWQuZ2V0QWRkcmVzcygpLCAyMDAwMCk7CisgICAgICAgICAgICB0aGlzLnNvY2tldC5zZXRTb1RpbWVvdXQocGluZ0ludGVydmFsKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0gY2F0Y2ggKFNvY2tldFRpbWVvdXRFeGNlcHRpb24gdG9lKSB7CisgICAgICAgICAgICAvKiBUaGUgbWF4IG51bWJlciBvZiByZXRyaWVzIGlzIDQ1LAorICAgICAgICAgICAgICogd2hpY2ggYW1vdW50cyB0byAyMHMqNDUgPSAxNSBtaW51dGVzIHJldHJpZXMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGhhbmRsZUNvbm5lY3Rpb25GYWlsdXJlKHRpbWVvdXRGYWlsdXJlcysrLCA0NSwgdG9lKTsKKyAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgaGFuZGxlQ29ubmVjdGlvbkZhaWx1cmUoaW9GYWlsdXJlcysrLCBtYXhSZXRyaWVzLCBpZSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCdWZmZXJlZElucHV0U3RyZWFtCisgICAgICAgICAgICAobmV3IFBpbmdJbnB1dFN0cmVhbShOZXRVdGlscy5nZXRJbnB1dFN0cmVhbShzb2NrZXQpKSkpOworICAgICAgICB0aGlzLm91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtCisgICAgICAgICAgICAobmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKE5ldFV0aWxzLmdldE91dHB1dFN0cmVhbShzb2NrZXQpKSk7CisgICAgICAgIHdyaXRlSGVhZGVyKCk7CisKKyAgICAgICAgLy8gdXBkYXRlIGxhc3QgYWN0aXZpdHkgdGltZQorICAgICAgICB0b3VjaCgpOworCisgICAgICAgIC8vIHN0YXJ0IHRoZSByZWNlaXZlciB0aHJlYWQgYWZ0ZXIgdGhlIHNvY2tldCBjb25uZWN0aW9uIGhhcyBiZWVuIHNldCB1cAorICAgICAgICBzdGFydCgpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBtYXJrQ2xvc2VkKGUpOworICAgICAgICBjbG9zZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8qIEhhbmRsZSBjb25uZWN0aW9uIGZhaWx1cmVzCisgICAgICoKKyAgICAgKiBJZiB0aGUgY3VycmVudCBudW1iZXIgb2YgcmV0cmllcyBpcyBlcXVhbCB0byB0aGUgbWF4IG51bWJlciBvZiByZXRyaWVzLAorICAgICAqIHN0b3AgcmV0cnlpbmcgYW5kIHRocm93IHRoZSBleGNlcHRpb247IE90aGVyd2lzZSBiYWNrb2ZmIDEgc2Vjb25kIGFuZAorICAgICAqIHRyeSBjb25uZWN0aW5nIGFnYWluLgorICAgICAqCisgICAgICogVGhpcyBNZXRob2QgaXMgb25seSBjYWxsZWQgZnJvbSBpbnNpZGUgc2V0dXBJT3N0cmVhbXMoKSwgd2hpY2ggaXMKKyAgICAgKiBzeW5jaHJvbml6ZWQuIEhlbmNlIHRoZSBzbGVlcCBpcyBzeW5jaHJvbml6ZWQ7IHRoZSBsb2NrcyB3aWxsIGJlIHJldGFpbmVkLgorICAgICAqCisgICAgICogQHBhcmFtIGN1clJldHJpZXMgY3VycmVudCBudW1iZXIgb2YgcmV0cmllcworICAgICAqIEBwYXJhbSBtYXhSZXRyaWVzIG1heCBudW1iZXIgb2YgcmV0cmllcyBhbGxvd2VkCisgICAgICogQHBhcmFtIGlvZSBmYWlsdXJlIHJlYXNvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgbWF4IG51bWJlciBvZiByZXRyaWVzIGlzIHJlYWNoZWQKKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgaGFuZGxlQ29ubmVjdGlvbkZhaWx1cmUoCisgICAgICAgIGludCBjdXJSZXRyaWVzLCBpbnQgbWF4UmV0cmllcywgSU9FeGNlcHRpb24gaW9lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gY2xvc2UgdGhlIGN1cnJlbnQgY29ubmVjdGlvbgorICAgICAgdHJ5IHsKKyAgICAgICAgc29ja2V0LmNsb3NlKCk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy53YXJuKCJOb3QgYWJsZSB0byBjbG9zZSBhIHNvY2tldCIsIGUpOworICAgICAgfQorICAgICAgLy8gc2V0IHNvY2tldCB0byBudWxsIHNvIHRoYXQgdGhlIG5leHQgY2FsbCB0byBzZXR1cElPc3RyZWFtcworICAgICAgLy8gY2FuIHN0YXJ0IHRoZSBwcm9jZXNzIG9mIGNvbm5lY3QgYWxsIG92ZXIgYWdhaW4uCisgICAgICBzb2NrZXQgPSBudWxsOworCisgICAgICAvLyB0aHJvdyB0aGUgZXhjZXB0aW9uIGlmIHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXRyaWVzIGlzIHJlYWNoZWQKKyAgICAgIGlmIChjdXJSZXRyaWVzID49IG1heFJldHJpZXMpIHsKKyAgICAgICAgdGhyb3cgaW9lOworICAgICAgfQorCisgICAgICAvLyBvdGhlcndpc2UgYmFjayBvZmYgYW5kIHJldHJ5CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZ25vcmVkKSB7fQorICAgICAgCisgICAgICBMT0cuaW5mbygiUmV0cnlpbmcgY29ubmVjdCB0byBzZXJ2ZXI6ICIgKyByZW1vdGVJZC5nZXRBZGRyZXNzKCkgKyAKKyAgICAgICAgICAiLiBBbHJlYWR5IHRyaWVkICIgKyBjdXJSZXRyaWVzICsgIiB0aW1lKHMpLiIpOworICAgIH0KKworICAgIC8qIFdyaXRlIHRoZSBoZWFkZXIgZm9yIGVhY2ggY29ubmVjdGlvbgorICAgICAqIE91dCBpcyBub3Qgc3luY2hyb25pemVkIGJlY2F1c2Ugb25seSB0aGUgZmlyc3QgdGhyZWFkIGRvZXMgdGhpcy4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgd3JpdGVIZWFkZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgb3V0LndyaXRlKEhCYXNlU2VydmVyLkhFQURFUi5hcnJheSgpKTsKKyAgICAgIG91dC53cml0ZShIQmFzZVNlcnZlci5DVVJSRU5UX1ZFUlNJT04pOworICAgICAgLy9XaGVuIHRoZXJlIGFyZSBtb3JlIGZpZWxkcyB3ZSBjYW4gaGF2ZSBDb25uZWN0aW9uSGVhZGVyIFdyaXRhYmxlLgorICAgICAgRGF0YU91dHB1dEJ1ZmZlciBidWYgPSBuZXcgRGF0YU91dHB1dEJ1ZmZlcigpOworICAgICAgT2JqZWN0V3JpdGFibGUud3JpdGVPYmplY3QoYnVmLCByZW1vdGVJZC5nZXRUaWNrZXQoKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVc2VyR3JvdXBJbmZvcm1hdGlvbi5jbGFzcywgY29uZik7CisgICAgICBpbnQgYnVmTGVuID0gYnVmLmdldExlbmd0aCgpOworICAgICAgb3V0LndyaXRlSW50KGJ1Zkxlbik7CisgICAgICBvdXQud3JpdGUoYnVmLmdldERhdGEoKSwgMCwgYnVmTGVuKTsKKyAgICB9CisgICAgCisgICAgLyogd2FpdCB0aWxsIHNvbWVvbmUgc2lnbmFscyB1cyB0byBzdGFydCByZWFkaW5nIFJQQyByZXNwb25zZSBvcgorICAgICAqIGl0IGlzIGlkbGUgdG9vIGxvbmcsIGl0IGlzIG1hcmtlZCBhcyB0byBiZSBjbG9zZWQsIAorICAgICAqIG9yIHRoZSBjbGllbnQgaXMgbWFya2VkIGFzIG5vdCBydW5uaW5nLgorICAgICAqIAorICAgICAqIFJldHVybiB0cnVlIGlmIGl0IGlzIHRpbWUgdG8gcmVhZCBhIHJlc3BvbnNlOyBmYWxzZSBvdGhlcndpc2UuCisgICAgICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgYm9vbGVhbiB3YWl0Rm9yV29yaygpIHsKKyAgICAgIGlmIChjYWxscy5pc0VtcHR5KCkgJiYgIXNob3VsZENsb3NlQ29ubmVjdGlvbi5nZXQoKSAgJiYgcnVubmluZy5nZXQoKSkgIHsKKyAgICAgICAgbG9uZyB0aW1lb3V0ID0gbWF4SWRsZVRpbWUtCisgICAgICAgICAgICAgIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKS1sYXN0QWN0aXZpdHkuZ2V0KCkpOworICAgICAgICBpZiAodGltZW91dD4wKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHdhaXQodGltZW91dCk7CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkge30KKyAgICAgICAgfQorICAgICAgfQorICAgICAgCisgICAgICBpZiAoIWNhbGxzLmlzRW1wdHkoKSAmJiAhc2hvdWxkQ2xvc2VDb25uZWN0aW9uLmdldCgpICYmIHJ1bm5pbmcuZ2V0KCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGVsc2UgaWYgKHNob3VsZENsb3NlQ29ubmVjdGlvbi5nZXQoKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9IGVsc2UgaWYgKGNhbGxzLmlzRW1wdHkoKSkgeyAvLyBpZGxlIGNvbm5lY3Rpb24gY2xvc2VkIG9yIHN0b3BwZWQKKyAgICAgICAgbWFya0Nsb3NlZChudWxsKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfSBlbHNlIHsgLy8gZ2V0IHN0b3BwZWQgYnV0IHRoZXJlIGFyZSBzdGlsbCBwZW5kaW5nIHJlcXVlc3RzIAorICAgICAgICBtYXJrQ2xvc2VkKChJT0V4Y2VwdGlvbiluZXcgSU9FeGNlcHRpb24oKS5pbml0Q2F1c2UoCisgICAgICAgICAgICBuZXcgSW50ZXJydXB0ZWRFeGNlcHRpb24oKSkpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIEluZXRTb2NrZXRBZGRyZXNzIGdldFJlbW90ZUFkZHJlc3MoKSB7CisgICAgICByZXR1cm4gcmVtb3RlSWQuZ2V0QWRkcmVzcygpOworICAgIH0KKworICAgIC8qIFNlbmQgYSBwaW5nIHRvIHRoZSBzZXJ2ZXIgaWYgdGhlIHRpbWUgZWxhcHNlZCAKKyAgICAgKiBzaW5jZSBsYXN0IEkvTyBhY3Rpdml0eSBpcyBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gdGhlIHBpbmcgaW50ZXJ2YWwKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgc2VuZFBpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgbG9uZyBjdXJUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICBpZiAoIGN1clRpbWUgLSBsYXN0QWN0aXZpdHkuZ2V0KCkgPj0gcGluZ0ludGVydmFsKSB7CisgICAgICAgIGxhc3RBY3Rpdml0eS5zZXQoY3VyVGltZSk7CisgICAgICAgIHN5bmNocm9uaXplZCAob3V0KSB7CisgICAgICAgICAgb3V0LndyaXRlSW50KFBJTkdfQ0FMTF9JRCk7CisgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpCisgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiBzdGFydGluZywgaGF2aW5nIGNvbm5lY3Rpb25zICIgCisgICAgICAgICAgICArIGNvbm5lY3Rpb25zLnNpemUoKSk7CisKKyAgICAgIHdoaWxlICh3YWl0Rm9yV29yaygpKSB7Ly93YWl0IGhlcmUgZm9yIHdvcmsgLSByZWFkIG9yIGNsb3NlIGNvbm5lY3Rpb24KKyAgICAgICAgcmVjZWl2ZVJlc3BvbnNlKCk7CisgICAgICB9CisgICAgICAKKyAgICAgIGNsb3NlKCk7CisgICAgICAKKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgTE9HLmRlYnVnKGdldE5hbWUoKSArICI6IHN0b3BwZWQsIHJlbWFpbmluZyBjb25uZWN0aW9ucyAiCisgICAgICAgICAgICArIGNvbm5lY3Rpb25zLnNpemUoKSk7CisgICAgfQorCisgICAgLyoqIEluaXRpYXRlcyBhIGNhbGwgYnkgc2VuZGluZyB0aGUgcGFyYW1ldGVyIHRvIHRoZSByZW1vdGUgc2VydmVyLgorICAgICAqIE5vdGU6IHRoaXMgaXMgbm90IGNhbGxlZCBmcm9tIHRoZSBDb25uZWN0aW9uIHRocmVhZCwgYnV0IGJ5IG90aGVyCisgICAgICogdGhyZWFkcy4KKyAgICAgKiBAcGFyYW0gY2FsbAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNlbmRQYXJhbShDYWxsIGNhbGwpIHsKKyAgICAgIGlmIChzaG91bGRDbG9zZUNvbm5lY3Rpb24uZ2V0KCkpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICBEYXRhT3V0cHV0QnVmZmVyIGQ9bnVsbDsKKyAgICAgIHRyeSB7CisgICAgICAgIHN5bmNocm9uaXplZCAodGhpcy5vdXQpIHsKKyAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpCisgICAgICAgICAgICBMT0cuZGVidWcoZ2V0TmFtZSgpICsgIiBzZW5kaW5nICMiICsgY2FsbC5pZCk7CisgICAgICAgICAgCisgICAgICAgICAgLy9mb3Igc2VyaWFsaXppbmcgdGhlCisgICAgICAgICAgLy9kYXRhIHRvIGJlIHdyaXR0ZW4KKyAgICAgICAgICBkID0gbmV3IERhdGFPdXRwdXRCdWZmZXIoKTsKKyAgICAgICAgICBkLndyaXRlSW50KGNhbGwuaWQpOworICAgICAgICAgIGNhbGwucGFyYW0ud3JpdGUoZCk7CisgICAgICAgICAgYnl0ZVtdIGRhdGEgPSBkLmdldERhdGEoKTsKKyAgICAgICAgICBpbnQgZGF0YUxlbmd0aCA9IGQuZ2V0TGVuZ3RoKCk7CisgICAgICAgICAgb3V0LndyaXRlSW50KGRhdGFMZW5ndGgpOyAgICAgIC8vZmlyc3QgcHV0IHRoZSBkYXRhIGxlbmd0aAorICAgICAgICAgIG91dC53cml0ZShkYXRhLCAwLCBkYXRhTGVuZ3RoKTsvL3dyaXRlIHRoZSBkYXRhCisgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgIH0KKyAgICAgIH0gY2F0Y2goSU9FeGNlcHRpb24gZSkgeworICAgICAgICBtYXJrQ2xvc2VkKGUpOworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgLy90aGUgYnVmZmVyIGlzIGp1c3QgYW4gaW4tbWVtb3J5IGJ1ZmZlciwgYnV0IGl0IGlzIHN0aWxsIHBvbGl0ZSB0bworICAgICAgICAvLyBjbG9zZSBlYXJseQorICAgICAgICBJT1V0aWxzLmNsb3NlU3RyZWFtKGQpOworICAgICAgfQorICAgIH0gIAorCisgICAgLyogUmVjZWl2ZSBhIHJlc3BvbnNlLgorICAgICAqIEJlY2F1c2Ugb25seSBvbmUgcmVjZWl2ZXIsIHNvIG5vIHN5bmNocm9uaXphdGlvbiBvbiBpbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcmVjZWl2ZVJlc3BvbnNlKCkgeworICAgICAgaWYgKHNob3VsZENsb3NlQ29ubmVjdGlvbi5nZXQoKSkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICB0b3VjaCgpOworICAgICAgCisgICAgICB0cnkgeworICAgICAgICBpbnQgaWQgPSBpbi5yZWFkSW50KCk7ICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gcmVhZCBhbiBpZAorCisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgICBMT0cuZGVidWcoZ2V0TmFtZSgpICsgIiBnb3QgdmFsdWUgIyIgKyBpZCk7CisKKyAgICAgICAgQ2FsbCBjYWxsID0gY2FsbHMucmVtb3ZlKGlkKTsKKworICAgICAgICBib29sZWFuIGlzRXJyb3IgPSBpbi5yZWFkQm9vbGVhbigpOyAgICAgLy8gcmVhZCBpZiBlcnJvcgorICAgICAgICBpZiAoaXNFcnJvcikgeworICAgICAgICAgIGNhbGwuc2V0RXhjZXB0aW9uKG5ldyBSZW1vdGVFeGNlcHRpb24oIFdyaXRhYmxlVXRpbHMucmVhZFN0cmluZyhpbiksCisgICAgICAgICAgICAgIFdyaXRhYmxlVXRpbHMucmVhZFN0cmluZyhpbikpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBXcml0YWJsZSB2YWx1ZSA9CisgICAgICAgICAgICAoV3JpdGFibGUpIFJlZmxlY3Rpb25VdGlscy5uZXdJbnN0YW5jZSh2YWx1ZUNsYXNzLCBjb25mKTsKKyAgICAgICAgICB2YWx1ZS5yZWFkRmllbGRzKGluKTsgICAgICAgICAgICAgICAgIC8vIHJlYWQgdmFsdWUKKyAgICAgICAgICBjYWxsLnNldFZhbHVlKHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBtYXJrQ2xvc2VkKGUpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIG1hcmtDbG9zZWQoSU9FeGNlcHRpb24gZSkgeworICAgICAgaWYgKHNob3VsZENsb3NlQ29ubmVjdGlvbi5jb21wYXJlQW5kU2V0KGZhbHNlLCB0cnVlKSkgeworICAgICAgICBjbG9zZUV4Y2VwdGlvbiA9IGU7CisgICAgICAgIG5vdGlmeUFsbCgpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICAvKiogQ2xvc2UgdGhlIGNvbm5lY3Rpb24uICovCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBjbG9zZSgpIHsKKyAgICAgIGlmICghc2hvdWxkQ2xvc2VDb25uZWN0aW9uLmdldCgpKSB7CisgICAgICAgIExPRy5lcnJvcigiVGhlIGNvbm5lY3Rpb24gaXMgbm90IGluIHRoZSBjbG9zZWQgc3RhdGUiKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICAvLyByZWxlYXNlIHRoZSByZXNvdXJjZXMKKyAgICAgIC8vIGZpcnN0IHRoaW5nIHRvIGRvO3Rha2UgdGhlIGNvbm5lY3Rpb24gb3V0IG9mIHRoZSBjb25uZWN0aW9uIGxpc3QKKyAgICAgIHN5bmNocm9uaXplZCAoY29ubmVjdGlvbnMpIHsKKyAgICAgICAgaWYgKGNvbm5lY3Rpb25zLmdldChyZW1vdGVJZCkgPT0gdGhpcykgeworICAgICAgICAgIGNvbm5lY3Rpb25zLnJlbW92ZShyZW1vdGVJZCk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLy8gY2xvc2UgdGhlIHN0cmVhbXMgYW5kIHRoZXJlZm9yZSB0aGUgc29ja2V0CisgICAgICBJT1V0aWxzLmNsb3NlU3RyZWFtKG91dCk7CisgICAgICBJT1V0aWxzLmNsb3NlU3RyZWFtKGluKTsKKworICAgICAgLy8gY2xlYW4gdXAgYWxsIGNhbGxzCisgICAgICBpZiAoY2xvc2VFeGNlcHRpb24gPT0gbnVsbCkgeworICAgICAgICBpZiAoIWNhbGxzLmlzRW1wdHkoKSkgeworICAgICAgICAgIExPRy53YXJuKAorICAgICAgICAgICAgICAiQSBjb25uZWN0aW9uIGlzIGNsb3NlZCBmb3Igbm8gY2F1c2UgYW5kIGNhbGxzIGFyZSBub3QgZW1wdHkiKTsKKworICAgICAgICAgIC8vIGNsZWFuIHVwIGNhbGxzIGFueXdheQorICAgICAgICAgIGNsb3NlRXhjZXB0aW9uID0gbmV3IElPRXhjZXB0aW9uKCJVbmV4cGVjdGVkIGNsb3NlZCBjb25uZWN0aW9uIik7CisgICAgICAgICAgY2xlYW51cENhbGxzKCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIGxvZyB0aGUgaW5mbworICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICBMT0cuZGVidWcoImNsb3NpbmcgaXBjIGNvbm5lY3Rpb24gdG8gIiArIHJlbW90ZUlkLmFkZHJlc3MgKyAiOiAiICsKKyAgICAgICAgICAgICAgY2xvc2VFeGNlcHRpb24uZ2V0TWVzc2FnZSgpLGNsb3NlRXhjZXB0aW9uKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNsZWFudXAgY2FsbHMKKyAgICAgICAgY2xlYW51cENhbGxzKCk7CisgICAgICB9CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpCisgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiBjbG9zZWQiKTsKKyAgICB9CisgICAgCisgICAgLyogQ2xlYW51cCBhbGwgY2FsbHMgYW5kIG1hcmsgdGhlbSBhcyBkb25lICovCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFudXBDYWxscygpIHsKKyAgICAgIEl0ZXJhdG9yPEVudHJ5PEludGVnZXIsIENhbGw+PiBpdG9yID0gY2FsbHMuZW50cnlTZXQoKS5pdGVyYXRvcigpIDsKKyAgICAgIHdoaWxlIChpdG9yLmhhc05leHQoKSkgeworICAgICAgICBDYWxsIGMgPSBpdG9yLm5leHQoKS5nZXRWYWx1ZSgpOyAKKyAgICAgICAgYy5zZXRFeGNlcHRpb24oY2xvc2VFeGNlcHRpb24pOyAvLyBsb2NhbCBleGNlcHRpb24KKyAgICAgICAgaXRvci5yZW1vdmUoKTsgICAgICAgICAKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKiogQ2FsbCBpbXBsZW1lbnRhdGlvbiB1c2VkIGZvciBwYXJhbGxlbCBjYWxscy4gKi8KKyAgcHJpdmF0ZSBjbGFzcyBQYXJhbGxlbENhbGwgZXh0ZW5kcyBDYWxsIHsKKyAgICBwcml2YXRlIFBhcmFsbGVsUmVzdWx0cyByZXN1bHRzOworICAgIHByb3RlY3RlZCBpbnQgaW5kZXg7CisgICAgCisgICAgcHVibGljIFBhcmFsbGVsQ2FsbChXcml0YWJsZSBwYXJhbSwgUGFyYWxsZWxSZXN1bHRzIHJlc3VsdHMsIGludCBpbmRleCkgeworICAgICAgc3VwZXIocGFyYW0pOworICAgICAgdGhpcy5yZXN1bHRzID0gcmVzdWx0czsKKyAgICAgIHRoaXMuaW5kZXggPSBpbmRleDsKKyAgICB9CisKKyAgICAvKiogRGVsaXZlciByZXN1bHQgdG8gcmVzdWx0IGNvbGxlY3Rvci4gKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjYWxsQ29tcGxldGUoKSB7CisgICAgICByZXN1bHRzLmNhbGxDb21wbGV0ZSh0aGlzKTsKKyAgICB9CisgIH0KKworICAvKiogUmVzdWx0IGNvbGxlY3RvciBmb3IgcGFyYWxsZWwgY2FsbHMuICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhcmFsbGVsUmVzdWx0cyB7CisgICAgcHJvdGVjdGVkIFdyaXRhYmxlW10gdmFsdWVzOworICAgIHByb3RlY3RlZCBpbnQgc2l6ZTsKKyAgICBwcm90ZWN0ZWQgaW50IGNvdW50OworCisgICAgcHVibGljIFBhcmFsbGVsUmVzdWx0cyhpbnQgc2l6ZSkgeworICAgICAgdGhpcy52YWx1ZXMgPSBuZXcgV3JpdGFibGVbc2l6ZV07CisgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbGxlY3QgYSByZXN1bHQuCisgICAgICogQHBhcmFtIGNhbGwKKyAgICAgKi8KKyAgICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2FsbENvbXBsZXRlKFBhcmFsbGVsQ2FsbCBjYWxsKSB7CisgICAgICB2YWx1ZXNbY2FsbC5pbmRleF0gPSBjYWxsLnZhbHVlOyAgICAgICAgICAgIC8vIHN0b3JlIHRoZSB2YWx1ZQorICAgICAgY291bnQrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCBpdAorICAgICAgaWYgKGNvdW50ID09IHNpemUpICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBhbGwgdmFsdWVzIGFyZSBpbgorICAgICAgICBub3RpZnkoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIG5vdGlmeSB3YWl0aW5nIGNhbGxlcgorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3QgYW4gSVBDIGNsaWVudCB3aG9zZSB2YWx1ZXMgYXJlIG9mIHRoZSBnaXZlbiB7QGxpbmsgV3JpdGFibGV9CisgICAqIGNsYXNzLgorICAgKiBAcGFyYW0gdmFsdWVDbGFzcworICAgKiBAcGFyYW0gY29uZgorICAgKiBAcGFyYW0gZmFjdG9yeQorICAgKi8KKyAgcHVibGljIEhCYXNlQ2xpZW50KENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZT4gdmFsdWVDbGFzcywgQ29uZmlndXJhdGlvbiBjb25mLCAKKyAgICAgIFNvY2tldEZhY3RvcnkgZmFjdG9yeSkgeworICAgIHRoaXMudmFsdWVDbGFzcyA9IHZhbHVlQ2xhc3M7CisgICAgdGhpcy5tYXhJZGxlVGltZSA9IAorICAgICAgY29uZi5nZXRJbnQoImlwYy5jbGllbnQuY29ubmVjdGlvbi5tYXhpZGxldGltZSIsIDEwMDAwKTsgLy8xMHMKKyAgICB0aGlzLm1heFJldHJpZXMgPSBjb25mLmdldEludCgiaXBjLmNsaWVudC5jb25uZWN0Lm1heC5yZXRyaWVzIiwgMTApOworICAgIHRoaXMudGNwTm9EZWxheSA9IGNvbmYuZ2V0Qm9vbGVhbigiaXBjLmNsaWVudC50Y3Bub2RlbGF5IiwgZmFsc2UpOworICAgIHRoaXMucGluZ0ludGVydmFsID0gZ2V0UGluZ0ludGVydmFsKGNvbmYpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJUaGUgcGluZyBpbnRlcnZhbCBpcyIgKyB0aGlzLnBpbmdJbnRlcnZhbCArICJtcy4iKTsKKyAgICB9CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB0aGlzLnNvY2tldEZhY3RvcnkgPSBmYWN0b3J5OworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhbiBJUEMgY2xpZW50IHdpdGggdGhlIGRlZmF1bHQgU29ja2V0RmFjdG9yeQorICAgKiBAcGFyYW0gdmFsdWVDbGFzcworICAgKiBAcGFyYW0gY29uZgorICAgKi8KKyAgcHVibGljIEhCYXNlQ2xpZW50KENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZT4gdmFsdWVDbGFzcywgQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgdGhpcyh2YWx1ZUNsYXNzLCBjb25mLCBOZXRVdGlscy5nZXREZWZhdWx0U29ja2V0RmFjdG9yeShjb25mKSk7CisgIH0KKyAKKyAgLyoqIFJldHVybiB0aGUgc29ja2V0IGZhY3Rvcnkgb2YgdGhpcyBjbGllbnQKKyAgICoKKyAgICogQHJldHVybiB0aGlzIGNsaWVudCdzIHNvY2tldCBmYWN0b3J5CisgICAqLworICBTb2NrZXRGYWN0b3J5IGdldFNvY2tldEZhY3RvcnkoKSB7CisgICAgcmV0dXJuIHNvY2tldEZhY3Rvcnk7CisgIH0KKworICAvKiogU3RvcCBhbGwgdGhyZWFkcyByZWxhdGVkIHRvIHRoaXMgY2xpZW50LiAgTm8gZnVydGhlciBjYWxscyBtYXkgYmUgbWFkZQorICAgKiB1c2luZyB0aGlzIGNsaWVudC4gKi8KKyAgcHVibGljIHZvaWQgc3RvcCgpIHsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiU3RvcHBpbmcgY2xpZW50Iik7CisgICAgfQorCisgICAgaWYgKCFydW5uaW5nLmNvbXBhcmVBbmRTZXQodHJ1ZSwgZmFsc2UpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIC8vIHdha2UgdXAgYWxsIGNvbm5lY3Rpb25zCisgICAgc3luY2hyb25pemVkIChjb25uZWN0aW9ucykgeworICAgICAgZm9yIChDb25uZWN0aW9uIGNvbm4gOiBjb25uZWN0aW9ucy52YWx1ZXMoKSkgeworICAgICAgICBjb25uLmludGVycnVwdCgpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICAvLyB3YWl0IHVudGlsIGFsbCBjb25uZWN0aW9ucyBhcmUgY2xvc2VkCisgICAgd2hpbGUgKCFjb25uZWN0aW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIFRocmVhZC5zbGVlcCgxMDApOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBNYWtlIGEgY2FsbCwgcGFzc2luZyA8Y29kZT5wYXJhbTwvY29kZT4sIHRvIHRoZSBJUEMgc2VydmVyIHJ1bm5pbmcgYXQKKyAgICogPGNvZGU+YWRkcmVzczwvY29kZT4sIHJldHVybmluZyB0aGUgdmFsdWUuICBUaHJvd3MgZXhjZXB0aW9ucyBpZiB0aGVyZSBhcmUKKyAgICogbmV0d29yayBwcm9ibGVtcyBvciBpZiB0aGUgcmVtb3RlIGNvZGUgdGhyZXcgYW4gZXhjZXB0aW9uLiAKKyAgICogQHBhcmFtIHBhcmFtIAorICAgKiBAcGFyYW0gYWRkcmVzcyAKKyAgICogQHJldHVybiBXcml0YWJsZSAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFdyaXRhYmxlIGNhbGwoV3JpdGFibGUgcGFyYW0sIEluZXRTb2NrZXRBZGRyZXNzIGFkZHJlc3MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gY2FsbChwYXJhbSwgYWRkcmVzcywgbnVsbCk7CisgIH0KKyAgCisgIHB1YmxpYyBXcml0YWJsZSBjYWxsKFdyaXRhYmxlIHBhcmFtLCBJbmV0U29ja2V0QWRkcmVzcyBhZGRyLCAKKyAgICAgICAgICAgICAgICAgICAgICAgVXNlckdyb3VwSW5mb3JtYXRpb24gdGlja2V0KSAgCisgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQ2FsbCBjYWxsID0gbmV3IENhbGwocGFyYW0pOworICAgIENvbm5lY3Rpb24gY29ubmVjdGlvbiA9IGdldENvbm5lY3Rpb24oYWRkciwgdGlja2V0LCBjYWxsKTsKKyAgICBjb25uZWN0aW9uLnNlbmRQYXJhbShjYWxsKTsgICAgICAgICAgICAgICAgIC8vIHNlbmQgdGhlIHBhcmFtZXRlcgorICAgIHN5bmNocm9uaXplZCAoY2FsbCkgeworICAgICAgd2hpbGUgKCFjYWxsLmRvbmUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBjYWxsLndhaXQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3YWl0IGZvciB0aGUgcmVzdWx0CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGlnbm9yZWQpIHt9CisgICAgICB9CisKKyAgICAgIGlmIChjYWxsLmVycm9yICE9IG51bGwpIHsKKyAgICAgICAgaWYgKGNhbGwuZXJyb3IgaW5zdGFuY2VvZiBSZW1vdGVFeGNlcHRpb24pIHsKKyAgICAgICAgICBjYWxsLmVycm9yLmZpbGxJblN0YWNrVHJhY2UoKTsKKyAgICAgICAgICB0aHJvdyBjYWxsLmVycm9yOworICAgICAgICB9CisgICAgICAgIC8vIGxvY2FsIGV4Y2VwdGlvbgorICAgICAgICB0aHJvdyB3cmFwRXhjZXB0aW9uKGFkZHIsIGNhbGwuZXJyb3IpOworICAgICAgfQorICAgICAgcmV0dXJuIGNhbGwudmFsdWU7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFRha2UgYW4gSU9FeGNlcHRpb24gYW5kIHRoZSBhZGRyZXNzIHdlIHdlcmUgdHJ5aW5nIHRvIGNvbm5lY3QgdG8KKyAgICogYW5kIHJldHVybiBhbiBJT0V4Y2VwdGlvbiB3aXRoIHRoZSBpbnB1dCBleGNlcHRpb24gYXMgdGhlIGNhdXNlLgorICAgKiBUaGUgbmV3IGV4Y2VwdGlvbiBwcm92aWRlcyB0aGUgc3RhY2sgdHJhY2Ugb2YgdGhlIHBsYWNlIHdoZXJlIAorICAgKiB0aGUgZXhjZXB0aW9uIGlzIHRocm93biBhbmQgc29tZSBleHRyYSBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbi4KKyAgICogSWYgdGhlIGV4Y2VwdGlvbiBpcyBDb25uZWN0RXhjZXB0aW9uIG9yIFNvY2tldFRpbWVvdXRFeGNlcHRpb24sIAorICAgKiByZXR1cm4gYSBuZXcgb25lIG9mIHRoZSBzYW1lIHR5cGU7IE90aGVyd2lzZSByZXR1cm4gYW4gSU9FeGNlcHRpb24uCisgICAqIAorICAgKiBAcGFyYW0gYWRkciB0YXJnZXQgYWRkcmVzcworICAgKiBAcGFyYW0gZXhjZXB0aW9uIHRoZSByZWxldmFudCBleGNlcHRpb24KKyAgICogQHJldHVybiBhbiBleGNlcHRpb24gdG8gdGhyb3cKKyAgICovCisgIHByaXZhdGUgSU9FeGNlcHRpb24gd3JhcEV4Y2VwdGlvbihJbmV0U29ja2V0QWRkcmVzcyBhZGRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJT0V4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgQ29ubmVjdEV4Y2VwdGlvbikgeworICAgICAgLy9jb25uZWN0aW9uIHJlZnVzZWQ7IGluY2x1ZGUgdGhlIGhvc3Q6cG9ydCBpbiB0aGUgZXJyb3IKKyAgICAgIHJldHVybiAoQ29ubmVjdEV4Y2VwdGlvbiluZXcgQ29ubmVjdEV4Y2VwdGlvbigKKyAgICAgICAgICAgIkNhbGwgdG8gIiArIGFkZHIgKyAiIGZhaWxlZCBvbiBjb25uZWN0aW9uIGV4Y2VwdGlvbjogIiArIGV4Y2VwdGlvbikKKyAgICAgICAgICAgICAgICAgICAgLmluaXRDYXVzZShleGNlcHRpb24pOworICAgIH0gZWxzZSBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgU29ja2V0VGltZW91dEV4Y2VwdGlvbikgeworICAgICAgcmV0dXJuIChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKW5ldyBTb2NrZXRUaW1lb3V0RXhjZXB0aW9uKAorICAgICAgICAgICAiQ2FsbCB0byAiICsgYWRkciArICIgZmFpbGVkIG9uIHNvY2tldCB0aW1lb3V0IGV4Y2VwdGlvbjogIgorICAgICAgICAgICAgICAgICAgICAgICsgZXhjZXB0aW9uKS5pbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIChJT0V4Y2VwdGlvbiluZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICJDYWxsIHRvICIgKyBhZGRyICsgIiBmYWlsZWQgb24gbG9jYWwgZXhjZXB0aW9uOiAiICsgZXhjZXB0aW9uKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmluaXRDYXVzZShleGNlcHRpb24pOworCisgICAgfQorICB9CisKKyAgLyoqIE1ha2VzIGEgc2V0IG9mIGNhbGxzIGluIHBhcmFsbGVsLiAgRWFjaCBwYXJhbWV0ZXIgaXMgc2VudCB0byB0aGUKKyAgICogY29ycmVzcG9uZGluZyBhZGRyZXNzLiAgV2hlbiBhbGwgdmFsdWVzIGFyZSBhdmFpbGFibGUsIG9yIGhhdmUgdGltZWQgb3V0CisgICAqIG9yIGVycm9yZWQsIHRoZSBjb2xsZWN0ZWQgcmVzdWx0cyBhcmUgcmV0dXJuZWQgaW4gYW4gYXJyYXkuICBUaGUgYXJyYXkKKyAgICogY29udGFpbnMgbnVsbHMgZm9yIGNhbGxzIHRoYXQgdGltZWQgb3V0IG9yIGVycm9yZWQuICAKKyAgICogQHBhcmFtIHBhcmFtcyAKKyAgICogQHBhcmFtIGFkZHJlc3NlcyAKKyAgICogQHJldHVybiAgV3JpdGFibGVbXQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgV3JpdGFibGVbXSBjYWxsKFdyaXRhYmxlW10gcGFyYW1zLCBJbmV0U29ja2V0QWRkcmVzc1tdIGFkZHJlc3NlcykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChhZGRyZXNzZXMubGVuZ3RoID09IDApIHJldHVybiBuZXcgV3JpdGFibGVbMF07CisKKyAgICBQYXJhbGxlbFJlc3VsdHMgcmVzdWx0cyA9IG5ldyBQYXJhbGxlbFJlc3VsdHMocGFyYW1zLmxlbmd0aCk7CisgICAgc3luY2hyb25pemVkIChyZXN1bHRzKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykgeworICAgICAgICBQYXJhbGxlbENhbGwgY2FsbCA9IG5ldyBQYXJhbGxlbENhbGwocGFyYW1zW2ldLCByZXN1bHRzLCBpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBnZXRDb25uZWN0aW9uKGFkZHJlc3Nlc1tpXSwgbnVsbCwgY2FsbCk7CisgICAgICAgICAgY29ubmVjdGlvbi5zZW5kUGFyYW0oY2FsbCk7ICAgICAgICAgICAgIC8vIHNlbmQgZWFjaCBwYXJhbWV0ZXIKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGxvZyBlcnJvcnMKKyAgICAgICAgICBMT0cuaW5mbygiQ2FsbGluZyAiK2FkZHJlc3Nlc1tpXSsiIGNhdWdodDogIiArIAorICAgICAgICAgICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpLGUpOworICAgICAgICAgIHJlc3VsdHMuc2l6ZS0tOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgd2FpdCBmb3Igb25lIGZld2VyIHJlc3VsdAorICAgICAgICB9CisgICAgICB9CisgICAgICB3aGlsZSAocmVzdWx0cy5jb3VudCAhPSByZXN1bHRzLnNpemUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHRzLndhaXQoKTsgICAgICAgICAgICAgICAgICAgIC8vIHdhaXQgZm9yIGFsbCByZXN1bHRzCisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHt9CisgICAgICB9CisKKyAgICAgIHJldHVybiByZXN1bHRzLnZhbHVlczsKKyAgICB9CisgIH0KKworICAvKiogR2V0IGEgY29ubmVjdGlvbiBmcm9tIHRoZSBwb29sLCBvciBjcmVhdGUgYSBuZXcgb25lIGFuZCBhZGQgaXQgdG8gdGhlCisgICAqIHBvb2wuICBDb25uZWN0aW9ucyB0byBhIGdpdmVuIGhvc3QvcG9ydCBhcmUgcmV1c2VkLiAqLworICBwcml2YXRlIENvbm5lY3Rpb24gZ2V0Q29ubmVjdGlvbihJbmV0U29ja2V0QWRkcmVzcyBhZGRyLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNlckdyb3VwSW5mb3JtYXRpb24gdGlja2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDYWxsIGNhbGwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCFydW5uaW5nLmdldCgpKSB7CisgICAgICAvLyB0aGUgY2xpZW50IGlzIHN0b3BwZWQKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGhlIGNsaWVudCBpcyBzdG9wcGVkIik7CisgICAgfQorICAgIENvbm5lY3Rpb24gY29ubmVjdGlvbjsKKyAgICAvKiB3ZSBjb3VsZCBhdm9pZCB0aGlzIGFsbG9jYXRpb24gZm9yIGVhY2ggUlBDIGJ5IGhhdmluZyBhICAKKyAgICAgKiBjb25uZWN0aW9uc0lkIG9iamVjdCBhbmQgd2l0aCBzZXQoKSBtZXRob2QuIFdlIG5lZWQgdG8gbWFuYWdlIHRoZQorICAgICAqIHJlZnMgZm9yIGtleXMgaW4gSGFzaE1hcCBwcm9wZXJseS4gRm9yIG5vdyBpdHMgb2suCisgICAgICovCisgICAgQ29ubmVjdGlvbklkIHJlbW90ZUlkID0gbmV3IENvbm5lY3Rpb25JZChhZGRyLCB0aWNrZXQpOworICAgIGRvIHsKKyAgICAgIHN5bmNocm9uaXplZCAoY29ubmVjdGlvbnMpIHsKKyAgICAgICAgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zLmdldChyZW1vdGVJZCk7CisgICAgICAgIGlmIChjb25uZWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgICBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24ocmVtb3RlSWQpOworICAgICAgICAgIGNvbm5lY3Rpb25zLnB1dChyZW1vdGVJZCwgY29ubmVjdGlvbik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IHdoaWxlICghY29ubmVjdGlvbi5hZGRDYWxsKGNhbGwpKTsKKyAgICAKKyAgICAvL3dlIGRvbid0IGludm9rZSB0aGUgbWV0aG9kIGJlbG93IGluc2lkZSAic3luY2hyb25pemVkIChjb25uZWN0aW9ucykiCisgICAgLy9ibG9jayBhYm92ZS4gVGhlIHJlYXNvbiBmb3IgdGhhdCBpcyBpZiB0aGUgc2VydmVyIGhhcHBlbnMgdG8gYmUgc2xvdywKKyAgICAvL2l0IHdpbGwgdGFrZSBsb25nZXIgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiBhbmQgdGhhdCB3aWxsIHNsb3cgdGhlCisgICAgLy9lbnRpcmUgc3lzdGVtIGRvd24uCisgICAgY29ubmVjdGlvbi5zZXR1cElPc3RyZWFtcygpOworICAgIHJldHVybiBjb25uZWN0aW9uOworICB9CisKKyAgLyoqCisgICAqIFRoaXMgY2xhc3MgaG9sZHMgdGhlIGFkZHJlc3MgYW5kIHRoZSB1c2VyIHRpY2tldC4gVGhlIGNsaWVudCBjb25uZWN0aW9ucworICAgKiB0byBzZXJ2ZXJzIGFyZSB1bmlxdWVseSBpZGVudGlmaWVkIGJ5IDxyZW1vdGVBZGRyZXNzLCB0aWNrZXQ+CisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDb25uZWN0aW9uSWQgeworICAgIEluZXRTb2NrZXRBZGRyZXNzIGFkZHJlc3M7CisgICAgVXNlckdyb3VwSW5mb3JtYXRpb24gdGlja2V0OworICAgIAorICAgIENvbm5lY3Rpb25JZChJbmV0U29ja2V0QWRkcmVzcyBhZGRyZXNzLCBVc2VyR3JvdXBJbmZvcm1hdGlvbiB0aWNrZXQpIHsKKyAgICAgIHRoaXMuYWRkcmVzcyA9IGFkZHJlc3M7CisgICAgICB0aGlzLnRpY2tldCA9IHRpY2tldDsKKyAgICB9CisgICAgCisgICAgSW5ldFNvY2tldEFkZHJlc3MgZ2V0QWRkcmVzcygpIHsKKyAgICAgIHJldHVybiBhZGRyZXNzOworICAgIH0KKyAgICBVc2VyR3JvdXBJbmZvcm1hdGlvbiBnZXRUaWNrZXQoKSB7CisgICAgICByZXR1cm4gdGlja2V0OworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ29ubmVjdGlvbklkKSB7CisgICAgICAgQ29ubmVjdGlvbklkIGlkID0gKENvbm5lY3Rpb25JZCkgb2JqOworICAgICAgIHJldHVybiBhZGRyZXNzLmVxdWFscyhpZC5hZGRyZXNzKSAmJiB0aWNrZXQgPT0gaWQudGlja2V0OworICAgICAgIC8vTm90ZSA6IHRpY2tldCBpcyBhIHJlZiBjb21wYXJpc2lvbi4KKyAgICAgfQorICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gYWRkcmVzcy5oYXNoQ29kZSgpIF4gU3lzdGVtLmlkZW50aXR5SGFzaENvZGUodGlja2V0KTsKKyAgICB9CisgIH0gIAorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlUlBDLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSEJhc2VSUEMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjE2NTU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlUlBDLmphdmEKQEAgLTAsMCArMSw2ODEgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYzsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25IYW5kbGVyOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LlByb3h5OworaW1wb3J0IGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0VGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IGphdmF4Lm5ldC5Tb2NrZXRGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5SZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlT2JqZWN0V3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlZlcnNpb25lZFByb3RvY29sOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm5ldC5OZXRVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5zZWN1cml0eS5Vc2VyR3JvdXBJbmZvcm1hdGlvbjsKKworLyoqIEEgc2ltcGxlIFJQQyBtZWNoYW5pc20uCisgKgorICogVGhpcyBpcyBhIGxvY2FsIGhiYXNlIGNvcHkgb2YgdGhlIGhhZG9vcCBSUEMgc28gd2UgY2FuIGRvIHRoaW5ncyBsaWtlCisgKiBhZGRyZXNzIEhBRE9PUC00MTQgZm9yIGhiYXNlLW9ubHkgYW5kIHRyeSBvdGhlciBoYmFzZS1zcGVjaWZpYworICogb3B0aW1pemF0aW9ucyBsaWtlIHVzaW5nIG91ciBvd24gdmVyc2lvbiBvZiBPYmplY3RXcml0YWJsZS4gIENsYXNzIGhhcyBiZWVuCisgKiByZW5hbWVkIHRvIGF2b2lkIGNvbmZ1c2luZyBpdCB3LyBoYWRvb3AgdmVyc2lvbnMuCisgKiA8cD4KKyAqIAorICoKKyAqIEEgPGk+cHJvdG9jb2w8L2k+IGlzIGEgSmF2YSBpbnRlcmZhY2UuICBBbGwgcGFyYW1ldGVycyBhbmQgcmV0dXJuIHR5cGVzIG11c3QKKyAqIGJlIG9uZSBvZjoKKyAqCisgKiA8dWw+IDxsaT5hIHByaW1pdGl2ZSB0eXBlLCA8Y29kZT5ib29sZWFuPC9jb2RlPiwgPGNvZGU+Ynl0ZTwvY29kZT4sCisgKiA8Y29kZT5jaGFyPC9jb2RlPiwgPGNvZGU+c2hvcnQ8L2NvZGU+LCA8Y29kZT5pbnQ8L2NvZGU+LCA8Y29kZT5sb25nPC9jb2RlPiwKKyAqIDxjb2RlPmZsb2F0PC9jb2RlPiwgPGNvZGU+ZG91YmxlPC9jb2RlPiwgb3IgPGNvZGU+dm9pZDwvY29kZT47IG9yPC9saT4KKyAqCisgKiA8bGk+YSB7QGxpbmsgU3RyaW5nfTsgb3I8L2xpPgorICoKKyAqIDxsaT5hIHtAbGluayBXcml0YWJsZX07IG9yPC9saT4KKyAqCisgKiA8bGk+YW4gYXJyYXkgb2YgdGhlIGFib3ZlIHR5cGVzPC9saT4gPC91bD4KKyAqCisgKiBBbGwgbWV0aG9kcyBpbiB0aGUgcHJvdG9jb2wgc2hvdWxkIHRocm93IG9ubHkgSU9FeGNlcHRpb24uICBObyBmaWVsZCBkYXRhIG9mCisgKiB0aGUgcHJvdG9jb2wgaW5zdGFuY2UgaXMgdHJhbnNtaXR0ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBIQmFzZVJQQyB7CisgIC8vIExlYXZlIHRoaXMgb3V0IGluIHRoZSBoYWRvb3AgaXBjIHBhY2thZ2UgYnV0IGtlZXAgY2xhc3MgbmFtZS4gIERvIHRoaXMKKyAgLy8gc28gdGhhdCB3ZSBkb250JyBnZXQgdGhlIGxvZ2dpbmcgb2YgdGhpcyBjbGFzcydzIGludm9jYXRpb25zIGJ5IGRvaW5nIG91cgorICAvLyBibGFua2V0IGVuYWJsaW5nIERFQlVHIG9uIHRoZSBvLmEuaC5oLiBwYWNrYWdlLgorICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIExvZyBMT0cgPQorICAgIExvZ0ZhY3RvcnkuZ2V0TG9nKCJvcmcuYXBhY2hlLmhhZG9vcC5pcGMuSGJhc2VSUEMiKTsKKworICBwcml2YXRlIEhCYXNlUlBDKCkgeworICAgIHN1cGVyKCk7CisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gcHVibGljIGN0b3IKKworCisgIC8qKiBBIG1ldGhvZCBpbnZvY2F0aW9uLCBpbmNsdWRpbmcgdGhlIG1ldGhvZCBuYW1lIGFuZCBpdHMgcGFyYW1ldGVycy4qLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbnZvY2F0aW9uIGltcGxlbWVudHMgV3JpdGFibGUsIENvbmZpZ3VyYWJsZSB7CisgICAgLy8gSGVyZSwgZm9yIGhiYXNlLCB3ZSBtYWludGFpbiB0d28gc3RhdGljIG1hcHMgb2YgbWV0aG9kIG5hbWVzIHRvIGNvZGUgYW5kCisgICAgLy8gdmljZSB2ZXJzYS4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8Qnl0ZSwgU3RyaW5nPiBDT0RFX1RPX01FVEhPRE5BTUUgPQorICAgICAgbmV3IEhhc2hNYXA8Qnl0ZSwgU3RyaW5nPigpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsIEJ5dGU+IE1FVEhPRE5BTUVfVE9fQ09ERSA9CisgICAgICBuZXcgSGFzaE1hcDxTdHJpbmcsIEJ5dGU+KCk7CisgICAgLy8gU3BlY2lhbCBjb2RlIHRoYXQgbWVhbnMgJ25vdC1lbmNvZGVkJy4KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIE5PVF9FTkNPREVEID0gMDsKKyAgICBzdGF0aWMgeworICAgICAgYnl0ZSBjb2RlID0gTk9UX0VOQ09ERUQgKyAxOworICAgICAgY29kZSA9IGFkZFRvTWFwKFZlcnNpb25lZFByb3RvY29sLmNsYXNzLCBjb2RlKTsKKyAgICAgIGNvZGUgPSBhZGRUb01hcChITWFzdGVySW50ZXJmYWNlLmNsYXNzLCBjb2RlKTsKKyAgICAgIGNvZGUgPSBhZGRUb01hcChITWFzdGVyUmVnaW9uSW50ZXJmYWNlLmNsYXNzLCBjb2RlKTsKKyAgICAgIGNvZGUgPSBhZGRUb01hcChUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlLmNsYXNzLCBjb2RlKTsKKyAgICB9CisgICAgLy8gRW5kIG9mIGhiYXNlIG1vZGlmaWNhdGlvbnMuCisKKyAgICBwcml2YXRlIFN0cmluZyBtZXRob2ROYW1lOworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIHByaXZhdGUgQ2xhc3NbXSBwYXJhbWV0ZXJDbGFzc2VzOworICAgIHByaXZhdGUgT2JqZWN0W10gcGFyYW1ldGVyczsKKyAgICBwcml2YXRlIENvbmZpZ3VyYXRpb24gY29uZjsKKworICAgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgICAgcHVibGljIEludm9jYXRpb24oKSB7CisgICAgICBzdXBlcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBtZXRob2QKKyAgICAgKiBAcGFyYW0gcGFyYW1ldGVycworICAgICAqLworICAgIHB1YmxpYyBJbnZvY2F0aW9uKE1ldGhvZCBtZXRob2QsIE9iamVjdFtdIHBhcmFtZXRlcnMpIHsKKyAgICAgIHRoaXMubWV0aG9kTmFtZSA9IG1ldGhvZC5nZXROYW1lKCk7CisgICAgICB0aGlzLnBhcmFtZXRlckNsYXNzZXMgPSBtZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKKyAgICAgIHRoaXMucGFyYW1ldGVycyA9IHBhcmFtZXRlcnM7CisgICAgfQorCisgICAgLyoqIEByZXR1cm4gVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCBpbnZva2VkLiAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWV0aG9kTmFtZSgpIHsgcmV0dXJuIG1ldGhvZE5hbWU7IH0KKworICAgIC8qKiBAcmV0dXJuIFRoZSBwYXJhbWV0ZXIgY2xhc3Nlcy4gKi8KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBwdWJsaWMgQ2xhc3NbXSBnZXRQYXJhbWV0ZXJDbGFzc2VzKCkgeyByZXR1cm4gcGFyYW1ldGVyQ2xhc3NlczsgfQorCisgICAgLyoqIEByZXR1cm4gVGhlIHBhcmFtZXRlciBpbnN0YW5jZXMuICovCisgICAgcHVibGljIE9iamVjdFtdIGdldFBhcmFtZXRlcnMoKSB7IHJldHVybiBwYXJhbWV0ZXJzOyB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkRmllbGRzKERhdGFJbnB1dCBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGJ5dGUgY29kZSA9IGluLnJlYWRCeXRlKCk7CisgICAgICBtZXRob2ROYW1lID0gQ09ERV9UT19NRVRIT0ROQU1FLmdldChCeXRlLnZhbHVlT2YoY29kZSkpOworICAgICAgcGFyYW1ldGVycyA9IG5ldyBPYmplY3RbaW4ucmVhZEludCgpXTsKKyAgICAgIHBhcmFtZXRlckNsYXNzZXMgPSBuZXcgQ2xhc3NbcGFyYW1ldGVycy5sZW5ndGhdOworICAgICAgSGJhc2VPYmplY3RXcml0YWJsZSBvYmplY3RXcml0YWJsZSA9IG5ldyBIYmFzZU9iamVjdFdyaXRhYmxlKCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgcGFyYW1ldGVyc1tpXSA9IEhiYXNlT2JqZWN0V3JpdGFibGUucmVhZE9iamVjdChpbiwgb2JqZWN0V3JpdGFibGUsCisgICAgICAgICAgdGhpcy5jb25mKTsKKyAgICAgICAgcGFyYW1ldGVyQ2xhc3Nlc1tpXSA9IG9iamVjdFdyaXRhYmxlLmdldERlY2xhcmVkQ2xhc3MoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHdyaXRlTWV0aG9kTmFtZUNvZGUob3V0LCB0aGlzLm1ldGhvZE5hbWUpOworICAgICAgb3V0LndyaXRlSW50KHBhcmFtZXRlckNsYXNzZXMubGVuZ3RoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ2xhc3Nlcy5sZW5ndGg7IGkrKykgeworICAgICAgICBIYmFzZU9iamVjdFdyaXRhYmxlLndyaXRlT2JqZWN0KG91dCwgcGFyYW1ldGVyc1tpXSwgcGFyYW1ldGVyQ2xhc3Nlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1aWxkZXIoMjU2KTsKKyAgICAgIGJ1ZmZlci5hcHBlbmQobWV0aG9kTmFtZSk7CisgICAgICBidWZmZXIuYXBwZW5kKCIoIik7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgaWYgKGkgIT0gMCkKKyAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsICIpOworICAgICAgICBidWZmZXIuYXBwZW5kKHBhcmFtZXRlcnNbaV0pOworICAgICAgfQorICAgICAgYnVmZmVyLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbmYoQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgICB0aGlzLmNvbmYgPSBjb25mOworICAgIH0KKworICAgIHB1YmxpYyBDb25maWd1cmF0aW9uIGdldENvbmYoKSB7CisgICAgICByZXR1cm4gdGhpcy5jb25mOworICAgIH0KKyAgICAKKyAgICAvLyBIYmFzZSBhZGRpdGlvbnMuCisgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhZGRUb01hcChmaW5hbCBTdHJpbmcgbmFtZSwgZmluYWwgYnl0ZSBjb2RlKSB7CisgICAgICBpZiAoTUVUSE9ETkFNRV9UT19DT0RFLmNvbnRhaW5zS2V5KG5hbWUpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIE1FVEhPRE5BTUVfVE9fQ09ERS5wdXQobmFtZSwgQnl0ZS52YWx1ZU9mKGNvZGUpKTsKKyAgICAgIENPREVfVE9fTUVUSE9ETkFNRS5wdXQoQnl0ZS52YWx1ZU9mKGNvZGUpLCBuYW1lKTsKKyAgICB9CisgICAgCisgICAgLyoKKyAgICAgKiBAcGFyYW0gYyBDbGFzcyB3aG9zZSBtZXRob2RzIHdlJ2xsIGFkZCB0byB0aGUgbWFwIG9mIG1ldGhvZHMgdG8gY29kZXMKKyAgICAgKiAoYW5kIHZpY2UgdmVyc2EpLgorICAgICAqIEBwYXJhbSBjb2RlIEN1cnJlbnQgc3RhdGUgb2YgdGhlIGJ5dGUgY29kZS4KKyAgICAgKiBAcmV0dXJuIFN0YXRlIG9mIDxjb2RlPmNvZGU8L2NvZGU+IHdoZW4gdGhpcyBtZXRob2QgaXMgZG9uZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBieXRlIGFkZFRvTWFwKGZpbmFsIENsYXNzPD8+IGMsIGZpbmFsIGJ5dGUgY29kZSkgeworICAgICAgYnl0ZSBsb2NhbENvZGUgPSBjb2RlOworICAgICAgTWV0aG9kIFtdIG1ldGhvZHMgPSBjLmdldE1ldGhvZHMoKTsKKyAgICAgIC8vIFRoZXJlIGFyZSBubyBndWFyYW50ZWVzIGFib3V0IHRoZSBvcmRlciBpbiB3aGljaCBpdGVtcyBhcmUgcmV0dXJuZWQgaW4KKyAgICAgIC8vIHNvIGRvIGEgc29ydCAoV2FzIHNlZWluZyB0aGF0IHNvcnQgd2FzIG9uZSB3YXkgb24gb25lIHNlcnZlciBhbmQgdGhlbgorICAgICAgLy8gYW5vdGhlciBvbiBkaWZmZXJlbnQgc2VydmVyKS4KKyAgICAgIEFycmF5cy5zb3J0KG1ldGhvZHMsIG5ldyBDb21wYXJhdG9yPE1ldGhvZD4oKSB7CisgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShNZXRob2QgbGVmdCwgTWV0aG9kIHJpZ2h0KSB7CisgICAgICAgICAgcmV0dXJuIGxlZnQuZ2V0TmFtZSgpLmNvbXBhcmVUbyhyaWdodC5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgICB9KTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgeworICAgICAgICBhZGRUb01hcChtZXRob2RzW2ldLmdldE5hbWUoKSwgbG9jYWxDb2RlKyspOworICAgICAgfQorICAgICAgcmV0dXJuIGxvY2FsQ29kZTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFdyaXRlIG91dCB0aGUgY29kZSBieXRlIGZvciBwYXNzZWQgQ2xhc3MuCisgICAgICogQHBhcmFtIG91dAorICAgICAqIEBwYXJhbSBjCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHdyaXRlTWV0aG9kTmFtZUNvZGUoZmluYWwgRGF0YU91dHB1dCBvdXQsIGZpbmFsIFN0cmluZyBtZXRob2RuYW1lKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBCeXRlIGNvZGUgPSBNRVRIT0ROQU1FX1RPX0NPREUuZ2V0KG1ldGhvZG5hbWUpOworICAgICAgaWYgKGNvZGUgPT0gbnVsbCkgeworICAgICAgICBMT0cuZXJyb3IoIlVuc3VwcG9ydGVkIHR5cGUgIiArIG1ldGhvZG5hbWUpOworICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIk5vIGNvZGUgZm9yIHVuZXhwZWN0ZWQgIiArCisgICAgICAgICAgbWV0aG9kbmFtZSk7CisgICAgICB9CisgICAgICBvdXQud3JpdGVCeXRlKGNvZGUuYnl0ZVZhbHVlKCkpOworICAgIH0KKyAgICAvLyBFbmQgb2YgaGJhc2UgYWRkaXRpb25zLgorICB9CisKKyAgLyogQ2FjaGUgYSBjbGllbnQgdXNpbmcgaXRzIHNvY2tldCBmYWN0b3J5IGFzIHRoZSBoYXNoIGtleSAqLworICBzdGF0aWMgcHJpdmF0ZSBjbGFzcyBDbGllbnRDYWNoZSB7CisgICAgcHJpdmF0ZSBNYXA8U29ja2V0RmFjdG9yeSwgSEJhc2VDbGllbnQ+IGNsaWVudHMgPQorICAgICAgbmV3IEhhc2hNYXA8U29ja2V0RmFjdG9yeSwgSEJhc2VDbGllbnQ+KCk7CisKKyAgICBwcm90ZWN0ZWQgQ2xpZW50Q2FjaGUoKSB7fQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0ICYgY2FjaGUgYW4gSVBDIGNsaWVudCB3aXRoIHRoZSB1c2VyLXByb3ZpZGVkIFNvY2tldEZhY3RvcnkgCisgICAgICogaWYgbm8gY2FjaGVkIGNsaWVudCBleGlzdHMuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbmYgQ29uZmlndXJhdGlvbgorICAgICAqIEByZXR1cm4gYW4gSVBDIGNsaWVudAorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgSEJhc2VDbGllbnQgZ2V0Q2xpZW50KENvbmZpZ3VyYXRpb24gY29uZiwKKyAgICAgICAgU29ja2V0RmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICAvLyBDb25zdHJ1Y3QgJiBjYWNoZSBjbGllbnQuICBUaGUgY29uZmlndXJhdGlvbiBpcyBvbmx5IHVzZWQgZm9yIHRpbWVvdXQsCisgICAgICAvLyBhbmQgQ2xpZW50cyBoYXZlIGNvbm5lY3Rpb24gcG9vbHMuICBTbyB3ZSBjYW4gZWl0aGVyIChhKSBsb3NlIHNvbWUKKyAgICAgIC8vIGNvbm5lY3Rpb24gcG9vbGluZyBhbmQgbGVhayBzb2NrZXRzLCBvciAoYikgdXNlIHRoZSBzYW1lIHRpbWVvdXQgZm9yIGFsbAorICAgICAgLy8gY29uZmlndXJhdGlvbnMuICBTaW5jZSB0aGUgSVBDIGlzIHVzdWFsbHkgaW50ZW5kZWQgZ2xvYmFsbHksIG5vdAorICAgICAgLy8gcGVyLWpvYiwgd2UgY2hvb3NlIChhKS4KKyAgICAgIEhCYXNlQ2xpZW50IGNsaWVudCA9IGNsaWVudHMuZ2V0KGZhY3RvcnkpOworICAgICAgaWYgKGNsaWVudCA9PSBudWxsKSB7CisgICAgICAgIC8vIE1ha2UgYW4gaGJhc2UgY2xpZW50IGluc3RlYWQgb2YgaGFkb29wIENsaWVudC4KKyAgICAgICAgY2xpZW50ID0gbmV3IEhCYXNlQ2xpZW50KEhiYXNlT2JqZWN0V3JpdGFibGUuY2xhc3MsIGNvbmYsIGZhY3RvcnkpOworICAgICAgICBjbGllbnRzLnB1dChmYWN0b3J5LCBjbGllbnQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgY2xpZW50LmluY0NvdW50KCk7CisgICAgICB9CisgICAgICByZXR1cm4gY2xpZW50OworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCAmIGNhY2hlIGFuIElQQyBjbGllbnQgd2l0aCB0aGUgZGVmYXVsdCBTb2NrZXRGYWN0b3J5IAorICAgICAqIGlmIG5vIGNhY2hlZCBjbGllbnQgZXhpc3RzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb25mIENvbmZpZ3VyYXRpb24KKyAgICAgKiBAcmV0dXJuIGFuIElQQyBjbGllbnQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIEhCYXNlQ2xpZW50IGdldENsaWVudChDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICAgIHJldHVybiBnZXRDbGllbnQoY29uZiwgU29ja2V0RmFjdG9yeS5nZXREZWZhdWx0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3AgYSBSUEMgY2xpZW50IGNvbm5lY3Rpb24gCisgICAgICogQSBSUEMgY2xpZW50IGlzIGNsb3NlZCBvbmx5IHdoZW4gaXRzIHJlZmVyZW5jZSBjb3VudCBiZWNvbWVzIHplcm8uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc3RvcENsaWVudChIQmFzZUNsaWVudCBjbGllbnQpIHsKKyAgICAgIHN5bmNocm9uaXplZCAodGhpcykgeworICAgICAgICBjbGllbnQuZGVjQ291bnQoKTsKKyAgICAgICAgaWYgKGNsaWVudC5pc1plcm9SZWZlcmVuY2UoKSkgeworICAgICAgICAgIGNsaWVudHMucmVtb3ZlKGNsaWVudC5nZXRTb2NrZXRGYWN0b3J5KCkpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoY2xpZW50LmlzWmVyb1JlZmVyZW5jZSgpKSB7CisgICAgICAgIGNsaWVudC5zdG9wKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBDbGllbnRDYWNoZSBDTElFTlRTID0gbmV3IENsaWVudENhY2hlKCk7CisgIAorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbnZva2VyIGltcGxlbWVudHMgSW52b2NhdGlvbkhhbmRsZXIgeworICAgIHByaXZhdGUgSW5ldFNvY2tldEFkZHJlc3MgYWRkcmVzczsKKyAgICBwcml2YXRlIFVzZXJHcm91cEluZm9ybWF0aW9uIHRpY2tldDsKKyAgICBwcml2YXRlIEhCYXNlQ2xpZW50IGNsaWVudDsKKyAgICBwcml2YXRlIGJvb2xlYW4gaXNDbG9zZWQgPSBmYWxzZTsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBhZGRyZXNzCisgICAgICogQHBhcmFtIHRpY2tldAorICAgICAqIEBwYXJhbSBjb25mCisgICAgICogQHBhcmFtIGZhY3RvcnkKKyAgICAgKi8KKyAgICBwdWJsaWMgSW52b2tlcihJbmV0U29ja2V0QWRkcmVzcyBhZGRyZXNzLCBVc2VyR3JvdXBJbmZvcm1hdGlvbiB0aWNrZXQsIAorICAgICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gY29uZiwgU29ja2V0RmFjdG9yeSBmYWN0b3J5KSB7CisgICAgICB0aGlzLmFkZHJlc3MgPSBhZGRyZXNzOworICAgICAgdGhpcy50aWNrZXQgPSB0aWNrZXQ7CisgICAgICB0aGlzLmNsaWVudCA9IENMSUVOVFMuZ2V0Q2xpZW50KGNvbmYsIGZhY3RvcnkpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgaW52b2tlKE9iamVjdCBwcm94eSwgTWV0aG9kIG1ldGhvZCwgT2JqZWN0W10gYXJncykKKyAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICBmaW5hbCBib29sZWFuIGxvZ0RlYnVnID0gTE9HLmlzRGVidWdFbmFibGVkKCk7CisgICAgICBsb25nIHN0YXJ0VGltZSA9IDA7CisgICAgICBpZiAobG9nRGVidWcpIHsKKyAgICAgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICB9CisgICAgICBIYmFzZU9iamVjdFdyaXRhYmxlIHZhbHVlID0gKEhiYXNlT2JqZWN0V3JpdGFibGUpCisgICAgICAgIGNsaWVudC5jYWxsKG5ldyBJbnZvY2F0aW9uKG1ldGhvZCwgYXJncyksIGFkZHJlc3MsIHRpY2tldCk7CisgICAgICBpZiAobG9nRGVidWcpIHsKKyAgICAgICAgbG9uZyBjYWxsVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lOworICAgICAgICBMT0cuZGVidWcoIkNhbGw6ICIgKyBtZXRob2QuZ2V0TmFtZSgpICsgIiAiICsgY2FsbFRpbWUpOworICAgICAgfQorICAgICAgcmV0dXJuIHZhbHVlLmdldCgpOworICAgIH0KKyAgICAKKyAgICAvKiBjbG9zZSB0aGUgSVBDIGNsaWVudCB0aGF0J3MgcmVzcG9uc2libGUgZm9yIHRoaXMgaW52b2tlcidzIFJQQ3MgKi8gCisgICAgc3luY2hyb25pemVkIHByb3RlY3RlZCB2b2lkIGNsb3NlKCkgeworICAgICAgaWYgKCFpc0Nsb3NlZCkgeworICAgICAgICBpc0Nsb3NlZCA9IHRydWU7CisgICAgICAgIENMSUVOVFMuc3RvcENsaWVudChjbGllbnQpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBBIHZlcnNpb24gbWlzbWF0Y2ggZm9yIHRoZSBSUEMgcHJvdG9jb2wuCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBWZXJzaW9uTWlzbWF0Y2ggZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBTdHJpbmcgaW50ZXJmYWNlTmFtZTsKKyAgICBwcml2YXRlIGxvbmcgY2xpZW50VmVyc2lvbjsKKyAgICBwcml2YXRlIGxvbmcgc2VydmVyVmVyc2lvbjsKKyAgICAKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB2ZXJzaW9uIG1pc21hdGNoIGV4Y2VwdGlvbgorICAgICAqIEBwYXJhbSBpbnRlcmZhY2VOYW1lIHRoZSBuYW1lIG9mIHRoZSBwcm90b2NvbCBtaXNtYXRjaAorICAgICAqIEBwYXJhbSBjbGllbnRWZXJzaW9uIHRoZSBjbGllbnQncyB2ZXJzaW9uIG9mIHRoZSBwcm90b2NvbAorICAgICAqIEBwYXJhbSBzZXJ2ZXJWZXJzaW9uIHRoZSBzZXJ2ZXIncyB2ZXJzaW9uIG9mIHRoZSBwcm90b2NvbAorICAgICAqLworICAgIHB1YmxpYyBWZXJzaW9uTWlzbWF0Y2goU3RyaW5nIGludGVyZmFjZU5hbWUsIGxvbmcgY2xpZW50VmVyc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgc2VydmVyVmVyc2lvbikgeworICAgICAgc3VwZXIoIlByb3RvY29sICIgKyBpbnRlcmZhY2VOYW1lICsgIiB2ZXJzaW9uIG1pc21hdGNoLiAoY2xpZW50ID0gIiArCisgICAgICAgICAgICBjbGllbnRWZXJzaW9uICsgIiwgc2VydmVyID0gIiArIHNlcnZlclZlcnNpb24gKyAiKSIpOworICAgICAgdGhpcy5pbnRlcmZhY2VOYW1lID0gaW50ZXJmYWNlTmFtZTsKKyAgICAgIHRoaXMuY2xpZW50VmVyc2lvbiA9IGNsaWVudFZlcnNpb247CisgICAgICB0aGlzLnNlcnZlclZlcnNpb24gPSBzZXJ2ZXJWZXJzaW9uOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIGludGVyZmFjZSBuYW1lCisgICAgICogQHJldHVybiB0aGUgamF2YSBjbGFzcyBuYW1lIAorICAgICAqICAgICAgICAgIChlZy4gb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkludGVyVHJhY2tlclByb3RvY29sKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0SW50ZXJmYWNlTmFtZSgpIHsKKyAgICAgIHJldHVybiBpbnRlcmZhY2VOYW1lOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSBjbGllbnQncyBwcmVmZXJyZWQgdmVyc2lvbgorICAgICAqLworICAgIHB1YmxpYyBsb25nIGdldENsaWVudFZlcnNpb24oKSB7CisgICAgICByZXR1cm4gY2xpZW50VmVyc2lvbjsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQHJldHVybiB0aGUgc2VydmVyJ3MgYWdyZWVkIHRvIHZlcnNpb24uCisgICAgICovCisgICAgcHVibGljIGxvbmcgZ2V0U2VydmVyVmVyc2lvbigpIHsKKyAgICAgIHJldHVybiBzZXJ2ZXJWZXJzaW9uOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBwcm90b2NvbAorICAgKiBAcGFyYW0gY2xpZW50VmVyc2lvbgorICAgKiBAcGFyYW0gYWRkcgorICAgKiBAcGFyYW0gY29uZgorICAgKiBAcGFyYW0gbWF4QXR0ZW1wdHMKKyAgICogQHJldHVybiBwcm94eQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyBWZXJzaW9uZWRQcm90b2NvbCB3YWl0Rm9yUHJveHkoQ2xhc3MgcHJvdG9jb2wsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgY2xpZW50VmVyc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgYWRkciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF4QXR0ZW1wdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgdGltZW91dAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gSEJhc2UgZG9lcyBsaW1pdGVkIG51bWJlciBvZiByZWNvbm5lY3RzIHdoaWNoIGlzIGRpZmZlcmVudCBmcm9tIGhhZG9vcC4KKyAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIElPRXhjZXB0aW9uIGlvZTsKKyAgICBpbnQgcmVjb25uZWN0QXR0ZW1wdHMgPSAwOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICB0cnkgeworICAgICAgICByZXR1cm4gZ2V0UHJveHkocHJvdG9jb2wsIGNsaWVudFZlcnNpb24sIGFkZHIsIGNvbmYpOworICAgICAgfSBjYXRjaChDb25uZWN0RXhjZXB0aW9uIHNlKSB7ICAvLyBuYW1lbm9kZSBoYXMgbm90IGJlZW4gc3RhcnRlZAorICAgICAgICBMT0cuaW5mbygiU2VydmVyIGF0ICIgKyBhZGRyICsgIiBub3QgYXZhaWxhYmxlIHlldCwgWnp6enouLi4iKTsKKyAgICAgICAgaW9lID0gc2U7CisgICAgICAgIGlmIChtYXhBdHRlbXB0cyA+PSAwICYmICsrcmVjb25uZWN0QXR0ZW1wdHMgPj0gbWF4QXR0ZW1wdHMpIHsKKyAgICAgICAgICBMT0cuaW5mbygiU2VydmVyIGF0ICIgKyBhZGRyICsgIiBjb3VsZCBub3QgYmUgcmVhY2hlZCBhZnRlciAiICsKKyAgICAgICAgICAgICAgICAgIHJlY29ubmVjdEF0dGVtcHRzICsgIiB0cmllcywgZ2l2aW5nIHVwLiIpOworICAgICAgICAgIHRocm93IG5ldyBSZXRyaWVzRXhoYXVzdGVkRXhjZXB0aW9uKGFkZHIudG9TdHJpbmcoKSwgInVua25vd24iLmdldEJ5dGVzKCksCisgICAgICAgICAgICAgICAgICAidW5rbm93biIuZ2V0Qnl0ZXMoKSwgcmVjb25uZWN0QXR0ZW1wdHMgLSAxLAorICAgICAgICAgICAgICAgICAgbmV3IEFycmF5TGlzdDxUaHJvd2FibGU+KCkpOworICAgICAgfQorICAgICAgfSBjYXRjaChTb2NrZXRUaW1lb3V0RXhjZXB0aW9uIHRlKSB7ICAvLyBuYW1lbm9kZSBpcyBidXN5CisgICAgICAgIExPRy5pbmZvKCJQcm9ibGVtIGNvbm5lY3RpbmcgdG8gc2VydmVyOiAiICsgYWRkcik7CisgICAgICAgIGlvZSA9IHRlOworICAgICAgfQorICAgICAgLy8gY2hlY2sgaWYgdGltZWQgb3V0CisgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCktdGltZW91dCA+PSBzdGFydFRpbWUpIHsKKyAgICAgICAgdGhyb3cgaW9lOworICAgICAgfQorCisgICAgICAvLyB3YWl0IGZvciByZXRyeQorICAgICAgdHJ5IHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgLy8gSUdOT1JFCisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIGNsaWVudC1zaWRlIHByb3h5IG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIG5hbWVkIHByb3RvY29sLAorICAgKiB0YWxraW5nIHRvIGEgc2VydmVyIGF0IHRoZSBuYW1lZCBhZGRyZXNzLgorICAgKgorICAgKiBAcGFyYW0gcHJvdG9jb2wKKyAgICogQHBhcmFtIGNsaWVudFZlcnNpb24KKyAgICogQHBhcmFtIGFkZHIKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHBhcmFtIGZhY3RvcnkKKyAgICogQHJldHVybiBwcm94eQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIFZlcnNpb25lZFByb3RvY29sIGdldFByb3h5KENsYXNzPD8+IHByb3RvY29sLAorICAgICAgbG9uZyBjbGllbnRWZXJzaW9uLCBJbmV0U29ja2V0QWRkcmVzcyBhZGRyLCBDb25maWd1cmF0aW9uIGNvbmYsCisgICAgICBTb2NrZXRGYWN0b3J5IGZhY3RvcnkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFByb3h5KHByb3RvY29sLCBjbGllbnRWZXJzaW9uLCBhZGRyLCBudWxsLCBjb25mLCBmYWN0b3J5KTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIGNsaWVudC1zaWRlIHByb3h5IG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIG5hbWVkIHByb3RvY29sLAorICAgKiB0YWxraW5nIHRvIGEgc2VydmVyIGF0IHRoZSBuYW1lZCBhZGRyZXNzLgorICAgKgorICAgKiBAcGFyYW0gcHJvdG9jb2wKKyAgICogQHBhcmFtIGNsaWVudFZlcnNpb24KKyAgICogQHBhcmFtIGFkZHIKKyAgICogQHBhcmFtIHRpY2tldAorICAgKiBAcGFyYW0gY29uZgorICAgKiBAcGFyYW0gZmFjdG9yeQorICAgKiBAcmV0dXJuIHByb3h5CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgVmVyc2lvbmVkUHJvdG9jb2wgZ2V0UHJveHkoQ2xhc3M8Pz4gcHJvdG9jb2wsCisgICAgICBsb25nIGNsaWVudFZlcnNpb24sIEluZXRTb2NrZXRBZGRyZXNzIGFkZHIsIFVzZXJHcm91cEluZm9ybWF0aW9uIHRpY2tldCwKKyAgICAgIENvbmZpZ3VyYXRpb24gY29uZiwgU29ja2V0RmFjdG9yeSBmYWN0b3J5KQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAgICAKKyAgICBWZXJzaW9uZWRQcm90b2NvbCBwcm94eSA9CisgICAgICAgIChWZXJzaW9uZWRQcm90b2NvbCkgUHJveHkubmV3UHJveHlJbnN0YW5jZSgKKyAgICAgICAgICAgIHByb3RvY29sLmdldENsYXNzTG9hZGVyKCksIG5ldyBDbGFzc1tdIHsgcHJvdG9jb2wgfSwKKyAgICAgICAgICAgIG5ldyBJbnZva2VyKGFkZHIsIHRpY2tldCwgY29uZiwgZmFjdG9yeSkpOworICAgIGxvbmcgc2VydmVyVmVyc2lvbiA9IHByb3h5LmdldFByb3RvY29sVmVyc2lvbihwcm90b2NvbC5nZXROYW1lKCksIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRWZXJzaW9uKTsKKyAgICBpZiAoc2VydmVyVmVyc2lvbiA9PSBjbGllbnRWZXJzaW9uKSB7CisgICAgICByZXR1cm4gcHJveHk7CisgICAgfQorICAgIHRocm93IG5ldyBWZXJzaW9uTWlzbWF0Y2gocHJvdG9jb2wuZ2V0TmFtZSgpLCBjbGllbnRWZXJzaW9uLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlclZlcnNpb24pOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIGNsaWVudC1zaWRlIHByb3h5IG9iamVjdCB3aXRoIHRoZSBkZWZhdWx0IFNvY2tldEZhY3RvcnkKKyAgICogCisgICAqIEBwYXJhbSBwcm90b2NvbAorICAgKiBAcGFyYW0gY2xpZW50VmVyc2lvbgorICAgKiBAcGFyYW0gYWRkcgorICAgKiBAcGFyYW0gY29uZgorICAgKiBAcmV0dXJuIGEgcHJveHkgaW5zdGFuY2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBWZXJzaW9uZWRQcm90b2NvbCBnZXRQcm94eShDbGFzczw/PiBwcm90b2NvbCwKKyAgICAgIGxvbmcgY2xpZW50VmVyc2lvbiwgSW5ldFNvY2tldEFkZHJlc3MgYWRkciwgQ29uZmlndXJhdGlvbiBjb25mKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIHJldHVybiBnZXRQcm94eShwcm90b2NvbCwgY2xpZW50VmVyc2lvbiwgYWRkciwgY29uZiwgTmV0VXRpbHMKKyAgICAgICAgLmdldERlZmF1bHRTb2NrZXRGYWN0b3J5KGNvbmYpKTsKKyAgfQorCisgIC8qKgorICAgKiBTdG9wIHRoaXMgcHJveHkgYW5kIHJlbGVhc2UgaXRzIGludm9rZXIncyByZXNvdXJjZQorICAgKiBAcGFyYW0gcHJveHkgdGhlIHByb3h5IHRvIGJlIHN0b3BwZWQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdG9wUHJveHkoVmVyc2lvbmVkUHJvdG9jb2wgcHJveHkpIHsKKyAgICBpZiAocHJveHkhPW51bGwpIHsKKyAgICAgICgoSW52b2tlcilQcm94eS5nZXRJbnZvY2F0aW9uSGFuZGxlcihwcm94eSkpLmNsb3NlKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEV4cGVydDogTWFrZSBtdWx0aXBsZSwgcGFyYWxsZWwgY2FsbHMgdG8gYSBzZXQgb2Ygc2VydmVycy4KKyAgICoKKyAgICogQHBhcmFtIG1ldGhvZAorICAgKiBAcGFyYW0gcGFyYW1zCisgICAqIEBwYXJhbSBhZGRycworICAgKiBAcGFyYW0gY29uZgorICAgKiBAcmV0dXJuIHZhbHVlcworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIE9iamVjdFtdIGNhbGwoTWV0aG9kIG1ldGhvZCwgT2JqZWN0W11bXSBwYXJhbXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmV0U29ja2V0QWRkcmVzc1tdIGFkZHJzLCBDb25maWd1cmF0aW9uIGNvbmYpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIEludm9jYXRpb25bXSBpbnZvY2F0aW9ucyA9IG5ldyBJbnZvY2F0aW9uW3BhcmFtcy5sZW5ndGhdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKQorICAgICAgaW52b2NhdGlvbnNbaV0gPSBuZXcgSW52b2NhdGlvbihtZXRob2QsIHBhcmFtc1tpXSk7CisgICAgSEJhc2VDbGllbnQgY2xpZW50ID0gQ0xJRU5UUy5nZXRDbGllbnQoY29uZik7CisgICAgdHJ5IHsKKyAgICBXcml0YWJsZVtdIHdyYXBwZWRWYWx1ZXMgPSBjbGllbnQuY2FsbChpbnZvY2F0aW9ucywgYWRkcnMpOworICAgIAorICAgIGlmIChtZXRob2QuZ2V0UmV0dXJuVHlwZSgpID09IFZvaWQuVFlQRSkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgT2JqZWN0W10gdmFsdWVzID0KKyAgICAgIChPYmplY3RbXSlBcnJheS5uZXdJbnN0YW5jZShtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLCB3cmFwcGVkVmFsdWVzLmxlbmd0aCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspCisgICAgICBpZiAod3JhcHBlZFZhbHVlc1tpXSAhPSBudWxsKQorICAgICAgICB2YWx1ZXNbaV0gPSAoKEhiYXNlT2JqZWN0V3JpdGFibGUpd3JhcHBlZFZhbHVlc1tpXSkuZ2V0KCk7CisgICAgCisgICAgcmV0dXJuIHZhbHVlczsKKyAgICB9IGZpbmFsbHkgeworICAgICAgQ0xJRU5UUy5zdG9wQ2xpZW50KGNsaWVudCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIHNlcnZlciBmb3IgYSBwcm90b2NvbCBpbXBsZW1lbnRhdGlvbiBpbnN0YW5jZSBsaXN0ZW5pbmcgb24gYQorICAgKiBwb3J0IGFuZCBhZGRyZXNzLgorICAgKgorICAgKiBAcGFyYW0gaW5zdGFuY2UKKyAgICogQHBhcmFtIGJpbmRBZGRyZXNzCisgICAqIEBwYXJhbSBwb3J0CisgICAqIEBwYXJhbSBjb25mCisgICAqIEByZXR1cm4gU2VydmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU2VydmVyIGdldFNlcnZlcihmaW5hbCBPYmplY3QgaW5zdGFuY2UsIGZpbmFsIFN0cmluZyBiaW5kQWRkcmVzcywgZmluYWwgaW50IHBvcnQsIENvbmZpZ3VyYXRpb24gY29uZikgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0U2VydmVyKGluc3RhbmNlLCBiaW5kQWRkcmVzcywgcG9ydCwgMSwgZmFsc2UsIGNvbmYpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIHNlcnZlciBmb3IgYSBwcm90b2NvbCBpbXBsZW1lbnRhdGlvbiBpbnN0YW5jZSBsaXN0ZW5pbmcgb24gYQorICAgKiBwb3J0IGFuZCBhZGRyZXNzLgorICAgKgorICAgKiBAcGFyYW0gaW5zdGFuY2UKKyAgICogQHBhcmFtIGJpbmRBZGRyZXNzCisgICAqIEBwYXJhbSBwb3J0CisgICAqIEBwYXJhbSBudW1IYW5kbGVycworICAgKiBAcGFyYW0gdmVyYm9zZQorICAgKiBAcGFyYW0gY29uZgorICAgKiBAcmV0dXJuIFNlcnZlcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIFNlcnZlciBnZXRTZXJ2ZXIoZmluYWwgT2JqZWN0IGluc3RhbmNlLCBmaW5hbCBTdHJpbmcgYmluZEFkZHJlc3MsIGZpbmFsIGludCBwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IG51bUhhbmRsZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiB2ZXJib3NlLCBDb25maWd1cmF0aW9uIGNvbmYpIAorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBTZXJ2ZXIoaW5zdGFuY2UsIGNvbmYsIGJpbmRBZGRyZXNzLCBwb3J0LCBudW1IYW5kbGVycywgdmVyYm9zZSk7CisgIH0KKworICAvKiogQW4gUlBDIFNlcnZlci4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBTZXJ2ZXIgZXh0ZW5kcyBIQmFzZVNlcnZlciB7CisgICAgcHJpdmF0ZSBPYmplY3QgaW5zdGFuY2U7CisgICAgcHJpdmF0ZSBDbGFzczw/PiBpbXBsZW1lbnRhdGlvbjsKKyAgICBwcml2YXRlIGJvb2xlYW4gdmVyYm9zZTsKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdCBhbiBSUEMgc2VydmVyLgorICAgICAqIEBwYXJhbSBpbnN0YW5jZSB0aGUgaW5zdGFuY2Ugd2hvc2UgbWV0aG9kcyB3aWxsIGJlIGNhbGxlZAorICAgICAqIEBwYXJhbSBjb25mIHRoZSBjb25maWd1cmF0aW9uIHRvIHVzZQorICAgICAqIEBwYXJhbSBiaW5kQWRkcmVzcyB0aGUgYWRkcmVzcyB0byBiaW5kIG9uIHRvIGxpc3RlbiBmb3IgY29ubmVjdGlvbgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0IHRvIGxpc3RlbiBmb3IgY29ubmVjdGlvbnMgb24KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNlcnZlcihPYmplY3QgaW5zdGFuY2UsIENvbmZpZ3VyYXRpb24gY29uZiwgU3RyaW5nIGJpbmRBZGRyZXNzLCBpbnQgcG9ydCkgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcyhpbnN0YW5jZSwgY29uZiwgIGJpbmRBZGRyZXNzLCBwb3J0LCAxLCBmYWxzZSk7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjbGFzc05hbWVCYXNlKFN0cmluZyBjbGFzc05hbWUpIHsKKyAgICAgIFN0cmluZ1tdIG5hbWVzID0gY2xhc3NOYW1lLnNwbGl0KCJcXC4iLCAtMSk7CisgICAgICBpZiAobmFtZXMgPT0gbnVsbCB8fCBuYW1lcy5sZW5ndGggPT0gMCkgeworICAgICAgICByZXR1cm4gY2xhc3NOYW1lOworICAgICAgfQorICAgICAgcmV0dXJuIG5hbWVzW25hbWVzLmxlbmd0aC0xXTsKKyAgICB9CisgICAgCisgICAgLyoqIENvbnN0cnVjdCBhbiBSUEMgc2VydmVyLgorICAgICAqIEBwYXJhbSBpbnN0YW5jZSB0aGUgaW5zdGFuY2Ugd2hvc2UgbWV0aG9kcyB3aWxsIGJlIGNhbGxlZAorICAgICAqIEBwYXJhbSBjb25mIHRoZSBjb25maWd1cmF0aW9uIHRvIHVzZQorICAgICAqIEBwYXJhbSBiaW5kQWRkcmVzcyB0aGUgYWRkcmVzcyB0byBiaW5kIG9uIHRvIGxpc3RlbiBmb3IgY29ubmVjdGlvbgorICAgICAqIEBwYXJhbSBwb3J0IHRoZSBwb3J0IHRvIGxpc3RlbiBmb3IgY29ubmVjdGlvbnMgb24KKyAgICAgKiBAcGFyYW0gbnVtSGFuZGxlcnMgdGhlIG51bWJlciBvZiBtZXRob2QgaGFuZGxlciB0aHJlYWRzIHRvIHJ1bgorICAgICAqIEBwYXJhbSB2ZXJib3NlIHdoZXRoZXIgZWFjaCBjYWxsIHNob3VsZCBiZSBsb2dnZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNlcnZlcihPYmplY3QgaW5zdGFuY2UsIENvbmZpZ3VyYXRpb24gY29uZiwgU3RyaW5nIGJpbmRBZGRyZXNzLCAgaW50IHBvcnQsCisgICAgICAgICAgICAgICAgICBpbnQgbnVtSGFuZGxlcnMsIGJvb2xlYW4gdmVyYm9zZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyKGJpbmRBZGRyZXNzLCBwb3J0LCBJbnZvY2F0aW9uLmNsYXNzLCBudW1IYW5kbGVycywgY29uZiwgY2xhc3NOYW1lQmFzZShpbnN0YW5jZS5nZXRDbGFzcygpLmdldE5hbWUoKSkpOworICAgICAgdGhpcy5pbnN0YW5jZSA9IGluc3RhbmNlOworICAgICAgdGhpcy5pbXBsZW1lbnRhdGlvbiA9IGluc3RhbmNlLmdldENsYXNzKCk7CisgICAgICB0aGlzLnZlcmJvc2UgPSB2ZXJib3NlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBXcml0YWJsZSBjYWxsKFdyaXRhYmxlIHBhcmFtLCBsb25nIHJlY2VpdmVkVGltZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEludm9jYXRpb24gY2FsbCA9IChJbnZvY2F0aW9uKXBhcmFtOworICAgICAgICBpZiAodmVyYm9zZSkgbG9nKCJDYWxsOiAiICsgY2FsbCk7CisgICAgICAgIE1ldGhvZCBtZXRob2QgPQorICAgICAgICAgIGltcGxlbWVudGF0aW9uLmdldE1ldGhvZChjYWxsLmdldE1ldGhvZE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbC5nZXRQYXJhbWV0ZXJDbGFzc2VzKCkpOworCisgICAgICAgIGxvbmcgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIE9iamVjdCB2YWx1ZSA9IG1ldGhvZC5pbnZva2UoaW5zdGFuY2UsIGNhbGwuZ2V0UGFyYW1ldGVycygpKTsKKyAgICAgICAgaW50IHByb2Nlc3NpbmdUaW1lID0gKGludCkgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lKTsKKyAgICAgICAgaW50IHFUaW1lID0gKGludCkgKHN0YXJ0VGltZS1yZWNlaXZlZFRpbWUpOworICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIlNlcnZlZDogIiArIGNhbGwuZ2V0TWV0aG9kTmFtZSgpICsKKyAgICAgICAgICAgICIgcXVldWVUaW1lPSAiICsgcVRpbWUgKworICAgICAgICAgICAgIiBwcm9jZXNpbmdUaW1lPSAiICsgcHJvY2Vzc2luZ1RpbWUpOworICAgICAgICAgIHJwY01ldHJpY3MucnBjUXVldWVUaW1lLmluYyhxVGltZSk7CisgICAgICAgICAgcnBjTWV0cmljcy5ycGNQcm9jZXNzaW5nVGltZS5pbmMocHJvY2Vzc2luZ1RpbWUpOworICAgICAgICB9CisgICAgICAgIHJwY01ldHJpY3MucnBjUXVldWVUaW1lLmluYyhxVGltZSk7CisgICAgICAgIHJwY01ldHJpY3MucnBjUHJvY2Vzc2luZ1RpbWUuaW5jKHByb2Nlc3NpbmdUaW1lKTsKKyAgICAgICAgcnBjTWV0cmljcy5pbmMoY2FsbC5nZXRNZXRob2ROYW1lKCksIHByb2Nlc3NpbmdUaW1lKTsKKyAgICAgICAgaWYgKHZlcmJvc2UpIGxvZygiUmV0dXJuOiAiK3ZhbHVlKTsKKworICAgICAgICByZXR1cm4gbmV3IEhiYXNlT2JqZWN0V3JpdGFibGUobWV0aG9kLmdldFJldHVyblR5cGUoKSwgdmFsdWUpOworCisgICAgICB9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgVGhyb3dhYmxlIHRhcmdldCA9IGUuZ2V0VGFyZ2V0RXhjZXB0aW9uKCk7CisgICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgeworICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbil0YXJnZXQ7CisgICAgICAgIH0KKyAgICAgICAgSU9FeGNlcHRpb24gaW9lID0gbmV3IElPRXhjZXB0aW9uKHRhcmdldC50b1N0cmluZygpKTsKKyAgICAgICAgaW9lLnNldFN0YWNrVHJhY2UodGFyZ2V0LmdldFN0YWNrVHJhY2UoKSk7CisgICAgICAgIHRocm93IGlvZTsKKyAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgIElPRXhjZXB0aW9uIGlvZSA9IG5ldyBJT0V4Y2VwdGlvbihlLnRvU3RyaW5nKCkpOworICAgICAgICBpb2Uuc2V0U3RhY2tUcmFjZShlLmdldFN0YWNrVHJhY2UoKSk7CisgICAgICAgIHRocm93IGlvZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgbG9nKFN0cmluZyB2YWx1ZSkgeworICAgIFN0cmluZyB2ID0gdmFsdWU7CisgICAgaWYgKHYgIT0gbnVsbCAmJiB2Lmxlbmd0aCgpID4gNTUpCisgICAgICB2ID0gdi5zdWJzdHJpbmcoMCwgNTUpKyIuLi4iOworICAgIExPRy5pbmZvKHYpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSEJhc2VSUENFcnJvckhhbmRsZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVJQQ0Vycm9ySGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkM2M3MGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSEJhc2VSUENFcnJvckhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDMxIEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGM7CisKKy8qKgorICogQW4gaW50ZXJmYWNlIGZvciBjYWxsaW5nIG91dCBvZiBSUEMgZm9yIGVycm9yIGNvbmRpdGlvbnMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSEJhc2VSUENFcnJvckhhbmRsZXIgeworCS8qKgorCSAqIFRha2UgYWN0aW9ucyBvbiB0aGUgZXZlbnQgb2YgYW4gT3V0T2ZNZW1vcnlFcnJvci4KKwkgKiBAcGFyYW0gZSB0aGUgdGhyb3dhYmxlCisJICogQHJldHVybiBpZiB0aGUgc2VydmVyIHNob3VsZCBiZSBzaHV0IGRvd24KKwkgKi8KKwlwdWJsaWMgYm9vbGVhbiBjaGVja09PTUUoZmluYWwgVGhyb3dhYmxlIGUpIDsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlUlBDUHJvdG9jb2xWZXJzaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA0ZDg1OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYzsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlwYy5WZXJzaW9uZWRQcm90b2NvbDsKKworLyoqCisgKiBUaGVyZSBpcyBvbmUgdmVyc2lvbiBpZCBmb3IgYWxsIHRoZSBSUEMgaW50ZXJmYWNlcy4gSWYgYW55IGludGVyZmFjZQorICogaXMgY2hhbmdlZCwgdGhlIHZlcnNpb25JRCBtdXN0IGJlIGNoYW5nZWQgaGVyZS4KKyAqLworcHVibGljIGludGVyZmFjZSBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbiBleHRlbmRzIFZlcnNpb25lZFByb3RvY29sIHsKKyAgLyoqCisgICAqIEludGVyZmFjZSB2ZXJzaW9uLgorICAgKiAKKyAgICogSE1hc3RlckludGVyZmFjZSB2ZXJzaW9uIGhpc3Rvcnk6CisgICAqIDx1bD4KKyAgICogPGxpPlZlcnNpb24gd2FzIGluY3JlbWVudGVkIHRvIDIgd2hlbiB3ZSBicm91Z2h0IHRoZSBoYWRvb3AgUlBDIGxvY2FsIHRvCisgICAqIGhiYXNlIEhBRE9PUC0yNDk1PC9saT4KKyAgICogPGxpPlZlcnNpb24gd2FzIGluY3JlbWVudGVkIHRvIDMgd2hlbiB3ZSBjaGFuZ2VkIHRoZSBSUEMgdG8gc2VuZCBjb2RlcworICAgKiBpbnN0ZWFkIG9mIGFjdHVhbCBjbGFzcyBuYW1lcyAoSEFET09QLTI1MTkpLjwvbGk+CisgICAqIDxsaT5WZXJzaW9uIDQgd2hlbiB3ZSBtb3ZlZCB0byBhbGwgYnl0ZSBhcnJheXMgKEhCQVNFLTQyKS48L2xpPgorICAgKiA8bGk+VmVyc2lvbiA1ICBIQkFTRS01NzYuPC9saT4KKyAgICogPGxpPlZlcnNpb24gNiAgbW9kaWZ5VGFibGUuPC9saT4KKyAgICogPC91bD4KKyAgICogPHA+SE1hc3RlclJlZ2lvbkludGVyZmFjZSB2ZXJzaW9uIGhpc3Rvcnk6CisgICAqIDx1bD4KKyAgICogPGxpPlZlcnNpb24gMiB3YXMgd2hlbiB0aGUgcmVnaW9uU2VydmVyU3RhcnR1cCB3YXMgY2hhbmdlZCB0byByZXR1cm4gYQorICAgKiBNYXBXcml0YWJsZSBpbnN0ZWFkIG9mIGEgSGJhc2VNYXBXcml0YWJsZSBhcyBwYXJ0IG9mIEhCQVNFLTgyIGNoYW5nZXMuPC9saT4KKyAgICogPGxpPlZlcnNpb24gMyB3YXMgd2hlbiBITXNnIHdhcyByZWZhY3RvcmVkIHNvIGl0IGNvdWxkIGNhcnJ5IG9wdGlvbmFsCisgICAqIG1lc3NhZ2VzIChIQkFTRS01MDQpLjwvbGk+CisgICAqIDxsaT5IQkFTRS01NzYgd2UgbW92ZWQgdGhpcyB0byA0LjwvbGk+CisgICAqIDwvdWw+CisgICAqIDxwPkhSZWdpb25JbnRlcmZhY2UgdmVyc2lvbiBoaXN0b3J5OgorICAgKiA8dWw+CisgICAqIDxsaT5VcHBlZCB0byA1IHdoZW4gd2UgYWRkZWQgc2Nhbm5lciBjYWNoaW5nPC9saT4KKyAgICogPGxpPkhCQVNFLTU3Niwgd2UgbW92ZWQgdGhpcyB0byA2LjwvbGk+CisgICAqIDwvdWw+CisgICAqIDxwPlRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UgdmVyc2lvbiBoaXN0b3J5OgorICAgKiA8dWw+CisgICAqIDxsaT5Nb3ZlZCB0byAyIGZvciBoYmFzZS01NzYuPC9saT4KKyAgICogPC91bD4KKyAgICogPHA+VW5pZmllZCBSUEMgdmVyc2lvbiBudW1iZXIgaGlzdG9yeToKKyAgICogPHVsPgorICAgKiA8bGk+VmVyc2lvbiAxMDogaW5pdGlhbCB2ZXJzaW9uIChoYWQgdG8gYmUgJmd0IGFsbCBvdGhlciBSUEMgdmVyc2lvbnM8L2xpPgorICAgKiA8bGk+VmVyc2lvbiAxMTogQ2hhbmdlZCBnZXRDbG9zZXN0Um93QmVmb3JlIHNpZ25hdHVyZS48L2xpPgorICAgKiA8bGk+VmVyc2lvbiAxMjogSFNlcnZlckxvYWQgZXh0ZW5zaW9ucyAoSEJBU0UtMTAxOCkuPC9saT4KKyAgICogPGxpPlZlcnNpb24gMTM6IEhCQVNFLTg0NzwvbGk+CisgICAqIDxsaT5WZXJzaW9uIDE0OiBIQkFTRS05MDA8L2xpPgorICAgKiA8bGk+VmVyc2lvbiAxNTogSFJlZ2lvbkludGVyZmFjZS5leGlzdHM8L2xpPgorICAgKiA8bGk+VmVyc2lvbiAxNjogUmVtb3ZlZCBITWFzdGVyUmVnaW9uSW50ZXJmYWNlLmdldFJvb3RSZWdpb25Mb2NhdGlvbiBhbmQKKyAgICogSE1hc3RlckludGVyZmFjZS5maW5kUm9vdFJlZ2lvbi4gV2UgdXNlIFpvb0tlZXBlciB0byBzdG9yZSByb290IHJlZ2lvbgorICAgKiBsb2NhdGlvbiBpbnN0ZWFkLjwvbGk+CisgICAqIDxsaT5WZXJzaW9uIDE3OiBBZGRlZCBpbmNyZW1lbnRDb2x1bW5WYWx1ZS48L2xpPgorICAgKiA8L3VsPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIHZlcnNpb25JRCA9IDE3TDsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVJwY01ldHJpY3MuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVJwY01ldHJpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZWI5NmFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlUnBjTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsMTE0IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjOworCitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLk1ldHJpY3NDb250ZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuTWV0cmljc1JlY29yZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLk1ldHJpY3NVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuVXBkYXRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLnV0aWwuTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZTsKKworLyoqCisgKiAKKyAqIFRoaXMgY2xhc3MgaXMgZm9yIG1haW50YWluaW5nICB0aGUgdmFyaW91cyBSUEMgc3RhdGlzdGljcworICogYW5kIHB1Ymxpc2hpbmcgdGhlbSB0aHJvdWdoIHRoZSBtZXRyaWNzIGludGVyZmFjZXMuCisgKiBUaGlzIGFsc28gcmVnaXN0ZXJzIHRoZSBKTVggTUJlYW4gZm9yIFJQQy4KKyAqIDxwPgorICogVGhpcyBjbGFzcyBoYXMgYSBudW1iZXIgb2YgbWV0cmljcyB2YXJpYWJsZXMgdGhhdCBhcmUgcHVibGljbHkgYWNjZXNzaWJsZTsKKyAqIHRoZXNlIHZhcmlhYmxlcyAob2JqZWN0cykgaGF2ZSBtZXRob2RzIHRvIHVwZGF0ZSB0aGVpciB2YWx1ZXM7CisgKiBmb3IgZXhhbXBsZToKKyAqICA8cD4ge0BsaW5rICNycGNRdWV1ZVRpbWV9LmluYyh0aW1lKQorICoKKyAqLworcHVibGljIGNsYXNzIEhCYXNlUnBjTWV0cmljcyBpbXBsZW1lbnRzIFVwZGF0ZXIgeworICBwcml2YXRlIE1ldHJpY3NSZWNvcmQgbWV0cmljc1JlY29yZDsKKyAgcHJpdmF0ZSBzdGF0aWMgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhCYXNlUnBjTWV0cmljcy5jbGFzcyk7CisKKyAgcHJpdmF0ZSBNYXAgPFN0cmluZywgTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZT4gcmVnaXN0cnkgPQorICAgIENvbGxlY3Rpb25zLnN5bmNocm9uaXplZE1hcChuZXcgSGFzaE1hcDxTdHJpbmcsIE1ldHJpY3NUaW1lVmFyeWluZ1JhdGU+KCkpOworICAKKyAgcHVibGljIEhCYXNlUnBjTWV0cmljcyhTdHJpbmcgaG9zdE5hbWUsIFN0cmluZyBwb3J0KSB7CisgICAgTWV0cmljc0NvbnRleHQgY29udGV4dCA9IE1ldHJpY3NVdGlsLmdldENvbnRleHQoInJwYyIpOworICAgIG1ldHJpY3NSZWNvcmQgPSBNZXRyaWNzVXRpbC5jcmVhdGVSZWNvcmQoY29udGV4dCwgIm1ldHJpY3MiKTsKKworICAgIG1ldHJpY3NSZWNvcmQuc2V0VGFnKCJwb3J0IiwgcG9ydCk7CisKKyAgICBMT0cuaW5mbygiSW5pdGlhbGl6aW5nIFJQQyBNZXRyaWNzIHdpdGggaG9zdE5hbWU9IiAKKyAgICAgICAgKyBob3N0TmFtZSArICIsIHBvcnQ9IiArIHBvcnQpOworCisgICAgY29udGV4dC5yZWdpc3RlclVwZGF0ZXIodGhpcyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUaGUgbWV0cmljcyB2YXJpYWJsZXMgYXJlIHB1YmxpYzoKKyAgICogIC0gdGhleSBjYW4gYmUgc2V0IGRpcmVjdGx5IGJ5IGNhbGxpbmcgdGhlaXIgc2V0L2luYyBtZXRob2RzCisgICAqICAtdGhleSBjYW4gYWxzbyBiZSByZWFkIGRpcmVjdGx5IC0gZS5nLiBKTVggZG9lcyB0aGlzLgorICAgKi8KKyAgcHVibGljIE1ldHJpY3NUaW1lVmFyeWluZ1JhdGUgcnBjUXVldWVUaW1lID0gCisgICAgbmV3IE1ldHJpY3NUaW1lVmFyeWluZ1JhdGUoIlJwY1F1ZXVlVGltZSIpOworICBwdWJsaWMgTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZSBycGNQcm9jZXNzaW5nVGltZSA9CisgICAgbmV3IE1ldHJpY3NUaW1lVmFyeWluZ1JhdGUoIlJwY1Byb2Nlc3NpbmdUaW1lIik7CisKKyAgcHJpdmF0ZSBNZXRyaWNzVGltZVZhcnlpbmdSYXRlIGdldChTdHJpbmcga2V5KSB7CisgICAgcmV0dXJuIHJlZ2lzdHJ5LmdldChrZXkpOworICB9CisgIAorICBwcml2YXRlIE1ldHJpY3NUaW1lVmFyeWluZ1JhdGUgY3JlYXRlKFN0cmluZyBrZXkpIHsKKyAgICBNZXRyaWNzVGltZVZhcnlpbmdSYXRlIG5ld01ldHJpYyA9IG5ldyBNZXRyaWNzVGltZVZhcnlpbmdSYXRlKGtleSk7CisgICAgcmVnaXN0cnkucHV0KGtleSwgbmV3TWV0cmljKTsKKyAgICByZXR1cm4gbmV3TWV0cmljOworICB9CisKKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGluYyhTdHJpbmcgbmFtZSwgaW50IGFtdCkgeworICAgIE1ldHJpY3NUaW1lVmFyeWluZ1JhdGUgbSA9IGdldChuYW1lKTsKKyAgICBpZiAobSA9PSBudWxsKSB7CisgICAgICBtID0gY3JlYXRlKG5hbWUpOworICAgIH0KKyAgICBtLmluYyhhbXQpOworICB9CisKKyAgLyoqCisgICAqIFB1c2ggdGhlIG1ldHJpY3MgdG8gdGhlIG1vbml0b3Jpbmcgc3Vic3lzdGVtIG9uIGRvVXBkYXRlKCkgY2FsbC4KKyAgICogQHBhcmFtIGNvbnRleHQKKyAgICovCisgIHB1YmxpYyB2b2lkIGRvVXBkYXRlcyhNZXRyaWNzQ29udGV4dCBjb250ZXh0KSB7CisgICAgcnBjUXVldWVUaW1lLnB1c2hNZXRyaWMobWV0cmljc1JlY29yZCk7CisgICAgcnBjUHJvY2Vzc2luZ1RpbWUucHVzaE1ldHJpYyhtZXRyaWNzUmVjb3JkKTsKKworICAgIHN5bmNocm9uaXplZCAocmVnaXN0cnkpIHsKKyAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCB0aGUgcmVnaXN0cnkgdG8gcHJvcG9nYXRlIHRoZSBkaWZmZXJlbnQgcnBjIG1ldHJpY3MuCisKKyAgICAgIGZvciAoU3RyaW5nIG1ldHJpY05hbWUgOiByZWdpc3RyeS5rZXlTZXQoKSApIHsKKyAgICAgICAgTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZSB2YWx1ZSA9IChNZXRyaWNzVGltZVZhcnlpbmdSYXRlKSByZWdpc3RyeS5nZXQobWV0cmljTmFtZSk7CisKKyAgICAgICAgdmFsdWUucHVzaE1ldHJpYyhtZXRyaWNzUmVjb3JkKTsKKyAgICAgIH0KKyAgICB9CisgICAgbWV0cmljc1JlY29yZC51cGRhdGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgeworICAgIC8vIE5vdGhpbmcgdG8gZG8KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVNlcnZlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hCYXNlU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNlMGJiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9IQmFzZVNlcnZlci5qYXZhCkBAIC0wLDAgKzEsMTE3MiBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5CaW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuQ2FuY2VsbGVkS2V5RXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkNsb3NlZENoYW5uZWxFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU2VsZWN0aW9uS2V5OworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlbGVjdG9yOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLlNlcnZlclNvY2tldENoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuU29ja2V0Q2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5SZWFkYWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLldyaXRhYmxlQnl0ZUNoYW5uZWw7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5MaW5rZWRCbG9ja2luZ1F1ZXVlOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLk9iamVjdFdyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3Auc2VjdXJpdHkuVXNlckdyb3VwSW5mb3JtYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5SZWZsZWN0aW9uVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5TdHJpbmdVdGlsczsKKworLyoqIEFuIGFic3RyYWN0IElQQyBzZXJ2aWNlLiAgSVBDIGNhbGxzIHRha2UgYSBzaW5nbGUge0BsaW5rIFdyaXRhYmxlfSBhcyBhCisgKiBwYXJhbWV0ZXIsIGFuZCByZXR1cm4gYSB7QGxpbmsgV3JpdGFibGV9IGFzIHRoZWlyIHZhbHVlLiAgQSBzZXJ2aWNlIHJ1bnMgb24KKyAqIGEgcG9ydCBhbmQgaXMgZGVmaW5lZCBieSBhIHBhcmFtZXRlciBjbGFzcyBhbmQgYSB2YWx1ZSBjbGFzcy4KKyAqIAorICogCisgKiA8cD5Db3BpZWQgbG9jYWwgc28gY2FuIGZpeCBIQkFTRS05MDAuCisgKiAKKyAqIEBzZWUgSEJhc2VDbGllbnQKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEhCYXNlU2VydmVyIHsKKyAgCisgIC8qKgorICAgKiBUaGUgZmlyc3QgZm91ciBieXRlcyBvZiBIYWRvb3AgUlBDIGNvbm5lY3Rpb25zCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIEJ5dGVCdWZmZXIgSEVBREVSID0gQnl0ZUJ1ZmZlci53cmFwKCJocnBjIi5nZXRCeXRlcygpKTsKKyAgCisgIC8vIDEgOiBJbnRyb2R1Y2UgcGluZyBhbmQgc2VydmVyIGRvZXMgbm90IHRocm93IGF3YXkgUlBDcworICAvLyAzIDogUlBDIHdhcyByZWZhY3RvcmVkIGluIDAuMTkgCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBDVVJSRU5UX1ZFUlNJT04gPSAzOworICAKKyAgLyoqCisgICAqIEhvdyBtYW55IGNhbGxzL2hhbmRsZXIgYXJlIGFsbG93ZWQgaW4gdGhlIHF1ZXVlLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9RVUVVRV9TSVpFX1BFUl9IQU5ETEVSID0gMTAwOworICAKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0KKyAgICBMb2dGYWN0b3J5LmdldExvZygib3JnLmFwYWNoZS5oYWRvb3AuaXBjLkhCYXNlU2VydmVyIik7CisKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBUaHJlYWRMb2NhbDxIQmFzZVNlcnZlcj4gU0VSVkVSID0gbmV3IFRocmVhZExvY2FsPEhCYXNlU2VydmVyPigpOworCisgIC8qKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgaW5zdGFuY2UgY2FsbGVkIHVuZGVyIG9yIG51bGwuICBNYXkgYmUgY2FsbGVkIHVuZGVyCisgICAqIHtAbGluayAjY2FsbChXcml0YWJsZSwgbG9uZyl9IGltcGxlbWVudGF0aW9ucywgYW5kIHVuZGVyIHtAbGluayBXcml0YWJsZX0KKyAgICogbWV0aG9kcyBvZiBwYXJhbXRlcnMgYW5kIHJldHVybiB2YWx1ZXMuICBQZXJtaXRzIGFwcGxpY2F0aW9ucyB0byBhY2Nlc3MKKyAgICogdGhlIHNlcnZlciBjb250ZXh0LgorICAgKiBAcmV0dXJuIEhCYXNlU2VydmVyCisgICAqLworICBwdWJsaWMgc3RhdGljIEhCYXNlU2VydmVyIGdldCgpIHsKKyAgICByZXR1cm4gU0VSVkVSLmdldCgpOworICB9CisgCisgIC8qKiBUaGlzIGlzIHNldCB0byBDYWxsIG9iamVjdCBiZWZvcmUgSGFuZGxlciBpbnZva2VzIGFuIFJQQyBhbmQgcmVzZXQKKyAgICogYWZ0ZXIgdGhlIGNhbGwgcmV0dXJucy4KKyAgICovCisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgVGhyZWFkTG9jYWw8Q2FsbD4gQ3VyQ2FsbCA9IG5ldyBUaHJlYWRMb2NhbDxDYWxsPigpOworICAKKyAgLyoqIFJldHVybnMgdGhlIHJlbW90ZSBzaWRlIGlwIGFkZHJlc3Mgd2hlbiBpbnZva2VkIGluc2lkZSBhbiBSUEMgCisgICAqICBSZXR1cm5zIG51bGwgaW5jYXNlIG9mIGFuIGVycm9yLgorICAgKiAgQHJldHVybiBJbmV0QWRkcmVzcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBJbmV0QWRkcmVzcyBnZXRSZW1vdGVJcCgpIHsKKyAgICBDYWxsIGNhbGwgPSBDdXJDYWxsLmdldCgpOworICAgIGlmIChjYWxsICE9IG51bGwpIHsKKyAgICAgIHJldHVybiBjYWxsLmNvbm5lY3Rpb24uc29ja2V0LmdldEluZXRBZGRyZXNzKCk7CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisgIC8qKiBSZXR1cm5zIHJlbW90ZSBhZGRyZXNzIGFzIGEgc3RyaW5nIHdoZW4gaW52b2tlZCBpbnNpZGUgYW4gUlBDLgorICAgKiAgUmV0dXJucyBudWxsIGluIGNhc2Ugb2YgYW4gZXJyb3IuCisgICAqICBAcmV0dXJuIFN0cmluZworICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UmVtb3RlQWRkcmVzcygpIHsKKyAgICBJbmV0QWRkcmVzcyBhZGRyID0gZ2V0UmVtb3RlSXAoKTsKKyAgICByZXR1cm4gKGFkZHIgPT0gbnVsbCkgPyBudWxsIDogYWRkci5nZXRIb3N0QWRkcmVzcygpOworICB9CisKKyAgcHJvdGVjdGVkIFN0cmluZyBiaW5kQWRkcmVzczsgCisgIHByb3RlY3RlZCBpbnQgcG9ydDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBvcnQgd2UgbGlzdGVuIG9uCisgIHByaXZhdGUgaW50IGhhbmRsZXJDb3VudDsgICAgICAgICAgICAgICAgICAgICAgIC8vIG51bWJlciBvZiBoYW5kbGVyIHRocmVhZHMKKyAgcHJvdGVjdGVkIENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZT4gcGFyYW1DbGFzczsgLy8gY2xhc3Mgb2YgY2FsbCBwYXJhbWV0ZXJzCisgIHByb3RlY3RlZCBpbnQgbWF4SWRsZVRpbWU7ICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBtYXhpbXVtIGlkbGUgdGltZSBhZnRlciAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggYSBjbGllbnQgbWF5IGJlIGRpc2Nvbm5lY3RlZAorICBwcm90ZWN0ZWQgaW50IHRocmVzaG9sZElkbGVDb25uZWN0aW9uczsgICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGlkbGUgY29ubmVjdGlvbnMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgd2hpY2ggd2Ugd2lsbCBzdGFydAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjbGVhbmluZyB1cCBpZGxlIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9ucworICBpbnQgbWF4Q29ubmVjdGlvbnNUb051a2U7ICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbWF4IG51bWJlciBvZiAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29ubmVjdGlvbnMgdG8gbnVrZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkdXJpbmcgYSBjbGVhbnVwCisgIAorICBwcm90ZWN0ZWQgSEJhc2VScGNNZXRyaWNzICBycGNNZXRyaWNzOworICAKKyAgcHJvdGVjdGVkIENvbmZpZ3VyYXRpb24gY29uZjsKKworICBwcml2YXRlIGludCBtYXhRdWV1ZVNpemU7CisgIHByb3RlY3RlZCBpbnQgc29ja2V0U2VuZEJ1ZmZlclNpemU7CisgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHRjcE5vRGVsYXk7IC8vIGlmIFQgdGhlbiBkaXNhYmxlIE5hZ2xlJ3MgQWxnb3JpdGhtCisKKyAgdm9sYXRpbGUgcHJvdGVjdGVkIGJvb2xlYW4gcnVubmluZyA9IHRydWU7ICAgICAgICAgLy8gdHJ1ZSB3aGlsZSBzZXJ2ZXIgcnVucworICBwcm90ZWN0ZWQgQmxvY2tpbmdRdWV1ZTxDYWxsPiBjYWxsUXVldWU7IC8vIHF1ZXVlZCBjYWxscworCisgIHByb3RlY3RlZCBMaXN0PENvbm5lY3Rpb24+IGNvbm5lY3Rpb25MaXN0ID0gCisgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTGlzdChuZXcgTGlua2VkTGlzdDxDb25uZWN0aW9uPigpKTsKKyAgLy9tYWludGFpbiBhIGxpc3QKKyAgLy9vZiBjbGllbnQgY29ubmVjdGlvbnMKKyAgcHJpdmF0ZSBMaXN0ZW5lciBsaXN0ZW5lciA9IG51bGw7CisgIHByb3RlY3RlZCBSZXNwb25kZXIgcmVzcG9uZGVyID0gbnVsbDsKKyAgcHJvdGVjdGVkIGludCBudW1Db25uZWN0aW9ucyA9IDA7CisgIHByaXZhdGUgSGFuZGxlcltdIGhhbmRsZXJzID0gbnVsbDsKKyAgcHJvdGVjdGVkIEhCYXNlUlBDRXJyb3JIYW5kbGVyIGVycm9ySGFuZGxlciA9IG51bGw7CisKKyAgLyoqCisgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIHRvIGJpbmQgdG8gYSBnaXZlbiBhZGRyZXNzIGFuZCByZXBvcnQgCisgICAqIGJldHRlciBleGNlcHRpb25zIGlmIHRoZSBhZGRyZXNzIGlzIG5vdCBhIHZhbGlkIGhvc3QuCisgICAqIEBwYXJhbSBzb2NrZXQgdGhlIHNvY2tldCB0byBiaW5kCisgICAqIEBwYXJhbSBhZGRyZXNzIHRoZSBhZGRyZXNzIHRvIGJpbmQgdG8KKyAgICogQHBhcmFtIGJhY2tsb2cgdGhlIG51bWJlciBvZiBjb25uZWN0aW9ucyBhbGxvd2VkIGluIHRoZSBxdWV1ZQorICAgKiBAdGhyb3dzIEJpbmRFeGNlcHRpb24gaWYgdGhlIGFkZHJlc3MgY2FuJ3QgYmUgYm91bmQKKyAgICogQHRocm93cyBVbmtub3duSG9zdEV4Y2VwdGlvbiBpZiB0aGUgYWRkcmVzcyBpc24ndCBhIHZhbGlkIGhvc3QgbmFtZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIG90aGVyIHJhbmRvbSBlcnJvcnMgZnJvbSBiaW5kCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgYmluZChTZXJ2ZXJTb2NrZXQgc29ja2V0LCBJbmV0U29ja2V0QWRkcmVzcyBhZGRyZXNzLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJhY2tsb2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHNvY2tldC5iaW5kKGFkZHJlc3MsIGJhY2tsb2cpOworICAgIH0gY2F0Y2ggKEJpbmRFeGNlcHRpb24gZSkgeworICAgICAgQmluZEV4Y2VwdGlvbiBiaW5kRXhjZXB0aW9uID0gbmV3IEJpbmRFeGNlcHRpb24oIlByb2JsZW0gYmluZGluZyB0byAiICsgYWRkcmVzcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIGJpbmRFeGNlcHRpb24uaW5pdENhdXNlKGUpOworICAgICAgdGhyb3cgYmluZEV4Y2VwdGlvbjsKKyAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gZSkgeworICAgICAgLy8gSWYgdGhleSB0cnkgdG8gYmluZCB0byBhIGRpZmZlcmVudCBob3N0J3MgYWRkcmVzcywgZ2l2ZSBhIGJldHRlcgorICAgICAgLy8gZXJyb3IgbWVzc2FnZS4KKyAgICAgIGlmICgiVW5yZXNvbHZlZCBhZGRyZXNzIi5lcXVhbHMoZS5nZXRNZXNzYWdlKCkpKSB7CisgICAgICAgIHRocm93IG5ldyBVbmtub3duSG9zdEV4Y2VwdGlvbigiSW52YWxpZCBob3N0bmFtZSBmb3Igc2VydmVyOiAiICsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzLmdldEhvc3ROYW1lKCkpOworICAgICAgfQorICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICAvKiogQSBjYWxsIHF1ZXVlZCBmb3IgaGFuZGxpbmcuICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIENhbGwgeworICAgIHByb3RlY3RlZCBpbnQgaWQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY2xpZW50J3MgY2FsbCBpZAorICAgIHByb3RlY3RlZCBXcml0YWJsZSBwYXJhbTsgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgcGFyYW1ldGVyIHBhc3NlZAorICAgIHByb3RlY3RlZCBDb25uZWN0aW9uIGNvbm5lY3Rpb247ICAgICAgICAgICAgICAvLyBjb25uZWN0aW9uIHRvIGNsaWVudAorICAgIHByb3RlY3RlZCBsb25nIHRpbWVzdGFtcDsgICAgICAvLyB0aGUgdGltZSByZWNlaXZlZCB3aGVuIHJlc3BvbnNlIGlzIG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHRpbWUgc2VydmVkIHdoZW4gcmVzcG9uc2UgaXMgbm90IG51bGwKKyAgICBwcm90ZWN0ZWQgQnl0ZUJ1ZmZlciByZXNwb25zZTsgICAgICAgICAgICAgICAgLy8gdGhlIHJlc3BvbnNlIGZvciB0aGlzIGNhbGwKKworICAgIHB1YmxpYyBDYWxsKGludCBpZCwgV3JpdGFibGUgcGFyYW0sIENvbm5lY3Rpb24gY29ubmVjdGlvbikgeworICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgdGhpcy5wYXJhbSA9IHBhcmFtOworICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICB0aGlzLnJlc3BvbnNlID0gbnVsbDsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIHJldHVybiBwYXJhbS50b1N0cmluZygpICsgIiBmcm9tICIgKyBjb25uZWN0aW9uLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UmVzcG9uc2UoQnl0ZUJ1ZmZlciByZXNwb25zZSkgeworICAgICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlOworICAgIH0KKyAgfQorCisgIC8qKiBMaXN0ZW5zIG9uIHRoZSBzb2NrZXQuIENyZWF0ZXMgam9icyBmb3IgdGhlIGhhbmRsZXIgdGhyZWFkcyovCisgIHByaXZhdGUgY2xhc3MgTGlzdGVuZXIgZXh0ZW5kcyBUaHJlYWQgeworICAgIAorICAgIHByaXZhdGUgU2VydmVyU29ja2V0Q2hhbm5lbCBhY2NlcHRDaGFubmVsID0gbnVsbDsgLy90aGUgYWNjZXB0IGNoYW5uZWwKKyAgICBwcml2YXRlIFNlbGVjdG9yIHNlbGVjdG9yID0gbnVsbDsgLy90aGUgc2VsZWN0b3IgdGhhdCB3ZSB1c2UgZm9yIHRoZSBzZXJ2ZXIKKyAgICBwcml2YXRlIEluZXRTb2NrZXRBZGRyZXNzIGFkZHJlc3M7IC8vdGhlIGFkZHJlc3Mgd2UgYmluZCBhdAorICAgIHByaXZhdGUgUmFuZG9tIHJhbmQgPSBuZXcgUmFuZG9tKCk7CisgICAgcHJpdmF0ZSBsb25nIGxhc3RDbGVhbnVwUnVuVGltZSA9IDA7IC8vdGhlIGxhc3QgdGltZSB3aGVuIGEgY2xlYW51cCBjb25uZWMtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLXRpb24gKGZvciBpZGxlIGNvbm5lY3Rpb25zKSByYW4KKyAgICBwcml2YXRlIGxvbmcgY2xlYW51cEludGVydmFsID0gMTAwMDA7IC8vdGhlIG1pbmltdW0gaW50ZXJ2YWwgYmV0d2VlbiAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHdvIGNsZWFudXAgcnVucworICAgIHByaXZhdGUgaW50IGJhY2tsb2dMZW5ndGggPSBjb25mLmdldEludCgiaXBjLnNlcnZlci5saXN0ZW4ucXVldWUuc2l6ZSIsIDEyOCk7CisgICAgCisgICAgcHVibGljIExpc3RlbmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGFkZHJlc3MgPSBuZXcgSW5ldFNvY2tldEFkZHJlc3MoYmluZEFkZHJlc3MsIHBvcnQpOworICAgICAgLy8gQ3JlYXRlIGEgbmV3IHNlcnZlciBzb2NrZXQgYW5kIHNldCB0byBub24gYmxvY2tpbmcgbW9kZQorICAgICAgYWNjZXB0Q2hhbm5lbCA9IFNlcnZlclNvY2tldENoYW5uZWwub3BlbigpOworICAgICAgYWNjZXB0Q2hhbm5lbC5jb25maWd1cmVCbG9ja2luZyhmYWxzZSk7CisKKyAgICAgIC8vIEJpbmQgdGhlIHNlcnZlciBzb2NrZXQgdG8gdGhlIGxvY2FsIGhvc3QgYW5kIHBvcnQKKyAgICAgIGJpbmQoYWNjZXB0Q2hhbm5lbC5zb2NrZXQoKSwgYWRkcmVzcywgYmFja2xvZ0xlbmd0aCk7CisgICAgICBwb3J0ID0gYWNjZXB0Q2hhbm5lbC5zb2NrZXQoKS5nZXRMb2NhbFBvcnQoKTsgLy9Db3VsZCBiZSBhbiBlcGhlbWVyYWwgcG9ydAorICAgICAgLy8gY3JlYXRlIGEgc2VsZWN0b3I7CisgICAgICBzZWxlY3Rvcj0gU2VsZWN0b3Iub3BlbigpOworCisgICAgICAvLyBSZWdpc3RlciBhY2NlcHRzIG9uIHRoZSBzZXJ2ZXIgc29ja2V0IHdpdGggdGhlIHNlbGVjdG9yLgorICAgICAgYWNjZXB0Q2hhbm5lbC5yZWdpc3RlcihzZWxlY3RvciwgU2VsZWN0aW9uS2V5Lk9QX0FDQ0VQVCk7CisgICAgICB0aGlzLnNldE5hbWUoIklQQyBTZXJ2ZXIgbGlzdGVuZXIgb24gIiArIHBvcnQpOworICAgICAgdGhpcy5zZXREYWVtb24odHJ1ZSk7CisgICAgfQorICAgIC8qKiBjbGVhbnVwIGNvbm5lY3Rpb25zIGZyb20gY29ubmVjdGlvbkxpc3QuIENob29zZSBhIHJhbmRvbSByYW5nZQorICAgICAqIHRvIHNjYW4gYW5kIGFsc28gaGF2ZSBhIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgdGhlIGNvbm5lY3Rpb25zCisgICAgICogdGhhdCB3aWxsIGJlIGNsZWFuZWR1cCBwZXIgcnVuLiBUaGUgY3JpdGVyaWEgZm9yIGNsZWFudXAgaXMgdGhlIHRpbWUKKyAgICAgKiBmb3Igd2hpY2ggdGhlIGNvbm5lY3Rpb24gd2FzIGlkbGUuIElmICdmb3JjZScgaXMgdHJ1ZSB0aGVuIGFsbCAKKyAgICAgKiBjb25uZWN0aW9ucyB3aWxsIGJlIGxvb2tlZCBhdCBmb3IgdGhlIGNsZWFudXAuCisgICAgICovCisgICAgcHJpdmF0ZSB2b2lkIGNsZWFudXBDb25uZWN0aW9ucyhib29sZWFuIGZvcmNlKSB7CisgICAgICBpZiAoZm9yY2UgfHwgbnVtQ29ubmVjdGlvbnMgPiB0aHJlc2hvbGRJZGxlQ29ubmVjdGlvbnMpIHsKKyAgICAgICAgbG9uZyBjdXJyZW50VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBpZiAoIWZvcmNlICYmIChjdXJyZW50VGltZSAtIGxhc3RDbGVhbnVwUnVuVGltZSkgPCBjbGVhbnVwSW50ZXJ2YWwpIHsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaW50IHN0YXJ0ID0gMDsKKyAgICAgICAgaW50IGVuZCA9IG51bUNvbm5lY3Rpb25zIC0gMTsKKyAgICAgICAgaWYgKCFmb3JjZSkgeworICAgICAgICAgIHN0YXJ0ID0gcmFuZC5uZXh0SW50KCkgJSBudW1Db25uZWN0aW9uczsKKyAgICAgICAgICBlbmQgPSByYW5kLm5leHRJbnQoKSAlIG51bUNvbm5lY3Rpb25zOworICAgICAgICAgIGludCB0ZW1wOworICAgICAgICAgIGlmIChlbmQgPCBzdGFydCkgeworICAgICAgICAgICAgdGVtcCA9IHN0YXJ0OworICAgICAgICAgICAgc3RhcnQgPSBlbmQ7CisgICAgICAgICAgICBlbmQgPSB0ZW1wOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpbnQgaSA9IHN0YXJ0OworICAgICAgICBpbnQgbnVtTnVrZWQgPSAwOworICAgICAgICB3aGlsZSAoaSA8PSBlbmQpIHsKKyAgICAgICAgICBDb25uZWN0aW9uIGM7CisgICAgICAgICAgc3luY2hyb25pemVkIChjb25uZWN0aW9uTGlzdCkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgYyA9IGNvbm5lY3Rpb25MaXN0LmdldChpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7cmV0dXJuO30KKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKGMudGltZWRPdXQoY3VycmVudFRpbWUpKSB7CisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpCisgICAgICAgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiBkaXNjb25uZWN0aW5nIGNsaWVudCAiICsgYy5nZXRIb3N0QWRkcmVzcygpKTsKKyAgICAgICAgICAgIGNsb3NlQ29ubmVjdGlvbihjKTsKKyAgICAgICAgICAgIG51bU51a2VkKys7CisgICAgICAgICAgICBlbmQtLTsKKyAgICAgICAgICAgIGMgPSBudWxsOworICAgICAgICAgICAgaWYgKCFmb3JjZSAmJiBudW1OdWtlZCA9PSBtYXhDb25uZWN0aW9uc1RvTnVrZSkgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGVsc2UgaSsrOworICAgICAgICB9CisgICAgICAgIGxhc3RDbGVhbnVwUnVuVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgIExPRy5pbmZvKGdldE5hbWUoKSArICI6IHN0YXJ0aW5nIik7CisgICAgICBTRVJWRVIuc2V0KEhCYXNlU2VydmVyLnRoaXMpOworCisgICAgICB3aGlsZSAocnVubmluZykgeworICAgICAgICBTZWxlY3Rpb25LZXkga2V5ID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBzZWxlY3Rvci5zZWxlY3QoKTsKKyAgICAgICAgICBJdGVyYXRvcjxTZWxlY3Rpb25LZXk+IGl0ZXIgPSBzZWxlY3Rvci5zZWxlY3RlZEtleXMoKS5pdGVyYXRvcigpOworICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICAgICAga2V5ID0gaXRlci5uZXh0KCk7CisgICAgICAgICAgICBpdGVyLnJlbW92ZSgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgaWYgKGtleS5pc1ZhbGlkKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoa2V5LmlzQWNjZXB0YWJsZSgpKQorICAgICAgICAgICAgICAgICAgZG9BY2NlcHQoa2V5KTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChrZXkuaXNSZWFkYWJsZSgpKQorICAgICAgICAgICAgICAgICAgZG9SZWFkKGtleSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGtleSA9IG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGUpIHsKKyAgICAgICAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChlcnJvckhhbmRsZXIuY2hlY2tPT01FKGUpKSB7CisgICAgICAgICAgICAgIExPRy5pbmZvKGdldE5hbWUoKSArICI6IGV4aXRpbmcgb24gT09NRSIpOworICAgICAgICAgICAgICBjbG9zZUN1cnJlbnRDb25uZWN0aW9uKGtleSk7CisgICAgICAgICAgICAgIGNsZWFudXBDb25uZWN0aW9ucyh0cnVlKTsKKyAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyB3ZSBjYW4gcnVuIG91dCBvZiBtZW1vcnkgaWYgd2UgaGF2ZSB0b28gbWFueSB0aHJlYWRzCisgICAgICAgICAgICAvLyBsb2cgdGhlIGV2ZW50IGFuZCBzbGVlcCBmb3IgYSBtaW51dGUgYW5kIGdpdmUgCisgICAgICAgICAgICAvLyBzb21lIHRocmVhZChzKSBhIGNoYW5jZSB0byBmaW5pc2gKKyAgICAgICAgICAgIExPRy53YXJuKCJPdXQgb2YgTWVtb3J5IGluIHNlcnZlciBzZWxlY3QiLCBlKTsKKyAgICAgICAgICAgIGNsb3NlQ3VycmVudENvbm5lY3Rpb24oa2V5KTsKKyAgICAgICAgICAgIGNsZWFudXBDb25uZWN0aW9ucyh0cnVlKTsKKyAgICAgICAgICAgIHRyeSB7IFRocmVhZC5zbGVlcCg2MDAwMCk7IH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZSkge30KKyAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIGlmIChydW5uaW5nKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkIC0tIGxvZyBpdAorICAgICAgICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIiBjYXVnaHQ6ICIgKworICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgY2xvc2VDdXJyZW50Q29ubmVjdGlvbihrZXkpOworICAgICAgICB9CisgICAgICAgIGNsZWFudXBDb25uZWN0aW9ucyhmYWxzZSk7CisgICAgICB9CisgICAgICBMT0cuaW5mbygiU3RvcHBpbmcgIiArIHRoaXMuZ2V0TmFtZSgpKTsKKworICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgYWNjZXB0Q2hhbm5lbC5jbG9zZSgpOworICAgICAgICAgIHNlbGVjdG9yLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsgfQorCisgICAgICAgIHNlbGVjdG9yPSBudWxsOworICAgICAgICBhY2NlcHRDaGFubmVsPSBudWxsOworICAgICAgICAKKyAgICAgICAgLy8gY2xlYW4gdXAgYWxsIGNvbm5lY3Rpb25zCisgICAgICAgIHdoaWxlICghY29ubmVjdGlvbkxpc3QuaXNFbXB0eSgpKSB7CisgICAgICAgICAgY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb25MaXN0LnJlbW92ZSgwKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgY2xvc2VDdXJyZW50Q29ubmVjdGlvbihTZWxlY3Rpb25LZXkga2V5KSB7CisgICAgICBpZiAoa2V5ICE9IG51bGwpIHsKKyAgICAgICAgQ29ubmVjdGlvbiBjID0gKENvbm5lY3Rpb24pa2V5LmF0dGFjaG1lbnQoKTsKKyAgICAgICAgaWYgKGMgIT0gbnVsbCkgeworICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiBkaXNjb25uZWN0aW5nIGNsaWVudCAiICsgYy5nZXRIb3N0QWRkcmVzcygpKTsKKyAgICAgICAgICBjbG9zZUNvbm5lY3Rpb24oYyk7CisgICAgICAgICAgYyA9IG51bGw7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBJbmV0U29ja2V0QWRkcmVzcyBnZXRBZGRyZXNzKCkgeworICAgICAgcmV0dXJuIChJbmV0U29ja2V0QWRkcmVzcylhY2NlcHRDaGFubmVsLnNvY2tldCgpLmdldExvY2FsU29ja2V0QWRkcmVzcygpOworICAgIH0KKyAgICAKKyAgICB2b2lkIGRvQWNjZXB0KFNlbGVjdGlvbktleSBrZXkpIHRocm93cyBJT0V4Y2VwdGlvbiwgT3V0T2ZNZW1vcnlFcnJvciB7CisgICAgICBDb25uZWN0aW9uIGMgPSBudWxsOworICAgICAgU2VydmVyU29ja2V0Q2hhbm5lbCBzZXJ2ZXIgPSAoU2VydmVyU29ja2V0Q2hhbm5lbCkga2V5LmNoYW5uZWwoKTsKKyAgICAgIC8vIGFjY2VwdCB1cCB0byAxMCBjb25uZWN0aW9ucworICAgICAgZm9yIChpbnQgaT0wOyBpPDEwOyBpKyspIHsKKyAgICAgICAgU29ja2V0Q2hhbm5lbCBjaGFubmVsID0gc2VydmVyLmFjY2VwdCgpOworICAgICAgICBpZiAoY2hhbm5lbD09bnVsbCkgcmV0dXJuOworCisgICAgICAgIGNoYW5uZWwuY29uZmlndXJlQmxvY2tpbmcoZmFsc2UpOworICAgICAgICBjaGFubmVsLnNvY2tldCgpLnNldFRjcE5vRGVsYXkodGNwTm9EZWxheSk7CisgICAgICAgIFNlbGVjdGlvbktleSByZWFkS2V5ID0gY2hhbm5lbC5yZWdpc3RlcihzZWxlY3RvciwgU2VsZWN0aW9uS2V5Lk9QX1JFQUQpOworICAgICAgICBjID0gbmV3IENvbm5lY3Rpb24oY2hhbm5lbCwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICByZWFkS2V5LmF0dGFjaChjKTsKKyAgICAgICAgc3luY2hyb25pemVkIChjb25uZWN0aW9uTGlzdCkgeworICAgICAgICAgIGNvbm5lY3Rpb25MaXN0LmFkZChudW1Db25uZWN0aW9ucywgYyk7CisgICAgICAgICAgbnVtQ29ubmVjdGlvbnMrKzsKKyAgICAgICAgfQorICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpCisgICAgICAgICAgTE9HLmRlYnVnKCJTZXJ2ZXIgY29ubmVjdGlvbiBmcm9tICIgKyBjLnRvU3RyaW5nKCkgKworICAgICAgICAgICAgICAiOyAjIGFjdGl2ZSBjb25uZWN0aW9uczogIiArIG51bUNvbm5lY3Rpb25zICsKKyAgICAgICAgICAgICAgIjsgIyBxdWV1ZWQgY2FsbHM6ICIgKyBjYWxsUXVldWUuc2l6ZSgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICB2b2lkIGRvUmVhZChTZWxlY3Rpb25LZXkga2V5KSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgIENvbm5lY3Rpb24gYyA9IChDb25uZWN0aW9uKWtleS5hdHRhY2htZW50KCk7CisgICAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICAgIHJldHVybjsgIAorICAgICAgfQorICAgICAgYy5zZXRMYXN0Q29udGFjdChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAKKyAgICAgIHRyeSB7CisgICAgICAgIGNvdW50ID0gYy5yZWFkQW5kUHJvY2VzcygpOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWVvKSB7CisgICAgICAgIHRocm93IGllbzsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiByZWFkQW5kUHJvY2VzcyB0aHJldyBleGNlcHRpb24gIiArIGUgKyAiLiBDb3VudCBvZiBieXRlcyByZWFkOiAiICsgY291bnQsIGUpOworICAgICAgICBjb3VudCA9IC0xOyAvL3NvIHRoYXQgdGhlIChjb3VudCA8IDApIGJsb2NrIGlzIGV4ZWN1dGVkCisgICAgICB9CisgICAgICBpZiAoY291bnQgPCAwKSB7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgICBMT0cuZGVidWcoZ2V0TmFtZSgpICsgIjogZGlzY29ubmVjdGluZyBjbGllbnQgIiArIAorICAgICAgICAgICAgICAgICAgICBjLmdldEhvc3RBZGRyZXNzKCkgKyAiLiBOdW1iZXIgb2YgYWN0aXZlIGNvbm5lY3Rpb25zOiAiKworICAgICAgICAgICAgICAgICAgICBudW1Db25uZWN0aW9ucyk7CisgICAgICAgIGNsb3NlQ29ubmVjdGlvbihjKTsKKyAgICAgICAgYyA9IG51bGw7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgYy5zZXRMYXN0Q29udGFjdChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICB9CisgICAgfSAgIAorCisgICAgc3luY2hyb25pemVkIHZvaWQgZG9TdG9wKCkgeworICAgICAgaWYgKHNlbGVjdG9yICE9IG51bGwpIHsKKyAgICAgICAgc2VsZWN0b3Iud2FrZXVwKCk7CisgICAgICAgIFRocmVhZC55aWVsZCgpOworICAgICAgfQorICAgICAgaWYgKGFjY2VwdENoYW5uZWwgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGFjY2VwdENoYW5uZWwuc29ja2V0KCkuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5pbmZvKGdldE5hbWUoKSArICI6RXhjZXB0aW9uIGluIGNsb3NpbmcgbGlzdGVuZXIgc29ja2V0LiAiICsgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBTZW5kcyByZXNwb25zZXMgb2YgUlBDIGJhY2sgdG8gY2xpZW50cy4KKyAgcHJpdmF0ZSBjbGFzcyBSZXNwb25kZXIgZXh0ZW5kcyBUaHJlYWQgeworICAgIHByaXZhdGUgU2VsZWN0b3Igd3JpdGVTZWxlY3RvcjsKKyAgICBwcml2YXRlIGludCBwZW5kaW5nOyAgICAgICAgIC8vIGNvbm5lY3Rpb25zIHdhaXRpbmcgdG8gcmVnaXN0ZXIKKyAgICAKKyAgICBmaW5hbCBzdGF0aWMgaW50IFBVUkdFX0lOVEVSVkFMID0gOTAwMDAwOyAvLyAxNW1pbnMKKworICAgIFJlc3BvbmRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLnNldE5hbWUoIklQQyBTZXJ2ZXIgUmVzcG9uZGVyIik7CisgICAgICB0aGlzLnNldERhZW1vbih0cnVlKTsKKyAgICAgIHdyaXRlU2VsZWN0b3IgPSBTZWxlY3Rvci5vcGVuKCk7IC8vIGNyZWF0ZSBhIHNlbGVjdG9yCisgICAgICBwZW5kaW5nID0gMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICBMT0cuaW5mbyhnZXROYW1lKCkgKyAiOiBzdGFydGluZyIpOworICAgICAgU0VSVkVSLnNldChIQmFzZVNlcnZlci50aGlzKTsKKyAgICAgIGxvbmcgbGFzdFB1cmdlVGltZSA9IDA7ICAgLy8gbGFzdCBjaGVjayBmb3Igb2xkIGNhbGxzLgorCisgICAgICB3aGlsZSAocnVubmluZykgeworICAgICAgICB0cnkgeworICAgICAgICAgIHdhaXRQZW5kaW5nKCk7ICAgICAvLyBJZiBhIGNoYW5uZWwgaXMgYmVpbmcgcmVnaXN0ZXJlZCwgd2FpdC4KKyAgICAgICAgICB3cml0ZVNlbGVjdG9yLnNlbGVjdChQVVJHRV9JTlRFUlZBTCk7CisgICAgICAgICAgSXRlcmF0b3I8U2VsZWN0aW9uS2V5PiBpdGVyID0gd3JpdGVTZWxlY3Rvci5zZWxlY3RlZEtleXMoKS5pdGVyYXRvcigpOworICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICAgICAgU2VsZWN0aW9uS2V5IGtleSA9IGl0ZXIubmV4dCgpOworICAgICAgICAgICAgaXRlci5yZW1vdmUoKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgIGlmIChrZXkuaXNWYWxpZCgpICYmIGtleS5pc1dyaXRhYmxlKCkpIHsKKyAgICAgICAgICAgICAgICAgIGRvQXN5bmNXcml0ZShrZXkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIExPRy5pbmZvKGdldE5hbWUoKSArICI6IGRvQXN5bmNXcml0ZSB0aHJldyBleGNlcHRpb24gIiArIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgIGlmIChub3cgPCBsYXN0UHVyZ2VUaW1lICsgUFVSR0VfSU5URVJWQUwpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgIH0KKyAgICAgICAgICBsYXN0UHVyZ2VUaW1lID0gbm93OworICAgICAgICAgIC8vCisgICAgICAgICAgLy8gSWYgdGhlcmUgd2VyZSBzb21lIGNhbGxzIHRoYXQgaGF2ZSBub3QgYmVlbiBzZW50IG91dCBmb3IgYQorICAgICAgICAgIC8vIGxvbmcgdGltZSwgZGlzY2FyZCB0aGVtLgorICAgICAgICAgIC8vCisgICAgICAgICAgTE9HLmRlYnVnKCJDaGVja2luZyBmb3Igb2xkIGNhbGwgcmVzcG9uc2VzLiIpOworICAgICAgICAgIEFycmF5TGlzdDxDYWxsPiBjYWxsczsKKyAgICAgICAgICAKKyAgICAgICAgICAvLyBnZXQgdGhlIGxpc3Qgb2YgY2hhbm5lbHMgZnJvbSBsaXN0IG9mIGtleXMuCisgICAgICAgICAgc3luY2hyb25pemVkICh3cml0ZVNlbGVjdG9yLmtleXMoKSkgeworICAgICAgICAgICAgY2FsbHMgPSBuZXcgQXJyYXlMaXN0PENhbGw+KHdyaXRlU2VsZWN0b3Iua2V5cygpLnNpemUoKSk7CisgICAgICAgICAgICBpdGVyID0gd3JpdGVTZWxlY3Rvci5rZXlzKCkuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgeworICAgICAgICAgICAgICBTZWxlY3Rpb25LZXkga2V5ID0gaXRlci5uZXh0KCk7CisgICAgICAgICAgICAgIENhbGwgY2FsbCA9IChDYWxsKWtleS5hdHRhY2htZW50KCk7CisgICAgICAgICAgICAgIGlmIChjYWxsICE9IG51bGwgJiYga2V5LmNoYW5uZWwoKSA9PSBjYWxsLmNvbm5lY3Rpb24uY2hhbm5lbCkgeyAKKyAgICAgICAgICAgICAgICBjYWxscy5hZGQoY2FsbCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgCisgICAgICAgICAgZm9yKENhbGwgY2FsbCA6IGNhbGxzKSB7CisgICAgICAgICAgICBkb1B1cmdlKGNhbGwsIG5vdyk7CisgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIGUpIHsKKyAgICAgICAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIGlmIChlcnJvckhhbmRsZXIuY2hlY2tPT01FKGUpKSB7CisgICAgICAgICAgICAgIExPRy5pbmZvKGdldE5hbWUoKSArICI6IGV4aXRpbmcgb24gT09NRSIpOworICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vCisgICAgICAgICAgICAvLyB3ZSBjYW4gcnVuIG91dCBvZiBtZW1vcnkgaWYgd2UgaGF2ZSB0b28gbWFueSB0aHJlYWRzCisgICAgICAgICAgICAvLyBsb2cgdGhlIGV2ZW50IGFuZCBzbGVlcCBmb3IgYSBtaW51dGUgYW5kIGdpdmUKKyAgICAgICAgICAgIC8vIHNvbWUgdGhyZWFkKHMpIGEgY2hhbmNlIHRvIGZpbmlzaAorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIExPRy53YXJuKCJPdXQgb2YgTWVtb3J5IGluIHNlcnZlciBzZWxlY3QiLCBlKTsKKyAgICAgICAgICAgIHRyeSB7IFRocmVhZC5zbGVlcCg2MDAwMCk7IH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZSkge30KKyAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cud2FybigiRXhjZXB0aW9uIGluIFJlc3BvbmRlciAiICsgCisgICAgICAgICAgICAgICAgICAgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgTE9HLmluZm8oIlN0b3BwaW5nICIgKyB0aGlzLmdldE5hbWUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGRvQXN5bmNXcml0ZShTZWxlY3Rpb25LZXkga2V5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgQ2FsbCBjYWxsID0gKENhbGwpa2V5LmF0dGFjaG1lbnQoKTsKKyAgICAgIGlmIChjYWxsID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgaWYgKGtleS5jaGFubmVsKCkgIT0gY2FsbC5jb25uZWN0aW9uLmNoYW5uZWwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJkb0FzeW5jV3JpdGU6IGJhZCBjaGFubmVsIik7CisgICAgICB9CisKKyAgICAgIHN5bmNocm9uaXplZChjYWxsLmNvbm5lY3Rpb24ucmVzcG9uc2VRdWV1ZSkgeworICAgICAgICBpZiAocHJvY2Vzc1Jlc3BvbnNlKGNhbGwuY29ubmVjdGlvbi5yZXNwb25zZVF1ZXVlLCBmYWxzZSkpIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAga2V5LmludGVyZXN0T3BzKDApOworICAgICAgICAgIH0gY2F0Y2ggKENhbmNlbGxlZEtleUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvKiBUaGUgTGlzdGVuZXIvcmVhZGVyIG1pZ2h0IGhhdmUgY2xvc2VkIHRoZSBzb2NrZXQuCisgICAgICAgICAgICAgKiBXZSBkb24ndCBleHBsaWNpdGx5IGNhbmNlbCB0aGUga2V5LCBzbyBub3Qgc3VyZSBpZiB0aGlzIHdpbGwKKyAgICAgICAgICAgICAqIGV2ZXIgZmlyZS4KKyAgICAgICAgICAgICAqIFRoaXMgd2FybmluZyBjb3VsZCBiZSByZW1vdmVkLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBMT0cud2FybigiRXhjZXB0aW9uIHdoaWxlIGNoYW5naW5nIG9wcyA6ICIgKyBlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLworICAgIC8vIFJlbW92ZSBjYWxscyB0aGF0IGhhdmUgYmVlbiBwZW5kaW5nIGluIHRoZSByZXNwb25zZVF1ZXVlIAorICAgIC8vIGZvciBhIGxvbmcgdGltZS4KKyAgICAvLworICAgIHByaXZhdGUgdm9pZCBkb1B1cmdlKENhbGwgY2FsbCwgbG9uZyBub3cpIHsKKyAgICAgIExpbmtlZExpc3Q8Q2FsbD4gcmVzcG9uc2VRdWV1ZSA9IGNhbGwuY29ubmVjdGlvbi5yZXNwb25zZVF1ZXVlOworICAgICAgc3luY2hyb25pemVkIChyZXNwb25zZVF1ZXVlKSB7CisgICAgICAgIEl0ZXJhdG9yPENhbGw+IGl0ZXIgPSByZXNwb25zZVF1ZXVlLmxpc3RJdGVyYXRvcigwKTsKKyAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7CisgICAgICAgICAgQ2FsbCBuZXh0Q2FsbCA9IGl0ZXIubmV4dCgpOworICAgICAgICAgIGlmIChub3cgPiBuZXh0Q2FsbC50aW1lc3RhbXAgKyBQVVJHRV9JTlRFUlZBTCkgeworICAgICAgICAgICAgY2xvc2VDb25uZWN0aW9uKG5leHRDYWxsLmNvbm5lY3Rpb24pOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gUHJvY2Vzc2VzIG9uZSByZXNwb25zZS4gUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBubyBtb3JlIHBlbmRpbmcKKyAgICAvLyBkYXRhIGZvciB0aGlzIGNoYW5uZWwuCisgICAgLy8KKyAgICBwcml2YXRlIGJvb2xlYW4gcHJvY2Vzc1Jlc3BvbnNlKExpbmtlZExpc3Q8Q2FsbD4gcmVzcG9uc2VRdWV1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5IYW5kbGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYm9vbGVhbiBlcnJvciA9IHRydWU7CisgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsgICAgICAgLy8gdGhlcmUgaXMgbW9yZSBkYXRhIGZvciB0aGlzIGNoYW5uZWwuCisgICAgICBpbnQgbnVtRWxlbWVudHMgPSAwOworICAgICAgQ2FsbCBjYWxsID0gbnVsbDsKKyAgICAgIHRyeSB7CisgICAgICAgIHN5bmNocm9uaXplZCAocmVzcG9uc2VRdWV1ZSkgeworICAgICAgICAgIC8vCisgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIGl0ZW1zIGZvciB0aGlzIGNoYW5uZWwsIHRoZW4gd2UgYXJlIGRvbmUKKyAgICAgICAgICAvLworICAgICAgICAgIG51bUVsZW1lbnRzID0gcmVzcG9uc2VRdWV1ZS5zaXplKCk7CisgICAgICAgICAgaWYgKG51bUVsZW1lbnRzID09IDApIHsKKyAgICAgICAgICAgIGVycm9yID0gZmFsc2U7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgIC8vIG5vIG1vcmUgZGF0YSBmb3IgdGhpcyBjaGFubmVsLgorICAgICAgICAgIH0KKyAgICAgICAgICAvLworICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIGZpcnN0IGNhbGwKKyAgICAgICAgICAvLworICAgICAgICAgIGNhbGwgPSByZXNwb25zZVF1ZXVlLnJlbW92ZUZpcnN0KCk7CisgICAgICAgICAgU29ja2V0Q2hhbm5lbCBjaGFubmVsID0gY2FsbC5jb25uZWN0aW9uLmNoYW5uZWw7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuZGVidWcoZ2V0TmFtZSgpICsgIjogcmVzcG9uZGluZyB0byAjIiArIGNhbGwuaWQgKyAiIGZyb20gIiArCisgICAgICAgICAgICAgICAgICAgICAgY2FsbC5jb25uZWN0aW9uKTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8KKyAgICAgICAgICAvLyBTZW5kIGFzIG11Y2ggZGF0YSBhcyB3ZSBjYW4gaW4gdGhlIG5vbi1ibG9ja2luZyBmYXNoaW9uCisgICAgICAgICAgLy8KKyAgICAgICAgICBpbnQgbnVtQnl0ZXMgPSBjaGFubmVsV3JpdGUoY2hhbm5lbCwgY2FsbC5yZXNwb25zZSk7CisgICAgICAgICAgaWYgKG51bUJ5dGVzIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICAgIGlmICghY2FsbC5yZXNwb25zZS5oYXNSZW1haW5pbmcoKSkgeworICAgICAgICAgICAgY2FsbC5jb25uZWN0aW9uLmRlY1JwY0NvdW50KCk7CisgICAgICAgICAgICBpZiAobnVtRWxlbWVudHMgPT0gMSkgeyAgICAvLyBsYXN0IGNhbGwgZnVsbHkgcHJvY2Vzc2VzLgorICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgICAgICAgICAgICAgLy8gbm8gbW9yZSBkYXRhIGZvciB0aGlzIGNoYW5uZWwuCisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBkb25lID0gZmFsc2U7ICAgICAgICAgICAgLy8gbW9yZSBjYWxscyBwZW5kaW5nIHRvIGJlIHNlbnQuCisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKGdldE5hbWUoKSArICI6IHJlc3BvbmRpbmcgdG8gIyIgKyBjYWxsLmlkICsgIiBmcm9tICIgKworICAgICAgICAgICAgICAgICAgICAgICAgY2FsbC5jb25uZWN0aW9uICsgIiBXcm90ZSAiICsgbnVtQnl0ZXMgKyAiIGJ5dGVzLiIpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLworICAgICAgICAgICAgLy8gSWYgd2Ugd2VyZSB1bmFibGUgdG8gd3JpdGUgdGhlIGVudGlyZSByZXNwb25zZSBvdXQsIHRoZW4gCisgICAgICAgICAgICAvLyBpbnNlcnQgaW4gU2VsZWN0b3IgcXVldWUuIAorICAgICAgICAgICAgLy8KKyAgICAgICAgICAgIGNhbGwuY29ubmVjdGlvbi5yZXNwb25zZVF1ZXVlLmFkZEZpcnN0KGNhbGwpOworICAgICAgICAgICAgCisgICAgICAgICAgICBpZiAoaW5IYW5kbGVyKSB7CisgICAgICAgICAgICAgIC8vIHNldCB0aGUgc2VydmUgdGltZSB3aGVuIHRoZSByZXNwb25zZSBoYXMgdG8gYmUgc2VudCBsYXRlcgorICAgICAgICAgICAgICBjYWxsLnRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgaW5jUGVuZGluZygpOworICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIFdha2V1cCB0aGUgdGhyZWFkIGJsb2NrZWQgb24gc2VsZWN0LCBvbmx5IHRoZW4gY2FuIHRoZSBjYWxsIAorICAgICAgICAgICAgICAgIC8vIHRvIGNoYW5uZWwucmVnaXN0ZXIoKSBjb21wbGV0ZS4KKyAgICAgICAgICAgICAgICB3cml0ZVNlbGVjdG9yLndha2V1cCgpOworICAgICAgICAgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIod3JpdGVTZWxlY3RvciwgU2VsZWN0aW9uS2V5Lk9QX1dSSVRFLCBjYWxsKTsKKyAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xvc2VkQ2hhbm5lbEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy9JdHMgb2suIGNoYW5uZWwgbWlnaHQgYmUgY2xvc2VkIGVsc2Ugd2hlcmUuCisgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgZGVjUGVuZGluZygpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKGdldE5hbWUoKSArICI6IHJlc3BvbmRpbmcgdG8gIyIgKyBjYWxsLmlkICsgIiBmcm9tICIgKworICAgICAgICAgICAgICAgICAgICAgICAgY2FsbC5jb25uZWN0aW9uICsgIiBXcm90ZSBwYXJ0aWFsICIgKyBudW1CeXRlcyArIAorICAgICAgICAgICAgICAgICAgICAgICAgIiBieXRlcy4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZXJyb3IgPSBmYWxzZTsgICAgICAgICAgICAgIC8vIGV2ZXJ5dGhpbmcgd2VudCBvZmYgd2VsbAorICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBpZiAoZXJyb3IgJiYgY2FsbCAhPSBudWxsKSB7CisgICAgICAgICAgTE9HLndhcm4oZ2V0TmFtZSgpKyIsIGNhbGwgIiArIGNhbGwgKyAiOiBvdXRwdXQgZXJyb3IiKTsKKyAgICAgICAgICBkb25lID0gdHJ1ZTsgICAgICAgICAgICAgICAvLyBlcnJvci4gbm8gbW9yZSBkYXRhIGZvciB0aGlzIGNoYW5uZWwuCisgICAgICAgICAgY2xvc2VDb25uZWN0aW9uKGNhbGwuY29ubmVjdGlvbik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBkb25lOworICAgIH0KKworICAgIC8vCisgICAgLy8gRW5xdWV1ZSBhIHJlc3BvbnNlIGZyb20gdGhlIGFwcGxpY2F0aW9uLgorICAgIC8vCisgICAgdm9pZCBkb1Jlc3BvbmQoQ2FsbCBjYWxsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgc3luY2hyb25pemVkIChjYWxsLmNvbm5lY3Rpb24ucmVzcG9uc2VRdWV1ZSkgeworICAgICAgICBjYWxsLmNvbm5lY3Rpb24ucmVzcG9uc2VRdWV1ZS5hZGRMYXN0KGNhbGwpOworICAgICAgICBpZiAoY2FsbC5jb25uZWN0aW9uLnJlc3BvbnNlUXVldWUuc2l6ZSgpID09IDEpIHsKKyAgICAgICAgICBwcm9jZXNzUmVzcG9uc2UoY2FsbC5jb25uZWN0aW9uLnJlc3BvbnNlUXVldWUsIHRydWUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBpbmNQZW5kaW5nKCkgeyAgIC8vIGNhbGwgd2FpdGluZyB0byBiZSBlbnF1ZXVlZC4KKyAgICAgIHBlbmRpbmcrKzsKKyAgICB9CisKKyAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGRlY1BlbmRpbmcoKSB7IC8vIGNhbGwgZG9uZSBlbnF1ZXVlaW5nLgorICAgICAgcGVuZGluZy0tOworICAgICAgbm90aWZ5KCk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCB3YWl0UGVuZGluZygpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgICB3aGlsZSAocGVuZGluZyA+IDApIHsKKyAgICAgICAgd2FpdCgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBSZWFkcyBjYWxscyBmcm9tIGEgY29ubmVjdGlvbiBhbmQgcXVldWVzIHRoZW0gZm9yIGhhbmRsaW5nLiAqLworICBwcml2YXRlIGNsYXNzIENvbm5lY3Rpb24geworICAgIHByaXZhdGUgYm9vbGVhbiB2ZXJzaW9uUmVhZCA9IGZhbHNlOyAvL2lmIGluaXRpYWwgc2lnbmF0dXJlIGFuZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ZlcnNpb24gYXJlIHJlYWQKKyAgICBwcml2YXRlIGJvb2xlYW4gaGVhZGVyUmVhZCA9IGZhbHNlOyAgLy9pZiB0aGUgY29ubmVjdGlvbiBoZWFkZXIgdGhhdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZvbGxvd3MgdmVyc2lvbiBpcyByZWFkLgorICAgIHByb3RlY3RlZCBTb2NrZXRDaGFubmVsIGNoYW5uZWw7CisgICAgcHJpdmF0ZSBCeXRlQnVmZmVyIGRhdGE7CisgICAgcHJpdmF0ZSBCeXRlQnVmZmVyIGRhdGFMZW5ndGhCdWZmZXI7CisgICAgcHJvdGVjdGVkIExpbmtlZExpc3Q8Q2FsbD4gcmVzcG9uc2VRdWV1ZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGludCBycGNDb3VudCA9IDA7IC8vIG51bWJlciBvZiBvdXRzdGFuZGluZyBycGNzCisgICAgcHJpdmF0ZSBsb25nIGxhc3RDb250YWN0OworICAgIHByaXZhdGUgaW50IGRhdGFMZW5ndGg7CisgICAgcHJvdGVjdGVkIFNvY2tldCBzb2NrZXQ7CisgICAgLy8gQ2FjaGUgdGhlIHJlbW90ZSBob3N0ICYgcG9ydCBpbmZvIHNvIHRoYXQgZXZlbiBpZiB0aGUgc29ja2V0IGlzIAorICAgIC8vIGRpc2Nvbm5lY3RlZCwgd2UgY2FuIHNheSB3aGVyZSBpdCB1c2VkIHRvIGNvbm5lY3QgdG8uCisgICAgcHJpdmF0ZSBTdHJpbmcgaG9zdEFkZHJlc3M7CisgICAgcHJpdmF0ZSBpbnQgcmVtb3RlUG9ydDsKKyAgICBwcm90ZWN0ZWQgVXNlckdyb3VwSW5mb3JtYXRpb24gdGlja2V0ID0gbnVsbDsKKworICAgIHB1YmxpYyBDb25uZWN0aW9uKFNvY2tldENoYW5uZWwgY2hhbm5lbCwgbG9uZyBsYXN0Q29udGFjdCkgeworICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKKyAgICAgIHRoaXMubGFzdENvbnRhY3QgPSBsYXN0Q29udGFjdDsKKyAgICAgIHRoaXMuZGF0YSA9IG51bGw7CisgICAgICB0aGlzLmRhdGFMZW5ndGhCdWZmZXIgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKDQpOworICAgICAgdGhpcy5zb2NrZXQgPSBjaGFubmVsLnNvY2tldCgpOworICAgICAgSW5ldEFkZHJlc3MgYWRkciA9IHNvY2tldC5nZXRJbmV0QWRkcmVzcygpOworICAgICAgaWYgKGFkZHIgPT0gbnVsbCkgeworICAgICAgICB0aGlzLmhvc3RBZGRyZXNzID0gIipVbmtub3duKiI7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aGlzLmhvc3RBZGRyZXNzID0gYWRkci5nZXRIb3N0QWRkcmVzcygpOworICAgICAgfQorICAgICAgdGhpcy5yZW1vdGVQb3J0ID0gc29ja2V0LmdldFBvcnQoKTsKKyAgICAgIHRoaXMucmVzcG9uc2VRdWV1ZSA9IG5ldyBMaW5rZWRMaXN0PENhbGw+KCk7CisgICAgICBpZiAoc29ja2V0U2VuZEJ1ZmZlclNpemUgIT0gMCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHNvY2tldC5zZXRTZW5kQnVmZmVyU2l6ZShzb2NrZXRTZW5kQnVmZmVyU2l6ZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cud2FybigiQ29ubmVjdGlvbjogdW5hYmxlIHRvIHNldCBzb2NrZXQgc2VuZCBidWZmZXIgc2l6ZSB0byAiICsKKyAgICAgICAgICAgICAgICAgICBzb2NrZXRTZW5kQnVmZmVyU2l6ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9ICAgCisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgcmV0dXJuIGdldEhvc3RBZGRyZXNzKCkgKyAiOiIgKyByZW1vdGVQb3J0OyAKKyAgICB9CisgICAgCisgICAgcHVibGljIFN0cmluZyBnZXRIb3N0QWRkcmVzcygpIHsKKyAgICAgIHJldHVybiBob3N0QWRkcmVzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRMYXN0Q29udGFjdChsb25nIGxhc3RDb250YWN0KSB7CisgICAgICB0aGlzLmxhc3RDb250YWN0ID0gbGFzdENvbnRhY3Q7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0TGFzdENvbnRhY3QoKSB7CisgICAgICByZXR1cm4gbGFzdENvbnRhY3Q7CisgICAgfQorCisgICAgLyogUmV0dXJuIHRydWUgaWYgdGhlIGNvbm5lY3Rpb24gaGFzIG5vIG91dHN0YW5kaW5nIHJwYyAqLworICAgIHByaXZhdGUgYm9vbGVhbiBpc0lkbGUoKSB7CisgICAgICByZXR1cm4gcnBjQ291bnQgPT0gMDsKKyAgICB9CisgICAgCisgICAgLyogRGVjcmVtZW50IHRoZSBvdXRzdGFuZGluZyBSUEMgY291bnQgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBkZWNScGNDb3VudCgpIHsKKyAgICAgIHJwY0NvdW50LS07CisgICAgfQorICAgIAorICAgIC8qIEluY3JlbWVudCB0aGUgb3V0c3RhbmRpbmcgUlBDIGNvdW50ICovCisgICAgcHJpdmF0ZSB2b2lkIGluY1JwY0NvdW50KCkgeworICAgICAgcnBjQ291bnQrKzsKKyAgICB9CisgICAgCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gdGltZWRPdXQobG9uZyBjdXJyZW50VGltZSkgeworICAgICAgaWYgKGlzSWRsZSgpICYmIGN1cnJlbnRUaW1lIC0gIGxhc3RDb250YWN0ID4gbWF4SWRsZVRpbWUpCisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVhZEFuZFByb2Nlc3MoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIC8qIFJlYWQgYXQgbW9zdCBvbmUgUlBDLiBJZiB0aGUgaGVhZGVyIGlzIG5vdCByZWFkIGNvbXBsZXRlbHkgeWV0CisgICAgICAgICAqIHRoZW4gaXRlcmF0ZSB1bnRpbCB3ZSByZWFkIGZpcnN0IFJQQyBvciB1bnRpbCB0aGVyZSBpcyBubyBkYXRhIGxlZnQuCisgICAgICAgICAqLyAgICAKKyAgICAgICAgaW50IGNvdW50ID0gLTE7CisgICAgICAgIGlmIChkYXRhTGVuZ3RoQnVmZmVyLnJlbWFpbmluZygpID4gMCkgeworICAgICAgICAgIGNvdW50ID0gY2hhbm5lbFJlYWQoY2hhbm5lbCwgZGF0YUxlbmd0aEJ1ZmZlcik7ICAgICAgIAorICAgICAgICAgIGlmIChjb3VudCA8IDAgfHwgZGF0YUxlbmd0aEJ1ZmZlci5yZW1haW5pbmcoKSA+IDApIAorICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICB9CisgICAgICAKKyAgICAgICAgaWYgKCF2ZXJzaW9uUmVhZCkgeworICAgICAgICAgIC8vRXZlcnkgY29ubmVjdGlvbiBpcyBleHBlY3RlZCB0byBzZW5kIHRoZSBoZWFkZXIuCisgICAgICAgICAgQnl0ZUJ1ZmZlciB2ZXJzaW9uQnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZSgxKTsKKyAgICAgICAgICBjb3VudCA9IGNoYW5uZWxSZWFkKGNoYW5uZWwsIHZlcnNpb25CdWZmZXIpOworICAgICAgICAgIGlmIChjb3VudCA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gY291bnQ7CisgICAgICAgICAgfQorICAgICAgICAgIGludCB2ZXJzaW9uID0gdmVyc2lvbkJ1ZmZlci5nZXQoMCk7CisgICAgICAgICAgCisgICAgICAgICAgZGF0YUxlbmd0aEJ1ZmZlci5mbGlwKCk7ICAgICAgICAgIAorICAgICAgICAgIGlmICghSEVBREVSLmVxdWFscyhkYXRhTGVuZ3RoQnVmZmVyKSB8fCB2ZXJzaW9uICE9IENVUlJFTlRfVkVSU0lPTikgeworICAgICAgICAgICAgLy9XYXJuaW5nIGlzIG9rIHNpbmNlIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlbi4KKyAgICAgICAgICAgIExPRy53YXJuKCJJbmNvcnJlY3QgaGVhZGVyIG9yIHZlcnNpb24gbWlzbWF0Y2ggZnJvbSAiICsgCisgICAgICAgICAgICAgICAgICAgICBob3N0QWRkcmVzcyArICI6IiArIHJlbW90ZVBvcnQgKworICAgICAgICAgICAgICAgICAgICAgIiBnb3QgdmVyc2lvbiAiICsgdmVyc2lvbiArIAorICAgICAgICAgICAgICAgICAgICAgIiBleHBlY3RlZCB2ZXJzaW9uICIgKyBDVVJSRU5UX1ZFUlNJT04pOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgIH0KKyAgICAgICAgICBkYXRhTGVuZ3RoQnVmZmVyLmNsZWFyKCk7CisgICAgICAgICAgdmVyc2lvblJlYWQgPSB0cnVlOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAoZGF0YSA9PSBudWxsKSB7CisgICAgICAgICAgZGF0YUxlbmd0aEJ1ZmZlci5mbGlwKCk7CisgICAgICAgICAgZGF0YUxlbmd0aCA9IGRhdGFMZW5ndGhCdWZmZXIuZ2V0SW50KCk7CisgICAgICAgCisgICAgICAgICAgaWYgKGRhdGFMZW5ndGggPT0gSEJhc2VDbGllbnQuUElOR19DQUxMX0lEKSB7CisgICAgICAgICAgICBkYXRhTGVuZ3RoQnVmZmVyLmNsZWFyKCk7CisgICAgICAgICAgICByZXR1cm4gMDsgIC8vcGluZyBtZXNzYWdlCisgICAgICAgICAgfQorICAgICAgICAgIGRhdGEgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKGRhdGFMZW5ndGgpOworICAgICAgICAgIGluY1JwY0NvdW50KCk7ICAvLyBJbmNyZW1lbnQgdGhlIHJwYyBjb3VudAorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBjb3VudCA9IGNoYW5uZWxSZWFkKGNoYW5uZWwsIGRhdGEpOworICAgICAgICAKKyAgICAgICAgaWYgKGRhdGEucmVtYWluaW5nKCkgPT0gMCkgeworICAgICAgICAgIGRhdGFMZW5ndGhCdWZmZXIuY2xlYXIoKTsKKyAgICAgICAgICBkYXRhLmZsaXAoKTsKKyAgICAgICAgICBpZiAoaGVhZGVyUmVhZCkgeworICAgICAgICAgICAgcHJvY2Vzc0RhdGEoKTsKKyAgICAgICAgICAgIGRhdGEgPSBudWxsOworICAgICAgICAgICAgcmV0dXJuIGNvdW50OworICAgICAgICAgIH0KKyAgICAgICAgICBwcm9jZXNzSGVhZGVyKCk7CisgICAgICAgICAgaGVhZGVyUmVhZCA9IHRydWU7CisgICAgICAgICAgZGF0YSA9IG51bGw7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0gCisgICAgICAgIHJldHVybiBjb3VudDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLy8gUmVhZHMgdGhlIGhlYWRlciBmb2xsb3dpbmcgdmVyc2lvbgorICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzSGVhZGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8qIEluIHRoZSBjdXJyZW50IHZlcnNpb24sIGl0IGlzIGp1c3QgYSB0aWNrZXQuCisgICAgICAgKiBMYXRlciB3ZSBjb3VsZCBpbnRyb2R1Y2UgYSAiQ29ubmVjdGlvbkhlYWRlciIgY2xhc3MuCisgICAgICAgKi8KKyAgICAgIERhdGFJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgIG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEuYXJyYXkoKSkpOworICAgICAgdGlja2V0ID0gKFVzZXJHcm91cEluZm9ybWF0aW9uKSBPYmplY3RXcml0YWJsZS5yZWFkT2JqZWN0KGluLCBjb25mKTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NEYXRhKCkgdGhyb3dzICBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgICAgRGF0YUlucHV0U3RyZWFtIGRpcyA9CisgICAgICAgIG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGRhdGEuYXJyYXkoKSkpOworICAgICAgaW50IGlkID0gZGlzLnJlYWRJbnQoKTsgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byByZWFkIGFuIGlkCisgICAgICAgIAorICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKQorICAgICAgICBMT0cuZGVidWcoIiBnb3QgIyIgKyBpZCk7CisgICAgICAgICAgICAKKyAgICAgIFdyaXRhYmxlIHBhcmFtID0gKFdyaXRhYmxlKSBSZWZsZWN0aW9uVXRpbHMubmV3SW5zdGFuY2UocGFyYW1DbGFzcywgY29uZik7CisgICAgICBwYXJhbS5yZWFkRmllbGRzKGRpcyk7ICAgICAgICAKKyAgICAgICAgCisgICAgICBDYWxsIGNhbGwgPSBuZXcgQ2FsbChpZCwgcGFyYW0sIHRoaXMpOworICAgICAgY2FsbFF1ZXVlLnB1dChjYWxsKTsgICAgICAgICAgICAgIC8vIHF1ZXVlIHRoZSBjYWxsOyBtYXliZSBibG9ja2VkIGhlcmUKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgY2xvc2UoKSB7CisgICAgICBkYXRhID0gbnVsbDsKKyAgICAgIGRhdGFMZW5ndGhCdWZmZXIgPSBudWxsOworICAgICAgaWYgKCFjaGFubmVsLmlzT3BlbigpKQorICAgICAgICByZXR1cm47CisgICAgICB0cnkge3NvY2tldC5zaHV0ZG93bk91dHB1dCgpO30gY2F0Y2goRXhjZXB0aW9uIGUpIHt9CisgICAgICBpZiAoY2hhbm5lbC5pc09wZW4oKSkgeworICAgICAgICB0cnkge2NoYW5uZWwuY2xvc2UoKTt9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7fQorICAgICAgfQorICAgICAgdHJ5IHtzb2NrZXQuY2xvc2UoKTt9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7fQorICAgIH0KKyAgfQorCisgIC8qKiBIYW5kbGVzIHF1ZXVlZCBjYWxscyAuICovCisgIHByaXZhdGUgY2xhc3MgSGFuZGxlciBleHRlbmRzIFRocmVhZCB7CisgICAgcHVibGljIEhhbmRsZXIoaW50IGluc3RhbmNlTnVtYmVyKSB7CisgICAgICB0aGlzLnNldERhZW1vbih0cnVlKTsKKyAgICAgIHRoaXMuc2V0TmFtZSgiSVBDIFNlcnZlciBoYW5kbGVyICIrIGluc3RhbmNlTnVtYmVyICsgIiBvbiAiICsgcG9ydCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIjogc3RhcnRpbmciKTsKKyAgICAgIFNFUlZFUi5zZXQoSEJhc2VTZXJ2ZXIudGhpcyk7CisgICAgICBmaW5hbCBpbnQgYnVmZmVyc2l6ZSA9IDE2ICogMTAyNDsKKyAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBidWYgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKGJ1ZmZlcnNpemUpOworICAgICAgd2hpbGUgKHJ1bm5pbmcpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBDYWxsIGNhbGwgPSBjYWxsUXVldWUudGFrZSgpOyAvLyBwb3AgdGhlIHF1ZXVlOyBtYXliZSBibG9ja2VkIGhlcmUKKworICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiOiBoYXMgIyIgKyBjYWxsLmlkICsgIiBmcm9tICIgKworICAgICAgICAgICAgICAgICAgICAgIGNhbGwuY29ubmVjdGlvbik7CisgICAgICAgICAgCisgICAgICAgICAgU3RyaW5nIGVycm9yQ2xhc3MgPSBudWxsOworICAgICAgICAgIFN0cmluZyBlcnJvciA9IG51bGw7CisgICAgICAgICAgV3JpdGFibGUgdmFsdWUgPSBudWxsOworICAgICAgICAgIAorICAgICAgICAgIEN1ckNhbGwuc2V0KGNhbGwpOworICAgICAgICAgIFVzZXJHcm91cEluZm9ybWF0aW9uIHByZXZpb3VzID0gVXNlckdyb3VwSW5mb3JtYXRpb24uZ2V0Q3VycmVudFVHSSgpOworICAgICAgICAgIFVzZXJHcm91cEluZm9ybWF0aW9uLnNldEN1cnJlbnRVR0koY2FsbC5jb25uZWN0aW9uLnRpY2tldCk7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHZhbHVlID0gY2FsbChjYWxsLnBhcmFtLCBjYWxsLnRpbWVzdGFtcCk7ICAgICAgICAgICAgIC8vIG1ha2UgdGhlIGNhbGwKKyAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpKyIsIGNhbGwgIitjYWxsKyI6IGVycm9yOiAiICsgZSwgZSk7CisgICAgICAgICAgICBlcnJvckNsYXNzID0gZS5nZXRDbGFzcygpLmdldE5hbWUoKTsKKyAgICAgICAgICAgIGVycm9yID0gU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBVc2VyR3JvdXBJbmZvcm1hdGlvbi5zZXRDdXJyZW50VUdJKHByZXZpb3VzKTsKKyAgICAgICAgICBDdXJDYWxsLnNldChudWxsKTsKKworICAgICAgICAgIGlmIChidWYuc2l6ZSgpID4gYnVmZmVyc2l6ZSkgeworICAgICAgICAgICAgLy8gQWxsb2NhdGUgYSBuZXcgQkFPUyBhcyByZXNldCBvbmx5IG1vdmVzIHNpemUgYmFjayB0byB6ZXJvIGJ1dAorICAgICAgICAgICAgLy8ga2VlcHMgdGhlIGJ1ZmZlciBvZiB3aGF0ZXZlciB0aGUgbGFyZ2VzdCB3cml0ZSB3YXMgLS0gc2VlCisgICAgICAgICAgICAvLyBoYmFzZS05MDAuCisgICAgICAgICAgICBidWYgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKGJ1ZmZlcnNpemUpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBidWYucmVzZXQoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShidWYpOworICAgICAgICAgIG91dC53cml0ZUludChjYWxsLmlkKTsgICAgICAgICAgICAgICAgLy8gd3JpdGUgY2FsbCBpZAorICAgICAgICAgIG91dC53cml0ZUJvb2xlYW4oZXJyb3IgIT0gbnVsbCk7ICAgICAgLy8gd3JpdGUgZXJyb3IgZmxhZworCisgICAgICAgICAgaWYgKGVycm9yID09IG51bGwpIHsKKyAgICAgICAgICAgIHZhbHVlLndyaXRlKG91dCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVTdHJpbmcob3V0LCBlcnJvckNsYXNzKTsKKyAgICAgICAgICAgIFdyaXRhYmxlVXRpbHMud3JpdGVTdHJpbmcob3V0LCBlcnJvcik7CisgICAgICAgICAgfQorICAgICAgICAgIGNhbGwuc2V0UmVzcG9uc2UoQnl0ZUJ1ZmZlci53cmFwKGJ1Zi50b0J5dGVBcnJheSgpKSk7CisgICAgICAgICAgcmVzcG9uZGVyLmRvUmVzcG9uZChjYWxsKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIGlmIChydW5uaW5nKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmV4cGVjdGVkIC0tIGxvZyBpdAorICAgICAgICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIiBjYXVnaHQ6ICIgKworICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKE91dE9mTWVtb3J5RXJyb3IgZSkgeworICAgICAgICAgIGlmIChlcnJvckhhbmRsZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgaWYgKGVycm9ySGFuZGxlci5jaGVja09PTUUoZSkpIHsKKyAgICAgICAgICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIjogZXhpdGluZyBvbiBPT01FIik7CisgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gcmV0aHJvdyBpZiBubyBoYW5kbGVyCisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuaW5mbyhnZXROYW1lKCkgKyAiIGNhdWdodDogIiArCisgICAgICAgICAgICAgICAgICAgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIjogZXhpdGluZyIpOworICAgIH0KKworICB9CisgIAorICBwcm90ZWN0ZWQgSEJhc2VTZXJ2ZXIoU3RyaW5nIGJpbmRBZGRyZXNzLCBpbnQgcG9ydCwKKyAgICAgICAgICAgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZT4gcGFyYW1DbGFzcywgaW50IGhhbmRsZXJDb3VudCwgCisgICAgICAgICAgICAgICAgICBDb25maWd1cmF0aW9uIGNvbmYpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIAorICB7CisgICAgdGhpcyhiaW5kQWRkcmVzcywgcG9ydCwgcGFyYW1DbGFzcywgaGFuZGxlckNvdW50LCAgY29uZiwgSW50ZWdlci50b1N0cmluZyhwb3J0KSk7CisgIH0KKyAgLyoqIENvbnN0cnVjdHMgYSBzZXJ2ZXIgbGlzdGVuaW5nIG9uIHRoZSBuYW1lZCBwb3J0IGFuZCBhZGRyZXNzLiAgUGFyYW1ldGVycyBwYXNzZWQgbXVzdAorICAgKiBiZSBvZiB0aGUgbmFtZWQgY2xhc3MuICBUaGUgPGNvZGU+aGFuZGxlckNvdW50PC9oYW5kbGVyQ291bnQ+IGRldGVybWluZXMKKyAgICogdGhlIG51bWJlciBvZiBoYW5kbGVyIHRocmVhZHMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcHJvY2VzcyBjYWxscy4KKyAgICogCisgICAqLworICBwcm90ZWN0ZWQgSEJhc2VTZXJ2ZXIoU3RyaW5nIGJpbmRBZGRyZXNzLCBpbnQgcG9ydCwgCisgICAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGU+IHBhcmFtQ2xhc3MsIGludCBoYW5kbGVyQ291bnQsIAorICAgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25mLCBTdHJpbmcgc2VydmVyTmFtZSkgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmJpbmRBZGRyZXNzID0gYmluZEFkZHJlc3M7CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB0aGlzLnBvcnQgPSBwb3J0OworICAgIHRoaXMucGFyYW1DbGFzcyA9IHBhcmFtQ2xhc3M7CisgICAgdGhpcy5oYW5kbGVyQ291bnQgPSBoYW5kbGVyQ291bnQ7CisgICAgdGhpcy5zb2NrZXRTZW5kQnVmZmVyU2l6ZSA9IDA7CisgICAgdGhpcy5tYXhRdWV1ZVNpemUgPSBoYW5kbGVyQ291bnQgKiBNQVhfUVVFVUVfU0laRV9QRVJfSEFORExFUjsKKyAgICB0aGlzLmNhbGxRdWV1ZSAgPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxDYWxsPihtYXhRdWV1ZVNpemUpOyAKKyAgICB0aGlzLm1heElkbGVUaW1lID0gMipjb25mLmdldEludCgiaXBjLmNsaWVudC5jb25uZWN0aW9uLm1heGlkbGV0aW1lIiwgMTAwMCk7CisgICAgdGhpcy5tYXhDb25uZWN0aW9uc1RvTnVrZSA9IGNvbmYuZ2V0SW50KCJpcGMuY2xpZW50LmtpbGwubWF4IiwgMTApOworICAgIHRoaXMudGhyZXNob2xkSWRsZUNvbm5lY3Rpb25zID0gY29uZi5nZXRJbnQoImlwYy5jbGllbnQuaWRsZXRocmVzaG9sZCIsIDQwMDApOworICAgIAorICAgIC8vIFN0YXJ0IHRoZSBsaXN0ZW5lciBoZXJlIGFuZCBsZXQgaXQgYmluZCB0byB0aGUgcG9ydAorICAgIGxpc3RlbmVyID0gbmV3IExpc3RlbmVyKCk7CisgICAgdGhpcy5wb3J0ID0gbGlzdGVuZXIuZ2V0QWRkcmVzcygpLmdldFBvcnQoKTsgICAgCisgICAgdGhpcy5ycGNNZXRyaWNzID0gbmV3IEhCYXNlUnBjTWV0cmljcyhzZXJ2ZXJOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKHRoaXMucG9ydCkpOworICAgIHRoaXMudGNwTm9EZWxheSA9IGNvbmYuZ2V0Qm9vbGVhbigiaXBjLnNlcnZlci50Y3Bub2RlbGF5IiwgZmFsc2UpOworCisgICAgLy8gQ3JlYXRlIHRoZSByZXNwb25kZXIgaGVyZQorICAgIHJlc3BvbmRlciA9IG5ldyBSZXNwb25kZXIoKTsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIGNsb3NlQ29ubmVjdGlvbihDb25uZWN0aW9uIGNvbm5lY3Rpb24pIHsKKyAgICBzeW5jaHJvbml6ZWQgKGNvbm5lY3Rpb25MaXN0KSB7CisgICAgICBpZiAoY29ubmVjdGlvbkxpc3QucmVtb3ZlKGNvbm5lY3Rpb24pKQorICAgICAgICBudW1Db25uZWN0aW9ucy0tOworICAgIH0KKyAgICBjb25uZWN0aW9uLmNsb3NlKCk7CisgIH0KKyAgCisgIC8qKiBTZXRzIHRoZSBzb2NrZXQgYnVmZmVyIHNpemUgdXNlZCBmb3IgcmVzcG9uZGluZyB0byBSUENzLgorICAgKiBAcGFyYW0gc2l6ZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0U29ja2V0U2VuZEJ1ZlNpemUoaW50IHNpemUpIHsgdGhpcy5zb2NrZXRTZW5kQnVmZmVyU2l6ZSA9IHNpemU7IH0KKworICAvKiogU3RhcnRzIHRoZSBzZXJ2aWNlLiAgTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGFueSBjYWxscyB3aWxsIGJlIGhhbmRsZWQuICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBzdGFydCgpIHsKKyAgICByZXNwb25kZXIuc3RhcnQoKTsKKyAgICBsaXN0ZW5lci5zdGFydCgpOworICAgIGhhbmRsZXJzID0gbmV3IEhhbmRsZXJbaGFuZGxlckNvdW50XTsKKyAgICAKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGhhbmRsZXJDb3VudDsgaSsrKSB7CisgICAgICBoYW5kbGVyc1tpXSA9IG5ldyBIYW5kbGVyKGkpOworICAgICAgaGFuZGxlcnNbaV0uc3RhcnQoKTsKKyAgICB9CisgIH0KKworICAvKiogU3RvcHMgdGhlIHNlcnZpY2UuICBObyBuZXcgY2FsbHMgd2lsbCBiZSBoYW5kbGVkIGFmdGVyIHRoaXMgaXMgY2FsbGVkLiAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc3RvcCgpIHsKKyAgICBMT0cuaW5mbygiU3RvcHBpbmcgc2VydmVyIG9uICIgKyBwb3J0KTsKKyAgICBydW5uaW5nID0gZmFsc2U7CisgICAgaWYgKGhhbmRsZXJzICE9IG51bGwpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFuZGxlckNvdW50OyBpKyspIHsKKyAgICAgICAgaWYgKGhhbmRsZXJzW2ldICE9IG51bGwpIHsKKyAgICAgICAgICBoYW5kbGVyc1tpXS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBsaXN0ZW5lci5pbnRlcnJ1cHQoKTsKKyAgICBsaXN0ZW5lci5kb1N0b3AoKTsKKyAgICByZXNwb25kZXIuaW50ZXJydXB0KCk7CisgICAgbm90aWZ5QWxsKCk7CisgICAgaWYgKHRoaXMucnBjTWV0cmljcyAhPSBudWxsKSB7CisgICAgICB0aGlzLnJwY01ldHJpY3Muc2h1dGRvd24oKTsKKyAgICB9CisgIH0KKworICAvKiogV2FpdCBmb3IgdGhlIHNlcnZlciB0byBiZSBzdG9wcGVkLgorICAgKiBEb2VzIG5vdCB3YWl0IGZvciBhbGwgc3VidGhyZWFkcyB0byBmaW5pc2guCisgICAqICBTZWUge0BsaW5rICNzdG9wKCl9LgorICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgam9pbigpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgd2hpbGUgKHJ1bm5pbmcpIHsKKyAgICAgIHdhaXQoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJuIHRoZSBzb2NrZXQgKGlwK3BvcnQpIG9uIHdoaWNoIHRoZSBSUEMgc2VydmVyIGlzIGxpc3RlbmluZyB0by4KKyAgICogQHJldHVybiB0aGUgc29ja2V0IChpcCtwb3J0KSBvbiB3aGljaCB0aGUgUlBDIHNlcnZlciBpcyBsaXN0ZW5pbmcgdG8uCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIEluZXRTb2NrZXRBZGRyZXNzIGdldExpc3RlbmVyQWRkcmVzcygpIHsKKyAgICByZXR1cm4gbGlzdGVuZXIuZ2V0QWRkcmVzcygpOworICB9CisgIAorICAvKiogQ2FsbGVkIGZvciBlYWNoIGNhbGwuIAorICAgKiBAcGFyYW0gcGFyYW0gCisgICAqIEBwYXJhbSByZWNlaXZlVGltZSAKKyAgICogQHJldHVybiBXcml0YWJsZSAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IFdyaXRhYmxlIGNhbGwoV3JpdGFibGUgcGFyYW0sIGxvbmcgcmVjZWl2ZVRpbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIFRoZSBudW1iZXIgb2Ygb3BlbiBSUEMgY29uZWN0aW9ucworICAgKiBAcmV0dXJuIHRoZSBudW1iZXIgb2Ygb3BlbiBycGMgY29ubmVjdGlvbnMKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0TnVtT3BlbkNvbm5lY3Rpb25zKCkgeworICAgIHJldHVybiBudW1Db25uZWN0aW9uczsKKyAgfQorICAKKyAgLyoqCisgICAqIFRoZSBudW1iZXIgb2YgcnBjIGNhbGxzIGluIHRoZSBxdWV1ZS4KKyAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHJwYyBjYWxscyBpbiB0aGUgcXVldWUuCisgICAqLworICBwdWJsaWMgaW50IGdldENhbGxRdWV1ZUxlbigpIHsKKyAgICByZXR1cm4gY2FsbFF1ZXVlLnNpemUoKTsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIGhhbmRsZXIgZm9yIGNhbGxpbmcgb3V0IG9mIFJQQyBmb3IgZXJyb3IgY29uZGl0aW9ucy4KKyAgICogQHBhcmFtIGhhbmRsZXIgdGhlIGhhbmRsZXIgaW1wbGVtZW50YXRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEVycm9ySGFuZGxlcihIQmFzZVJQQ0Vycm9ySGFuZGxlciBoYW5kbGVyKSB7CisgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBoYW5kbGVyOworICB9ICAgICAgCisKKyAgLyoqCisgICAqIFdoZW4gdGhlIHJlYWQgb3Igd3JpdGUgYnVmZmVyIHNpemUgaXMgbGFyZ2VyIHRoYW4gdGhpcyBsaW1pdCwgaS9vIHdpbGwgYmUgCisgICAqIGRvbmUgaW4gY2h1bmtzIG9mIHRoaXMgc2l6ZS4gTW9zdCBSUEMgcmVxdWVzdHMgYW5kIHJlc3BvbnNlcyB3b3VsZCBiZQorICAgKiBiZSBzbWFsbGVyLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgaW50IE5JT19CVUZGRVJfTElNSVQgPSA4KjEwMjQ7IC8vc2hvdWxkIG5vdCBiZSBtb3JlIHRoYW4gNjRLQi4KKyAgCisgIC8qKgorICAgKiBUaGlzIGlzIGEgd3JhcHBlciBhcm91bmQge0BsaW5rIFdyaXRhYmxlQnl0ZUNoYW5uZWwjd3JpdGUoQnl0ZUJ1ZmZlcil9LgorICAgKiBJZiB0aGUgYW1vdW50IG9mIGRhdGEgaXMgbGFyZ2UsIGl0IHdyaXRlcyB0byBjaGFubmVsIGluIHNtYWxsZXIgY2h1bmtzLiAKKyAgICogVGhpcyBpcyB0byBhdm9pZCBqZGsgZnJvbSBjcmVhdGluZyBtYW55IGRpcmVjdCBidWZmZXJzIGFzIHRoZSBzaXplIG9mIAorICAgKiBidWZmZXIgaW5jcmVhc2VzLiBUaGlzIGFsc28gbWluaW1pemVzIGV4dHJhIGNvcGllcyBpbiBOSU8gbGF5ZXIKKyAgICogYXMgYSByZXN1bHQgb2YgbXVsdGlwbGUgd3JpdGUgb3BlcmF0aW9ucyByZXF1aXJlZCB0byB3cml0ZSBhIGxhcmdlIAorICAgKiBidWZmZXIuICAKKyAgICoKKyAgICogQHNlZSBXcml0YWJsZUJ5dGVDaGFubmVsI3dyaXRlKEJ5dGVCdWZmZXIpCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGludCBjaGFubmVsV3JpdGUoV3JpdGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgYnVmZmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiAoYnVmZmVyLnJlbWFpbmluZygpIDw9IE5JT19CVUZGRVJfTElNSVQpID8KKyAgICAgICAgICAgY2hhbm5lbC53cml0ZShidWZmZXIpIDogY2hhbm5lbElPKG51bGwsIGNoYW5uZWwsIGJ1ZmZlcik7CisgIH0KKworICAvKioKKyAgICogVGhpcyBpcyBhIHdyYXBwZXIgYXJvdW5kIHtAbGluayBSZWFkYWJsZUJ5dGVDaGFubmVsI3JlYWQoQnl0ZUJ1ZmZlcil9LgorICAgKiBJZiB0aGUgYW1vdW50IG9mIGRhdGEgaXMgbGFyZ2UsIGl0IHdyaXRlcyB0byBjaGFubmVsIGluIHNtYWxsZXIgY2h1bmtzLiAKKyAgICogVGhpcyBpcyB0byBhdm9pZCBqZGsgZnJvbSBjcmVhdGluZyBtYW55IGRpcmVjdCBidWZmZXJzIGFzIHRoZSBzaXplIG9mIAorICAgKiBCeXRlQnVmZmVyIGluY3JlYXNlcy4gVGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgcGVyZm9ybWFuY2UgZGVncmVkYXRpb24uCisgICAqIAorICAgKiBAc2VlIFJlYWRhYmxlQnl0ZUNoYW5uZWwjcmVhZChCeXRlQnVmZmVyKQorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBpbnQgY2hhbm5lbFJlYWQoUmVhZGFibGVCeXRlQ2hhbm5lbCBjaGFubmVsLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnl0ZUJ1ZmZlciBidWZmZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIChidWZmZXIucmVtYWluaW5nKCkgPD0gTklPX0JVRkZFUl9MSU1JVCkgPworICAgICAgICAgICBjaGFubmVsLnJlYWQoYnVmZmVyKSA6IGNoYW5uZWxJTyhjaGFubmVsLCBudWxsLCBidWZmZXIpOworICB9CisKKyAgLyoqCisgICAqIEhlbHBlciBmb3Ige0BsaW5rICNjaGFubmVsUmVhZChSZWFkYWJsZUJ5dGVDaGFubmVsLCBCeXRlQnVmZmVyKX0KKyAgICogYW5kIHtAbGluayAjY2hhbm5lbFdyaXRlKFdyaXRhYmxlQnl0ZUNoYW5uZWwsIEJ5dGVCdWZmZXIpfS4gT25seQorICAgKiBvbmUgb2YgcmVhZENoIG9yIHdyaXRlQ2ggc2hvdWxkIGJlIG5vbi1udWxsLgorICAgKiAKKyAgICogQHNlZSAjY2hhbm5lbFJlYWQoUmVhZGFibGVCeXRlQ2hhbm5lbCwgQnl0ZUJ1ZmZlcikKKyAgICogQHNlZSAjY2hhbm5lbFdyaXRlKFdyaXRhYmxlQnl0ZUNoYW5uZWwsIEJ5dGVCdWZmZXIpCisgICAqLworICBwcml2YXRlIHN0YXRpYyBpbnQgY2hhbm5lbElPKFJlYWRhYmxlQnl0ZUNoYW5uZWwgcmVhZENoLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXcml0YWJsZUJ5dGVDaGFubmVsIHdyaXRlQ2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnl0ZUJ1ZmZlciBidWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgCisgICAgaW50IG9yaWdpbmFsTGltaXQgPSBidWYubGltaXQoKTsKKyAgICBpbnQgaW5pdGlhbFJlbWFpbmluZyA9IGJ1Zi5yZW1haW5pbmcoKTsKKyAgICBpbnQgcmV0ID0gMDsKKyAgICAKKyAgICB3aGlsZSAoYnVmLnJlbWFpbmluZygpID4gMCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgaW50IGlvU2l6ZSA9IE1hdGgubWluKGJ1Zi5yZW1haW5pbmcoKSwgTklPX0JVRkZFUl9MSU1JVCk7CisgICAgICAgIGJ1Zi5saW1pdChidWYucG9zaXRpb24oKSArIGlvU2l6ZSk7CisgICAgICAgIAorICAgICAgICByZXQgPSAocmVhZENoID09IG51bGwpID8gd3JpdGVDaC53cml0ZShidWYpIDogcmVhZENoLnJlYWQoYnVmKTsgCisgICAgICAgIAorICAgICAgICBpZiAocmV0IDwgaW9TaXplKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgYnVmLmxpbWl0KG9yaWdpbmFsTGltaXQpOyAgICAgICAgCisgICAgICB9CisgICAgfQorCisgICAgaW50IG5CeXRlcyA9IGluaXRpYWxSZW1haW5pbmcgLSBidWYucmVtYWluaW5nKCk7IAorICAgIHJldHVybiAobkJ5dGVzID4gMCkgPyBuQnl0ZXMgOiByZXQ7CisgIH0gICAgICAKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9ITWFzdGVySW50ZXJmYWNlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSE1hc3RlckludGVyZmFjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2Y2YwMTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSE1hc3RlckludGVyZmFjZS5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CisKKy8qKgorICogQ2xpZW50cyBpbnRlcmFjdCB3aXRoIHRoZSBITWFzdGVySW50ZXJmYWNlIHRvIGdhaW4gYWNjZXNzIHRvIG1ldGEtbGV2ZWwKKyAqIEhCYXNlIGZ1bmN0aW9uYWxpdHksIGxpa2UgZmluZGluZyBhbiBIUmVnaW9uU2VydmVyIGFuZCBjcmVhdGluZy9kZXN0cm95aW5nCisgKiB0YWJsZXMuCisgKiAKKyAqIDxwPk5PVEU6IGlmIHlvdSBjaGFuZ2UgdGhlIGludGVyZmFjZSwgeW91IG11c3QgY2hhbmdlIHRoZSBSUEMgdmVyc2lvbgorICogbnVtYmVyIGluIEhCYXNlUlBDUHJvdG9jb2xWZXJzaW9uCisgKiAKKyAqLworcHVibGljIGludGVyZmFjZSBITWFzdGVySW50ZXJmYWNlIGV4dGVuZHMgSEJhc2VSUENQcm90b2NvbFZlcnNpb24geworCisgIC8qKiBAcmV0dXJuIHRydWUgaWYgbWFzdGVyIGlzIGF2YWlsYWJsZSAqLworICBwdWJsaWMgYm9vbGVhbiBpc01hc3RlclJ1bm5pbmcoKTsKKyAgCisgIC8vIEFkbWluIHRvb2xzIHdvdWxkIHVzZSB0aGVzZSBjbWRzCisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgdGFibGUKKyAgICogQHBhcmFtIGRlc2MgdGFibGUgZGVzY3JpcHRvcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBjcmVhdGVUYWJsZShIVGFibGVEZXNjcmlwdG9yIGRlc2MpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogRGVsZXRlcyBhIHRhYmxlCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlVGFibGUoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBBZGRzIGEgY29sdW1uIHRvIHRoZSBzcGVjaWZpZWQgdGFibGUKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBkZXNjcmlwdG9yCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGFkZENvbHVtbihmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgSENvbHVtbkRlc2NyaXB0b3IgY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIE1vZGlmaWVzIGFuIGV4aXN0aW5nIGNvbHVtbiBvbiB0aGUgc3BlY2lmaWVkIHRhYmxlCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIGNvbHVtbk5hbWUgbmFtZSBvZiB0aGUgY29sdW1uIHRvIGVkaXQKKyAgICogQHBhcmFtIGRlc2NyaXB0b3IgbmV3IGNvbHVtbiBkZXNjcmlwdG9yCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIG1vZGlmeUNvbHVtbihmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgZmluYWwgYnl0ZSBbXSBjb2x1bW5OYW1lLCAKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBkZXNjcmlwdG9yKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisKKyAgLyoqCisgICAqIERlbGV0ZXMgYSBjb2x1bW4gZnJvbSB0aGUgc3BlY2lmaWVkIHRhYmxlCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIGNvbHVtbk5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQ29sdW1uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLCBmaW5hbCBieXRlIFtdIGNvbHVtbk5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBQdXRzIHRoZSB0YWJsZSBvbi1saW5lIChvbmx5IG5lZWRlZCBpZiB0YWJsZSBoYXMgYmVlbiBwcmV2aW91c2x5IHRha2VuIG9mZmxpbmUpCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZW5hYmxlVGFibGUoZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBUYWtlIHRhYmxlIG9mZmxpbmUKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGlzYWJsZVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIE1vZGlmeSBhIHRhYmxlJ3MgbWV0YWRhdGEKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIG9wCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIG1vZGlmeVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUsIGludCBvcCwgV3JpdGFibGVbXSBhcmdzKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogU2h1dGRvd24gYW4gSEJhc2UgY2x1c3Rlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSE1hc3RlclJlZ2lvbkludGVyZmFjZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hNYXN0ZXJSZWdpb25JbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iN2UzODRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hNYXN0ZXJSZWdpb25JbnRlcmZhY2UuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLk1hcFdyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhNc2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CisKKy8qKgorICogSFJlZ2lvblNlcnZlcnMgaW50ZXJhY3Qgd2l0aCB0aGUgSE1hc3RlclJlZ2lvbkludGVyZmFjZSB0byByZXBvcnQgb24gbG9jYWwgCisgKiBnb2luZ3Mtb24gYW5kIHRvIG9idGFpbiBkYXRhLWhhbmRsaW5nIGluc3RydWN0aW9ucyBmcm9tIHRoZSBITWFzdGVyLgorICogPHA+Q2hhbmdlcyBoZXJlIG5lZWQgdG8gYmUgcmVmbGVjdGVkIGluIEhiYXNlT2JqZWN0V3JpdGFibGUgSGJhc2VSUEMjSW52b2tlci4KKyAqIAorICogPHA+Tk9URTogaWYgeW91IGNoYW5nZSB0aGUgaW50ZXJmYWNlLCB5b3UgbXVzdCBjaGFuZ2UgdGhlIFJQQyB2ZXJzaW9uCisgKiBudW1iZXIgaW4gSEJhc2VSUENQcm90b2NvbFZlcnNpb24KKyAqIAorICovCitwdWJsaWMgaW50ZXJmYWNlIEhNYXN0ZXJSZWdpb25JbnRlcmZhY2UgZXh0ZW5kcyBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbiB7CisKKyAgLyoqCisgICAqIENhbGxlZCB3aGVuIGEgcmVnaW9uIHNlcnZlciBmaXJzdCBzdGFydHMKKyAgICogQHBhcmFtIGluZm8KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAcmV0dXJuIENvbmZpZ3VyYXRpb24gZm9yIHRoZSByZWdpb25zZXJ2ZXIgdG8gdXNlOiBlLmcuIGZpbGVzeXN0ZW0sCisgICAqIGhiYXNlIHJvb3RkaXIsIGV0Yy4KKyAgICovCisgIHB1YmxpYyBNYXBXcml0YWJsZSByZWdpb25TZXJ2ZXJTdGFydHVwKEhTZXJ2ZXJJbmZvIGluZm8pIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogQ2FsbGVkIHRvIHJlbmV3IGxlYXNlLCB0ZWxsIG1hc3RlciB3aGF0IHRoZSByZWdpb24gc2VydmVyIGlzIGRvaW5nIGFuZCB0bworICAgKiByZWNlaXZlIG5ldyBpbnN0cnVjdGlvbnMgZnJvbSB0aGUgbWFzdGVyCisgICAqIAorICAgKiBAcGFyYW0gaW5mbyBzZXJ2ZXIncyBhZGRyZXNzIGFuZCBzdGFydCBjb2RlCisgICAqIEBwYXJhbSBtc2dzIHRoaW5ncyB0aGUgcmVnaW9uIHNlcnZlciB3YW50cyB0byB0ZWxsIHRoZSBtYXN0ZXIKKyAgICogQHBhcmFtIG1vc3RMb2FkZWRSZWdpb25zIEFycmF5IG9mIEhSZWdpb25JbmZvcyB0aGF0IHNob3VsZCBjb250YWluIHRoZSAKKyAgICogcmVwb3J0aW5nIHNlcnZlcidzIG1vc3QgbG9hZGVkIHJlZ2lvbnMuIFRoZXNlIGFyZSBjYW5kaWRhdGVzIGZvciBiZWluZworICAgKiByZWJhbGFuY2VkLgorICAgKiBAcmV0dXJuIGluc3RydWN0aW9ucyBmcm9tIHRoZSBtYXN0ZXIgdG8gdGhlIHJlZ2lvbiBzZXJ2ZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhNc2dbXSByZWdpb25TZXJ2ZXJSZXBvcnQoSFNlcnZlckluZm8gaW5mbywgSE1zZyBtc2dzW10sIAorICAgIEhSZWdpb25JbmZvIG1vc3RMb2FkZWRSZWdpb25zW10pCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvSFJlZ2lvbkludGVyZmFjZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hSZWdpb25JbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjZkZWU4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0hSZWdpb25JbnRlcmZhY2UuamF2YQpAQCAtMCwwICsxLDMwOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlTWFwV3JpdGFibGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Ob3RTZXJ2aW5nUmVnaW9uRXhjZXB0aW9uOworCisvKioKKyAqIENsaWVudHMgaW50ZXJhY3Qgd2l0aCBIUmVnaW9uU2VydmVycyB1c2luZyBhIGhhbmRsZSB0byB0aGUgSFJlZ2lvbkludGVyZmFjZS4KKyAqIAorICogPHA+Tk9URTogaWYgeW91IGNoYW5nZSB0aGUgaW50ZXJmYWNlLCB5b3UgbXVzdCBjaGFuZ2UgdGhlIFJQQyB2ZXJzaW9uCisgKiBudW1iZXIgaW4gSEJhc2VSUENQcm90b2NvbFZlcnNpb24KKyAqIAorICovCitwdWJsaWMgaW50ZXJmYWNlIEhSZWdpb25JbnRlcmZhY2UgZXh0ZW5kcyBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbiB7CisgIC8qKiAKKyAgICogR2V0IG1ldGFpbmZvIGFib3V0IGFuIEhSZWdpb24KKyAgICogCisgICAqIEBwYXJhbSByZWdpb25OYW1lIG5hbWUgb2YgdGhlIHJlZ2lvbgorICAgKiBAcmV0dXJuIEhSZWdpb25JbmZvIG9iamVjdCBmb3IgcmVnaW9uCisgICAqIEB0aHJvd3MgTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25JbmZvIGdldFJlZ2lvbkluZm8oZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lKQorICB0aHJvd3MgTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdmVyc2lvbnMgb2YgdGhlIHNwZWNpZmllZCByb3cgYW5kIGNvbHVtbiB3aXRoCisgICAqIHRoZSBzcGVjaWZpZWQgdGltZXN0YW1wLgorICAgKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4ga2V5CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0dXJuCisgICAqIEByZXR1cm4gYXJyYXkgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsW10gZ2V0KGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwgZmluYWwgYnl0ZSBbXSByb3csCisgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogUmV0dXJuIGFsbCB0aGUgZGF0YSBmb3IgdGhlIHJvdyB0aGF0IG1hdGNoZXMgPGk+cm93PC9pPiBleGFjdGx5LCAKKyAgICogb3IgdGhlIG9uZSB0aGF0IGltbWVkaWF0ZWx5IHByZWNlZWRzIGl0LgorICAgKiAKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgcmVnaW9uIG5hbWUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW5GYW1pbHkgQ29sdW1uIGZhbWlseSB0byBsb29rIGZvciByb3cgaW4uCisgICAqIEByZXR1cm4gbWFwIG9mIHZhbHVlcworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0IGdldENsb3Nlc3RSb3dCZWZvcmUoZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLAorICAgIGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbkZhbWlseSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBHZXQgc2VsZWN0ZWQgY29sdW1ucyBmb3IgdGhlIHNwZWNpZmllZCByb3cgYXQgYSBnaXZlbiB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBnZXQKKyAgICogQHBhcmFtIHRzIHRpbWUgc3RhbXAKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucworICAgKiBAcGFyYW0gbG9ja0lkIGxvY2sgaWQKKyAgICogQHJldHVybiBtYXAgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwgZmluYWwgYnl0ZSBbXSByb3csIAorICAgIGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGxvbmcgdHMsCisgICAgZmluYWwgaW50IG51bVZlcnNpb25zLCBmaW5hbCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBBcHBsaWVzIGEgYmF0Y2ggb2YgdXBkYXRlcyB2aWEgb25lIFJQQworICAgKiAKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgbmFtZSBvZiB0aGUgcmVnaW9uIHRvIHVwZGF0ZQorICAgKiBAcGFyYW0gYiBCYXRjaFVwZGF0ZQorICAgKiBAcGFyYW0gbG9ja0lkIGxvY2sgaWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLCBmaW5hbCBCYXRjaFVwZGF0ZSBiLAorICAgICAgZmluYWwgbG9uZyBsb2NrSWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBBcHBsaWVzIGEgYmF0Y2ggb2YgdXBkYXRlcyB2aWEgb25lIFJQQyBmb3IgbWFueSByb3dzCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSBuYW1lIG9mIHRoZSByZWdpb24gdG8gdXBkYXRlCisgICAqIEBwYXJhbSBiIEJhdGNoVXBkYXRlW10KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAcmV0dXJuIG51bWJlciBvZiB1cGRhdGVzIGFwcGxpZWQKKyAgICovCisgIHB1YmxpYyBpbnQgYmF0Y2hVcGRhdGVzKGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLCBmaW5hbCBCYXRjaFVwZGF0ZVtdIGIpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBBcHBsaWVzIGEgYmF0Y2ggb2YgdXBkYXRlcyB0byBvbmUgcm93IGF0b21pY2FsbHkgdmlhIG9uZSBSUEMKKyAgICogaWYgdGhlIGNvbHVtbnMgc3BlY2lmaWVkIGluIGV4cGVjdGVkVmFsdWVzIG1hdGNoCisgICAqIHRoZSBnaXZlbiB2YWx1ZXMgaW4gZXhwZWN0ZWRWYWx1ZXMKKyAgICogCisgICAqIEBwYXJhbSByZWdpb25OYW1lIG5hbWUgb2YgdGhlIHJlZ2lvbiB0byB1cGRhdGUKKyAgICogQHBhcmFtIGIgQmF0Y2hVcGRhdGUKKyAgICogQHBhcmFtIGV4cGVjdGVkVmFsdWVzIG1hcCBvZiBjb2x1bW4gbmFtZXMgdG8gZXhwZWN0ZWQgZGF0YSB2YWx1ZXMuCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB1cGRhdGUgd2FzIGFwcGxpZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gY2hlY2tBbmRTYXZlKGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwgZmluYWwgQmF0Y2hVcGRhdGUgYiwKKyAgICAgIGZpbmFsIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZVtdLGJ5dGVbXT4gZXhwZWN0ZWRWYWx1ZXMpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgY29sdW1uIGFuZCB3aG9zZSB0aW1lc3RhbXAKKyAgICogaXMgZXF1YWwtdG8gb3Igb2xkZXIgdGhhbiB0aGUgcGFzc2VkIHRpbWVzdGFtcC4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb25OYW1lIHJlZ2lvbiBuYW1lCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBrZXkKKyAgICogQHBhcmFtIHRpbWVzdGFtcCBEZWxldGUgYWxsIGVudHJpZXMgdGhhdCBoYXZlIHRoaXMgdGltZXN0YW1wIG9yIG9sZGVyCisgICAqIEBwYXJhbSBsb2NrSWQgbG9jayBpZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdywgYnl0ZSBbXSBjb2x1bW4sCisgICAgbG9uZyB0aW1lc3RhbXAsIGxvbmcgbG9ja0lkKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgd2hvc2UKKyAgICogdGltZXN0YW1wIGlzIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqCisgICAqIEBwYXJhbSByZWdpb25OYW1lIHJlZ2lvbiBuYW1lCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gdGltZXN0YW1wIERlbGV0ZSBhbGwgZW50cmllcyB0aGF0IGhhdmUgdGhpcyB0aW1lc3RhbXAgb3Igb2xkZXIKKyAgICogQHBhcmFtIGxvY2tJZCBsb2NrIGlkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChieXRlIFtdIHJlZ2lvbk5hbWUsIGJ5dGUgW10gcm93LCBsb25nIHRpbWVzdGFtcCwKKyAgICAgIGxvbmcgbG9ja0lkKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93ICYgdGhlIGNvbHVtbiByZWdleCBhbmQgd2hvc2UKKyAgICogdGltZXN0YW1wIGlzIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2xSZWdleAorICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqIEBwYXJhbSBsb2NrSWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsQnlSZWdleChieXRlIFtdIHJlZ2lvbk5hbWUsIGJ5dGUgW10gcm93LCBTdHJpbmcgY29sUmVnZXgsIAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGxvbmcgbG9ja0lkKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgZm9yIGEgcm93IHdpdGggbWF0Y2hpbmcgY29sdW1uIGZhbWlseSB3aXRoIHRpbWVzdGFtcHMKKyAgICogbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDxpPnRpbWVzdGFtcDwvaT4uCisgICAqCisgICAqIEBwYXJhbSByZWdpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSByZWdpb24gdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5IFRoZSBjb2x1bW4gZmFtaWx5IHRvIG1hdGNoCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEBwYXJhbSBsb2NrSWQgbG9jayBpZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVGYW1pbHkoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdywgYnl0ZSBbXSBmYW1pbHksIAorICAgIGxvbmcgdGltZXN0YW1wLCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworICAKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgZm9yIGEgcm93IHdpdGggbWF0Y2hpbmcgY29sdW1uIGZhbWlseSByZWdleCB3aXRoIAorICAgKiB0aW1lc3RhbXBzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKiAKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIHJlZ2lvbiB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdyB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSBmYW1pbHlSZWdleCBjb2x1bW4gZmFtaWx5IHJlZ2V4CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEBwYXJhbSBsb2NrSWQgbG9jayBpZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVGYW1pbHlCeVJlZ2V4KGJ5dGUgW10gcmVnaW9uTmFtZSwgYnl0ZSBbXSByb3csIFN0cmluZyBmYW1pbHlSZWdleCwgCisgICAgbG9uZyB0aW1lc3RhbXAsIGxvbmcgbG9ja0lkKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgYW55IGNlbGxzIGV4aXN0IGZvciB0aGUgZ2l2ZW4gY29vcmRpbmF0ZS4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSByZWdpb24KKyAgICogQHBhcmFtIHJvdyBUaGUgcm93CisgICAqIEBwYXJhbSBjb2x1bW4gVGhlIGNvbHVtbiwgb3IgbnVsbCBmb3IgYW55CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGhlIHRpbWVzdGFtcCwgb3IgTEFURVNUX1RJTUVTVEFNUCBmb3IgYW55CisgICAqIEBwYXJhbSBsb2NrSUQgbG9jayBpZAorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHJvdyBleGlzdHMsIGZhbHNlIG90aGVyd2lzZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdywgYnl0ZSBbXSBjb2x1bW4sIAorICAgIGxvbmcgdGltZXN0YW1wLCBsb25nIGxvY2tJRCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8vCisgIC8vIHJlbW90ZSBzY2FubmVyIGludGVyZmFjZQorICAvLworCisgIC8qKgorICAgKiBPcGVucyBhIHJlbW90ZSBzY2FubmVyIHdpdGggYSBSb3dGaWx0ZXIuCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSBuYW1lIG9mIHJlZ2lvbiB0byBzY2FuCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGZvciBjb2x1bW4gZmFtaWx5IG5hbWUuIEEgY29sdW1uIG5hbWUgaXMganVkZ2VkIHRvIGJlCisgICAqIHJlZ2V4IGlmIGl0IGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6CisgICAqIDxjb2RlPlwrfF4mKiRbXV19eykoPC9jb2RlPi4KKyAgICogQHBhcmFtIHN0YXJ0Um93IHN0YXJ0aW5nIHJvdyB0byBzY2FuCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgb25seSByZXR1cm4gdmFsdWVzIHdob3NlIHRpbWVzdGFtcCBpcyA8PSB0aGlzIHZhbHVlCisgICAqIEBwYXJhbSBmaWx0ZXIgUm93RmlsdGVyIGZvciBmaWx0ZXJpbmcgcmVzdWx0cyBhdCB0aGUgcm93LWxldmVsLgorICAgKgorICAgKiBAcmV0dXJuIHNjYW5uZXJJZCBzY2FubmVyIGlkZW50aWZpZXIgdXNlZCBpbiBvdGhlciBjYWxscworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgbG9uZyBvcGVuU2Nhbm5lcihmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zLAorICAgICAgZmluYWwgYnl0ZSBbXSBzdGFydFJvdywgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIG5leHQgc2V0IG9mIHZhbHVlcworICAgKiBAcGFyYW0gc2Nhbm5lcklkIGNsaWVudElkIHBhc3NlZCB0byBvcGVuU2Nhbm5lcgorICAgKiBAcmV0dXJuIG1hcCBvZiB2YWx1ZXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBuZXh0KGxvbmcgc2Nhbm5lcklkKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogR2V0IHRoZSBuZXh0IHNldCBvZiB2YWx1ZXMKKyAgICogQHBhcmFtIHNjYW5uZXJJZCBjbGllbnRJZCBwYXNzZWQgdG8gb3BlblNjYW5uZXIKKyAgICogQHBhcmFtIG51bWJlck9mUm93cyB0aGUgbnVtYmVyIG9mIHJvd3MgdG8gZmV0Y2gKKyAgICogQHJldHVybiBtYXAgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHRbXSBuZXh0KGxvbmcgc2Nhbm5lcklkLCBpbnQgbnVtYmVyT2ZSb3dzKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogQ2xvc2UgYSBzY2FubmVyCisgICAqIAorICAgKiBAcGFyYW0gc2Nhbm5lcklkIHRoZSBzY2FubmVyIGlkIHJldHVybmVkIGJ5IG9wZW5TY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGNsb3NlKGxvbmcgc2Nhbm5lcklkKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogT3BlbnMgYSByZW1vdGUgcm93IGxvY2suCisgICAqCisgICAqIEBwYXJhbSByZWdpb25OYW1lIG5hbWUgb2YgcmVnaW9uCisgICAqIEBwYXJhbSByb3cgcm93IHRvIGxvY2sKKyAgICogQHJldHVybiBsb2NrSWQgbG9jayBpZGVudGlmaWVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBsb25nIGxvY2tSb3coZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLCBmaW5hbCBieXRlIFtdIHJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBSZWxlYXNlcyBhIHJlbW90ZSByb3cgbG9jay4KKyAgICoKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogQHBhcmFtIGxvY2tJZCB0aGUgbG9jayBpZCByZXR1cm5lZCBieSBsb2NrUm93CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHVubG9ja1JvdyhmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIGxvbmcgbG9ja0lkKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogQXRvbWljYWxseSBpbmNyZW1lbnRzIGEgY29sdW1uIHZhbHVlLiBJZiB0aGUgY29sdW1uIHZhbHVlIGlzbid0IGxvbmctbGlrZSwgdGhpcyBjb3VsZAorICAgKiB0aHJvdyBhbiBleGNlcHRpb24uCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIGFtb3VudAorICAgKiBAcmV0dXJuIG5ldyBpbmNyZW1lbnRlZCBjb2x1bW4gdmFsdWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGxvbmcgaW5jcmVtZW50Q29sdW1uVmFsdWUoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdywKKyAgICAgIGJ5dGUgW10gY29sdW1uLCBsb25nIGFtb3VudCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL0luZGV4ZWRSZWdpb25JbnRlcmZhY2UuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9JbmRleGVkUmVnaW9uSW50ZXJmYWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmY1YmIwYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9JbmRleGVkUmVnaW9uSW50ZXJmYWNlLmphdmEKQEAgLTAsMCArMSwxMSBAQAorLyoKKyAqICRJZCQKKyAqIENyZWF0ZWQgb24gU2VwIDEwLCAyMDA4CisgKiAKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGM7CisKKy8qKiBJbnRlcmZhY2UgZm9yIHRoZSBpbmRleGVkIHJlZ2lvbiBzZXJ2ZXIuICovCitwdWJsaWMgaW50ZXJmYWNlIEluZGV4ZWRSZWdpb25JbnRlcmZhY2UgZXh0ZW5kcyBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlIHsKKyAgLy8gTm8gbWV0aG9kcyBmb3Igbm93Li4uCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pcGMvVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL1RyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGU1MGM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL1RyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UuamF2YQpAQCAtMCwwICsxLDIwOCBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYzsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworCisvKioKKyAqIEludGVyZmFjZSBmb3IgdHJhbnNhY3Rpb25hbCByZWdpb24gc2VydmVycy4KKyAqIAorICogPHA+Tk9URTogaWYgeW91IGNoYW5nZSB0aGUgaW50ZXJmYWNlLCB5b3UgbXVzdCBjaGFuZ2UgdGhlIFJQQyB2ZXJzaW9uCisgKiBudW1iZXIgaW4gSEJhc2VSUENQcm90b2NvbFZlcnNpb24KKyAqIAorICovCitwdWJsaWMgaW50ZXJmYWNlIFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UgZXh0ZW5kcyBIUmVnaW9uSW50ZXJmYWNlIHsKKworICAvKioKKyAgICogU2VudCB0byBpbml0aWF0ZSBhIHRyYW5zYWN0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgbmFtZSBvZiByZWdpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmVnaW5UcmFuc2FjdGlvbihsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBSZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVnaW9uIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhbmQKKyAgICogY29sdW1uIGtleXMKKyAgICoKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgbmFtZSBvZiByZWdpb24KKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIGtleQorICAgKiBAcmV0dXJuIGFsdWUgZm9yIHRoYXQgcmVnaW9uL3Jvdy9jb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGwgZ2V0KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW10gY29sdW1uKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBvZiB0aGUgc3BlY2lmaWVkIHJvdyBhbmQgY29sdW1uCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4ga2V5CisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0dXJuCisgICAqIEByZXR1cm4gYXJyYXkgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsW10gZ2V0KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW10gY29sdW1uLCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBvZiB0aGUgc3BlY2lmaWVkIHJvdyBhbmQgY29sdW1uIHdpdGgKKyAgICogdGhlIHNwZWNpZmllZCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbiBjb2x1bW4ga2V5CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0dXJuCisgICAqIEByZXR1cm4gYXJyYXkgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsW10gZ2V0KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW10gY29sdW1uLCBmaW5hbCBsb25nIHRpbWVzdGFtcCwKKyAgICAgIGZpbmFsIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIGdpdmVuIHRpbWVzdGFtcAorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgcmVnaW9uIG5hbWUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSB0cyB0aW1lc3RhbXAKKyAgICogQHJldHVybiBtYXAgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBsb25nIHRzKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIEdldCBzZWxlY3RlZCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHJvdyBhdCBhIGdpdmVuIHRpbWVzdGFtcC4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkCisgICAqIEBwYXJhbSByZWdpb25OYW1lIHJlZ2lvbiBuYW1lCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bXMgdG8gZ2V0CisgICAqIEBwYXJhbSB0cyB0aW1lc3RhbXAKKyAgICogQHJldHVybiBtYXAgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW11bXSBjb2x1bW5zLCBmaW5hbCBsb25nIHRzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBHZXQgc2VsZWN0ZWQgY29sdW1ucyBmb3IgdGhlIHNwZWNpZmllZCByb3cgYXQgdGhlIGxhdGVzdCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBnZXQKKyAgICogQHJldHVybiBtYXAgb2YgdmFsdWVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW11bXSBjb2x1bW5zKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgdGhhdCBtYXRjaCB0aGUgcGFzc2VkIHJvdyBhbmQgd2hvc2UgdGltZXN0YW1wIGlzIGVxdWFsLXRvCisgICAqIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSByZWdpb24gbmFtZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIHRpbWVzdGFtcCBEZWxldGUgYWxsIGVudHJpZXMgdGhhdCBoYXZlIHRoaXMgdGltZXN0YW1wIG9yIG9sZGVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChsb25nIHRyYW5zYWN0aW9uSWQsIGJ5dGVbXSByZWdpb25OYW1lLCBieXRlW10gcm93LAorICAgICAgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogT3BlbnMgYSByZW1vdGUgc2Nhbm5lciB3aXRoIGEgUm93RmlsdGVyLgorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgbmFtZSBvZiByZWdpb24gdG8gc2NhbgorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8KKyAgICogcGFzcyBhIHJlZ2V4IGZvciBjb2x1bW4gZmFtaWx5IG5hbWUuIEEgY29sdW1uIG5hbWUgaXMganVkZ2VkIHRvIGJlIHJlZ2V4IGlmCisgICAqIGl0IGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6CisgICAqIDxjb2RlPlwrfF4mKiRbXV19eykoPC9jb2RlPi4KKyAgICogQHBhcmFtIHN0YXJ0Um93IHN0YXJ0aW5nIHJvdyB0byBzY2FuCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgb25seSByZXR1cm4gdmFsdWVzIHdob3NlIHRpbWVzdGFtcCBpcyA8PSB0aGlzIHZhbHVlCisgICAqIEBwYXJhbSBmaWx0ZXIgUm93RmlsdGVyIGZvciBmaWx0ZXJpbmcgcmVzdWx0cyBhdCB0aGUgcm93LWxldmVsLgorICAgKiAKKyAgICogQHJldHVybiBzY2FubmVySWQgc2Nhbm5lciBpZGVudGlmaWVyIHVzZWQgaW4gb3RoZXIgY2FsbHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGxvbmcgb3BlblNjYW5uZXIoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGVbXVtdIGNvbHVtbnMsIGZpbmFsIGJ5dGVbXSBzdGFydFJvdywgbG9uZyB0aW1lc3RhbXAsCisgICAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIEFwcGxpZXMgYSBiYXRjaCBvZiB1cGRhdGVzIHZpYSBvbmUgUlBDCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZSBuYW1lIG9mIHRoZSByZWdpb24gdG8gdXBkYXRlCisgICAqIEBwYXJhbSBiIEJhdGNoVXBkYXRlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGJhdGNoVXBkYXRlKGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBCYXRjaFVwZGF0ZSBiKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIEFzayBpZiB3ZSBjYW4gY29tbWl0IHRoZSBnaXZlbiB0cmFuc2FjdGlvbi4KKyAgICoKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHJldHVybiB0cnVlIGlmIHdlIGNhbiBjb21taXQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gY29tbWl0UmVxdWVzdChmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwgbG9uZyB0cmFuc2FjdGlvbklkKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIC8qKgorICAgKiBDb21taXQgdGhlIHRyYW5zYWN0aW9uLgorICAgKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBjb21taXQoZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsIGxvbmcgdHJhbnNhY3Rpb25JZCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogQWJvcnQgdGhlIHRyYW5zYWN0aW9uLgorICAgKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBhYm9ydChmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwgbG9uZyB0cmFuc2FjdGlvbklkKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaXBjL3BhY2thZ2UuaHRtbCBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9wYWNrYWdlLmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGUwMWJkYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lwYy9wYWNrYWdlLmh0bWwKQEAgLTAsMCArMSwyNCBAQAorPGh0bWw+CisKKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPGJvZHk+CitUb29scyB0byBoZWxwIGRlZmluZSBuZXR3b3JrIGNsaWVudHMgYW5kIHNlcnZlcnMuCitUaGlzIGlzIHRoZSBoYWRvb3AgY29waWVkIGxvY2FsIHNvIGNhbiBmaXggYnVncyBhbmQgbWFrZSBoYmFzZS1zcGVjaWZpYyBvcHRpbWl6YXRpb25zLgorPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0J1aWxkVGFibGVJbmRleC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0J1aWxkVGFibGVJbmRleC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2OTg4ODMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvQnVpbGRUYWJsZUluZGV4LmphdmEKQEAgLTAsMCArMSwyMDUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlT3V0cHV0Rm9ybWF0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDbGllbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CisKKy8qKgorICogRXhhbXBsZSB0YWJsZSBjb2x1bW4gaW5kZXhpbmcgY2xhc3MuICBSdW5zIGEgbWFwcmVkdWNlIGpvYiB0byBpbmRleAorICogc3BlY2lmaWVkIHRhYmxlIGNvbHVtbnMuCisgKiA8dWw+PGxpPkVhY2ggcm93IGlzIG1vZGVsZWQgYXMgYSBMdWNlbmUgZG9jdW1lbnQ6IHJvdyBrZXkgaXMgaW5kZXhlZCBpbgorICogaXRzIHVudG9rZW5pemVkIGZvcm0sIGNvbHVtbiBuYW1lLXZhbHVlIHBhaXJzIGFyZSBMdWNlbmUgZmllbGQgbmFtZS12YWx1ZSAKKyAqIHBhaXJzLjwvbGk+CisgKiA8bGk+QSBmaWxlIHBhc3NlZCBvbiBjb21tYW5kIGxpbmUgaXMgdXNlZCB0byBwb3B1bGF0ZSBhbgorICoge0BsaW5rIEluZGV4Q29uZmlndXJhdGlvbn0gd2hpY2ggaXMgdXNlZCB0byBzZXQgdmFyaW91cyBMdWNlbmUgcGFyYW1ldGVycywKKyAqIHNwZWNpZnkgd2hldGhlciB0byBvcHRpbWl6ZSBhbiBpbmRleCBhbmQgd2hpY2ggY29sdW1ucyB0byBpbmRleCBhbmQvb3IKKyAqIHN0b3JlLCBpbiB0b2tlbml6ZWQgb3IgdW50b2tlbml6ZWQgZm9ybSwgZXRjLiBGb3IgYW4gZXhhbXBsZSwgc2VlIHRoZQorICogPGNvZGU+Y3JlYXRlSW5kZXhDb25mQ29udGVudDwvY29kZT4gbWV0aG9kIGluIFRlc3RUYWJsZUluZGV4CisgKiA8L2xpPgorICogPGxpPlRoZSBudW1iZXIgb2YgcmVkdWNlIHRhc2tzIGRlY2lkZXMgdGhlIG51bWJlciBvZiBpbmRleGVzIChwYXJ0aXRpb25zKS4KKyAqIFRoZSBpbmRleChlcykgaXMgc3RvcmVkIGluIHRoZSBvdXRwdXQgcGF0aCBvZiBqb2IgY29uZmlndXJhdGlvbi48L2xpPgorICogPGxpPlRoZSBpbmRleCBidWlsZCBwcm9jZXNzIGlzIGRvbmUgaW4gdGhlIHJlZHVjZSBwaGFzZS4gVXNlcnMgY2FuIHVzZQorICogdGhlIG1hcCBwaGFzZSB0byBqb2luIHJvd3MgZnJvbSBkaWZmZXJlbnQgdGFibGVzIG9yIHRvIHByZS1wYXJzZS9hbmFseXplCisgKiBjb2x1bW4gY29udGVudCwgZXRjLjwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgY2xhc3MgQnVpbGRUYWJsZUluZGV4IHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFVTQUdFID0gIlVzYWdlOiBCdWlsZFRhYmxlSW5kZXggIiArCisgICAgIi1tIDxudW1NYXBUYXNrcz4gLXIgPG51bVJlZHVjZVRhc2tzPlxuICAtaW5kZXhDb25mIDxpY29uZkZpbGU+ICIgKworICAgICItaW5kZXhEaXIgPGluZGV4RGlyPlxuICAtdGFibGUgPHRhYmxlTmFtZT4gLWNvbHVtbnMgPGNvbHVtbk5hbWUxPiAiICsKKyAgICAiWzxjb2x1bW5OYW1lMj4gLi4uXSI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFVzYWdlKFN0cmluZyBtZXNzYWdlKSB7CisgICAgU3lzdGVtLmVyci5wcmludGxuKG1lc3NhZ2UpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbihVU0FHRSk7CisgICAgU3lzdGVtLmV4aXQoLTEpOworICB9CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIEJ1aWxkVGFibGVJbmRleCgpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHJ1bihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChhcmdzLmxlbmd0aCA8IDYpIHsKKyAgICAgIHByaW50VXNhZ2UoIlRvbyBmZXcgYXJndW1lbnRzIik7CisgICAgfQorCisgICAgaW50IG51bU1hcFRhc2tzID0gMTsKKyAgICBpbnQgbnVtUmVkdWNlVGFza3MgPSAxOworICAgIFN0cmluZyBpY29uZkZpbGUgPSBudWxsOworICAgIFN0cmluZyBpbmRleERpciA9IG51bGw7CisgICAgU3RyaW5nIHRhYmxlTmFtZSA9IG51bGw7CisgICAgU3RyaW5nQnVmZmVyIGNvbHVtbk5hbWVzID0gbnVsbDsKKworICAgIC8vIHBhcnNlIGFyZ3MKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoIC0gMTsgaSsrKSB7CisgICAgICBpZiAoIi1tIi5lcXVhbHMoYXJnc1tpXSkpIHsKKyAgICAgICAgbnVtTWFwVGFza3MgPSBJbnRlZ2VyLnBhcnNlSW50KGFyZ3NbKytpXSk7CisgICAgICB9IGVsc2UgaWYgKCItciIuZXF1YWxzKGFyZ3NbaV0pKSB7CisgICAgICAgIG51bVJlZHVjZVRhc2tzID0gSW50ZWdlci5wYXJzZUludChhcmdzWysraV0pOworICAgICAgfSBlbHNlIGlmICgiLWluZGV4Q29uZiIuZXF1YWxzKGFyZ3NbaV0pKSB7CisgICAgICAgIGljb25mRmlsZSA9IGFyZ3NbKytpXTsKKyAgICAgIH0gZWxzZSBpZiAoIi1pbmRleERpciIuZXF1YWxzKGFyZ3NbaV0pKSB7CisgICAgICAgIGluZGV4RGlyID0gYXJnc1srK2ldOworICAgICAgfSBlbHNlIGlmICgiLXRhYmxlIi5lcXVhbHMoYXJnc1tpXSkpIHsKKyAgICAgICAgdGFibGVOYW1lID0gYXJnc1srK2ldOworICAgICAgfSBlbHNlIGlmICgiLWNvbHVtbnMiLmVxdWFscyhhcmdzW2ldKSkgeworICAgICAgICBjb2x1bW5OYW1lcyA9IG5ldyBTdHJpbmdCdWZmZXIoYXJnc1srK2ldKTsKKyAgICAgICAgd2hpbGUgKGkgKyAxIDwgYXJncy5sZW5ndGggJiYgIWFyZ3NbaSArIDFdLnN0YXJ0c1dpdGgoIi0iKSkgeworICAgICAgICAgIGNvbHVtbk5hbWVzLmFwcGVuZCgiICIpOworICAgICAgICAgIGNvbHVtbk5hbWVzLmFwcGVuZChhcmdzWysraV0pOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludFVzYWdlKCJVbnN1cHBvcnRlZCBvcHRpb24gIiArIGFyZ3NbaV0pOworICAgICAgfQorICAgIH0KKworICAgIGlmIChpbmRleERpciA9PSBudWxsIHx8IHRhYmxlTmFtZSA9PSBudWxsIHx8IGNvbHVtbk5hbWVzID09IG51bGwpIHsKKyAgICAgIHByaW50VXNhZ2UoIkluZGV4IGRpcmVjdG9yeSwgdGFibGUgbmFtZSBhbmQgYXQgbGVhc3Qgb25lIGNvbHVtbiBtdXN0ICIgKworICAgICAgICAiYmUgc3BlY2lmaWVkIik7CisgICAgfQorCisgICAgQ29uZmlndXJhdGlvbiBjb25mID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIGlmIChpY29uZkZpbGUgIT0gbnVsbCkgeworICAgICAgLy8gc2V0IGluZGV4IGNvbmZpZ3VyYXRpb24gY29udGVudCBmcm9tIGEgZmlsZQorICAgICAgU3RyaW5nIGNvbnRlbnQgPSByZWFkQ29udGVudChpY29uZkZpbGUpOworICAgICAgSW5kZXhDb25maWd1cmF0aW9uIGljb25mID0gbmV3IEluZGV4Q29uZmlndXJhdGlvbigpOworICAgICAgLy8gcHVyZWx5IHRvIHZhbGlkYXRlLCBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgbm90IHZhbGlkCisgICAgICBpY29uZi5hZGRGcm9tWE1MKGNvbnRlbnQpOworICAgICAgY29uZi5zZXQoImhiYXNlLmluZGV4LmNvbmYiLCBjb250ZW50KTsKKyAgICB9CisKKyAgICBpZiAoY29sdW1uTmFtZXMgIT0gbnVsbCkgeworICAgICAgSm9iQ29uZiBqb2JDb25mID0gY3JlYXRlSm9iKGNvbmYsIG51bU1hcFRhc2tzLCBudW1SZWR1Y2VUYXNrcywgaW5kZXhEaXIsCisgICAgICAgICAgdGFibGVOYW1lLCBjb2x1bW5OYW1lcy50b1N0cmluZygpKTsKKyAgICAgIEpvYkNsaWVudC5ydW5Kb2Ioam9iQ29uZik7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqIEBwYXJhbSBudW1NYXBUYXNrcworICAgKiBAcGFyYW0gbnVtUmVkdWNlVGFza3MKKyAgICogQHBhcmFtIGluZGV4RGlyCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIGNvbHVtbk5hbWVzCisgICAqIEByZXR1cm4gSm9iQ29uZgorICAgKi8KKyAgcHVibGljIEpvYkNvbmYgY3JlYXRlSm9iKENvbmZpZ3VyYXRpb24gY29uZiwgaW50IG51bU1hcFRhc2tzLAorICAgICAgaW50IG51bVJlZHVjZVRhc2tzLCBTdHJpbmcgaW5kZXhEaXIsIFN0cmluZyB0YWJsZU5hbWUsCisgICAgICBTdHJpbmcgY29sdW1uTmFtZXMpIHsKKyAgICBKb2JDb25mIGpvYkNvbmYgPSBuZXcgSm9iQ29uZihjb25mLCBCdWlsZFRhYmxlSW5kZXguY2xhc3MpOworICAgIGpvYkNvbmYuc2V0Sm9iTmFtZSgiYnVpbGQgaW5kZXggZm9yIHRhYmxlICIgKyB0YWJsZU5hbWUpOworICAgIGpvYkNvbmYuc2V0TnVtTWFwVGFza3MobnVtTWFwVGFza3MpOworICAgIC8vIG51bWJlciBvZiBpbmRleGVzIHRvIHBhcnRpdGlvbiBpbnRvCisgICAgam9iQ29uZi5zZXROdW1SZWR1Y2VUYXNrcyhudW1SZWR1Y2VUYXNrcyk7CisKKyAgICAvLyB1c2UgaWRlbnRpdHkgbWFwIChhIHdhc3RlLCBidXQganVzdCBhcyBhbiBleGFtcGxlKQorICAgIElkZW50aXR5VGFibGVNYXAuaW5pdEpvYih0YWJsZU5hbWUsIGNvbHVtbk5hbWVzLCBJZGVudGl0eVRhYmxlTWFwLmNsYXNzLAorICAgICAgICBqb2JDb25mKTsKKworICAgIC8vIHVzZSBJbmRleFRhYmxlUmVkdWNlIHRvIGJ1aWxkIGEgTHVjZW5lIGluZGV4CisgICAgam9iQ29uZi5zZXRSZWR1Y2VyQ2xhc3MoSW5kZXhUYWJsZVJlZHVjZS5jbGFzcyk7CisgICAgRmlsZU91dHB1dEZvcm1hdC5zZXRPdXRwdXRQYXRoKGpvYkNvbmYsIG5ldyBQYXRoKGluZGV4RGlyKSk7CisgICAgam9iQ29uZi5zZXRPdXRwdXRGb3JtYXQoSW5kZXhPdXRwdXRGb3JtYXQuY2xhc3MpOworCisgICAgcmV0dXJuIGpvYkNvbmY7CisgIH0KKworICAvKgorICAgKiBSZWFkIHhtbCBmaWxlIG9mIGluZGV4aW5nIGNvbmZpZ3VyYXRpb25zLiAgVGhlIHhtbCBmb3JtYXQgaXMgc2ltaWxhciB0bworICAgKiBoYmFzZS1kZWZhdWx0LnhtbCBhbmQgaGFkb29wLWRlZmF1bHQueG1sLiBGb3IgYW4gZXhhbXBsZSBjb25maWd1cmF0aW9uLAorICAgKiBzZWUgdGhlIDxjb2RlPmNyZWF0ZUluZGV4Q29uZkNvbnRlbnQ8L2NvZGU+IG1ldGhvZCBpbiBUZXN0VGFibGVJbmRleAorICAgKiBAcGFyYW0gZmlsZU5hbWUgRmlsZSB0byByZWFkLgorICAgKiBAcmV0dXJuIFhNTCBjb25maWd1cmF0aW9uIHJlYWQgZnJvbSBmaWxlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgU3RyaW5nIHJlYWRDb250ZW50KFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShmaWxlTmFtZSk7CisgICAgaW50IGxlbmd0aCA9IChpbnQpIGZpbGUubGVuZ3RoKCk7CisgICAgaWYgKGxlbmd0aCA9PSAwKSB7CisgICAgICBwcmludFVzYWdlKCJJbmRleCBjb25maWd1cmF0aW9uIGZpbGUgIiArIGZpbGVOYW1lICsgIiBkb2VzIG5vdCBleGlzdCIpOworICAgIH0KKworICAgIGludCBieXRlc1JlYWQgPSAwOworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSk7CisKKyAgICB0cnkgeworICAgICAgLy8gcmVhZCBlbnRpcmUgZmlsZSBpbnRvIGNvbnRlbnQKKyAgICAgIHdoaWxlIChieXRlc1JlYWQgPCBsZW5ndGgpIHsKKyAgICAgICAgaW50IHJlYWQgPSBmaXMucmVhZChieXRlcywgYnl0ZXNSZWFkLCBsZW5ndGggLSBieXRlc1JlYWQpOworICAgICAgICBpZiAocmVhZCA+IDApIHsKKyAgICAgICAgICBieXRlc1JlYWQgKz0gcmVhZDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBmaXMuY2xvc2UoKTsKKyAgICB9CisKKyAgICByZXR1cm4gbmV3IFN0cmluZyhieXRlcywgMCwgYnl0ZXNSZWFkLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnVpbGRUYWJsZUluZGV4IGJ1aWxkID0gbmV3IEJ1aWxkVGFibGVJbmRleCgpOworICAgIGJ1aWxkLnJ1bihhcmdzKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9Ecml2ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9Ecml2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTM2OTVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0RyaXZlci5qYXZhCkBAIC0wLDAgKzEsMzkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyYW1Ecml2ZXI7CisKKy8qKgorICogRHJpdmVyIGZvciBoYmFzZSBtYXByZWR1Y2Ugam9icy4gU2VsZWN0IHdoaWNoIHRvIHJ1biBieSBwYXNzaW5nCisgKiBuYW1lIG9mIGpvYiB0byB0aGlzIG1haW4uCisgKi8KK3B1YmxpYyBjbGFzcyBEcml2ZXIgeworICAvKioKKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHRocm93cyBUaHJvd2FibGUgCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICBQcm9ncmFtRHJpdmVyIHBnZCA9IG5ldyBQcm9ncmFtRHJpdmVyKCk7CisgICAgcGdkLmFkZENsYXNzKFJvd0NvdW50ZXIuTkFNRSwgUm93Q291bnRlci5jbGFzcywKKyAgICAgICJDb3VudCByb3dzIGluIEhCYXNlIHRhYmxlIik7CisgICAgcGdkLmRyaXZlcihhcmdzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0dyb3VwaW5nVGFibGVNYXAuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9Hcm91cGluZ1RhYmxlTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGViOWNmYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9Hcm91cGluZ1RhYmxlTWFwLmphdmEKQEAgLTAsMCArMSwxNjAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ29uZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuTWFwUmVkdWNlQmFzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuT3V0cHV0Q29sbGVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZXBvcnRlcjsKKworCisvKioKKyAqIEV4dHJhY3QgZ3JvdXBpbmcgY29sdW1ucyBmcm9tIGlucHV0IHJlY29yZAorICovCitwdWJsaWMgY2xhc3MgR3JvdXBpbmdUYWJsZU1hcAorZXh0ZW5kcyBNYXBSZWR1Y2VCYXNlCitpbXBsZW1lbnRzIFRhYmxlTWFwPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsUm93UmVzdWx0PiB7CisKKyAgLyoqCisgICAqIEpvYkNvbmYgcGFyYW1ldGVyIHRvIHNwZWNpZnkgdGhlIGNvbHVtbnMgdXNlZCB0byBwcm9kdWNlIHRoZSBrZXkgcGFzc2VkIHRvIAorICAgKiBjb2xsZWN0IGZyb20gdGhlIG1hcCBwaGFzZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR1JPVVBfQ09MVU1OUyA9CisgICAgImhiYXNlLm1hcHJlZC5ncm91cGluZ3RhYmxlbWFwLmNvbHVtbnMiOworICAKKyAgcHJvdGVjdGVkIGJ5dGUgW11bXSBtX2NvbHVtbnM7CisKKyAgLyoqCisgICAqIFVzZSB0aGlzIGJlZm9yZSBzdWJtaXR0aW5nIGEgVGFibGVNYXAgam9iLiBJdCB3aWxsIGFwcHJvcHJpYXRlbHkgc2V0IHVwIHRoZQorICAgKiBKb2JDb25mLgorICAgKgorICAgKiBAcGFyYW0gdGFibGUgdGFibGUgdG8gYmUgcHJvY2Vzc2VkCisgICAqIEBwYXJhbSBjb2x1bW5zIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGNvbHVtbnMgdG8gZmV0Y2gKKyAgICogQHBhcmFtIGdyb3VwQ29sdW1ucyBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBjb2x1bW5zIHVzZWQgdG8gZm9ybSB0aGUga2V5CisgICAqIHVzZWQgaW4gY29sbGVjdAorICAgKiBAcGFyYW0gbWFwcGVyIG1hcCBjbGFzcworICAgKiBAcGFyYW0gam9iIGpvYiBjb25maWd1cmF0aW9uIG9iamVjdAorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBpbml0Sm9iKFN0cmluZyB0YWJsZSwgU3RyaW5nIGNvbHVtbnMsIFN0cmluZyBncm91cENvbHVtbnMsIAorICAgIENsYXNzPD8gZXh0ZW5kcyBUYWJsZU1hcD4gbWFwcGVyLCBKb2JDb25mIGpvYikgeworICAgIAorICAgIFRhYmxlTWFwUmVkdWNlVXRpbC5pbml0VGFibGVNYXBKb2IodGFibGUsIGNvbHVtbnMsIG1hcHBlciwKKyAgICAgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZS5jbGFzcywgUm93UmVzdWx0LmNsYXNzLCBqb2IpOworICAgIGpvYi5zZXQoR1JPVVBfQ09MVU1OUywgZ3JvdXBDb2x1bW5zKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjb25maWd1cmUoSm9iQ29uZiBqb2IpIHsKKyAgICBzdXBlci5jb25maWd1cmUoam9iKTsKKyAgICBTdHJpbmdbXSBjb2xzID0gam9iLmdldChHUk9VUF9DT0xVTU5TLCAiIikuc3BsaXQoIiAiKTsKKyAgICBtX2NvbHVtbnMgPSBuZXcgYnl0ZVtjb2xzLmxlbmd0aF1bXTsKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgY29scy5sZW5ndGg7IGkrKykgeworICAgICAgbV9jb2x1bW5zW2ldID0gQnl0ZXMudG9CeXRlcyhjb2xzW2ldKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRXh0cmFjdCB0aGUgZ3JvdXBpbmcgY29sdW1ucyBmcm9tIHZhbHVlIHRvIGNvbnN0cnVjdCBhIG5ldyBrZXkuCisgICAqIAorICAgKiBQYXNzIHRoZSBuZXcga2V5IGFuZCB2YWx1ZSB0byByZWR1Y2UuCisgICAqIElmIGFueSBvZiB0aGUgZ3JvdXBpbmcgY29sdW1ucyBhcmUgbm90IGZvdW5kIGluIHRoZSB2YWx1ZSwgdGhlIHJlY29yZCBpcyBza2lwcGVkLgorICAgKiBAcGFyYW0ga2V5IAorICAgKiBAcGFyYW0gdmFsdWUgCisgICAqIEBwYXJhbSBvdXRwdXQgCisgICAqIEBwYXJhbSByZXBvcnRlciAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIG1hcChJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSwgUm93UmVzdWx0IHZhbHVlLCAKKyAgICAgIE91dHB1dENvbGxlY3RvcjxJbW11dGFibGVCeXRlc1dyaXRhYmxlLFJvd1Jlc3VsdD4gb3V0cHV0LAorICAgICAgUmVwb3J0ZXIgcmVwb3J0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgCisgICAgYnl0ZVtdW10ga2V5VmFscyA9IGV4dHJhY3RLZXlWYWx1ZXModmFsdWUpOworICAgIGlmKGtleVZhbHMgIT0gbnVsbCkgeworICAgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSB0S2V5ID0gY3JlYXRlR3JvdXBLZXkoa2V5VmFscyk7CisgICAgICBvdXRwdXQuY29sbGVjdCh0S2V5LCB2YWx1ZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEV4dHJhY3QgY29sdW1ucyB2YWx1ZXMgZnJvbSB0aGUgY3VycmVudCByZWNvcmQuIFRoaXMgbWV0aG9kIHJldHVybnMKKyAgICogbnVsbCBpZiBhbnkgb2YgdGhlIGNvbHVtbnMgYXJlIG5vdCBmb3VuZC4KKyAgICogCisgICAqIE92ZXJyaWRlIHRoaXMgbWV0aG9kIGlmIHlvdSB3YW50IHRvIGRlYWwgd2l0aCBudWxscyBkaWZmZXJlbnRseS4KKyAgICogCisgICAqIEBwYXJhbSByCisgICAqIEByZXR1cm4gYXJyYXkgb2YgYnl0ZSB2YWx1ZXMKKyAgICovCisgIHByb3RlY3RlZCBieXRlW11bXSBleHRyYWN0S2V5VmFsdWVzKFJvd1Jlc3VsdCByKSB7CisgICAgYnl0ZVtdW10ga2V5VmFscyA9IG51bGw7CisgICAgQXJyYXlMaXN0PGJ5dGVbXT4gZm91bmRMaXN0ID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgaW50IG51bUNvbHMgPSBtX2NvbHVtbnMubGVuZ3RoOworICAgIGlmKG51bUNvbHMgPiAwKSB7CisgICAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPiBlOiByLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgYnl0ZSBbXSBjb2x1bW4gPSBlLmdldEtleSgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUNvbHM7IGkrKykgeworICAgICAgICAgIGlmIChCeXRlcy5lcXVhbHMoY29sdW1uLCBtX2NvbHVtbnNbaV0pKSB7CisgICAgICAgICAgICBmb3VuZExpc3QuYWRkKGUuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYoZm91bmRMaXN0LnNpemUoKSA9PSBudW1Db2xzKSB7CisgICAgICAgIGtleVZhbHMgPSBmb3VuZExpc3QudG9BcnJheShuZXcgYnl0ZVtudW1Db2xzXVtdKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGtleVZhbHM7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGEga2V5IGJ5IGNvbmNhdGVuYXRpbmcgbXVsdGlwbGUgY29sdW1uIHZhbHVlcy4gCisgICAqIE92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gb3JkZXIgdG8gcHJvZHVjZSBkaWZmZXJlbnQgdHlwZXMgb2Yga2V5cy4KKyAgICogCisgICAqIEBwYXJhbSB2YWxzCisgICAqIEByZXR1cm4ga2V5IGdlbmVyYXRlZCBieSBjb25jYXRlbmF0aW5nIG11bHRpcGxlIGNvbHVtbiB2YWx1ZXMKKyAgICovCisgIHByb3RlY3RlZCBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGNyZWF0ZUdyb3VwS2V5KGJ5dGVbXVtdIHZhbHMpIHsKKyAgICBpZih2YWxzID09IG51bGwpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gIG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgZm9yKGludCBpID0gMDsgaSA8IHZhbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgIGlmKGkgPiAwKSB7CisgICAgICAgIHNiLmFwcGVuZCgiICIpOworICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgc2IuYXBwZW5kKG5ldyBTdHJpbmcodmFsc1tpXSwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKHNiLnRvU3RyaW5nKCkpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0hSZWdpb25QYXJ0aXRpb25lci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0hSZWdpb25QYXJ0aXRpb25lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1YTU2ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvSFJlZ2lvblBhcnRpdGlvbmVyLmphdmEKQEAgLTAsMCArMSw5MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5JbW11dGFibGVCeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlBhcnRpdGlvbmVyOworCisKKy8qKgorICogVGhpcyBpcyB1c2VkIHRvIHBhcnRpdGlvbiB0aGUgb3V0cHV0IGtleXMgaW50byBncm91cHMgb2Yga2V5cy4KKyAqIEtleXMgYXJlIGdyb3VwZWQgYWNjb3JkaW5nIHRvIHRoZSByZWdpb25zIHRoYXQgY3VycmVudGx5IGV4aXN0CisgKiBzbyB0aGF0IGVhY2ggcmVkdWNlciBmaWxscyBhIHNpbmdsZSByZWdpb24gc28gbG9hZCBpcyBkaXN0cmlidXRlZC4KKyAqIAorICogQHBhcmFtIDxLMj4KKyAqIEBwYXJhbSA8VjI+CisgKi8KK3B1YmxpYyBjbGFzcyBIUmVnaW9uUGFydGl0aW9uZXI8SzIsVjI+IAoraW1wbGVtZW50cyBQYXJ0aXRpb25lcjxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBWMj4geworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUYWJsZUlucHV0Rm9ybWF0LmNsYXNzKTsKKyAgcHJpdmF0ZSBIVGFibGUgdGFibGU7CisgIHByaXZhdGUgYnl0ZVtdW10gc3RhcnRLZXlzOyAKKyAgCisgIHB1YmxpYyB2b2lkIGNvbmZpZ3VyZShKb2JDb25mIGpvYikgeworICAgIHRyeSB7CisgICAgICB0aGlzLnRhYmxlID0gbmV3IEhUYWJsZShuZXcgSEJhc2VDb25maWd1cmF0aW9uKGpvYiksIAorICAgICAgICBqb2IuZ2V0KFRhYmxlT3V0cHV0Rm9ybWF0Lk9VVFBVVF9UQUJMRSkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcihlKTsKKyAgICB9CisgICAgCisgICAgdHJ5IHsKKyAgICAgIHRoaXMuc3RhcnRLZXlzID0gdGhpcy50YWJsZS5nZXRTdGFydEtleXMoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIGludCBnZXRQYXJ0aXRpb24oSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXksCisgICAgICBWMiB2YWx1ZSwgaW50IG51bVBhcnRpdGlvbnMpIHsKKyAgICBieXRlW10gcmVnaW9uID0gbnVsbDsKKyAgICAvLyBPbmx5IG9uZSByZWdpb24gcmV0dXJuIDAKKyAgICBpZiAodGhpcy5zdGFydEtleXMubGVuZ3RoID09IDEpeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHRyeSB7CisgICAgICAvLyBOb3Qgc3VyZSBpZiB0aGlzIGlzIGNhY2hlZCBhZnRlciBhIHNwbGl0IHNvIHdlIGNvdWxkIGhhdmUgcHJvYmxlbXMKKyAgICAgIC8vIGhlcmUgaWYgYSByZWdpb24gc3BsaXRzIHdoaWxlIG1hcHBpbmcKKyAgICAgIHJlZ2lvbiA9IHRhYmxlLmdldFJlZ2lvbkxvY2F0aW9uKGtleS5nZXQoKSkuZ2V0UmVnaW9uSW5mbygpLmdldFN0YXJ0S2V5KCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKGUpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc3RhcnRLZXlzLmxlbmd0aDsgaSsrKXsKKyAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8ocmVnaW9uLCB0aGlzLnN0YXJ0S2V5c1tpXSkgPT0gMCApeworICAgICAgICBpZiAoaSA+PSBudW1QYXJ0aXRpb25zLTEpeworICAgICAgICAgIC8vIGNvdmVyIGlmIHdlIGhhdmUgbGVzcyByZWR1Y2VzIHRoZW4gcmVnaW9ucy4KKyAgICAgICAgICByZXR1cm4gKEludGVnZXIudG9TdHJpbmcoaSkuaGFzaENvZGUoKSAKKyAgICAgICAgICAgICAgJiBJbnRlZ2VyLk1BWF9WQUxVRSkgJSBudW1QYXJ0aXRpb25zOworICAgICAgICB9CisgICAgICAgIHJldHVybiBpOworICAgICAgfQorICAgIH0KKyAgICAvLyBpZiBhYm92ZSBmYWlscyB0byBmaW5kIHN0YXJ0IGtleSB0aGF0IG1hdGNoIHdlIG5lZWQgdG8gcmV0dXJuIHNvbWV0aGluZworICAgIHJldHVybiAwOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvSWRlbnRpdHlUYWJsZU1hcC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0lkZW50aXR5VGFibGVNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2YwZmMwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0lkZW50aXR5VGFibGVNYXAuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDb25mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NYXBSZWR1Y2VCYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5PdXRwdXRDb2xsZWN0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlJlcG9ydGVyOworCisvKioKKyAqIFBhc3MgdGhlIGdpdmVuIGtleSBhbmQgcmVjb3JkIGFzLWlzIHRvIHJlZHVjZQorICovCitwdWJsaWMgY2xhc3MgSWRlbnRpdHlUYWJsZU1hcAorZXh0ZW5kcyBNYXBSZWR1Y2VCYXNlCitpbXBsZW1lbnRzIFRhYmxlTWFwPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIFJvd1Jlc3VsdD4geworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgSWRlbnRpdHlUYWJsZU1hcCgpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIFVzZSB0aGlzIGJlZm9yZSBzdWJtaXR0aW5nIGEgVGFibGVNYXAgam9iLiBJdCB3aWxsCisgICAqIGFwcHJvcHJpYXRlbHkgc2V0IHVwIHRoZSBKb2JDb25mLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlIHRhYmxlIG5hbWUKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuCisgICAqIEBwYXJhbSBtYXBwZXIgbWFwcGVyIGNsYXNzCisgICAqIEBwYXJhbSBqb2Igam9iIGNvbmZpZ3VyYXRpb24KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdEpvYihTdHJpbmcgdGFibGUsIFN0cmluZyBjb2x1bW5zLAorICAgIENsYXNzPD8gZXh0ZW5kcyBUYWJsZU1hcD4gbWFwcGVyLCBKb2JDb25mIGpvYikgeworICAgIFRhYmxlTWFwUmVkdWNlVXRpbC5pbml0VGFibGVNYXBKb2IodGFibGUsIGNvbHVtbnMsIG1hcHBlciwKKyAgICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MsCisgICAgICBSb3dSZXN1bHQuY2xhc3MsIGpvYik7CisgIH0KKworICAvKioKKyAgICogUGFzcyB0aGUga2V5LCB2YWx1ZSB0byByZWR1Y2UKKyAgICogQHBhcmFtIGtleSAKKyAgICogQHBhcmFtIHZhbHVlIAorICAgKiBAcGFyYW0gb3V0cHV0IAorICAgKiBAcGFyYW0gcmVwb3J0ZXIgCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCBtYXAoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXksIFJvd1Jlc3VsdCB2YWx1ZSwKKyAgICAgIE91dHB1dENvbGxlY3RvcjxJbW11dGFibGVCeXRlc1dyaXRhYmxlLFJvd1Jlc3VsdD4gb3V0cHV0LAorICAgICAgUmVwb3J0ZXIgcmVwb3J0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgCisgICAgLy8gY29udmVydCAKKyAgICBvdXRwdXQuY29sbGVjdChrZXksIHZhbHVlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0lkZW50aXR5VGFibGVSZWR1Y2UuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9JZGVudGl0eVRhYmxlUmVkdWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDhiNTRkNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9JZGVudGl0eVRhYmxlUmVkdWNlLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuTWFwUmVkdWNlQmFzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuT3V0cHV0Q29sbGVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZXBvcnRlcjsKKworLyoqCisgKiBXcml0ZSB0byB0YWJsZSBlYWNoIGtleSwgcmVjb3JkIHBhaXIKKyAqLworcHVibGljIGNsYXNzIElkZW50aXR5VGFibGVSZWR1Y2UKK2V4dGVuZHMgTWFwUmVkdWNlQmFzZQoraW1wbGVtZW50cyBUYWJsZVJlZHVjZTxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBCYXRjaFVwZGF0ZT4geworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9CisgICAgTG9nRmFjdG9yeS5nZXRMb2coSWRlbnRpdHlUYWJsZVJlZHVjZS5jbGFzcy5nZXROYW1lKCkpOworICAKKyAgLyoqCisgICAqIE5vIGFnZ3JlZ2F0aW9uLCBvdXRwdXQgcGFpcnMgb2YgKGtleSwgcmVjb3JkKQorICAgKiBAcGFyYW0ga2V5IAorICAgKiBAcGFyYW0gdmFsdWVzIAorICAgKiBAcGFyYW0gb3V0cHV0IAorICAgKiBAcGFyYW0gcmVwb3J0ZXIgCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCByZWR1Y2UoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXksIEl0ZXJhdG9yPEJhdGNoVXBkYXRlPiB2YWx1ZXMsCisgICAgICBPdXRwdXRDb2xsZWN0b3I8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgQmF0Y2hVcGRhdGU+IG91dHB1dCwKKyAgICAgIFJlcG9ydGVyIHJlcG9ydGVyKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAKKyAgICB3aGlsZSh2YWx1ZXMuaGFzTmV4dCgpKSB7CisgICAgICBvdXRwdXQuY29sbGVjdChrZXksIHZhbHVlcy5uZXh0KCkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4Q29uZmlndXJhdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4Q29uZmlndXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkOTg4ODEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4Q29uZmlndXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDIyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uVHJhbnNmb3JtZXI7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5UcmFuc2Zvcm1lckZhY3Rvcnk7CitpbXBvcnQgamF2YXgueG1sLnRyYW5zZm9ybS5kb20uRE9NU291cmNlOworaW1wb3J0IGphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtLlN0cmVhbVJlc3VsdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGU7CitpbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CitpbXBvcnQgb3JnLnczYy5kb20uVGV4dDsKKworLyoqCisgKiBDb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgZm9yIGJ1aWxkaW5nIGEgTHVjZW5lIGluZGV4CisgKi8KK3B1YmxpYyBjbGFzcyBJbmRleENvbmZpZ3VyYXRpb24gZXh0ZW5kcyBDb25maWd1cmF0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEluZGV4Q29uZmlndXJhdGlvbi5jbGFzcyk7CisKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIQkFTRV9DT0xVTU5fTkFNRSA9ICJoYmFzZS5jb2x1bW4ubmFtZSI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ09MVU1OX1NUT1JFID0gImhiYXNlLmNvbHVtbi5zdG9yZSI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ09MVU1OX0lOREVYID0gImhiYXNlLmNvbHVtbi5pbmRleCI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ09MVU1OX1RPS0VOSVpFID0gImhiYXNlLmNvbHVtbi50b2tlbml6ZSI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ09MVU1OX0JPT1NUID0gImhiYXNlLmNvbHVtbi5ib29zdCI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEJBU0VfQ09MVU1OX09NSVRfTk9STVMgPSAiaGJhc2UuY29sdW1uLm9taXQubm9ybXMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX1JPV0tFWV9OQU1FID0gImhiYXNlLmluZGV4LnJvd2tleS5uYW1lIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIQkFTRV9JTkRFWF9BTkFMWVpFUl9OQU1FID0gImhiYXNlLmluZGV4LmFuYWx5emVyLm5hbWUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX01BWF9CVUZGRVJFRF9ET0NTID0KKyAgICAiaGJhc2UuaW5kZXgubWF4LmJ1ZmZlcmVkLmRvY3MiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX01BWF9CVUZGRVJFRF9ERUxTID0KKyAgICAiaGJhc2UuaW5kZXgubWF4LmJ1ZmZlcmVkLmRlbHMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX01BWF9GSUVMRF9MRU5HVEggPQorICAgICJoYmFzZS5pbmRleC5tYXguZmllbGQubGVuZ3RoIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIQkFTRV9JTkRFWF9NQVhfTUVSR0VfRE9DUyA9CisgICAgImhiYXNlLmluZGV4Lm1heC5tZXJnZS5kb2NzIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIQkFTRV9JTkRFWF9NRVJHRV9GQUNUT1IgPSAiaGJhc2UuaW5kZXgubWVyZ2UuZmFjdG9yIjsKKyAgLy8gZG91YmxlIHJhbUJ1ZmZlclNpemVNQjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIQkFTRV9JTkRFWF9TSU1JTEFSSVRZX05BTUUgPQorICAgICJoYmFzZS5pbmRleC5zaW1pbGFyaXR5Lm5hbWUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX1VTRV9DT01QT1VORF9GSUxFID0KKyAgICAiaGJhc2UuaW5kZXgudXNlLmNvbXBvdW5kLmZpbGUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEhCQVNFX0lOREVYX09QVElNSVpFID0gImhiYXNlLmluZGV4Lm9wdGltaXplIjsKKworICBwdWJsaWMgc3RhdGljIGNsYXNzIENvbHVtbkNvbmYgZXh0ZW5kcyBQcm9wZXJ0aWVzIHsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc0MTkwMTIyOTA1ODA2MDc4MjFMOworCisgICAgYm9vbGVhbiBnZXRCb29sZWFuKFN0cmluZyBuYW1lLCBib29sZWFuIGRlZmF1bHRWYWx1ZSkgeworICAgICAgU3RyaW5nIHZhbHVlU3RyaW5nID0gZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICBpZiAoInRydWUiLmVxdWFscyh2YWx1ZVN0cmluZykpCisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgZWxzZSBpZiAoImZhbHNlIi5lcXVhbHModmFsdWVTdHJpbmcpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBlbHNlCisgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgfQorCisgICAgdm9pZCBzZXRCb29sZWFuKFN0cmluZyBuYW1lLCBib29sZWFuIHZhbHVlKSB7CisgICAgICBzZXRQcm9wZXJ0eShuYW1lLCBCb29sZWFuLnRvU3RyaW5nKHZhbHVlKSk7CisgICAgfQorCisgICAgZmxvYXQgZ2V0RmxvYXQoU3RyaW5nIG5hbWUsIGZsb2F0IGRlZmF1bHRWYWx1ZSkgeworICAgICAgU3RyaW5nIHZhbHVlU3RyaW5nID0gZ2V0UHJvcGVydHkobmFtZSk7CisgICAgICBpZiAodmFsdWVTdHJpbmcgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiBGbG9hdC5wYXJzZUZsb2F0KHZhbHVlU3RyaW5nKTsKKyAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgICAgICB9CisgICAgfQorCisgICAgdm9pZCBzZXRGbG9hdChTdHJpbmcgbmFtZSwgZmxvYXQgdmFsdWUpIHsKKyAgICAgIHNldFByb3BlcnR5KG5hbWUsIEZsb2F0LnRvU3RyaW5nKHZhbHVlKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBDb2x1bW5Db25mPiBjb2x1bW5NYXAgPQorICAgIG5ldyBDb25jdXJyZW50SGFzaE1hcDxTdHJpbmcsIENvbHVtbkNvbmY+KCk7CisKKyAgcHVibGljIEl0ZXJhdG9yPFN0cmluZz4gY29sdW1uTmFtZUl0ZXJhdG9yKCkgeworICAgIHJldHVybiBjb2x1bW5NYXAua2V5U2V0KCkuaXRlcmF0b3IoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzSW5kZXgoU3RyaW5nIGNvbHVtbk5hbWUpIHsKKyAgICByZXR1cm4gZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLmdldEJvb2xlYW4oSEJBU0VfQ09MVU1OX0lOREVYLCB0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEluZGV4KFN0cmluZyBjb2x1bW5OYW1lLCBib29sZWFuIGluZGV4KSB7CisgICAgZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLnNldEJvb2xlYW4oSEJBU0VfQ09MVU1OX0lOREVYLCBpbmRleCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc1N0b3JlKFN0cmluZyBjb2x1bW5OYW1lKSB7CisgICAgcmV0dXJuIGdldENvbHVtbihjb2x1bW5OYW1lKS5nZXRCb29sZWFuKEhCQVNFX0NPTFVNTl9TVE9SRSwgZmFsc2UpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0U3RvcmUoU3RyaW5nIGNvbHVtbk5hbWUsIGJvb2xlYW4gc3RvcmUpIHsKKyAgICBnZXRDb2x1bW4oY29sdW1uTmFtZSkuc2V0Qm9vbGVhbihIQkFTRV9DT0xVTU5fU1RPUkUsIHN0b3JlKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzVG9rZW5pemUoU3RyaW5nIGNvbHVtbk5hbWUpIHsKKyAgICByZXR1cm4gZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLmdldEJvb2xlYW4oSEJBU0VfQ09MVU1OX1RPS0VOSVpFLCB0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFRva2VuaXplKFN0cmluZyBjb2x1bW5OYW1lLCBib29sZWFuIHRva2VuaXplKSB7CisgICAgZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLnNldEJvb2xlYW4oSEJBU0VfQ09MVU1OX1RPS0VOSVpFLCB0b2tlbml6ZSk7CisgIH0KKworICBwdWJsaWMgZmxvYXQgZ2V0Qm9vc3QoU3RyaW5nIGNvbHVtbk5hbWUpIHsKKyAgICByZXR1cm4gZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLmdldEZsb2F0KEhCQVNFX0NPTFVNTl9CT09TVCwgMS4wZik7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRCb29zdChTdHJpbmcgY29sdW1uTmFtZSwgZmxvYXQgYm9vc3QpIHsKKyAgICBnZXRDb2x1bW4oY29sdW1uTmFtZSkuc2V0RmxvYXQoSEJBU0VfQ09MVU1OX0JPT1NULCBib29zdCk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBpc09taXROb3JtcyhTdHJpbmcgY29sdW1uTmFtZSkgeworICAgIHJldHVybiBnZXRDb2x1bW4oY29sdW1uTmFtZSkuZ2V0Qm9vbGVhbihIQkFTRV9DT0xVTU5fT01JVF9OT1JNUywgdHJ1ZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRPbWl0Tm9ybXMoU3RyaW5nIGNvbHVtbk5hbWUsIGJvb2xlYW4gb21pdE5vcm1zKSB7CisgICAgZ2V0Q29sdW1uKGNvbHVtbk5hbWUpLnNldEJvb2xlYW4oSEJBU0VfQ09MVU1OX09NSVRfTk9STVMsIG9taXROb3Jtcyk7CisgIH0KKworICBwcml2YXRlIENvbHVtbkNvbmYgZ2V0Q29sdW1uKFN0cmluZyBjb2x1bW5OYW1lKSB7CisgICAgQ29sdW1uQ29uZiBjb2x1bW4gPSBjb2x1bW5NYXAuZ2V0KGNvbHVtbk5hbWUpOworICAgIGlmIChjb2x1bW4gPT0gbnVsbCkgeworICAgICAgY29sdW1uID0gbmV3IENvbHVtbkNvbmYoKTsKKyAgICAgIGNvbHVtbk1hcC5wdXQoY29sdW1uTmFtZSwgY29sdW1uKTsKKyAgICB9CisgICAgcmV0dXJuIGNvbHVtbjsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0QW5hbHl6ZXJOYW1lKCkgeworICAgIHJldHVybiBnZXQoSEJBU0VfSU5ERVhfQU5BTFlaRVJfTkFNRSwKKyAgICAgICAgIm9yZy5hcGFjaGUubHVjZW5lLmFuYWx5c2lzLnN0YW5kYXJkLlN0YW5kYXJkQW5hbHl6ZXIiKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEFuYWx5emVyTmFtZShTdHJpbmcgYW5hbHl6ZXJOYW1lKSB7CisgICAgc2V0KEhCQVNFX0lOREVYX0FOQUxZWkVSX05BTUUsIGFuYWx5emVyTmFtZSk7CisgIH0KKworICBwdWJsaWMgaW50IGdldE1heEJ1ZmZlcmVkRGVsZXRlVGVybXMoKSB7CisgICAgcmV0dXJuIGdldEludChIQkFTRV9JTkRFWF9NQVhfQlVGRkVSRURfREVMUywgMTAwMCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNYXhCdWZmZXJlZERlbGV0ZVRlcm1zKGludCBtYXhCdWZmZXJlZERlbGV0ZVRlcm1zKSB7CisgICAgc2V0SW50KEhCQVNFX0lOREVYX01BWF9CVUZGRVJFRF9ERUxTLCBtYXhCdWZmZXJlZERlbGV0ZVRlcm1zKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0TWF4QnVmZmVyZWREb2NzKCkgeworICAgIHJldHVybiBnZXRJbnQoSEJBU0VfSU5ERVhfTUFYX0JVRkZFUkVEX0RPQ1MsIDEwKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1heEJ1ZmZlcmVkRG9jcyhpbnQgbWF4QnVmZmVyZWREb2NzKSB7CisgICAgc2V0SW50KEhCQVNFX0lOREVYX01BWF9CVUZGRVJFRF9ET0NTLCBtYXhCdWZmZXJlZERvY3MpOworICB9CisKKyAgcHVibGljIGludCBnZXRNYXhGaWVsZExlbmd0aCgpIHsKKyAgICByZXR1cm4gZ2V0SW50KEhCQVNFX0lOREVYX01BWF9GSUVMRF9MRU5HVEgsIEludGVnZXIuTUFYX1ZBTFVFKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1heEZpZWxkTGVuZ3RoKGludCBtYXhGaWVsZExlbmd0aCkgeworICAgIHNldEludChIQkFTRV9JTkRFWF9NQVhfRklFTERfTEVOR1RILCBtYXhGaWVsZExlbmd0aCk7CisgIH0KKworICBwdWJsaWMgaW50IGdldE1heE1lcmdlRG9jcygpIHsKKyAgICByZXR1cm4gZ2V0SW50KEhCQVNFX0lOREVYX01BWF9NRVJHRV9ET0NTLCBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNYXhNZXJnZURvY3MoaW50IG1heE1lcmdlRG9jcykgeworICAgIHNldEludChIQkFTRV9JTkRFWF9NQVhfTUVSR0VfRE9DUywgbWF4TWVyZ2VEb2NzKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0TWVyZ2VGYWN0b3IoKSB7CisgICAgcmV0dXJuIGdldEludChIQkFTRV9JTkRFWF9NRVJHRV9GQUNUT1IsIDEwKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1lcmdlRmFjdG9yKGludCBtZXJnZUZhY3RvcikgeworICAgIHNldEludChIQkFTRV9JTkRFWF9NRVJHRV9GQUNUT1IsIG1lcmdlRmFjdG9yKTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0Um93a2V5TmFtZSgpIHsKKyAgICByZXR1cm4gZ2V0KEhCQVNFX0lOREVYX1JPV0tFWV9OQU1FLCAiUk9XS0VZIik7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRSb3drZXlOYW1lKFN0cmluZyByb3drZXlOYW1lKSB7CisgICAgc2V0KEhCQVNFX0lOREVYX1JPV0tFWV9OQU1FLCByb3drZXlOYW1lKTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0U2ltaWxhcml0eU5hbWUoKSB7CisgICAgcmV0dXJuIGdldChIQkFTRV9JTkRFWF9TSU1JTEFSSVRZX05BTUUsIG51bGwpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0U2ltaWxhcml0eU5hbWUoU3RyaW5nIHNpbWlsYXJpdHlOYW1lKSB7CisgICAgc2V0KEhCQVNFX0lOREVYX1NJTUlMQVJJVFlfTkFNRSwgc2ltaWxhcml0eU5hbWUpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNVc2VDb21wb3VuZEZpbGUoKSB7CisgICAgcmV0dXJuIGdldEJvb2xlYW4oSEJBU0VfSU5ERVhfVVNFX0NPTVBPVU5EX0ZJTEUsIGZhbHNlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFVzZUNvbXBvdW5kRmlsZShib29sZWFuIHVzZUNvbXBvdW5kRmlsZSkgeworICAgIHNldEJvb2xlYW4oSEJBU0VfSU5ERVhfVVNFX0NPTVBPVU5EX0ZJTEUsIHVzZUNvbXBvdW5kRmlsZSk7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBkb09wdGltaXplKCkgeworICAgIHJldHVybiBnZXRCb29sZWFuKEhCQVNFX0lOREVYX09QVElNSVpFLCB0cnVlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldERvT3B0aW1pemUoYm9vbGVhbiBkb09wdGltaXplKSB7CisgICAgc2V0Qm9vbGVhbihIQkFTRV9JTkRFWF9PUFRJTUlaRSwgZG9PcHRpbWl6ZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBhZGRGcm9tWE1MKFN0cmluZyBjb250ZW50KSB7CisgICAgdHJ5IHsKKyAgICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeS5uZXdJbnN0YW5jZSgpCisgICAgICAgICAgLm5ld0RvY3VtZW50QnVpbGRlcigpOworCisgICAgICBEb2N1bWVudCBkb2MgPSBidWlsZGVyCisgICAgICAgICAgLnBhcnNlKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb250ZW50LmdldEJ5dGVzKCkpKTsKKworICAgICAgRWxlbWVudCByb290ID0gZG9jLmdldERvY3VtZW50RWxlbWVudCgpOworICAgICAgaWYgKCEiY29uZmlndXJhdGlvbiIuZXF1YWxzKHJvb3QuZ2V0VGFnTmFtZSgpKSkgeworICAgICAgICBMT0cuZmF0YWwoImJhZCBjb25mIGZpbGU6IHRvcC1sZXZlbCBlbGVtZW50IG5vdCA8Y29uZmlndXJhdGlvbj4iKTsKKyAgICAgIH0KKworICAgICAgTm9kZUxpc3QgcHJvcHMgPSByb290LmdldENoaWxkTm9kZXMoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvcHMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgICBOb2RlIHByb3BOb2RlID0gcHJvcHMuaXRlbShpKTsKKyAgICAgICAgaWYgKCEocHJvcE5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgRWxlbWVudCBwcm9wID0gKEVsZW1lbnQpIHByb3BOb2RlOworICAgICAgICBpZiAoInByb3BlcnR5Ii5lcXVhbHMocHJvcC5nZXRUYWdOYW1lKCkpKSB7CisgICAgICAgICAgcHJvcGVydHlGcm9tWE1MKHByb3AsIG51bGwpOworICAgICAgICB9IGVsc2UgaWYgKCJjb2x1bW4iLmVxdWFscyhwcm9wLmdldFRhZ05hbWUoKSkpIHsKKyAgICAgICAgICBjb2x1bW5Db25mRnJvbVhNTChwcm9wKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBMT0cud2FybigiYmFkIGNvbmYgY29udGVudDogZWxlbWVudCBuZWl0aGVyIDxwcm9wZXJ0eT4gbm9yIDxjb2x1bW4+Iik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmZhdGFsKCJlcnJvciBwYXJzaW5nIGNvbmYgY29udGVudDogIiArIGUpOworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHByb3BlcnR5RnJvbVhNTChFbGVtZW50IHByb3AsIFByb3BlcnRpZXMgcHJvcGVydGllcykgeworICAgIE5vZGVMaXN0IGZpZWxkcyA9IHByb3AuZ2V0Q2hpbGROb2RlcygpOworICAgIFN0cmluZyBhdHRyID0gbnVsbDsKKyAgICBTdHJpbmcgdmFsdWUgPSBudWxsOworCisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWVsZHMuZ2V0TGVuZ3RoKCk7IGorKykgeworICAgICAgTm9kZSBmaWVsZE5vZGUgPSBmaWVsZHMuaXRlbShqKTsKKyAgICAgIGlmICghKGZpZWxkTm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICBFbGVtZW50IGZpZWxkID0gKEVsZW1lbnQpIGZpZWxkTm9kZTsKKyAgICAgIGlmICgibmFtZSIuZXF1YWxzKGZpZWxkLmdldFRhZ05hbWUoKSkpIHsKKyAgICAgICAgYXR0ciA9ICgoVGV4dCkgZmllbGQuZ2V0Rmlyc3RDaGlsZCgpKS5nZXREYXRhKCk7CisgICAgICB9CisgICAgICBpZiAoInZhbHVlIi5lcXVhbHMoZmllbGQuZ2V0VGFnTmFtZSgpKSAmJiBmaWVsZC5oYXNDaGlsZE5vZGVzKCkpIHsKKyAgICAgICAgdmFsdWUgPSAoKFRleHQpIGZpZWxkLmdldEZpcnN0Q2hpbGQoKSkuZ2V0RGF0YSgpOworICAgICAgfQorICAgIH0KKworICAgIGlmIChhdHRyICE9IG51bGwgJiYgdmFsdWUgIT0gbnVsbCkgeworICAgICAgaWYgKHByb3BlcnRpZXMgPT0gbnVsbCkgeworICAgICAgICBzZXQoYXR0ciwgdmFsdWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eShhdHRyLCB2YWx1ZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNvbHVtbkNvbmZGcm9tWE1MKEVsZW1lbnQgY29sdW1uKSB7CisgICAgQ29sdW1uQ29uZiBjb2x1bW5Db25mID0gbmV3IENvbHVtbkNvbmYoKTsKKyAgICBOb2RlTGlzdCBwcm9wcyA9IGNvbHVtbi5nZXRDaGlsZE5vZGVzKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm9wcy5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICBOb2RlIHByb3BOb2RlID0gcHJvcHMuaXRlbShpKTsKKyAgICAgIGlmICghKHByb3BOb2RlIGluc3RhbmNlb2YgRWxlbWVudCkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIEVsZW1lbnQgcHJvcCA9IChFbGVtZW50KSBwcm9wTm9kZTsKKyAgICAgIGlmICgicHJvcGVydHkiLmVxdWFscyhwcm9wLmdldFRhZ05hbWUoKSkpIHsKKyAgICAgICAgcHJvcGVydHlGcm9tWE1MKHByb3AsIGNvbHVtbkNvbmYpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgTE9HLndhcm4oImJhZCBjb25mIGNvbnRlbnQ6IGVsZW1lbnQgbm90IDxwcm9wZXJ0eT4iKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoY29sdW1uQ29uZi5nZXRQcm9wZXJ0eShIQkFTRV9DT0xVTU5fTkFNRSkgIT0gbnVsbCkgeworICAgICAgY29sdW1uTWFwLnB1dChjb2x1bW5Db25mLmdldFByb3BlcnR5KEhCQVNFX0NPTFVNTl9OQU1FKSwgY29sdW1uQ29uZik7CisgICAgfSBlbHNlIHsKKyAgICAgIExPRy53YXJuKCJiYWQgY29sdW1uIGNvbmY6IG5hbWUgbm90IHNwZWNpZmllZCIpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICB0cnkgeworICAgICAgRG9jdW1lbnQgZG9jID0gd3JpdGVEb2N1bWVudCgpOworICAgICAgRE9NU291cmNlIHNvdXJjZSA9IG5ldyBET01Tb3VyY2UoZG9jKTsKKyAgICAgIFN0cmVhbVJlc3VsdCByZXN1bHQgPSBuZXcgU3RyZWFtUmVzdWx0KG91dCk7CisgICAgICBUcmFuc2Zvcm1lckZhY3RvcnkgdHJhbnNGYWN0b3J5ID0gVHJhbnNmb3JtZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CisgICAgICBUcmFuc2Zvcm1lciB0cmFuc2Zvcm1lciA9IHRyYW5zRmFjdG9yeS5uZXdUcmFuc2Zvcm1lcigpOworICAgICAgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHNvdXJjZSwgcmVzdWx0KTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBEb2N1bWVudCB3cml0ZURvY3VtZW50KCkgeworICAgIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4+IGl0ZXIgPSBpdGVyYXRvcigpOworICAgIHRyeSB7CisgICAgICBEb2N1bWVudCBkb2MgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3RG9jdW1lbnRCdWlsZGVyKCkKKyAgICAgICAgICAubmV3RG9jdW1lbnQoKTsKKyAgICAgIEVsZW1lbnQgY29uZiA9IGRvYy5jcmVhdGVFbGVtZW50KCJjb25maWd1cmF0aW9uIik7CisgICAgICBkb2MuYXBwZW5kQ2hpbGQoY29uZik7CisgICAgICBjb25mLmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZSgiXG4iKSk7CisKKyAgICAgIE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZW50cnk7CisgICAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgZW50cnkgPSBpdGVyLm5leHQoKTsKKyAgICAgICAgU3RyaW5nIG5hbWUgPSBlbnRyeS5nZXRLZXkoKTsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKTsKKyAgICAgICAgd3JpdGVQcm9wZXJ0eShkb2MsIGNvbmYsIG5hbWUsIHZhbHVlKTsKKyAgICAgIH0KKworICAgICAgSXRlcmF0b3I8U3RyaW5nPiBjb2x1bW5JdGVyID0gY29sdW1uTmFtZUl0ZXJhdG9yKCk7CisgICAgICB3aGlsZSAoY29sdW1uSXRlci5oYXNOZXh0KCkpIHsKKyAgICAgICAgd3JpdGVDb2x1bW4oZG9jLCBjb25mLCBjb2x1bW5JdGVyLm5leHQoKSk7CisgICAgICB9CisKKyAgICAgIHJldHVybiBkb2M7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCB3cml0ZVByb3BlcnR5KERvY3VtZW50IGRvYywgRWxlbWVudCBwYXJlbnQsIFN0cmluZyBuYW1lLAorICAgICAgU3RyaW5nIHZhbHVlKSB7CisgICAgRWxlbWVudCBwcm9wTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCJwcm9wZXJ0eSIpOworICAgIHBhcmVudC5hcHBlbmRDaGlsZChwcm9wTm9kZSk7CisKKyAgICBFbGVtZW50IG5hbWVOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoIm5hbWUiKTsKKyAgICBuYW1lTm9kZS5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUobmFtZSkpOworICAgIHByb3BOb2RlLmFwcGVuZENoaWxkKG5hbWVOb2RlKTsKKworICAgIEVsZW1lbnQgdmFsdWVOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoInZhbHVlIik7CisgICAgdmFsdWVOb2RlLmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZSh2YWx1ZSkpOworICAgIHByb3BOb2RlLmFwcGVuZENoaWxkKHZhbHVlTm9kZSk7CisKKyAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKCJcbiIpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB3cml0ZUNvbHVtbihEb2N1bWVudCBkb2MsIEVsZW1lbnQgcGFyZW50LCBTdHJpbmcgY29sdW1uTmFtZSkgeworICAgIEVsZW1lbnQgY29sdW1uID0gZG9jLmNyZWF0ZUVsZW1lbnQoImNvbHVtbiIpOworICAgIHBhcmVudC5hcHBlbmRDaGlsZChjb2x1bW4pOworICAgIGNvbHVtbi5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUoIlxuIikpOworCisgICAgQ29sdW1uQ29uZiBjb2x1bW5Db25mID0gZ2V0Q29sdW1uKGNvbHVtbk5hbWUpOworICAgIGZvciAoTWFwLkVudHJ5PE9iamVjdCwgT2JqZWN0PiBlbnRyeSA6IGNvbHVtbkNvbmYuZW50cnlTZXQoKSkgeworICAgICAgaWYgKGVudHJ5LmdldEtleSgpIGluc3RhbmNlb2YgU3RyaW5nCisgICAgICAgICAgJiYgZW50cnkuZ2V0VmFsdWUoKSBpbnN0YW5jZW9mIFN0cmluZykgeworICAgICAgICB3cml0ZVByb3BlcnR5KGRvYywgY29sdW1uLCAoU3RyaW5nKSBlbnRyeS5nZXRLZXkoKSwgKFN0cmluZykgZW50cnkKKyAgICAgICAgICAgIC5nZXRWYWx1ZSgpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgIHRyeSB7CisgICAgICBEb2N1bWVudCBkb2MgPSB3cml0ZURvY3VtZW50KCk7CisgICAgICBET01Tb3VyY2Ugc291cmNlID0gbmV3IERPTVNvdXJjZShkb2MpOworICAgICAgU3RyZWFtUmVzdWx0IHJlc3VsdCA9IG5ldyBTdHJlYW1SZXN1bHQod3JpdGVyKTsKKyAgICAgIFRyYW5zZm9ybWVyRmFjdG9yeSB0cmFuc0ZhY3RvcnkgPSBUcmFuc2Zvcm1lckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKKyAgICAgIFRyYW5zZm9ybWVyIHRyYW5zZm9ybWVyID0gdHJhbnNGYWN0b3J5Lm5ld1RyYW5zZm9ybWVyKCk7CisgICAgICB0cmFuc2Zvcm1lci50cmFuc2Zvcm0oc291cmNlLCByZXN1bHQpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICB9CisgICAgcmV0dXJuIHdyaXRlci50b1N0cmluZygpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4T3V0cHV0Rm9ybWF0LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvSW5kZXhPdXRwdXRGb3JtYXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNWU3YzcwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4T3V0cHV0Rm9ybWF0LmphdmEKQEAgLTAsMCArMSwxNjMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ29uZjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuRmlsZU91dHB1dEZvcm1hdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVjb3JkV3JpdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZXBvcnRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyZXNzYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5hbmFseXNpcy5BbmFseXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5kb2N1bWVudC5Eb2N1bWVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5pbmRleC5JbmRleFdyaXRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5zZWFyY2guU2ltaWxhcml0eTsKKworLyoqCisgKiBDcmVhdGUgYSBsb2NhbCBpbmRleCwgdW53cmFwIEx1Y2VuZSBkb2N1bWVudHMgY3JlYXRlZCBieSByZWR1Y2UsIGFkZCB0aGVtIHRvCisgKiB0aGUgaW5kZXgsIGFuZCBjb3B5IHRoZSBpbmRleCB0byB0aGUgZGVzdGluYXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBJbmRleE91dHB1dEZvcm1hdCBleHRlbmRzCisgICAgRmlsZU91dHB1dEZvcm1hdDxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBMdWNlbmVEb2N1bWVudFdyYXBwZXI+IHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhJbmRleE91dHB1dEZvcm1hdC5jbGFzcyk7CisKKyAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgUmVjb3JkV3JpdGVyPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEx1Y2VuZURvY3VtZW50V3JhcHBlcj4KKyAgZ2V0UmVjb3JkV3JpdGVyKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIEpvYkNvbmYgam9iLCBTdHJpbmcgbmFtZSwKKyAgICAgIGZpbmFsIFByb2dyZXNzYWJsZSBwcm9ncmVzcykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIGZpbmFsIFBhdGggcGVybSA9IG5ldyBQYXRoKEZpbGVPdXRwdXRGb3JtYXQuZ2V0T3V0cHV0UGF0aChqb2IpLCBuYW1lKTsKKyAgICBmaW5hbCBQYXRoIHRlbXAgPSBqb2IuZ2V0TG9jYWxQYXRoKCJpbmRleC9fIgorICAgICAgICArIEludGVnZXIudG9TdHJpbmcocmFuZG9tLm5leHRJbnQoKSkpOworCisgICAgTE9HLmluZm8oIlRvIGluZGV4IGludG8gIiArIHBlcm0pOworCisgICAgLy8gZGVsZXRlIG9sZCwgaWYgYW55CisgICAgZnMuZGVsZXRlKHBlcm0sIHRydWUpOworCisgICAgZmluYWwgSW5kZXhDb25maWd1cmF0aW9uIGluZGV4Q29uZiA9IG5ldyBJbmRleENvbmZpZ3VyYXRpb24oKTsKKyAgICBTdHJpbmcgY29udGVudCA9IGpvYi5nZXQoImhiYXNlLmluZGV4LmNvbmYiKTsKKyAgICBpZiAoY29udGVudCAhPSBudWxsKSB7CisgICAgICBpbmRleENvbmYuYWRkRnJvbVhNTChjb250ZW50KTsKKyAgICB9CisKKyAgICBTdHJpbmcgYW5hbHl6ZXJOYW1lID0gaW5kZXhDb25mLmdldEFuYWx5emVyTmFtZSgpOworICAgIEFuYWx5emVyIGFuYWx5emVyOworICAgIHRyeSB7CisgICAgICBDbGFzczw/PiBhbmFseXplckNsYXNzID0gQ2xhc3MuZm9yTmFtZShhbmFseXplck5hbWUpOworICAgICAgYW5hbHl6ZXIgPSAoQW5hbHl6ZXIpIGFuYWx5emVyQ2xhc3MubmV3SW5zdGFuY2UoKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFcnJvciBpbiBjcmVhdGluZyBhbiBhbmFseXplciBvYmplY3QgIgorICAgICAgICAgICsgYW5hbHl6ZXJOYW1lKTsKKyAgICB9CisKKyAgICAvLyBidWlsZCBsb2NhbGx5IGZpcnN0CisgICAgZmluYWwgSW5kZXhXcml0ZXIgd3JpdGVyID0gbmV3IEluZGV4V3JpdGVyKGZzLnN0YXJ0TG9jYWxPdXRwdXQocGVybSwgdGVtcCkKKyAgICAgICAgLnRvU3RyaW5nKCksIGFuYWx5emVyLCB0cnVlKTsKKworICAgIC8vIG5vIGRlbGV0ZSwgc28gbm8gbmVlZCBmb3IgbWF4QnVmZmVyZWREZWxldGVUZXJtcworICAgIHdyaXRlci5zZXRNYXhCdWZmZXJlZERvY3MoaW5kZXhDb25mLmdldE1heEJ1ZmZlcmVkRG9jcygpKTsKKyAgICB3cml0ZXIuc2V0TWF4RmllbGRMZW5ndGgoaW5kZXhDb25mLmdldE1heEZpZWxkTGVuZ3RoKCkpOworICAgIHdyaXRlci5zZXRNYXhNZXJnZURvY3MoaW5kZXhDb25mLmdldE1heE1lcmdlRG9jcygpKTsKKyAgICB3cml0ZXIuc2V0TWVyZ2VGYWN0b3IoaW5kZXhDb25mLmdldE1lcmdlRmFjdG9yKCkpOworICAgIFN0cmluZyBzaW1pbGFyaXR5TmFtZSA9IGluZGV4Q29uZi5nZXRTaW1pbGFyaXR5TmFtZSgpOworICAgIGlmIChzaW1pbGFyaXR5TmFtZSAhPSBudWxsKSB7CisgICAgICB0cnkgeworICAgICAgICBDbGFzczw/PiBzaW1pbGFyaXR5Q2xhc3MgPSBDbGFzcy5mb3JOYW1lKHNpbWlsYXJpdHlOYW1lKTsKKyAgICAgICAgU2ltaWxhcml0eSBzaW1pbGFyaXR5ID0gKFNpbWlsYXJpdHkpIHNpbWlsYXJpdHlDbGFzcy5uZXdJbnN0YW5jZSgpOworICAgICAgICB3cml0ZXIuc2V0U2ltaWxhcml0eShzaW1pbGFyaXR5KTsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXJyb3IgaW4gY3JlYXRpbmcgYSBzaW1pbGFydHkgb2JqZWN0ICIKKyAgICAgICAgICAgICsgc2ltaWxhcml0eU5hbWUpOworICAgICAgfQorICAgIH0KKyAgICB3cml0ZXIuc2V0VXNlQ29tcG91bmRGaWxlKGluZGV4Q29uZi5pc1VzZUNvbXBvdW5kRmlsZSgpKTsKKworICAgIHJldHVybiBuZXcgUmVjb3JkV3JpdGVyPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEx1Y2VuZURvY3VtZW50V3JhcHBlcj4oKSB7CisgICAgICBib29sZWFuIGNsb3NlZDsKKyAgICAgIHByaXZhdGUgbG9uZyBkb2NDb3VudCA9IDA7CisKKyAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKEltbXV0YWJsZUJ5dGVzV3JpdGFibGUga2V5LCAKKyAgICAgICAgICBMdWNlbmVEb2N1bWVudFdyYXBwZXIgdmFsdWUpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyB1bndyYXAgYW5kIGluZGV4IGRvYworICAgICAgICBEb2N1bWVudCBkb2MgPSB2YWx1ZS5nZXQoKTsKKyAgICAgICAgd3JpdGVyLmFkZERvY3VtZW50KGRvYyk7CisgICAgICAgIGRvY0NvdW50Kys7CisgICAgICAgIHByb2dyZXNzLnByb2dyZXNzKCk7CisgICAgICB9CisKKyAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKGZpbmFsIFJlcG9ydGVyIHJlcG9ydGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBzcGF3biBhIHRocmVhZCB0byBnaXZlIHByb2dyZXNzIGhlYXJ0YmVhdHMKKyAgICAgICAgVGhyZWFkIHByb2cgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIHdoaWxlICghY2xvc2VkKSB7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgcmVwb3J0ZXIuc2V0U3RhdHVzKCJjbG9zaW5nIik7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIHRyeSB7CisgICAgICAgICAgcHJvZy5zdGFydCgpOworCisgICAgICAgICAgLy8gb3B0aW1pemUgaW5kZXgKKyAgICAgICAgICBpZiAoaW5kZXhDb25mLmRvT3B0aW1pemUoKSkgeworICAgICAgICAgICAgaWYgKExPRy5pc0luZm9FbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmluZm8oIk9wdGltaXppbmcgaW5kZXguIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3cml0ZXIub3B0aW1pemUoKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBjbG9zZSBpbmRleAorICAgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgICAgIGlmIChMT0cuaXNJbmZvRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuaW5mbygiRG9uZSBpbmRleGluZyAiICsgZG9jQ291bnQgKyAiIGRvY3MuIik7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gY29weSB0byBwZXJtIGRlc3RpbmF0aW9uIGluIGRmcworICAgICAgICAgIGZzLmNvbXBsZXRlTG9jYWxPdXRwdXQocGVybSwgdGVtcCk7CisgICAgICAgICAgaWYgKExPRy5pc0luZm9FbmFibGVkKCkpIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJDb3B5IGRvbmUuIik7CisgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvSW5kZXhUYWJsZVJlZHVjZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4VGFibGVSZWR1Y2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTQ4OWIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0luZGV4VGFibGVSZWR1Y2UuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1hcFJlZHVjZUJhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk91dHB1dENvbGxlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVkdWNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVwb3J0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5sdWNlbmUuZG9jdW1lbnQuRG9jdW1lbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5sdWNlbmUuZG9jdW1lbnQuRmllbGQ7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKKy8qKgorICogQ29uc3RydWN0IGEgTHVjZW5lIGRvY3VtZW50IHBlciByb3csIHdoaWNoIGlzIGNvbnN1bWVkIGJ5IEluZGV4T3V0cHV0Rm9ybWF0CisgKiB0byBidWlsZCBhIEx1Y2VuZSBpbmRleAorICovCitwdWJsaWMgY2xhc3MgSW5kZXhUYWJsZVJlZHVjZSBleHRlbmRzIE1hcFJlZHVjZUJhc2UgaW1wbGVtZW50cworICAgIFJlZHVjZXI8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgUm93UmVzdWx0LCBJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBMdWNlbmVEb2N1bWVudFdyYXBwZXI+IHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEluZGV4VGFibGVSZWR1Y2UuY2xhc3MpOworICBwcml2YXRlIEluZGV4Q29uZmlndXJhdGlvbiBpbmRleENvbmY7CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNvbmZpZ3VyZShKb2JDb25mIGpvYikgeworICAgIHN1cGVyLmNvbmZpZ3VyZShqb2IpOworICAgIGluZGV4Q29uZiA9IG5ldyBJbmRleENvbmZpZ3VyYXRpb24oKTsKKyAgICBTdHJpbmcgY29udGVudCA9IGpvYi5nZXQoImhiYXNlLmluZGV4LmNvbmYiKTsKKyAgICBpZiAoY29udGVudCAhPSBudWxsKSB7CisgICAgICBpbmRleENvbmYuYWRkRnJvbVhNTChjb250ZW50KTsKKyAgICB9CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoIkluZGV4IGNvbmY6ICIgKyBpbmRleENvbmYpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIuY2xvc2UoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlZHVjZShJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSwgSXRlcmF0b3I8Um93UmVzdWx0PiB2YWx1ZXMsCisgICAgICBPdXRwdXRDb2xsZWN0b3I8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgTHVjZW5lRG9jdW1lbnRXcmFwcGVyPiBvdXRwdXQsCisgICAgICBSZXBvcnRlciByZXBvcnRlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIXZhbHVlcy5oYXNOZXh0KCkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBEb2N1bWVudCBkb2MgPSBuZXcgRG9jdW1lbnQoKTsKKworICAgIC8vIGluZGV4IGFuZCBzdG9yZSByb3cga2V5LCByb3cga2V5IGFscmVhZHkgVVRGLTggZW5jb2RlZAorICAgIEZpZWxkIGtleUZpZWxkID0gbmV3IEZpZWxkKGluZGV4Q29uZi5nZXRSb3drZXlOYW1lKCksCisgICAgICBCeXRlcy50b1N0cmluZyhrZXkuZ2V0KCksIGtleS5nZXRPZmZzZXQoKSwga2V5LmdldExlbmd0aCgpKSwKKyAgICAgIEZpZWxkLlN0b3JlLllFUywgRmllbGQuSW5kZXguVU5fVE9LRU5JWkVEKTsKKyAgICBrZXlGaWVsZC5zZXRPbWl0Tm9ybXModHJ1ZSk7CisgICAgZG9jLmFkZChrZXlGaWVsZCk7CisKKyAgICB3aGlsZSAodmFsdWVzLmhhc05leHQoKSkgeworICAgICAgUm93UmVzdWx0IHZhbHVlID0gdmFsdWVzLm5leHQoKTsKKworICAgICAgLy8gZWFjaCBjb2x1bW4gKG5hbWUtdmFsdWUgcGFpcikgaXMgYSBmaWVsZCAobmFtZS12YWx1ZSBwYWlyKQorICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4gZW50cnkgOiB2YWx1ZS5lbnRyeVNldCgpKSB7CisgICAgICAgIC8vIG5hbWUgaXMgYWxyZWFkeSBVVEYtOCBlbmNvZGVkCisgICAgICAgIFN0cmluZyBjb2x1bW4gPSBCeXRlcy50b1N0cmluZyhlbnRyeS5nZXRLZXkoKSk7CisgICAgICAgIGJ5dGVbXSBjb2x1bW5WYWx1ZSA9IGVudHJ5LmdldFZhbHVlKCkuZ2V0VmFsdWUoKTsKKyAgICAgICAgRmllbGQuU3RvcmUgc3RvcmUgPSBpbmRleENvbmYuaXNTdG9yZShjb2x1bW4pPworICAgICAgICAgIEZpZWxkLlN0b3JlLllFUzogRmllbGQuU3RvcmUuTk87CisgICAgICAgIEZpZWxkLkluZGV4IGluZGV4ID0gaW5kZXhDb25mLmlzSW5kZXgoY29sdW1uKT8KKyAgICAgICAgICAoaW5kZXhDb25mLmlzVG9rZW5pemUoY29sdW1uKT8KKyAgICAgICAgICAgIEZpZWxkLkluZGV4LlRPS0VOSVpFRDogRmllbGQuSW5kZXguVU5fVE9LRU5JWkVEKToKKyAgICAgICAgICAgIEZpZWxkLkluZGV4Lk5POworCisgICAgICAgIC8vIFVURi04IGVuY29kZSB2YWx1ZQorICAgICAgICBGaWVsZCBmaWVsZCA9IG5ldyBGaWVsZChjb2x1bW4sIEJ5dGVzLnRvU3RyaW5nKGNvbHVtblZhbHVlKSwgCisgICAgICAgICAgc3RvcmUsIGluZGV4KTsKKyAgICAgICAgZmllbGQuc2V0Qm9vc3QoaW5kZXhDb25mLmdldEJvb3N0KGNvbHVtbikpOworICAgICAgICBmaWVsZC5zZXRPbWl0Tm9ybXMoaW5kZXhDb25mLmlzT21pdE5vcm1zKGNvbHVtbikpOworCisgICAgICAgIGRvYy5hZGQoZmllbGQpOworICAgICAgfQorICAgIH0KKyAgICBvdXRwdXQuY29sbGVjdChrZXksIG5ldyBMdWNlbmVEb2N1bWVudFdyYXBwZXIoZG9jKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9MdWNlbmVEb2N1bWVudFdyYXBwZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9MdWNlbmVEb2N1bWVudFdyYXBwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wN2ZlMzBjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL0x1Y2VuZURvY3VtZW50V3JhcHBlci5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5sdWNlbmUuZG9jdW1lbnQuRG9jdW1lbnQ7CisKKy8qKgorICogQSB1dGlsaXR5IGNsYXNzIHVzZWQgdG8gcGFzcyBhIGx1Y2VuZSBkb2N1bWVudCBmcm9tIHJlZHVjZSB0byBPdXRwdXRGb3JtYXQuCisgKiBJdCBkb2Vzbid0IHJlYWxseSBzZXJpYWxpemUvZGVzZXJpYWxpemUgYSBsdWNlbmUgZG9jdW1lbnQuCisgKi8KK2NsYXNzIEx1Y2VuZURvY3VtZW50V3JhcHBlciBpbXBsZW1lbnRzIFdyaXRhYmxlIHsKKyAgcHJpdmF0ZSBEb2N1bWVudCBkb2M7CisKKyAgLyoqCisgICAqIEBwYXJhbSBkb2MKKyAgICovCisgIHB1YmxpYyBMdWNlbmVEb2N1bWVudFdyYXBwZXIoRG9jdW1lbnQgZG9jKSB7CisgICAgdGhpcy5kb2MgPSBkb2M7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgZG9jdW1lbnQKKyAgICovCisgIHB1YmxpYyBEb2N1bWVudCBnZXQoKSB7CisgICAgcmV0dXJuIGRvYzsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWRGaWVsZHMoRGF0YUlucHV0IGluKSB7CisgICAgLy8gaW50ZW50aW9uYWxseSBsZWZ0IGJsYW5rCisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgeworICAgIC8vIGludGVudGlvbmFsbHkgbGVmdCBibGFuaworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvUm93Q291bnRlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Jvd0NvdW50ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGRmYWQ0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Jvd0NvdW50ZXIuamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJlZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlT3V0cHV0Rm9ybWF0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDbGllbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk91dHB1dENvbGxlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVwb3J0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLmxpYi5JZGVudGl0eVJlZHVjZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Ub29sOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVG9vbFJ1bm5lcjsKKworLyoqCisgKiBBIGpvYiB3aXRoIGEgbWFwIHRvIGNvdW50IHJvd3MuCisgKiBNYXAgb3V0cHV0cyB0YWJsZSByb3dzIElGIHRoZSBpbnB1dCByb3cgaGFzIGNvbHVtbnMgdGhhdCBoYXZlIGNvbnRlbnQuICAKKyAqIFVzZXMgYW4ge0BsaW5rIElkZW50aXR5UmVkdWNlcn0KKyAqLworcHVibGljIGNsYXNzIFJvd0NvdW50ZXIgZXh0ZW5kcyBDb25maWd1cmVkIGltcGxlbWVudHMgVG9vbCB7CisgIC8vIE5hbWUgb2YgdGhpcyAncHJvZ3JhbScKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gInJvd2NvdW50ZXIiOworCisgIC8qKgorICAgKiBNYXBwZXIgdGhhdCBydW5zIHRoZSBjb3VudC4KKyAgICovCisgIHN0YXRpYyBjbGFzcyBSb3dDb3VudGVyTWFwcGVyCisgIGltcGxlbWVudHMgVGFibGVNYXA8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgUm93UmVzdWx0PiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZW51bSBDb3VudGVycyB7Uk9XU30KKworICAgIHB1YmxpYyB2b2lkIG1hcChJbW11dGFibGVCeXRlc1dyaXRhYmxlIHJvdywgUm93UmVzdWx0IHZhbHVlLAorICAgICAgICBPdXRwdXRDb2xsZWN0b3I8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgUm93UmVzdWx0PiBvdXRwdXQsCisgICAgICAgIFJlcG9ydGVyIHJlcG9ydGVyKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBib29sZWFuIGNvbnRlbnQgPSBmYWxzZTsKKyAgICAgIGZvciAoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGU6IHZhbHVlLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgQ2VsbCBjZWxsID0gZS5nZXRWYWx1ZSgpOworICAgICAgICBpZiAoY2VsbCAhPSBudWxsICYmIGNlbGwuZ2V0VmFsdWUoKS5sZW5ndGggPiAwKSB7CisgICAgICAgICAgY29udGVudCA9IHRydWU7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlmICghY29udGVudCkgeworICAgICAgICAvLyBEb24ndCBjb3VudCByb3dzIHRoYXQgYXJlIGFsbCBlbXB0eSB2YWx1ZXMuCisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIC8vIEdpdmUgb3V0IHNhbWUgdmFsdWUgZXZlcnkgdGltZS4gIFdlJ3JlIG9ubHkgaW50ZXJlc3RlZCBpbiB0aGUgcm93L2tleQorICAgICAgcmVwb3J0ZXIuaW5jckNvdW50ZXIoQ291bnRlcnMuUk9XUywgMSk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY29uZmlndXJlKEpvYkNvbmYgamMpIHsKKyAgICAgIC8vIE5vdGhpbmcgdG8gZG8uCisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gTm90aGluZyB0byBkby4KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHJldHVybiB0aGUgSm9iQ29uZgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSm9iQ29uZiBjcmVhdGVTdWJtaXR0YWJsZUpvYihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEpvYkNvbmYgYyA9IG5ldyBKb2JDb25mKGdldENvbmYoKSwgZ2V0Q2xhc3MoKSk7CisgICAgYy5zZXRKb2JOYW1lKE5BTUUpOworICAgIC8vIENvbHVtbnMgYXJlIHNwYWNlIGRlbGltaXRlZAorICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIGZpbmFsIGludCBjb2x1bW5vZmZzZXQgPSAyOworICAgIGZvciAoaW50IGkgPSBjb2x1bW5vZmZzZXQ7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoaSA+IGNvbHVtbm9mZnNldCkgeworICAgICAgICBzYi5hcHBlbmQoIiAiKTsKKyAgICAgIH0KKyAgICAgIHNiLmFwcGVuZChhcmdzW2ldKTsKKyAgICB9CisgICAgLy8gU2Vjb25kIGFyZ3VtZW50IGlzIHRoZSB0YWJsZSBuYW1lLgorICAgIFRhYmxlTWFwUmVkdWNlVXRpbC5pbml0VGFibGVNYXBKb2IoYXJnc1sxXSwgc2IudG9TdHJpbmcoKSwKKyAgICAgIFJvd0NvdW50ZXJNYXBwZXIuY2xhc3MsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MsIFJvd1Jlc3VsdC5jbGFzcywgYyk7CisgICAgYy5zZXROdW1SZWR1Y2VUYXNrcygwKTsKKyAgICAvLyBGaXJzdCBhcmcgaXMgdGhlIG91dHB1dCBkaXJlY3RvcnkuCisgICAgRmlsZU91dHB1dEZvcm1hdC5zZXRPdXRwdXRQYXRoKGMsIG5ldyBQYXRoKGFyZ3NbMF0pKTsKKyAgICByZXR1cm4gYzsKKyAgfQorICAKKyAgc3RhdGljIGludCBwcmludFVzYWdlKCkgeworICAgIFN5c3RlbS5vdXQucHJpbnRsbihOQU1FICsKKyAgICAgICIgPG91dHB1dGRpcj4gPHRhYmxlbmFtZT4gPGNvbHVtbjE+IFs8Y29sdW1uMj4uLi5dIik7CisgICAgcmV0dXJuIC0xOworICB9CisgIAorICBwdWJsaWMgaW50IHJ1bihmaW5hbCBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIGF0IGxlYXN0IDMgcGFyYW1ldGVycworICAgIGlmIChhcmdzLmxlbmd0aCA8IDMpIHsKKyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRVJST1I6IFdyb25nIG51bWJlciBvZiBwYXJhbWV0ZXJzOiAiICsgYXJncy5sZW5ndGgpOworICAgICAgcmV0dXJuIHByaW50VXNhZ2UoKTsKKyAgICB9CisgICAgSm9iQ2xpZW50LnJ1bkpvYihjcmVhdGVTdWJtaXR0YWJsZUpvYihhcmdzKSk7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIGludCBlcnJDb2RlID0gVG9vbFJ1bm5lci5ydW4oYywgbmV3IFJvd0NvdW50ZXIoKSwgYXJncyk7CisgICAgU3lzdGVtLmV4aXQoZXJyQ29kZSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvUm93Q291bnRlcl9Db3VudGVycy5wcm9wZXJ0aWVzIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Jvd0NvdW50ZXJfQ291bnRlcnMucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZjRlMmM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Jvd0NvdW50ZXJfQ291bnRlcnMucHJvcGVydGllcwpAQCAtMCwwICsxLDYgQEAKKworIyBSZXNvdXJjZUJ1bmRsZSBwcm9wZXJ0aWVzIGZpbGUgZm9yIFJvd0NvdW50ZXIgTVIgam9iCisKK0NvdW50ZXJHcm91cE5hbWU9ICAgICAgICAgUm93Q291bnRlcgorCitST1dTLm5hbWU9ICAgICAgICAgICAgICAgIFJvd3MKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZUlucHV0Rm9ybWF0LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVJbnB1dEZvcm1hdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4ZDU2YjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVJbnB1dEZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlSW5wdXRGb3JtYXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmZpZ3VyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlN0cmluZ1V0aWxzOworCisvKioKKyAqIENvbnZlcnQgSEJhc2UgdGFidWxhciBkYXRhIGludG8gYSBmb3JtYXQgdGhhdCBpcyBjb25zdW1hYmxlIGJ5IE1hcC9SZWR1Y2UuCisgKi8KK3B1YmxpYyBjbGFzcyBUYWJsZUlucHV0Rm9ybWF0IGV4dGVuZHMgVGFibGVJbnB1dEZvcm1hdEJhc2UgaW1wbGVtZW50cworICAgIEpvYkNvbmZpZ3VyYWJsZSB7CisgIHByaXZhdGUgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRhYmxlSW5wdXRGb3JtYXQuY2xhc3MpOworCisgIC8qKgorICAgKiBzcGFjZSBkZWxpbWl0ZWQgbGlzdCBvZiBjb2x1bW5zCisgICAqCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhBYnN0cmFjdFNjYW5uZXIgZm9yIGNvbHVtbiBuYW1lCisgICAqICAgICAgd2lsZGNhcmRzCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT0xVTU5fTElTVCA9ICJoYmFzZS5tYXByZWQudGFibGVjb2x1bW5zIjsKKworICBwdWJsaWMgdm9pZCBjb25maWd1cmUoSm9iQ29uZiBqb2IpIHsKKyAgICBQYXRoW10gdGFibGVOYW1lcyA9IEZpbGVJbnB1dEZvcm1hdC5nZXRJbnB1dFBhdGhzKGpvYik7CisgICAgU3RyaW5nIGNvbEFyZyA9IGpvYi5nZXQoQ09MVU1OX0xJU1QpOworICAgIFN0cmluZ1tdIGNvbE5hbWVzID0gY29sQXJnLnNwbGl0KCIgIik7CisgICAgYnl0ZSBbXVtdIG1fY29scyA9IG5ldyBieXRlW2NvbE5hbWVzLmxlbmd0aF1bXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1fY29scy5sZW5ndGg7IGkrKykgeworICAgICAgbV9jb2xzW2ldID0gQnl0ZXMudG9CeXRlcyhjb2xOYW1lc1tpXSk7CisgICAgfQorICAgIHNldElucHV0Q29sdW1ucyhtX2NvbHMpOworICAgIHRyeSB7CisgICAgICBzZXRIVGFibGUobmV3IEhUYWJsZShuZXcgSEJhc2VDb25maWd1cmF0aW9uKGpvYiksIHRhYmxlTmFtZXNbMF0uZ2V0TmFtZSgpKSk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcihTdHJpbmdVdGlscy5zdHJpbmdpZnlFeGNlcHRpb24oZSkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlSW5wdXQoSm9iQ29uZiBqb2IpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gZXhwZWN0aW5nIGV4YWN0bHkgb25lIHBhdGgKKyAgICBQYXRoIFtdIHRhYmxlTmFtZXMgPSBGaWxlSW5wdXRGb3JtYXQuZ2V0SW5wdXRQYXRocyhqb2IpOworICAgIGlmICh0YWJsZU5hbWVzID09IG51bGwgfHwgdGFibGVOYW1lcy5sZW5ndGggPiAxKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImV4cGVjdGluZyBvbmUgdGFibGUgbmFtZSIpOworICAgIH0KKworICAgIC8vIGNvbm5lY3RlZCB0byB0YWJsZT8KKyAgICBpZiAoZ2V0SFRhYmxlKCkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjb3VsZCBub3QgY29ubmVjdCB0byB0YWJsZSAnIiArCisgICAgICAgIHRhYmxlTmFtZXNbMF0uZ2V0TmFtZSgpICsgIiciKTsKKyAgICB9CisKKyAgICAvLyBleHBlY3RpbmcgYXQgbGVhc3Qgb25lIGNvbHVtbgorICAgIFN0cmluZyBjb2xBcmcgPSBqb2IuZ2V0KENPTFVNTl9MSVNUKTsKKyAgICBpZiAoY29sQXJnID09IG51bGwgfHwgY29sQXJnLmxlbmd0aCgpID09IDApIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiZXhwZWN0aW5nIGF0IGxlYXN0IG9uZSBjb2x1bW4iKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZUlucHV0Rm9ybWF0QmFzZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlSW5wdXRGb3JtYXRCYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmE4MmI3YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZUlucHV0Rm9ybWF0QmFzZS5qYXZhCkBAIC0wLDAgKzEsMzQxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Vbmtub3duU2Nhbm5lckV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlclNldDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuU3RvcFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuV2hpbGVNYXRjaFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5JbW11dGFibGVCeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSW5wdXRGb3JtYXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLklucHV0U3BsaXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlJlY29yZFJlYWRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVwb3J0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5TdHJpbmdVdGlsczsKKworLyoqCisgKiBBIEJhc2UgZm9yIHtAbGluayBUYWJsZUlucHV0Rm9ybWF0fXMuIFJlY2VpdmVzIGEge0BsaW5rIEhUYWJsZX0sIGEKKyAqIGJ5dGVbXSBvZiBpbnB1dCBjb2x1bW5zIGFuZCBvcHRpb25hbGx5IGEge0BsaW5rIFJvd0ZpbHRlckludGVyZmFjZX0uCisgKiBTdWJjbGFzc2VzIG1heSB1c2Ugb3RoZXIgVGFibGVSZWNvcmRSZWFkZXIgaW1wbGVtZW50YXRpb25zLgorICogPHA+CisgKiBBbiBleGFtcGxlIG9mIGEgc3ViY2xhc3M6CisgKiA8cHJlPgorICogICBjbGFzcyBFeGFtcGxlVElGIGV4dGVuZHMgVGFibGVJbnB1dEZvcm1hdEJhc2UgaW1wbGVtZW50cyBKb2JDb25maWd1cmFibGUgeworICoKKyAqICAgICBwdWJsaWMgdm9pZCBjb25maWd1cmUoSm9iQ29uZiBqb2IpIHsKKyAqICAgICAgIEhUYWJsZSBleGFtcGxlVGFibGUgPSBuZXcgSFRhYmxlKG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oam9iKSwKKyAqICAgICAgICAgQnl0ZXMudG9CeXRlcygiZXhhbXBsZVRhYmxlIikpOworICogICAgICAgLy8gbWFuZGF0b3J5CisgKiAgICAgICBzZXRIVGFibGUoZXhhbXBsZVRhYmxlKTsKKyAqICAgICAgIFRleHRbXSBpbnB1dENvbHVtbnMgPSBuZXcgYnl0ZSBbXVtdIHsgQnl0ZXMudG9CeXRlcygiY29sdW1uQSIpLAorICogICAgICAgICBCeXRlcy50b0J5dGVzKCJjb2x1bW5CIikgfTsKKyAqICAgICAgIC8vIG1hbmRhdG9yeQorICogICAgICAgc2V0SW5wdXRDb2x1bW5zKGlucHV0Q29sdW1ucyk7CisgKiAgICAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgZXhhbXBsZUZpbHRlciA9IG5ldyBSZWdFeHBSb3dGaWx0ZXIoImtleVByZWZpeC4qIik7CisgKiAgICAgICAvLyBvcHRpb25hbAorICogICAgICAgc2V0Um93RmlsdGVyKGV4YW1wbGVGaWx0ZXIpOworICogICAgIH0KKyAqCisgKiAgICAgcHVibGljIHZvaWQgdmFsaWRhdGVJbnB1dChKb2JDb25mIGpvYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAqICAgICB9CisgKiAgfQorICogPC9wcmU+CisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBUYWJsZUlucHV0Rm9ybWF0QmFzZQoraW1wbGVtZW50cyBJbnB1dEZvcm1hdDxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBSb3dSZXN1bHQ+IHsKKyAgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRhYmxlSW5wdXRGb3JtYXRCYXNlLmNsYXNzKTsKKyAgcHJpdmF0ZSBieXRlIFtdW10gaW5wdXRDb2x1bW5zOworICBwcml2YXRlIEhUYWJsZSB0YWJsZTsKKyAgcHJpdmF0ZSBUYWJsZVJlY29yZFJlYWRlciB0YWJsZVJlY29yZFJlYWRlcjsKKyAgcHJpdmF0ZSBSb3dGaWx0ZXJJbnRlcmZhY2Ugcm93RmlsdGVyOworCisgIC8qKgorICAgKiBJdGVyYXRlIG92ZXIgYW4gSEJhc2UgdGFibGUgZGF0YSwgcmV0dXJuIChUZXh0LCBSb3dSZXN1bHQpIHBhaXJzCisgICAqLworICBwcm90ZWN0ZWQgY2xhc3MgVGFibGVSZWNvcmRSZWFkZXIKKyAgaW1wbGVtZW50cyBSZWNvcmRSZWFkZXI8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgUm93UmVzdWx0PiB7CisgICAgcHJpdmF0ZSBieXRlIFtdIHN0YXJ0Um93OworICAgIHByaXZhdGUgYnl0ZSBbXSBlbmRSb3c7CisgICAgcHJpdmF0ZSBieXRlIFtdIGxhc3RSb3c7CisgICAgcHJpdmF0ZSBSb3dGaWx0ZXJJbnRlcmZhY2UgdHJyUm93RmlsdGVyOworICAgIHByaXZhdGUgU2Nhbm5lciBzY2FubmVyOworICAgIHByaXZhdGUgSFRhYmxlIGh0YWJsZTsKKyAgICBwcml2YXRlIGJ5dGUgW11bXSB0cnJJbnB1dENvbHVtbnM7CisKKyAgICAvKioKKyAgICAgKiBSZXN0YXJ0IGZyb20gc3Vydml2YWJsZSBleGNlcHRpb25zIGJ5IGNyZWF0aW5nIGEgbmV3IHNjYW5uZXIuCisgICAgICoKKyAgICAgKiBAcGFyYW0gZmlyc3RSb3cKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzdGFydChieXRlW10gZmlyc3RSb3cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoKGVuZFJvdyAhPSBudWxsKSAmJiAoZW5kUm93Lmxlbmd0aCA+IDApKSB7CisgICAgICAgIGlmICh0cnJSb3dGaWx0ZXIgIT0gbnVsbCkgeworICAgICAgICAgIGZpbmFsIFNldDxSb3dGaWx0ZXJJbnRlcmZhY2U+IHJvd0ZpbHRlcnNTZXQgPQorICAgICAgICAgICAgbmV3IEhhc2hTZXQ8Um93RmlsdGVySW50ZXJmYWNlPigpOworICAgICAgICAgIHJvd0ZpbHRlcnNTZXQuYWRkKG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyKG5ldyBTdG9wUm93RmlsdGVyKGVuZFJvdykpKTsKKyAgICAgICAgICByb3dGaWx0ZXJzU2V0LmFkZCh0cnJSb3dGaWx0ZXIpOworICAgICAgICAgIHRoaXMuc2Nhbm5lciA9IHRoaXMuaHRhYmxlLmdldFNjYW5uZXIodHJySW5wdXRDb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgICAgIG5ldyBSb3dGaWx0ZXJTZXQoUm93RmlsdGVyU2V0Lk9wZXJhdG9yLk1VU1RfUEFTU19BTEwsCisgICAgICAgICAgICAgIHJvd0ZpbHRlcnNTZXQpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aGlzLnNjYW5uZXIgPQorICAgICAgICAgICAgdGhpcy5odGFibGUuZ2V0U2Nhbm5lcih0cnJJbnB1dENvbHVtbnMsIGZpcnN0Um93LCBlbmRSb3cpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICB0aGlzLnNjYW5uZXIgPQorICAgICAgICAgIHRoaXMuaHRhYmxlLmdldFNjYW5uZXIodHJySW5wdXRDb2x1bW5zLCBmaXJzdFJvdywgdHJyUm93RmlsdGVyKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBCdWlsZCB0aGUgc2Nhbm5lci4gTm90IGRvbmUgaW4gY29uc3RydWN0b3IgdG8gYWxsb3cgZm9yIGV4dGVuc2lvbi4KKyAgICAgKgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBpbml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJlc3RhcnQoc3RhcnRSb3cpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBodGFibGUgdGhlIHtAbGluayBIVGFibGV9IHRvIHNjYW4uCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0SFRhYmxlKEhUYWJsZSBodGFibGUpIHsKKyAgICAgIHRoaXMuaHRhYmxlID0gaHRhYmxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSBpbnB1dENvbHVtbnMgdGhlIGNvbHVtbnMgdG8gYmUgcGxhY2VkIGluIHtAbGluayBSb3dSZXN1bHR9LgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldElucHV0Q29sdW1ucyhmaW5hbCBieXRlIFtdW10gaW5wdXRDb2x1bW5zKSB7CisgICAgICB0aGlzLnRycklucHV0Q29sdW1ucyA9IGlucHV0Q29sdW1uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cgdGhlIGZpcnN0IHJvdyBpbiB0aGUgc3BsaXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFydFJvdyhmaW5hbCBieXRlIFtdIHN0YXJ0Um93KSB7CisgICAgICB0aGlzLnN0YXJ0Um93ID0gc3RhcnRSb3c7CisgICAgfQorCisgICAgLyoqCisgICAgICoKKyAgICAgKiBAcGFyYW0gZW5kUm93IHRoZSBsYXN0IHJvdyBpbiB0aGUgc3BsaXQKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXRFbmRSb3coZmluYWwgYnl0ZSBbXSBlbmRSb3cpIHsKKyAgICAgIHRoaXMuZW5kUm93ID0gZW5kUm93OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSByb3dGaWx0ZXIgdGhlIHtAbGluayBSb3dGaWx0ZXJJbnRlcmZhY2V9IHRvIGJlIHVzZWQuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Um93RmlsdGVyKFJvd0ZpbHRlckludGVyZmFjZSByb3dGaWx0ZXIpIHsKKyAgICAgIHRoaXMudHJyUm93RmlsdGVyID0gcm93RmlsdGVyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgdGhpcy5zY2FubmVyLmNsb3NlKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHJldHVybiBJbW11dGFibGVCeXRlc1dyaXRhYmxlCisgICAgICoKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZWNvcmRSZWFkZXIjY3JlYXRlS2V5KCkKKyAgICAgKi8KKyAgICBwdWJsaWMgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBjcmVhdGVLZXkoKSB7CisgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIFJvd1Jlc3VsdAorICAgICAqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVjb3JkUmVhZGVyI2NyZWF0ZVZhbHVlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgUm93UmVzdWx0IGNyZWF0ZVZhbHVlKCkgeworICAgICAgcmV0dXJuIG5ldyBSb3dSZXN1bHQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRQb3MoKSB7CisgICAgICAvLyBUaGlzIHNob3VsZCBiZSB0aGUgb3JkaW5hbCB0dXBsZSBpbiB0aGUgcmFuZ2U7CisgICAgICAvLyBub3QgY2xlYXIgaG93IHRvIGNhbGN1bGF0ZS4uLgorICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIGZsb2F0IGdldFByb2dyZXNzKCkgeworICAgICAgLy8gRGVwZW5kcyBvbiB0aGUgdG90YWwgbnVtYmVyIG9mIHR1cGxlcyBhbmQgZ2V0UG9zCisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0ga2V5IEhTdG9yZUtleSBhcyBpbnB1dCBrZXkuCisgICAgICogQHBhcmFtIHZhbHVlIE1hcFdyaXRhYmxlIGFzIGlucHV0IHZhbHVlCisgICAgICogQHJldHVybiB0cnVlIGlmIHRoZXJlIHdhcyBtb3JlIGRhdGEKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gbmV4dChJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSwgUm93UmVzdWx0IHZhbHVlKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBSb3dSZXN1bHQgcmVzdWx0OworICAgICAgdHJ5IHsKKyAgICAgICAgcmVzdWx0ID0gdGhpcy5zY2FubmVyLm5leHQoKTsKKyAgICAgIH0gY2F0Y2ggKFVua25vd25TY2FubmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJyZWNvdmVyZWQgZnJvbSAiICsgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsgIAorICAgICAgICByZXN0YXJ0KGxhc3RSb3cpOworICAgICAgICB0aGlzLnNjYW5uZXIubmV4dCgpOyAgICAvLyBza2lwIHByZXN1bWVkIGFscmVhZHkgbWFwcGVkIHJvdworICAgICAgICByZXN1bHQgPSB0aGlzLnNjYW5uZXIubmV4dCgpOworICAgICAgfQorCisgICAgICBpZiAocmVzdWx0ICE9IG51bGwgJiYgcmVzdWx0LnNpemUoKSA+IDApIHsKKyAgICAgICAga2V5LnNldChyZXN1bHQuZ2V0Um93KCkpOworICAgICAgICBsYXN0Um93ID0ga2V5LmdldCgpOworICAgICAgICBXcml0YWJsZXMuY29weVdyaXRhYmxlKHJlc3VsdCwgdmFsdWUpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQnVpbGRzIGEgVGFibGVSZWNvcmRSZWFkZXIuIElmIG5vIFRhYmxlUmVjb3JkUmVhZGVyIHdhcyBwcm92aWRlZCwgdXNlcworICAgKiB0aGUgZGVmYXVsdC4KKyAgICoKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSW5wdXRGb3JtYXQjZ2V0UmVjb3JkUmVhZGVyKElucHV0U3BsaXQsCisgICAqICAgICAgSm9iQ29uZiwgUmVwb3J0ZXIpCisgICAqLworICBwdWJsaWMgUmVjb3JkUmVhZGVyPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIFJvd1Jlc3VsdD4gZ2V0UmVjb3JkUmVhZGVyKAorICAgICAgSW5wdXRTcGxpdCBzcGxpdCwgSm9iQ29uZiBqb2IsIFJlcG9ydGVyIHJlcG9ydGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFRhYmxlU3BsaXQgdFNwbGl0ID0gKFRhYmxlU3BsaXQpIHNwbGl0OworICAgIFRhYmxlUmVjb3JkUmVhZGVyIHRyciA9IHRoaXMudGFibGVSZWNvcmRSZWFkZXI7CisgICAgLy8gaWYgbm8gdGFibGUgcmVjb3JkIHJlYWRlciB3YXMgcHJvdmlkZWQgdXNlIGRlZmF1bHQKKyAgICBpZiAodHJyID09IG51bGwpIHsKKyAgICAgIHRyciA9IG5ldyBUYWJsZVJlY29yZFJlYWRlcigpOworICAgIH0KKyAgICB0cnIuc2V0U3RhcnRSb3codFNwbGl0LmdldFN0YXJ0Um93KCkpOworICAgIHRyci5zZXRFbmRSb3codFNwbGl0LmdldEVuZFJvdygpKTsKKyAgICB0cnIuc2V0SFRhYmxlKHRoaXMudGFibGUpOworICAgIHRyci5zZXRJbnB1dENvbHVtbnModGhpcy5pbnB1dENvbHVtbnMpOworICAgIHRyci5zZXRSb3dGaWx0ZXIodGhpcy5yb3dGaWx0ZXIpOworICAgIHRyci5pbml0KCk7CisgICAgcmV0dXJuIHRycjsKKyAgfQorCisgIC8qKgorICAgKiBDYWxjdWxhdGVzIHRoZSBzcGxpdHMgdGhhdCB3aWxsIHNlcnZlIGFzIGlucHV0IGZvciB0aGUgbWFwIHRhc2tzLgorICAgKiA8dWw+CisgICAqIFNwbGl0cyBhcmUgY3JlYXRlZCBpbiBudW1iZXIgZXF1YWwgdG8gdGhlIHNtYWxsZXN0IGJldHdlZW4gbnVtU3BsaXRzIGFuZAorICAgKiB0aGUgbnVtYmVyIG9mIHtAbGluayBIUmVnaW9ufXMgaW4gdGhlIHRhYmxlLiBJZiB0aGUgbnVtYmVyIG9mIHNwbGl0cyBpcworICAgKiBzbWFsbGVyIHRoYW4gdGhlIG51bWJlciBvZiB7QGxpbmsgSFJlZ2lvbn1zIHRoZW4gc3BsaXRzIGFyZSBzcGFubmVkIGFjcm9zcworICAgKiBtdWx0aXBsZSB7QGxpbmsgSFJlZ2lvbn1zIGFuZCBhcmUgZ3JvdXBlZCB0aGUgbW9zdCBldmVubHkgcG9zc2libGUuIEluIHRoZQorICAgKiBjYXNlIHNwbGl0cyBhcmUgdW5ldmVuIHRoZSBiaWdnZXIgc3BsaXRzIGFyZSBwbGFjZWQgZmlyc3QgaW4gdGhlCisgICAqIHtAbGluayBJbnB1dFNwbGl0fSBhcnJheS4KKyAgICoKKyAgICogQHBhcmFtIGpvYiB0aGUgbWFwIHRhc2sge0BsaW5rIEpvYkNvbmZ9CisgICAqIEBwYXJhbSBudW1TcGxpdHMgYSBoaW50IHRvIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHNwbGl0cyAobWFwcmVkLm1hcC50YXNrcykuCisgICAqCisgICAqIEByZXR1cm4gdGhlIGlucHV0IHNwbGl0cworICAgKgorICAgKiBAc2VlIG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5JbnB1dEZvcm1hdCNnZXRTcGxpdHMob3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmYsIGludCkKKyAgICovCisgIHB1YmxpYyBJbnB1dFNwbGl0W10gZ2V0U3BsaXRzKEpvYkNvbmYgam9iLCBpbnQgbnVtU3BsaXRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW11bXSBzdGFydEtleXMgPSB0aGlzLnRhYmxlLmdldFN0YXJ0S2V5cygpOworICAgIGlmIChzdGFydEtleXMgPT0gbnVsbCB8fCBzdGFydEtleXMubGVuZ3RoID09IDApIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhwZWN0aW5nIGF0IGxlYXN0IG9uZSByZWdpb24iKTsKKyAgICB9CisgICAgaWYgKHRoaXMudGFibGUgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJObyB0YWJsZSB3YXMgcHJvdmlkZWQiKTsKKyAgICB9CisgICAgaWYgKHRoaXMuaW5wdXRDb2x1bW5zID09IG51bGwgfHwgdGhpcy5pbnB1dENvbHVtbnMubGVuZ3RoID09IDApIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRXhwZWN0aW5nIGF0IGxlYXN0IG9uZSBjb2x1bW4iKTsKKyAgICB9CisgICAgaW50IHJlYWxOdW1TcGxpdHMgPSBudW1TcGxpdHMgPiBzdGFydEtleXMubGVuZ3RoPyBzdGFydEtleXMubGVuZ3RoOgorICAgICAgbnVtU3BsaXRzOworICAgIElucHV0U3BsaXRbXSBzcGxpdHMgPSBuZXcgSW5wdXRTcGxpdFtyZWFsTnVtU3BsaXRzXTsKKyAgICBpbnQgbWlkZGxlID0gc3RhcnRLZXlzLmxlbmd0aCAvIHJlYWxOdW1TcGxpdHM7CisgICAgaW50IHN0YXJ0UG9zID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlYWxOdW1TcGxpdHM7IGkrKykgeworICAgICAgaW50IGxhc3RQb3MgPSBzdGFydFBvcyArIG1pZGRsZTsKKyAgICAgIGxhc3RQb3MgPSBzdGFydEtleXMubGVuZ3RoICUgcmVhbE51bVNwbGl0cyA+IGkgPyBsYXN0UG9zICsgMSA6IGxhc3RQb3M7CisgICAgICBTdHJpbmcgcmVnaW9uTG9jYXRpb24gPSB0YWJsZS5nZXRSZWdpb25Mb2NhdGlvbihzdGFydEtleXNbc3RhcnRQb3NdKS4KKyAgICAgICAgZ2V0U2VydmVyQWRkcmVzcygpLmdldEhvc3RuYW1lKCk7IAorICAgICAgc3BsaXRzW2ldID0gbmV3IFRhYmxlU3BsaXQodGhpcy50YWJsZS5nZXRUYWJsZU5hbWUoKSwKKyAgICAgICAgc3RhcnRLZXlzW3N0YXJ0UG9zXSwgKChpICsgMSkgPCByZWFsTnVtU3BsaXRzKSA/IHN0YXJ0S2V5c1tsYXN0UG9zXToKKyAgICAgICAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywgcmVnaW9uTG9jYXRpb24pOworICAgICAgTE9HLmluZm8oInNwbGl0OiAiICsgaSArICItPiIgKyBzcGxpdHNbaV0pOworICAgICAgc3RhcnRQb3MgPSBsYXN0UG9zOworICAgIH0KKyAgICByZXR1cm4gc3BsaXRzOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBpbnB1dENvbHVtbnMgdG8gYmUgcGFzc2VkIGluIHtAbGluayBSb3dSZXN1bHR9IHRvIHRoZSBtYXAgdGFzay4KKyAgICovCisgIHByb3RlY3RlZCB2b2lkIHNldElucHV0Q29sdW1ucyhieXRlIFtdW10gaW5wdXRDb2x1bW5zKSB7CisgICAgdGhpcy5pbnB1dENvbHVtbnMgPSBpbnB1dENvbHVtbnM7CisgIH0KKworICAvKioKKyAgICogQWxsb3dzIHN1YmNsYXNzZXMgdG8gZ2V0IHRoZSB7QGxpbmsgSFRhYmxlfS4KKyAgICovCisgIHByb3RlY3RlZCBIVGFibGUgZ2V0SFRhYmxlKCkgeworICAgIHJldHVybiB0aGlzLnRhYmxlOworICB9CisKKyAgLyoqCisgICAqIEFsbG93cyBzdWJjbGFzc2VzIHRvIHNldCB0aGUge0BsaW5rIEhUYWJsZX0uCisgICAqCisgICAqIEBwYXJhbSB0YWJsZSB0byBnZXQgdGhlIGRhdGEgZnJvbQorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgc2V0SFRhYmxlKEhUYWJsZSB0YWJsZSkgeworICAgIHRoaXMudGFibGUgPSB0YWJsZTsKKyAgfQorCisgIC8qKgorICAgKiBBbGxvd3Mgc3ViY2xhc3NlcyB0byBzZXQgdGhlIHtAbGluayBUYWJsZVJlY29yZFJlYWRlcn0uCisgICAqCisgICAqIEBwYXJhbSB0YWJsZVJlY29yZFJlYWRlcgorICAgKiAgICAgICAgICAgICAgICB0byBwcm92aWRlIG90aGVyIHtAbGluayBUYWJsZVJlY29yZFJlYWRlcn0gaW1wbGVtZW50YXRpb25zLgorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgc2V0VGFibGVSZWNvcmRSZWFkZXIoVGFibGVSZWNvcmRSZWFkZXIgdGFibGVSZWNvcmRSZWFkZXIpIHsKKyAgICB0aGlzLnRhYmxlUmVjb3JkUmVhZGVyID0gdGFibGVSZWNvcmRSZWFkZXI7CisgIH0KKworICAvKioKKyAgICogQWxsb3dzIHN1YmNsYXNzZXMgdG8gc2V0IHRoZSB7QGxpbmsgUm93RmlsdGVySW50ZXJmYWNlfSB0byBiZSB1c2VkLgorICAgKgorICAgKiBAcGFyYW0gcm93RmlsdGVyCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBzZXRSb3dGaWx0ZXIoUm93RmlsdGVySW50ZXJmYWNlIHJvd0ZpbHRlcikgeworICAgIHRoaXMucm93RmlsdGVyID0gcm93RmlsdGVyOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVNYXAuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZU1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwOTA3MDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVNYXAuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NYXBwZXI7CisKKy8qKgorICogU2NhbiBhbiBIQmFzZSB0YWJsZSB0byBzb3J0IGJ5IGEgc3BlY2lmaWVkIHNvcnQgY29sdW1uLgorICogSWYgdGhlIGNvbHVtbiBkb2VzIG5vdCBleGlzdCwgdGhlIHJlY29yZCBpcyBub3QgcGFzc2VkIHRvIFJlZHVjZS4KKyAqCisgKiBAcGFyYW0gPEs+IFdyaXRhYmxlQ29tcGFyYWJsZSBrZXkgY2xhc3MKKyAqIEBwYXJhbSA8Vj4gV3JpdGFibGUgdmFsdWUgY2xhc3MKKyAqLworcHVibGljIGludGVyZmFjZSBUYWJsZU1hcDxLIGV4dGVuZHMgV3JpdGFibGVDb21wYXJhYmxlPEs+LCBWIGV4dGVuZHMgV3JpdGFibGU+CitleHRlbmRzIE1hcHBlcjxJbW11dGFibGVCeXRlc1dyaXRhYmxlLCBSb3dSZXN1bHQsIEssIFY+IHsKKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlTWFwUmVkdWNlVXRpbC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlTWFwUmVkdWNlVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5MGM2NTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVNYXBSZWR1Y2VVdGlsLmphdmEKQEAgLTAsMCArMSwxNzEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkZpbGVJbnB1dEZvcm1hdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ29uZjsKKworLyoqCisgKiBVdGlsaXR5IGZvciB7QGxpbmsgVGFibGVNYXB9IGFuZCB7QGxpbmsgVGFibGVSZWR1Y2V9CisgKi8KK0BTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorcHVibGljIGNsYXNzIFRhYmxlTWFwUmVkdWNlVXRpbCB7CisgIAorICAvKioKKyAgICogVXNlIHRoaXMgYmVmb3JlIHN1Ym1pdHRpbmcgYSBUYWJsZU1hcCBqb2IuIEl0IHdpbGwKKyAgICogYXBwcm9wcmlhdGVseSBzZXQgdXAgdGhlIEpvYkNvbmYuCisgICAqIAorICAgKiBAcGFyYW0gdGFibGUgIFRoZSB0YWJsZSBuYW1lIHRvIHJlYWQgZnJvbS4KKyAgICogQHBhcmFtIGNvbHVtbnMgIFRoZSBjb2x1bW5zIHRvIHNjYW4uCisgICAqIEBwYXJhbSBtYXBwZXIgIFRoZSBtYXBwZXIgY2xhc3MgdG8gdXNlLgorICAgKiBAcGFyYW0gb3V0cHV0S2V5Q2xhc3MgIFRoZSBjbGFzcyBvZiB0aGUgb3V0cHV0IGtleS4KKyAgICogQHBhcmFtIG91dHB1dFZhbHVlQ2xhc3MgIFRoZSBjbGFzcyBvZiB0aGUgb3V0cHV0IHZhbHVlLgorICAgKiBAcGFyYW0gam9iICBUaGUgY3VycmVudCBqb2IgY29uZmlndXJhdGlvbiB0byBhZGp1c3QuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdFRhYmxlTWFwSm9iKFN0cmluZyB0YWJsZSwgU3RyaW5nIGNvbHVtbnMsCisgICAgQ2xhc3M8PyBleHRlbmRzIFRhYmxlTWFwPiBtYXBwZXIsIAorICAgIENsYXNzPD8gZXh0ZW5kcyBXcml0YWJsZUNvbXBhcmFibGU+IG91dHB1dEtleUNsYXNzLCAKKyAgICBDbGFzczw/IGV4dGVuZHMgV3JpdGFibGU+IG91dHB1dFZhbHVlQ2xhc3MsIEpvYkNvbmYgam9iKSB7CisgICAgICAKKyAgICBqb2Iuc2V0SW5wdXRGb3JtYXQoVGFibGVJbnB1dEZvcm1hdC5jbGFzcyk7CisgICAgam9iLnNldE1hcE91dHB1dFZhbHVlQ2xhc3Mob3V0cHV0VmFsdWVDbGFzcyk7CisgICAgam9iLnNldE1hcE91dHB1dEtleUNsYXNzKG91dHB1dEtleUNsYXNzKTsKKyAgICBqb2Iuc2V0TWFwcGVyQ2xhc3MobWFwcGVyKTsKKyAgICBGaWxlSW5wdXRGb3JtYXQuYWRkSW5wdXRQYXRocyhqb2IsIHRhYmxlKTsKKyAgICBqb2Iuc2V0KFRhYmxlSW5wdXRGb3JtYXQuQ09MVU1OX0xJU1QsIGNvbHVtbnMpOworICB9CisgIAorICAvKioKKyAgICogVXNlIHRoaXMgYmVmb3JlIHN1Ym1pdHRpbmcgYSBUYWJsZVJlZHVjZSBqb2IuIEl0IHdpbGwKKyAgICogYXBwcm9wcmlhdGVseSBzZXQgdXAgdGhlIEpvYkNvbmYuCisgICAqIAorICAgKiBAcGFyYW0gdGFibGUgIFRoZSBvdXRwdXQgdGFibGUuCisgICAqIEBwYXJhbSByZWR1Y2VyICBUaGUgcmVkdWNlciBjbGFzcyB0byB1c2UuCisgICAqIEBwYXJhbSBqb2IgIFRoZSBjdXJyZW50IGpvYiBjb25maWd1cmF0aW9uIHRvIGFkanVzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIGRldGVybWluaW5nIHRoZSByZWdpb24gY291bnQgZmFpbHMuIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGluaXRUYWJsZVJlZHVjZUpvYihTdHJpbmcgdGFibGUsCisgICAgQ2xhc3M8PyBleHRlbmRzIFRhYmxlUmVkdWNlPiByZWR1Y2VyLCBKb2JDb25mIGpvYikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbml0VGFibGVSZWR1Y2VKb2IodGFibGUsIHJlZHVjZXIsIGpvYiwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogVXNlIHRoaXMgYmVmb3JlIHN1Ym1pdHRpbmcgYSBUYWJsZVJlZHVjZSBqb2IuIEl0IHdpbGwKKyAgICogYXBwcm9wcmlhdGVseSBzZXQgdXAgdGhlIEpvYkNvbmYuCisgICAqIAorICAgKiBAcGFyYW0gdGFibGUgIFRoZSBvdXRwdXQgdGFibGUuCisgICAqIEBwYXJhbSByZWR1Y2VyICBUaGUgcmVkdWNlciBjbGFzcyB0byB1c2UuCisgICAqIEBwYXJhbSBqb2IgIFRoZSBjdXJyZW50IGpvYiBjb25maWd1cmF0aW9uIHRvIGFkanVzdC4KKyAgICogQHBhcmFtIHBhcnRpdGlvbmVyICBQYXJ0aXRpb25lciB0byB1c2UuIFBhc3MgPGNvZGU+bnVsbDwvY29kZT4gdG8gdXNlIAorICAgKiBkZWZhdWx0IHBhcnRpdGlvbmVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gZGV0ZXJtaW5pbmcgdGhlIHJlZ2lvbiBjb3VudCBmYWlscy4gCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgaW5pdFRhYmxlUmVkdWNlSm9iKFN0cmluZyB0YWJsZSwKKyAgICBDbGFzczw/IGV4dGVuZHMgVGFibGVSZWR1Y2U+IHJlZHVjZXIsIEpvYkNvbmYgam9iLCBDbGFzcyBwYXJ0aXRpb25lcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBqb2Iuc2V0T3V0cHV0Rm9ybWF0KFRhYmxlT3V0cHV0Rm9ybWF0LmNsYXNzKTsKKyAgICBqb2Iuc2V0UmVkdWNlckNsYXNzKHJlZHVjZXIpOworICAgIGpvYi5zZXQoVGFibGVPdXRwdXRGb3JtYXQuT1VUUFVUX1RBQkxFLCB0YWJsZSk7CisgICAgam9iLnNldE91dHB1dEtleUNsYXNzKEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MpOworICAgIGpvYi5zZXRPdXRwdXRWYWx1ZUNsYXNzKEJhdGNoVXBkYXRlLmNsYXNzKTsKKyAgICBpZiAocGFydGl0aW9uZXIgPT0gSFJlZ2lvblBhcnRpdGlvbmVyLmNsYXNzKSB7CisgICAgICBqb2Iuc2V0UGFydGl0aW9uZXJDbGFzcyhIUmVnaW9uUGFydGl0aW9uZXIuY2xhc3MpOworICAgICAgSFRhYmxlIG91dHB1dFRhYmxlID0gbmV3IEhUYWJsZShuZXcgSEJhc2VDb25maWd1cmF0aW9uKGpvYiksIHRhYmxlKTsKKyAgICAgIGludCByZWdpb25zID0gb3V0cHV0VGFibGUuZ2V0UmVnaW9uc0luZm8oKS5zaXplKCk7CisgICAgICBpZiAoam9iLmdldE51bVJlZHVjZVRhc2tzKCkgPiByZWdpb25zKSB7CisgICAgICAgIGpvYi5zZXROdW1SZWR1Y2VUYXNrcyhvdXRwdXRUYWJsZS5nZXRSZWdpb25zSW5mbygpLnNpemUoKSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChwYXJ0aXRpb25lciAhPSBudWxsKSB7CisgICAgICBqb2Iuc2V0UGFydGl0aW9uZXJDbGFzcyhwYXJ0aXRpb25lcik7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogRW5zdXJlcyB0aGF0IHRoZSBnaXZlbiBudW1iZXIgb2YgcmVkdWNlIHRhc2tzIGZvciB0aGUgZ2l2ZW4gam9iIAorICAgKiBjb25maWd1cmF0aW9uIGRvZXMgbm90IGV4Y2VlZCB0aGUgbnVtYmVyIG9mIHJlZ2lvbnMgZm9yIHRoZSBnaXZlbiB0YWJsZS4gCisgICAqIAorICAgKiBAcGFyYW0gdGFibGUgIFRoZSB0YWJsZSB0byBnZXQgdGhlIHJlZ2lvbiBjb3VudCBmb3IuCisgICAqIEBwYXJhbSBqb2IgIFRoZSBjdXJyZW50IGpvYiBjb25maWd1cmF0aW9uIHRvIGFkanVzdC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBXaGVuIHJldHJpZXZpbmcgdGhlIHRhYmxlIGRldGFpbHMgZmFpbHMuCisgICAqLworICBwdWJsaWMgdm9pZCBsaW1pdE51bVJlZHVjZVRhc2tzKFN0cmluZyB0YWJsZSwgSm9iQ29uZiBqb2IpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geyAKKyAgICBIVGFibGUgb3V0cHV0VGFibGUgPSBuZXcgSFRhYmxlKG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oam9iKSwgdGFibGUpOworICAgIGludCByZWdpb25zID0gb3V0cHV0VGFibGUuZ2V0UmVnaW9uc0luZm8oKS5zaXplKCk7CisgICAgaWYgKGpvYi5nZXROdW1SZWR1Y2VUYXNrcygpID4gcmVnaW9ucykKKyAgICAgIGpvYi5zZXROdW1SZWR1Y2VUYXNrcyhyZWdpb25zKTsKKyAgfQorCisgIC8qKgorICAgKiBFbnN1cmVzIHRoYXQgdGhlIGdpdmVuIG51bWJlciBvZiBtYXAgdGFza3MgZm9yIHRoZSBnaXZlbiBqb2IgCisgICAqIGNvbmZpZ3VyYXRpb24gZG9lcyBub3QgZXhjZWVkIHRoZSBudW1iZXIgb2YgcmVnaW9ucyBmb3IgdGhlIGdpdmVuIHRhYmxlLiAKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZSAgVGhlIHRhYmxlIHRvIGdldCB0aGUgcmVnaW9uIGNvdW50IGZvci4KKyAgICogQHBhcmFtIGpvYiAgVGhlIGN1cnJlbnQgam9iIGNvbmZpZ3VyYXRpb24gdG8gYWRqdXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gcmV0cmlldmluZyB0aGUgdGFibGUgZGV0YWlscyBmYWlscy4KKyAgICovCisgIHB1YmxpYyB2b2lkIGxpbWl0TnVtTWFwVGFza3MoU3RyaW5nIHRhYmxlLCBKb2JDb25mIGpvYikgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgIEhUYWJsZSBvdXRwdXRUYWJsZSA9IG5ldyBIVGFibGUobmV3IEhCYXNlQ29uZmlndXJhdGlvbihqb2IpLCB0YWJsZSk7CisgICAgaW50IHJlZ2lvbnMgPSBvdXRwdXRUYWJsZS5nZXRSZWdpb25zSW5mbygpLnNpemUoKTsKKyAgICBpZiAoam9iLmdldE51bU1hcFRhc2tzKCkgPiByZWdpb25zKQorICAgICAgam9iLnNldE51bU1hcFRhc2tzKHJlZ2lvbnMpOworICB9CisKKyAgLyoqCisgICAqIFNldHMgdGhlIG51bWJlciBvZiByZWR1Y2UgdGFza3MgZm9yIHRoZSBnaXZlbiBqb2IgY29uZmlndXJhdGlvbiB0byB0aGUgCisgICAqIG51bWJlciBvZiByZWdpb25zIHRoZSBnaXZlbiB0YWJsZSBoYXMuIAorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlICBUaGUgdGFibGUgdG8gZ2V0IHRoZSByZWdpb24gY291bnQgZm9yLgorICAgKiBAcGFyYW0gam9iICBUaGUgY3VycmVudCBqb2IgY29uZmlndXJhdGlvbiB0byBhZGp1c3QuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gV2hlbiByZXRyaWV2aW5nIHRoZSB0YWJsZSBkZXRhaWxzIGZhaWxzLgorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TnVtUmVkdWNlVGFza3MoU3RyaW5nIHRhYmxlLCBKb2JDb25mIGpvYikgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7IAorICAgIEhUYWJsZSBvdXRwdXRUYWJsZSA9IG5ldyBIVGFibGUobmV3IEhCYXNlQ29uZmlndXJhdGlvbihqb2IpLCB0YWJsZSk7CisgICAgaW50IHJlZ2lvbnMgPSBvdXRwdXRUYWJsZS5nZXRSZWdpb25zSW5mbygpLnNpemUoKTsKKyAgICBqb2Iuc2V0TnVtUmVkdWNlVGFza3MocmVnaW9ucyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTZXRzIHRoZSBudW1iZXIgb2YgbWFwIHRhc2tzIGZvciB0aGUgZ2l2ZW4gam9iIGNvbmZpZ3VyYXRpb24gdG8gdGhlIAorICAgKiBudW1iZXIgb2YgcmVnaW9ucyB0aGUgZ2l2ZW4gdGFibGUgaGFzLiAKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZSAgVGhlIHRhYmxlIHRvIGdldCB0aGUgcmVnaW9uIGNvdW50IGZvci4KKyAgICogQHBhcmFtIGpvYiAgVGhlIGN1cnJlbnQgam9iIGNvbmZpZ3VyYXRpb24gdG8gYWRqdXN0LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFdoZW4gcmV0cmlldmluZyB0aGUgdGFibGUgZGV0YWlscyBmYWlscy4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldE51bU1hcFRhc2tzKFN0cmluZyB0YWJsZSwgSm9iQ29uZiBqb2IpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geyAKKyAgICBIVGFibGUgb3V0cHV0VGFibGUgPSBuZXcgSFRhYmxlKG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oam9iKSwgdGFibGUpOworICAgIGludCByZWdpb25zID0gb3V0cHV0VGFibGUuZ2V0UmVnaW9uc0luZm8oKS5zaXplKCk7CisgICAgam9iLnNldE51bU1hcFRhc2tzKHJlZ2lvbnMpOworICB9CisgIAorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZU91dHB1dEZvcm1hdC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlT3V0cHV0Rm9ybWF0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQ2YWRiNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZU91dHB1dEZvcm1hdC5qYXZhCkBAIC0wLDAgKzEsMTA1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuRmlsZUFscmVhZHlFeGlzdHNFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkludmFsaWRKb2JDb25mRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDb25mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlT3V0cHV0Rm9ybWF0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZWNvcmRXcml0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlJlcG9ydGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJvZ3Jlc3NhYmxlOworCisvKioKKyAqIENvbnZlcnQgTWFwL1JlZHVjZSBvdXRwdXQgYW5kIHdyaXRlIGl0IHRvIGFuIEhCYXNlIHRhYmxlCisgKi8KK3B1YmxpYyBjbGFzcyBUYWJsZU91dHB1dEZvcm1hdCBleHRlbmRzCitGaWxlT3V0cHV0Rm9ybWF0PEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEJhdGNoVXBkYXRlPiB7CisKKyAgLyoqIEpvYkNvbmYgcGFyYW1ldGVyIHRoYXQgc3BlY2lmaWVzIHRoZSBvdXRwdXQgdGFibGUgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUUFVUX1RBQkxFID0gImhiYXNlLm1hcHJlZC5vdXRwdXR0YWJsZSI7CisgIHByaXZhdGUgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRhYmxlT3V0cHV0Rm9ybWF0LmNsYXNzKTsKKworICAvKioKKyAgICogQ29udmVydCBSZWR1Y2Ugb3V0cHV0IChrZXksIHZhbHVlKSB0byAoSFN0b3JlS2V5LCBLZXllZERhdGFBcnJheVdyaXRhYmxlKSAKKyAgICogYW5kIHdyaXRlIHRvIGFuIEhCYXNlIHRhYmxlCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIFRhYmxlUmVjb3JkV3JpdGVyCisgICAgaW1wbGVtZW50cyBSZWNvcmRXcml0ZXI8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgQmF0Y2hVcGRhdGU+IHsKKyAgICBwcml2YXRlIEhUYWJsZSBtX3RhYmxlOworCisgICAgLyoqCisgICAgICogSW5zdGFudGlhdGUgYSBUYWJsZVJlY29yZFdyaXRlciB3aXRoIHRoZSBIQmFzZSBIQ2xpZW50IGZvciB3cml0aW5nLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZQorICAgICAqLworICAgIHB1YmxpYyBUYWJsZVJlY29yZFdyaXRlcihIVGFibGUgdGFibGUpIHsKKyAgICAgIG1fdGFibGUgPSB0YWJsZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZShSZXBvcnRlciByZXBvcnRlcikgCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgbV90YWJsZS5mbHVzaENvbW1pdHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSwKKyAgICAgICAgQmF0Y2hVcGRhdGUgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBtX3RhYmxlLmNvbW1pdChuZXcgQmF0Y2hVcGRhdGUodmFsdWUpKTsKKyAgICB9CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIFJlY29yZFdyaXRlciBnZXRSZWNvcmRXcml0ZXIoRmlsZVN5c3RlbSBpZ25vcmVkLAorICAgICAgSm9iQ29uZiBqb2IsIFN0cmluZyBuYW1lLCBQcm9ncmVzc2FibGUgcHJvZ3Jlc3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgCisgICAgLy8gZXhwZWN0aW5nIGV4YWN0bHkgb25lIHBhdGgKKyAgICAKKyAgICBTdHJpbmcgdGFibGVOYW1lID0gam9iLmdldChPVVRQVVRfVEFCTEUpOworICAgIEhUYWJsZSB0YWJsZSA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIHRhYmxlID0gbmV3IEhUYWJsZShuZXcgSEJhc2VDb25maWd1cmF0aW9uKGpvYiksIHRhYmxlTmFtZSk7CisgICAgfSBjYXRjaChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoZSk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgICB0YWJsZS5zZXRBdXRvRmx1c2goZmFsc2UpOworICAgIHJldHVybiBuZXcgVGFibGVSZWNvcmRXcml0ZXIodGFibGUpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNoZWNrT3V0cHV0U3BlY3MoRmlsZVN5c3RlbSBpZ25vcmVkLCBKb2JDb25mIGpvYikKKyAgdGhyb3dzIEZpbGVBbHJlYWR5RXhpc3RzRXhjZXB0aW9uLCBJbnZhbGlkSm9iQ29uZkV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgIAorICAgIFN0cmluZyB0YWJsZU5hbWUgPSBqb2IuZ2V0KE9VVFBVVF9UQUJMRSk7CisgICAgaWYodGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiTXVzdCBzcGVjaWZ5IHRhYmxlIG5hbWUiKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZVJlZHVjZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlUmVkdWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzU4NDc3MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UYWJsZVJlZHVjZS5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5JbW11dGFibGVCeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVkdWNlcjsKKworLyoqCisgKiBXcml0ZSBhIHRhYmxlLCBzb3J0aW5nIGJ5IHRoZSBpbnB1dCBrZXkKKyAqCisgKiBAcGFyYW0gPEs+IGtleSBjbGFzcworICogQHBhcmFtIDxWPiB2YWx1ZSBjbGFzcworICovCitAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKK3B1YmxpYyBpbnRlcmZhY2UgVGFibGVSZWR1Y2U8SyBleHRlbmRzIFdyaXRhYmxlQ29tcGFyYWJsZSwgViBleHRlbmRzIFdyaXRhYmxlPgorZXh0ZW5kcyBSZWR1Y2VyPEssIFYsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEJhdGNoVXBkYXRlPiB7CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGFibGVTcGxpdC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlU3BsaXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MzVlMmE3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1RhYmxlU3BsaXQuamF2YQpAQCAtMCwwICsxLDExMiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0OworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5JbnB1dFNwbGl0OworCisvKioKKyAqIEEgdGFibGUgc3BsaXQgY29ycmVzcG9uZHMgdG8gYSBrZXkgcmFuZ2UgW2xvdywgaGlnaCkKKyAqLworcHVibGljIGNsYXNzIFRhYmxlU3BsaXQgaW1wbGVtZW50cyBJbnB1dFNwbGl0LCBDb21wYXJhYmxlPFRhYmxlU3BsaXQ+IHsKKyAgcHJpdmF0ZSBieXRlIFtdIG1fdGFibGVOYW1lOworICBwcml2YXRlIGJ5dGUgW10gbV9zdGFydFJvdzsKKyAgcHJpdmF0ZSBieXRlIFtdIG1fZW5kUm93OworICBwcml2YXRlIFN0cmluZyBtX3JlZ2lvbkxvY2F0aW9uOworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBUYWJsZVNwbGl0KCkgeworICAgIHRoaXMoSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZLCBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVksCisgICAgICBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVksICIiKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAqIEBwYXJhbSBzdGFydFJvdworICAgKiBAcGFyYW0gZW5kUm93CisgICAqIEBwYXJhbSBsb2NhdGlvbgorICAgKi8KKyAgcHVibGljIFRhYmxlU3BsaXQoYnl0ZSBbXSB0YWJsZU5hbWUsIGJ5dGUgW10gc3RhcnRSb3csIGJ5dGUgW10gZW5kUm93LAorICAgICAgZmluYWwgU3RyaW5nIGxvY2F0aW9uKSB7CisgICAgdGhpcy5tX3RhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB0aGlzLm1fc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICB0aGlzLm1fZW5kUm93ID0gZW5kUm93OworICAgIHRoaXMubV9yZWdpb25Mb2NhdGlvbiA9IGxvY2F0aW9uOworICB9CisKKyAgLyoqIEByZXR1cm4gdGFibGUgbmFtZSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgcmV0dXJuIHRoaXMubV90YWJsZU5hbWU7CisgIH0KKworICAvKiogQHJldHVybiBzdGFydGluZyByb3cga2V5ICovCisgIHB1YmxpYyBieXRlIFtdIGdldFN0YXJ0Um93KCkgeworICAgIHJldHVybiB0aGlzLm1fc3RhcnRSb3c7CisgIH0KKworICAvKiogQHJldHVybiBlbmQgcm93IGtleSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRFbmRSb3coKSB7CisgICAgcmV0dXJuIHRoaXMubV9lbmRSb3c7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgcmVnaW9uJ3MgaG9zdG5hbWUgKi8KKyAgcHVibGljIFN0cmluZyBnZXRSZWdpb25Mb2NhdGlvbigpIHsKKyAgICByZXR1cm4gdGhpcy5tX3JlZ2lvbkxvY2F0aW9uOworICB9CisKKyAgcHVibGljIFN0cmluZ1tdIGdldExvY2F0aW9ucygpIHsKKyAgICByZXR1cm4gbmV3IFN0cmluZ1tdIHt0aGlzLm1fcmVnaW9uTG9jYXRpb259OworICB9CisKKyAgcHVibGljIGxvbmcgZ2V0TGVuZ3RoKCkgeworICAgIC8vIE5vdCBjbGVhciBob3cgdG8gb2J0YWluIHRoaXMuLi4gc2VlbXMgdG8gYmUgdXNlZCBvbmx5IGZvciBzb3J0aW5nIHNwbGl0cworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5tX3RhYmxlTmFtZSA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgIHRoaXMubV9zdGFydFJvdyA9IEJ5dGVzLnJlYWRCeXRlQXJyYXkoaW4pOworICAgIHRoaXMubV9lbmRSb3cgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICB0aGlzLm1fcmVnaW9uTG9jYXRpb24gPSBCeXRlcy50b1N0cmluZyhCeXRlcy5yZWFkQnl0ZUFycmF5KGluKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIHRoaXMubV90YWJsZU5hbWUpOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy5tX3N0YXJ0Um93KTsKKyAgICBCeXRlcy53cml0ZUJ5dGVBcnJheShvdXQsIHRoaXMubV9lbmRSb3cpOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgQnl0ZXMudG9CeXRlcyh0aGlzLm1fcmVnaW9uTG9jYXRpb24pKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiBtX3JlZ2lvbkxvY2F0aW9uICsgIjoiICsKKyAgICAgIEJ5dGVzLnRvU3RyaW5nKG1fc3RhcnRSb3cpICsgIiwiICsgQnl0ZXMudG9TdHJpbmcobV9lbmRSb3cpOworICB9CisKKyAgcHVibGljIGludCBjb21wYXJlVG8oVGFibGVTcGxpdCBvKSB7CisgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhnZXRTdGFydFJvdygpLCBvLmdldFN0YXJ0Um93KCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvcGFja2FnZS1pbmZvLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvcGFja2FnZS1pbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTFkMzcxOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9wYWNrYWdlLWluZm8uamF2YQpAQCAtMCwwICsxLDI2NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorUHJvdmlkZXMgSEJhc2UgPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGFkb29wTWFwUmVkdWNlIj5NYXBSZWR1Y2U8L2E+CitJbnB1dC9PdXRwdXRGb3JtYXRzLCBhIHRhYmxlIGluZGV4aW5nIE1hcFJlZHVjZSBqb2IsIGFuZCB1dGlsaXR5CisKKzxoMj5UYWJsZSBvZiBDb250ZW50czwvaDI+Cis8dWw+Cis8bGk+PGEgaHJlZj0iI2NsYXNzcGF0aCI+SEJhc2UsIE1hcFJlZHVjZSBhbmQgdGhlIENMQVNTUEFUSDwvYT48L2xpPgorPGxpPjxhIGhyZWY9IiNzaW5rIj5IQmFzZSBhcyBNYXBSZWR1Y2Ugam9iIGRhdGEgc291cmNlIGFuZCBzaW5rPC9hPjwvbGk+Cis8bGk+PGEgaHJlZj0iI2V4YW1wbGVzIj5FeGFtcGxlIENvZGU8L2E+PC9saT4KKzwvdWw+CisKKzxoMj48YSBuYW1lPSJjbGFzc3BhdGgiPkhCYXNlLCBNYXBSZWR1Y2UgYW5kIHRoZSBDTEFTU1BBVEg8L2E+PC9oMj4KKworPHA+TWFwUmVkdWNlIGpvYnMgZGVwbG95ZWQgdG8gYSBNYXBSZWR1Y2UgY2x1c3RlciBkbyBub3QgYnkgZGVmYXVsdCBoYXZlIGFjY2VzcwordG8gdGhlIEhCYXNlIGNvbmZpZ3VyYXRpb24gdW5kZXIgPGNvZGU+JEhCQVNFX0NPTkZfRElSPC9jb2RlPiBub3IgdG8gSEJhc2UgY2xhc3Nlcy4KK1lvdSBjb3VsZCBhZGQgPGNvZGU+aGJhc2Utc2l0ZS54bWw8L2NvZGU+IHRvICRIQURPT1BfSE9NRS9jb25mIGFuZCBhZGQKKzxjb2RlPmhiYXNlLVguWC5YLmphcjwvY29kZT4gdG8gdGhlIDxjb2RlPiRIQURPT1BfSE9NRS9saWI8L2NvZGU+IGFuZCBjb3B5IHRoZXNlCitjaGFuZ2VzIGFjcm9zcyB5b3VyIGNsdXN0ZXIgYnV0IHRoZSBjbGVhbmVzdCBtZWFucyBvZiBhZGRpbmcgaGJhc2UgY29uZmlndXJhdGlvbgorYW5kIGNsYXNzZXMgdG8gdGhlIGNsdXN0ZXIgPGNvZGU+Q0xBU1NQQVRIPC9jb2RlPiBpcyBieSB1bmNvbW1lbnRpbmcKKzxjb2RlPkhBRE9PUF9DTEFTU1BBVEg8L2NvZGU+IGluIDxjb2RlPiRIQURPT1BfSE9NRS9jb25mL2hhZG9vcC1lbnYuc2g8L2NvZGU+CithbmQgYWRkaW5nIHRoZSBwYXRoIHRvIHRoZSBoYmFzZSBqYXIgYW5kIDxjb2RlPiRIQkFTRV9DT05GX0RJUjwvY29kZT4gZGlyZWN0b3J5LgorVGhlbiBjb3B5IHRoZSBhbWVuZGVkIGNvbmZpZ3VyYXRpb24gYXJvdW5kIHRoZSBjbHVzdGVyLgorWW91J2xsIHByb2JhYmx5IG5lZWQgdG8gcmVzdGFydCB0aGUgTWFwUmVkdWNlIGNsdXN0ZXIgaWYgeW91IHdhbnQgaXQgdG8gbm90aWNlCit0aGUgbmV3IGNvbmZpZ3VyYXRpb24uCis8L3A+CisKKzxwPkZvciBleGFtcGxlLCBoZXJlIGlzIGhvdyB5b3Ugd291bGQgYW1lbmQgPGNvZGU+aGFkb29wLWVudi5zaDwvY29kZT4gYWRkaW5nIHRoZQorYnVpbHQgaGJhc2UgamFyLCBoYmFzZSBjb25mLCBhbmQgdGhlIDxjb2RlPlBlcmZvcm1hbmNlRXZhbHVhdGlvbjwvY29kZT4gY2xhc3MgZnJvbQordGhlIGJ1aWx0IGhiYXNlIHRlc3QgamFyIHRvIHRoZSBoYWRvb3AgPGNvZGU+Q0xBU1NQQVRIPGNvZGU+OgorCis8YmxvY2txdW90ZT48cHJlPiMgRXh0cmEgSmF2YSBDTEFTU1BBVEggZWxlbWVudHMuIE9wdGlvbmFsLgorIyBleHBvcnQgSEFET09QX0NMQVNTUEFUSD0KK2V4cG9ydCBIQURPT1BfQ0xBU1NQQVRIPSRIQkFTRV9IT01FL2J1aWxkL3Rlc3Q6JEhCQVNFX0hPTUUvYnVpbGQvaGJhc2UtWC5YLlguamFyOiRIQkFTRV9IT01FL2J1aWxkL2hiYXNlLVguWC5YLXRlc3QuamFyOiRIQkFTRV9IT01FL2NvbmY8L3ByZT48L2Jsb2NrcXVvdGU+CisKKzxwPkV4cGFuZCA8Y29kZT4kSEJBU0VfSE9NRTwvY29kZT4gaW4gdGhlIGFib3ZlIGFwcHJvcHJpYXRlbHkgdG8gc3VpdCB5b3VyCitsb2NhbCBlbnZpcm9ubWVudC48L3A+CisKKzxwPkFmdGVyIGNvcHlpbmcgdGhlIGFib3ZlIGNoYW5nZSBhcm91bmQgeW91ciBjbHVzdGVyLCB0aGlzIGlzIGhvdyB5b3Ugd291bGQgcnVuCit0aGUgUGVyZm9ybWFuY2VFdmFsdWF0aW9uIE1SIGpvYiB0byBwdXQgdXAgNCBjbGllbnRzIChQcmVzdW1lcyBhIHJlYWR5IG1hcHJlZHVjZQorY2x1c3Rlcik6CisKKzxibG9ja3F1b3RlPjxwcmU+JEhBRE9PUF9IT01FL2Jpbi9oYWRvb3Agb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUGVyZm9ybWFuY2VFdmFsdWF0aW9uIHNlcXVlbnRpYWxXcml0ZSA0PC9wcmU+PC9ibG9ja3F1b3RlPgorCitUaGUgUGVyZm9ybWFuY2VFdmFsdWF0aW9uIGNsYXNzIHdpbCBiZSBmb3VuZCBvbiB0aGUgQ0xBU1NQQVRIIGJlY2F1c2UgeW91CithZGRlZCA8Y29kZT4kSEJBU0VfSE9NRS9idWlsZC90ZXN0PC9jb2RlPiB0byBIQURPT1BfQ0xBU1NQQVRICis8L3A+CisKKzxwPkFub3RoZXIgcG9zc2liaWxpdHksIGlmIGZvciBleGFtcGxlIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gaGFkb29wLWVudi5zaCBvcgorYXJlIHVuYWJsZSB0byByZXN0YXJ0IHRoZSBoYWRvb3AgY2x1c3RlciwgaXMgYnVuZGxpbmcgdGhlIGhiYXNlIGphciBpbnRvIGEgbWFwcmVkdWNlCitqb2IgamFyIGFkZGluZyBpdCBhbmQgaXRzIGRlcGVuZGVuY2llcyB1bmRlciB0aGUgam9iIGphciA8Y29kZT5saWIvPC9jb2RlPgorZGlyZWN0b3J5IGFuZCB0aGUgaGJhc2UgY29uZiBpbnRvIGEgam9iIGphciA8Y29kZT5jb25mLzwvY29kZT4gZGlyZWN0b3J5LgorPC9hPgorCis8aDI+PGEgbmFtZT0ic2luayI+SEJhc2UgYXMgTWFwUmVkdWNlIGpvYiBkYXRhIHNvdXJjZSBhbmQgc2luazwvYT48L2gyPgorCis8cD5IQmFzZSBjYW4gYmUgdXNlZCBhcyBhIGRhdGEgc291cmNlLCB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlRhYmxlSW5wdXRGb3JtYXQgVGFibGVJbnB1dEZvcm1hdH0sCithbmQgZGF0YSBzaW5rLCB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlRhYmxlT3V0cHV0Rm9ybWF0IFRhYmxlT3V0cHV0Rm9ybWF0fSwgZm9yIE1hcFJlZHVjZSBqb2JzLgorV3JpdGluZyBNYXBSZWR1Y2Ugam9icyB0aGF0IHJlYWQgb3Igd3JpdGUgSEJhc2UsIHlvdSdsbCBwcm9iYWJseSB3YW50IHRvIHN1YmNsYXNzCit7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlRhYmxlTWFwIFRhYmxlTWFwfSBhbmQvb3IKK3tAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQuVGFibGVSZWR1Y2UgVGFibGVSZWR1Y2V9LiAgU2VlIHRoZSBkby1ub3RoaW5nCitwYXNzLXRocm91Z2ggY2xhc3NlcyB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLklkZW50aXR5VGFibGVNYXAgSWRlbnRpdHlUYWJsZU1hcH0gYW5kCit7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLklkZW50aXR5VGFibGVSZWR1Y2UgSWRlbnRpdHlUYWJsZVJlZHVjZX0gZm9yIGJhc2ljIHVzYWdlLiAgRm9yIGEgbW9yZQoraW52b2x2ZWQgZXhhbXBsZSwgc2VlIHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQuQnVpbGRUYWJsZUluZGV4IEJ1aWxkVGFibGVJbmRleH0KK29yIHJldmlldyB0aGUgPGNvZGU+b3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlRlc3RUYWJsZU1hcFJlZHVjZTwvY29kZT4gdW5pdCB0ZXN0LgorPC9wPgorCis8cD5SdW5uaW5nIG1hcHJlZHVjZSBqb2JzIHRoYXQgaGF2ZSBoYmFzZSBhcyBzb3VyY2Ugb3Igc2luaywgeW91J2xsIG5lZWQgdG8KK3NwZWNpZnkgc291cmNlL3NpbmsgdGFibGUgYW5kIGNvbHVtbiBuYW1lcyBpbiB5b3VyIGNvbmZpZ3VyYXRpb24uPC9wPgorCis8cD5SZWFkaW5nIGZyb20gaGJhc2UsIHRoZSBUYWJsZUlucHV0Rm9ybWF0IGFza3MgaGJhc2UgZm9yIHRoZSBsaXN0IG9mCityZWdpb25zIGFuZCBtYWtlcyBhIG1hcC1wZXItcmVnaW9uIG9yIDxjb2RlPm1hcHJlZC5tYXAudGFza3MgbWFwczwvY29kZT4sCit3aGljaGV2ZXIgaXMgc21hbGxlciAoSWYgeW91ciBqb2Igb25seSBoYXMgdHdvIG1hcHMsIHVwIG1hcHJlZC5tYXAudGFza3MKK3RvIGEgbnVtYmVyID4gbnVtYmVyIG9mIHJlZ2lvbnMpLiBNYXBzIHdpbGwgcnVuIG9uIHRoZSBhZGphY2VudCBUYXNrVHJhY2tlcgoraWYgeW91IGFyZSBydW5uaW5nIGEgVGFza1RyYWNlciBhbmQgUmVnaW9uU2VydmVyIHBlciBub2RlLgorV3JpdGluZywgaXQgbWF5IG1ha2Ugc2Vuc2UgdG8gYXZvaWQgdGhlIHJlZHVjZSBzdGVwIGFuZCB3cml0ZSB5b3Vyc2VsZiBiYWNrIGludG8KK2hiYXNlIGZyb20gaW5zaWRlIHlvdXIgbWFwLiBZb3UnZCBkbyB0aGlzIHdoZW4geW91ciBqb2IgZG9lcyBub3QgbmVlZCB0aGUgc29ydAorYW5kIGNvbGxhdGlvbiB0aGF0IG1hcHJlZHVjZSBkb2VzIG9uIHRoZSBtYXAgZW1pdHRlZCBkYXRhOyBvbiBpbnNlcnQsCitoYmFzZSAnc29ydHMnIHNvIHRoZXJlIGlzIG5vIHBvaW50IGRvdWJsZS1zb3J0aW5nIChhbmQgc2h1ZmZsaW5nIGRhdGEgYXJvdW5kCit5b3VyIG1hcHJlZHVjZSBjbHVzdGVyKSB1bmxlc3MgeW91IG5lZWQgdG8uIElmIHlvdSBkbyBub3QgbmVlZCB0aGUgcmVkdWNlLAoreW91IG1pZ2h0IGp1c3QgaGF2ZSB5b3VyIG1hcCBlbWl0IGNvdW50cyBvZiByZWNvcmRzIHByb2Nlc3NlZCBqdXN0IHNvIHRoZQorZnJhbWV3b3JrJ3MgcmVwb3J0IGF0IHRoZSBlbmQgb2YgeW91ciBqb2IgaGFzIG1lYW5pbmcgb3Igc2V0IHRoZSBudW1iZXIgb2YKK3JlZHVjZXMgdG8gemVybyBhbmQgdXNlIFRhYmxlT3V0cHV0Rm9ybWF0LiBTZWUgZXhhbXBsZSBjb2RlCitiZWxvdy4gSWYgcnVubmluZyB0aGUgcmVkdWNlIHN0ZXAgbWFrZXMgc2Vuc2UgaW4geW91ciBjYXNlLCBpdHMgdXN1YWxseSBiZXR0ZXIKK3RvIGhhdmUgbG90cyBvZiByZWR1Y2VycyBzbyBsb2FkIGlzIHNwcmVhZCBhY3Jvc3MgdGhlIGhiYXNlIGNsdXN0ZXIuPC9wPgorCis8cD5UaGVyZSBpcyBhbHNvIGEgbmV3IGhiYXNlIHBhcnRpdGlvbmVyIHRoYXQgd2lsbCBydW4gYXMgbWFueSByZWR1Y2VycyBhcworY3VycmVudGx5IGV4aXN0aW5nIHJlZ2lvbnMuICBUaGUgCit7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLkhSZWdpb25QYXJ0aXRpb25lcn0gaXMgc3VpdGFibGUKK3doZW4geW91ciB0YWJsZSBpcyBsYXJnZSBhbmQgeW91ciB1cGxvYWQgaXMgbm90IHN1Y2ggdGhhdCBpdCB3aWxsIGdyZWF0bHkKK2FsdGVyIHRoZSBudW1iZXIgb2YgZXhpc3RpbmcgcmVnaW9ucyB3aGVuIGRvbmU7IG90aGVyIHVzZSB0aGUgZGVmYXVsdAorcGFydGl0aW9uZXIuCis8L3A+CisKKzxoMj48YSBuYW1lPSJleGFtcGxlcyI+RXhhbXBsZSBDb2RlPC9hPjwvaDI+Cis8aDM+U2FtcGxlIFJvdyBDb3VudGVyPC9oMz4KKzxwPlNlZSB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkLlJvd0NvdW50ZXJ9LiAgWW91IHNob3VsZCBiZSBhYmxlIHRvIHJ1bgoraXQgYnkgZG9pbmc6IDxjb2RlPiUgLi9iaW4vaGFkb29wIGphciBoYmFzZS1YLlguWC5qYXI8L2NvZGU+LiAgVGhpcyB3aWxsIGludm9rZQordGhlIGhiYXNlIE1hcFJlZHVjZSBEcml2ZXIgY2xhc3MuICBTZWxlY3QgJ3Jvd2NvdW50ZXInIGZyb20gdGhlIGNob2ljZSBvZiBqb2JzCitvZmZlcmVkLiBZb3UgbWF5IG5lZWQgdG8gYWRkIHRoZSBoYmFzZSBjb25mIGRpcmVjdG9yeSB0byA8Y29kZT4kSEFET09QX0hPTUUvY29uZi9oYWRvb3AtZW52LnNoI0hBRE9PUF9DTEFTU1BBVEg8L2NvZGU+CitzbyB0aGUgcm93Y291bnRlciBnZXRzIHBvaW50ZWQgYXQgdGhlIHJpZ2h0IGhiYXNlIGNsdXN0ZXIgKG9yLCBidWlsZCBhIG5ldyBqYXIKK3dpdGggYW4gYXBwcm9wcmlhdGUgaGJhc2Utc2l0ZS54bWwgYnVpbHQgaW50byB5b3VyIGpvYiBqYXIpLgorPC9wPgorPGgzPlBlcmZvcm1hbmNlRXZhbHVhdGlvbjwvaDM+Cis8cD5TZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUGVyZm9ybWFuY2VFdmFsdWF0aW9uIGZyb20gaGJhc2Ugc3JjL3Rlc3QuICBJdCBydW5zCithIG1hcHJlZHVjZSBqb2IgdG8gcnVuIGNvbmN1cnJlbnQgY2xpZW50cyByZWFkaW5nIGFuZCB3cml0aW5nIGhiYXNlLgorPC9wPgorCis8aDM+U2FtcGxlIE1SIEJ1bGsgVXBsb2FkZXI8L2gzPgorPHA+QSBzdHVkZW50cy9jbGFzc2VzIGV4YW1wbGUgYmFzZWQgb24gYSBjb250cmlidXRpb24gYnkgTmFhbWEgS3JhdXMgd2l0aCBsb2dzIG9mCitkb2N1bWVudGF0aW9uIGNhbiBiZSBmb3VuZCBvdmVyIGluIHNyYy9leGFtcGxlcy9tYXByZWQuCitJdHMgdGhlIDxjb2RlPm9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZC5TYW1wbGVVcGxvYWRlcjwvY29kZT4gY2xhc3MuCitKdXN0IGNvcHkgaXQgdW5kZXIgc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkIHRvIGNvbXBpbGUgYW5kIHRyeSBpdAorKHVudGlsIHdlIHN0YXJ0IGdlbmVyYXRpbmcgYW4gaGJhc2UgZXhhbXBsZXMgamFyKS4gIFRoZSBjbGFzcyByZWFkcyBhIGRhdGEgZmlsZQorZnJvbSBIREZTIGFuZCBwZXIgbGluZSwgZG9lcyBhbiB1cGxvYWQgdG8gSEJhc2UgdXNpbmcgVGFibGVSZWR1Y2UuCitSZWFkIHRoZSBjbGFzcyBjb21tZW50IGZvciBzcGVjaWZpY2F0aW9uIG9mIGlucHV0cywgcHJlcmVxdWlzaXRlcywgZXRjLgorPC9wPgorCis8aDM+RXhhbXBsZSB0byBidWxrIGltcG9ydC9sb2FkIGEgdGV4dCBmaWxlIGludG8gYW4gSFRhYmxlCis8L2gzPgorCis8cD5IZXJlJ3MgYSBzYW1wbGUgcHJvZ3JhbSBmcm9tIAorPGEgaHJlZj0iaHR0cDovL3d3dy5zcGljeWxvZ2ljLmNvbS9hbGxlbmRheS9ibG9nL2NhdGVnb3J5L2NvbXB1dGluZy9kaXN0cmlidXRlZC1zeXN0ZW1zL2hhZG9vcC9oYmFzZS8iPkFsbGVuIERheTwvYT4KK3RoYXQgdGFrZXMgYW4gSERGUyB0ZXh0IGZpbGUgcGF0aCBhbmQgYW4gSEJhc2UgdGFibGUgbmFtZSBhcyBpbnB1dHMsIGFuZCBsb2FkcyB0aGUgY29udGVudHMgb2YgdGhlIHRleHQgZmlsZSB0byB0aGUgdGFibGUKK2FsbCB1cCBpbiB0aGUgbWFwIHBoYXNlLgorPC9wPgorCis8YmxvY2txdW90ZT48cHJlPgorcGFja2FnZSBjb20uc3BpY3lsb2dpYy5oYmFzZTsKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Mb25nV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uVGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuRmlsZUlucHV0Rm9ybWF0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDbGllbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1hcFJlZHVjZUJhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1hcHBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuT3V0cHV0Q29sbGVjdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5SZXBvcnRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQubGliLk51bGxPdXRwdXRGb3JtYXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Ub29sOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVG9vbFJ1bm5lcjsKKworLyoqCisgKiBDbGFzcyB0aGF0IGFkZHMgdGhlIHBhcnNlZCBsaW5lIGZyb20gdGhlIGlucHV0IHRvIGhiYXNlCisgKiBpbiB0aGUgbWFwIGZ1bmN0aW9uLiAgTWFwIGhhcyBubyBlbWlzc2lvbnMgYW5kIGpvYgorICogaGFzIG5vIHJlZHVjZS4KKyAqJiN4MmY7CitwdWJsaWMgY2xhc3MgQnVsa0ltcG9ydCBpbXBsZW1lbnRzIFRvb2wgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRSA9ICJCdWxrSW1wb3J0IjsKKyAgcHJpdmF0ZSBDb25maWd1cmF0aW9uIGNvbmY7CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBJbm5lck1hcCBleHRlbmRzIE1hcFJlZHVjZUJhc2UgaW1wbGVtZW50cyBNYXBwZXImbHQ7TG9uZ1dyaXRhYmxlLCBUZXh0LCBUZXh0LCBUZXh0PiB7CisgICAgcHJpdmF0ZSBIVGFibGUgdGFibGU7CisgICAgcHJpdmF0ZSBIQmFzZUNvbmZpZ3VyYXRpb24gSEJjb25mOworCisgICAgcHVibGljIHZvaWQgbWFwKExvbmdXcml0YWJsZSBrZXksIFRleHQgdmFsdWUsCisgICAgICAgIE91dHB1dENvbGxlY3RvciZsdDtUZXh0LCBUZXh0PiBvdXRwdXQsIFJlcG9ydGVyIHJlcG9ydGVyKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoIHRhYmxlID09IG51bGwgKQorICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInRhYmxlIGlzIG51bGwiKTsKKyAgICAgIAorICAgICAgLy8gU3BsaXQgaW5wdXQgbGluZSBvbiB0YWIgY2hhcmFjdGVyCisgICAgICBTdHJpbmcgW10gc3BsaXRzID0gdmFsdWUudG9TdHJpbmcoKS5zcGxpdCgiXHQiKTsKKyAgICAgIGlmICggc3BsaXRzLmxlbmd0aCAhPSA0ICkKKyAgICAgICAgcmV0dXJuOworICAgICAgCisgICAgICBTdHJpbmcgcm93SUQgPSBzcGxpdHNbMF07CisgICAgICBpbnQgdGltZXN0YW1wICA9IEludGVnZXIucGFyc2VJbnQoIHNwbGl0c1sxXSApOworICAgICAgU3RyaW5nIGNvbElEID0gc3BsaXRzWzJdOworICAgICAgU3RyaW5nIGNlbGxWYWx1ZSA9IHNwbGl0c1szXTsKKworICAgICAgcmVwb3J0ZXIuc2V0U3RhdHVzKCJNYXAgZW1pdHRpbmcgY2VsbCBmb3Igcm93PSciICsgcm93SUQgKworICAgICAgICAgICInLCBjb2x1bW49JyIgKyBjb2xJRCArICInLCB0aW1lPSciICsgdGltZXN0YW1wICsgIiciKTsKKworICAgICAgQmF0Y2hVcGRhdGUgYnUgPSBuZXcgQmF0Y2hVcGRhdGUoIHJvd0lEICk7CisgICAgICBpZiAoIHRpbWVzdGFtcCA+IDAgKQorICAgICAgICBidS5zZXRUaW1lc3RhbXAoIHRpbWVzdGFtcCApOworCisgICAgICBidS5wdXQoY29sSUQsIGNlbGxWYWx1ZS5nZXRCeXRlcygpKTsgICAgICAKKyAgICAgIHRhYmxlLmNvbW1pdCggYnUgKTsgICAgICAKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjb25maWd1cmUoSm9iQ29uZiBqb2IpIHsKKyAgICAgIEhCY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oam9iKTsKKyAgICAgIHRyeSB7CisgICAgICAgIHRhYmxlID0gbmV3IEhUYWJsZSggSEJjb25mLCBqb2IuZ2V0KCJpbnB1dC50YWJsZSIpICk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKKyAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyBKb2JDb25mIGNyZWF0ZVN1Ym1pdHRhYmxlSm9iKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBKb2JDb25mIGMgPSBuZXcgSm9iQ29uZihnZXRDb25mKCksIEJ1bGtJbXBvcnQuY2xhc3MpOworICAgIGMuc2V0Sm9iTmFtZShOQU1FKTsKKyAgICBGaWxlSW5wdXRGb3JtYXQuc2V0SW5wdXRQYXRocyhjLCBuZXcgUGF0aChhcmdzWzBdKSk7CisKKyAgICBjLnNldCgiaW5wdXQudGFibGUiLCBhcmdzWzFdKTsKKyAgICBjLnNldE1hcHBlckNsYXNzKElubmVyTWFwLmNsYXNzKTsKKyAgICBjLnNldE51bVJlZHVjZVRhc2tzKDApOworICAgIGMuc2V0T3V0cHV0Rm9ybWF0KE51bGxPdXRwdXRGb3JtYXQuY2xhc3MpOworICAgIHJldHVybiBjOworICB9CisgIAorICBzdGF0aWMgaW50IHByaW50VXNhZ2UoKSB7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogIiArIE5BTUUgKyAiICZsdDtpbnB1dD4gJmx0O3RhYmxlX25hbWU+Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJcdHdoZXJlICZsdDtpbnB1dD4gaXMgYSB0YWItZGVsaW1pdGVkIHRleHQgZmlsZSB3aXRoIDQgY29sdW1ucy4iKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIlx0XHRjb2x1bW4gMSA9IHJvdyBJRCIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXHRcdGNvbHVtbiAyID0gdGltZXN0YW1wICh1c2UgYSBuZWdhdGl2ZSB2YWx1ZSBmb3IgY3VycmVudCB0aW1lKSIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXHRcdGNvbHVtbiAzID0gY29sdW1uIElEIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJcdFx0Y29sdW1uIDQgPSBjZWxsIHZhbHVlIik7CisgICAgcmV0dXJuIC0xOworICB9IAorCisgIHB1YmxpYyBpbnQgcnVuKEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKSBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIGV4YWN0bHkgMyBwYXJhbWV0ZXJzIGxlZnQuCisgICAgaWYgKGFyZ3MubGVuZ3RoICE9IDIpIHsKKyAgICAgIHJldHVybiBwcmludFVzYWdlKCk7CisgICAgfQorICAgIEpvYkNsaWVudC5ydW5Kb2IoY3JlYXRlU3VibWl0dGFibGVKb2IoYXJncykpOworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIENvbmZpZ3VyYXRpb24gZ2V0Q29uZigpIHsKKyAgICByZXR1cm4gdGhpcy5jb25mOworICB9IAorCisgIHB1YmxpYyB2b2lkIHNldENvbmYoZmluYWwgQ29uZmlndXJhdGlvbiBjKSB7CisgICAgdGhpcy5jb25mID0gYzsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIGludCBlcnJDb2RlID0gVG9vbFJ1bm5lci5ydW4obmV3IENvbmZpZ3VyYXRpb24oKSwgbmV3IEJ1bGtJbXBvcnQoKSwgYXJncyk7CisgICAgU3lzdGVtLmV4aXQoZXJyQ29kZSk7CisgIH0KK30KKzwvcHJlPjwvYmxvY2txdW90ZT4KKworKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFwcmVkOwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0FkZENvbHVtbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0FkZENvbHVtbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM0NmFhNDEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvQWRkQ29sdW1uLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKKworLyoqIEluc3RhbnRpYXRlZCB0byBhZGQgYSBjb2x1bW4gZmFtaWx5IHRvIGEgdGFibGUgKi8KK2NsYXNzIEFkZENvbHVtbiBleHRlbmRzIENvbHVtbk9wZXJhdGlvbiB7CisgIHByaXZhdGUgZmluYWwgSENvbHVtbkRlc2NyaXB0b3IgbmV3Q29sdW1uOworCisgIEFkZENvbHVtbihmaW5hbCBITWFzdGVyIG1hc3RlciwgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsIAorICAgIGZpbmFsIEhDb2x1bW5EZXNjcmlwdG9yIG5ld0NvbHVtbikgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIobWFzdGVyLCB0YWJsZU5hbWUpOworICAgIHRoaXMubmV3Q29sdW1uID0gbmV3Q29sdW1uOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHBvc3RQcm9jZXNzTWV0YShNZXRhUmVnaW9uIG0sIEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoSFJlZ2lvbkluZm8gaTogdW5zZXJ2ZWRSZWdpb25zKSB7CisgICAgICAvLyBBbGwgd2UgbmVlZCB0byBkbyB0byBhZGQgYSBjb2x1bW4gaXMgYWRkIGl0IHRvIHRoZSB0YWJsZSBkZXNjcmlwdG9yLgorICAgICAgLy8gV2hlbiB0aGUgcmVnaW9uIGlzIGJyb3VnaHQgb24tbGluZSwgaXQgd2lsbCBmaW5kIHRoZSBjb2x1bW4gbWlzc2luZworICAgICAgLy8gYW5kIGNyZWF0ZSBpdC4KKyAgICAgIGkuZ2V0VGFibGVEZXNjKCkuYWRkRmFtaWx5KG5ld0NvbHVtbik7CisgICAgICB1cGRhdGVSZWdpb25JbmZvKHNlcnZlciwgbS5nZXRSZWdpb25OYW1lKCksIGkpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9CYXNlU2Nhbm5lci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0Jhc2VTY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTJjNWU4ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9CYXNlU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsNDA2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3RhdHVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aEZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5DaG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVW5rbm93blNjYW5uZXJFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5ITG9nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5TdG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuU3RvcmVGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaXBjLlJlbW90ZUV4Y2VwdGlvbjsKKworCisvKioKKyAqIEJhc2UgSFJlZ2lvbiBzY2FubmVyIGNsYXNzLiBIb2xkcyB1dGlsdHkgY29tbW9uIHRvIDxjb2RlPlJPT1Q8L2NvZGU+IGFuZAorICogPGNvZGU+TUVUQTwvY29kZT4gSFJlZ2lvbiBzY2FubmVycy4KKyAqIAorICogPHA+SG93IGRvIHdlIGtub3cgaWYgYWxsIHJlZ2lvbnMgYXJlIGFzc2lnbmVkPyBBZnRlciB0aGUgaW5pdGlhbCBzY2FuIG9mCisgKiB0aGUgPGNvZGU+Uk9PVDwvY29kZT4gYW5kIDxjb2RlPk1FVEE8L2NvZGU+IHJlZ2lvbnMsIGFsbCByZWdpb25zIGtub3duIGF0CisgKiB0aGF0IHRpbWUgd2lsbCBoYXZlIGJlZW4gb3IgYXJlIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGFzc2lnbmVkLjwvcD4KKyAqIAorICogPHA+V2hlbiBhIHJlZ2lvbiBpcyBzcGxpdCB0aGUgcmVnaW9uIHNlcnZlciBub3RpZmllcyB0aGUgbWFzdGVyIG9mIHRoZQorICogc3BsaXQgYW5kIHRoZSBuZXcgcmVnaW9ucyBhcmUgYXNzaWduZWQuIEJ1dCBzdXBwb3NlIHRoZSBtYXN0ZXIgbG9zZXMgdGhlCisgKiBzcGxpdCBtZXNzYWdlPyBXZSBuZWVkIHRvIHBlcmlvZGljYWxseSByZXNjYW4gdGhlIDxjb2RlPlJPT1Q8L2NvZGU+IGFuZAorICogPGNvZGU+TUVUQTwvY29kZT4gcmVnaW9ucy4KKyAqICAgIDx1bD4KKyAqICAgIDxsaT5JZiB3ZSByZXNjYW4sIGFueSByZWdpb25zIHRoYXQgYXJlIG5ldyBidXQgbm90IGFzc2lnbmVkIHdpbGwgaGF2ZQorICogICAgbm8gc2VydmVyIGluZm8uIEFueSByZWdpb25zIHRoYXQgYXJlIG5vdCBiZWluZyBzZXJ2ZWQgYnkgdGhlIHNhbWUKKyAqICAgIHNlcnZlciB3aWxsIGdldCByZS1hc3NpZ25lZC48L2xpPgorICogICAgICAKKyAqICAgIDxsaT5UaHVzIGEgcGVyaW9kaWMgcmVzY2FuIG9mIHRoZSByb290IHJlZ2lvbiB3aWxsIGZpbmQgYW55IG5ldworICogICAgPGNvZGU+TUVUQTwvY29kZT4gcmVnaW9ucyB3aGVyZSB3ZSBtaXNzZWQgdGhlIDxjb2RlPk1FVEE8L2NvZGU+IHNwbGl0CisgKiAgICBtZXNzYWdlIG9yIHdlIGZhaWxlZCB0byBkZXRlY3QgYSBzZXJ2ZXIgZGVhdGggYW5kIGNvbnNlcXVlbnRseSBuZWVkIHRvCisgKiAgICBhc3NpZ24gdGhlIHJlZ2lvbiB0byBhIG5ldyBzZXJ2ZXIuPC9saT4KKyAqICAgICAgICAKKyAqICAgIDxsaT5pZiB3ZSBrZWVwIHRyYWNrIG9mIGFsbCB0aGUga25vd24gPGNvZGU+TUVUQTwvY29kZT4gcmVnaW9ucywgdGhlbgorICogICAgd2UgY2FuIHJlc2NhbiB0aGVtIHBlcmlvZGljYWxseS4gSWYgd2UgZG8gdGhpcyB0aGVuIHdlIGNhbiBkZXRlY3QgYW55CisgKiAgICByZWdpb25zIGZvciB3aGljaCB3ZSBtaXNzZWQgYSByZWdpb24gc3BsaXQgbWVzc2FnZS48L2xpPgorICogICAgPC91bD4KKyAqICAgIAorICogVGh1cyBqdXN0IGtlZXBpbmcgdHJhY2sgb2YgYWxsIHRoZSA8Y29kZT5NRVRBPC9jb2RlPiByZWdpb25zIHBlcm1pdHMKKyAqIHBlcmlvZGljIHJlc2Nhbm5pbmcgd2hpY2ggd2lsbCBkZXRlY3QgdW5hc3NpZ25lZCByZWdpb25zIChuZXcgb3IKKyAqIG90aGVyd2lzZSkgd2l0aG91dCB0aGUgbmVlZCB0byBrZWVwIHRyYWNrIG9mIGV2ZXJ5IHJlZ2lvbi48L3A+CisgKiAKKyAqIDxwPlNvIHRoZSA8Y29kZT5ST09UPC9jb2RlPiByZWdpb24gc2Nhbm5lciBuZWVkcyB0byB3YWtlIHVwOgorICogPG9sPgorICogPGxpPndoZW4gdGhlIG1hc3RlciByZWNlaXZlcyBub3RpZmljYXRpb24gdGhhdCB0aGUgPGNvZGU+Uk9PVDwvY29kZT4KKyAqIHJlZ2lvbiBoYXMgYmVlbiBvcGVuZWQuPC9saT4KKyAqIDxsaT5wZXJpb2RpY2FsbHkgYWZ0ZXIgdGhlIGZpcnN0IHNjYW48L2xpPgorICogPC9vbD4KKyAqIAorICogVGhlIDxjb2RlPk1FVEE8L2NvZGU+ICBzY2FubmVyIG5lZWRzIHRvIHdha2UgdXA6CisgKiA8b2w+CisgKiA8bGk+d2hlbiBhIDxjb2RlPk1FVEE8L2NvZGU+IHJlZ2lvbiBjb21lcyBvbiBsaW5lPC9saT4KKyAqIDwvbGk+cGVyaW9kaWNhbGx5IHRvIHJlc2NhbiB0aGUgb25saW5lIDxjb2RlPk1FVEE8L2NvZGU+IHJlZ2lvbnM8L2xpPgorICogPC9vbD4KKyAqIAorICogPHA+QSA8Y29kZT5NRVRBPC9jb2RlPiByZWdpb24gaXMgbm90ICdvbmxpbmUnIHVudGlsIGl0IGhhcyBiZWVuIHNjYW5uZWQKKyAqIG9uY2UuCisgKi8KK2Fic3RyYWN0IGNsYXNzIEJhc2VTY2FubmVyIGV4dGVuZHMgQ2hvcmUgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhCYXNlU2Nhbm5lci5jbGFzcy5nZXROYW1lKCkpOworICAgIAorICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcm9vdFJlZ2lvbjsKKyAgcHJvdGVjdGVkIGZpbmFsIEhNYXN0ZXIgbWFzdGVyOworICAKKyAgcHJvdGVjdGVkIGJvb2xlYW4gaW5pdGlhbFNjYW5Db21wbGV0ZTsKKyAgCisgIHByb3RlY3RlZCBhYnN0cmFjdCBib29sZWFuIGluaXRpYWxTY2FuKCk7CisgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIG1haW50ZW5hbmNlU2NhbigpOworICAKKyAgLy8gd2lsbCB1c2UgdGhpcyB2YXJpYWJsZSB0byBzeW5jaHJvbml6ZSBhbmQgbWFrZSBzdXJlIHdlIGFyZW4ndCBpbnRlcnJ1cHRlZCAKKyAgLy8gbWlkLXNjYW4KKyAgZmluYWwgT2JqZWN0IHNjYW5uZXJMb2NrID0gbmV3IE9iamVjdCgpOworICAKKyAgQmFzZVNjYW5uZXIoZmluYWwgSE1hc3RlciBtYXN0ZXIsIGZpbmFsIGJvb2xlYW4gcm9vdFJlZ2lvbiwgZmluYWwgaW50IHBlcmlvZCwKKyAgICAgIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcCkgeworICAgIHN1cGVyKHBlcmlvZCwgc3RvcCk7CisgICAgdGhpcy5yb290UmVnaW9uID0gcm9vdFJlZ2lvbjsKKyAgICB0aGlzLm1hc3RlciA9IG1hc3RlcjsKKyAgICB0aGlzLmluaXRpYWxTY2FuQ29tcGxldGUgPSBmYWxzZTsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gdHJ1ZSBpZiBpbml0aWFsIHNjYW4gY29tcGxldGVkIHN1Y2Nlc3NmdWxseSAqLworICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxTY2FuQ29tcGxldGUoKSB7CisgICAgcmV0dXJuIGluaXRpYWxTY2FuQ29tcGxldGU7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBpbml0aWFsQ2hvcmUoKSB7CisgICAgcmV0dXJuIGluaXRpYWxTY2FuKCk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBjaG9yZSgpIHsKKyAgICBtYWludGVuYW5jZVNjYW4oKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcmVnaW9uIFJlZ2lvbiB0byBzY2FuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByb3RlY3RlZCB2b2lkIHNjYW5SZWdpb24oZmluYWwgTWV0YVJlZ2lvbiByZWdpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbkludGVyZmFjZSByZWdpb25TZXJ2ZXIgPSBudWxsOworICAgIGxvbmcgc2Nhbm5lcklkID0gLTFMOworICAgIExPRy5pbmZvKFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpICsgIiBzY2FubmluZyBtZXRhIHJlZ2lvbiAiICsKKyAgICAgIHJlZ2lvbi50b1N0cmluZygpKTsKKworICAgIC8vIEFycmF5IHRvIGhvbGQgbGlzdCBvZiBzcGxpdCBwYXJlbnRzIGZvdW5kLiAgU2NhbiBhZGRzIHRvIGxpc3QuICBBZnRlcgorICAgIC8vIHNjYW4gd2UgZ28gY2hlY2sgaWYgcGFyZW50cyBjYW4gYmUgcmVtb3ZlZC4KKyAgICBNYXA8SFJlZ2lvbkluZm8sIFJvd1Jlc3VsdD4gc3BsaXRQYXJlbnRzID0KKyAgICAgIG5ldyBIYXNoTWFwPEhSZWdpb25JbmZvLCBSb3dSZXN1bHQ+KCk7CisgICAgTGlzdDxieXRlIFtdPiBlbXB0eVJvd3MgPSBuZXcgQXJyYXlMaXN0PGJ5dGUgW10+KCk7CisgICAgaW50IHJvd3MgPSAwOworICAgIHRyeSB7CisgICAgICByZWdpb25TZXJ2ZXIgPSBtYXN0ZXIuY29ubmVjdGlvbi5nZXRIUmVnaW9uQ29ubmVjdGlvbihyZWdpb24uZ2V0U2VydmVyKCkpOworICAgICAgc2Nhbm5lcklkID0gcmVnaW9uU2VydmVyLm9wZW5TY2FubmVyKHJlZ2lvbi5nZXRSZWdpb25OYW1lKCksCisgICAgICAgIENPTFVNTl9GQU1JTFlfQVJSQVksIEVNUFRZX1NUQVJUX1JPVywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIFJvd1Jlc3VsdCB2YWx1ZXMgPSByZWdpb25TZXJ2ZXIubmV4dChzY2FubmVySWQpOworICAgICAgICBpZiAodmFsdWVzID09IG51bGwgfHwgdmFsdWVzLnNpemUoKSA9PSAwKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgSFJlZ2lvbkluZm8gaW5mbyA9IG1hc3Rlci5nZXRIUmVnaW9uSW5mbyh2YWx1ZXMuZ2V0Um93KCksIHZhbHVlcyk7CisgICAgICAgIGlmIChpbmZvID09IG51bGwpIHsKKyAgICAgICAgICBlbXB0eVJvd3MuYWRkKHZhbHVlcy5nZXRSb3coKSk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgU3RyaW5nIHNlcnZlck5hbWUgPSBXcml0YWJsZXMuY2VsbFRvU3RyaW5nKHZhbHVlcy5nZXQoQ09MX1NFUlZFUikpOworICAgICAgICBsb25nIHN0YXJ0Q29kZSA9IFdyaXRhYmxlcy5jZWxsVG9Mb25nKHZhbHVlcy5nZXQoQ09MX1NUQVJUQ09ERSkpOworCisgICAgICAgIC8vIE5vdGUgUmVnaW9uIGhhcyBiZWVuIGFzc2lnbmVkLgorICAgICAgICBjaGVja0Fzc2lnbmVkKGluZm8sIHNlcnZlck5hbWUsIHN0YXJ0Q29kZSk7CisgICAgICAgIGlmIChpc1NwbGl0UGFyZW50KGluZm8pKSB7CisgICAgICAgICAgc3BsaXRQYXJlbnRzLnB1dChpbmZvLCB2YWx1ZXMpOworICAgICAgICB9CisgICAgICAgIHJvd3MgKz0gMTsKKyAgICAgIH0KKyAgICAgIGlmIChyb290UmVnaW9uKSB7CisgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuc2V0TnVtTWV0YVJlZ2lvbnMocm93cyk7CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSZW1vdGVFeGNlcHRpb24pIHsKKyAgICAgICAgZSA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKChSZW1vdGVFeGNlcHRpb24pIGUpOworICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFVua25vd25TY2FubmVyRXhjZXB0aW9uKSB7CisgICAgICAgICAgLy8gUmVzZXQgc2Nhbm5lcklkIHNvIHdlIGRvIG5vdCB0cnkgY2xvc2luZyBhIHNjYW5uZXIgdGhlIG90aGVyIHNpZGUKKyAgICAgICAgICAvLyBoYXMgbG9zdCBhY2NvdW50IG9mOiBwcmV2ZW50cyBkdXBsaWNhdGVkIHN0YWNrIHRyYWNlIG91dCBvZiB0aGUgCisgICAgICAgICAgLy8gYmVsb3cgY2xvc2UgaW4gdGhlIGZpbmFsbHkuCisgICAgICAgICAgc2Nhbm5lcklkID0gLTFMOworICAgICAgICB9CisgICAgICB9CisgICAgICB0aHJvdyBlOworICAgIH0gZmluYWxseSB7CisgICAgICB0cnkgeworICAgICAgICBpZiAoc2Nhbm5lcklkICE9IC0xTCAmJiByZWdpb25TZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgIHJlZ2lvblNlcnZlci5jbG9zZShzY2FubmVySWQpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiQ2xvc2luZyBzY2FubmVyIiwKKyAgICAgICAgICAgIFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKSk7CisgICAgICB9CisgICAgfQorCisgICAgLy8gU2NhbiBpcyBmaW5pc2hlZC4KKyAgICAKKyAgICAvLyBGaXJzdCBjbGVhbiB1cCBhbnkgbWV0YSByZWdpb24gcm93cyB3aGljaCBoYWQgbnVsbCBIUmVnaW9uSW5mb3MKKyAgICBpZiAoZW1wdHlSb3dzLnNpemUoKSA+IDApIHsKKyAgICAgIExPRy53YXJuKCJGb3VuZCAiICsgZW1wdHlSb3dzLnNpemUoKSArICIgcm93cyB3aXRoIGVtcHR5IEhSZWdpb25JbmZvICIgKworICAgICAgICAid2hpbGUgc2Nhbm5pbmcgbWV0YSByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbi5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICAgIHRoaXMubWFzdGVyLmRlbGV0ZUVtcHR5TWV0YVJvd3MocmVnaW9uU2VydmVyLCByZWdpb24uZ2V0UmVnaW9uTmFtZSgpLAorICAgICAgICAgIGVtcHR5Um93cyk7CisgICAgfQorCisgICAgLy8gVGFrZSBhIGxvb2sgYXQgc3BsaXQgcGFyZW50cyB0byBzZWUgaWYgYW55IHdlIGNhbiBjbGVhbiB1cC4KKyAgICAKKyAgICBpZiAoc3BsaXRQYXJlbnRzLnNpemUoKSA+IDApIHsKKyAgICAgIGZvciAoTWFwLkVudHJ5PEhSZWdpb25JbmZvLCBSb3dSZXN1bHQ+IGUgOiBzcGxpdFBhcmVudHMuZW50cnlTZXQoKSkgeworICAgICAgICBIUmVnaW9uSW5mbyBocmkgPSBlLmdldEtleSgpOworICAgICAgICBjbGVhbnVwU3BsaXRzKHJlZ2lvbi5nZXRSZWdpb25OYW1lKCksIHJlZ2lvblNlcnZlciwgaHJpLCBlLmdldFZhbHVlKCkpOworICAgICAgfQorICAgIH0KKyAgICBMT0cuaW5mbyhUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSArICIgc2NhbiBvZiAiICsgcm93cyArCisgICAgICAiIHJvdyhzKSBvZiBtZXRhIHJlZ2lvbiAiICsgcmVnaW9uLnRvU3RyaW5nKCkgKyAiIGNvbXBsZXRlIik7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gaW5mbyBSZWdpb24gdG8gY2hlY2suCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIGlzIGEgc3BsaXQgcGFyZW50LgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGlzU3BsaXRQYXJlbnQoZmluYWwgSFJlZ2lvbkluZm8gaW5mbykgeworICAgIGlmICghaW5mby5pc1NwbGl0KCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKCFpbmZvLmlzT2ZmbGluZSgpKSB7CisgICAgICBMT0cud2FybigiUmVnaW9uIGlzIHNwbGl0IGJ1dCBub3Qgb2ZmbGluZTogIiArCisgICAgICAgIGluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qCisgICAqIElmIGRhdWdodGVycyBubyBsb25nZXIgaG9sZCByZWZlcmVuY2UgdG8gdGhlIHBhcmVudHMsIGRlbGV0ZSB0aGUgcGFyZW50LgorICAgKiBAcGFyYW0gbWV0YVJlZ2lvbk5hbWUgTWV0YSByZWdpb24gbmFtZS4KKyAgICogQHBhcmFtIHNlcnZlciBIUmVnaW9uSW50ZXJmYWNlIG9mIG1ldGEgc2VydmVyIHRvIHRhbGsgdG8gCisgICAqIEBwYXJhbSBwYXJlbnQgSFJlZ2lvbkluZm8gb2Ygc3BsaXQgcGFyZW50CisgICAqIEBwYXJhbSByb3dDb250ZW50IENvbnRlbnQgb2YgPGNvZGU+cGFyZW50PC9jb2RlPiByb3cgaW4KKyAgICogPGNvZGU+bWV0YVJlZ2lvbk5hbWU8L2NvZGU+CisgICAqIEByZXR1cm4gVHJ1ZSBpZiB3ZSByZW1vdmVkIDxjb2RlPnBhcmVudDwvY29kZT4gZnJvbSBtZXRhIHRhYmxlIGFuZCBmcm9tCisgICAqIHRoZSBmaWxlc3lzdGVtLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gY2xlYW51cFNwbGl0cyhmaW5hbCBieXRlIFtdIG1ldGFSZWdpb25OYW1lLCAKKyAgICBmaW5hbCBIUmVnaW9uSW50ZXJmYWNlIHNydnIsIGZpbmFsIEhSZWdpb25JbmZvIHBhcmVudCwKKyAgICBSb3dSZXN1bHQgcm93Q29udGVudCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBib29sZWFuIHJlc3VsdCA9IGZhbHNlOworICAgIGJvb2xlYW4gaGFzUmVmZXJlbmNlc0EgPSBoYXNSZWZlcmVuY2VzKG1ldGFSZWdpb25OYW1lLCBzcnZyLAorICAgICAgICBwYXJlbnQuZ2V0UmVnaW9uTmFtZSgpLCByb3dDb250ZW50LCBDT0xfU1BMSVRBKTsKKyAgICBib29sZWFuIGhhc1JlZmVyZW5jZXNCID0gaGFzUmVmZXJlbmNlcyhtZXRhUmVnaW9uTmFtZSwgc3J2ciwKKyAgICAgICAgcGFyZW50LmdldFJlZ2lvbk5hbWUoKSwgcm93Q29udGVudCwgQ09MX1NQTElUQik7CisgICAgaWYgKCFoYXNSZWZlcmVuY2VzQSAmJiAhaGFzUmVmZXJlbmNlc0IpIHsKKyAgICAgIExPRy5pbmZvKCJEZWxldGluZyByZWdpb24gIiArIHBhcmVudC5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSArCisgICAgICAgICIgKGVuY29kZWQ9IiArIHBhcmVudC5nZXRFbmNvZGVkTmFtZSgpICsKKyAgICAgICAgIikgYmVjYXVzZSBkYXVnaHRlciBzcGxpdHMgbm8gbG9uZ2VyIGhvbGQgcmVmZXJlbmNlcyIpOworICAgICAgSFJlZ2lvbi5kZWxldGVSZWdpb24odGhpcy5tYXN0ZXIuZnMsIHRoaXMubWFzdGVyLnJvb3RkaXIsIHBhcmVudCk7CisgICAgICBIUmVnaW9uLnJlbW92ZVJlZ2lvbkZyb21NRVRBKHNydnIsIG1ldGFSZWdpb25OYW1lLAorICAgICAgICBwYXJlbnQuZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qIAorICAgKiBDaGVja3MgaWYgYSBkYXVnaHRlciByZWdpb24gLS0gZWl0aGVyIHNwbGl0QSBvciBzcGxpdEIgLS0gc3RpbGwgaG9sZHMKKyAgICogcmVmZXJlbmNlcyB0byBwYXJlbnQuICBJZiBub3QsIHJlbW92ZXMgcmVmZXJlbmNlIHRvIHRoZSBzcGxpdCBmcm9tCisgICAqIHRoZSBwYXJlbnQgbWV0YSByZWdpb24gcm93LgorICAgKiBAcGFyYW0gbWV0YVJlZ2lvbk5hbWUgTmFtZSBvZiBtZXRhIHJlZ2lvbiB0byBsb29rIGluLgorICAgKiBAcGFyYW0gc3J2ciBXaGVyZSByZWdpb24gcmVzaWRlcy4KKyAgICogQHBhcmFtIHBhcmVudCBQYXJlbnQgcmVnaW9uIG5hbWUuIAorICAgKiBAcGFyYW0gcm93Q29udGVudCBLZXllZCBjb250ZW50IG9mIHRoZSBwYXJlbnQgcm93IGluIG1ldGEgcmVnaW9uLgorICAgKiBAcGFyYW0gc3BsaXRDb2x1bW4gQ29sdW1uIG5hbWUgb2YgZGF1Z2h0ZXIgc3BsaXQgdG8gZXhhbWluZQorICAgKiBAcmV0dXJuIFRydWUgaWYgc3RpbGwgaGFzIHJlZmVyZW5jZXMgdG8gcGFyZW50LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gaGFzUmVmZXJlbmNlcyhmaW5hbCBieXRlIFtdIG1ldGFSZWdpb25OYW1lLCAKKyAgICBmaW5hbCBIUmVnaW9uSW50ZXJmYWNlIHNydnIsIGZpbmFsIGJ5dGUgW10gcGFyZW50LAorICAgIFJvd1Jlc3VsdCByb3dDb250ZW50LCBmaW5hbCBieXRlIFtdIHNwbGl0Q29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisgICAgSFJlZ2lvbkluZm8gc3BsaXQgPQorICAgICAgV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKHJvd0NvbnRlbnQuZ2V0KHNwbGl0Q29sdW1uKSk7CisgICAgaWYgKHNwbGl0ID09IG51bGwpIHsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIFBhdGggdGFibGVkaXIgPSBuZXcgUGF0aCh0aGlzLm1hc3Rlci5yb290ZGlyLCBzcGxpdC5nZXRUYWJsZURlc2MoKS5nZXROYW1lQXNTdHJpbmcoKSk7CisgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBmYW1pbHk6IHNwbGl0LmdldFRhYmxlRGVzYygpLmdldEZhbWlsaWVzKCkpIHsKKyAgICAgIFBhdGggcCA9IFN0b3JlLmdldFN0b3JlSG9tZWRpcih0YWJsZWRpciwgc3BsaXQuZ2V0RW5jb2RlZE5hbWUoKSwKKyAgICAgICAgZmFtaWx5LmdldE5hbWUoKSk7CisgICAgICAvLyBMb29rIGZvciByZWZlcmVuY2UgZmlsZXMuICBDYWxsIGxpc3RTdGF0dXMgd2l0aCBhbiBhbm9ueW1vdXMKKyAgICAgIC8vIGluc3RhbmNlIG9mIFBhdGhGaWx0ZXIuCisgICAgICBGaWxlU3RhdHVzIFtdIHBzID0gdGhpcy5tYXN0ZXIuZnMubGlzdFN0YXR1cyhwLAorICAgICAgICAgIG5ldyBQYXRoRmlsdGVyICgpIHsKKyAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChQYXRoIHBhdGgpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIFN0b3JlRmlsZS5pc1JlZmVyZW5jZShwYXRoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICApOworCisgICAgICBpZiAocHMgIT0gbnVsbCAmJiBwcy5sZW5ndGggPiAwKSB7CisgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBpZiAocmVzdWx0KSB7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICAKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZyhzcGxpdC5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSArCisgICAgICAgICIgbm8gbG9uZ2VyIGhhcyByZWZlcmVuY2VzIHRvICIgKyBCeXRlcy50b1N0cmluZyhwYXJlbnQpKTsKKyAgICB9CisgICAgCisgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShwYXJlbnQpOworICAgIGIuZGVsZXRlKHNwbGl0Q29sdW1uKTsKKyAgICBzcnZyLmJhdGNoVXBkYXRlKG1ldGFSZWdpb25OYW1lLCBiLCAtMUwpOworICAgICAgCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIGNoZWNrQXNzaWduZWQoZmluYWwgSFJlZ2lvbkluZm8gaW5mbywKKyAgICBmaW5hbCBTdHJpbmcgc2VydmVyQWRkcmVzcywgZmluYWwgbG9uZyBzdGFydENvZGUpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN0cmluZyBzZXJ2ZXJOYW1lID0gbnVsbDsKKyAgICBpZiAoc2VydmVyQWRkcmVzcyAhPSBudWxsICYmIHNlcnZlckFkZHJlc3MubGVuZ3RoKCkgPiAwKSB7CisgICAgICBzZXJ2ZXJOYW1lID0gSFNlcnZlckluZm8uZ2V0U2VydmVyTmFtZShzZXJ2ZXJBZGRyZXNzLCBzdGFydENvZGUpOworICAgIH0KKyAgICBIU2VydmVySW5mbyBzdG9yZWRJbmZvID0gbnVsbDsKKyAgICBzeW5jaHJvbml6ZWQgKHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIpIHsKKyAgICAgIC8qCisgICAgICAgKiBXZSBkb24ndCBhc3NpZ24gcmVnaW9ucyB0aGF0IGFyZSBvZmZsaW5lLCBpbiB0cmFuc2l0aW9uIG9yIHdlcmUgb24KKyAgICAgICAqIGEgZGVhZCBzZXJ2ZXIuIFJlZ2lvbnMgdGhhdCB3ZXJlIG9uIGEgZGVhZCBzZXJ2ZXIgd2lsbCBnZXQgcmVhc3NpZ25lZAorICAgICAgICogYnkgUHJvY2Vzc1NlcnZlclNodXRkb3duCisgICAgICAgKi8KKyAgICAgIGlmIChpbmZvLmlzT2ZmbGluZSgpIHx8CisgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuCisgICAgICAgICAgICByZWdpb25Jc0luVHJhbnNpdGlvbihpbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKSB8fAorICAgICAgICAgIChzZXJ2ZXJOYW1lICE9IG51bGwgJiYgdGhpcy5tYXN0ZXIuc2VydmVyTWFuYWdlci5pc0RlYWQoc2VydmVyTmFtZSkpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGlmIChzZXJ2ZXJOYW1lICE9IG51bGwpIHsKKyAgICAgICAgc3RvcmVkSW5mbyA9IHRoaXMubWFzdGVyLnNlcnZlck1hbmFnZXIuZ2V0U2VydmVySW5mbyhzZXJ2ZXJOYW1lKTsKKyAgICAgIH0KKworICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCB0aGUgSFNlcnZlckluZm8sIHRoZW4gYWRkIGl0IHRvIHRoZSBsaXN0IG9mCisgICAgICAvLyAgdW5hc3NpZ25lZCByZWdpb25zLgorICAgICAgaWYgKHN0b3JlZEluZm8gPT0gbnVsbCkgeworICAgICAgICAvLyBUaGUgY3VycmVudCBhc3NpZ25tZW50IGlzIGludmFsaWQKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJDdXJyZW50IGFzc2lnbm1lbnQgb2YgIiArIGluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKworICAgICAgICAgICAgIiBpcyBub3QgdmFsaWQ7ICIgKyAiIFNlcnZlciAnIiArIHNlcnZlckFkZHJlc3MgKyAiJyBzdGFydENvZGU6ICIgKworICAgICAgICAgICAgc3RhcnRDb2RlICsgIiB1bmtub3duLiIpOworICAgICAgICB9CisKKyAgICAgICAgLy8gUmVjb3ZlciB0aGUgcmVnaW9uIHNlcnZlcidzIGxvZyBpZiB0aGVyZSBpcyBvbmUuCisgICAgICAgIC8vIFRoaXMgaXMgb25seSBkb25lIGZyb20gaGVyZSBpZiB3ZSBhcmUgcmVzdGFydGluZyBhbmQgdGhlcmUgaXMgc3RhbGUKKyAgICAgICAgLy8gZGF0YSBpbiB0aGUgbWV0YSByZWdpb24uIE9uY2Ugd2UgYXJlIG9uLWxpbmUsIGRlYWQgc2VydmVyIGxvZworICAgICAgICAvLyByZWNvdmVyeSBpcyBoYW5kbGVkIGJ5IGxlYXNlIGV4cGlyYXRpb24gYW5kIFByb2Nlc3NTZXJ2ZXJTaHV0ZG93bgorICAgICAgICBpZiAoIXRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuaXNJbml0aWFsTWV0YVNjYW5Db21wbGV0ZSgpICYmCisgICAgICAgICAgICBzZXJ2ZXJOYW1lICE9IG51bGwpIHsKKyAgICAgICAgICBQYXRoIGxvZ0RpciA9CisgICAgICAgICAgICBuZXcgUGF0aCh0aGlzLm1hc3Rlci5yb290ZGlyLCBITG9nLmdldEhMb2dEaXJlY3RvcnlOYW1lKHNlcnZlck5hbWUpKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKG1hc3Rlci5mcy5leGlzdHMobG9nRGlyKSkgeworICAgICAgICAgICAgICB0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLnNwbGl0TG9nTG9jay5sb2NrKCk7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgSExvZy5zcGxpdExvZyhtYXN0ZXIucm9vdGRpciwgbG9nRGlyLCBtYXN0ZXIuZnMsCisgICAgICAgICAgICAgICAgICAgIG1hc3Rlci5nZXRDb25maWd1cmF0aW9uKCkpOworICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuc3BsaXRMb2dMb2NrLnVubG9jaygpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKCJTcGxpdCAiICsgbG9nRGlyLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIExPRy53YXJuKCJ1bmFibGUgdG8gc3BsaXQgcmVnaW9uIHNlcnZlciBsb2cgYmVjYXVzZTogIiwgZSk7CisgICAgICAgICAgICB0aHJvdyBlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBOb3cgZ2V0IHRoZSByZWdpb24gYXNzaWduZWQKKyAgICAgICAgdGhpcy5tYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRVbmFzc2lnbmVkKGluZm8sIHRydWUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBOb3RpZnkgdGhlIHRocmVhZCB0byBkaWUgYXQgdGhlIGVuZCBvZiBpdHMgbmV4dCBydW4KKyAgICovCisgIHB1YmxpYyB2b2lkIGludGVycnVwdElmQWxpdmUoKSB7CisgICAgc3luY2hyb25pemVkKHNjYW5uZXJMb2NrKXsKKyAgICAgIGlmIChpc0FsaXZlKCkpIHsKKyAgICAgICAgc3VwZXIuaW50ZXJydXB0KCk7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvQ2hhbmdlVGFibGVTdGF0ZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0NoYW5nZVRhYmxlU3RhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iN2MwOWY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0NoYW5nZVRhYmxlU3RhdGUuamF2YQpAQCAtMCwwICsxLDEzMyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKiogSW5zdGFudGlhdGVkIHRvIGVuYWJsZSBvciBkaXNhYmxlIGEgdGFibGUgKi8KK2NsYXNzIENoYW5nZVRhYmxlU3RhdGUgZXh0ZW5kcyBUYWJsZU9wZXJhdGlvbiB7CisgIHByaXZhdGUgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKHRoaXMuZ2V0Q2xhc3MoKSk7CisgIHByaXZhdGUgYm9vbGVhbiBvbmxpbmU7CisKKyAgcHJvdGVjdGVkIGZpbmFsIE1hcDxTdHJpbmcsIEhhc2hTZXQ8SFJlZ2lvbkluZm8+PiBzZXJ2ZWRSZWdpb25zID0KKyAgICBuZXcgSGFzaE1hcDxTdHJpbmcsIEhhc2hTZXQ8SFJlZ2lvbkluZm8+PigpOworICAKKyAgcHJvdGVjdGVkIGxvbmcgbG9ja2lkOworCisgIENoYW5nZVRhYmxlU3RhdGUoZmluYWwgSE1hc3RlciBtYXN0ZXIsIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLCAKKyAgICBmaW5hbCBib29sZWFuIG9uTGluZSkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIobWFzdGVyLCB0YWJsZU5hbWUpOworICAgIHRoaXMub25saW5lID0gb25MaW5lOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NTY2FuSXRlbShTdHJpbmcgc2VydmVyTmFtZSwgSFJlZ2lvbkluZm8gaW5mbykgeworICAgICAgCisgICAgaWYgKGlzQmVpbmdTZXJ2ZWQoc2VydmVyTmFtZSkpIHsKKyAgICAgIEhhc2hTZXQ8SFJlZ2lvbkluZm8+IHJlZ2lvbnMgPSBzZXJ2ZWRSZWdpb25zLmdldChzZXJ2ZXJOYW1lKTsKKyAgICAgIGlmIChyZWdpb25zID09IG51bGwpIHsKKyAgICAgICAgcmVnaW9ucyA9IG5ldyBIYXNoU2V0PEhSZWdpb25JbmZvPigpOworICAgICAgfQorICAgICAgcmVnaW9ucy5hZGQoaW5mbyk7CisgICAgICBzZXJ2ZWRSZWdpb25zLnB1dChzZXJ2ZXJOYW1lLCByZWdpb25zKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgcG9zdFByb2Nlc3NNZXRhKE1ldGFSZWdpb24gbSwgSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gUHJvY2VzcyByZWdpb25zIG5vdCBiZWluZyBzZXJ2ZWQKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygicHJvY2Vzc2luZyB1bnNlcnZlZCByZWdpb25zIik7CisgICAgfQorICAgIGZvciAoSFJlZ2lvbkluZm8gaTogdW5zZXJ2ZWRSZWdpb25zKSB7CisgICAgICBpZiAoaS5pc09mZmxpbmUoKSAmJiBpLmlzU3BsaXQoKSkgeworICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIlNraXBwaW5nIHJlZ2lvbiAiICsgaS50b1N0cmluZygpICsKKyAgICAgICAgICAgICAgIiBiZWNhdXNlIGl0IGlzIG9mZmxpbmUgYmVjYXVzZSBpdCBoYXMgYmVlbiBzcGxpdCIpOworICAgICAgICB9CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICAvLyBVcGRhdGUgbWV0YSB0YWJsZQorICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShpLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICB1cGRhdGVSZWdpb25JbmZvKGIsIGkpOworICAgICAgYi5kZWxldGUoQ09MX1NFUlZFUik7CisgICAgICBiLmRlbGV0ZShDT0xfU1RBUlRDT0RFKTsKKyAgICAgIHNlcnZlci5iYXRjaFVwZGF0ZShtLmdldFJlZ2lvbk5hbWUoKSwgYiwgLTFMKTsKKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoIlVwZGF0ZWQgY29sdW1ucyBpbiByb3c6ICIgKyBpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgIH0KKworICAgICAgc3luY2hyb25pemVkIChtYXN0ZXIucmVnaW9uTWFuYWdlcikgeworICAgICAgICBpZiAob25saW5lKSB7CisgICAgICAgICAgLy8gQnJpbmcgb2ZmbGluZSByZWdpb25zIG9uLWxpbmUKKyAgICAgICAgICBpZiAoIW1hc3Rlci5yZWdpb25NYW5hZ2VyLnJlZ2lvbklzT3BlbmluZyhpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKSkgeworICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc2V0VW5hc3NpZ25lZChpLCBmYWxzZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFByZXZlbnQgcmVnaW9uIGZyb20gZ2V0dGluZyBhc3NpZ25lZC4KKyAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5yZW1vdmVSZWdpb24oaSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBQcm9jZXNzIHJlZ2lvbnMgY3VycmVudGx5IGJlaW5nIHNlcnZlZAorICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJwcm9jZXNzaW5nIHJlZ2lvbnMgY3VycmVudGx5IGJlaW5nIHNlcnZlZCIpOworICAgIH0KKyAgICBzeW5jaHJvbml6ZWQgKG1hc3Rlci5yZWdpb25NYW5hZ2VyKSB7CisgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIEhhc2hTZXQ8SFJlZ2lvbkluZm8+PiBlOiBzZXJ2ZWRSZWdpb25zLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgU3RyaW5nIHNlcnZlck5hbWUgPSBlLmdldEtleSgpOworICAgICAgICBpZiAob25saW5lKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJBbHJlYWR5IG9ubGluZSIpOworICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWxyZWFkeSBiZWluZyBzZXJ2ZWQKKyAgICAgICAgfQorCisgICAgICAgIC8vIENhdXNlIHJlZ2lvbnMgYmVpbmcgc2VydmVkIHRvIGJlIHRha2VuIG9mZi1saW5lIGFuZCBkaXNhYmxlZAorICAgICAgICBmb3IgKEhSZWdpb25JbmZvIGk6IGUuZ2V0VmFsdWUoKSkgeworICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgTE9HLmRlYnVnKCJhZGRpbmcgcmVnaW9uICIgKyBpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpICsgIiB0byBraWxsIGxpc3QiKTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gdGhpcyBtYXJrcyB0aGUgcmVnaW9ucyB0byBiZSBjbG9zZWQKKyAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRDbG9zaW5nKHNlcnZlck5hbWUsIGksIHRydWUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHNlcnZlZFJlZ2lvbnMuY2xlYXIoKTsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIHVwZGF0ZVJlZ2lvbkluZm8oZmluYWwgQmF0Y2hVcGRhdGUgYiwgZmluYWwgSFJlZ2lvbkluZm8gaSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpLnNldE9mZmxpbmUoIW9ubGluZSk7CisgICAgYi5wdXQoQ09MX1JFR0lPTklORk8sIFdyaXRhYmxlcy5nZXRCeXRlcyhpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Db2x1bW5PcGVyYXRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Db2x1bW5PcGVyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZjU3MThlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0NvbHVtbk9wZXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKKworYWJzdHJhY3QgY2xhc3MgQ29sdW1uT3BlcmF0aW9uIGV4dGVuZHMgVGFibGVPcGVyYXRpb24geworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkpOworICAKKyAgcHJvdGVjdGVkIENvbHVtbk9wZXJhdGlvbihmaW5hbCBITWFzdGVyIG1hc3RlciwgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKG1hc3RlciwgdGFibGVOYW1lKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzU2Nhbkl0ZW0oU3RyaW5nIHNlcnZlck5hbWUsIGZpbmFsIEhSZWdpb25JbmZvIGluZm8pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzRW5hYmxlZChpbmZvKSkgeworICAgICAgdGhyb3cgbmV3IFRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24odGFibGVOYW1lKTsKKyAgICB9CisgIH0KKworICBwcm90ZWN0ZWQgdm9pZCB1cGRhdGVSZWdpb25JbmZvKEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyLCBieXRlIFtdIHJlZ2lvbk5hbWUsCisgICAgSFJlZ2lvbkluZm8gaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCYXRjaFVwZGF0ZSBiID0gbmV3IEJhdGNoVXBkYXRlKGkuZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICBiLnB1dChDT0xfUkVHSU9OSU5GTywgV3JpdGFibGVzLmdldEJ5dGVzKGkpKTsKKyAgICBzZXJ2ZXIuYmF0Y2hVcGRhdGUocmVnaW9uTmFtZSwgYiwgLTFMKTsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygidXBkYXRlZCBjb2x1bW5zIGluIHJvdzogIiArIGkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0RlbGV0ZUNvbHVtbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0RlbGV0ZUNvbHVtbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1YjhjYWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvRGVsZXRlQ29sdW1uLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5TdG9yZTsKKworLyoqIEluc3RhbnRpYXRlZCB0byByZW1vdmUgYSBjb2x1bW4gZmFtaWx5IGZyb20gYSB0YWJsZSAqLworY2xhc3MgRGVsZXRlQ29sdW1uIGV4dGVuZHMgQ29sdW1uT3BlcmF0aW9uIHsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdIGNvbHVtbk5hbWU7CisKKyAgRGVsZXRlQ29sdW1uKGZpbmFsIEhNYXN0ZXIgbWFzdGVyLCBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgCisgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW5OYW1lKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcihtYXN0ZXIsIHRhYmxlTmFtZSk7CisgICAgdGhpcy5jb2x1bW5OYW1lID0gY29sdW1uTmFtZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBwb3N0UHJvY2Vzc01ldGEoTWV0YVJlZ2lvbiBtLCBIUmVnaW9uSW50ZXJmYWNlIHNlcnZlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKEhSZWdpb25JbmZvIGk6IHVuc2VydmVkUmVnaW9ucykgeworICAgICAgaS5nZXRUYWJsZURlc2MoKS5yZW1vdmVGYW1pbHkoY29sdW1uTmFtZSk7CisgICAgICB1cGRhdGVSZWdpb25JbmZvKHNlcnZlciwgbS5nZXRSZWdpb25OYW1lKCksIGkpOworICAgICAgLy8gRGVsZXRlIHRoZSBkaXJlY3RvcmllcyB1c2VkIGJ5IHRoZSBjb2x1bW4KKyAgICAgIFBhdGggdGFibGVkaXIgPQorICAgICAgICBuZXcgUGF0aCh0aGlzLm1hc3Rlci5yb290ZGlyLCBpLmdldFRhYmxlRGVzYygpLmdldE5hbWVBc1N0cmluZygpKTsKKyAgICAgIHRoaXMubWFzdGVyLmZzLmRlbGV0ZShTdG9yZS5nZXRTdG9yZUhvbWVkaXIodGFibGVkaXIsIGkuZ2V0RW5jb2RlZE5hbWUoKSwKKyAgICAgICAgdGhpcy5jb2x1bW5OYW1lKSwgdHJ1ZSk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL0hNYXN0ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9ITWFzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTUwNjlkYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9ITWFzdGVyLmphdmEKQEAgLTAsMCArMSwxMDc0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5NYW5hZ2VtZW50RmFjdG9yeTsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5SdW50aW1lTVhCZWFuOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5EZWxheVF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkxpbmtlZEJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuRGlzdHJpYnV0ZWRGaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmRmcy5GU0NvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVySW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyTG9hZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU3RvcmVLZXk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Mb2NhbEhCYXNlQ2x1c3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5NYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlZ2lvbkhpc3RvcmlhbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlRhYmxlRXhpc3RzRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TZXJ2ZXJDb25uZWN0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TZXJ2ZXJDb25uZWN0aW9uTWFuYWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IQmFzZVJQQzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSEJhc2VSUENQcm90b2NvbFZlcnNpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhCYXNlU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5ITWFzdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5ITWFzdGVyUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3Rlci5tZXRyaWNzLk1hc3Rlck1ldHJpY3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkZTVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5JbmZvU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuUGFpcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlNsZWVwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyLlpvb0tlZXBlcldyYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uTWFwV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uVGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pcGMuUmVtb3RlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuU3RyaW5nVXRpbHM7CisKKy8qKgorICogSE1hc3RlciBpcyB0aGUgIm1hc3RlciBzZXJ2ZXIiIGZvciBhIEhCYXNlLgorICogVGhlcmUgaXMgb25seSBvbmUgSE1hc3RlciBmb3IgYSBzaW5nbGUgSEJhc2UgZGVwbG95bWVudC4KKyAqIAorICogTk9URTogVGhpcyBjbGFzcyBleHRlbmRzIFRocmVhZCByYXRoZXIgdGhhbiBDaG9yZSBiZWNhdXNlIHRoZSBzbGVlcCB0aW1lCisgKiBjYW4gYmUgaW50ZXJydXB0ZWQgd2hlbiB0aGVyZSBpcyBzb21ldGhpbmcgdG8gZG8sIHJhdGhlciB0aGFuIHRoZSBDaG9yZQorICogc2xlZXAgdGltZSB3aGljaCBpcyBpbnZhcmlhbnQuCisgKi8KK3B1YmxpYyBjbGFzcyBITWFzdGVyIGV4dGVuZHMgVGhyZWFkIGltcGxlbWVudHMgSENvbnN0YW50cywgSE1hc3RlckludGVyZmFjZSwgCisgIEhNYXN0ZXJSZWdpb25JbnRlcmZhY2UgeworCisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coSE1hc3Rlci5jbGFzcy5nZXROYW1lKCkpOworCisgIHB1YmxpYyBsb25nIGdldFByb3RvY29sVmVyc2lvbihTdHJpbmcgcHJvdG9jb2wsIGxvbmcgY2xpZW50VmVyc2lvbikgeworICAgIHJldHVybiBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi52ZXJzaW9uSUQ7CisgIH0KKworICAvLyBXZSBzdGFydCBvdXQgd2l0aCBjbG9zZWQgZmxhZyBvbi4gIFVzaW5nIEF0b21pY0Jvb2xlYW4gcmF0aGVyIHRoYW4KKyAgLy8gcGxhaW4gYm9vbGVhbiBiZWNhdXNlIHdhbnQgdG8gcGFzcyBhIHJlZmVyZW5jZSB0byBzdXBwb3J0aW5nIHRocmVhZHMKKyAgLy8gc3RhcnRlZCBoZXJlIGluIEhNYXN0ZXIgcmF0aGVyIHRoYW4gaGF2ZSB0aGVtIGhhdmUgdG8ga25vdyBhYm91dCB0aGUKKyAgLy8gaG9zdGluZyBjbGFzcworICB2b2xhdGlsZSBBdG9taWNCb29sZWFuIGNsb3NlZCA9IG5ldyBBdG9taWNCb29sZWFuKHRydWUpOworICB2b2xhdGlsZSBBdG9taWNCb29sZWFuIHNodXRkb3duUmVxdWVzdGVkID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworICB2b2xhdGlsZSBib29sZWFuIGZzT2sgPSB0cnVlOworICBmaW5hbCBQYXRoIHJvb3RkaXI7CisgIHByaXZhdGUgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisgIGZpbmFsIEZpbGVTeXN0ZW0gZnM7CisgIGZpbmFsIFJhbmRvbSByYW5kOworICBmaW5hbCBpbnQgdGhyZWFkV2FrZUZyZXF1ZW5jeTsgCisgIGZpbmFsIGludCBudW1SZXRyaWVzOworICBmaW5hbCBsb25nIG1heFJlZ2lvbk9wZW5UaW1lOworICBmaW5hbCBpbnQgbGVhc2VUaW1lb3V0OworICBwcml2YXRlIGZpbmFsIFpvb0tlZXBlcldyYXBwZXIgem9vS2VlcGVyV3JhcHBlcjsKKyAgcHJpdmF0ZSBmaW5hbCBaS01hc3RlckFkZHJlc3NXYXRjaGVyIHprTWFzdGVyQWRkcmVzc1dhdGNoZXI7CisKKyAgdm9sYXRpbGUgRGVsYXlRdWV1ZTxSZWdpb25TZXJ2ZXJPcGVyYXRpb24+IGRlbGF5ZWRUb0RvUXVldWUgPQorICAgIG5ldyBEZWxheVF1ZXVlPFJlZ2lvblNlcnZlck9wZXJhdGlvbj4oKTsKKyAgdm9sYXRpbGUgQmxvY2tpbmdRdWV1ZTxSZWdpb25TZXJ2ZXJPcGVyYXRpb24+IHRvRG9RdWV1ZSA9CisgICAgbmV3IExpbmtlZEJsb2NraW5nUXVldWU8UmVnaW9uU2VydmVyT3BlcmF0aW9uPigpOworCisgIHByaXZhdGUgZmluYWwgSEJhc2VTZXJ2ZXIgc2VydmVyOworICBwcml2YXRlIGZpbmFsIEhTZXJ2ZXJBZGRyZXNzIGFkZHJlc3M7CisKKyAgZmluYWwgU2VydmVyQ29ubmVjdGlvbiBjb25uZWN0aW9uOworCisgIGZpbmFsIGludCBtZXRhUmVzY2FuSW50ZXJ2YWw7CisgIAorICAvLyBBIFNsZWVwZXIgdGhhdCBzbGVlcHMgZm9yIHRocmVhZFdha2VGcmVxdWVuY3kKKyAgcHJpdmF0ZSBmaW5hbCBTbGVlcGVyIHNsZWVwZXI7CisgIAorICAvLyBEZWZhdWx0IGFjY2VzcyBzbyBhY2Nlc2libGUgZnJvbSB1bml0IHRlc3RzLiBNQVNURVIgaXMgbmFtZSBvZiB0aGUgd2ViYXBwCisgIC8vIGFuZCB0aGUgYXR0cmlidXRlIG5hbWUgdXNlZCBzdHVmZmluZyB0aGlzIGluc3RhbmNlIGludG8gd2ViIGNvbnRleHQuCisgIEluZm9TZXJ2ZXIgaW5mb1NlcnZlcjsKKyAgCisgIC8qKiBOYW1lIG9mIG1hc3RlciBzZXJ2ZXIgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFTVEVSID0gIm1hc3RlciI7CisKKyAgLyoqIEByZXR1cm4gSW5mb1NlcnZlciBvYmplY3QgKi8KKyAgcHVibGljIEluZm9TZXJ2ZXIgZ2V0SW5mb1NlcnZlcigpIHsKKyAgICByZXR1cm4gaW5mb1NlcnZlcjsKKyAgfQorCisgIFNlcnZlck1hbmFnZXIgc2VydmVyTWFuYWdlcjsKKyAgUmVnaW9uTWFuYWdlciByZWdpb25NYW5hZ2VyOworICAKKyAgcHJpdmF0ZSBNYXN0ZXJNZXRyaWNzIG1ldHJpY3M7CisKKyAgLyoqIAorICAgKiBCdWlsZCB0aGUgSE1hc3RlciBvdXQgb2YgYSByYXcgY29uZmlndXJhdGlvbiBpdGVtLgorICAgKiBAcGFyYW0gY29uZiBjb25maWd1cmF0aW9uCisgICAqIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSE1hc3RlcihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBmaW5kIG91dCBvdXIgYWRkcmVzcy4gSWYgaXQncyBzZXQgaW4gY29uZmlnLCB1c2UgdGhhdCwgb3RoZXJ3aXNlIGxvb2sgaXQKKyAgICAvLyB1cCBpbiBETlMuCisgICAgU3RyaW5nIGFkZHJlc3NTdHIgPSBjb25mLmdldChNQVNURVJfQUREUkVTUyk7CisgICAgaWYgKGFkZHJlc3NTdHIgPT0gbnVsbCkgeworICAgICAgYWRkcmVzc1N0ciA9IGNvbmYuZ2V0KE1BU1RFUl9IT1NUX05BTUUpOworICAgICAgaWYgKGFkZHJlc3NTdHIgPT0gbnVsbCkgeworICAgICAgICBhZGRyZXNzU3RyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCkuZ2V0Q2Fub25pY2FsSG9zdE5hbWUoKTsKKyAgICAgIH0KKyAgICAgIGFkZHJlc3NTdHIgKz0gIjoiOworICAgICAgYWRkcmVzc1N0ciArPSBjb25mLmdldCgiaGJhc2UubWFzdGVyLnBvcnQiLCBJbnRlZ2VyLnRvU3RyaW5nKERFRkFVTFRfTUFTVEVSX1BPUlQpKTsKKyAgICB9CisgICAgSFNlcnZlckFkZHJlc3MgYWRkcmVzcyA9IG5ldyBIU2VydmVyQWRkcmVzcyhhZGRyZXNzU3RyKTsKKyAgICBMT0cuaW5mbygiTXkgYWRkcmVzcyBpcyAiICsgYWRkcmVzcyk7CisKKyAgICB0aGlzLmNvbmYgPSBjb25mOworICAgIHRoaXMucm9vdGRpciA9IG5ldyBQYXRoKGNvbmYuZ2V0KEhCQVNFX0RJUikpOworICAgIHRyeSB7CisgICAgICBGU1V0aWxzLnZhbGlkYXRlUm9vdFBhdGgodGhpcy5yb290ZGlyKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoIk5vdCBzdGFydGluZyBITWFzdGVyIGJlY2F1c2UgdGhlIHJvb3QgZGlyZWN0b3J5IHBhdGggJyIgKworICAgICAgICAgIHRoaXMucm9vdGRpciArICInIGlzIG5vdCB2YWxpZC4gQ2hlY2sgdGhlIHNldHRpbmcgb2YgdGhlIiArCisgICAgICAgICAgIiBjb25maWd1cmF0aW9uIHBhcmFtZXRlciAnIiArIEhCQVNFX0RJUiArICInIiwgZSk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgICB0aGlzLnRocmVhZFdha2VGcmVxdWVuY3kgPSBjb25mLmdldEludChUSFJFQURfV0FLRV9GUkVRVUVOQ1ksIDEwICogMTAwMCk7CisgICAgLy8gVGhlIGZpbGVzeXN0ZW0gaGJhc2Ugd2FudHMgdG8gdXNlIGlzIHByb2JhYmx5IG5vdCB3aGF0IGlzIHNldCBpbnRvCisgICAgLy8gZnMuZGVmYXVsdC5uYW1lOyBpdHMgdmFsdWUgaXMgcHJvYmFibHkgdGhlIGRlZmF1bHQuCisgICAgdGhpcy5jb25mLnNldCgiZnMuZGVmYXVsdC5uYW1lIiwgdGhpcy5yb290ZGlyLnRvU3RyaW5nKCkpOworICAgIHRoaXMuZnMgPSBGaWxlU3lzdGVtLmdldChjb25mKTsKKyAgICBpZiAodGhpcy5mcyBpbnN0YW5jZW9mIERpc3RyaWJ1dGVkRmlsZVN5c3RlbSkgeworICAgICAgLy8gTWFrZSBzdXJlIGRmcyBpcyBub3QgaW4gc2FmZSBtb2RlCisgICAgICBTdHJpbmcgbWVzc2FnZSA9ICJXYWl0aW5nIGZvciBkZnMgdG8gZXhpdCBzYWZlIG1vZGUuLi4iOworICAgICAgd2hpbGUgKCgoRGlzdHJpYnV0ZWRGaWxlU3lzdGVtKSBmcykuc2V0U2FmZU1vZGUoCisgICAgICAgICAgRlNDb25zdGFudHMuU2FmZU1vZGVBY3Rpb24uU0FGRU1PREVfR0VUKSkgeworICAgICAgICBMT0cuaW5mbyhtZXNzYWdlKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAodGhpcy50aHJlYWRXYWtlRnJlcXVlbmN5KTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vY29udGludWUKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICB0aGlzLmNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLCB0aGlzLnJvb3RkaXIudG9TdHJpbmcoKSk7CisgICAgdGhpcy5yYW5kID0gbmV3IFJhbmRvbSgpOworCisgICAgdHJ5IHsKKyAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgaGJhc2Ugcm9vdCBkaXJlY3RvcnkgZXhpc3RzIQorICAgICAgaWYgKCFmcy5leGlzdHMocm9vdGRpcikpIHsKKyAgICAgICAgZnMubWtkaXJzKHJvb3RkaXIpOyAKKyAgICAgICAgRlNVdGlscy5zZXRWZXJzaW9uKGZzLCByb290ZGlyKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEZTVXRpbHMuY2hlY2tWZXJzaW9uKGZzLCByb290ZGlyLCB0cnVlKTsKKyAgICAgIH0KKworICAgICAgLy8gTWFrZSBzdXJlIHRoZSByb290IHJlZ2lvbiBkaXJlY3RvcnkgZXhpc3RzIQorICAgICAgaWYgKCFGU1V0aWxzLnJvb3RSZWdpb25FeGlzdHMoZnMsIHJvb3RkaXIpKSB7CisgICAgICAgIGJvb3RzdHJhcCgpOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiTm90IHN0YXJ0aW5nIEhNYXN0ZXIgYmVjYXVzZToiLCBlKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorCisgICAgdGhpcy5udW1SZXRyaWVzID0gIGNvbmYuZ2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCAyKTsKKyAgICB0aGlzLm1heFJlZ2lvbk9wZW5UaW1lID0KKyAgICAgIGNvbmYuZ2V0TG9uZygiaGJhc2UuaGJhc2VtYXN0ZXIubWF4cmVnaW9ub3BlbiIsIDEyMCAqIDEwMDApOworICAgIHRoaXMubGVhc2VUaW1lb3V0ID0gY29uZi5nZXRJbnQoImhiYXNlLm1hc3Rlci5sZWFzZS5wZXJpb2QiLCAxMjAgKiAxMDAwKTsKKyAgICAKKyAgICB0aGlzLnNlcnZlciA9IEhCYXNlUlBDLmdldFNlcnZlcih0aGlzLCBhZGRyZXNzLmdldEJpbmRBZGRyZXNzKCksCisgICAgICAgIGFkZHJlc3MuZ2V0UG9ydCgpLCBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmhhbmRsZXIuY291bnQiLCAxMCksCisgICAgICAgIGZhbHNlLCBjb25mKTsKKworICAgIC8vICBUaGUgcnBjLXNlcnZlciBwb3J0IGNhbiBiZSBlcGhlbWVyYWwuLi4gZW5zdXJlIHdlIGhhdmUgdGhlIGNvcnJlY3QgaW5mbworICAgIHRoaXMuYWRkcmVzcyA9IG5ldyBIU2VydmVyQWRkcmVzcyhzZXJ2ZXIuZ2V0TGlzdGVuZXJBZGRyZXNzKCkpOworCisgICAgdGhpcy5jb25uZWN0aW9uID0gU2VydmVyQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKTsKKworICAgIHRoaXMubWV0YVJlc2NhbkludGVydmFsID0KKyAgICAgIGNvbmYuZ2V0SW50KCJoYmFzZS5tYXN0ZXIubWV0YS50aHJlYWQucmVzY2FuZnJlcXVlbmN5IiwgNjAgKiAxMDAwKTsKKworICAgIHRoaXMuc2xlZXBlciA9IG5ldyBTbGVlcGVyKHRoaXMudGhyZWFkV2FrZUZyZXF1ZW5jeSwgdGhpcy5jbG9zZWQpOworICAgIAorICAgIHpvb0tlZXBlcldyYXBwZXIgPSBuZXcgWm9vS2VlcGVyV3JhcHBlcihjb25mKTsKKyAgICB6a01hc3RlckFkZHJlc3NXYXRjaGVyID0gbmV3IFpLTWFzdGVyQWRkcmVzc1dhdGNoZXIoem9vS2VlcGVyV3JhcHBlcik7CisgICAgc2VydmVyTWFuYWdlciA9IG5ldyBTZXJ2ZXJNYW5hZ2VyKHRoaXMpOworICAgIHJlZ2lvbk1hbmFnZXIgPSBuZXcgUmVnaW9uTWFuYWdlcih0aGlzKTsKKworICAgIHdyaXRlQWRkcmVzc1RvWm9vS2VlcGVyKCk7CisKKyAgICAvLyBXZSdyZSBhbG1vc3Qgb3BlbiBmb3IgYnVzaW5lc3MKKyAgICB0aGlzLmNsb3NlZC5zZXQoZmFsc2UpOworICAgIExPRy5pbmZvKCJITWFzdGVyIGluaXRpYWxpemVkIG9uICIgKyB0aGlzLmFkZHJlc3MudG9TdHJpbmcoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgd3JpdGVBZGRyZXNzVG9ab29LZWVwZXIoKSB7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIHprTWFzdGVyQWRkcmVzc1dhdGNoZXIud2FpdEZvck1hc3RlckFkZHJlc3NBdmFpbGFiaWxpdHkoKTsKKyAgICAgIGlmICh6b29LZWVwZXJXcmFwcGVyLndyaXRlTWFzdGVyQWRkcmVzcyhhZGRyZXNzKSkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGJvb3RzdHJhcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTE9HLmluZm8oIkJPT1RTVFJBUDogY3JlYXRpbmcgUk9PVCBhbmQgZmlyc3QgTUVUQSByZWdpb25zIik7CisgICAgdHJ5IHsKKyAgICAgIEhSZWdpb24gcm9vdCA9IEhSZWdpb24uY3JlYXRlSFJlZ2lvbihIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8sCisgICAgICAgIHRoaXMucm9vdGRpciwgdGhpcy5jb25mKTsKKyAgICAgIEhSZWdpb24gbWV0YSA9IEhSZWdpb24uY3JlYXRlSFJlZ2lvbihIUmVnaW9uSW5mby5GSVJTVF9NRVRBX1JFR0lPTklORk8sCisgICAgICAgIHRoaXMucm9vdGRpciwgdGhpcy5jb25mKTsKKworICAgICAgLy8gQWRkIGZpcnN0IHJlZ2lvbiBmcm9tIHRoZSBNRVRBIHRhYmxlIHRvIHRoZSBST09UIHJlZ2lvbi4KKyAgICAgIEhSZWdpb24uYWRkUmVnaW9uVG9NRVRBKHJvb3QsIG1ldGEpOworICAgICAgcm9vdC5jbG9zZSgpOworICAgICAgcm9vdC5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgbWV0YS5jbG9zZSgpOworICAgICAgbWV0YS5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUgPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZSk7CisgICAgICBMT0cuZXJyb3IoImJvb3RzdHJhcCIsIGUpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ2hlY2tzIHRvIHNlZSBpZiB0aGUgZmlsZSBzeXN0ZW0gaXMgc3RpbGwgYWNjZXNzaWJsZS4KKyAgICogSWYgbm90LCBzZXRzIGNsb3NlZAorICAgKiBAcmV0dXJuIGZhbHNlIGlmIGZpbGUgc3lzdGVtIGlzIG5vdCBhdmFpbGFibGUKKyAgICovCisgIHByb3RlY3RlZCBib29sZWFuIGNoZWNrRmlsZVN5c3RlbSgpIHsKKyAgICBpZiAoZnNPaykgeworICAgICAgdHJ5IHsKKyAgICAgICAgRlNVdGlscy5jaGVja0ZpbGVTeXN0ZW1BdmFpbGFibGUoZnMpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuZmF0YWwoIlNodXR0aW5nIGRvd24gSEJhc2UgY2x1c3RlcjogZmlsZSBzeXN0ZW0gbm90IGF2YWlsYWJsZSIsIGUpOworICAgICAgICBjbG9zZWQuc2V0KHRydWUpOworICAgICAgICBmc09rID0gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmc09rOworICB9CisKKyAgLyoqIEByZXR1cm4gSFNlcnZlckFkZHJlc3Mgb2YgdGhlIG1hc3RlciBzZXJ2ZXIgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzIGdldE1hc3RlckFkZHJlc3MoKSB7CisgICAgcmV0dXJuIGFkZHJlc3M7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIEhiYXNlIHJvb3QgZGlyLgorICAgKi8KKyAgcHVibGljIFBhdGggZ2V0Um9vdERpcigpIHsKKyAgICByZXR1cm4gdGhpcy5yb290ZGlyOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmVhZC1vbmx5IG1hcCBvZiBzZXJ2ZXJzIHRvIHNlcnZlcmluZm8uCisgICAqLworICBwdWJsaWMgTWFwPFN0cmluZywgSFNlcnZlckluZm8+IGdldFNlcnZlcnNUb1NlcnZlckluZm8oKSB7CisgICAgcmV0dXJuIHNlcnZlck1hbmFnZXIuZ2V0U2VydmVyc1RvU2VydmVySW5mbygpOworICB9CisKKyAgcHVibGljIE1hcDxIU2VydmVyQWRkcmVzcywgSFNlcnZlckluZm8+IGdldFNlcnZlckFkZHJlc3NUb1NlcnZlckluZm8oKSB7CisgICAgcmV0dXJuIHNlcnZlck1hbmFnZXIuZ2V0U2VydmVyQWRkcmVzc1RvU2VydmVySW5mbygpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmVhZC1vbmx5IG1hcCBvZiBzZXJ2ZXJzIHRvIGxvYWQuCisgICAqLworICBwdWJsaWMgTWFwPFN0cmluZywgSFNlcnZlckxvYWQ+IGdldFNlcnZlcnNUb0xvYWQoKSB7CisgICAgcmV0dXJuIHNlcnZlck1hbmFnZXIuZ2V0U2VydmVyc1RvTG9hZCgpOworICB9CisgIAorICAvKiogQHJldHVybiBUaGUgYXZlcmFnZSBsb2FkICovCisgIHB1YmxpYyBkb3VibGUgZ2V0QXZlcmFnZUxvYWQoKSB7CisgICAgcmV0dXJuIHNlcnZlck1hbmFnZXIuZ2V0QXZlcmFnZUxvYWQoKTsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gdGhlIG51bWJlciBvZiByZWdpb25zIG9uIGZpbGVzeXN0ZW0gKi8KKyAgcHVibGljIGludCBjb3VudFJlZ2lvbnNPbkZTKCkgeworICAgIHRyeSB7CisgICAgICByZXR1cm4gcmVnaW9uTWFuYWdlci5jb3VudFJlZ2lvbnNPbkZTKCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLndhcm4oIkdldCBjb3VudCBvZiBSZWdpb25zIG9uIEZpbGVTeXN0ZW0gZXJyb3IgOiAiICsgCisgICAgICAgICAgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICB9CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gTG9jYXRpb24gb2YgdGhlIDxjb2RlPi1ST09ULTwvY29kZT4gcmVnaW9uLgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzIGdldFJvb3RSZWdpb25Mb2NhdGlvbigpIHsKKyAgICBIU2VydmVyQWRkcmVzcyByb290U2VydmVyID0gbnVsbDsKKyAgICBpZiAoIXNodXRkb3duUmVxdWVzdGVkLmdldCgpICYmICFjbG9zZWQuZ2V0KCkpIHsKKyAgICAgIHJvb3RTZXJ2ZXIgPSByZWdpb25NYW5hZ2VyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpOworICAgIH0KKyAgICByZXR1cm4gcm9vdFNlcnZlcjsKKyAgfQorICAKKyAgLyoqCisgICAqIFdhaXQgdW50aWwgcm9vdCByZWdpb24gaXMgYXZhaWxhYmxlCisgICAqLworICBwdWJsaWMgdm9pZCB3YWl0Rm9yUm9vdFJlZ2lvbkxvY2F0aW9uKCkgeworICAgIHJlZ2lvbk1hbmFnZXIud2FpdEZvclJvb3RSZWdpb25Mb2NhdGlvbigpOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiBSZWFkLW9ubHkgbWFwIG9mIG9ubGluZSByZWdpb25zLgorICAgKi8KKyAgcHVibGljIE1hcDxieXRlIFtdLCBNZXRhUmVnaW9uPiBnZXRPbmxpbmVNZXRhUmVnaW9ucygpIHsKKyAgICByZXR1cm4gcmVnaW9uTWFuYWdlci5nZXRPbmxpbmVNZXRhUmVnaW9ucygpOworICB9CisKKyAgLyoqIE1haW4gcHJvY2Vzc2luZyBsb29wICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgZmluYWwgU3RyaW5nIHRocmVhZE5hbWUgPSAiSE1hc3RlciI7CisgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5zZXROYW1lKHRocmVhZE5hbWUpOworICAgIHN0YXJ0U2VydmljZVRocmVhZHMoKTsKKyAgICAvKiBNYWluIHByb2Nlc3NpbmcgbG9vcCAqLworICAgIHRyeSB7CisgICAgICB3aGlsZSAoIWNsb3NlZC5nZXQoKSkgeworICAgICAgICAvLyBjaGVjayBpZiB3ZSBzaG91bGQgYmUgc2h1dHRpbmcgZG93bgorICAgICAgICBpZiAoc2h1dGRvd25SZXF1ZXN0ZWQuZ2V0KCkpIHsKKyAgICAgICAgICAvLyBUaGUgcmVnaW9uIHNlcnZlcnMgd29uJ3QgYWxsIGV4aXQgdW50aWwgd2Ugc3RvcCBzY2FubmluZyB0aGUKKyAgICAgICAgICAvLyBtZXRhIHJlZ2lvbnMKKyAgICAgICAgICByZWdpb25NYW5hZ2VyLnN0b3BTY2FubmVycygpOworICAgICAgICAgIGlmIChzZXJ2ZXJNYW5hZ2VyLm51bVNlcnZlcnMoKSA9PSAwKSB7CisgICAgICAgICAgICBzdGFydFNodXRkb3duKCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gd29yayBvbiB0aGUgVG9kb1F1ZXVlLiBJZiB0aGF0IGZhaWxzLCB3ZSBzaG91bGQgc2h1dCBkb3duLgorICAgICAgICBpZiAoIXByb2Nlc3NUb0RvUXVldWUoKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIExPRy5mYXRhbCgiVW5oYW5kbGVkIGV4Y2VwdGlvbi4gU3RhcnRpbmcgc2h1dGRvd24uIiwgdCk7CisgICAgICBjbG9zZWQuc2V0KHRydWUpOworICAgIH0KKyAgICAKKyAgICAvLyBXYWl0IGZvciBhbGwgdGhlIHJlbWFpbmluZyByZWdpb24gc2VydmVycyB0byByZXBvcnQgaW4uCisgICAgc2VydmVyTWFuYWdlci5sZXRSZWdpb25TZXJ2ZXJzU2h1dGRvd24oKTsKKworICAgIC8qCisgICAgICogQ2xlYW4gdXAgYW5kIGNsb3NlIHVwIHNob3AKKyAgICAgKi8KKyAgICBSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKS5vZmZsaW5lKCk7CisgICAgaWYgKHRoaXMuaW5mb1NlcnZlciAhPSBudWxsKSB7CisgICAgICBMT0cuaW5mbygiU3RvcHBpbmcgaW5mb1NlcnZlciIpOworICAgICAgdHJ5IHsKKyAgICAgICAgdGhpcy5pbmZvU2VydmVyLnN0b3AoKTsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIH0KKyAgICB9CisgICAgc2VydmVyLnN0b3AoKTsgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcCBzZXJ2ZXIKKyAgICByZWdpb25NYW5hZ2VyLnN0b3AoKTsKKyAgICAKKyAgICAvLyBKb2luIHVwIHdpdGggYWxsIHRocmVhZHMKKyAgICBMT0cuaW5mbygiSE1hc3RlciBtYWluIHRocmVhZCBleGl0aW5nIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBUcnkgdG8gZ2V0IGFuIG9wZXJhdGlvbiBvZmYgb2YgdGhlIHRvZG8gcXVldWUgYW5kIHBlcmZvcm0gaXQuCisgICAqLyAKKyAgcHJpdmF0ZSBib29sZWFuIHByb2Nlc3NUb0RvUXVldWUoKSB7CisgICAgUmVnaW9uU2VydmVyT3BlcmF0aW9uIG9wID0gbnVsbDsKKworICAgIC8vIGJsb2NrIHVudGlsIHRoZSByb290IHJlZ2lvbiBpcyBvbmxpbmUKKyAgICBpZiAocmVnaW9uTWFuYWdlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKSAhPSBudWxsKSB7CisgICAgICAvLyBXZSBjYW4ndCBwcm9jZXNzIHNlcnZlciBzaHV0ZG93bnMgdW5sZXNzIHRoZSByb290IHJlZ2lvbiBpcyBvbmxpbmUKKyAgICAgIG9wID0gZGVsYXllZFRvRG9RdWV1ZS5wb2xsKCk7CisgICAgfQorICAgIAorICAgIC8vIGlmIHRoZXJlIGFyZW4ndCBhbnkgdG9kbyBpdGVtcyBpbiB0aGUgcXVldWUsIHNsZWVwIGZvciBhIGJpdC4KKyAgICBpZiAob3AgPT0gbnVsbCApIHsKKyAgICAgIHRyeSB7CisgICAgICAgIG9wID0gdG9Eb1F1ZXVlLnBvbGwodGhyZWFkV2FrZUZyZXF1ZW5jeSwgVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gY29udGludWUKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLy8gYXQgdGhpcyBwb2ludCwgaWYgdGhlcmUncyBzdGlsbCBubyB0b2RvIG9wZXJhdGlvbiwgb3Igd2UncmUgc3VwcG9zZWQgdG8KKyAgICAvLyBiZSBjbG9zZWQsIHJldHVybi4KKyAgICBpZiAob3AgPT0gbnVsbCB8fCBjbG9zZWQuZ2V0KCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICAKKyAgICB0cnkgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiUHJvY2Vzc2luZyB0b2RvOiAiICsgb3AudG9TdHJpbmcoKSk7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIHBlcmZvcm0gdGhlIG9wZXJhdGlvbi4gCisgICAgICBpZiAoIW9wLnByb2Nlc3MoKSkgeworICAgICAgICAvLyBPcGVyYXRpb24gd291bGQgaGF2ZSBibG9ja2VkIGJlY2F1c2Ugbm90IGFsbCBtZXRhIHJlZ2lvbnMgYXJlCisgICAgICAgIC8vIG9ubGluZS4gVGhpcyBjb3VsZCBjYXVzZSBhIGRlYWRsb2NrLCBiZWNhdXNlIHRoaXMgdGhyZWFkIGlzIHdhaXRpbmcKKyAgICAgICAgLy8gZm9yIHRoZSBtaXNzaW5nIG1ldGEgcmVnaW9uKHMpIHRvIGNvbWUgYmFjayBvbmxpbmUsIGJ1dCBzaW5jZSBpdAorICAgICAgICAvLyBpcyB3YWl0aW5nLCBpdCBjYW5ub3QgcHJvY2VzcyB0aGUgbWV0YSByZWdpb24gb25saW5lIG9wZXJhdGlvbiBpdAorICAgICAgICAvLyBpcyB3YWl0aW5nIGZvci4gU28gcHV0IHRoaXMgb3BlcmF0aW9uIGJhY2sgb24gdGhlIHF1ZXVlIGZvciBub3cuCisgICAgICAgIGlmICh0b0RvUXVldWUuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAvLyBUaGUgcXVldWUgaXMgY3VycmVudGx5IGVtcHR5IHNvIHdhaXQgZm9yIGEgd2hpbGUgdG8gc2VlIGlmIHdoYXQKKyAgICAgICAgICAvLyB3ZSBuZWVkIGNvbWVzIGluIGZpcnN0CisgICAgICAgICAgc2xlZXBlci5zbGVlcCgpOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuZGVidWcoIlB1dCAiICsgb3AudG9TdHJpbmcoKSArICIgYmFjayBvbiBxdWV1ZSIpOworICAgICAgICAgIH0KKyAgICAgICAgICB0b0RvUXVldWUucHV0KG9wKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICAgIlB1dHRpbmcgaW50byB0b0RvUXVldWUgd2FzIGludGVycnVwdGVkLiIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAvLyBUaGVyZSB3YXMgYW4gZXhjZXB0aW9uIHBlcmZvcm1pbmcgdGhlIG9wZXJhdGlvbi4KKyAgICAgIGlmIChleCBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgICB0cnkgeworICAgICAgICAgIGV4ID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5kZWNvZGVSZW1vdGVFeGNlcHRpb24oCisgICAgICAgICAgICAoUmVtb3RlRXhjZXB0aW9uKWV4KTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIGV4ID0gZTsKKyAgICAgICAgICBMT0cud2FybigibWFpbiBwcm9jZXNzaW5nIGxvb3A6ICIgKyBvcC50b1N0cmluZygpLCBlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgLy8gbWFrZSBzdXJlIHRoZSBmaWxlc3lzdGVtIGlzIHN0aWxsIG9rLiBvdGhlcndpc2UsIHdlJ3JlIHRvYXN0LgorICAgICAgaWYgKCFjaGVja0ZpbGVTeXN0ZW0oKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBMT0cud2FybigiUHJvY2Vzc2luZyBwZW5kaW5nIG9wZXJhdGlvbnM6ICIgKyBvcC50b1N0cmluZygpLCBleCk7CisgICAgICB0cnkgeworICAgICAgICAvLyBwdXQgdGhlIG9wZXJhdGlvbiBiYWNrIG9uIHRoZSBxdWV1ZS4uLiBtYXliZSBpdCdsbCB3b3JrIG5leHQgdGltZS4KKyAgICAgICAgdG9Eb1F1ZXVlLnB1dChvcCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAorICAgICAgICAgICJQdXR0aW5nIGludG8gdG9Eb1F1ZXVlIHdhcyBpbnRlcnJ1cHRlZC4iLCBlKTsKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigibWFpbiBwcm9jZXNzaW5nIGxvb3A6ICIgKyBvcC50b1N0cmluZygpLCBlKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgCisgIC8qCisgICAqIFN0YXJ0IHVwIGFsbCBzZXJ2aWNlcy4gSWYgYW55IG9mIHRoZXNlIHRocmVhZHMgZ2V0cyBhbiB1bmhhbmRsZWQgZXhjZXB0aW9uCisgICAqIHRoZW4gdGhleSBqdXN0IGRpZSB3aXRoIGEgbG9nZ2VkIG1lc3NhZ2UuICBUaGlzIHNob3VsZCBiZSBmaW5lIGJlY2F1c2UKKyAgICogaW4gZ2VuZXJhbCwgd2UgZG8gbm90IGV4cGVjdCB0aGUgbWFzdGVyIHRvIGdldCBzdWNoIHVuaGFuZGxlZCBleGNlcHRpb25zCisgICAqICBhcyBPT01FczsgaXQgc2hvdWxkIGJlIGxpZ2h0bHkgbG9hZGVkLiBTZWUgd2hhdCBIUmVnaW9uU2VydmVyIGRvZXMgaWYKKyAgICogIG5lZWQgdG8gaW5zdGFsbCBhbiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiBoYW5kbGVyLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHN0YXJ0U2VydmljZVRocmVhZHMoKSB7CisgICAgLy8gRG8gYWZ0ZXIgbWFpbiB0aHJlYWQgbmFtZSBoYXMgYmVlbiBzZXQKKyAgICB0aGlzLm1ldHJpY3MgPSBuZXcgTWFzdGVyTWV0cmljcygpOworICAgIHRyeSB7CisgICAgICByZWdpb25NYW5hZ2VyLnN0YXJ0KCk7CisgICAgICAvLyBQdXQgdXAgaW5mbyBzZXJ2ZXIuCisgICAgICBpbnQgcG9ydCA9IHRoaXMuY29uZi5nZXRJbnQoImhiYXNlLm1hc3Rlci5pbmZvLnBvcnQiLCA2MDAxMCk7CisgICAgICBpZiAocG9ydCA+PSAwKSB7CisgICAgICAgIFN0cmluZyBhID0gdGhpcy5jb25mLmdldCgiaGJhc2UubWFzdGVyLmluZm8uYmluZEFkZHJlc3MiLCAiMC4wLjAuMCIpOworICAgICAgICB0aGlzLmluZm9TZXJ2ZXIgPSBuZXcgSW5mb1NlcnZlcihNQVNURVIsIGEsIHBvcnQsIGZhbHNlKTsKKyAgICAgICAgdGhpcy5pbmZvU2VydmVyLnNldEF0dHJpYnV0ZShNQVNURVIsIHRoaXMpOworICAgICAgICB0aGlzLmluZm9TZXJ2ZXIuc3RhcnQoKTsKKyAgICAgIH0KKyAgICAgIC8vIFN0YXJ0IHRoZSBzZXJ2ZXIgc28gZXZlcnl0aGluZyBlbHNlIGlzIHJ1bm5pbmcgYmVmb3JlIHdlIHN0YXJ0CisgICAgICAvLyByZWNlaXZpbmcgcmVxdWVzdHMuCisgICAgICB0aGlzLnNlcnZlci5zdGFydCgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGlmIChlIGluc3RhbmNlb2YgUmVtb3RlRXhjZXB0aW9uKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgZSA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuZGVjb2RlUmVtb3RlRXhjZXB0aW9uKChSZW1vdGVFeGNlcHRpb24pIGUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgIExPRy53YXJuKCJ0aHJlYWQgc3RhcnQiLCBleCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIC8vIFNvbWV0aGluZyBoYXBwZW5lZCBkdXJpbmcgc3RhcnR1cC4gU2h1dCB0aGluZ3MgZG93bi4KKyAgICAgIHRoaXMuY2xvc2VkLnNldCh0cnVlKTsKKyAgICAgIExPRy5lcnJvcigiRmFpbGVkIHN0YXJ0dXAiLCBlKTsKKyAgICB9CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoIlN0YXJ0ZWQgc2VydmljZSB0aHJlYWRzIik7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogU3RhcnQgc2h1dHRpbmcgZG93biB0aGUgbWFzdGVyCisgICAqLworICB2b2lkIHN0YXJ0U2h1dGRvd24oKSB7CisgICAgY2xvc2VkLnNldCh0cnVlKTsKKyAgICByZWdpb25NYW5hZ2VyLnN0b3BTY2FubmVycygpOworICAgIHN5bmNocm9uaXplZCh0b0RvUXVldWUpIHsKKyAgICAgIHRvRG9RdWV1ZS5jbGVhcigpOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFbXB0eSB0aGUgcXVldWUKKyAgICAgIGRlbGF5ZWRUb0RvUXVldWUuY2xlYXIoKTsgICAgICAgICAgICAgICAgICAvLyBFbXB0eSBzaHV0IGRvd24gcXVldWUKKyAgICAgIHRvRG9RdWV1ZS5ub3RpZnlBbGwoKTsgICAgICAgICAgICAgICAgICAgICAvLyBXYWtlIG1haW4gdGhyZWFkCisgICAgfQorICAgIHNlcnZlck1hbmFnZXIubm90aWZ5U2VydmVycygpOworICB9CisKKyAgLyoKKyAgICogSE1hc3RlclJlZ2lvbkludGVyZmFjZQorICAgKi8KKyAgcHVibGljIE1hcFdyaXRhYmxlIHJlZ2lvblNlcnZlclN0YXJ0dXAoZmluYWwgSFNlcnZlckluZm8gc2VydmVySW5mbykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgdGhlIGFkZHJlc3MgZm9yIG5vdyBldmVuIHRobyBpdCB3aWxsIG5vdCBiZSBwZXJzaXN0ZWQgb24gSFJTIHNpZGUKKyAgICAvLyBJZiB0aGUgYWRkcmVzcyBnaXZlbiBpcyBub3QgdGhlIGRlZmF1bHQgb25lLAorICAgIC8vIHVzZSB0aGUgSVAgZ2l2ZW4gYnkgdGhlIHVzZXIuCisgICAgaWYgKHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLmdldEJpbmRBZGRyZXNzKCkuZXF1YWxzKAorICAgICAgICBERUZBVUxUX0hPU1QpKSB7CisgICAgICBTdHJpbmcgcnNBZGRyZXNzID0gSEJhc2VTZXJ2ZXIuZ2V0UmVtb3RlQWRkcmVzcygpOworICAgICAgc2VydmVySW5mby5zZXRTZXJ2ZXJBZGRyZXNzKG5ldyBIU2VydmVyQWRkcmVzcyhyc0FkZHJlc3MsCisgICAgICBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKS5nZXRQb3J0KCkpKTsKKyAgICB9CisgICAgLy8gUmVnaXN0ZXIgd2l0aCBzZXJ2ZXIgbWFuYWdlcgorICAgIHRoaXMuc2VydmVyTWFuYWdlci5yZWdpb25TZXJ2ZXJTdGFydHVwKHNlcnZlckluZm8pOworICAgIC8vIFNlbmQgYmFjayBzb21lIGNvbmZpZyBpbmZvCisgICAgcmV0dXJuIGNyZWF0ZUNvbmZpZ3VyYXRpb25TdWJzZXQoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEByZXR1cm4gU3Vic2V0IG9mIGNvbmZpZ3VyYXRpb24gdG8gcGFzcyBpbml0aWFsaXppbmcgcmVnaW9uc2VydmVyczogZS5nLgorICAgKiB0aGUgZmlsZXN5c3RlbSB0byB1c2UgYW5kIHJvb3QgZGlyZWN0b3J5IHRvIHVzZS4KKyAgICovCisgIHByb3RlY3RlZCBNYXBXcml0YWJsZSBjcmVhdGVDb25maWd1cmF0aW9uU3Vic2V0KCkgeworICAgIE1hcFdyaXRhYmxlIG13ID0gYWRkQ29uZmlnKG5ldyBNYXBXcml0YWJsZSgpLCBIQ29uc3RhbnRzLkhCQVNFX0RJUik7CisgICAgLy8gR2V0IHRoZSByZWFsIGFkZHJlc3Mgb2YgdGhlIEhSUy4KKyAgICBTdHJpbmcgcnNBZGRyZXNzID0gSEJhc2VTZXJ2ZXIuZ2V0UmVtb3RlQWRkcmVzcygpOworICAgIGlmIChyc0FkZHJlc3MgIT0gbnVsbCkgeworICAgICAgbXcucHV0KG5ldyBUZXh0KCJoYmFzZS5yZWdpb25zZXJ2ZXIuYWRkcmVzcyIpLCBuZXcgVGV4dChyc0FkZHJlc3MpKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGFkZENvbmZpZyhtdywgImZzLmRlZmF1bHQubmFtZSIpOworICB9CisKKyAgcHJpdmF0ZSBNYXBXcml0YWJsZSBhZGRDb25maWcoZmluYWwgTWFwV3JpdGFibGUgbXcsIGZpbmFsIFN0cmluZyBrZXkpIHsKKyAgICBtdy5wdXQobmV3IFRleHQoa2V5KSwgbmV3IFRleHQodGhpcy5jb25mLmdldChrZXkpKSk7CisgICAgcmV0dXJuIG13OworICB9CisKKyAgcHVibGljIEhNc2dbXSByZWdpb25TZXJ2ZXJSZXBvcnQoSFNlcnZlckluZm8gc2VydmVySW5mbywgSE1zZyBtc2dzW10sIAorICAgIEhSZWdpb25JbmZvW10gbW9zdExvYWRlZFJlZ2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHNlcnZlck1hbmFnZXIucmVnaW9uU2VydmVyUmVwb3J0KHNlcnZlckluZm8sIG1zZ3MsIAorICAgICAgbW9zdExvYWRlZFJlZ2lvbnMpOworICB9CisKKyAgLyoKKyAgICogSE1hc3RlckludGVyZmFjZQorICAgKi8KKworICBwdWJsaWMgYm9vbGVhbiBpc01hc3RlclJ1bm5pbmcoKSB7CisgICAgcmV0dXJuICFjbG9zZWQuZ2V0KCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICBMT0cuaW5mbygiQ2x1c3RlciBzaHV0ZG93biByZXF1ZXN0ZWQuIFN0YXJ0aW5nIHRvIHF1aWVzY2Ugc2VydmVycyIpOworICAgIHRoaXMuc2h1dGRvd25SZXF1ZXN0ZWQuc2V0KHRydWUpOworICB9CisKKyAgcHVibGljIHZvaWQgY3JlYXRlVGFibGUoSFRhYmxlRGVzY3JpcHRvciBkZXNjKQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAgICAKKyAgICBpZiAoIWlzTWFzdGVyUnVubmluZygpKSB7CisgICAgICB0aHJvdyBuZXcgTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbigpOworICAgIH0KKyAgICBIUmVnaW9uSW5mbyBuZXdSZWdpb24gPSBuZXcgSFJlZ2lvbkluZm8oZGVzYywgbnVsbCwgbnVsbCk7CisKKyAgICBmb3IgKGludCB0cmllcyA9IDA7IHRyaWVzIDwgbnVtUmV0cmllczsgdHJpZXMrKykgeworICAgICAgdHJ5IHsKKyAgICAgICAgLy8gV2UgY2FuIG5vdCBjcmVhdGUgYSB0YWJsZSB1bmxlc3MgbWV0YSByZWdpb25zIGhhdmUgYWxyZWFkeSBiZWVuCisgICAgICAgIC8vIGFzc2lnbmVkIGFuZCBzY2FubmVkLgorICAgICAgICBpZiAoIXJlZ2lvbk1hbmFnZXIuYXJlQWxsTWV0YVJlZ2lvbnNPbmxpbmUoKSkgeworICAgICAgICAgIHRocm93IG5ldyBOb3RBbGxNZXRhUmVnaW9uc09ubGluZUV4Y2VwdGlvbigpOworICAgICAgICB9CisgICAgICAgIGNyZWF0ZVRhYmxlKG5ld1JlZ2lvbik7CisgICAgICAgIExPRy5pbmZvKCJjcmVhdGVkIHRhYmxlICIgKyBkZXNjLmdldE5hbWVBc1N0cmluZygpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9IGNhdGNoIChUYWJsZUV4aXN0c0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IGU7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIGlmICh0cmllcyA9PSBudW1SZXRyaWVzIC0gMSkgeworICAgICAgICAgIHRocm93IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgICAgICBzbGVlcGVyLnNsZWVwKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBjcmVhdGVUYWJsZShmaW5hbCBIUmVnaW9uSW5mbyBuZXdSZWdpb24pIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN0cmluZyB0YWJsZU5hbWUgPSBuZXdSZWdpb24uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZUFzU3RyaW5nKCk7CisgICAgLy8gMS4gQ2hlY2sgdG8gc2VlIGlmIHRhYmxlIGFscmVhZHkgZXhpc3RzLiBHZXQgbWV0YSByZWdpb24gd2hlcmUKKyAgICAvLyB0YWJsZSB3b3VsZCBzaXQgc2hvdWxkIGl0IGV4aXN0LiBPcGVuIHNjYW5uZXIgb24gaXQuIElmIGEgcmVnaW9uCisgICAgLy8gZm9yIHRoZSB0YWJsZSB3ZSB3YW50IHRvIGNyZWF0ZSBhbHJlYWR5IGV4aXN0cywgdGhlbiB0YWJsZSBhbHJlYWR5CisgICAgLy8gY3JlYXRlZC4gVGhyb3cgYWxyZWFkeS1leGlzdHMgZXhjZXB0aW9uLgorICAgIE1ldGFSZWdpb24gbSA9IHJlZ2lvbk1hbmFnZXIuZ2V0Rmlyc3RNZXRhUmVnaW9uRm9yUmVnaW9uKG5ld1JlZ2lvbik7CisgICAgICAgIAorICAgIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUgPSBtLmdldFJlZ2lvbk5hbWUoKTsKKyAgICBIUmVnaW9uSW50ZXJmYWNlIHNydnIgPSBjb25uZWN0aW9uLmdldEhSZWdpb25Db25uZWN0aW9uKG0uZ2V0U2VydmVyKCkpOworICAgIGJ5dGVbXSBmaXJzdFJvd0luVGFibGUgPSBCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSArICIsLCIpOworICAgIGxvbmcgc2Nhbm5lcmlkID0gc3J2ci5vcGVuU2Nhbm5lcihtZXRhUmVnaW9uTmFtZSwgQ09MX1JFR0lPTklORk9fQVJSQVksCisgICAgICAgIGZpcnN0Um93SW5UYWJsZSwgTEFURVNUX1RJTUVTVEFNUCwgbnVsbCk7CisgICAgdHJ5IHsKKyAgICAgIFJvd1Jlc3VsdCBkYXRhID0gc3J2ci5uZXh0KHNjYW5uZXJpZCk7CisgICAgICBpZiAoZGF0YSAhPSBudWxsICYmIGRhdGEuc2l6ZSgpID4gMCkgeworICAgICAgICBIUmVnaW9uSW5mbyBpbmZvID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKGRhdGEuZ2V0KENPTF9SRUdJT05JTkZPKSk7CisgICAgICAgIGlmIChpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWVBc1N0cmluZygpLmVxdWFscyh0YWJsZU5hbWUpKSB7CisgICAgICAgICAgLy8gQSByZWdpb24gZm9yIHRoaXMgdGFibGUgYWxyZWFkeSBleGlzdHMuIEVyZ28gdGFibGUgZXhpc3RzLgorICAgICAgICAgIHRocm93IG5ldyBUYWJsZUV4aXN0c0V4Y2VwdGlvbih0YWJsZU5hbWUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNydnIuY2xvc2Uoc2Nhbm5lcmlkKTsKKyAgICB9CisgICAgcmVnaW9uTWFuYWdlci5jcmVhdGVSZWdpb24obmV3UmVnaW9uLCBzcnZyLCBtZXRhUmVnaW9uTmFtZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBkZWxldGVUYWJsZShmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoQnl0ZXMuZXF1YWxzKHRhYmxlTmFtZSwgUk9PVF9UQUJMRV9OQU1FKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDYW4ndCBkZWxldGUgcm9vdCB0YWJsZSIpOworICAgIH0KKyAgICBuZXcgVGFibGVEZWxldGUodGhpcywgdGFibGVOYW1lKS5wcm9jZXNzKCk7CisgICAgTE9HLmluZm8oImRlbGV0ZWQgdGFibGU6ICIgKyBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFkZENvbHVtbihieXRlIFtdIHRhYmxlTmFtZSwgSENvbHVtbkRlc2NyaXB0b3IgY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAgICAKKyAgICBuZXcgQWRkQ29sdW1uKHRoaXMsIHRhYmxlTmFtZSwgY29sdW1uKS5wcm9jZXNzKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBtb2RpZnlDb2x1bW4oYnl0ZSBbXSB0YWJsZU5hbWUsIGJ5dGUgW10gY29sdW1uTmFtZSwgCisgICAgSENvbHVtbkRlc2NyaXB0b3IgZGVzY3JpcHRvcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBuZXcgTW9kaWZ5Q29sdW1uKHRoaXMsIHRhYmxlTmFtZSwgY29sdW1uTmFtZSwgZGVzY3JpcHRvcikucHJvY2VzcygpOworICB9CisKKyAgcHVibGljIHZvaWQgZGVsZXRlQ29sdW1uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLCBmaW5hbCBieXRlIFtdIGMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbmV3IERlbGV0ZUNvbHVtbih0aGlzLCB0YWJsZU5hbWUsIEhTdG9yZUtleS5nZXRGYW1pbHkoYykpLnByb2Nlc3MoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGVuYWJsZVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChCeXRlcy5lcXVhbHModGFibGVOYW1lLCBST09UX1RBQkxFX05BTUUpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbid0IGVuYWJsZSByb290IHRhYmxlIik7CisgICAgfQorICAgIG5ldyBDaGFuZ2VUYWJsZVN0YXRlKHRoaXMsIHRhYmxlTmFtZSwgdHJ1ZSkucHJvY2VzcygpOworICB9CisKKyAgcHVibGljIHZvaWQgZGlzYWJsZVRhYmxlKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChCeXRlcy5lcXVhbHModGFibGVOYW1lLCBST09UX1RBQkxFX05BTUUpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbid0IGRpc2FibGUgcm9vdCB0YWJsZSIpOworICAgIH0KKyAgICBuZXcgQ2hhbmdlVGFibGVTdGF0ZSh0aGlzLCB0YWJsZU5hbWUsIGZhbHNlKS5wcm9jZXNzKCk7CisgIH0KKworICBwcml2YXRlIExpc3Q8UGFpcjxIUmVnaW9uSW5mbyxIU2VydmVyQWRkcmVzcz4+CisgIGdldFRhYmxlUmVnaW9ucyhmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PiByZXN1bHQgPQorICAgICAgICBuZXcgQXJyYXlMaXN0PFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PigpOworICAgIFNldDxNZXRhUmVnaW9uPiByZWdpb25zID0gcmVnaW9uTWFuYWdlci5nZXRNZXRhUmVnaW9uc0ZvclRhYmxlKHRhYmxlTmFtZSk7CisgICAgYnl0ZSBbXSBmaXJzdFJvd0luVGFibGUgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkgKyAiLCwiKTsKKyAgICBmb3IgKE1ldGFSZWdpb24gbTogcmVnaW9ucykgeworICAgICAgYnl0ZSBbXSBtZXRhUmVnaW9uTmFtZSA9IG0uZ2V0UmVnaW9uTmFtZSgpOworICAgICAgSFJlZ2lvbkludGVyZmFjZSBzcnZyID0gY29ubmVjdGlvbi5nZXRIUmVnaW9uQ29ubmVjdGlvbihtLmdldFNlcnZlcigpKTsKKyAgICAgIGxvbmcgc2Nhbm5lcmlkID0gCisgICAgICAgIHNydnIub3BlblNjYW5uZXIobWV0YVJlZ2lvbk5hbWUsIAorICAgICAgICAgIG5ldyBieXRlW11bXSB7Q09MX1JFR0lPTklORk8sIENPTF9TRVJWRVJ9LAorICAgICAgICAgIGZpcnN0Um93SW5UYWJsZSwgCisgICAgICAgICAgTEFURVNUX1RJTUVTVEFNUCwgCisgICAgICAgICAgbnVsbCk7CisgICAgICB0cnkgeworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgIFJvd1Jlc3VsdCBkYXRhID0gc3J2ci5uZXh0KHNjYW5uZXJpZCk7CisgICAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCB8fCBkYXRhLnNpemUoKSA8PSAwKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgSFJlZ2lvbkluZm8gaW5mbyA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mbyhkYXRhLmdldChDT0xfUkVHSU9OSU5GTykpOworICAgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8oaW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCksIHRhYmxlTmFtZSkgPT0gMCkgeworICAgICAgICAgICAgQ2VsbCBjZWxsID0gZGF0YS5nZXQoQ09MX1NFUlZFUik7CisgICAgICAgICAgICBpZiAoY2VsbCAhPSBudWxsKSB7CisgICAgICAgICAgICAgIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlciA9CisgICAgICAgICAgICAgICAgbmV3IEhTZXJ2ZXJBZGRyZXNzKEJ5dGVzLnRvU3RyaW5nKGNlbGwuZ2V0VmFsdWUoKSkpOworICAgICAgICAgICAgICByZXN1bHQuYWRkKG5ldyBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPihpbmZvLCBzZXJ2ZXIpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzcnZyLmNsb3NlKHNjYW5uZXJpZCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwcml2YXRlIFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+CisgIGdldFRhYmxlUmVnaW9uQ2xvc2VzdChmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSwgZmluYWwgYnl0ZSBbXSByb3dLZXkpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTZXQ8TWV0YVJlZ2lvbj4gcmVnaW9ucyA9IHJlZ2lvbk1hbmFnZXIuZ2V0TWV0YVJlZ2lvbnNGb3JUYWJsZSh0YWJsZU5hbWUpOworICAgIGZvciAoTWV0YVJlZ2lvbiBtOiByZWdpb25zKSB7CisgICAgICBieXRlIFtdIGZpcnN0Um93SW5UYWJsZSA9IEJ5dGVzLnRvQnl0ZXMoQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSArICIsLCIpOworICAgICAgYnl0ZSBbXSBtZXRhUmVnaW9uTmFtZSA9IG0uZ2V0UmVnaW9uTmFtZSgpOworICAgICAgSFJlZ2lvbkludGVyZmFjZSBzcnZyID0gY29ubmVjdGlvbi5nZXRIUmVnaW9uQ29ubmVjdGlvbihtLmdldFNlcnZlcigpKTsKKyAgICAgIGxvbmcgc2Nhbm5lcmlkID0gCisgICAgICAgICAgc3J2ci5vcGVuU2Nhbm5lcihtZXRhUmVnaW9uTmFtZSwgCisgICAgICAgICAgICBuZXcgYnl0ZVtdW10ge0NPTF9SRUdJT05JTkZPLCBDT0xfU0VSVkVSfSwKKyAgICAgICAgICAgIGZpcnN0Um93SW5UYWJsZSwgCisgICAgICAgICAgICBMQVRFU1RfVElNRVNUQU1QLCAKKyAgICAgICAgICAgIG51bGwpOworICAgICAgdHJ5IHsKKyAgICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgICBSb3dSZXN1bHQgZGF0YSA9IHNydnIubmV4dChzY2FubmVyaWQpOworICAgICAgICAgIGlmIChkYXRhID09IG51bGwgfHwgZGF0YS5zaXplKCkgPD0gMCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8oZGF0YS5nZXQoQ09MX1JFR0lPTklORk8pKTsKKyAgICAgICAgICBpZiAoQnl0ZXMuY29tcGFyZVRvKGluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLCB0YWJsZU5hbWUpID09IDApIHsKKyAgICAgICAgICAgIGlmICgoQnl0ZXMuY29tcGFyZVRvKGluZm8uZ2V0U3RhcnRLZXkoKSwgcm93S2V5KSA+PSAwKSAmJgorICAgICAgICAgICAgICAgIChCeXRlcy5jb21wYXJlVG8oaW5mby5nZXRFbmRLZXkoKSwgcm93S2V5KSA8IDApKSB7CisgICAgICAgICAgICAgICAgQ2VsbCBjZWxsID0gZGF0YS5nZXQoQ09MX1NFUlZFUik7CisgICAgICAgICAgICAgICAgaWYgKGNlbGwgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgSFNlcnZlckFkZHJlc3Mgc2VydmVyID0KKyAgICAgICAgICAgICAgICAgICAgbmV3IEhTZXJ2ZXJBZGRyZXNzKEJ5dGVzLnRvU3RyaW5nKGNlbGwuZ2V0VmFsdWUoKSkpOworICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPihpbmZvLCBzZXJ2ZXIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzcnZyLmNsb3NlKHNjYW5uZXJpZCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisKKyAgcHJpdmF0ZSBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPgorICBnZXRUYWJsZVJlZ2lvbkZyb21OYW1lKGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSkKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW10gdGFibGVOYW1lID0gSFJlZ2lvbkluZm8ucGFyc2VSZWdpb25OYW1lKHJlZ2lvbk5hbWUpWzBdOworICAgIFNldDxNZXRhUmVnaW9uPiByZWdpb25zID0gcmVnaW9uTWFuYWdlci5nZXRNZXRhUmVnaW9uc0ZvclRhYmxlKHRhYmxlTmFtZSk7CisgICAgZm9yIChNZXRhUmVnaW9uIG06IHJlZ2lvbnMpIHsKKyAgICAgIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUgPSBtLmdldFJlZ2lvbk5hbWUoKTsKKyAgICAgIEhSZWdpb25JbnRlcmZhY2Ugc3J2ciA9IGNvbm5lY3Rpb24uZ2V0SFJlZ2lvbkNvbm5lY3Rpb24obS5nZXRTZXJ2ZXIoKSk7CisgICAgICBSb3dSZXN1bHQgZGF0YSA9IHNydnIuZ2V0Um93KG1ldGFSZWdpb25OYW1lLCByZWdpb25OYW1lLCAKKyAgICAgICAgbmV3IGJ5dGVbXVtdIHtDT0xfUkVHSU9OSU5GTywgQ09MX1NFUlZFUn0sCisgICAgICAgIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSwgLTFMKTsKKyAgICAgIGlmKGRhdGEgPT0gbnVsbCB8fCBkYXRhLnNpemUoKSA8PSAwKSBjb250aW51ZTsKKyAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8oZGF0YS5nZXQoQ09MX1JFR0lPTklORk8pKTsKKyAgICAgIENlbGwgY2VsbCA9IGRhdGEuZ2V0KENPTF9TRVJWRVIpOworICAgICAgaWYoY2VsbCAhPSBudWxsKSB7CisgICAgICAgIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlciA9CisgICAgICAgICAgbmV3IEhTZXJ2ZXJBZGRyZXNzKEJ5dGVzLnRvU3RyaW5nKGNlbGwuZ2V0VmFsdWUoKSkpOworICAgICAgICByZXR1cm4gbmV3IFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+KGluZm8sIHNlcnZlcik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisgIAorICAvKioKKyAgICogR2V0IHJvdyBmcm9tIG1ldGEgdGFibGUuCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIGNvbHVtbnMKKyAgICogQHJldHVybiBSb3dSZXN1bHQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJvdGVjdGVkIFJvd1Jlc3VsdCBnZXRGcm9tTUVUQShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWV0YVJlZ2lvbiBtZXRhID0gdGhpcy5yZWdpb25NYW5hZ2VyLmdldE1ldGFSZWdpb25Gb3JSb3cocm93KTsKKyAgICBIUmVnaW9uSW50ZXJmYWNlIHNydnIgPSBnZXRNRVRBU2VydmVyKG1ldGEpOworICAgIHJldHVybiBzcnZyLmdldFJvdyhtZXRhLmdldFJlZ2lvbk5hbWUoKSwgcm93LCBjb2x1bW5zLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCAxLCAtMSk7CisgIH0KKyAgCisgIC8qCisgICAqIEBwYXJhbSBtZXRhCisgICAqIEByZXR1cm4gU2VydmVyIGNvbm5lY3Rpb24gdG8gPGNvZGU+bWV0YTwvY29kZT4gLk1FVEEuIHJlZ2lvbi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBIUmVnaW9uSW50ZXJmYWNlIGdldE1FVEFTZXJ2ZXIoZmluYWwgTWV0YVJlZ2lvbiBtZXRhKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24uZ2V0SFJlZ2lvbkNvbm5lY3Rpb24obWV0YS5nZXRTZXJ2ZXIoKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBtb2RpZnlUYWJsZShmaW5hbCBieXRlW10gdGFibGVOYW1lLCBpbnQgb3AsIFdyaXRhYmxlW10gYXJncykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN3aXRjaCAob3ApIHsKKyAgICBjYXNlIE1PRElGWV9UQUJMRV9TRVRfSFREOgorICAgICAgaWYgKGFyZ3MgPT0gbnVsbCB8fCBhcmdzLmxlbmd0aCA8IDEgfHwgCisgICAgICAgICAgIShhcmdzWzBdIGluc3RhbmNlb2YgSFRhYmxlRGVzY3JpcHRvcikpCisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU0VUX0hURCByZXF1ZXN0IHJlcXVpcmVzIGFuIEhUYWJsZURlc2NyaXB0b3IiKTsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gKEhUYWJsZURlc2NyaXB0b3IpIGFyZ3NbMF07CisgICAgICBMT0cuaW5mbygibW9kaWZ5VGFibGUoU0VUX0hURCk6ICIgKyBodGQpOworICAgICAgbmV3IE1vZGlmeVRhYmxlTWV0YSh0aGlzLCB0YWJsZU5hbWUsIGh0ZCkucHJvY2VzcygpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIE1PRElGWV9UQUJMRV9TUExJVDoKKyAgICBjYXNlIE1PRElGWV9UQUJMRV9DT01QQUNUOgorICAgIGNhc2UgTU9ESUZZX1RBQkxFX01BSk9SX0NPTVBBQ1Q6CisgICAgY2FzZSBNT0RJRllfVEFCTEVfRkxVU0g6CisgICAgICBpZiAoYXJncyAhPSBudWxsICYmIGFyZ3MubGVuZ3RoID4gMCkgeworICAgICAgICBpZiAoIShhcmdzWzBdIGluc3RhbmNlb2YgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSkpCisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorICAgICAgICAgICAgInJlcXVlc3QgYXJndW1lbnQgbXVzdCBiZSBJbW11dGFibGVCeXRlc1dyaXRhYmxlIik7CisgICAgICAgIFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+IHBhaXIgPSBudWxsOworICAgICAgICBpZih0YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICAgIGJ5dGUgW10gcmVnaW9uTmFtZSA9ICgoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSlhcmdzWzBdKS5nZXQoKTsKKyAgICAgICAgICBwYWlyID0gZ2V0VGFibGVSZWdpb25Gcm9tTmFtZShyZWdpb25OYW1lKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBieXRlIFtdIHJvd0tleSA9ICgoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSlhcmdzWzBdKS5nZXQoKTsKKyAgICAgICAgICBwYWlyID0gZ2V0VGFibGVSZWdpb25DbG9zZXN0KHRhYmxlTmFtZSwgcm93S2V5KTsKKyAgICAgICAgfQorICAgICAgICBpZiAocGFpciAhPSBudWxsKSB7CisgICAgICAgICAgdGhpcy5yZWdpb25NYW5hZ2VyLnN0YXJ0QWN0aW9uKHBhaXIuZ2V0Rmlyc3QoKS5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgICBwYWlyLmdldEZpcnN0KCksIHBhaXIuZ2V0U2Vjb25kKCksIG9wKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgZm9yIChQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPiBwYWlyOiBnZXRUYWJsZVJlZ2lvbnModGFibGVOYW1lKSkKKyAgICAgICAgICB0aGlzLnJlZ2lvbk1hbmFnZXIuc3RhcnRBY3Rpb24ocGFpci5nZXRGaXJzdCgpLmdldFJlZ2lvbk5hbWUoKSwKKyAgICAgICAgICAgIHBhaXIuZ2V0Rmlyc3QoKSwgcGFpci5nZXRTZWNvbmQoKSwgb3ApOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIE1PRElGWV9DTE9TRV9SRUdJT046CisgICAgICBpZiAoYXJncyA9PSBudWxsIHx8IGFyZ3MubGVuZ3RoIDwgMSB8fCBhcmdzLmxlbmd0aCA+IDIpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZXF1aXJlcyBhdCBsZWFzdCBhIHJlZ2lvbiBuYW1lOyAiICsKKyAgICAgICAgICAib3IgY2Fubm90IGhhdmUgbW9yZSB0aGFuIHJlZ2lvbiBuYW1lIGFuZCBzZXJ2ZXJuYW1lIik7CisgICAgICB9CisgICAgICAvLyBBcmd1bWVudHMgYXJlIHJlZ2lvbm5hbWUgYW5kIGFuIG9wdGlvbmFsIHNlcnZlciBuYW1lLgorICAgICAgYnl0ZSBbXSByZWdpb25uYW1lID0gKChJbW11dGFibGVCeXRlc1dyaXRhYmxlKWFyZ3NbMF0pLmdldCgpOworICAgICAgU3RyaW5nIHNlcnZlcm5hbWUgPSBudWxsOworICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDIpIHsKKyAgICAgICAgc2VydmVybmFtZSA9IEJ5dGVzLnRvU3RyaW5nKCgoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSlhcmdzWzFdKS5nZXQoKSk7CisgICAgICB9CisgICAgICAvLyBOZWVkIGhyaQorICAgICAgUm93UmVzdWx0IHJyID0gZ2V0RnJvbU1FVEEocmVnaW9ubmFtZSwgSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZX0FSUkFZKTsKKyAgICAgIEhSZWdpb25JbmZvIGhyaSA9IGdldEhSZWdpb25JbmZvKHJyLmdldFJvdygpLCBycik7CisgICAgICBpZiAoc2VydmVybmFtZSA9PSBudWxsKSB7CisgICAgICAgIC8vIEdldCBzZXJ2ZXIgZnJvbSB0aGUgLk1FVEEuIGlmIGl0IHdhc24ndCBwYXNzZWQgYXMgYXJndW1lbnQKKyAgICAgICAgc2VydmVybmFtZSA9IFdyaXRhYmxlcy5jZWxsVG9TdHJpbmcocnIuZ2V0KENPTF9TRVJWRVIpKTsKKyAgICAgIH0KKyAgICAgIExPRy5pbmZvKCJNYXJraW5nICIgKyBocmkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKworICAgICAgICAiIGFzIGNsb3NlZCBvbiAiICsgc2VydmVybmFtZSArICI7IGNsZWFuaW5nIFNFUlZFUiArIFNUQVJUQ09ERTsgIiArCisgICAgICAgICAgIm1hc3RlciB3aWxsIHRlbGwgcmVnaW9uc2VydmVyIHRvIGNsb3NlIHJlZ2lvbiBvbiBuZXh0IGhlYXJ0YmVhdCIpOworICAgICAgdGhpcy5yZWdpb25NYW5hZ2VyLnNldENsb3Npbmcoc2VydmVybmFtZSwgaHJpLCBocmkuaXNPZmZsaW5lKCkpOworICAgICAgTWV0YVJlZ2lvbiBtZXRhID0gdGhpcy5yZWdpb25NYW5hZ2VyLmdldE1ldGFSZWdpb25Gb3JSb3cocmVnaW9ubmFtZSk7CisgICAgICBIUmVnaW9uSW50ZXJmYWNlIHNydnIgPSBnZXRNRVRBU2VydmVyKG1ldGEpOworICAgICAgSFJlZ2lvbi5jbGVhblJlZ2lvbkluTUVUQShzcnZyLCBtZXRhLmdldFJlZ2lvbk5hbWUoKSwgaHJpKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidW5zdXBwb3J0ZWQgbW9kaWZ5VGFibGUgb3AgIiArIG9wKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBTZXJ2ZXIgbWV0cmljcworICAgKi8KKyAgcHVibGljIE1hc3Rlck1ldHJpY3MgZ2V0TWV0cmljcygpIHsKKyAgICByZXR1cm4gdGhpcy5tZXRyaWNzOworICB9CisKKyAgLyoKKyAgICogTWFuYWdpbmcgbGVhc2VzCisgICAqLworCisgIC8qKgorICAgKiBAcmV0dXJuIFJldHVybiBjb25maWd1cmF0aW9uIGJlaW5nIHVzZWQgYnkgdGhpcyBzZXJ2ZXIuCisgICAqLworICBwdWJsaWMgSEJhc2VDb25maWd1cmF0aW9uIGdldENvbmZpZ3VyYXRpb24oKSB7CisgICAgcmV0dXJuIHRoaXMuY29uZjsKKyAgfQorICAgIAorICAvKgorICAgKiBHZXQgSFJlZ2lvbkluZm8gZnJvbSBwYXNzZWQgTUVUQSBtYXAgb2Ygcm93IHZhbHVlcy4KKyAgICogUmV0dXJucyBudWxsIGlmIG5vbmUgZm91bmQgKGFuZCBsb2dzIGZhY3QgdGhhdCBleHBlY3RlZCBDT0xfUkVHSU9OSU5GTworICAgKiB3YXMgbWlzc2luZykuICBVdGlsaXR5IG1ldGhvZCB1c2VkIGJ5IHNjYW5uZXJzIG9mIE1FVEEgdGFibGVzLgorICAgKiBAcGFyYW0gcm93IG5hbWUgb2YgdGhlIHJvdworICAgKiBAcGFyYW0gbWFwIE1hcCB0byBkbyBsb29rdXAgaW4uCisgICAqIEByZXR1cm4gTnVsbCBvciBmb3VuZCBIUmVnaW9uSW5mby4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgSFJlZ2lvbkluZm8gZ2V0SFJlZ2lvbkluZm8oZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIE1hcDxieXRlIFtdLCBDZWxsPiBtYXApCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQ2VsbCByZWdpb25pbmZvID0gbWFwLmdldChDT0xfUkVHSU9OSU5GTyk7CisgICAgaWYgKHJlZ2lvbmluZm8gPT0gbnVsbCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9ICBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgZm9yIChieXRlIFtdIGU6IG1hcC5rZXlTZXQoKSkgeworICAgICAgICBpZiAoc2IubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgICAgc2IuYXBwZW5kKCIsICIpOworICAgICAgICB9CisgICAgICAgIHNiLmFwcGVuZChCeXRlcy50b1N0cmluZyhlKSk7CisgICAgICB9CisgICAgICBMT0cud2FybihCeXRlcy50b1N0cmluZyhDT0xfUkVHSU9OSU5GTykgKyAiIGlzIGVtcHR5IGZvciByb3c6ICIgKworICAgICAgICAgQnl0ZXMudG9TdHJpbmcocm93KSArICI7IGhhcyBrZXlzOiAiICsgc2IudG9TdHJpbmcoKSk7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcmV0dXJuIFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mbyhyZWdpb25pbmZvLmdldFZhbHVlKCkpOworICB9CisKKyAgLyoKKyAgICogV2hlbiB3ZSBmaW5kIHJvd3MgaW4gYSBtZXRhIHJlZ2lvbiB0aGF0IGhhcyBhbiBlbXB0eSBIUmVnaW9uSW5mbywgd2UKKyAgICogY2xlYW4gdGhlbSB1cCBoZXJlLgorICAgKiAKKyAgICogQHBhcmFtIHMgY29ubmVjdGlvbiB0byBzZXJ2ZXIgc2VydmluZyBtZXRhIHJlZ2lvbgorICAgKiBAcGFyYW0gbWV0YVJlZ2lvbk5hbWUgbmFtZSBvZiB0aGUgbWV0YSByZWdpb24gd2Ugc2Nhbm5lZAorICAgKiBAcGFyYW0gZW1wdHlSb3dzIHRoZSByb3cga2V5cyB0aGF0IGhhZCBlbXB0eSBIUmVnaW9uSW5mb3MKKyAgICovCisgIHByb3RlY3RlZCB2b2lkIGRlbGV0ZUVtcHR5TWV0YVJvd3MoSFJlZ2lvbkludGVyZmFjZSBzLCAKKyAgICAgIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUsCisgICAgICBMaXN0PGJ5dGUgW10+IGVtcHR5Um93cykgeworICAgIGZvciAoYnl0ZSBbXSByZWdpb25OYW1lOiBlbXB0eVJvd3MpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhSZWdpb24ucmVtb3ZlUmVnaW9uRnJvbU1FVEEocywgbWV0YVJlZ2lvbk5hbWUsIHJlZ2lvbk5hbWUpOworICAgICAgICBMT0cud2FybigiUmVtb3ZlZCByZWdpb246ICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb25OYW1lKSArCisgICAgICAgICAgIiBmcm9tIG1ldGEgcmVnaW9uOiAiICsKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyhtZXRhUmVnaW9uTmFtZSkgKyAiIGJlY2F1c2UgSFJlZ2lvbkluZm8gd2FzIGVtcHR5Iik7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiZGVsZXRpbmcgcmVnaW9uOiAiICsgQnl0ZXMudG9TdHJpbmcocmVnaW9uTmFtZSkgKworICAgICAgICAgICAgIiBmcm9tIG1ldGEgcmVnaW9uOiAiICsgQnl0ZXMudG9TdHJpbmcobWV0YVJlZ2lvbk5hbWUpLCBlKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIFpLIHdyYXBwZXIgb2JqZWN0CisgICAqIEByZXR1cm4gdGhlIHpvb2tlZXBlciB3cmFwcGVyCisgICAqLworICBwdWJsaWMgWm9vS2VlcGVyV3JhcHBlciBnZXRab29LZWVwZXJXcmFwcGVyKCkgeworICAgIHJldHVybiB6b29LZWVwZXJXcmFwcGVyOworICB9CisgICAKKyAgLyoKKyAgICogTWFpbiBwcm9ncmFtCisgICAqLworCisgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRVc2FnZUFuZEV4aXQoKSB7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogamF2YSBvcmcuYXBhY2hlLmhiYXNlLkhNYXN0ZXIgIiArCisgICAgIlstLWJpbmQ9aG9zdG5hbWU6cG9ydF0gc3RhcnR8c3RvcCIpOworICAgIFN5c3RlbS5leGl0KDApOworICB9CisKKyAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGRvTWFpbihTdHJpbmcgW10gYXJncywKKyAgICAgIENsYXNzPD8gZXh0ZW5kcyBITWFzdGVyPiBtYXN0ZXJDbGFzcykgeworCisgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgeworICAgICAgcHJpbnRVc2FnZUFuZEV4aXQoKTsKKyAgICB9CisKKyAgICBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKworICAgIC8vIFByb2Nlc3MgY29tbWFuZC1saW5lIGFyZ3MuIFRPRE86IEJldHRlciBjbWQtbGluZSBwcm9jZXNzaW5nCisgICAgLy8gKGJ1dCBob3BlZnVsbHkgc29tZXRoaW5nIG5vdCBhcyBwYWluZnVsIGFzIGNsaSBvcHRpb25zKS4KKworICAgIGZpbmFsIFN0cmluZyBhZGRyZXNzQXJnS2V5ID0gIi0tYmluZD0iOworICAgIGZvciAoU3RyaW5nIGNtZDogYXJncykgeworICAgICAgaWYgKGNtZC5zdGFydHNXaXRoKGFkZHJlc3NBcmdLZXkpKSB7CisgICAgICAgIGNvbmYuc2V0KE1BU1RFUl9BRERSRVNTLCBjbWQuc3Vic3RyaW5nKGFkZHJlc3NBcmdLZXkubGVuZ3RoKCkpKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIGlmIChjbWQuZXF1YWxzKCJzdGFydCIpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgUnVudGltZU1YQmVhbiBydW50aW1lID0gTWFuYWdlbWVudEZhY3RvcnkuZ2V0UnVudGltZU1YQmVhbigpOworICAgICAgICAgIGlmIChydW50aW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJ2bU5hbWU9IiArIHJ1bnRpbWUuZ2V0Vm1OYW1lKCkgKyAiLCB2bVZlbmRvcj0iICsKKyAgICAgICAgICAgICAgcnVudGltZS5nZXRWbVZlbmRvcigpICsgIiwgdm1WZXJzaW9uPSIgKyBydW50aW1lLmdldFZtVmVyc2lvbigpKTsKKyAgICAgICAgICAgIExPRy5pbmZvKCJ2bUlucHV0QXJndW1lbnRzPSIgKyBydW50aW1lLmdldElucHV0QXJndW1lbnRzKCkpOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBJZiAnbG9jYWwnLCBkZWZlciB0byBMb2NhbEhCYXNlQ2x1c3RlciBpbnN0YW5jZS4KKyAgICAgICAgICBpZiAoTG9jYWxIQmFzZUNsdXN0ZXIuaXNMb2NhbChjb25mKSkgeworICAgICAgICAgICAgKG5ldyBMb2NhbEhCYXNlQ2x1c3Rlcihjb25mKSkuc3RhcnR1cCgpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgSE1hc3Rlcj4gYyA9CisgICAgICAgICAgICAgIG1hc3RlckNsYXNzLmdldENvbnN0cnVjdG9yKEhCYXNlQ29uZmlndXJhdGlvbi5jbGFzcyk7CisgICAgICAgICAgICBITWFzdGVyIG1hc3RlciA9IGMubmV3SW5zdGFuY2UoY29uZik7CisgICAgICAgICAgICBtYXN0ZXIuc3RhcnQoKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgTE9HLmVycm9yKCAiQ2FuIG5vdCBzdGFydCBtYXN0ZXIiLCB0KTsKKyAgICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGlmIChjbWQuZXF1YWxzKCJzdG9wIikpIHsKKyAgICAgICAgSEJhc2VBZG1pbiBhZG0gPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgIGFkbSA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgICAgICB9IGNhdGNoIChNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoIm1hc3RlciBpcyBub3QgcnVubmluZyIpOworICAgICAgICAgIFN5c3RlbS5leGl0KDApOworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgYWRtLnNodXRkb3duKCk7CisgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgTE9HLmVycm9yKCAiQ2FuIG5vdCBzdG9wIG1hc3RlciIsIHQpOworICAgICAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gUHJpbnQgb3V0IHVzYWdlIGlmIHdlIGdldCB0byBoZXJlLgorICAgICAgcHJpbnRVc2FnZUFuZEV4aXQoKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBNYWluIHByb2dyYW0KKyAgICogQHBhcmFtIGFyZ3MKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBbXSBhcmdzKSB7CisgICAgZG9NYWluKGFyZ3MsIEhNYXN0ZXIuY2xhc3MpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9JbnZhbGlkQ29sdW1uTmFtZUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc3OTQyMDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRG9Ob3RSZXRyeUlPRXhjZXB0aW9uOworCisKKy8qKgorICogVGhyb3duIHdoZW4gYW4gaW52YWxpZCBjb2x1bW4gbmFtZSBpcyBlbmNvdW50ZXJlZAorICovCitwdWJsaWMgY2xhc3MgSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24gZXh0ZW5kcyBEb05vdFJldHJ5SU9FeGNlcHRpb24geworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTCA8PCAyOSAtIDFMOworICAvKiogZGVmYXVsdCBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gcyBtZXNzYWdlCisgICAqLworICBwdWJsaWMgSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9NZXRhUmVnaW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvTWV0YVJlZ2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0ZjU3YjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvTWV0YVJlZ2lvbi5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisKKy8qKiBEZXNjcmliZXMgYSBtZXRhIHJlZ2lvbiBhbmQgaXRzIHNlcnZlciAqLworcHVibGljIGNsYXNzIE1ldGFSZWdpb24gaW1wbGVtZW50cyBDb21wYXJhYmxlPE1ldGFSZWdpb24+IHsKKyAgcHJpdmF0ZSBmaW5hbCBIU2VydmVyQWRkcmVzcyBzZXJ2ZXI7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lOworICBwcml2YXRlIGZpbmFsIGJ5dGUgW10gc3RhcnRLZXk7CisKKyAgTWV0YVJlZ2lvbihmaW5hbCBIU2VydmVyQWRkcmVzcyBzZXJ2ZXIsIGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSkgeworICAgIHRoaXMgKHNlcnZlciwgcmVnaW9uTmFtZSwgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1cpOworICB9CisKKyAgTWV0YVJlZ2lvbihmaW5hbCBIU2VydmVyQWRkcmVzcyBzZXJ2ZXIsIGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gc3RhcnRLZXkpIHsKKyAgICBpZiAoc2VydmVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oInNlcnZlciBjYW5ub3QgYmUgbnVsbCIpOworICAgIH0KKyAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjsKKyAgICBpZiAocmVnaW9uTmFtZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJyZWdpb25OYW1lIGNhbm5vdCBiZSBudWxsIik7CisgICAgfQorICAgIHRoaXMucmVnaW9uTmFtZSA9IHJlZ2lvbk5hbWU7CisgICAgdGhpcy5zdGFydEtleSA9IHN0YXJ0S2V5OworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gIntyZWdpb25uYW1lOiAiICsgQnl0ZXMudG9TdHJpbmcodGhpcy5yZWdpb25OYW1lKSArCisgICAgICAiLCBzdGFydEtleTogPCIgKyBCeXRlcy50b1N0cmluZyh0aGlzLnN0YXJ0S2V5KSArCisgICAgICAiPiwgc2VydmVyOiAiICsgdGhpcy5zZXJ2ZXIudG9TdHJpbmcoKSArICJ9IjsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSByZWdpb25OYW1lICovCisgIHB1YmxpYyBieXRlIFtdIGdldFJlZ2lvbk5hbWUoKSB7CisgICAgcmV0dXJuIHJlZ2lvbk5hbWU7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgc2VydmVyICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyBnZXRTZXJ2ZXIoKSB7CisgICAgcmV0dXJuIHNlcnZlcjsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBzdGFydEtleSAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRTdGFydEtleSgpIHsKKyAgICByZXR1cm4gc3RhcnRLZXk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CisgICAgcmV0dXJuIG8gaW5zdGFuY2VvZiBNZXRhUmVnaW9uICYmIHRoaXMuY29tcGFyZVRvKChNZXRhUmVnaW9uKW8pID09IDA7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICBpbnQgcmVzdWx0ID0gQXJyYXlzLmhhc2hDb2RlKHRoaXMucmVnaW9uTmFtZSk7CisgICAgcmVzdWx0IF49IEFycmF5cy5oYXNoQ29kZSh0aGlzLnN0YXJ0S2V5KTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gQ29tcGFyYWJsZQorCisgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE1ldGFSZWdpb24gb3RoZXIpIHsKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKHRoaXMucmVnaW9uTmFtZSwgb3RoZXIuZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICBpZihyZXN1bHQgPT0gMCkgeworICAgICAgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKHRoaXMuc3RhcnRLZXksIG90aGVyLmdldFN0YXJ0S2V5KCkpOworICAgICAgaWYgKHJlc3VsdCA9PSAwKSB7CisgICAgICAgIC8vIE1pZ2h0IGJlIG9uIGRpZmZlcmVudCBob3N0PworICAgICAgICByZXN1bHQgPSB0aGlzLnNlcnZlci5jb21wYXJlVG8ob3RoZXIuc2VydmVyKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9NZXRhU2Nhbm5lci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL01ldGFTY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM2MTljNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9NZXRhU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsMTgxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CisKKy8qKgorICogTWV0YVNjYW5uZXIgPGNvZGU+TUVUQTwvY29kZT4gdGFibGUuCisgKiAKKyAqIFdoZW4gYSA8Y29kZT5NRVRBPC9jb2RlPiBzZXJ2ZXIgY29tZXMgb24gbGluZSwgYSBNZXRhUmVnaW9uIG9iamVjdCBpcworICogcXVldWVkIHVwIGJ5IHJlZ2lvblNlcnZlclJlcG9ydCgpIGFuZCB0aGlzIHRocmVhZCB3YWtlcyB1cC4KKyAqCisgKiBJdCdzIGltcG9ydGFudCB0byBkbyB0aGlzIHdvcmsgaW4gYSBzZXBhcmF0ZSB0aHJlYWQsIG9yIGVsc2UgdGhlIGJsb2NraW5nIAorICogYWN0aW9uIHdvdWxkIHByZXZlbnQgb3RoZXIgd29yayBmcm9tIGdldHRpbmcgZG9uZS4KKyAqLworY2xhc3MgTWV0YVNjYW5uZXIgZXh0ZW5kcyBCYXNlU2Nhbm5lciB7CisgIC8qKiBJbml0aWFsIHdvcmsgZm9yIHRoZSBtZXRhIHNjYW5uZXIgaXMgcXVldWVkIHVwIGhlcmUgKi8KKyAgcHJpdmF0ZSB2b2xhdGlsZSBCbG9ja2luZ1F1ZXVlPE1ldGFSZWdpb24+IG1ldGFSZWdpb25zVG9TY2FuID0KKyAgICBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxNZXRhUmVnaW9uPigpOworICAgIAorICBwcml2YXRlIGZpbmFsIExpc3Q8TWV0YVJlZ2lvbj4gbWV0YVJlZ2lvbnNUb1Jlc2NhbiA9CisgICAgbmV3IEFycmF5TGlzdDxNZXRhUmVnaW9uPigpOworICAgIAorICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogCisgICAqIEBwYXJhbSBtYXN0ZXIKKyAgICovCisgIHB1YmxpYyBNZXRhU2Nhbm5lcihITWFzdGVyIG1hc3RlcikgeworICAgIHN1cGVyKG1hc3RlciwgZmFsc2UsIG1hc3Rlci5tZXRhUmVzY2FuSW50ZXJ2YWwsIG1hc3Rlci5zaHV0ZG93blJlcXVlc3RlZCk7CisgIH0KKworICAvLyBEb24ndCByZXRyeSBpZiB3ZSBnZXQgYW4gZXJyb3Igd2hpbGUgc2Nhbm5pbmcuIEVycm9ycyBhcmUgbW9zdCBvZnRlbgorICAvLyBjYXVzZWQgYnkgdGhlIHNlcnZlciBnb2luZyBhd2F5LiBXYWl0IHVudGlsIG5leHQgcmVzY2FuIGludGVydmFsIHdoZW4KKyAgLy8gdGhpbmdzIHNob3VsZCBiZSBiYWNrIHRvIG5vcm1hbC4KKyAgcHJpdmF0ZSBib29sZWFuIHNjYW5PbmVNZXRhUmVnaW9uKE1ldGFSZWdpb24gcmVnaW9uKSB7CisgICAgd2hpbGUgKCF0aGlzLm1hc3Rlci5jbG9zZWQuZ2V0KCkgJiYKKyAgICAgICAgIXRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuaXNJbml0aWFsUm9vdFNjYW5Db21wbGV0ZSgpICYmCisgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCkgPT0gbnVsbCkgeworICAgICAgc2xlZXAoKTsKKyAgICB9CisgICAgaWYgKHRoaXMubWFzdGVyLmNsb3NlZC5nZXQoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHRyeSB7CisgICAgICAvLyBEb24ndCBpbnRlcnJ1cHQgdXMgd2hpbGUgd2UncmUgd29ya2luZworICAgICAgc3luY2hyb25pemVkIChzY2FubmVyTG9jaykgeworICAgICAgICBzY2FuUmVnaW9uKHJlZ2lvbik7CisgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIucHV0TWV0YVJlZ2lvbk9ubGluZShyZWdpb24pOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUgPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZSk7CisgICAgICBMT0cud2FybigiU2NhbiBvbmUgTUVUQSByZWdpb246ICIgKyByZWdpb24udG9TdHJpbmcoKSwgZSk7CisgICAgICAvLyBUaGUgcmVnaW9uIG1heSBoYXZlIG1vdmVkIChUZXN0UmVnaW9uU2VydmVyQWJvcnQsIGV0Yy4pLiAgSWYKKyAgICAgIC8vIHNvLCBlaXRoZXIgaXQgd29uJ3QgYmUgaW4gdGhlIG9ubGluZU1ldGFSZWdpb25zIGxpc3Qgb3IgaXRzIGhvc3QKKyAgICAgIC8vIGFkZHJlc3MgaGFzIGNoYW5nZWQgYW5kIHRoZSBjb250YWluc1ZhbHVlIHdpbGwgZmFpbC4gSWYgbm90CisgICAgICAvLyBmb3VuZCwgYmVzdCB0aGluZyB0byBkbyBoZXJlIGlzIHByb2JhYmx5IHJldHVybi4KKyAgICAgIGlmICghdGhpcy5tYXN0ZXIucmVnaW9uTWFuYWdlci5pc01ldGFSZWdpb25PbmxpbmUocmVnaW9uLmdldFN0YXJ0S2V5KCkpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiU2Nhbm5lZCByZWdpb24gaXMgbm8gbG9uZ2VyIGluIG1hcCBvZiBvbmxpbmUgIiArCisgICAgICAgICJyZWdpb25zIG9yIGl0cyB2YWx1ZSBoYXMgY2hhbmdlZCIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBNYWtlIHN1cmUgdGhlIGZpbGUgc3lzdGVtIGlzIHN0aWxsIGF2YWlsYWJsZQorICAgICAgdGhpcy5tYXN0ZXIuY2hlY2tGaWxlU3lzdGVtKCk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIElmIGZvciBzb21lIHJlYXNvbiB3ZSBnZXQgc29tZSBvdGhlciBraW5kIG9mIGV4Y2VwdGlvbiwgCisgICAgICAvLyBhdCBsZWFzdCBsb2cgaXQgcmF0aGVyIHRoYW4gZ28gb3V0IHNpbGVudGx5LgorICAgICAgTE9HLmVycm9yKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIsIGUpOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBpbml0aWFsU2NhbigpIHsKKyAgICBNZXRhUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgd2hpbGUgKCF0aGlzLm1hc3Rlci5jbG9zZWQuZ2V0KCkgJiYKKyAgICAgICAgKHJlZ2lvbiA9PSBudWxsICYmIG1ldGFSZWdpb25zVG9TY2FuLnNpemUoKSA+IDApICYmCisgICAgICAgICAgIW1ldGFSZWdpb25zU2Nhbm5lZCgpKSB7CisgICAgICB0cnkgeworICAgICAgICByZWdpb24gPSBtZXRhUmVnaW9uc1RvU2Nhbi5wb2xsKHRoaXMubWFzdGVyLnRocmVhZFdha2VGcmVxdWVuY3ksIAorICAgICAgICAgIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICB9CisgICAgICBpZiAocmVnaW9uID09IG51bGwgJiYgbWV0YVJlZ2lvbnNUb1Jlc2Nhbi5zaXplKCkgIT0gMCkgeworICAgICAgICByZWdpb24gPSBtZXRhUmVnaW9uc1RvUmVzY2FuLnJlbW92ZSgwKTsKKyAgICAgIH0KKyAgICAgIGlmIChyZWdpb24gIT0gbnVsbCkgeworICAgICAgICBpZiAoIXNjYW5PbmVNZXRhUmVnaW9uKHJlZ2lvbikpIHsKKyAgICAgICAgICBtZXRhUmVnaW9uc1RvUmVzY2FuLmFkZChyZWdpb24pOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGluaXRpYWxTY2FuQ29tcGxldGUgPSB0cnVlOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIG1haW50ZW5hbmNlU2NhbigpIHsKKyAgICBMaXN0PE1ldGFSZWdpb24+IHJlZ2lvbnMgPQorICAgICAgdGhpcy5tYXN0ZXIucmVnaW9uTWFuYWdlci5nZXRMaXN0T2ZPbmxpbmVNZXRhUmVnaW9ucygpOworICAgIGludCByZWdpb25Db3VudCA9IDA7CisgICAgZm9yIChNZXRhUmVnaW9uIHI6IHJlZ2lvbnMpIHsKKyAgICAgIHNjYW5PbmVNZXRhUmVnaW9uKHIpOworICAgICAgcmVnaW9uQ291bnQrKzsKKyAgICB9CisgICAgTE9HLmluZm8oIkFsbCAiICsgcmVnaW9uQ291bnQgKyAiIC5NRVRBLiByZWdpb24ocykgc2Nhbm5lZCIpOworICAgIG1ldGFSZWdpb25zU2Nhbm5lZCgpOworICB9CisKKyAgLyoKKyAgICogQ2FsbGVkIGJ5IHRoZSBtZXRhIHNjYW5uZXIgd2hlbiBpdCBoYXMgY29tcGxldGVkIHNjYW5uaW5nIGFsbCBtZXRhIAorICAgKiByZWdpb25zLiBUaGlzIHdha2VzIHVwIGFueSB0aHJlYWRzIHRoYXQgd2VyZSB3YWl0aW5nIGZvciB0aGlzIHRvIGhhcHBlbi4KKyAgICogQHBhcmFtIHRvdGFsUm93cyBUb3RhbCByb3dzIHNjYW5uZWQuCisgICAqIEBwYXJhbSByZWdpb25Db3VudCBDb3VudCBvZiByZWdpb25zIGluICAuTUVUQS4gdGFibGUuCisgICAqIEByZXR1cm4gRmFsc2UgaWYgbnVtYmVyIG9mIG1ldGEgcmVnaW9ucyBtYXRjaGVzIGNvdW50IG9mIG9ubGluZSByZWdpb25zLgorICAgKi8KKyAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgYm9vbGVhbiBtZXRhUmVnaW9uc1NjYW5uZWQoKSB7CisgICAgaWYgKCF0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzSW5pdGlhbFJvb3RTY2FuQ29tcGxldGUoKSB8fAorICAgICAgICB0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLm51bU1ldGFSZWdpb25zKCkgIT0KKyAgICAgICAgICB0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLm51bU9ubGluZU1ldGFSZWdpb25zKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgbm90aWZ5QWxsKCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogT3RoZXIgdGhyZWFkcyBjYWxsIHRoaXMgbWV0aG9kIHRvIHdhaXQgdW50aWwgYWxsIHRoZSBtZXRhIHJlZ2lvbnMgaGF2ZQorICAgKiBiZWVuIHNjYW5uZWQuCisgICAqLworICBzeW5jaHJvbml6ZWQgYm9vbGVhbiB3YWl0Rm9yTWV0YVJlZ2lvbnNPckNsb3NlKCkgeworICAgIHdoaWxlICghdGhpcy5tYXN0ZXIuY2xvc2VkLmdldCgpKSB7CisgICAgICBzeW5jaHJvbml6ZWQgKG1hc3Rlci5yZWdpb25NYW5hZ2VyKSB7CisgICAgICAgIGlmICh0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzSW5pdGlhbFJvb3RTY2FuQ29tcGxldGUoKSAmJgorICAgICAgICAgICAgdGhpcy5tYXN0ZXIucmVnaW9uTWFuYWdlci5udW1NZXRhUmVnaW9ucygpID09CisgICAgICAgICAgICAgIHRoaXMubWFzdGVyLnJlZ2lvbk1hbmFnZXIubnVtT25saW5lTWV0YVJlZ2lvbnMoKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICB3YWl0KHRoaXMubWFzdGVyLnRocmVhZFdha2VGcmVxdWVuY3kpOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBjb250aW51ZQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdGhpcy5tYXN0ZXIuY2xvc2VkLmdldCgpOworICB9CisgIAorICAvKioKKyAgICogQWRkIGFub3RoZXIgbWV0YSByZWdpb24gdG8gc2NhbiB0byB0aGUgcXVldWUuCisgICAqLyAKKyAgdm9pZCBhZGRNZXRhUmVnaW9uVG9TY2FuKE1ldGFSZWdpb24gbSkgeworICAgIG1ldGFSZWdpb25zVG9TY2FuLmFkZChtKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Nb2RpZnlDb2x1bW4uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Nb2RpZnlDb2x1bW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNTBjYTVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL01vZGlmeUNvbHVtbi5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CisKKy8qKiBJbnN0YW50aWF0ZWQgdG8gbW9kaWZ5IGFuIGV4aXN0aW5nIGNvbHVtbiBmYW1pbHkgb24gYSB0YWJsZSAqLworY2xhc3MgTW9kaWZ5Q29sdW1uIGV4dGVuZHMgQ29sdW1uT3BlcmF0aW9uIHsKKyAgcHJpdmF0ZSBmaW5hbCBIQ29sdW1uRGVzY3JpcHRvciBkZXNjcmlwdG9yOworICBwcml2YXRlIGZpbmFsIGJ5dGUgW10gY29sdW1uTmFtZTsKKyAgCisgIE1vZGlmeUNvbHVtbihmaW5hbCBITWFzdGVyIG1hc3RlciwgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsIAorICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uTmFtZSwgSENvbHVtbkRlc2NyaXB0b3IgZGVzY3JpcHRvcikgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIobWFzdGVyLCB0YWJsZU5hbWUpOworICAgIHRoaXMuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgICAgdGhpcy5jb2x1bW5OYW1lID0gY29sdW1uTmFtZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBwb3N0UHJvY2Vzc01ldGEoTWV0YVJlZ2lvbiBtLCBIUmVnaW9uSW50ZXJmYWNlIHNlcnZlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKEhSZWdpb25JbmZvIGk6IHVuc2VydmVkUmVnaW9ucykgeworICAgICAgaWYgKGkuZ2V0VGFibGVEZXNjKCkuaGFzRmFtaWx5KGNvbHVtbk5hbWUpKSB7CisgICAgICAgIGkuZ2V0VGFibGVEZXNjKCkuYWRkRmFtaWx5KGRlc2NyaXB0b3IpOworICAgICAgICB1cGRhdGVSZWdpb25JbmZvKHNlcnZlciwgbS5nZXRSZWdpb25OYW1lKCksIGkpOworICAgICAgfSBlbHNlIHsgLy8gb3RoZXJ3aXNlLCB3ZSBoYXZlIGFuIGVycm9yLgorICAgICAgICB0aHJvdyBuZXcgSW52YWxpZENvbHVtbk5hbWVFeGNlcHRpb24oIkNvbHVtbiBmYW1pbHkgJyIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGNvbHVtbk5hbWUpICsgCisgICAgICAgICAgIicgZG9lc24ndCBleGlzdCwgc28gY2Fubm90IGJlIG1vZGlmaWVkLiIpOworICAgICAgfQorICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL01vZGlmeVRhYmxlTWV0YS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL01vZGlmeVRhYmxlTWV0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjYWE0YmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvTW9kaWZ5VGFibGVNZXRhLmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKKworLyoqIEluc3RhbnRpYXRlZCB0byBtb2RpZnkgdGFibGUgZGVzY3JpcHRvciBtZXRhZGF0YSAqLworY2xhc3MgTW9kaWZ5VGFibGVNZXRhIGV4dGVuZHMgVGFibGVPcGVyYXRpb24geworCisgIHByaXZhdGUgc3RhdGljIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhNb2RpZnlUYWJsZU1ldGEuY2xhc3MpOworCisgIHByaXZhdGUgSFRhYmxlRGVzY3JpcHRvciBkZXNjOworCisgIE1vZGlmeVRhYmxlTWV0YShmaW5hbCBITWFzdGVyIG1hc3RlciwgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUsIAorICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIobWFzdGVyLCB0YWJsZU5hbWUpOworICAgIHRoaXMuZGVzYyA9IGRlc2M7CisgICAgTE9HLmRlYnVnKCJtb2RpZnlpbmcgIiArIEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkgKyAiOiAiICsKKyAgICAgICAgZGVzYy50b1N0cmluZygpKTsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIHVwZGF0ZVJlZ2lvbkluZm8oSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXIsIGJ5dGUgW10gcmVnaW9uTmFtZSwKKyAgICBIUmVnaW9uSW5mbyBpKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUoaS5nZXRSZWdpb25OYW1lKCkpOworICAgIGIucHV0KENPTF9SRUdJT05JTkZPLCBXcml0YWJsZXMuZ2V0Qnl0ZXMoaSkpOworICAgIHNlcnZlci5iYXRjaFVwZGF0ZShyZWdpb25OYW1lLCBiLCAtMUwpOworICAgIExPRy5kZWJ1ZygidXBkYXRlZCBIVGFibGVEZXNjcmlwdG9yIGZvciByZWdpb24gIiArIGkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NTY2FuSXRlbShTdHJpbmcgc2VydmVyTmFtZSwKKyAgICAgIGZpbmFsIEhSZWdpb25JbmZvIGluZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzRW5hYmxlZChpbmZvKSkgeworICAgICAgdGhyb3cgbmV3IFRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb24oQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHBvc3RQcm9jZXNzTWV0YShNZXRhUmVnaW9uIG0sIEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoSFJlZ2lvbkluZm8gaTogdW5zZXJ2ZWRSZWdpb25zKSB7CisgICAgICBpLnNldFRhYmxlRGVzYyhkZXNjKTsKKyAgICAgIHVwZGF0ZVJlZ2lvbkluZm8oc2VydmVyLCBtLmdldFJlZ2lvbk5hbWUoKSwgaSk7CisgICAgfQorICAgIC8vIGtpY2sgb2ZmIGEgbWV0YSBzY2FuIHJpZ2h0IGF3YXkKKyAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5tZXRhU2Nhbm5lclRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL05vdEFsbE1ldGFSZWdpb25zT25saW5lRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmQ4YWI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL05vdEFsbE1ldGFSZWdpb25zT25saW5lRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRG9Ob3RSZXRyeUlPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGFuIG9wZXJhdGlvbiByZXF1aXJlcyB0aGUgcm9vdCBhbmQgYWxsIG1ldGEgcmVnaW9ucyB0byBiZSBvbmxpbmUKKyAqLworcHVibGljIGNsYXNzIE5vdEFsbE1ldGFSZWdpb25zT25saW5lRXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjQzOTc4NjE1Nzg3NDgyNzUyM0w7CisKKyAgLyoqCisgICAqIGRlZmF1bHQgY29uc3RydWN0b3IKKyAgICovCisgIHB1YmxpYyBOb3RBbGxNZXRhUmVnaW9uc09ubGluZUV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBtZXNzYWdlCisgICAqLworICBwdWJsaWMgTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1JlZ2lvbkNsb3NlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1JlZ2lvbkNsb3NlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTUzNzM2MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Qcm9jZXNzUmVnaW9uQ2xvc2UuamF2YQpAQCAtMCwwICsxLDkyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworCisvKioKKyAqIFByb2Nlc3NSZWdpb25DbG9zZSBpcyB0aGUgd2F5IHdlIGRvIHBvc3QtcHJvY2Vzc2luZyBvbiBhIGNsb3NlZCByZWdpb24uIFdlCisgKiBvbmx5IHNwYXduIG9uZSBvZiB0aGVzZSBhc3luY2hyb25vdXMgdGFza3Mgd2hlbiB0aGUgcmVnaW9uIG5lZWRzIHRvIGJlIAorICogZWl0aGVyIG9mZmxpbmVkIG9yIGRlbGV0ZWQuIFdlIHVzZWQgdG8gY3JlYXRlIG9uZSBvZiB0aGVzZSB0YXNrcyB3aGVuZXZlcgorICogYSByZWdpb24gd2FzIGNsb3NlZCwgYnV0IHNpbmNlIGNsb3NpbmcgYSByZWdpb24gdGhhdCBpc24ndCBiZWluZyBvZmZsaW5lZAorICogb3IgZGVsZXRlZCBkb2Vzbid0IGFjdHVhbGx5IHJlcXVpcmUgcG9zdCBwcm9jZXNzaW5nLCBpdCdzIG5vIGxvbmdlciAKKyAqIG5lY2Vzc2FyeS4KKyAqLworY2xhc3MgUHJvY2Vzc1JlZ2lvbkNsb3NlIGV4dGVuZHMgUHJvY2Vzc1JlZ2lvblN0YXR1c0NoYW5nZSB7CisgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIG9mZmxpbmVSZWdpb247CisgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHJlYXNzaWduUmVnaW9uOworCisgIC8qKgorICAqIEBwYXJhbSBtYXN0ZXIKKyAgKiBAcGFyYW0gcmVnaW9uSW5mbyBSZWdpb24gdG8gb3BlcmF0ZSBvbgorICAqIEBwYXJhbSBvZmZsaW5lUmVnaW9uIGlmIHRydWUsIHNldCB0aGUgcmVnaW9uIHRvIG9mZmxpbmUgaW4gbWV0YQorICAqIEBwYXJhbSByZWFzc2lnblJlZ2lvbiBpZiB0cnVlLCByZWdpb24gaXMgdG8gYmUgcmVhc3NpZ25lZAorICAqLworICBwdWJsaWMgUHJvY2Vzc1JlZ2lvbkNsb3NlKEhNYXN0ZXIgbWFzdGVyLCBIUmVnaW9uSW5mbyByZWdpb25JbmZvLCAKKyAgICAgIGJvb2xlYW4gb2ZmbGluZVJlZ2lvbiwgYm9vbGVhbiByZWFzc2lnblJlZ2lvbikgeworCisgICBzdXBlcihtYXN0ZXIsIHJlZ2lvbkluZm8pOworICAgdGhpcy5vZmZsaW5lUmVnaW9uID0gb2ZmbGluZVJlZ2lvbjsKKyAgIHRoaXMucmVhc3NpZ25SZWdpb24gPSByZWFzc2lnblJlZ2lvbjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiUHJvY2Vzc1JlZ2lvbkNsb3NlIG9mICIgKyB0aGlzLnJlZ2lvbkluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKworICAgICAgIiwgIiArIHRoaXMub2ZmbGluZVJlZ2lvbjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm9jZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCb29sZWFuIHJlc3VsdCA9IG51bGw7CisgICAgaWYgKG9mZmxpbmVSZWdpb24pIHsKKyAgICAgIHJlc3VsdCA9CisgICAgICAgIG5ldyBSZXRyeWFibGVNZXRhT3BlcmF0aW9uPEJvb2xlYW4+KGdldE1ldGFSZWdpb24oKSwgdGhpcy5tYXN0ZXIpIHsKKyAgICAgICAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJyZWdpb24gY2xvc2VkOiAiICsgcmVnaW9uSW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisKKyAgICAgICAgICAgIC8vIFdlIGNhbid0IHByb2NlZWQgdW5sZXNzIHRoZSBtZXRhIHJlZ2lvbiB3ZSBhcmUgZ29pbmcgdG8gdXBkYXRlCisgICAgICAgICAgICAvLyBpcyBvbmxpbmUuIG1ldGFSZWdpb25BdmFpbGFibGUoKSB3aWxsIHB1dCB0aGlzIG9wZXJhdGlvbiBvbiB0aGUKKyAgICAgICAgICAgIC8vIGRlbGF5ZWRUb0RvUXVldWUsIHNvIHJldHVybiB0cnVlIHNvIHRoZSBvcGVyYXRpb24gaXMgbm90IHB1dCAKKyAgICAgICAgICAgIC8vIGJhY2sgb24gdGhlIHRvRG9RdWV1ZQorCisgICAgICAgICAgICBpZiAobWV0YVJlZ2lvbkF2YWlsYWJsZSgpKSB7CisgICAgICAgICAgICAgIC8vIG9mZmxpbmUgdGhlIHJlZ2lvbiBpbiBtZXRhIGFuZCB0aGVuIHJlbW92ZSBpdCBmcm9tIHRoZQorICAgICAgICAgICAgICAvLyBzZXQgb2YgcmVnaW9ucyBpbiB0cmFuc2l0aW9uCisgICAgICAgICAgICAgIEhSZWdpb24ub2ZmbGluZVJlZ2lvbkluTUVUQShzZXJ2ZXIsIG1ldGFSZWdpb25OYW1lLAorICAgICAgICAgICAgICAgICAgcmVnaW9uSW5mbyk7CisgICAgICAgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLnJlbW92ZVJlZ2lvbihyZWdpb25JbmZvKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfS5kb1dpdGhSZXRyaWVzKCk7CisgICAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PSBudWxsID8gdHJ1ZSA6IHJlc3VsdDsKKworICAgIH0gZWxzZSBpZiAocmVhc3NpZ25SZWdpb24pIHsKKyAgICAgIC8vIHdlIGFyZSByZWFzc2lnbmluZyB0aGUgcmVnaW9uIGV2ZW50dWFsbHksIHNvIHNldCBpdCB1bmFzc2lnbmVkCisgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRVbmFzc2lnbmVkKHJlZ2lvbkluZm8sIGZhbHNlKTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyB0cnVlIDogcmVzdWx0OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1JlZ2lvbk9wZW4uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Qcm9jZXNzUmVnaW9uT3Blbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhYjJiN2IKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1JlZ2lvbk9wZW4uamF2YQpAQCAtMCwwICsxLDEyNiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVySW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZWdpb25IaXN0b3JpYW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIAorICogUHJvY2Vzc1JlZ2lvbk9wZW4gaXMgaW5zdGFudGlhdGVkIHdoZW4gYSByZWdpb24gc2VydmVyIHJlcG9ydHMgdGhhdCBpdCBpcworICogc2VydmluZyBhIHJlZ2lvbi4gVGhpcyBhcHBsaWVzIHRvIGFsbCBtZXRhIGFuZCB1c2VyIHJlZ2lvbnMgZXhjZXB0IHRoZSAKKyAqIHJvb3QgcmVnaW9uIHdoaWNoIGlzIGhhbmRsZWQgc3BlY2lhbGx5LgorICovCitjbGFzcyBQcm9jZXNzUmVnaW9uT3BlbiBleHRlbmRzIFByb2Nlc3NSZWdpb25TdGF0dXNDaGFuZ2UgeworICBwcm90ZWN0ZWQgZmluYWwgSFNlcnZlckluZm8gc2VydmVySW5mbzsKKworICAvKioKKyAgICogQHBhcmFtIG1hc3RlcgorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUHJvY2Vzc1JlZ2lvbk9wZW4oSE1hc3RlciBtYXN0ZXIsIEhTZXJ2ZXJJbmZvIGluZm8sCisgICAgICBIUmVnaW9uSW5mbyByZWdpb25JbmZvKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKG1hc3RlciwgcmVnaW9uSW5mbyk7CisgICAgaWYgKGluZm8gPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJIU2VydmVySW5mbyBjYW5ub3QgYmUgbnVsbDsgIiArCisgICAgICAgICJoYmFzZS05NTggZGVidWdnaW5nIik7CisgICAgfQorICAgIHRoaXMuc2VydmVySW5mbyA9IGluZm87CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gIlBlbmRpbmdPcGVuT3BlcmF0aW9uIGZyb20gIiArIEhTZXJ2ZXJJbmZvLmdldFNlcnZlck5hbWUoc2VydmVySW5mbyk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvY2VzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQm9vbGVhbiByZXN1bHQgPQorICAgICAgbmV3IFJldHJ5YWJsZU1ldGFPcGVyYXRpb248Qm9vbGVhbj4oZ2V0TWV0YVJlZ2lvbigpLCB0aGlzLm1hc3RlcikgeworICAgICAgICBwcml2YXRlIGZpbmFsIFJlZ2lvbkhpc3RvcmlhbiBoaXN0b3JpYW4gPSBSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKTsKKyAgICAgIAorICAgICAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICBMT0cuaW5mbyhyZWdpb25JbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpICsgIiBvcGVuIG9uICIgKworICAgICAgICAgICAgc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgaWYgKCFtZXRhUmVnaW9uQXZhaWxhYmxlKCkpIHsKKyAgICAgICAgICAgIC8vIFdlIGNhbid0IHByb2NlZWQgdW5sZXNzIHRoZSBtZXRhIHJlZ2lvbiB3ZSBhcmUgZ29pbmcgdG8gdXBkYXRlCisgICAgICAgICAgICAvLyBpcyBvbmxpbmUuIG1ldGFSZWdpb25BdmFpbGFibGUoKSBoYXMgcHV0IHRoaXMgb3BlcmF0aW9uIG9uIHRoZQorICAgICAgICAgICAgLy8gZGVsYXllZFRvRG9RdWV1ZSwgc28gcmV0dXJuIHRydWUgc28gdGhlIG9wZXJhdGlvbiBpcyBub3QgcHV0IAorICAgICAgICAgICAgLy8gYmFjayBvbiB0aGUgdG9Eb1F1ZXVlCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBSZWdpc3RlciB0aGUgbmV3bHktYXZhaWxhYmxlIFJlZ2lvbidzIGxvY2F0aW9uLgorICAgICAgICAgIExPRy5pbmZvKCJ1cGRhdGluZyByb3cgIiArIHJlZ2lvbkluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKworICAgICAgICAgICAgICAiIGluIHJlZ2lvbiAiICsgQnl0ZXMudG9TdHJpbmcobWV0YVJlZ2lvbk5hbWUpICsgIiB3aXRoICIgKworICAgICAgICAgICAgICAiIHdpdGggc3RhcnRjb2RlICIgKyBzZXJ2ZXJJbmZvLmdldFN0YXJ0Q29kZSgpICsgIiBhbmQgc2VydmVyICIgKworICAgICAgICAgICAgICBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKSk7CisgICAgICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShyZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICAgICAgYi5wdXQoQ09MX1NFUlZFUiwKKyAgICAgICAgICAgICAgQnl0ZXMudG9CeXRlcyhzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKS50b1N0cmluZygpKSk7CisgICAgICAgICAgYi5wdXQoQ09MX1NUQVJUQ09ERSwgQnl0ZXMudG9CeXRlcyhzZXJ2ZXJJbmZvLmdldFN0YXJ0Q29kZSgpKSk7CisgICAgICAgICAgc2VydmVyLmJhdGNoVXBkYXRlKG1ldGFSZWdpb25OYW1lLCBiLCAtMUwpOworICAgICAgICAgIGlmICghdGhpcy5oaXN0b3JpYW4uaXNPbmxpbmUoKSkgeworICAgICAgICAgICAgLy8gVGhpcyBpcyBzYWZlc3QgcGxhY2UgdG8gZG8gdGhlIG9ubGluaW5nIG9mIHRoZSBoaXN0b3JpYW4gaW4KKyAgICAgICAgICAgIC8vIHRoZSBtYXN0ZXIuICBXaGVuIHdlIGdldCB0byBoZXJlLCB3ZSBrbm93IHRoZXJlIGlzIGEgLk1FVEEuCisgICAgICAgICAgICAvLyBmb3IgdGhlIGhpc3RvcmlhbiB0byBnbyBhZ2FpbnN0LgorICAgICAgICAgICAgdGhpcy5oaXN0b3JpYW4ub25saW5lKHRoaXMubWFzdGVyLmdldENvbmZpZ3VyYXRpb24oKSk7CisgICAgICAgICAgfQorICAgICAgICAgIHRoaXMuaGlzdG9yaWFuLmFkZFJlZ2lvbk9wZW4ocmVnaW9uSW5mbywgc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkpOworICAgICAgICAgIHN5bmNocm9uaXplZCAobWFzdGVyLnJlZ2lvbk1hbmFnZXIpIHsKKyAgICAgICAgICAgIGlmIChpc01ldGFUYWJsZSkgeworICAgICAgICAgICAgICAvLyBJdCdzIGEgbWV0YSByZWdpb24uCisgICAgICAgICAgICAgIE1ldGFSZWdpb24gbSA9CisgICAgICAgICAgICAgICAgbmV3IE1ldGFSZWdpb24obmV3IEhTZXJ2ZXJBZGRyZXNzKHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpKSwKKyAgICAgICAgICAgICAgICAgIHJlZ2lvbkluZm8uZ2V0UmVnaW9uTmFtZSgpLCByZWdpb25JbmZvLmdldFN0YXJ0S2V5KCkpOworICAgICAgICAgICAgICBpZiAoIW1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzSW5pdGlhbE1ldGFTY2FuQ29tcGxldGUoKSkgeworICAgICAgICAgICAgICAgIC8vIFB1dCBpdCBvbiB0aGUgcXVldWUgdG8gYmUgc2Nhbm5lZCBmb3IgdGhlIGZpcnN0IHRpbWUuCisgICAgICAgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICAgICAgICBMT0cuZGVidWcoIkFkZGluZyAiICsgbS50b1N0cmluZygpICsgIiB0byByZWdpb25zIHRvIHNjYW4iKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuYWRkTWV0YVJlZ2lvblRvU2NhbihtKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBBZGQgaXQgdG8gdGhlIG9ubGluZSBtZXRhIHJlZ2lvbnMKKyAgICAgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgIExPRy5kZWJ1ZygiQWRkaW5nIHRvIG9ubGluZU1ldGFSZWdpb25zOiAiICsgbS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIucHV0TWV0YVJlZ2lvbk9ubGluZShtKTsKKyAgICAgICAgICAgICAgICAvLyBJbnRlcnJ1cHRpbmcgdGhlIE1ldGEgU2Nhbm5lciBzbGVlcCBzbyB0aGF0IGl0IGNhbgorICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgcmVnaW9ucyByaWdodCBhd2F5CisgICAgICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIubWV0YVNjYW5uZXJUaHJlYWQuaW50ZXJydXB0KCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIElmIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5LCByZW1vdmUgZnJvbSBwZW5kaW5nIGxpc3QuCisgICAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5yZW1vdmVSZWdpb24ocmVnaW9uSW5mbyk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9LmRvV2l0aFJldHJpZXMoKTsKKyAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyB0cnVlIDogcmVzdWx0OworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1Byb2Nlc3NSZWdpb25TdGF0dXNDaGFuZ2UuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Qcm9jZXNzUmVnaW9uU3RhdHVzQ2hhbmdlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTBlZjBlMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Qcm9jZXNzUmVnaW9uU3RhdHVzQ2hhbmdlLmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CisKKy8qKgorICogQWJzdHJhY3QgY2xhc3MgdGhhdCBwZXJmb3JtcyBjb21tb24gb3BlcmF0aW9ucyBmb3IgCisgKiBAc2VlICNQcm9jZXNzUmVnaW9uQ2xvc2UgYW5kIEBzZWUgI1Byb2Nlc3NSZWdpb25PcGVuCisgKi8KK2Fic3RyYWN0IGNsYXNzIFByb2Nlc3NSZWdpb25TdGF0dXNDaGFuZ2UgZXh0ZW5kcyBSZWdpb25TZXJ2ZXJPcGVyYXRpb24geworICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc01ldGFUYWJsZTsKKyAgcHJvdGVjdGVkIGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm87CisgIHByaXZhdGUgdm9sYXRpbGUgTWV0YVJlZ2lvbiBtZXRhUmVnaW9uID0gbnVsbDsKKyAgcHJvdGVjdGVkIHZvbGF0aWxlIGJ5dGVbXSBtZXRhUmVnaW9uTmFtZSA9IG51bGw7CisgIAorICAvKioKKyAgICogQHBhcmFtIG1hc3RlcgorICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKi8KKyAgcHVibGljIFByb2Nlc3NSZWdpb25TdGF0dXNDaGFuZ2UoSE1hc3RlciBtYXN0ZXIsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm8pIHsKKyAgICBzdXBlcihtYXN0ZXIpOworICAgIHRoaXMucmVnaW9uSW5mbyA9IHJlZ2lvbkluZm87CisgICAgdGhpcy5pc01ldGFUYWJsZSA9IHJlZ2lvbkluZm8uaXNNZXRhVGFibGUoKTsKKyAgfQorICAKKyAgcHJvdGVjdGVkIGJvb2xlYW4gbWV0YVJlZ2lvbkF2YWlsYWJsZSgpIHsKKyAgICBib29sZWFuIGF2YWlsYWJsZSA9IHRydWU7CisgICAgaWYgKGlzTWV0YVRhYmxlKSB7CisgICAgICAvLyBUaGlzIG9wZXJhdGlvbiBpcyBmb3IgdGhlIG1ldGEgdGFibGUKKyAgICAgIGlmICghcm9vdEF2YWlsYWJsZSgpKSB7CisgICAgICAgIC8vIEJ1dCB3ZSBjYW4ndCBwcm9jZWVkIHVubGVzcyB0aGUgcm9vdCByZWdpb24gaXMgYXZhaWxhYmxlCisgICAgICAgIGF2YWlsYWJsZSA9IGZhbHNlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoIW1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzSW5pdGlhbFJvb3RTY2FuQ29tcGxldGUoKSB8fAorICAgICAgICAgICFtZXRhVGFibGVBdmFpbGFibGUoKSkgeworICAgICAgICAvLyBUaGUgcm9vdCByZWdpb24gaGFzIG5vdCBiZWVuIHNjYW5uZWQgb3IgdGhlIG1ldGEgdGFibGUgaXMgbm90CisgICAgICAgIC8vIGF2YWlsYWJsZSBzbyB3ZSBjYW4ndCBwcm9jZWVkLgorICAgICAgICAvLyBQdXQgdGhlIG9wZXJhdGlvbiBvbiB0aGUgZGVsYXllZFRvRG9RdWV1ZQorICAgICAgICByZXF1ZXVlKCk7CisgICAgICAgIGF2YWlsYWJsZSA9IGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gYXZhaWxhYmxlOworICB9CisKKyAgcHJvdGVjdGVkIE1ldGFSZWdpb24gZ2V0TWV0YVJlZ2lvbigpIHsKKyAgICBpZiAoaXNNZXRhVGFibGUpIHsKKyAgICAgIHRoaXMubWV0YVJlZ2lvbk5hbWUgPSBIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8uZ2V0UmVnaW9uTmFtZSgpOworICAgICAgdGhpcy5tZXRhUmVnaW9uID0gbmV3IE1ldGFSZWdpb24obWFzdGVyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpLAorICAgICAgICAgIHRoaXMubWV0YVJlZ2lvbk5hbWUsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICB9IGVsc2UgeworICAgICAgdGhpcy5tZXRhUmVnaW9uID0KKyAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuZ2V0Rmlyc3RNZXRhUmVnaW9uRm9yUmVnaW9uKHJlZ2lvbkluZm8pOworICAgICAgdGhpcy5tZXRhUmVnaW9uTmFtZSA9IHRoaXMubWV0YVJlZ2lvbi5nZXRSZWdpb25OYW1lKCk7CisgICAgfQorICAgIHJldHVybiB0aGlzLm1ldGFSZWdpb247CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1NlcnZlclNodXRkb3duLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUHJvY2Vzc1NlcnZlclNodXRkb3duLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM1ZDc5MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Qcm9jZXNzU2VydmVyU2h1dGRvd24uamF2YQpAQCAtMCwwICsxLDMxOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhMb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CisKKy8qKiAKKyAqIEluc3RhbnRpYXRlZCB3aGVuIGEgc2VydmVyJ3MgbGVhc2UgaGFzIGV4cGlyZWQsIG1lYW5pbmcgaXQgaGFzIGNyYXNoZWQuCisgKiBUaGUgcmVnaW9uIHNlcnZlcidzIGxvZyBmaWxlIG5lZWRzIHRvIGJlIHNwbGl0IHVwIGZvciBlYWNoIHJlZ2lvbiBpdCB3YXMKKyAqIHNlcnZpbmcsIGFuZCB0aGUgcmVnaW9ucyBuZWVkIHRvIGdldCByZWFzc2lnbmVkLgorICovCitjbGFzcyBQcm9jZXNzU2VydmVyU2h1dGRvd24gZXh0ZW5kcyBSZWdpb25TZXJ2ZXJPcGVyYXRpb24geworICBwcml2YXRlIGZpbmFsIFN0cmluZyBkZWFkU2VydmVyOworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcm9vdFJlZ2lvblNlcnZlcjsKKyAgcHJpdmF0ZSBib29sZWFuIHJvb3RSZWdpb25SZWFzc2lnbmVkID0gZmFsc2U7CisgIHByaXZhdGUgUGF0aCBvbGRMb2dEaXI7CisgIHByaXZhdGUgYm9vbGVhbiBsb2dTcGxpdDsKKyAgcHJpdmF0ZSBib29sZWFuIHJvb3RSZXNjYW5uZWQ7CisgIAorCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFRvRG9FbnRyeSB7CisgICAgYm9vbGVhbiByZWdpb25PZmZsaW5lOworICAgIGZpbmFsIGJ5dGUgW10gcm93OworICAgIGZpbmFsIEhSZWdpb25JbmZvIGluZm87CisKKyAgICBUb0RvRW50cnkoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIEhSZWdpb25JbmZvIGluZm8pIHsKKyAgICAgIHRoaXMucmVnaW9uT2ZmbGluZSA9IGZhbHNlOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLmluZm8gPSBpbmZvOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbWFzdGVyCisgICAqIEBwYXJhbSBzZXJ2ZXJJbmZvCisgICAqIEBwYXJhbSByb290UmVnaW9uU2VydmVyCisgICAqLworICBwdWJsaWMgUHJvY2Vzc1NlcnZlclNodXRkb3duKEhNYXN0ZXIgbWFzdGVyLCBIU2VydmVySW5mbyBzZXJ2ZXJJbmZvLAorICAgICAgYm9vbGVhbiByb290UmVnaW9uU2VydmVyKSB7CisgICAgc3VwZXIobWFzdGVyKTsKKyAgICB0aGlzLmRlYWRTZXJ2ZXIgPSBIU2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKHNlcnZlckluZm8pOworICAgIHRoaXMucm9vdFJlZ2lvblNlcnZlciA9IHJvb3RSZWdpb25TZXJ2ZXI7CisgICAgdGhpcy5sb2dTcGxpdCA9IGZhbHNlOworICAgIHRoaXMucm9vdFJlc2Nhbm5lZCA9IGZhbHNlOworICAgIHRoaXMub2xkTG9nRGlyID0KKyAgICAgIG5ldyBQYXRoKG1hc3Rlci5yb290ZGlyLCBITG9nLmdldEhMb2dEaXJlY3RvcnlOYW1lKHNlcnZlckluZm8pKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIHJldHVybiAiUHJvY2Vzc1NlcnZlclNodXRkb3duIG9mICIgKyB0aGlzLmRlYWRTZXJ2ZXI7CisgIH0KKworICAvKiogRmluZHMgcmVnaW9ucyB0aGF0IHRoZSBkZWFkIHJlZ2lvbiBzZXJ2ZXIgd2FzIHNlcnZpbmcKKyAgICovCisgIHByb3RlY3RlZCB2b2lkIHNjYW5NZXRhUmVnaW9uKEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyLCBsb25nIHNjYW5uZXJJZCwKKyAgICBieXRlIFtdIHJlZ2lvbk5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTGlzdDxUb0RvRW50cnk+IHRvRG9MaXN0ID0gbmV3IEFycmF5TGlzdDxUb0RvRW50cnk+KCk7CisgICAgU2V0PEhSZWdpb25JbmZvPiByZWdpb25zID0gbmV3IEhhc2hTZXQ8SFJlZ2lvbkluZm8+KCk7CisgICAgTGlzdDxieXRlIFtdPiBlbXB0eVJvd3MgPSBuZXcgQXJyYXlMaXN0PGJ5dGUgW10+KCk7CisgICAgdHJ5IHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIFJvd1Jlc3VsdCB2YWx1ZXMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgIHZhbHVlcyA9IHNlcnZlci5uZXh0KHNjYW5uZXJJZCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoIlNodXRkb3duIHNjYW5uaW5nIG9mIG1ldGEgcmVnaW9uIiwKKyAgICAgICAgICAgIFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHZhbHVlcyA9PSBudWxsIHx8IHZhbHVlcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJ5dGUgW10gcm93ID0gdmFsdWVzLmdldFJvdygpOworICAgICAgICAvLyBDaGVjayBzZXJ2ZXIgbmFtZS4gIElmIG51bGwsIHNraXAgKFdlIHVzZWQgdG8gY29uc2lkZXIgaXQgd2FzIG9uCisgICAgICAgIC8vIHNodXRkb3duIHNlcnZlciBidXQgdGhhdCB3b3VsZCBtZWFuIHRoYXQgd2UnZCByZWFzc2lnbiByZWdpb25zIHRoYXQKKyAgICAgICAgLy8gd2VyZSBhbHJlYWR5IG91dCBiZWluZyBhc3NpZ25lZCwgb25lcyB0aGF0IHdlcmUgcHJvZHVjdCBvZiBhIHNwbGl0CisgICAgICAgIC8vIHRoYXQgaGFwcGVuZWQgd2hpbGUgdGhlIHNodXRkb3duIHdhcyBiZWluZyBwcm9jZXNzZWQuCisgICAgICAgIFN0cmluZyBzZXJ2ZXJBZGRyZXNzID0gV3JpdGFibGVzLmNlbGxUb1N0cmluZyh2YWx1ZXMuZ2V0KENPTF9TRVJWRVIpKTsKKyAgICAgICAgbG9uZyBzdGFydENvZGUgPSBXcml0YWJsZXMuY2VsbFRvTG9uZyh2YWx1ZXMuZ2V0KENPTF9TVEFSVENPREUpKTsgCisgICAgICAgIFN0cmluZyBzZXJ2ZXJOYW1lID0gbnVsbDsKKyAgICAgICAgaWYgKHNlcnZlckFkZHJlc3MgIT0gbnVsbCAmJiBzZXJ2ZXJBZGRyZXNzLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgIHNlcnZlck5hbWUgPSBIU2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKHNlcnZlckFkZHJlc3MsIHN0YXJ0Q29kZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNlcnZlck5hbWUgPT0gbnVsbCB8fCAhZGVhZFNlcnZlci5lcXVhbHMoc2VydmVyTmFtZSkpIHsKKyAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSBzZXJ2ZXIgeW91J3JlIGxvb2tpbmcgZm9yIC0gbW92ZSBhbG9uZworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpICYmIHJvdyAhPSBudWxsKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJTaHV0ZG93biBzY2FubmVyIGZvciAiICsgc2VydmVyTmFtZSArICIgcHJvY2Vzc2luZyAiICsKKyAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHJvdykpOworICAgICAgICB9CisKKyAgICAgICAgSFJlZ2lvbkluZm8gaW5mbyA9IG1hc3Rlci5nZXRIUmVnaW9uSW5mbyhyb3csIHZhbHVlcyk7CisgICAgICAgIGlmIChpbmZvID09IG51bGwpIHsKKyAgICAgICAgICBlbXB0eVJvd3MuYWRkKHJvdyk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBzeW5jaHJvbml6ZWQgKG1hc3Rlci5yZWdpb25NYW5hZ2VyKSB7CisgICAgICAgICAgaWYgKGluZm8uaXNNZXRhVGFibGUoKSkgeworICAgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICAgIExPRy5kZWJ1ZygicmVtb3ZpbmcgbWV0YSByZWdpb24gIiArCisgICAgICAgICAgICAgICAgICBCeXRlcy50b1N0cmluZyhpbmZvLmdldFJlZ2lvbk5hbWUoKSkgKworICAgICAgICAgICAgICAiIGZyb20gb25saW5lIG1ldGEgcmVnaW9ucyIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIub2ZmbGluZU1ldGFSZWdpb24oaW5mby5nZXRTdGFydEtleSgpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBUb0RvRW50cnkgdG9kbyA9IG5ldyBUb0RvRW50cnkocm93LCBpbmZvKTsKKyAgICAgICAgICB0b0RvTGlzdC5hZGQodG9kbyk7CisKKyAgICAgICAgICBpZiAobWFzdGVyLnJlZ2lvbk1hbmFnZXIuaXNPZmZsaW5lZChpbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKSB8fAorICAgICAgICAgICAgICBpbmZvLmlzT2ZmbGluZSgpKSB7CisgICAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5yZW1vdmVSZWdpb24oaW5mbyk7CisgICAgICAgICAgICAvLyBNYXJrIHJlZ2lvbiBvZmZsaW5lCisgICAgICAgICAgICBpZiAoIWluZm8uaXNPZmZsaW5lKCkpIHsKKyAgICAgICAgICAgICAgdG9kby5yZWdpb25PZmZsaW5lID0gdHJ1ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKCFpbmZvLmlzT2ZmbGluZSgpICYmICFpbmZvLmlzU3BsaXQoKSkgeworICAgICAgICAgICAgICAvLyBHZXQgcmVnaW9uIHJlYXNzaWduZWQKKyAgICAgICAgICAgICAgcmVnaW9ucy5hZGQoaW5mbyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChzY2FubmVySWQgIT0gLTFMKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgc2VydmVyLmNsb3NlKHNjYW5uZXJJZCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoIkNsb3Npbmcgc2Nhbm5lciIsCisgICAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZSkpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gU2NhbiBjb21wbGV0ZS4gUmVtb3ZlIGFueSByb3dzIHdoaWNoIGhhZCBlbXB0eSBIUmVnaW9uSW5mb3MKKyAgICAKKyAgICBpZiAoZW1wdHlSb3dzLnNpemUoKSA+IDApIHsKKyAgICAgIExPRy53YXJuKCJGb3VuZCAiICsgZW1wdHlSb3dzLnNpemUoKSArCisgICAgICAgICIgcm93cyB3aXRoIGVtcHR5IEhSZWdpb25JbmZvIHdoaWxlIHNjYW5uaW5nIG1ldGEgcmVnaW9uICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhyZWdpb25OYW1lKSk7CisgICAgICBtYXN0ZXIuZGVsZXRlRW1wdHlNZXRhUm93cyhzZXJ2ZXIsIHJlZ2lvbk5hbWUsIGVtcHR5Um93cyk7CisgICAgfQorICAgIC8vIFVwZGF0ZSBzZXJ2ZXIgaW4gcm9vdC9tZXRhIGVudHJpZXMKKyAgICBmb3IgKFRvRG9FbnRyeSBlOiB0b0RvTGlzdCkgeworICAgICAgaWYgKGUucmVnaW9uT2ZmbGluZSkgeworICAgICAgICBIUmVnaW9uLm9mZmxpbmVSZWdpb25Jbk1FVEEoc2VydmVyLCByZWdpb25OYW1lLCBlLmluZm8pOworICAgICAgfQorICAgIH0KKworICAgIC8vIEdldCByZWdpb25zIHJlYXNzaWduZWQKKyAgICBmb3IgKEhSZWdpb25JbmZvIGluZm86IHJlZ2lvbnMpIHsKKyAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLnNldFVuYXNzaWduZWQoaW5mbywgdHJ1ZSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBTY2FuUm9vdFJlZ2lvbiBleHRlbmRzIFJldHJ5YWJsZU1ldGFPcGVyYXRpb248Qm9vbGVhbj4geworICAgIFNjYW5Sb290UmVnaW9uKE1ldGFSZWdpb24gbSwgSE1hc3RlciBtYXN0ZXIpIHsKKyAgICAgIHN1cGVyKG0sIG1hc3Rlcik7CisgICAgfQorCisgICAgcHVibGljIEJvb2xlYW4gY2FsbCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJwcm9jZXNzIHNlcnZlciBzaHV0ZG93biBzY2FubmluZyByb290IHJlZ2lvbiBvbiAiICsKKyAgICAgICAgICAgIG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKS5nZXRCaW5kQWRkcmVzcygpKTsKKyAgICAgIH0KKyAgICAgIGxvbmcgc2Nhbm5lcklkID0gc2VydmVyLm9wZW5TY2FubmVyKAorICAgICAgICAgIEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTy5nZXRSZWdpb25OYW1lKCksIENPTFVNTl9GQU1JTFlfQVJSQVksCisgICAgICAgICAgRU1QVFlfU1RBUlRfUk9XLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgICAgc2Nhbk1ldGFSZWdpb24oc2VydmVyLCBzY2FubmVySWQsCisgICAgICAgICAgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIGNsYXNzIFNjYW5NZXRhUmVnaW9ucyBleHRlbmRzIFJldHJ5YWJsZU1ldGFPcGVyYXRpb248Qm9vbGVhbj4geworICAgIFNjYW5NZXRhUmVnaW9ucyhNZXRhUmVnaW9uIG0sIEhNYXN0ZXIgbWFzdGVyKSB7CisgICAgICBzdXBlcihtLCBtYXN0ZXIpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoInByb2Nlc3Mgc2VydmVyIHNodXRkb3duIHNjYW5uaW5nICIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKG0uZ2V0UmVnaW9uTmFtZSgpKSArICIgb24gIiArIG0uZ2V0U2VydmVyKCkpOworICAgICAgfQorICAgICAgbG9uZyBzY2FubmVySWQgPQorICAgICAgICBzZXJ2ZXIub3BlblNjYW5uZXIobS5nZXRSZWdpb25OYW1lKCksIENPTFVNTl9GQU1JTFlfQVJSQVksCisgICAgICAgIEVNUFRZX1NUQVJUX1JPVywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKyAgICAgIHNjYW5NZXRhUmVnaW9uKHNlcnZlciwgc2Nhbm5lcklkLCBtLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGJvb2xlYW4gcHJvY2VzcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTE9HLmluZm8oInByb2Nlc3Mgc2h1dGRvd24gb2Ygc2VydmVyICIgKyB0aGlzLmRlYWRTZXJ2ZXIgKworICAgICAgIjogbG9nU3BsaXQ6ICIgKworICAgICAgbG9nU3BsaXQgKyAiLCByb290UmVzY2FubmVkOiAiICsgcm9vdFJlc2Nhbm5lZCArCisgICAgICAiLCBudW1iZXJPZk1ldGFSZWdpb25zOiAiICsgCisgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5udW1NZXRhUmVnaW9ucygpICsKKyAgICAgICIsIG9ubGluZU1ldGFSZWdpb25zLnNpemUoKTogIiArIAorICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIubnVtT25saW5lTWV0YVJlZ2lvbnMoKSk7CisgICAgaWYgKCFsb2dTcGxpdCkgeworICAgICAgLy8gUHJvY2VzcyB0aGUgb2xkIGxvZyBmaWxlCisgICAgICBpZiAobWFzdGVyLmZzLmV4aXN0cyhvbGRMb2dEaXIpKSB7CisgICAgICAgIGlmICghbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc3BsaXRMb2dMb2NrLnRyeUxvY2soKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgIEhMb2cuc3BsaXRMb2cobWFzdGVyLnJvb3RkaXIsIG9sZExvZ0RpciwgbWFzdGVyLmZzLAorICAgICAgICAgICAgbWFzdGVyLmdldENvbmZpZ3VyYXRpb24oKSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc3BsaXRMb2dMb2NrLnVubG9jaygpOworICAgICAgICB9CisgICAgICB9CisgICAgICBsb2dTcGxpdCA9IHRydWU7CisgICAgfQorCisgICAgaWYgKHRoaXMucm9vdFJlZ2lvblNlcnZlciAmJiAhdGhpcy5yb290UmVnaW9uUmVhc3NpZ25lZCkgeworICAgICAgLy8gYXZvaWQgbXVsdGlwbGUgcm9vdCByZWdpb24gcmVhc3NpZ25tZW50IAorICAgICAgdGhpcy5yb290UmVnaW9uUmVhc3NpZ25lZCA9IHRydWU7CisgICAgICAvLyBUaGUgc2VydmVyIHRoYXQgZGllZCB3YXMgc2VydmluZyB0aGUgcm9vdCByZWdpb24uIE5vdyB0aGF0IHRoZSBsb2cKKyAgICAgIC8vIGhhcyBiZWVuIHNwbGl0LCBnZXQgaXQgcmVhc3NpZ25lZC4KKyAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLnJlYXNzaWduUm9vdFJlZ2lvbigpOworICAgICAgLy8gV2hlbiB3ZSBjYWxsIHJvb3RBdmFpbGFibGUgYmVsb3csIGl0IHdpbGwgcHV0IHVzIG9uIHRoZSBkZWxheWVkCisgICAgICAvLyB0byBkbyBxdWV1ZSB0byBhbGxvdyBzb21lIHRpbWUgdG8gcGFzcyBkdXJpbmcgd2hpY2ggdGhlIHJvb3QgCisgICAgICAvLyByZWdpb24gd2lsbCBob3BlZnVsbHkgZ2V0IHJlYXNzaWduZWQuCisgICAgfQorCisgICAgaWYgKCFyb290QXZhaWxhYmxlKCkpIHsKKyAgICAgIC8vIFJldHVybiB0cnVlIHNvIHRoYXQgd29ya2VyIGRvZXMgbm90IHB1dCB0aGlzIHJlcXVlc3QgYmFjayBvbiB0aGUKKyAgICAgIC8vIHRvRG9RdWV1ZS4KKyAgICAgIC8vIHJvb3RBdmFpbGFibGUoKSBoYXMgYWxyZWFkeSBwdXQgaXQgb24gdGhlIGRlbGF5ZWRUb0RvUXVldWUKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGlmICghcm9vdFJlc2Nhbm5lZCkgeworICAgICAgLy8gU2NhbiB0aGUgUk9PVCByZWdpb24KKyAgICAgIEJvb2xlYW4gcmVzdWx0ID0gbmV3IFNjYW5Sb290UmVnaW9uKAorICAgICAgICAgIG5ldyBNZXRhUmVnaW9uKG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKSwKKyAgICAgICAgICAgICAgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLmdldFJlZ2lvbk5hbWUoKSwKKyAgICAgICAgICAgICAgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1cpLCB0aGlzLm1hc3RlcikuZG9XaXRoUmV0cmllcygpOworICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgIC8vIE1hc3RlciBpcyBjbG9zaW5nIC0gZ2l2ZSB1cAorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygicHJvY2VzcyBzZXJ2ZXIgc2h1dGRvd24gc2Nhbm5pbmcgcm9vdCByZWdpb24gb24gIiArCisgICAgICAgICAgbWFzdGVyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpLmdldEJpbmRBZGRyZXNzKCkgKyAKKyAgICAgICAgICAiIGZpbmlzaGVkICIgKyBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSk7CisgICAgICB9CisgICAgICByb290UmVzY2FubmVkID0gdHJ1ZTsKKyAgICB9CisgICAgaWYgKCFtZXRhVGFibGVBdmFpbGFibGUoKSkgeworICAgICAgLy8gV2UgY2FuJ3QgcHJvY2VlZCBiZWNhdXNlIG5vdCBhbGwgbWV0YSByZWdpb25zIGFyZSBvbmxpbmUuCisgICAgICAvLyBtZXRhQXZhaWxhYmxlKCkgaGFzIHB1dCB0aGlzIHJlcXVlc3Qgb24gdGhlIGRlbGF5ZWRUb0RvUXVldWUKKyAgICAgIC8vIFJldHVybiB0cnVlIHNvIHRoYXQgd29ya2VyIGRvZXMgbm90IHB1dCB0aGlzIG9uIHRoZSB0b0RvUXVldWUKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIExpc3Q8TWV0YVJlZ2lvbj4gcmVnaW9ucyA9IG1hc3Rlci5yZWdpb25NYW5hZ2VyLmdldExpc3RPZk9ubGluZU1ldGFSZWdpb25zKCk7CisgICAgZm9yIChNZXRhUmVnaW9uIHI6IHJlZ2lvbnMpIHsKKyAgICAgIEJvb2xlYW4gcmVzdWx0ID0gbmV3IFNjYW5NZXRhUmVnaW9ucyhyLCB0aGlzLm1hc3RlcikuZG9XaXRoUmV0cmllcygpOworICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygicHJvY2VzcyBzZXJ2ZXIgc2h1dGRvd24gZmluaXNoZWQgc2Nhbm5pbmcgIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcoci5nZXRSZWdpb25OYW1lKCkpICsgIiBvbiAiICsgci5nZXRTZXJ2ZXIoKSk7CisgICAgICB9CisgICAgfQorICAgIC8vIFJlbW92ZSB0aGlzIHNlcnZlciBmcm9tIGRlYWQgc2VydmVycyBsaXN0LiAgRmluaXNoZWQgc3BsaXR0aW5nIGxvZ3MuCisgICAgdGhpcy5tYXN0ZXIuc2VydmVyTWFuYWdlci5yZW1vdmVEZWFkU2VydmVyKGRlYWRTZXJ2ZXIpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJSZW1vdmVkICIgKyBkZWFkU2VydmVyICsgIiBmcm9tIGRlYWRzZXJ2ZXJzIE1hcCIpOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9SZWdpb25NYW5hZ2VyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUmVnaW9uTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3ZjE1MTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUmVnaW9uTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMTM1NiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3RlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5Mb2NrOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudExvY2s7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudFNraXBMaXN0TWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGhGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckxvYWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVnaW9uSGlzdG9yaWFuOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhNc2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlBhaXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5UaHJlYWRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnpvb2tlZXBlci5ab29LZWVwZXJXcmFwcGVyOworCisvKioKKyAqIENsYXNzIHRvIG1hbmFnZSBhc3NpZ25pbmcgcmVnaW9ucyB0byBzZXJ2ZXJzLCBzdGF0ZSBvZiByb290IGFuZCBtZXRhLCBldGMuCisgKi8gCitjbGFzcyBSZWdpb25NYW5hZ2VyIGltcGxlbWVudHMgSENvbnN0YW50cyB7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFJlZ2lvbk1hbmFnZXIuY2xhc3MpOworICAKKyAgcHJpdmF0ZSBBdG9taWNSZWZlcmVuY2U8SFNlcnZlckFkZHJlc3M+IHJvb3RSZWdpb25Mb2NhdGlvbiA9CisgICAgbmV3IEF0b21pY1JlZmVyZW5jZTxIU2VydmVyQWRkcmVzcz4obnVsbCk7CisgIAorICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gc2FmZU1vZGUgPSB0cnVlOworICAKKyAgZmluYWwgTG9jayBzcGxpdExvZ0xvY2sgPSBuZXcgUmVlbnRyYW50TG9jaygpOworICAKKyAgcHJpdmF0ZSBmaW5hbCBSb290U2Nhbm5lciByb290U2Nhbm5lclRocmVhZDsKKyAgZmluYWwgTWV0YVNjYW5uZXIgbWV0YVNjYW5uZXJUaHJlYWQ7CisgIAorICAvKiogU2V0IGJ5IHJvb3Qgc2Nhbm5lciB0byBpbmRpY2F0ZSB0aGUgbnVtYmVyIG9mIG1ldGEgcmVnaW9ucyAqLworICBwcml2YXRlIGZpbmFsIEF0b21pY0ludGVnZXIgbnVtYmVyT2ZNZXRhUmVnaW9ucyA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisKKyAgLyoqIFRoZXNlIGFyZSB0aGUgb25saW5lIG1ldGEgcmVnaW9ucyAqLworICBwcml2YXRlIGZpbmFsIE5hdmlnYWJsZU1hcDxieXRlIFtdLCBNZXRhUmVnaW9uPiBvbmxpbmVNZXRhUmVnaW9ucyA9CisgICAgbmV3IENvbmN1cnJlbnRTa2lwTGlzdE1hcDxieXRlIFtdLCBNZXRhUmVnaW9uPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gT1ZFUkxPQURFRCA9IEJ5dGVzLnRvQnl0ZXMoIk92ZXJsb2FkZWQiKTsKKworICAvKioKKyAgICogTWFwIG9mIHJlZ2lvbiBuYW1lIHRvIFJlZ2lvblN0YXRlIGZvciByZWdpb25zIHRoYXQgYXJlIGluIHRyYW5zaXRpb24gc3VjaCBhcworICAgKiAKKyAgICogdW5hc3NpZ25lZCAtPiBwZW5kaW5nT3BlbiAtPiBvcGVuCisgICAqIGNsb3NpbmcgLT4gcGVuZGluZ0Nsb3NlIC0+IGNsb3NlZDsgaWYgKGNsb3NlZCAmJiAhb2ZmbGluZSkgLT4gdW5hc3NpZ25lZAorICAgKiAKKyAgICogQXQgdGhlIGVuZCBvZiBhIHRyYW5zaXRpb24sIHJlbW92ZVJlZ2lvbiBpcyB1c2VkIHRvIHJlbW92ZSB0aGUgcmVnaW9uIGZyb20KKyAgICogdGhlIG1hcCAoc2luY2UgaXQgaXMgbm8gbG9uZ2VyIGluIHRyYW5zaXRpb24pCisgICAqIAorICAgKiBOb3RlOiBOZWVkcyB0byBiZSBTb3J0ZWRNYXAgc28gd2UgY2FuIHNwZWNpZnkgYSBjb21wYXJhdG9yCisgICAqIAorICAgKiBAc2VlIFJlZ2lvblN0YXRlIGlubmVyLWNsYXNzIGJlbG93CisgICAqLworICBwcml2YXRlIGZpbmFsIFNvcnRlZE1hcDxTdHJpbmcsIFJlZ2lvblN0YXRlPiByZWdpb25zSW5UcmFuc2l0aW9uID0KKyAgICBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTb3J0ZWRNYXAobmV3IFRyZWVNYXA8U3RyaW5nLCBSZWdpb25TdGF0ZT4oKSk7CisKKyAgLy8gSG93IG1hbnkgcmVnaW9ucyB0byBhc3NpZ24gYSBzZXJ2ZXIgYXQgYSB0aW1lLgorICBwcml2YXRlIGZpbmFsIGludCBtYXhBc3NpZ25Jbk9uZUdvOworCisgIHByaXZhdGUgZmluYWwgSE1hc3RlciBtYXN0ZXI7CisgIHByaXZhdGUgZmluYWwgUmVnaW9uSGlzdG9yaWFuIGhpc3RvcmlhbjsKKyAgcHJpdmF0ZSBmaW5hbCBmbG9hdCBzbG9wOworCisgIC8qKiBTZXQgb2YgcmVnaW9ucyB0byBzcGxpdC4gKi8KKyAgcHJpdmF0ZSBmaW5hbCBTb3J0ZWRNYXA8Ynl0ZVtdLCBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPj4KKyAgICByZWdpb25zVG9TcGxpdCA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNvcnRlZE1hcCgKKyAgICAgICAgbmV3IFRyZWVNYXA8Ynl0ZVtdLFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PgorICAgICAgICAoQnl0ZXMuQllURVNfQ09NUEFSQVRPUikpOworICAvKiogU2V0IG9mIHJlZ2lvbnMgdG8gY29tcGFjdC4gKi8KKyAgcHJpdmF0ZSBmaW5hbCBTb3J0ZWRNYXA8Ynl0ZVtdLCBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPj4KKyAgICByZWdpb25zVG9Db21wYWN0ID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkU29ydGVkTWFwKAorICAgICAgICBuZXcgVHJlZU1hcDxieXRlW10sUGFpcjxIUmVnaW9uSW5mbyxIU2VydmVyQWRkcmVzcz4+CisgICAgICAgIChCeXRlcy5CWVRFU19DT01QQVJBVE9SKSk7CisgIC8qKiBTZXQgb2YgcmVnaW9ucyB0byBtYWpvciBjb21wYWN0LiAqLworICBwcml2YXRlIGZpbmFsIFNvcnRlZE1hcDxieXRlW10sIFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PgorICAgIHJlZ2lvbnNUb01ham9yQ29tcGFjdCA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNvcnRlZE1hcCgKKyAgICAgICAgbmV3IFRyZWVNYXA8Ynl0ZVtdLFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PgorICAgICAgICAoQnl0ZXMuQllURVNfQ09NUEFSQVRPUikpOworICAvKiogU2V0IG9mIHJlZ2lvbnMgdG8gZmx1c2guICovCisgIHByaXZhdGUgZmluYWwgU29ydGVkTWFwPGJ5dGVbXSwgUGFpcjxIUmVnaW9uSW5mbyxIU2VydmVyQWRkcmVzcz4+CisgICAgcmVnaW9uc1RvRmx1c2ggPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTb3J0ZWRNYXAoCisgICAgICAgIG5ldyBUcmVlTWFwPGJ5dGVbXSxQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPj4KKyAgICAgICAgKEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpKTsKKworICBwcml2YXRlIGZpbmFsIFpvb0tlZXBlcldyYXBwZXIgem9vS2VlcGVyV3JhcHBlcjsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgem9vS2VlcGVyTnVtUmV0cmllczsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgem9vS2VlcGVyUGF1c2U7CisKKyAgUmVnaW9uTWFuYWdlcihITWFzdGVyIG1hc3RlcikgeworICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mID0gbWFzdGVyLmdldENvbmZpZ3VyYXRpb24oKTsKKworICAgIHRoaXMubWFzdGVyID0gbWFzdGVyOworICAgIHRoaXMuaGlzdG9yaWFuID0gUmVnaW9uSGlzdG9yaWFuLmdldEluc3RhbmNlKCk7CisgICAgdGhpcy5tYXhBc3NpZ25Jbk9uZUdvID0gY29uZi5nZXRJbnQoImhiYXNlLnJlZ2lvbnMucGVyY2hlY2tpbiIsIDEwKTsKKyAgICB0aGlzLnNsb3AgPSBjb25mLmdldEZsb2F0KCJoYmFzZS5yZWdpb25zLnNsb3AiLCAoZmxvYXQpMC4xKTsKKworICAgIC8vIFRoZSByb290IHJlZ2lvbgorICAgIHJvb3RTY2FubmVyVGhyZWFkID0gbmV3IFJvb3RTY2FubmVyKG1hc3Rlcik7CisKKyAgICAvLyBTY2FucyB0aGUgbWV0YSB0YWJsZQorICAgIG1ldGFTY2FubmVyVGhyZWFkID0gbmV3IE1ldGFTY2FubmVyKG1hc3Rlcik7CisKKyAgICB6b29LZWVwZXJXcmFwcGVyID0gbWFzdGVyLmdldFpvb0tlZXBlcldyYXBwZXIoKTsKKyAgICB6b29LZWVwZXJOdW1SZXRyaWVzID0gY29uZi5nZXRJbnQoWk9PS0VFUEVSX1JFVFJJRVMsIERFRkFVTFRfWk9PS0VFUEVSX1JFVFJJRVMpOworICAgIHpvb0tlZXBlclBhdXNlID0gY29uZi5nZXRJbnQoWk9PS0VFUEVSX1BBVVNFLCBERUZBVUxUX1pPT0tFRVBFUl9QQVVTRSk7CisKKyAgICByZWFzc2lnblJvb3RSZWdpb24oKTsKKyAgfQorCisgIHZvaWQgc3RhcnQoKSB7CisgICAgVGhyZWFkcy5zZXREYWVtb25UaHJlYWRSdW5uaW5nKHJvb3RTY2FubmVyVGhyZWFkLAorICAgICAgIlJlZ2lvbk1hbmFnZXIucm9vdFNjYW5uZXIiKTsKKyAgICBUaHJlYWRzLnNldERhZW1vblRocmVhZFJ1bm5pbmcobWV0YVNjYW5uZXJUaHJlYWQsCisgICAgICAiUmVnaW9uTWFuYWdlci5tZXRhU2Nhbm5lciIpOyAgICAKKyAgfQorCisgIHZvaWQgdW5zZXRSb290UmVnaW9uKCkgeworICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luVHJhbnNpdGlvbikgeworICAgICAgcm9vdFJlZ2lvbkxvY2F0aW9uLnNldChudWxsKTsKKyAgICAgIHJlZ2lvbnNJblRyYW5zaXRpb24ucmVtb3ZlKAorICAgICAgICAgIEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTy5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgfQorICB9CisgIAorICB2b2lkIHJlYXNzaWduUm9vdFJlZ2lvbigpIHsKKyAgICB1bnNldFJvb3RSZWdpb24oKTsKKyAgICBpZiAoIW1hc3Rlci5zaHV0ZG93blJlcXVlc3RlZC5nZXQoKSkgeworICAgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICAgIFJlZ2lvblN0YXRlIHMgPSBuZXcgUmVnaW9uU3RhdGUoSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPKTsKKyAgICAgICAgcy5zZXRVbmFzc2lnbmVkKCk7CisgICAgICAgIHJlZ2lvbnNJblRyYW5zaXRpb24ucHV0KAorICAgICAgICAgICAgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpLCBzKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIEFzc2lnbnMgcmVnaW9ucyB0byByZWdpb24gc2VydmVycyBhdHRlbXB0aW5nIHRvIGJhbGFuY2UgdGhlIGxvYWQgYWNyb3NzCisgICAqIGFsbCByZWdpb24gc2VydmVycy4gTm90ZSB0aGF0IG5vIHN5bmNocm9uaXphdGlvbiBpcyBuZWNlc3NhcnkgYXMgdGhlIGNhbGxlciAKKyAgICogKFNlcnZlck1hbmFnZXIucHJvY2Vzc01zZ3MpIGFscmVhZHkgb3ducyB0aGUgbW9uaXRvciBmb3IgdGhlIFJlZ2lvbk1hbmFnZXIuCisgICAqIAorICAgKiBAcGFyYW0gaW5mbworICAgKiBAcGFyYW0gbW9zdExvYWRlZFJlZ2lvbnMKKyAgICogQHBhcmFtIHJldHVybk1zZ3MKKyAgICovCisgIHZvaWQgYXNzaWduUmVnaW9ucyhIU2VydmVySW5mbyBpbmZvLCBIUmVnaW9uSW5mb1tdIG1vc3RMb2FkZWRSZWdpb25zLAorICAgICAgQXJyYXlMaXN0PEhNc2c+IHJldHVybk1zZ3MpIHsKKyAgICBIU2VydmVyTG9hZCB0aGlzU2VydmVyc0xvYWQgPSBpbmZvLmdldExvYWQoKTsKKyAgICAvLyBmaWd1cmUgb3V0IHdoYXQgcmVnaW9ucyBuZWVkIHRvIGJlIGFzc2lnbmVkIGFuZCBhcmVuJ3QgY3VycmVudGx5IGJlaW5nCisgICAgLy8gd29ya2VkIG9uIGVsc2V3aGVyZS4KKyAgICBTZXQ8UmVnaW9uU3RhdGU+IHJlZ2lvbnNUb0Fzc2lnbiA9IHJlZ2lvbnNBd2FpdGluZ0Fzc2lnbm1lbnQoKTsKKyAgICBpZiAocmVnaW9uc1RvQXNzaWduLnNpemUoKSA9PSAwKSB7CisgICAgICAvLyBUaGVyZSBhcmUgbm8gcmVnaW9ucyB3YWl0aW5nIHRvIGJlIGFzc2lnbmVkLgorICAgICAgaWYgKCFpblNhZmVNb2RlKCkpIHsKKyAgICAgICAgLy8gV2Ugb25seSBkbyBsb2FkIGJhbGFuY2luZyBvbmNlIGFsbCByZWdpb25zIGFyZSBhc3NpZ25lZC4KKyAgICAgICAgLy8gVGhpcyBwcmV2ZW50cyBjaHVybiB3aGlsZSB0aGUgY2x1c3RlciBpcyBzdGFydGluZyB1cC4KKyAgICAgICAgZG91YmxlIGF2Z0xvYWQgPSBtYXN0ZXIuc2VydmVyTWFuYWdlci5nZXRBdmVyYWdlTG9hZCgpOworICAgICAgICBkb3VibGUgYXZnTG9hZFdpdGhTbG9wID0gYXZnTG9hZCArCisgICAgICAgICgodGhpcy5zbG9wICE9IDApPyBhdmdMb2FkICogdGhpcy5zbG9wOiBhdmdMb2FkKTsKKyAgICAgICAgaWYgKGF2Z0xvYWQgPiAyLjAgJiYKKyAgICAgICAgICAgIHRoaXNTZXJ2ZXJzTG9hZC5nZXROdW1iZXJPZlJlZ2lvbnMoKSA+IGF2Z0xvYWRXaXRoU2xvcCkgeworICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgTE9HLmRlYnVnKCJTZXJ2ZXIgIiArIGluZm8uZ2V0U2VydmVyTmFtZSgpICsKKyAgICAgICAgICAgICAgICAiIGlzIG92ZXJsb2FkZWQuIFNlcnZlciBsb2FkOiAiICsgCisgICAgICAgICAgICAgICAgdGhpc1NlcnZlcnNMb2FkLmdldE51bWJlck9mUmVnaW9ucygpICsgIiBhdmc6ICIgKyBhdmdMb2FkICsKKyAgICAgICAgICAgICAgICAiLCBzbG9wOiAiICsgdGhpcy5zbG9wKTsKKyAgICAgICAgICB9CisgICAgICAgICAgdW5hc3NpZ25Tb21lUmVnaW9ucyhpbmZvLCB0aGlzU2VydmVyc0xvYWQsCisgICAgICAgICAgICAgIGF2Z0xvYWQsIG1vc3RMb2FkZWRSZWdpb25zLCByZXR1cm5Nc2dzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBpZiB0aGVyZSdzIG9ubHkgb25lIHNlcnZlciwganVzdCBnaXZlIGl0IGFsbCB0aGUgcmVnaW9ucworICAgICAgaWYgKG1hc3Rlci5zZXJ2ZXJNYW5hZ2VyLm51bVNlcnZlcnMoKSA9PSAxKSB7CisgICAgICAgIGFzc2lnblJlZ2lvbnNUb09uZVNlcnZlcihyZWdpb25zVG9Bc3NpZ24sIGluZm8sIHJldHVybk1zZ3MpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gb3RoZXJ3aXNlLCBnaXZlIHRoaXMgc2VydmVyIGEgZmV3IHJlZ2lvbnMgdGFraW5nIGludG8gYWNjb3VudCB0aGUgCisgICAgICAgIC8vIGxvYWQgb2YgYWxsIHRoZSBvdGhlciBzZXJ2ZXJzLgorICAgICAgICBhc3NpZ25SZWdpb25zVG9NdWx0aXBsZVNlcnZlcnModGhpc1NlcnZlcnNMb2FkLCByZWdpb25zVG9Bc3NpZ24sIAorICAgICAgICAgICAgaW5mbywgcmV0dXJuTXNncyk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICAvKgorICAgKiBNYWtlIHJlZ2lvbiBhc3NpZ25tZW50cyB0YWtpbmcgaW50byBhY2NvdW50IG11bHRpcGxlIHNlcnZlcnMnIGxvYWRzLgorICAgKgorICAgKiBOb3RlIHRoYXQgbm8gc3luY2hyb25pemF0aW9uIGlzIG5lZWRlZCB3aGlsZSB3ZSBpdGVyYXRlIG92ZXIKKyAgICogcmVnaW9uc0luVHJhbnNpdGlvbiBiZWNhdXNlIHRoaXMgbWV0aG9kIGlzIG9ubHkgY2FsbGVkIGJ5IGFzc2lnblJlZ2lvbnMKKyAgICogd2hvc2UgY2FsbGVyIG93bnMgdGhlIG1vbml0b3IgZm9yIFJlZ2lvbk1hbmFnZXIKKyAgICovIAorICBwcml2YXRlIHZvaWQgYXNzaWduUmVnaW9uc1RvTXVsdGlwbGVTZXJ2ZXJzKGZpbmFsIEhTZXJ2ZXJMb2FkIHRoaXNTZXJ2ZXJzTG9hZCwKKyAgICBmaW5hbCBTZXQ8UmVnaW9uU3RhdGU+IHJlZ2lvbnNUb0Fzc2lnbiwgZmluYWwgSFNlcnZlckluZm8gaW5mbywgCisgICAgZmluYWwgQXJyYXlMaXN0PEhNc2c+IHJldHVybk1zZ3MpIHsKKyAgICAKKyAgICBpbnQgblJlZ2lvbnNUb0Fzc2lnbiA9IHJlZ2lvbnNUb0Fzc2lnbi5zaXplKCk7CisgICAgaW50IG5yZWdpb25zID0gcmVnaW9uc1BlclNlcnZlcihuUmVnaW9uc1RvQXNzaWduLCB0aGlzU2VydmVyc0xvYWQpOworICAgIG5SZWdpb25zVG9Bc3NpZ24gLT0gbnJlZ2lvbnM7CisgICAgaWYgKG5SZWdpb25zVG9Bc3NpZ24gPiAwKSB7CisgICAgICAvLyBXZSBzdGlsbCBoYXZlIG1vcmUgcmVnaW9ucyB0byBhc3NpZ24uIFNlZSBob3cgbWFueSB3ZSBjYW4gYXNzaWduCisgICAgICAvLyBiZWZvcmUgdGhpcyBzZXJ2ZXIgYmVjb21lcyBtb3JlIGhlYXZpbHkgbG9hZGVkIHRoYW4gdGhlIG5leHQKKyAgICAgIC8vIG1vc3QgaGVhdmlseSBsb2FkZWQgc2VydmVyLgorICAgICAgSFNlcnZlckxvYWQgaGVhdmllckxvYWQgPSBuZXcgSFNlcnZlckxvYWQoKTsKKyAgICAgIGludCBuc2VydmVycyA9IGNvbXB1dGVOZXh0SGVhdmllc3RMb2FkKHRoaXNTZXJ2ZXJzTG9hZCwgaGVhdmllckxvYWQpOworCisgICAgICBucmVnaW9ucyA9IDA7CisgICAgICAKKyAgICAgIC8vIEFkdmFuY2UgcGFzdCBhbnkgbGVzcy1sb2FkZWQgc2VydmVycworICAgICAgZm9yIChIU2VydmVyTG9hZCBsb2FkID0gbmV3IEhTZXJ2ZXJMb2FkKHRoaXNTZXJ2ZXJzTG9hZCk7CisgICAgICAgIGxvYWQuY29tcGFyZVRvKGhlYXZpZXJMb2FkKSA8PSAwICYmIG5yZWdpb25zIDwgblJlZ2lvbnNUb0Fzc2lnbjsKKyAgICAgICAgbG9hZC5zZXROdW1iZXJPZlJlZ2lvbnMobG9hZC5nZXROdW1iZXJPZlJlZ2lvbnMoKSArIDEpLCBucmVnaW9ucysrKSB7CisgICAgICAgIC8vIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICBpZiAobnJlZ2lvbnMgPCBuUmVnaW9uc1RvQXNzaWduKSB7CisgICAgICAgIC8vIFRoZXJlIGFyZSBzb21lIG1vcmUgaGVhdmlseSBsb2FkZWQgc2VydmVycworICAgICAgICAvLyBidXQgd2UgY2FuJ3QgYXNzaWduIGFsbCB0aGUgcmVnaW9ucyB0byB0aGlzIHNlcnZlci4KKyAgICAgICAgaWYgKG5zZXJ2ZXJzID4gMCkgeworICAgICAgICAgIC8vIFRoZXJlIGFyZSBvdGhlciBzZXJ2ZXJzIHRoYXQgY2FuIHNoYXJlIHRoZSBsb2FkLgorICAgICAgICAgIC8vIFNwbGl0IHJlZ2lvbnMgdGhhdCBuZWVkIGFzc2lnbm1lbnQgYWNyb3NzIHRoZSBzZXJ2ZXJzLgorICAgICAgICAgIG5yZWdpb25zID0gKGludCkgTWF0aC5jZWlsKCgxLjAgKiBuUmVnaW9uc1RvQXNzaWduKQorICAgICAgICAgICAgICAvICgxLjAgKiBuc2VydmVycykpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIE5vIG90aGVyIHNlcnZlcnMgd2l0aCBzYW1lIGxvYWQuCisgICAgICAgICAgLy8gU3BsaXQgcmVnaW9ucyBvdmVyIGFsbCBhdmFpbGFibGUgc2VydmVycworICAgICAgICAgIG5yZWdpb25zID0gKGludCkgTWF0aC5jZWlsKCgxLjAgKiBuUmVnaW9uc1RvQXNzaWduKQorICAgICAgICAgICAgICAvICgxLjAgKiBtYXN0ZXIuc2VydmVyTWFuYWdlci5udW1TZXJ2ZXJzKCkpKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQXNzaWduIGFsbCByZWdpb25zIHRvIHRoaXMgc2VydmVyCisgICAgICAgIG5yZWdpb25zID0gblJlZ2lvbnNUb0Fzc2lnbjsKKyAgICAgIH0KKworICAgICAgaWYgKG5yZWdpb25zID4gdGhpcy5tYXhBc3NpZ25Jbk9uZUdvKSB7CisgICAgICAgIG5yZWdpb25zID0gdGhpcy5tYXhBc3NpZ25Jbk9uZUdvOworICAgICAgfQorICAgICAgCisgICAgICBmb3IgKFJlZ2lvblN0YXRlIHM6IHJlZ2lvbnNUb0Fzc2lnbikgeworICAgICAgICBkb1JlZ2lvbkFzc2lnbm1lbnQocywgaW5mbywgcmV0dXJuTXNncyk7CisgICAgICAgIGlmICgtLW5yZWdpb25zIDw9IDApIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qCisgICAqIEFzc2lnbiBhbGwgdG8gdGhlIG9ubHkgc2VydmVyLiBBbiB1bmxpa2VseSBjYXNlIGJ1dCBzdGlsbCBwb3NzaWJsZS4KKyAgICogCisgICAqIE5vdGUgdGhhdCBubyBzeW5jaHJvbml6YXRpb24gaXMgbmVlZGVkIG9uIHJlZ2lvbnNJblRyYW5zaXRpb24gd2hpbGUKKyAgICogaXRlcmF0aW5nIG9uIGl0IGJlY2F1c2UgdGhlIG9ubHkgY2FsbGVyIGlzIGFzc2lnblJlZ2lvbnMgd2hvc2UgY2FsbGVyIG93bnMgCisgICAqIHRoZSBtb25pdG9yIGZvciBSZWdpb25NYW5hZ2VyCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uc1RvQXNzaWduCisgICAqIEBwYXJhbSBzZXJ2ZXJOYW1lCisgICAqIEBwYXJhbSByZXR1cm5Nc2dzCisgICAqLworICBwcml2YXRlIHZvaWQgYXNzaWduUmVnaW9uc1RvT25lU2VydmVyKGZpbmFsIFNldDxSZWdpb25TdGF0ZT4gcmVnaW9uc1RvQXNzaWduLAorICAgICAgZmluYWwgSFNlcnZlckluZm8gaW5mbywgZmluYWwgQXJyYXlMaXN0PEhNc2c+IHJldHVybk1zZ3MpIHsKKyAgICBmb3IgKFJlZ2lvblN0YXRlIHM6IHJlZ2lvbnNUb0Fzc2lnbikgeworICAgICAgZG9SZWdpb25Bc3NpZ25tZW50KHMsIGluZm8sIHJldHVybk1zZ3MpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIERvIHNpbmdsZSByZWdpb24gYXNzaWdubWVudC4KKyAgICogQHBhcmFtIHJzCisgICAqIEBwYXJhbSBzaW5mbworICAgKiBAcGFyYW0gcmV0dXJuTXNncworICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGRvUmVnaW9uQXNzaWdubWVudChmaW5hbCBSZWdpb25TdGF0ZSBycywKKyAgICAgIGZpbmFsIEhTZXJ2ZXJJbmZvIHNpbmZvLCBmaW5hbCBBcnJheUxpc3Q8SE1zZz4gcmV0dXJuTXNncykgeworICAgIFN0cmluZyByZWdpb25OYW1lID0gcnMuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpOworICAgIExPRy5pbmZvKCJBc3NpZ25pbmcgcmVnaW9uICIgKyByZWdpb25OYW1lICsgIiB0byAiICsgc2luZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICBycy5zZXRQZW5kaW5nT3BlbihzaW5mby5nZXRTZXJ2ZXJOYW1lKCkpOworICAgIHRoaXMucmVnaW9uc0luVHJhbnNpdGlvbi5wdXQocmVnaW9uTmFtZSwgcnMpOworICAgIHRoaXMuaGlzdG9yaWFuLmFkZFJlZ2lvbkFzc2lnbm1lbnQocnMuZ2V0UmVnaW9uSW5mbygpLAorICAgICAgICBzaW5mby5nZXRTZXJ2ZXJOYW1lKCkpOworICAgIHJldHVybk1zZ3MuYWRkKG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVHSU9OX09QRU4sIHJzLmdldFJlZ2lvbkluZm8oKSkpOworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIG5SZWdpb25zVG9Bc3NpZ24KKyAgICogQHBhcmFtIHRoaXNTZXJ2ZXJzTG9hZAorICAgKiBAcmV0dXJuIEhvdyBtYW55IHJlZ2lvbnMgd2UgY2FuIGFzc2lnbiB0byBtb3JlIGxpZ2h0bHkgbG9hZGVkIHNlcnZlcnMKKyAgICovCisgIHByaXZhdGUgaW50IHJlZ2lvbnNQZXJTZXJ2ZXIoZmluYWwgaW50IG51bVVuYXNzaWduZWRSZWdpb25zLAorICAgIGZpbmFsIEhTZXJ2ZXJMb2FkIHRoaXNTZXJ2ZXJzTG9hZCkgeworICAgIAorICAgIFNvcnRlZE1hcDxIU2VydmVyTG9hZCwgU2V0PFN0cmluZz4+IGxpZ2h0U2VydmVycyA9CisgICAgICBuZXcgVHJlZU1hcDxIU2VydmVyTG9hZCwgU2V0PFN0cmluZz4+KCk7CisKKyAgICAvLyBHZXQgYWxsIHRoZSBzZXJ2ZXJzIHdobyBhcmUgbW9yZSBsaWdodGx5IGxvYWRlZCB0aGFuIHRoaXMgb25lLgorICAgIHN5bmNocm9uaXplZCAobWFzdGVyLnNlcnZlck1hbmFnZXIubG9hZFRvU2VydmVycykgeworICAgICAgbGlnaHRTZXJ2ZXJzLnB1dEFsbChtYXN0ZXIuc2VydmVyTWFuYWdlci5sb2FkVG9TZXJ2ZXJzLmhlYWRNYXAodGhpc1NlcnZlcnNMb2FkKSk7CisgICAgfQorCisgICAgLy8gRXhhbWluZSB0aGUgbGlzdCBvZiBzZXJ2ZXJzIHRoYXQgYXJlIG1vcmUgbGlnaHRseSBsb2FkZWQgdGhhbiB0aGlzIG9uZS4KKyAgICAvLyBQcmV0ZW5kIHRoYXQgd2Ugd2lsbCBhc3NpZ24gcmVnaW9ucyB0byB0aGVzZSBtb3JlIGxpZ2h0bHkgbG9hZGVkIHNlcnZlcnMKKyAgICAvLyB1bnRpbCB0aGV5IHJlYWNoIGxvYWQgZXF1YWwgd2l0aCBvdXJzLiBUaGVuLCBzZWUgaG93IG1hbnkgcmVnaW9ucyBhcmUgbGVmdAorICAgIC8vIHVuYXNzaWduZWQuIFRoYXQgaXMgaG93IG1hbnkgcmVnaW9ucyB3ZSBzaG91bGQgYXNzaWduIHRvIHRoaXMgc2VydmVyLgorICAgIGludCBuUmVnaW9ucyA9IDA7CisgICAgZm9yIChNYXAuRW50cnk8SFNlcnZlckxvYWQsIFNldDxTdHJpbmc+PiBlIDogbGlnaHRTZXJ2ZXJzLmVudHJ5U2V0KCkpIHsKKyAgICAgIEhTZXJ2ZXJMb2FkIGxpZ2h0TG9hZCA9IG5ldyBIU2VydmVyTG9hZChlLmdldEtleSgpKTsKKyAgICAgIGRvIHsKKyAgICAgICAgbGlnaHRMb2FkLnNldE51bWJlck9mUmVnaW9ucyhsaWdodExvYWQuZ2V0TnVtYmVyT2ZSZWdpb25zKCkgKyAxKTsKKyAgICAgICAgblJlZ2lvbnMgKz0gMTsKKyAgICAgIH0gd2hpbGUgKGxpZ2h0TG9hZC5jb21wYXJlVG8odGhpc1NlcnZlcnNMb2FkKSA8PSAwCisgICAgICAgICAgJiYgblJlZ2lvbnMgPCBudW1VbmFzc2lnbmVkUmVnaW9ucyk7CisKKyAgICAgIG5SZWdpb25zICo9IGUuZ2V0VmFsdWUoKS5zaXplKCk7CisgICAgICBpZiAoblJlZ2lvbnMgPj0gbnVtVW5hc3NpZ25lZFJlZ2lvbnMpIHsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBuUmVnaW9uczsKKyAgfQorICAKKyAgLyoKKyAgICogR2V0IHRoZSBzZXQgb2YgcmVnaW9ucyB0aGF0IHNob3VsZCBiZSBhc3NpZ25hYmxlIGluIHRoaXMgcGFzcy4KKyAgICogCisgICAqIE5vdGUgdGhhdCBubyBzeW5jaHJvbml6YXRpb24gb24gcmVnaW9uc0luVHJhbnNpdGlvbiBpcyBuZWVkZWQgYmVjYXVzZSB0aGUKKyAgICogb25seSBjYWxsZXIgKGFzc2lnblJlZ2lvbnMsIHdob3NlIGNhbGxlciBpcyBTZXJ2ZXJNYW5hZ2VyLnByb2Nlc3NNc2dzKSBvd25zCisgICAqIHRoZSBtb25pdG9yIGZvciBSZWdpb25NYW5hZ2VyCisgICAqLyAKKyAgcHJpdmF0ZSBTZXQ8UmVnaW9uU3RhdGU+IHJlZ2lvbnNBd2FpdGluZ0Fzc2lnbm1lbnQoKSB7CisgICAgLy8gc2V0IG9mIHJlZ2lvbnMgd2Ugd2FudCB0byBhc3NpZ24gdG8gdGhpcyBzZXJ2ZXIKKyAgICBTZXQ8UmVnaW9uU3RhdGU+IHJlZ2lvbnNUb0Fzc2lnbiA9IG5ldyBIYXNoU2V0PFJlZ2lvblN0YXRlPigpOworICAgIAorICAgIC8vIExvb2sgb3ZlciB0aGUgc2V0IG9mIHJlZ2lvbnMgdGhhdCBhcmVuJ3QgY3VycmVudGx5IGFzc2lnbmVkIHRvIAorICAgIC8vIGRldGVybWluZSB3aGljaCB3ZSBzaG91bGQgYXNzaWduIHRvIHRoaXMgc2VydmVyLgorICAgIGZvciAoUmVnaW9uU3RhdGUgczogcmVnaW9uc0luVHJhbnNpdGlvbi52YWx1ZXMoKSkgeworICAgICAgSFJlZ2lvbkluZm8gaSA9IHMuZ2V0UmVnaW9uSW5mbygpOworICAgICAgaWYgKGkgPT0gbnVsbCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGlmIChudW1iZXJPZk1ldGFSZWdpb25zLmdldCgpICE9IG9ubGluZU1ldGFSZWdpb25zLnNpemUoKSAmJgorICAgICAgICAgICFpLmlzTWV0YVJlZ2lvbigpKSB7CisgICAgICAgIC8vIENhbid0IGFzc2lnbiB1c2VyIHJlZ2lvbnMgdW50aWwgYWxsIG1ldGEgcmVnaW9ucyBoYXZlIGJlZW4gYXNzaWduZWQKKyAgICAgICAgLy8gYW5kIGFyZSBvbi1saW5lCisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgaWYgKHMuaXNVbmFzc2lnbmVkKCkpIHsKKyAgICAgICAgcmVnaW9uc1RvQXNzaWduLmFkZChzKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlZ2lvbnNUb0Fzc2lnbjsKKyAgfQorICAKKyAgLyoKKyAgICogRmlndXJlIG91dCB0aGUgbG9hZCB0aGF0IGlzIG5leHQgaGlnaGVzdCBhbW9uZ3N0IGFsbCByZWdpb25zZXJ2ZXJzLiBBbHNvLAorICAgKiByZXR1cm4gaG93IG1hbnkgc2VydmVycyBleGlzdCBhdCB0aGF0IGxvYWQuIAorICAgKi8KKyAgcHJpdmF0ZSBpbnQgY29tcHV0ZU5leHRIZWF2aWVzdExvYWQoSFNlcnZlckxvYWQgcmVmZXJlbmNlTG9hZCwgCisgICAgSFNlcnZlckxvYWQgaGVhdmllckxvYWQpIHsKKyAgICAKKyAgICBTb3J0ZWRNYXA8SFNlcnZlckxvYWQsIFNldDxTdHJpbmc+PiBoZWF2eVNlcnZlcnMgPQorICAgICAgbmV3IFRyZWVNYXA8SFNlcnZlckxvYWQsIFNldDxTdHJpbmc+PigpOworICAgIHN5bmNocm9uaXplZCAobWFzdGVyLnNlcnZlck1hbmFnZXIubG9hZFRvU2VydmVycykgeworICAgICAgaGVhdnlTZXJ2ZXJzLnB1dEFsbCgKKyAgICAgICAgbWFzdGVyLnNlcnZlck1hbmFnZXIubG9hZFRvU2VydmVycy50YWlsTWFwKHJlZmVyZW5jZUxvYWQpKTsKKyAgICB9CisgICAgaW50IG5zZXJ2ZXJzID0gMDsKKyAgICBmb3IgKE1hcC5FbnRyeTxIU2VydmVyTG9hZCwgU2V0PFN0cmluZz4+IGUgOiBoZWF2eVNlcnZlcnMuZW50cnlTZXQoKSkgeworICAgICAgU2V0PFN0cmluZz4gc2VydmVycyA9IGUuZ2V0VmFsdWUoKTsKKyAgICAgIG5zZXJ2ZXJzICs9IHNlcnZlcnMuc2l6ZSgpOworICAgICAgaWYgKGUuZ2V0S2V5KCkuY29tcGFyZVRvKHJlZmVyZW5jZUxvYWQpID09IDApIHsKKyAgICAgICAgLy8gVGhpcyBpcyB0aGUgbG9hZCBmYWN0b3Igb2YgdGhlIHNlcnZlciB3ZSBhcmUgY29uc2lkZXJpbmcKKyAgICAgICAgbnNlcnZlcnMgLT0gMTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIC8vIElmIHdlIGdldCBoZXJlLCB3ZSBhcmUgYXQgdGhlIGZpcnN0IGxvYWQgZW50cnkgdGhhdCBpcyBhCisgICAgICAvLyBoZWF2aWVyIGxvYWQgdGhhbiB0aGUgc2VydmVyIHdlIGFyZSBjb25zaWRlcmluZworICAgICAgaGVhdmllckxvYWQuc2V0TnVtYmVyT2ZSZXF1ZXN0cyhlLmdldEtleSgpLmdldE51bWJlck9mUmVxdWVzdHMoKSk7CisgICAgICBoZWF2aWVyTG9hZC5zZXROdW1iZXJPZlJlZ2lvbnMoZS5nZXRLZXkoKS5nZXROdW1iZXJPZlJlZ2lvbnMoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgcmV0dXJuIG5zZXJ2ZXJzOworICB9CisKKyAgLyoKKyAgICogVGhlIHNlcnZlciBjaGVja2luZyBpbiByaWdodCBub3cgaXMgb3ZlcmxvYWRlZC4gV2Ugd2lsbCB0ZWxsIGl0IHRvIGNsb3NlCisgICAqIHNvbWUgb3IgYWxsIG9mIGl0cyBtb3N0IGxvYWRlZCByZWdpb25zLCBhbGxvd2luZyBpdCB0byByZWR1Y2UgaXRzIGxvYWQuCisgICAqIFRoZSBjbG9zZWQgcmVnaW9ucyB3aWxsIHRoZW4gZ2V0IHBpY2tlZCB1cCBieSBvdGhlciB1bmRlcmxvYWRlZCBtYWNoaW5lcy4KKyAgICoKKyAgICogTm90ZSB0aGF0IG5vIHN5bmNocm9uaXphdGlvbiBpcyBuZWVkZWQgYmVjYXVzZSB0aGUgb25seSBjYWxsZXIgCisgICAqIChhc3NpZ25SZWdpb25zKSB3aG9zZSBjYWxsZXIgb3ducyB0aGUgbW9uaXRvciBmb3IgUmVnaW9uTWFuYWdlcgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHVuYXNzaWduU29tZVJlZ2lvbnMoZmluYWwgSFNlcnZlckluZm8gaW5mbywgCisgICAgICBmaW5hbCBIU2VydmVyTG9hZCBsb2FkLCBmaW5hbCBkb3VibGUgYXZnTG9hZCwKKyAgICAgIGZpbmFsIEhSZWdpb25JbmZvW10gbW9zdExvYWRlZFJlZ2lvbnMsIEFycmF5TGlzdDxITXNnPiByZXR1cm5Nc2dzKSB7CisgICAgaW50IG51bVJlZ2lvbnNUb0Nsb3NlID0gbG9hZC5nZXROdW1iZXJPZlJlZ2lvbnMoKSAtIChpbnQpTWF0aC5jZWlsKGF2Z0xvYWQpOworICAgIExPRy5kZWJ1ZygiQ2hvb3NpbmcgdG8gcmVhc3NpZ24gIiArIG51bVJlZ2lvbnNUb0Nsb3NlIAorICAgICAgKyAiIHJlZ2lvbnMuIG1vc3RMb2FkZWRSZWdpb25zIGhhcyAiICsgbW9zdExvYWRlZFJlZ2lvbnMubGVuZ3RoIAorICAgICAgKyAiIHJlZ2lvbnMgaW4gaXQuIik7CisgICAgaW50IHJlZ2lvbklkeCA9IDA7CisgICAgaW50IHJlZ2lvbnNDbG9zZWQgPSAwOworICAgIGludCBza2lwcGVkID0gMDsKKyAgICB3aGlsZSAocmVnaW9uc0Nsb3NlZCA8IG51bVJlZ2lvbnNUb0Nsb3NlICYmCisgICAgICAgIHJlZ2lvbklkeCA8IG1vc3RMb2FkZWRSZWdpb25zLmxlbmd0aCkgeworICAgICAgSFJlZ2lvbkluZm8gY3VycmVudFJlZ2lvbiA9IG1vc3RMb2FkZWRSZWdpb25zW3JlZ2lvbklkeF07CisgICAgICByZWdpb25JZHgrKzsKKyAgICAgIC8vIHNraXAgdGhlIHJlZ2lvbiBpZiBpdCdzIG1ldGEgb3Igcm9vdAorICAgICAgaWYgKGN1cnJlbnRSZWdpb24uaXNSb290UmVnaW9uKCkgfHwgY3VycmVudFJlZ2lvbi5pc01ldGFUYWJsZSgpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgU3RyaW5nIHJlZ2lvbk5hbWUgPSBjdXJyZW50UmVnaW9uLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpOworICAgICAgaWYgKHJlZ2lvbklzSW5UcmFuc2l0aW9uKHJlZ2lvbk5hbWUpKSB7CisgICAgICAgIHNraXBwZWQrKzsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJHb2luZyB0byBjbG9zZSByZWdpb24gIiArIHJlZ2lvbk5hbWUpOworICAgICAgfQorICAgICAgLy8gbWFrZSBhIG1lc3NhZ2UgdG8gY2xvc2UgdGhlIHJlZ2lvbgorICAgICAgcmV0dXJuTXNncy5hZGQobmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRUdJT05fQ0xPU0UsIGN1cnJlbnRSZWdpb24sCisgICAgICAgIE9WRVJMT0FERUQpKTsKKyAgICAgIC8vIG1hcmsgdGhlIHJlZ2lvbiBhcyBjbG9zaW5nCisgICAgICBzZXRDbG9zaW5nKGluZm8uZ2V0U2VydmVyTmFtZSgpLCBjdXJyZW50UmVnaW9uLCBmYWxzZSk7CisgICAgICBzZXRQZW5kaW5nQ2xvc2UocmVnaW9uTmFtZSk7CisgICAgICAvLyBpbmNyZW1lbnQgdGhlIGNvdW50IG9mIHJlZ2lvbnMgd2UndmUgbWFya2VkCisgICAgICByZWdpb25zQ2xvc2VkKys7CisgICAgfQorICAgIExPRy5pbmZvKCJTa2lwcGVkICIgKyBza2lwcGVkICsgIiByZWdpb24ocykgdGhhdCBhcmUgaW4gdHJhbnNpdGlvbiBzdGF0ZXMiKTsKKyAgfQorICAKKyAgc3RhdGljIGNsYXNzIFRhYmxlRGlyRmlsdGVyIGltcGxlbWVudHMgUGF0aEZpbHRlciB7CisKKyAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQoUGF0aCBwYXRoKSB7CisgICAgICAvLyBza2lwIHRoZSByZWdpb24gc2VydmVycycgbG9nIGRpcnMgJiYgdmVyc2lvbiBmaWxlCisgICAgICAvLyBIQkFTRS0xMTEyIHdhbnQgdG8gc3BlcmF0ZSB0aGUgbG9nIGRpcnMgZnJvbSB0YWJsZSdzIGRhdGEgZGlycyBieSBhIHNwZWNpYWwgY2hhcmFjdGVyLgorICAgICAgU3RyaW5nIHBhdGhuYW1lID0gcGF0aC5nZXROYW1lKCk7CisgICAgICByZXR1cm4gIXBhdGhuYW1lLnN0YXJ0c1dpdGgoImxvZ18iKSAmJiAhcGF0aG5hbWUuZXF1YWxzKFZFUlNJT05fRklMRV9OQU1FKTsKKyAgICB9CisgICAgCisgIH0KKyAgCisgIHN0YXRpYyBjbGFzcyBSZWdpb25EaXJGaWx0ZXIgaW1wbGVtZW50cyBQYXRoRmlsdGVyIHsKKworICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChQYXRoIHBhdGgpIHsgCisgICAgICByZXR1cm4gIXBhdGguZ2V0TmFtZSgpLmVxdWFscyhIUkVHSU9OX0NPTVBBQ1RJT05ESVJfTkFNRSk7CisgICAgfQorICAgIAorICB9CisgIAorICAvKioKKyAgICogQHJldHVybiB0aGUgcm91Z2ggbnVtYmVyIG9mIHRoZSByZWdpb25zIG9uIGZzCisgICAqIE5vdGU6IHRoaXMgbWV0aG9kIHNpbXBseSBjb3VudHMgdGhlIHJlZ2lvbnMgb24gZnMgYnkgYWNjdW11bGF0aW5nIGFsbCB0aGUgZGlycyAKKyAgICogaW4gZWFjaCB0YWJsZSBkaXIgKCR7SEJBU0VfUk9PVH0vJFRBQkxFKSBhbmQgc2tpcHBpbmcgbG9nZmlsZXMsIGNvbXBhY3Rpb24gZGlycy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBpbnQgY291bnRSZWdpb25zT25GUygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IHJlZ2lvbnMgPSAwOworICAgIAorICAgIEZpbGVTdGF0dXNbXSB0YWJsZURpcnMgPSAKKyAgICAgIG1hc3Rlci5mcy5saXN0U3RhdHVzKG1hc3Rlci5yb290ZGlyLCBuZXcgVGFibGVEaXJGaWx0ZXIoKSk7CisgICAgCisgICAgRmlsZVN0YXR1c1tdIHJlZ2lvbkRpcnM7CisgICAgUmVnaW9uRGlyRmlsdGVyIHJkZiA9IG5ldyBSZWdpb25EaXJGaWx0ZXIoKTsKKyAgICBmb3IoRmlsZVN0YXR1cyB0YWJsZWRpciA6IHRhYmxlRGlycykgeworICAgICAgaWYodGFibGVkaXIuaXNEaXIoKSkgeworICAgICAgICByZWdpb25EaXJzID0gbWFzdGVyLmZzLmxpc3RTdGF0dXModGFibGVkaXIuZ2V0UGF0aCgpLCByZGYpOworICAgICAgICByZWdpb25zICs9IHJlZ2lvbkRpcnMubGVuZ3RoOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICByZXR1cm4gcmVnaW9uczsKKyAgfQorICAKKyAgLyoqCisgICAqIEByZXR1cm4gUmVhZC1vbmx5IG1hcCBvZiBvbmxpbmUgcmVnaW9ucy4KKyAgICovCisgIHB1YmxpYyBNYXA8Ynl0ZSBbXSwgTWV0YVJlZ2lvbj4gZ2V0T25saW5lTWV0YVJlZ2lvbnMoKSB7CisgICAgc3luY2hyb25pemVkIChvbmxpbmVNZXRhUmVnaW9ucykgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChvbmxpbmVNZXRhUmVnaW9ucyk7CisgICAgfQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gbWV0YVJlZ2lvbnNJblRyYW5zaXRpb24oKSB7CisgICAgc3luY2hyb25pemVkIChvbmxpbmVNZXRhUmVnaW9ucykgeworICAgICAgZm9yIChNZXRhUmVnaW9uIG1ldGFSZWdpb24gOiBvbmxpbmVNZXRhUmVnaW9ucy52YWx1ZXMoKSkgeworICAgICAgICBTdHJpbmcgcmVnaW9uTmFtZSA9IEJ5dGVzLnRvU3RyaW5nKG1ldGFSZWdpb24uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgICAgaWYgKHJlZ2lvbklzSW5UcmFuc2l0aW9uKHJlZ2lvbk5hbWUpKSB7CisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIFN0b3AgdGhlIHJvb3QgYW5kIG1ldGEgc2Nhbm5lcnMgc28gdGhhdCB0aGUgcmVnaW9uIHNlcnZlcnMgc2VydmluZyBtZXRhCisgICAqIHJlZ2lvbnMgY2FuIHNodXQgZG93bi4KKyAgICovCisgIHB1YmxpYyB2b2lkIHN0b3BTY2FubmVycygpIHsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygidGVsbGluZyByb290IHNjYW5uZXIgdG8gc3RvcCIpOworICAgIH0KKyAgICByb290U2Nhbm5lclRocmVhZC5pbnRlcnJ1cHRJZkFsaXZlKCk7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoInRlbGxpbmcgbWV0YSBzY2FubmVyIHRvIHN0b3AiKTsKKyAgICB9CisgICAgbWV0YVNjYW5uZXJUaHJlYWQuaW50ZXJydXB0SWZBbGl2ZSgpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJtZXRhIGFuZCByb290IHNjYW5uZXJzIG5vdGlmaWVkIik7CisgICAgfQorICB9CisgIAorICAvKiogU3RvcCB0aGUgcmVnaW9uIGFzc2lnbmVyICovCisgIHB1YmxpYyB2b2lkIHN0b3AoKSB7ICAKKyAgICB0cnkgeworICAgICAgaWYgKHJvb3RTY2FubmVyVGhyZWFkLmlzQWxpdmUoKSkgeworICAgICAgICByb290U2Nhbm5lclRocmVhZC5qb2luKCk7ICAgICAgIC8vIFdhaXQgZm9yIHRoZSByb290IHNjYW5uZXIgdG8gZmluaXNoLgorICAgICAgfQorICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZXgpIHsKKyAgICAgIExPRy53YXJuKCJyb290IHNjYW5uZXIiLCBpZXgpOworICAgIH0KKyAgICB0cnkgeworICAgICAgaWYgKG1ldGFTY2FubmVyVGhyZWFkLmlzQWxpdmUoKSkgeworICAgICAgICBtZXRhU2Nhbm5lclRocmVhZC5qb2luKCk7ICAgICAgIC8vIFdhaXQgZm9yIG1ldGEgc2Nhbm5lciB0byBmaW5pc2guCisgICAgICB9CisgICAgfSBjYXRjaChFeGNlcHRpb24gaWV4KSB7CisgICAgICBMT0cud2FybigibWV0YSBzY2FubmVyIiwgaWV4KTsKKyAgICB9CisgICAgem9vS2VlcGVyV3JhcHBlci5jbG9zZSgpOworICB9CisgIAorICAvKioKKyAgICogQmxvY2sgdW50aWwgbWV0YSByZWdpb25zIGFyZSBvbmxpbmUgb3Igd2UncmUgc2h1dHRpbmcgZG93bi4KKyAgICogQHJldHVybiB0cnVlIGlmIHdlIGZvdW5kIG1ldGEgcmVnaW9ucywgZmFsc2UgaWYgd2UncmUgY2xvc2luZy4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGFyZUFsbE1ldGFSZWdpb25zT25saW5lKCkgeworICAgIHN5bmNocm9uaXplZCAob25saW5lTWV0YVJlZ2lvbnMpIHsKKyAgICAgIHJldHVybiAocm9vdFJlZ2lvbkxvY2F0aW9uLmdldCgpICE9IG51bGwgJiYKKyAgICAgICAgICBudW1iZXJPZk1ldGFSZWdpb25zLmdldCgpID09IG9ubGluZU1ldGFSZWdpb25zLnNpemUoKSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogU2VhcmNoIG91ciBtYXAgb2Ygb25saW5lIG1ldGEgcmVnaW9ucyB0byBmaW5kIHRoZSBmaXJzdCBtZXRhIHJlZ2lvbiB0aGF0IAorICAgKiBzaG91bGQgY29udGFpbiBhIHBvaW50ZXIgdG8gPGk+bmV3UmVnaW9uPC9pPi4KKyAgICogQHBhcmFtIG5ld1JlZ2lvbgorICAgKiBAcmV0dXJuIE1ldGFSZWdpb24gd2hlcmUgdGhlIG5ld1JlZ2lvbiBzaG91bGQgbGl2ZQorICAgKi8KKyAgcHVibGljIE1ldGFSZWdpb24gZ2V0Rmlyc3RNZXRhUmVnaW9uRm9yUmVnaW9uKEhSZWdpb25JbmZvIG5ld1JlZ2lvbikgeworICAgIHN5bmNocm9uaXplZCAob25saW5lTWV0YVJlZ2lvbnMpIHsKKyAgICAgIGlmIChvbmxpbmVNZXRhUmVnaW9ucy5zaXplKCkgPT0gMCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0gZWxzZSBpZiAob25saW5lTWV0YVJlZ2lvbnMuc2l6ZSgpID09IDEpIHsKKyAgICAgICAgcmV0dXJuIG9ubGluZU1ldGFSZWdpb25zLmdldChvbmxpbmVNZXRhUmVnaW9ucy5maXJzdEtleSgpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChvbmxpbmVNZXRhUmVnaW9ucy5jb250YWluc0tleShuZXdSZWdpb24uZ2V0UmVnaW9uTmFtZSgpKSkgeworICAgICAgICAgIHJldHVybiBvbmxpbmVNZXRhUmVnaW9ucy5nZXQobmV3UmVnaW9uLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICAgIH0gCisgICAgICAgIHJldHVybiBvbmxpbmVNZXRhUmVnaW9ucy5nZXQob25saW5lTWV0YVJlZ2lvbnMuaGVhZE1hcCgKKyAgICAgICAgICAgIG5ld1JlZ2lvbi5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCkpLmxhc3RLZXkoKSk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogR2V0IGEgc2V0IG9mIGFsbCB0aGUgbWV0YSByZWdpb25zIHRoYXQgY29udGFpbiBpbmZvIGFib3V0IGEgZ2l2ZW4gdGFibGUuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgVGFibGUgeW91IG5lZWQgdG8ga25vdyBhbGwgdGhlIG1ldGEgcmVnaW9ucyBmb3IKKyAgICogQHJldHVybiBzZXQgb2YgTWV0YVJlZ2lvbiBvYmplY3RzIHRoYXQgY29udGFpbiB0aGUgdGFibGUKKyAgICogQHRocm93cyBOb3RBbGxNZXRhUmVnaW9uc09ubGluZUV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFNldDxNZXRhUmVnaW9uPiBnZXRNZXRhUmVnaW9uc0ZvclRhYmxlKGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24geworICAgIGJ5dGUgW10gZmlyc3RNZXRhUmVnaW9uID0gbnVsbDsKKyAgICBTZXQ8TWV0YVJlZ2lvbj4gbWV0YVJlZ2lvbnMgPSBuZXcgSGFzaFNldDxNZXRhUmVnaW9uPigpOworICAgIGlmIChCeXRlcy5lcXVhbHModGFibGVOYW1lLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSkpIHsKKyAgICAgIGlmIChyb290UmVnaW9uTG9jYXRpb24uZ2V0KCkgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24oCisgICAgICAgICAgICBCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSkpOworICAgICAgfQorICAgICAgbWV0YVJlZ2lvbnMuYWRkKG5ldyBNZXRhUmVnaW9uKHJvb3RSZWdpb25Mb2NhdGlvbi5nZXQoKSwKKyAgICAgICAgICBIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8uZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmICghYXJlQWxsTWV0YVJlZ2lvbnNPbmxpbmUoKSkgeworICAgICAgICB0aHJvdyBuZXcgTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24oKTsKKyAgICAgIH0KKyAgICAgIHN5bmNocm9uaXplZCAob25saW5lTWV0YVJlZ2lvbnMpIHsKKyAgICAgICAgaWYgKG9ubGluZU1ldGFSZWdpb25zLnNpemUoKSA9PSAxKSB7CisgICAgICAgICAgZmlyc3RNZXRhUmVnaW9uID0gb25saW5lTWV0YVJlZ2lvbnMuZmlyc3RLZXkoKTsKKyAgICAgICAgfSBlbHNlIGlmIChvbmxpbmVNZXRhUmVnaW9ucy5jb250YWluc0tleSh0YWJsZU5hbWUpKSB7CisgICAgICAgICAgZmlyc3RNZXRhUmVnaW9uID0gdGFibGVOYW1lOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGZpcnN0TWV0YVJlZ2lvbiA9IG9ubGluZU1ldGFSZWdpb25zLmhlYWRNYXAodGFibGVOYW1lKS5sYXN0S2V5KCk7CisgICAgICAgIH0KKyAgICAgICAgbWV0YVJlZ2lvbnMuYWRkQWxsKG9ubGluZU1ldGFSZWdpb25zLnRhaWxNYXAoZmlyc3RNZXRhUmVnaW9uKS52YWx1ZXMoKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBtZXRhUmVnaW9uczsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgbWV0YXJlZ2lvbiB0aGF0IHdvdWxkIGhvc3QgcGFzc2VkIGluIHJvdy4KKyAgICogQHBhcmFtIHJvdyBSb3cgbmVlZCB0byBrbm93IGFsbCB0aGUgbWV0YSByZWdpb25zIGZvcgorICAgKiBAcmV0dXJuIHNldCBvZiBNZXRhUmVnaW9uIG9iamVjdHMgdGhhdCBjb250YWluIHRoZSB0YWJsZQorICAgKiBAdGhyb3dzIE5vdEFsbE1ldGFSZWdpb25zT25saW5lRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgTWV0YVJlZ2lvbiBnZXRNZXRhUmVnaW9uRm9yUm93KGZpbmFsIGJ5dGUgW10gcm93KQorICB0aHJvd3MgTm90QWxsTWV0YVJlZ2lvbnNPbmxpbmVFeGNlcHRpb24geworICAgIGlmICghYXJlQWxsTWV0YVJlZ2lvbnNPbmxpbmUoKSkgeworICAgICAgdGhyb3cgbmV3IE5vdEFsbE1ldGFSZWdpb25zT25saW5lRXhjZXB0aW9uKCk7CisgICAgfQorICAgIHJldHVybiB0aGlzLm9ubGluZU1ldGFSZWdpb25zLmZsb29yRW50cnkocm93KS5nZXRWYWx1ZSgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIG5ldyBIUmVnaW9uLCBwdXQgYSByb3cgZm9yIGl0IGludG8gTUVUQSAob3IgUk9PVCksIGFuZCBtYXJrIHRoZQorICAgKiBuZXcgcmVnaW9uIHVuYXNzaWduZWQgc28gdGhhdCBpdCB3aWxsIGdldCBhc3NpZ25lZCB0byBhIHJlZ2lvbiBzZXJ2ZXIuCisgICAqIEBwYXJhbSBuZXdSZWdpb24gSFJlZ2lvbkluZm8gZm9yIHRoZSByZWdpb24gdG8gY3JlYXRlCisgICAqIEBwYXJhbSBzZXJ2ZXIgc2VydmVyIGhvc3RpbmcgdGhlIE1FVEEgKG9yIFJPT1QpIHJlZ2lvbiB3aGVyZSB0aGUgbmV3CisgICAqIHJlZ2lvbiBuZWVkcyB0byBiZSBub3RlZAorICAgKiBAcGFyYW0gbWV0YVJlZ2lvbk5hbWUgbmFtZSBvZiB0aGUgbWV0YSByZWdpb24gd2hlcmUgbmV3IHJlZ2lvbiBpcyB0byBiZQorICAgKiB3cml0dGVuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGNyZWF0ZVJlZ2lvbihIUmVnaW9uSW5mbyBuZXdSZWdpb24sIEhSZWdpb25JbnRlcmZhY2Ugc2VydmVyLCAKKyAgICAgIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIDIuIENyZWF0ZSB0aGUgSFJlZ2lvbgorICAgIEhSZWdpb24gcmVnaW9uID0gSFJlZ2lvbi5jcmVhdGVIUmVnaW9uKG5ld1JlZ2lvbiwgbWFzdGVyLnJvb3RkaXIsCisgICAgICBtYXN0ZXIuZ2V0Q29uZmlndXJhdGlvbigpKTsKKworICAgIC8vIDMuIEluc2VydCBpbnRvIG1ldGEKKyAgICBIUmVnaW9uSW5mbyBpbmZvID0gcmVnaW9uLmdldFJlZ2lvbkluZm8oKTsKKyAgICBieXRlIFtdIHJlZ2lvbk5hbWUgPSByZWdpb24uZ2V0UmVnaW9uTmFtZSgpOworICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUocmVnaW9uTmFtZSk7CisgICAgYi5wdXQoQ09MX1JFR0lPTklORk8sIFdyaXRhYmxlcy5nZXRCeXRlcyhpbmZvKSk7CisgICAgc2VydmVyLmJhdGNoVXBkYXRlKG1ldGFSZWdpb25OYW1lLCBiLCAtMUwpOworICAgIAorICAgIC8vIDQuIENsb3NlIHRoZSBuZXcgcmVnaW9uIHRvIGZsdXNoIGl0IHRvIGRpc2suICBDbG9zZSBpdHMgbG9nIGZpbGUgdG9vLgorICAgIHJlZ2lvbi5jbG9zZSgpOworICAgIHJlZ2lvbi5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworCisgICAgLy8gNS4gR2V0IGl0IGFzc2lnbmVkIHRvIGEgc2VydmVyCisgICAgc2V0VW5hc3NpZ25lZChpbmZvLCB0cnVlKTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBTZXQgYSBNZXRhUmVnaW9uIGFzIG9ubGluZS4gCisgICAqIEBwYXJhbSBtZXRhUmVnaW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgcHV0TWV0YVJlZ2lvbk9ubGluZShNZXRhUmVnaW9uIG1ldGFSZWdpb24pIHsKKyAgICBvbmxpbmVNZXRhUmVnaW9ucy5wdXQobWV0YVJlZ2lvbi5nZXRTdGFydEtleSgpLCBtZXRhUmVnaW9uKTsKKyAgfQorCisgIC8qKiAKKyAgICogR2V0IGEgbGlzdCBvZiBvbmxpbmUgTWV0YVJlZ2lvbnMgCisgICAqIEByZXR1cm4gbGlzdCBvZiBNZXRhUmVnaW9uIG9iamVjdHMKKyAgICovCisgIHB1YmxpYyBMaXN0PE1ldGFSZWdpb24+IGdldExpc3RPZk9ubGluZU1ldGFSZWdpb25zKCkgeworICAgIExpc3Q8TWV0YVJlZ2lvbj4gcmVnaW9ucyA9IG51bGw7CisgICAgc3luY2hyb25pemVkKG9ubGluZU1ldGFSZWdpb25zKSB7CisgICAgICByZWdpb25zID0gbmV3IEFycmF5TGlzdDxNZXRhUmVnaW9uPihvbmxpbmVNZXRhUmVnaW9ucy52YWx1ZXMoKSk7CisgICAgfQorICAgIHJldHVybiByZWdpb25zOworICB9CisgIAorICAvKiogCisgICAqIENvdW50IG9mIG9ubGluZSBtZXRhIHJlZ2lvbnMgCisgICAqIEByZXR1cm4gY291bnQgb2Ygb25saW5lIG1ldGEgcmVnaW9ucworICAgKi8KKyAgcHVibGljIGludCBudW1PbmxpbmVNZXRhUmVnaW9ucygpIHsKKyAgICByZXR1cm4gb25saW5lTWV0YVJlZ2lvbnMuc2l6ZSgpOworICB9CisgIAorICAvKiogCisgICAqIENoZWNrIGlmIGEgbWV0YSByZWdpb24gaXMgb25saW5lIGJ5IGl0cyBuYW1lIAorICAgKiBAcGFyYW0gc3RhcnRLZXkgbmFtZSBvZiB0aGUgbWV0YSByZWdpb24gdG8gY2hlY2sKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSByZWdpb24gaXMgb25saW5lLCBmYWxzZSBvdGhlcndpc2UKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzTWV0YVJlZ2lvbk9ubGluZShieXRlIFtdIHN0YXJ0S2V5KSB7CisgICAgcmV0dXJuIG9ubGluZU1ldGFSZWdpb25zLmNvbnRhaW5zS2V5KHN0YXJ0S2V5KTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBTZXQgYW4gb25saW5lIE1ldGFSZWdpb24gb2ZmbGluZSAtIHJlbW92ZSBpdCBmcm9tIHRoZSBtYXAuIAorICAgKiBAcGFyYW0gc3RhcnRLZXkgcmVnaW9uIG5hbWUKKyAgICovCisgIHB1YmxpYyB2b2lkIG9mZmxpbmVNZXRhUmVnaW9uKGJ5dGUgW10gc3RhcnRLZXkpIHsKKyAgICBvbmxpbmVNZXRhUmVnaW9ucy5yZW1vdmUoc3RhcnRLZXkpOyAKKyAgfQorICAKKyAgLyoqCisgICAqIFJlbW92ZSBhIHJlZ2lvbiBmcm9tIHRoZSByZWdpb24gc3RhdGUgbWFwLgorICAgKiAKKyAgICogQHBhcmFtIGluZm8KKyAgICovCisgIHB1YmxpYyB2b2lkIHJlbW92ZVJlZ2lvbihIUmVnaW9uSW5mbyBpbmZvKSB7CisgICAgdGhpcy5yZWdpb25zSW5UcmFuc2l0aW9uLnJlbW92ZShpbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSByZWdpb25OYW1lCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbmFtZWQgcmVnaW9uIGlzIGluIGEgdHJhbnNpdGlvbiBzdGF0ZQorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gcmVnaW9uSXNJblRyYW5zaXRpb24oU3RyaW5nIHJlZ2lvbk5hbWUpIHsKKyAgICByZXR1cm4gcmVnaW9uc0luVHJhbnNpdGlvbi5jb250YWluc0tleShyZWdpb25OYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHJlZ2lvbiBpcyB1bmFzc2lnbmVkLCBwZW5kaW5nT3BlbiBvciBvcGVuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiByZWdpb25Jc09wZW5pbmcoU3RyaW5nIHJlZ2lvbk5hbWUpIHsKKyAgICBSZWdpb25TdGF0ZSBzdGF0ZSA9IHJlZ2lvbnNJblRyYW5zaXRpb24uZ2V0KHJlZ2lvbk5hbWUpOworICAgIGlmIChzdGF0ZSAhPSBudWxsKSB7CisgICAgICByZXR1cm4gc3RhdGUuaXNPcGVuaW5nKCk7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKiAKKyAgICogU2V0IGEgcmVnaW9uIHRvIHVuYXNzaWduZWQgCisgICAqIEBwYXJhbSBpbmZvIFJlZ2lvbiB0byBzZXQgdW5hc3NpZ25lZAorICAgKiBAcGFyYW0gZm9yY2UgaWYgdHJ1ZSBtYXJrIHJlZ2lvbiB1bmFzc2lnbmVkIHdoYXRldmVyIGl0cyBjdXJyZW50IHN0YXRlCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRVbmFzc2lnbmVkKEhSZWdpb25JbmZvIGluZm8sIGJvb2xlYW4gZm9yY2UpIHsKKyAgICBzeW5jaHJvbml6ZWQodGhpcy5yZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICBSZWdpb25TdGF0ZSBzID0gcmVnaW9uc0luVHJhbnNpdGlvbi5nZXQoaW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgIHMgPSBuZXcgUmVnaW9uU3RhdGUoaW5mbyk7CisgICAgICAgIHJlZ2lvbnNJblRyYW5zaXRpb24ucHV0KGluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCksIHMpOworICAgICAgfQorICAgICAgaWYgKGZvcmNlIHx8ICghcy5pc1BlbmRpbmdPcGVuKCkgJiYgIXMuaXNPcGVuKCkpKSB7CisgICAgICAgIHMuc2V0VW5hc3NpZ25lZCgpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqIAorICAgKiBDaGVjayBpZiBhIHJlZ2lvbiBpcyBvbiB0aGUgdW5hc3NpZ25lZCBsaXN0CisgICAqIEBwYXJhbSBpbmZvIEhSZWdpb25JbmZvIHRvIGNoZWNrIGZvcgorICAgKiBAcmV0dXJuIHRydWUgaWYgb24gdGhlIHVuYXNzaWduZWQgbGlzdCwgZmFsc2UgaWYgaXQgaXNuJ3QuIE5vdGUgdGhhdCB0aGlzCisgICAqIG1lYW5zIGEgcmVnaW9uIGNvdWxkIG5vdCBiZSBvbiB0aGUgdW5hc3NpZ25lZCBsaXN0IEFORCBub3QgYmUgYXNzaWduZWQsIGlmCisgICAqIGl0IGhhcHBlbnMgdG8gYmUgYmV0d2VlbiBzdGF0ZXMuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1VuYXNzaWduZWQoSFJlZ2lvbkluZm8gaW5mbykgeworICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luVHJhbnNpdGlvbikgeworICAgICAgUmVnaW9uU3RhdGUgcyA9IHJlZ2lvbnNJblRyYW5zaXRpb24uZ2V0KGluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgICAgaWYgKHMgIT0gbnVsbCkgeworICAgICAgICByZXR1cm4gcy5pc1VuYXNzaWduZWQoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIAorICAvKioKKyAgICogQ2hlY2sgaWYgYSByZWdpb24gaGFzIGJlZW4gYXNzaWduZWQgYW5kIHdlJ3JlIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2UgZnJvbQorICAgKiB0aGUgcmVnaW9uIHNlcnZlci4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb25OYW1lIG5hbWUgb2YgdGhlIHJlZ2lvbgorICAgKiBAcmV0dXJuIHRydWUgaWYgb3BlbiwgZmFsc2Ugb3RoZXJ3aXNlCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1BlbmRpbmdPcGVuKFN0cmluZyByZWdpb25OYW1lKSB7CisgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICBSZWdpb25TdGF0ZSBzID0gcmVnaW9uc0luVHJhbnNpdGlvbi5nZXQocmVnaW9uTmFtZSk7CisgICAgICBpZiAocyAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBzLmlzUGVuZGluZ09wZW4oKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIFJlZ2lvbiBoYXMgYmVlbiBhc3NpZ25lZCB0byBhIHNlcnZlciBhbmQgdGhlIHNlcnZlciBoYXMgdG9sZCB1cyBpdCBpcyBvcGVuCisgICAqIEBwYXJhbSByZWdpb25OYW1lCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRPcGVuKFN0cmluZyByZWdpb25OYW1lKSB7CisgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICBSZWdpb25TdGF0ZSBzID0gcmVnaW9uc0luVHJhbnNpdGlvbi5nZXQocmVnaW9uTmFtZSk7CisgICAgICBpZiAocyAhPSBudWxsKSB7CisgICAgICAgIHMuc2V0T3BlbigpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSByZWdpb25OYW1lCisgICAqIEByZXR1cm4gdHJ1ZSBpZiByZWdpb24gaXMgbWFya2VkIHRvIGJlIG9mZmxpbmVkLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNPZmZsaW5lZChTdHJpbmcgcmVnaW9uTmFtZSkgeworICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luVHJhbnNpdGlvbikgeworICAgICAgUmVnaW9uU3RhdGUgcyA9IHJlZ2lvbnNJblRyYW5zaXRpb24uZ2V0KHJlZ2lvbk5hbWUpOworICAgICAgaWYgKHMgIT0gbnVsbCkgeworICAgICAgICByZXR1cm4gcy5pc09mZmxpbmVkKCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKiAKKyAgICogTWFyayBhIHJlZ2lvbiBhcyBjbG9zaW5nIAorICAgKiBAcGFyYW0gc2VydmVyTmFtZQorICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKiBAcGFyYW0gc2V0T2ZmbGluZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0Q2xvc2luZyhmaW5hbCBTdHJpbmcgc2VydmVyTmFtZSwgZmluYWwgSFJlZ2lvbkluZm8gcmVnaW9uSW5mbywKKyAgICAgIGZpbmFsIGJvb2xlYW4gc2V0T2ZmbGluZSkgeworICAgIHN5bmNocm9uaXplZCAodGhpcy5yZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICBSZWdpb25TdGF0ZSBzID0KKyAgICAgICAgdGhpcy5yZWdpb25zSW5UcmFuc2l0aW9uLmdldChyZWdpb25JbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgIGlmIChzID09IG51bGwpIHsKKyAgICAgICAgcyA9IG5ldyBSZWdpb25TdGF0ZShyZWdpb25JbmZvKTsKKyAgICAgIH0KKyAgICAgIHMuc2V0Q2xvc2luZyhzZXJ2ZXJOYW1lLCBzZXRPZmZsaW5lKTsKKyAgICAgIHRoaXMucmVnaW9uc0luVHJhbnNpdGlvbi5wdXQocmVnaW9uSW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSwgcyk7CisgICAgfQorICB9CisgIAorICAvKiogCisgICAqIFJlbW92ZSB0aGUgbWFwIG9mIHJlZ2lvbiBuYW1lcyB0byByZWdpb24gaW5mb3Mgd2FpdGluZyB0byBiZSBvZmZsaW5lZCBmb3IgYSAKKyAgICogZ2l2ZW4gc2VydmVyCisgICAqICAKKyAgICogQHBhcmFtIHNlcnZlck5hbWUKKyAgICogQHJldHVybiBzZXQgb2YgaW5mb3MgdG8gY2xvc2UKKyAgICovCisgIHB1YmxpYyBTZXQ8SFJlZ2lvbkluZm8+IGdldE1hcmtlZFRvQ2xvc2UoU3RyaW5nIHNlcnZlck5hbWUpIHsKKyAgICBTZXQ8SFJlZ2lvbkluZm8+IHJlc3VsdCA9IG5ldyBIYXNoU2V0PEhSZWdpb25JbmZvPigpOworICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luVHJhbnNpdGlvbikgeworICAgICAgZm9yIChSZWdpb25TdGF0ZSBzOiByZWdpb25zSW5UcmFuc2l0aW9uLnZhbHVlcygpKSB7CisgICAgICAgIGlmIChzLmlzQ2xvc2luZygpICYmICFzLmlzUGVuZGluZ0Nsb3NlKCkgJiYgIXMuaXNDbG9zZWQoKSAmJgorICAgICAgICAgICAgcy5nZXRTZXJ2ZXJOYW1lKCkuY29tcGFyZVRvKHNlcnZlck5hbWUpID09IDApIHsKKyAgICAgICAgICByZXN1bHQuYWRkKHMuZ2V0UmVnaW9uSW5mbygpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogQ2FsbGVkIHdoZW4gd2UgaGF2ZSB0b2xkIGEgcmVnaW9uIHNlcnZlciB0byBjbG9zZSB0aGUgcmVnaW9uCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0UGVuZGluZ0Nsb3NlKFN0cmluZyByZWdpb25OYW1lKSB7CisgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5UcmFuc2l0aW9uKSB7CisgICAgICBSZWdpb25TdGF0ZSBzID0gcmVnaW9uc0luVHJhbnNpdGlvbi5nZXQocmVnaW9uTmFtZSk7CisgICAgICBpZiAocyAhPSBudWxsKSB7CisgICAgICAgIHMuc2V0UGVuZGluZ0Nsb3NlKCk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldENsb3NlZChTdHJpbmcgcmVnaW9uTmFtZSkgeworICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luVHJhbnNpdGlvbikgeworICAgICAgUmVnaW9uU3RhdGUgcyA9IHJlZ2lvbnNJblRyYW5zaXRpb24uZ2V0KHJlZ2lvbk5hbWUpOworICAgICAgaWYgKHMgIT0gbnVsbCkgeworICAgICAgICBzLnNldENsb3NlZCgpOworICAgICAgfQorICAgIH0KKyAgfQorICAvKioKKyAgICogQWRkIGEgbWV0YSByZWdpb24gdG8gdGhlIHNjYW4gcXVldWUKKyAgICogQHBhcmFtIG0gTWV0YVJlZ2lvbiB0aGF0IG5lZWRzIHRvIGdldCBzY2FubmVkCisgICAqLworICBwdWJsaWMgdm9pZCBhZGRNZXRhUmVnaW9uVG9TY2FuKE1ldGFSZWdpb24gbSkgeworICAgIG1ldGFTY2FubmVyVGhyZWFkLmFkZE1ldGFSZWdpb25Ub1NjYW4obSk7CisgIH0KKyAgCisgIC8qKiAKKyAgICogQ2hlY2sgaWYgdGhlIGluaXRpYWwgcm9vdCBzY2FuIGhhcyBiZWVuIGNvbXBsZXRlZC4KKyAgICogQHJldHVybiB0cnVlIGlmIHNjYW4gY29tcGxldGVkLCBmYWxzZSBvdGhlcndpc2UKKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzSW5pdGlhbFJvb3RTY2FuQ29tcGxldGUoKSB7CisgICAgcmV0dXJuIHJvb3RTY2FubmVyVGhyZWFkLmlzSW5pdGlhbFNjYW5Db21wbGV0ZSgpOworICB9CisKKyAgLyoqIAorICAgKiBDaGVjayBpZiB0aGUgaW5pdGlhbCBtZXRhIHNjYW4gaGFzIGJlZW4gY29tcGxldGVkLgorICAgKiBAcmV0dXJuIHRydWUgaWYgbWV0YSBjb21wbGV0ZWQsIGZhbHNlIG90aGVyd2lzZQorICAgKi8gIAorICBwdWJsaWMgYm9vbGVhbiBpc0luaXRpYWxNZXRhU2NhbkNvbXBsZXRlKCkgeworICAgIHJldHVybiBtZXRhU2Nhbm5lclRocmVhZC5pc0luaXRpYWxTY2FuQ29tcGxldGUoKTsKKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiB0ZWxsWm9vS2VlcGVyT3V0T2ZTYWZlTW9kZSgpIHsKKyAgICBmb3IgKGludCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8IHpvb0tlZXBlck51bVJldHJpZXM7ICsrYXR0ZW1wdCkgeworICAgICAgaWYgKHpvb0tlZXBlcldyYXBwZXIud3JpdGVPdXRPZlNhZmVNb2RlKCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisKKyAgICAgIHNsZWVwKGF0dGVtcHQpOworICAgIH0KKworICAgIExPRy5lcnJvcigiRmFpbGVkIHRvIHRlbGwgWm9vS2VlcGVyIHdlJ3JlIG91dCBvZiBzYWZlIG1vZGUgYWZ0ZXIgIiArCisgICAgICAgICAgICAgIHpvb0tlZXBlck51bVJldHJpZXMgKyAiIHJldHJpZXMiKTsKKworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKiAKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBpbml0aWFsIG1ldGEgc2NhbiBpcyBjb21wbGV0ZSBhbmQgdGhlcmUgYXJlIG5vCisgICAqIHVuYXNzaWduZWQgb3IgcGVuZGluZyByZWdpb25zCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpblNhZmVNb2RlKCkgeworICAgIGlmIChzYWZlTW9kZSkgeworICAgICAgaWYoaXNJbml0aWFsTWV0YVNjYW5Db21wbGV0ZSgpICYmIHJlZ2lvbnNJblRyYW5zaXRpb24uc2l6ZSgpID09IDAgJiYKKyAgICAgICAgIHRlbGxab29LZWVwZXJPdXRPZlNhZmVNb2RlKCkpIHsKKyAgICAgICAgbWFzdGVyLmNvbm5lY3Rpb24udW5zZXRSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICAgICAgc2FmZU1vZGUgPSBmYWxzZTsKKyAgICAgICAgTE9HLmluZm8oImV4aXRpbmcgc2FmZSBtb2RlIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBMT0cuaW5mbygiaW4gc2FmZSBtb2RlIik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBzYWZlTW9kZTsKKyAgfQorICAKKyAgLyoqIAorICAgKiBHZXQgdGhlIHJvb3QgcmVnaW9uIGxvY2F0aW9uLgorICAgKiBAcmV0dXJuIEhTZXJ2ZXJBZGRyZXNzIGRlc2NyaWJpbmcgcm9vdCByZWdpb24gc2VydmVyLgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzIGdldFJvb3RSZWdpb25Mb2NhdGlvbigpIHsKKyAgICByZXR1cm4gcm9vdFJlZ2lvbkxvY2F0aW9uLmdldCgpOworICB9CisgIAorICAvKioKKyAgICogQmxvY2sgdW50aWwgZWl0aGVyIHRoZSByb290IHJlZ2lvbiBsb2NhdGlvbiBpcyBhdmFpbGFibGUgb3Igd2UncmUgc2h1dHRpbmcKKyAgICogZG93bi4KKyAgICovCisgIHB1YmxpYyB2b2lkIHdhaXRGb3JSb290UmVnaW9uTG9jYXRpb24oKSB7CisgICAgc3luY2hyb25pemVkIChyb290UmVnaW9uTG9jYXRpb24pIHsKKyAgICAgIHdoaWxlICghbWFzdGVyLmNsb3NlZC5nZXQoKSAmJiByb290UmVnaW9uTG9jYXRpb24uZ2V0KCkgPT0gbnVsbCkgeworICAgICAgICAvLyByb290UmVnaW9uTG9jYXRpb24gd2lsbCBiZSBmaWxsZWQgaW4gd2hlbiB3ZSBnZXQgYW4gJ29wZW4gcmVnaW9uJworICAgICAgICAvLyByZWdpb25TZXJ2ZXJSZXBvcnQgbWVzc2FnZSBmcm9tIHRoZSBIUmVnaW9uU2VydmVyIHRoYXQgaGFzIGJlZW4KKyAgICAgICAgLy8gYWxsb2NhdGVkIHRoZSBST09UIHJlZ2lvbiBiZWxvdy4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByb290UmVnaW9uTG9jYXRpb24ud2FpdCgpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIG1ldGEgcmVnaW9ucy4KKyAgICogQHJldHVybiBudW1iZXIgb2YgbWV0YSByZWdpb25zCisgICAqLworICBwdWJsaWMgaW50IG51bU1ldGFSZWdpb25zKCkgeworICAgIHJldHVybiBudW1iZXJPZk1ldGFSZWdpb25zLmdldCgpOworICB9CisgIAorICAvKioKKyAgICogQnVtcCB0aGUgY291bnQgb2YgbWV0YSByZWdpb25zIHVwIG9uZQorICAgKi8KKyAgcHVibGljIHZvaWQgaW5jcmVtZW50TnVtTWV0YVJlZ2lvbnMoKSB7CisgICAgbnVtYmVyT2ZNZXRhUmVnaW9ucy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgfQorCisgIHByaXZhdGUgbG9uZyBnZXRQYXVzZVRpbWUoaW50IHRyaWVzKSB7CisgICAgaW50IGF0dGVtcHQgPSB0cmllczsKKyAgICBpZiAoYXR0ZW1wdCA+PSBSRVRSWV9CQUNLT0ZGLmxlbmd0aCkgeworICAgICAgYXR0ZW1wdCA9IFJFVFJZX0JBQ0tPRkYubGVuZ3RoIC0gMTsKKyAgICB9CisgICAgcmV0dXJuIHRoaXMuem9vS2VlcGVyUGF1c2UgKiBSRVRSWV9CQUNLT0ZGW2F0dGVtcHRdOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNsZWVwKGludCBhdHRlbXB0KSB7CisgICAgdHJ5IHsKKyAgICAgIFRocmVhZC5zbGVlcChnZXRQYXVzZVRpbWUoYXR0ZW1wdCkpOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGNvbnRpbnVlCisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlUm9vdFJlZ2lvbkxvY2F0aW9uVG9ab29LZWVwZXIoSFNlcnZlckFkZHJlc3MgYWRkcmVzcykgeworICAgIGZvciAoaW50IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgem9vS2VlcGVyTnVtUmV0cmllczsgKythdHRlbXB0KSB7CisgICAgICBpZiAoem9vS2VlcGVyV3JhcHBlci53cml0ZVJvb3RSZWdpb25Mb2NhdGlvbihhZGRyZXNzKSkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisKKyAgICAgIHNsZWVwKGF0dGVtcHQpOworICAgIH0KKworICAgIExPRy5lcnJvcigiRmFpbGVkIHRvIHdyaXRlIHJvb3QgcmVnaW9uIGxvY2F0aW9uIHRvIFpvb0tlZXBlciBhZnRlciAiICsKKyAgICAgICAgICAgICAgem9vS2VlcGVyTnVtUmV0cmllcyArICIgcmV0cmllcywgc2h1dHRpbmcgZG93biIpOworCisgICAgdGhpcy5tYXN0ZXIuc2h1dGRvd24oKTsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIHJvb3QgcmVnaW9uIGxvY2F0aW9uLgorICAgKiBAcGFyYW0gYWRkcmVzcyBBZGRyZXNzIG9mIHRoZSByZWdpb24gc2VydmVyIHdoZXJlIHRoZSByb290IGxpdmVzCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRSb290UmVnaW9uTG9jYXRpb24oSFNlcnZlckFkZHJlc3MgYWRkcmVzcykgeworICAgIHdyaXRlUm9vdFJlZ2lvbkxvY2F0aW9uVG9ab29LZWVwZXIoYWRkcmVzcyk7CisKKyAgICBzeW5jaHJvbml6ZWQgKHJvb3RSZWdpb25Mb2NhdGlvbikgeworICAgICAgcm9vdFJlZ2lvbkxvY2F0aW9uLnNldChuZXcgSFNlcnZlckFkZHJlc3MoYWRkcmVzcykpOworICAgICAgcm9vdFJlZ2lvbkxvY2F0aW9uLm5vdGlmeUFsbCgpOworICAgIH0gCisgIH0KKyAgCisgIC8qKgorICAgKiBTZXQgdGhlIG51bWJlciBvZiBtZXRhIHJlZ2lvbnMuCisgICAqIEBwYXJhbSBudW0gTnVtYmVyIG9mIG1ldGEgcmVnaW9ucworICAgKi8KKyAgcHVibGljIHZvaWQgc2V0TnVtTWV0YVJlZ2lvbnMoaW50IG51bSkgeworICAgIG51bWJlck9mTWV0YVJlZ2lvbnMuc2V0KG51bSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogQHBhcmFtIGluZm8KKyAgICogQHBhcmFtIHNlcnZlcgorICAgKiBAcGFyYW0gb3AKKyAgICovCisgIHB1YmxpYyB2b2lkIHN0YXJ0QWN0aW9uKGJ5dGVbXSByZWdpb25OYW1lLCBIUmVnaW9uSW5mbyBpbmZvLAorICAgICAgSFNlcnZlckFkZHJlc3Mgc2VydmVyLCBpbnQgb3ApIHsKKyAgICBzd2l0Y2ggKG9wKSB7CisgICAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX1NQTElUOgorICAgICAgICBzdGFydEFjdGlvbihyZWdpb25OYW1lLCBpbmZvLCBzZXJ2ZXIsIHRoaXMucmVnaW9uc1RvU3BsaXQpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfQ09NUEFDVDoKKyAgICAgICAgc3RhcnRBY3Rpb24ocmVnaW9uTmFtZSwgaW5mbywgc2VydmVyLCB0aGlzLnJlZ2lvbnNUb0NvbXBhY3QpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfTUFKT1JfQ09NUEFDVDoKKyAgICAgICAgc3RhcnRBY3Rpb24ocmVnaW9uTmFtZSwgaW5mbywgc2VydmVyLCB0aGlzLnJlZ2lvbnNUb01ham9yQ29tcGFjdCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBIQ29uc3RhbnRzLk1PRElGWV9UQUJMRV9GTFVTSDoKKyAgICAgICAgc3RhcnRBY3Rpb24ocmVnaW9uTmFtZSwgaW5mbywgc2VydmVyLCB0aGlzLnJlZ2lvbnNUb0ZsdXNoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbGxlZ2FsIHRhYmxlIGFjdGlvbiAiICsgb3ApOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBzdGFydEFjdGlvbihmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwgZmluYWwgSFJlZ2lvbkluZm8gaW5mbywKKyAgICAgIGZpbmFsIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlciwKKyAgICAgIGZpbmFsIFNvcnRlZE1hcDxieXRlW10sIFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PiBtYXApIHsKKyAgICBtYXAucHV0KHJlZ2lvbk5hbWUsIG5ldyBQYWlyPEhSZWdpb25JbmZvLEhTZXJ2ZXJBZGRyZXNzPihpbmZvLCBzZXJ2ZXIpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gb3AKKyAgICovCisgIHB1YmxpYyB2b2lkIGVuZEFjdGlvbihieXRlW10gcmVnaW9uTmFtZSwgaW50IG9wKSB7CisgICAgc3dpdGNoIChvcCkgeworICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfU1BMSVQ6CisgICAgICB0aGlzLnJlZ2lvbnNUb1NwbGl0LnJlbW92ZShyZWdpb25OYW1lKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfQ09NUEFDVDoKKyAgICAgIHRoaXMucmVnaW9uc1RvQ29tcGFjdC5yZW1vdmUocmVnaW9uTmFtZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX01BSk9SX0NPTVBBQ1Q6CisgICAgICB0aGlzLnJlZ2lvbnNUb01ham9yQ29tcGFjdC5yZW1vdmUocmVnaW9uTmFtZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX0ZMVVNIOgorICAgICAgdGhpcy5yZWdpb25zVG9GbHVzaC5yZW1vdmUocmVnaW9uTmFtZSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaWxsZWdhbCB0YWJsZSBhY3Rpb24gIiArIG9wKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICovCisgIHB1YmxpYyB2b2lkIGVuZEFjdGlvbnMoYnl0ZVtdIHJlZ2lvbk5hbWUpIHsKKyAgICByZWdpb25zVG9TcGxpdC5yZW1vdmUocmVnaW9uTmFtZSk7CisgICAgcmVnaW9uc1RvQ29tcGFjdC5yZW1vdmUocmVnaW9uTmFtZSk7CisgIH0KKworICAvKioKKyAgICogU2VuZCBtZXNzYWdlcyB0byB0aGUgZ2l2ZW4gcmVnaW9uIHNlcnZlciBhc2tpbmcgaXQgdG8gc3BsaXQgYW55CisgICAqIHJlZ2lvbnMgaW4gJ3JlZ2lvbnNUb1NwbGl0JywgZXRjLgorICAgKiBAcGFyYW0gc2VydmVySW5mbworICAgKiBAcGFyYW0gcmV0dXJuTXNncworICAgKi8KKyAgcHVibGljIHZvaWQgYXBwbHlBY3Rpb25zKEhTZXJ2ZXJJbmZvIHNlcnZlckluZm8sIEFycmF5TGlzdDxITXNnPiByZXR1cm5Nc2dzKSB7CisgICAgYXBwbHlBY3Rpb25zKHNlcnZlckluZm8sIHJldHVybk1zZ3MsIHRoaXMucmVnaW9uc1RvQ29tcGFjdCwKKyAgICAgICAgSE1zZy5UeXBlLk1TR19SRUdJT05fQ09NUEFDVCk7CisgICAgYXBwbHlBY3Rpb25zKHNlcnZlckluZm8sIHJldHVybk1zZ3MsIHRoaXMucmVnaW9uc1RvU3BsaXQsCisgICAgICBITXNnLlR5cGUuTVNHX1JFR0lPTl9TUExJVCk7CisgICAgYXBwbHlBY3Rpb25zKHNlcnZlckluZm8sIHJldHVybk1zZ3MsIHRoaXMucmVnaW9uc1RvRmx1c2gsCisgICAgICAgIEhNc2cuVHlwZS5NU0dfUkVHSU9OX0ZMVVNIKTsKKyAgICBhcHBseUFjdGlvbnMoc2VydmVySW5mbywgcmV0dXJuTXNncywgdGhpcy5yZWdpb25zVG9NYWpvckNvbXBhY3QsCisgICAgICAgIEhNc2cuVHlwZS5NU0dfUkVHSU9OX01BSk9SX0NPTVBBQ1QpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgYXBwbHlBY3Rpb25zKGZpbmFsIEhTZXJ2ZXJJbmZvIHNlcnZlckluZm8sCisgICAgICBmaW5hbCBBcnJheUxpc3Q8SE1zZz4gcmV0dXJuTXNncywKKyAgICAgIFNvcnRlZE1hcDxieXRlW10sIFBhaXI8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+PiBtYXAsCisgICAgICBmaW5hbCBITXNnLlR5cGUgbXNnKSB7CisgICAgSFNlcnZlckFkZHJlc3MgYWRkciA9IHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpOworICAgIEl0ZXJhdG9yPFBhaXI8SFJlZ2lvbkluZm8sIEhTZXJ2ZXJBZGRyZXNzPj4gaSA9IG1hcC52YWx1ZXMoKS5pdGVyYXRvcigpOworICAgIHN5bmNocm9uaXplZCAobWFwKSB7CisgICAgICB3aGlsZSAoaS5oYXNOZXh0KCkpIHsKKyAgICAgICAgUGFpcjxIUmVnaW9uSW5mbyxIU2VydmVyQWRkcmVzcz4gcGFpciA9IGkubmV4dCgpOworICAgICAgICBpZiAoYWRkci5lcXVhbHMocGFpci5nZXRTZWNvbmQoKSkpIHsKKyAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgIExPRy5kZWJ1ZygiU2VuZGluZyAiICsgbXNnICsgIiAiICsgcGFpci5nZXRGaXJzdCgpICsgIiB0byAiICsgYWRkcik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybk1zZ3MuYWRkKG5ldyBITXNnKG1zZywgcGFpci5nZXRGaXJzdCgpKSk7CisgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qCisgICAqIFN0YXRlIG9mIGEgUmVnaW9uIGFzIGl0IHRyYW5zaXRpb25zIGZyb20gY2xvc2VkIHRvIG9wZW4sIGV0Yy4gIFNlZQorICAgKiBub3RlIG9uIHJlZ2lvbnNJblRyYW5zaXRpb24gZGF0YSBtZW1iZXIgYWJvdmUgZm9yIGxpc3Rpbmcgb2Ygc3RhdGUKKyAgICogdHJhbnNpdGlvbnMuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWdpb25TdGF0ZSBpbXBsZW1lbnRzIENvbXBhcmFibGU8UmVnaW9uU3RhdGU+IHsKKyAgICBwcml2YXRlIGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm87CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIHVuYXNzaWduZWQgPSBmYWxzZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gcGVuZGluZ09wZW4gPSBmYWxzZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gb3BlbiA9IGZhbHNlOworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjbG9zaW5nID0gZmFsc2U7CisgICAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIHBlbmRpbmdDbG9zZSA9IGZhbHNlOworICAgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKKyAgICBwcml2YXRlIHZvbGF0aWxlIGJvb2xlYW4gb2ZmbGluZWQgPSBmYWxzZTsKKyAgICAKKyAgICAvKiBTZXQgd2hlbiByZWdpb24gaXMgYXNzaWduZWQgb3IgY2xvc2luZyAqLworICAgIHByaXZhdGUgdm9sYXRpbGUgU3RyaW5nIHNlcnZlck5hbWUgPSBudWxsOworCisgICAgLyogQ29uc3RydWN0b3IgKi8KKyAgICBSZWdpb25TdGF0ZShIUmVnaW9uSW5mbyBpbmZvKSB7CisgICAgICB0aGlzLnJlZ2lvbkluZm8gPSBpbmZvOworICAgIH0KKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgSFJlZ2lvbkluZm8gZ2V0UmVnaW9uSW5mbygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJlZ2lvbkluZm87CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCBieXRlIFtdIGdldFJlZ2lvbk5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEByZXR1cm4gU2VydmVyIHRoaXMgcmVnaW9uIHdhcyBhc3NpZ25lZCB0bworICAgICAqLworICAgIHN5bmNocm9uaXplZCBTdHJpbmcgZ2V0U2VydmVyTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnNlcnZlck5hbWU7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHJlZ2lvbiBpcyBiZWluZyBvcGVuZWQKKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc09wZW5pbmcoKSB7CisgICAgICByZXR1cm4gdGhpcy51bmFzc2lnbmVkIHx8IHRoaXMucGVuZGluZ09wZW4gfHwgdGhpcy5vcGVuOworICAgIH0KKworICAgIC8qCisgICAgICogQHJldHVybiB0cnVlIGlmIHJlZ2lvbiBpcyB1bmFzc2lnbmVkCisgICAgICovCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gaXNVbmFzc2lnbmVkKCkgeworICAgICAgcmV0dXJuIHVuYXNzaWduZWQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBOb3RlOiBjYWxsZXJzIG9mIHRoaXMgbWV0aG9kIChyZWFzc2lnblJvb3RSZWdpb24sIAorICAgICAqIHJlZ2lvbnNBd2FpdGluZ0Fzc2lnbm1lbnQsIHNldFVuYXNzaWduZWQpIGVuc3VyZSB0aGF0IHRoaXMgbWV0aG9kIGlzIG5vdAorICAgICAqIGNhbGxlZCB1bmxlc3MgaXQgaXMgc2FmZSB0byBkbyBzby4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBzZXRVbmFzc2lnbmVkKCkgeworICAgICAgdGhpcy51bmFzc2lnbmVkID0gdHJ1ZTsKKyAgICAgIHRoaXMucGVuZGluZ09wZW4gPSBmYWxzZTsKKyAgICAgIHRoaXMub3BlbiA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zaW5nID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdDbG9zZSA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMub2ZmbGluZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMuc2VydmVyTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gaXNQZW5kaW5nT3BlbigpIHsKKyAgICAgIHJldHVybiBwZW5kaW5nT3BlbjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIEBwYXJhbSBzZXJ2ZXJOYW1lIFNlcnZlciByZWdpb24gd2FzIGFzc2lnbmVkIHRvLgorICAgICAqLworICAgIHN5bmNocm9uaXplZCB2b2lkIHNldFBlbmRpbmdPcGVuKGZpbmFsIFN0cmluZyBzZXJ2ZXJOYW1lKSB7CisgICAgICBpZiAoIXRoaXMudW5hc3NpZ25lZCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbm5vdCBhc3NpZ24gYSByZWdpb24gdGhhdCBpcyBub3QgY3VycmVudGx5IHVuYXNzaWduZWQuIFN0YXRlOiAiICsKKyAgICAgICAgICAgIHRvU3RyaW5nKCkpOworICAgICAgfQorICAgICAgdGhpcy51bmFzc2lnbmVkID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdPcGVuID0gdHJ1ZTsKKyAgICAgIHRoaXMub3BlbiA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zaW5nID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdDbG9zZSA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMub2ZmbGluZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMuc2VydmVyTmFtZSA9IHNlcnZlck5hbWU7CisgICAgfQorCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gaXNPcGVuKCkgeworICAgICAgcmV0dXJuIG9wZW47CisgICAgfQorCisgICAgc3luY2hyb25pemVkIHZvaWQgc2V0T3BlbigpIHsKKyAgICAgIGlmICghcGVuZGluZ09wZW4pIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJDYW5ub3Qgc2V0IGEgcmVnaW9uIGFzIG9wZW4gaWYgaXQgaGFzIG5vdCBiZWVuIHBlbmRpbmcuIFN0YXRlOiAiICsKKyAgICAgICAgICAgIHRvU3RyaW5nKCkpOworICAgICAgfQorICAgICAgdGhpcy51bmFzc2lnbmVkID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdPcGVuID0gZmFsc2U7CisgICAgICB0aGlzLm9wZW4gPSB0cnVlOworICAgICAgdGhpcy5jbG9zaW5nID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdDbG9zZSA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMub2ZmbGluZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc0Nsb3NpbmcoKSB7CisgICAgICByZXR1cm4gY2xvc2luZzsKKyAgICB9CisKKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBzZXRDbG9zaW5nKFN0cmluZyBzZXJ2ZXJOYW1lLCBib29sZWFuIHNldE9mZmxpbmUpIHsKKyAgICAgIHRoaXMudW5hc3NpZ25lZCA9IGZhbHNlOworICAgICAgdGhpcy5wZW5kaW5nT3BlbiA9IGZhbHNlOworICAgICAgdGhpcy5vcGVuID0gZmFsc2U7CisgICAgICB0aGlzLmNsb3NpbmcgPSB0cnVlOworICAgICAgdGhpcy5wZW5kaW5nQ2xvc2UgPSBmYWxzZTsKKyAgICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7CisgICAgICB0aGlzLm9mZmxpbmVkID0gc2V0T2ZmbGluZTsKKyAgICAgIHRoaXMuc2VydmVyTmFtZSA9IHNlcnZlck5hbWU7CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCBib29sZWFuIGlzUGVuZGluZ0Nsb3NlKCkgeworICAgICAgcmV0dXJuIHRoaXMucGVuZGluZ0Nsb3NlOworICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIHNldFBlbmRpbmdDbG9zZSgpIHsKKyAgICAgIGlmICghY2xvc2luZykgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbm5vdCBzZXQgYSByZWdpb24gYXMgcGVuZGluZyBjbG9zZSBpZiBpdCBoYXMgbm90IGJlZW4gY2xvc2luZy4gIiArCisgICAgICAgICAgICAiU3RhdGU6ICIgKyB0b1N0cmluZygpKTsKKyAgICAgIH0KKyAgICAgIHRoaXMudW5hc3NpZ25lZCA9IGZhbHNlOworICAgICAgdGhpcy5wZW5kaW5nT3BlbiA9IGZhbHNlOworICAgICAgdGhpcy5vcGVuID0gZmFsc2U7CisgICAgICB0aGlzLmNsb3NpbmcgPSBmYWxzZTsKKyAgICAgIHRoaXMucGVuZGluZ0Nsb3NlID0gdHJ1ZTsKKyAgICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7CisgICAgfQorCisgICAgc3luY2hyb25pemVkIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgICByZXR1cm4gdGhpcy5jbG9zZWQ7CisgICAgfQorICAgIAorICAgIHN5bmNocm9uaXplZCB2b2lkIHNldENsb3NlZCgpIHsKKyAgICAgIGlmICghcGVuZGluZ0Nsb3NlICYmICFwZW5kaW5nT3BlbikgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbm5vdCBzZXQgYSByZWdpb24gdG8gYmUgY2xvc2VkIGlmIGl0IHdhcyBub3QgYWxyZWFkeSBtYXJrZWQgYXMiICsKKyAgICAgICAgICAgICIgcGVuZGluZyBjbG9zZSBvciBwZW5kaW5nIG9wZW4uIFN0YXRlOiAiICsgdG9TdHJpbmcoKSk7CisgICAgICB9CisgICAgICB0aGlzLnVuYXNzaWduZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMucGVuZGluZ09wZW4gPSBmYWxzZTsKKyAgICAgIHRoaXMub3BlbiA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zaW5nID0gZmFsc2U7CisgICAgICB0aGlzLnBlbmRpbmdDbG9zZSA9IGZhbHNlOworICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlOworICAgIH0KKyAgICAKKyAgICBzeW5jaHJvbml6ZWQgYm9vbGVhbiBpc09mZmxpbmVkKCkgeworICAgICAgcmV0dXJuIHRoaXMub2ZmbGluZWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gKCJuYW1lPSIgKyBCeXRlcy50b1N0cmluZyhnZXRSZWdpb25OYW1lKCkpICsKKyAgICAgICAgICAiLCB1bmFzc2lnbmVkPSIgKyB0aGlzLnVuYXNzaWduZWQgKworICAgICAgICAgICIsIHBlbmRpbmdPcGVuPSIgKyB0aGlzLnBlbmRpbmdPcGVuICsKKyAgICAgICAgICAiLCBvcGVuPSIgKyB0aGlzLm9wZW4gKworICAgICAgICAgICIsIGNsb3Npbmc9IiArIHRoaXMuY2xvc2luZyArCisgICAgICAgICAgIiwgcGVuZGluZ0Nsb3NlPSIgKyB0aGlzLnBlbmRpbmdDbG9zZSArCisgICAgICAgICAgIiwgY2xvc2VkPSIgKyB0aGlzLmNsb3NlZCArCisgICAgICAgICAgIiwgb2ZmbGluZWQ9IiArIHRoaXMub2ZmbGluZWQpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICAgIGlmICh0aGlzID09IG8pIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAobyA9PSBudWxsIHx8IGdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0aGlzLmNvbXBhcmVUbygoUmVnaW9uU3RhdGUpIG8pID09IDA7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcoZ2V0UmVnaW9uTmFtZSgpKS5oYXNoQ29kZSgpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhSZWdpb25TdGF0ZSBvKSB7CisgICAgICBpZiAobyA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgICAgcmV0dXJuIEJ5dGVzLmNvbXBhcmVUbyhnZXRSZWdpb25OYW1lKCksIG8uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9SZWdpb25TZXJ2ZXJPcGVyYXRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9SZWdpb25TZXJ2ZXJPcGVyYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTFkYTExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1JlZ2lvblNlcnZlck9wZXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5EZWxheWVkOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworCithYnN0cmFjdCBjbGFzcyBSZWdpb25TZXJ2ZXJPcGVyYXRpb24gaW1wbGVtZW50cyBEZWxheWVkLCBIQ29uc3RhbnRzIHsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gCisgICAgTG9nRmFjdG9yeS5nZXRMb2coUmVnaW9uU2VydmVyT3BlcmF0aW9uLmNsYXNzLmdldE5hbWUoKSk7CisgIAorICBwcml2YXRlIGxvbmcgZXhwaXJlOworICBwcm90ZWN0ZWQgZmluYWwgSE1hc3RlciBtYXN0ZXI7CisgIHByb3RlY3RlZCBmaW5hbCBpbnQgbnVtUmV0cmllczsKKyAgCisgIHByb3RlY3RlZCBSZWdpb25TZXJ2ZXJPcGVyYXRpb24oSE1hc3RlciBtYXN0ZXIpIHsKKyAgICB0aGlzLm1hc3RlciA9IG1hc3RlcjsKKyAgICB0aGlzLm51bVJldHJpZXMgPSBtYXN0ZXIubnVtUmV0cmllczsKKyAgICAvLyBTZXQgdGhlIGZ1dHVyZSB0aW1lIGF0IHdoaWNoIHdlIGV4cGVjdCB0byBiZSByZWxlYXNlZCBmcm9tIHRoZQorICAgIC8vIERlbGF5UXVldWUgd2UncmUgaW5zZXJ0ZWQgaW4gb24gbGVhc2UgZXhwaXJhdGlvbi4KKyAgICB0aGlzLmV4cGlyZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgdGhpcy5tYXN0ZXIubGVhc2VUaW1lb3V0IC8gMjsKKyAgfQorICAKKyAgcHVibGljIGxvbmcgZ2V0RGVsYXkoVGltZVVuaXQgdW5pdCkgeworICAgIHJldHVybiB1bml0LmNvbnZlcnQodGhpcy5leHBpcmUgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAgICAgIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisgIH0KKyAgCisgIHB1YmxpYyBpbnQgY29tcGFyZVRvKERlbGF5ZWQgbykgeworICAgIHJldHVybiBMb25nLnZhbHVlT2YoZ2V0RGVsYXkoVGltZVVuaXQuTUlMTElTRUNPTkRTKQorICAgICAgICAtIG8uZ2V0RGVsYXkoVGltZVVuaXQuTUlMTElTRUNPTkRTKSkuaW50VmFsdWUoKTsKKyAgfQorICAKKyAgcHJvdGVjdGVkIHZvaWQgcmVxdWV1ZSgpIHsKKyAgICB0aGlzLmV4cGlyZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgdGhpcy5tYXN0ZXIubGVhc2VUaW1lb3V0IC8gMjsKKyAgICBtYXN0ZXIuZGVsYXllZFRvRG9RdWV1ZS5wdXQodGhpcyk7CisgIH0KKyAgCisgIHByb3RlY3RlZCBib29sZWFuIHJvb3RBdmFpbGFibGUoKSB7CisgICAgYm9vbGVhbiBhdmFpbGFibGUgPSB0cnVlOworICAgIGlmIChtYXN0ZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCkgPT0gbnVsbCkgeworICAgICAgYXZhaWxhYmxlID0gZmFsc2U7CisgICAgICByZXF1ZXVlKCk7CisgICAgfQorICAgIHJldHVybiBhdmFpbGFibGU7CisgIH0KKworICBwcm90ZWN0ZWQgYm9vbGVhbiBtZXRhVGFibGVBdmFpbGFibGUoKSB7CisgICAgYm9vbGVhbiBhdmFpbGFibGUgPSB0cnVlOworICAgIGlmICgobWFzdGVyLnJlZ2lvbk1hbmFnZXIubnVtTWV0YVJlZ2lvbnMoKSAhPQorICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIubnVtT25saW5lTWV0YVJlZ2lvbnMoKSkgfHwKKyAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLm1ldGFSZWdpb25zSW5UcmFuc2l0aW9uKCkpIHsKKyAgICAgIC8vIFdlIGNhbid0IHByb2NlZWQgYmVjYXVzZSBub3QgYWxsIG9mIHRoZSBtZXRhIHJlZ2lvbnMgYXJlIG9ubGluZS4KKyAgICAgIC8vIFdlIGNhbid0IGJsb2NrIGVpdGhlciBiZWNhdXNlIHRoYXQgd291bGQgcHJldmVudCB0aGUgbWV0YSByZWdpb24KKyAgICAgIC8vIG9ubGluZSBtZXNzYWdlIGZyb20gYmVpbmcgcHJvY2Vzc2VkLiBJbiBvcmRlciB0byBwcmV2ZW50IHNwaW5uaW5nCisgICAgICAvLyBpbiB0aGUgcnVuIHF1ZXVlLCBwdXQgdGhpcyByZXF1ZXN0IG9uIHRoZSBkZWxheSBxdWV1ZSB0byBnaXZlCisgICAgICAvLyBvdGhlciB0aHJlYWRzIHRoZSBvcHBvcnR1bml0eSB0byBnZXQgdGhlIG1ldGEgcmVnaW9ucyBvbi1saW5lLgorICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygibnVtYmVyT2ZNZXRhUmVnaW9uczogIiArIAorICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIubnVtTWV0YVJlZ2lvbnMoKSArCisgICAgICAgICAgICAiLCBvbmxpbmVNZXRhUmVnaW9ucy5zaXplKCk6ICIgKyAKKyAgICAgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLm51bU9ubGluZU1ldGFSZWdpb25zKCkpOworICAgICAgICBMT0cuZGVidWcoIlJlcXVldWluZyBiZWNhdXNlIG5vdCBhbGwgbWV0YSByZWdpb25zIGFyZSBvbmxpbmUiKTsKKyAgICAgIH0KKyAgICAgIGF2YWlsYWJsZSA9IGZhbHNlOworICAgICAgcmVxdWV1ZSgpOworICAgIH0KKyAgICByZXR1cm4gYXZhaWxhYmxlOworICB9CisgIAorICBwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBwcm9jZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9SZXRyeWFibGVNZXRhT3BlcmF0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUmV0cnlhYmxlTWV0YU9wZXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkZTg5YzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUmV0cnlhYmxlTWV0YU9wZXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pcGMuUmVtb3RlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVGFibGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5UYWJsZU5vdERpc2FibGVkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5TbGVlcGVyOworCisvKioKKyAqIFVzZXMgQ2FsbGFibGUgcGF0dGVybiBzbyB0aGF0IG9wZXJhdGlvbnMgYWdhaW5zdCBtZXRhIHJlZ2lvbnMgZG8gbm90IG5lZWQKKyAqIHRvIGR1cGxpY2F0ZSByZXRyeSBsb2dpYy4KKyAqLworYWJzdHJhY3QgY2xhc3MgUmV0cnlhYmxlTWV0YU9wZXJhdGlvbjxUPiBpbXBsZW1lbnRzIENhbGxhYmxlPFQ+IHsKKyAgcHJvdGVjdGVkIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkpOworICBwcm90ZWN0ZWQgZmluYWwgU2xlZXBlciBzbGVlcGVyOworICBwcm90ZWN0ZWQgZmluYWwgTWV0YVJlZ2lvbiBtOworICBwcm90ZWN0ZWQgZmluYWwgSE1hc3RlciBtYXN0ZXI7CisgIAorICBwcm90ZWN0ZWQgSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXI7CisgIAorICBwcm90ZWN0ZWQgUmV0cnlhYmxlTWV0YU9wZXJhdGlvbihNZXRhUmVnaW9uIG0sIEhNYXN0ZXIgbWFzdGVyKSB7CisgICAgdGhpcy5tID0gbTsKKyAgICB0aGlzLm1hc3RlciA9IG1hc3RlcjsKKyAgICB0aGlzLnNsZWVwZXIgPSBuZXcgU2xlZXBlcihtYXN0ZXIudGhyZWFkV2FrZUZyZXF1ZW5jeSwgbWFzdGVyLmNsb3NlZCk7CisgIH0KKyAgCisgIHByb3RlY3RlZCBUIGRvV2l0aFJldHJpZXMoKQorICB0aHJvd3MgSU9FeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24geworICAgIExpc3Q8SU9FeGNlcHRpb24+IGV4Y2VwdGlvbnMgPSBuZXcgQXJyYXlMaXN0PElPRXhjZXB0aW9uPigpOworICAgIGZvcihpbnQgdHJpZXMgPSAwOyB0cmllcyA8IG1hc3Rlci5udW1SZXRyaWVzOyB0cmllcysrKSB7CisgICAgICBpZiAobWFzdGVyLmNsb3NlZC5nZXQoKSkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIHRoaXMuc2VydmVyID0gbWFzdGVyLmNvbm5lY3Rpb24uZ2V0SFJlZ2lvbkNvbm5lY3Rpb24obS5nZXRTZXJ2ZXIoKSk7CisgICAgICAgIHJldHVybiB0aGlzLmNhbGwoKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIHx8CisgICAgICAgICAgICBlIGluc3RhbmNlb2YgVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbiB8fAorICAgICAgICAgICAgZSBpbnN0YW5jZW9mIEludmFsaWRDb2x1bW5OYW1lRXhjZXB0aW9uKSB7CisgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJlbW90ZUV4Y2VwdGlvbikgeworICAgICAgICAgIGUgPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmRlY29kZVJlbW90ZUV4Y2VwdGlvbigoUmVtb3RlRXhjZXB0aW9uKSBlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAodHJpZXMgPT0gbWFzdGVyLm51bVJldHJpZXMgLSAxKSB7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIG1lc3NhZ2UgPSBuZXcgU3RyaW5nQnVpbGRlcigKKyAgICAgICAgICAgICAgICAiVHJ5aW5nIHRvIGNvbnRhY3QgcmVnaW9uIHNlcnZlciBmb3IgcmVnaW9uTmFtZSAnIiArIAorICAgICAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKG0uZ2V0UmVnaW9uTmFtZSgpKSArICInLCBidXQgZmFpbGVkIGFmdGVyICIgKworICAgICAgICAgICAgICAgICh0cmllcyArIDEpICsgIiBhdHRlbXB0cy5cbiIpOworICAgICAgICAgICAgaW50IGkgPSAxOworICAgICAgICAgICAgZm9yIChJT0V4Y2VwdGlvbiBlMiA6IGV4Y2VwdGlvbnMpIHsKKyAgICAgICAgICAgICAgbWVzc2FnZS5hcHBlbmQoIkV4Y2VwdGlvbiAiICsgaSArICI6XG4iICsgZTIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgTE9HLmRlYnVnKG1lc3NhZ2UpOworICAgICAgICAgIH0KKyAgICAgICAgICB0aGlzLm1hc3Rlci5jaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIGV4Y2VwdGlvbnMuYWRkKGUpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICAgIH0KKyAgICAgIHNsZWVwZXIuc2xlZXAoKTsKKyAgICB9CisgICAgcmV0dXJuIG51bGw7ICAgIAorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUm9vdFNjYW5uZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9Sb290U2Nhbm5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZGVlZmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvUm9vdFNjYW5uZXIuamF2YQpAQCAtMCwwICsxLDgxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CisKKy8qKiBTY2FubmVyIGZvciB0aGUgPGNvZGU+Uk9PVDwvY29kZT4gSFJlZ2lvbi4gKi8KK2NsYXNzIFJvb3RTY2FubmVyIGV4dGVuZHMgQmFzZVNjYW5uZXIgeworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIG1hc3RlcgorICAgKi8KKyAgcHVibGljIFJvb3RTY2FubmVyKEhNYXN0ZXIgbWFzdGVyKSB7CisgICAgc3VwZXIobWFzdGVyLCB0cnVlLCBtYXN0ZXIubWV0YVJlc2NhbkludGVydmFsLCBtYXN0ZXIuc2h1dGRvd25SZXF1ZXN0ZWQpOworICB9CisKKyAgLyoqCisgICAqIERvbid0IHJldHJ5IGlmIHdlIGdldCBhbiBlcnJvciB3aGlsZSBzY2FubmluZy4gRXJyb3JzIGFyZSBtb3N0IG9mdGVuCisgICAqCisgICAqIGNhdXNlZCBieSB0aGUgc2VydmVyIGdvaW5nIGF3YXkuIFdhaXQgdW50aWwgbmV4dCByZXNjYW4gaW50ZXJ2YWwgd2hlbgorICAgKiB0aGluZ3Mgc2hvdWxkIGJlIGJhY2sgdG8gbm9ybWFsLgorICAgKiBAcmV0dXJuIFRydWUgaWYgc3VjY2Vzc2Z1bGx5IHNjYW5uZWQuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gc2NhblJvb3QoKSB7CisgICAgbWFzdGVyLndhaXRGb3JSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICBpZiAobWFzdGVyLmNsb3NlZC5nZXQoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHRyeSB7CisgICAgICAvLyBEb24ndCBpbnRlcnJ1cHQgdXMgd2hpbGUgd2UncmUgd29ya2luZworICAgICAgc3luY2hyb25pemVkKHNjYW5uZXJMb2NrKSB7CisgICAgICAgIGlmIChtYXN0ZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCkgIT0gbnVsbCkgeworICAgICAgICAgIHNjYW5SZWdpb24obmV3IE1ldGFSZWdpb24obWFzdGVyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpLAorICAgICAgICAgICAgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLmdldFJlZ2lvbk5hbWUoKSkpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgZSA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKTsKKyAgICAgIExPRy53YXJuKCJTY2FuIFJPT1QgcmVnaW9uIiwgZSk7CisgICAgICAvLyBNYWtlIHN1cmUgdGhlIGZpbGUgc3lzdGVtIGlzIHN0aWxsIGF2YWlsYWJsZQorICAgICAgbWFzdGVyLmNoZWNrRmlsZVN5c3RlbSgpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBJZiBmb3Igc29tZSByZWFzb24gd2UgZ2V0IHNvbWUgb3RoZXIga2luZCBvZiBleGNlcHRpb24sIAorICAgICAgLy8gYXQgbGVhc3QgbG9nIGl0IHJhdGhlciB0aGFuIGdvIG91dCBzaWxlbnRseS4KKyAgICAgIExPRy5lcnJvcigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBlKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGJvb2xlYW4gaW5pdGlhbFNjYW4oKSB7CisgICAgdGhpcy5pbml0aWFsU2NhbkNvbXBsZXRlID0gc2NhblJvb3QoKTsKKyAgICByZXR1cm4gaW5pdGlhbFNjYW5Db21wbGV0ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBtYWludGVuYW5jZVNjYW4oKSB7CisgICAgc2NhblJvb3QoKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9TZXJ2ZXJNYW5hZ2VyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvU2VydmVyTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZjNjZmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvU2VydmVyTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsNzkxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuQ2hvcmU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckxvYWQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25Mb2NhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5MZWFzZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZy5UeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyLlpvb0tlZXBlcldyYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlZEV2ZW50OworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLldhdGNoZXI7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlci5FdmVudC5FdmVudFR5cGU7CisKKy8qKgorICogVGhlIFNlcnZlck1hbmFnZXIgY2xhc3MgbWFuYWdlcyBpbmZvIGFib3V0IHJlZ2lvbiBzZXJ2ZXJzIC0gSFNlcnZlckluZm8sIAorICogbG9hZCBudW1iZXJzLCBkeWluZyBzZXJ2ZXJzLCBldGMuCisgKi8KK2NsYXNzIFNlcnZlck1hbmFnZXIgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPQorICAgIExvZ0ZhY3RvcnkuZ2V0TG9nKFNlcnZlck1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSE1zZyBSRUdJT05TRVJWRVJfUVVJRVNDRSA9CisgICAgbmV3IEhNc2coVHlwZS5NU0dfUkVHSU9OU0VSVkVSX1FVSUVTQ0UpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBITXNnIFJFR0lPTlNFUlZFUl9TVE9QID0KKyAgICBuZXcgSE1zZyhUeXBlLk1TR19SRUdJT05TRVJWRVJfU1RPUCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhNc2cgQ0FMTF9TRVJWRVJfU1RBUlRVUCA9CisgICAgbmV3IEhNc2coVHlwZS5NU0dfQ0FMTF9TRVJWRVJfU1RBUlRVUCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhNc2cgW10gRU1QVFlfSE1TR19BUlJBWSA9IG5ldyBITXNnWzBdOworICAKKyAgcHJpdmF0ZSBmaW5hbCBBdG9taWNJbnRlZ2VyIHF1aWVzY2VkU2VydmVycyA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworICBwcml2YXRlIGZpbmFsIFpvb0tlZXBlcldyYXBwZXIgem9vS2VlcGVyV3JhcHBlcjsKKworICAvKiogVGhlIG1hcCBvZiBrbm93biBzZXJ2ZXIgbmFtZXMgdG8gc2VydmVyIGluZm8gKi8KKyAgZmluYWwgTWFwPFN0cmluZywgSFNlcnZlckluZm8+IHNlcnZlcnNUb1NlcnZlckluZm8gPQorICAgIG5ldyBDb25jdXJyZW50SGFzaE1hcDxTdHJpbmcsIEhTZXJ2ZXJJbmZvPigpOworCisgIGZpbmFsIE1hcDxIU2VydmVyQWRkcmVzcywgSFNlcnZlckluZm8+IHNlcnZlckFkZHJlc3NUb1NlcnZlckluZm8gPQorICAgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPEhTZXJ2ZXJBZGRyZXNzLCBIU2VydmVySW5mbz4oKTsKKyAgCisgIC8qKgorICAgKiBTZXQgb2Yga25vd24gZGVhZCBzZXJ2ZXJzLiAgT24gem5vZGUgZXhwaXJhdGlvbiwgc2VydmVycyBhcmUgYWRkZWQgaGVyZS4KKyAgICogVGhpcyBpcyBuZWVkZWQgaW4gY2FzZSBvZiBhIG5ldHdvcmsgcGFydGl0aW9uaW5nIHdoZXJlIHRoZSBzZXJ2ZXIncyBsZWFzZQorICAgKiBleHBpcmVzLCBidXQgdGhlIHNlcnZlciBpcyBzdGlsbCBydW5uaW5nLiBBZnRlciB0aGUgbmV0d29yayBpcyBoZWFsZWQsCisgICAqIGFuZCBpdCdzIHNlcnZlciBsb2dzIGFyZSByZWNvdmVyZWQsIGl0IHdpbGwgYmUgdG9sZCB0byBjYWxsIHNlcnZlciBzdGFydHVwCisgICAqIGJlY2F1c2UgYnkgdGhlbiwgaXRzIHJlZ2lvbnMgaGF2ZSBwcm9iYWJseSBiZWVuIHJlYXNzaWduZWQuCisgICAqLworICBwcm90ZWN0ZWQgZmluYWwgU2V0PFN0cmluZz4gZGVhZFNlcnZlcnMgPQorICAgIENvbGxlY3Rpb25zLnN5bmNocm9uaXplZFNldChuZXcgSGFzaFNldDxTdHJpbmc+KCkpOworCisgIC8qKiBTb3J0ZWRNYXAgc2VydmVyIGxvYWQgLT4gU2V0IG9mIHNlcnZlciBuYW1lcyAqLworICBmaW5hbCBTb3J0ZWRNYXA8SFNlcnZlckxvYWQsIFNldDxTdHJpbmc+PiBsb2FkVG9TZXJ2ZXJzID0KKyAgICBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTb3J0ZWRNYXAobmV3IFRyZWVNYXA8SFNlcnZlckxvYWQsIFNldDxTdHJpbmc+PigpKTsKKworICAvKiogTWFwIG9mIHNlcnZlciBuYW1lcyAtPiBzZXJ2ZXIgbG9hZCAqLworICBmaW5hbCBNYXA8U3RyaW5nLCBIU2VydmVyTG9hZD4gc2VydmVyc1RvTG9hZCA9CisgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPFN0cmluZywgSFNlcnZlckxvYWQ+KCk7ICAKKworICBwcm90ZWN0ZWQgSE1hc3RlciBtYXN0ZXI7CisgIAorICAvKiBUaGUgcmVnaW9uc2VydmVyIHdpbGwgbm90IGJlIGFzc2lnbmVkIG9yIGFza2VkIGNsb3NlIHJlZ2lvbnMgaWYgaXQKKyAgICogaXMgY3VycmVudGx5IG9wZW5pbmcgPj0gdGhpcyBtYW55IHJlZ2lvbnMuCisgICAqLworICBwcml2YXRlIGZpbmFsIGludCBub2JhbGFuY2luZ0NvdW50OworCisgIGNsYXNzIFNlcnZlck1vbml0b3IgZXh0ZW5kcyBDaG9yZSB7CisKKyAgICBTZXJ2ZXJNb25pdG9yKGZpbmFsIGludCBwZXJpb2QsIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcCkgeworICAgICAgc3VwZXIocGVyaW9kLCBzdG9wKTsKKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgdm9pZCBjaG9yZSgpIHsKKyAgICAgIGludCBudW1TZXJ2ZXJzID0gc2VydmVyQWRkcmVzc1RvU2VydmVySW5mby5zaXplKCk7CisgICAgICBpbnQgbnVtRGVhZFNlcnZlcnMgPSBkZWFkU2VydmVycy5zaXplKCk7CisgICAgICBkb3VibGUgYXZlcmFnZUxvYWQgPSBnZXRBdmVyYWdlTG9hZCgpOworICAgICAgTE9HLmluZm8obnVtU2VydmVycyArICIgcmVnaW9uIHNlcnZlcnMsICIgKyBudW1EZWFkU2VydmVycyArIAorICAgICAgICAiIGRlYWQsIGF2ZXJhZ2UgbG9hZCAiICsgYXZlcmFnZUxvYWQpOworICAgICAgaWYgKG51bURlYWRTZXJ2ZXJzID4gMCkgeworICAgICAgICBMT0cuaW5mbygiREVBRCBbIik7CisgICAgICAgIGZvciAoU3RyaW5nIHNlcnZlcjogZGVhZFNlcnZlcnMpIHsKKyAgICAgICAgICBMT0cuaW5mbygiICAiICsgc2VydmVyKTsKKyAgICAgICAgfQorICAgICAgICBMT0cuaW5mbygiXSIpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgfQorCisgIFNlcnZlck1vbml0b3Igc2VydmVyTW9uaXRvclRocmVhZDsKKworICAvKioKKyAgICogQHBhcmFtIG1hc3RlcgorICAgKi8KKyAgcHVibGljIFNlcnZlck1hbmFnZXIoSE1hc3RlciBtYXN0ZXIpIHsKKyAgICB0aGlzLm1hc3RlciA9IG1hc3RlcjsKKyAgICB6b29LZWVwZXJXcmFwcGVyID0gbWFzdGVyLmdldFpvb0tlZXBlcldyYXBwZXIoKTsKKyAgICB0aGlzLm5vYmFsYW5jaW5nQ291bnQgPSBtYXN0ZXIuZ2V0Q29uZmlndXJhdGlvbigpLgorICAgICAgZ2V0SW50KCJoYmFzZS5yZWdpb25zLm5vYmFsYW5jaW5nLmNvdW50IiwgNCk7CisgICAgc2VydmVyTW9uaXRvclRocmVhZCA9IG5ldyBTZXJ2ZXJNb25pdG9yKG1hc3Rlci5tZXRhUmVzY2FuSW50ZXJ2YWwsCisgICAgICBtYXN0ZXIuc2h1dGRvd25SZXF1ZXN0ZWQpOworICAgIHNlcnZlck1vbml0b3JUaHJlYWQuc3RhcnQoKTsKKyAgfQorIAorICAvKioKKyAgICogTGV0IHRoZSBzZXJ2ZXIgbWFuYWdlciBrbm93IGEgbmV3IHJlZ2lvbnNlcnZlciBoYXMgY29tZSBvbmxpbmUKKyAgICogQHBhcmFtIHNlcnZlckluZm8KKyAgICogQHRocm93cyBMZWFzZXMuTGVhc2VTdGlsbEhlbGRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHJlZ2lvblNlcnZlclN0YXJ0dXAoZmluYWwgSFNlcnZlckluZm8gc2VydmVySW5mbykgCisgIHRocm93cyBMZWFzZXMuTGVhc2VTdGlsbEhlbGRFeGNlcHRpb24geworICAgIEhTZXJ2ZXJJbmZvIGluZm8gPSBuZXcgSFNlcnZlckluZm8oc2VydmVySW5mbyk7CisgICAgU3RyaW5nIHNlcnZlck5hbWUgPSBIU2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKGluZm8pOworICAgIGlmIChzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLmNvbnRhaW5zS2V5KHNlcnZlck5hbWUpIHx8CisgICAgICAgIGRlYWRTZXJ2ZXJzLmNvbnRhaW5zKHNlcnZlck5hbWUpKSB7CisgICAgICBMT0cuZGVidWcoIlNlcnZlciBzdGFydCB3YXMgcmVqZWN0ZWQ6ICIgKyBzZXJ2ZXJJbmZvKTsKKyAgICAgIExPRy5kZWJ1Zygic2VydmVyc1RvU2VydmVySW5mby5jb250YWluc0tleTogIiArIHNlcnZlcnNUb1NlcnZlckluZm8uY29udGFpbnNLZXkoc2VydmVyTmFtZSkpOworICAgICAgTE9HLmRlYnVnKCJkZWFkU2VydmVycy5jb250YWluczogIiArIGRlYWRTZXJ2ZXJzLmNvbnRhaW5zKHNlcnZlck5hbWUpKTsKKyAgICAgIHRocm93IG5ldyBMZWFzZXMuTGVhc2VTdGlsbEhlbGRFeGNlcHRpb24oc2VydmVyTmFtZSk7CisgICAgfQorICAgIFdhdGNoZXIgd2F0Y2hlciA9IG5ldyBTZXJ2ZXJFeHBpcmVyKHNlcnZlck5hbWUsIGluZm8uZ2V0U2VydmVyQWRkcmVzcygpKTsKKyAgICB6b29LZWVwZXJXcmFwcGVyLnVwZGF0ZVJTTG9jYXRpb25HZXRXYXRjaChpbmZvLCB3YXRjaGVyKTsKKyAgICAKKyAgICBMT0cuaW5mbygiUmVjZWl2ZWQgc3RhcnQgbWVzc2FnZSBmcm9tOiAiICsgc2VydmVyTmFtZSk7CisgICAgLy8gR28gb24gdG8gcHJvY2VzcyB0aGUgcmVnaW9uc2VydmVyIHJlZ2lzdHJhdGlvbi4KKyAgICBIU2VydmVyTG9hZCBsb2FkID0gc2VydmVyc1RvTG9hZC5yZW1vdmUoc2VydmVyTmFtZSk7CisgICAgaWYgKGxvYWQgIT0gbnVsbCkgeworICAgICAgLy8gVGhlIHN0YXJ0dXAgbWVzc2FnZSB3YXMgZnJvbSBhIGtub3duIHNlcnZlci4KKyAgICAgIC8vIFJlbW92ZSBzdGFsZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2VydmVyJ3MgbG9hZC4KKyAgICAgIHN5bmNocm9uaXplZCAobG9hZFRvU2VydmVycykgeworICAgICAgICBTZXQ8U3RyaW5nPiBzZXJ2ZXJzID0gbG9hZFRvU2VydmVycy5nZXQobG9hZCk7CisgICAgICAgIGlmIChzZXJ2ZXJzICE9IG51bGwpIHsKKyAgICAgICAgICBzZXJ2ZXJzLnJlbW92ZShzZXJ2ZXJOYW1lKTsKKyAgICAgICAgICBsb2FkVG9TZXJ2ZXJzLnB1dChsb2FkLCBzZXJ2ZXJzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBIU2VydmVySW5mbyBzdG9yZWRJbmZvID0gc2VydmVyc1RvU2VydmVySW5mby5yZW1vdmUoc2VydmVyTmFtZSk7CisgICAgaWYgKHN0b3JlZEluZm8gIT0gbnVsbCAmJiAhbWFzdGVyLmNsb3NlZC5nZXQoKSkgeworICAgICAgLy8gVGhlIHN0YXJ0dXAgbWVzc2FnZSB3YXMgZnJvbSBhIGtub3duIHNlcnZlciB3aXRoIHRoZSBzYW1lIG5hbWUuCisgICAgICAvLyBUaW1lb3V0IHRoZSBvbGQgb25lIHJpZ2h0IGF3YXkuCisgICAgICBIU2VydmVyQWRkcmVzcyByb290ID0gbWFzdGVyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpOworICAgICAgYm9vbGVhbiByb290U2VydmVyID0gZmFsc2U7CisgICAgICBpZiAocm9vdCAhPSBudWxsICYmIHJvb3QuZXF1YWxzKHN0b3JlZEluZm8uZ2V0U2VydmVyQWRkcmVzcygpKSkgeworICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci51bnNldFJvb3RSZWdpb24oKTsKKyAgICAgICAgcm9vdFNlcnZlciA9IHRydWU7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBtYXN0ZXIudG9Eb1F1ZXVlLnB1dCgKKyAgICAgICAgICAgIG5ldyBQcm9jZXNzU2VydmVyU2h1dGRvd24obWFzdGVyLCBzdG9yZWRJbmZvLCByb290U2VydmVyKSk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiSW5zZXJ0aW9uIGludG8gdG9Eb1F1ZXVlIHdhcyBpbnRlcnJ1cHRlZCIsIGUpOworICAgICAgfQorICAgIH0KKyAgICAvLyByZWNvcmQgbmV3IHNlcnZlcgorICAgIGxvYWQgPSBuZXcgSFNlcnZlckxvYWQoKTsKKyAgICBpbmZvLnNldExvYWQobG9hZCk7CisgICAgc2VydmVyc1RvU2VydmVySW5mby5wdXQoc2VydmVyTmFtZSwgaW5mbyk7CisgICAgc2VydmVyQWRkcmVzc1RvU2VydmVySW5mby5wdXQoaW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCksIGluZm8pOworICAgIHNlcnZlcnNUb0xvYWQucHV0KHNlcnZlck5hbWUsIGxvYWQpOworICAgIHN5bmNocm9uaXplZCAobG9hZFRvU2VydmVycykgeworICAgICAgU2V0PFN0cmluZz4gc2VydmVycyA9IGxvYWRUb1NlcnZlcnMuZ2V0KGxvYWQpOworICAgICAgaWYgKHNlcnZlcnMgPT0gbnVsbCkgeworICAgICAgICBzZXJ2ZXJzID0gbmV3IEhhc2hTZXQ8U3RyaW5nPigpOworICAgICAgfQorICAgICAgc2VydmVycy5hZGQoc2VydmVyTmFtZSk7CisgICAgICBsb2FkVG9TZXJ2ZXJzLnB1dChsb2FkLCBzZXJ2ZXJzKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBDYWxsZWQgdG8gcHJvY2VzcyB0aGUgbWVzc2FnZXMgc2VudCBmcm9tIHRoZSByZWdpb24gc2VydmVyIHRvIHRoZSBtYXN0ZXIKKyAgICogYWxvbmcgd2l0aCB0aGUgaGVhcnQgYmVhdC4KKyAgICogCisgICAqIEBwYXJhbSBzZXJ2ZXJJbmZvCisgICAqIEBwYXJhbSBtc2dzCisgICAqIEBwYXJhbSBtb3N0TG9hZGVkUmVnaW9ucyBBcnJheSBvZiByZWdpb25zIHRoZSByZWdpb24gc2VydmVyIGlzIHN1Ym1pdHRpbmcKKyAgICogYXMgY2FuZGlkYXRlcyB0byBiZSByZWJhbGFuY2VkLCBzaG91bGQgaXQgYmUgb3ZlcmxvYWRlZAorICAgKiBAcmV0dXJuIG1lc3NhZ2VzIGZyb20gbWFzdGVyIHRvIHJlZ2lvbiBzZXJ2ZXIgaW5kaWNhdGluZyB3aGF0IHJlZ2lvbgorICAgKiBzZXJ2ZXIgc2hvdWxkIGRvLgorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhNc2cgW10gcmVnaW9uU2VydmVyUmVwb3J0KGZpbmFsIEhTZXJ2ZXJJbmZvIHNlcnZlckluZm8sCisgICAgZmluYWwgSE1zZyBtc2dzW10sIGZpbmFsIEhSZWdpb25JbmZvW10gbW9zdExvYWRlZFJlZ2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFNlcnZlckluZm8gaW5mbyA9IG5ldyBIU2VydmVySW5mbyhzZXJ2ZXJJbmZvKTsKKyAgICBpZiAoaXNEZWFkKGluZm8uZ2V0U2VydmVyTmFtZSgpKSkgeworICAgICAgdGhyb3cgbmV3IExlYXNlcy5MZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbihpbmZvLmdldFNlcnZlck5hbWUoKSk7CisgICAgfQorICAgIGlmIChtc2dzLmxlbmd0aCA+IDApIHsKKyAgICAgIGlmIChtc2dzWzBdLmlzVHlwZShITXNnLlR5cGUuTVNHX1JFUE9SVF9FWElUSU5HKSkgeworICAgICAgICBwcm9jZXNzUmVnaW9uU2VydmVyRXhpdChpbmZvLCBtc2dzKTsKKyAgICAgICAgcmV0dXJuIEVNUFRZX0hNU0dfQVJSQVk7CisgICAgICB9IGVsc2UgaWYgKG1zZ3NbMF0uaXNUeXBlKEhNc2cuVHlwZS5NU0dfUkVQT1JUX1FVSUVTQ0VEKSkgeworICAgICAgICBMT0cuaW5mbygiUmVnaW9uIHNlcnZlciAiICsgaW5mby5nZXRTZXJ2ZXJOYW1lKCkgKyAiIHF1aWVzY2VkIik7CisgICAgICAgIHF1aWVzY2VkU2VydmVycy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAobWFzdGVyLnNodXRkb3duUmVxdWVzdGVkLmdldCgpKSB7CisgICAgICBpZihxdWllc2NlZFNlcnZlcnMuZ2V0KCkgPj0gc2VydmVyc1RvU2VydmVySW5mby5zaXplKCkpIHsKKyAgICAgICAgLy8gSWYgdGhlIG9ubHkgc2VydmVycyB3ZSBrbm93IGFib3V0IGFyZSBtZXRhIHNlcnZlcnMsIHRoZW4gd2UgY2FuCisgICAgICAgIC8vIHByb2NlZWQgd2l0aCBzaHV0ZG93bgorICAgICAgICBMT0cuaW5mbygiQWxsIHVzZXIgdGFibGVzIHF1aWVzY2VkLiBQcm9jZWVkaW5nIHdpdGggc2h1dGRvd24iKTsKKyAgICAgICAgbWFzdGVyLnN0YXJ0U2h1dGRvd24oKTsKKyAgICAgIH0KKworICAgICAgaWYgKCFtYXN0ZXIuY2xvc2VkLmdldCgpKSB7CisgICAgICAgIGlmIChtc2dzLmxlbmd0aCA+IDAgJiYKKyAgICAgICAgICAgIG1zZ3NbMF0uaXNUeXBlKEhNc2cuVHlwZS5NU0dfUkVQT1JUX1FVSUVTQ0VEKSkgeworICAgICAgICAgIC8vIFNlcnZlciBpcyBhbHJlYWR5IHF1aWVzY2VkLCBidXQgd2UgYXJlbid0IHJlYWR5IHRvIHNodXQgZG93bgorICAgICAgICAgIC8vIHJldHVybiBlbXB0eSByZXNwb25zZQorICAgICAgICAgIHJldHVybiBFTVBUWV9ITVNHX0FSUkFZOworICAgICAgICB9CisgICAgICAgIC8vIFRlbGwgdGhlIHNlcnZlciB0byBzdG9wIHNlcnZpbmcgYW55IHVzZXIgcmVnaW9ucworICAgICAgICByZXR1cm4gbmV3IEhNc2cgW10ge1JFR0lPTlNFUlZFUl9RVUlFU0NFfTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAobWFzdGVyLmNsb3NlZC5nZXQoKSkgeworICAgICAgLy8gVGVsbCBzZXJ2ZXIgdG8gc2h1dCBkb3duIGlmIHdlIGFyZSBzaHV0dGluZyBkb3duLiAgVGhpcyBzaG91bGQKKyAgICAgIC8vIGhhcHBlbiBhZnRlciBjaGVjayBvZiBNU0dfUkVQT1JUX0VYSVRJTkcgYWJvdmUsIHNpbmNlIHJlZ2lvbiBzZXJ2ZXIKKyAgICAgIC8vIHdpbGwgc2VuZCB1cyBvbmUgb2YgdGhlc2UgbWVzc2FnZXMgYWZ0ZXIgaXQgZ2V0cyBNU0dfUkVHSU9OU0VSVkVSX1NUT1AKKyAgICAgIHJldHVybiBuZXcgSE1zZyBbXSB7UkVHSU9OU0VSVkVSX1NUT1B9OworICAgIH0KKworICAgIEhTZXJ2ZXJJbmZvIHN0b3JlZEluZm8gPSBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLmdldChpbmZvLmdldFNlcnZlck5hbWUoKSk7CisgICAgaWYgKHN0b3JlZEluZm8gPT0gbnVsbCkgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygicmVjZWl2ZWQgc2VydmVyIHJlcG9ydCBmcm9tIHVua25vd24gc2VydmVyOiAiICsKKyAgICAgICAgICAgIGluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgIH0KKworICAgICAgLy8gVGhlIEhCYXNlTWFzdGVyIG1heSBoYXZlIGJlZW4gcmVzdGFydGVkLgorICAgICAgLy8gVGVsbCB0aGUgUmVnaW9uU2VydmVyIHRvIHN0YXJ0IG92ZXIgYW5kIGNhbGwgcmVnaW9uU2VydmVyU3RhcnR1cCgpCisgICAgICByZXR1cm4gbmV3IEhNc2dbXXtDQUxMX1NFUlZFUl9TVEFSVFVQfTsKKyAgICB9IGVsc2UgaWYgKHN0b3JlZEluZm8uZ2V0U3RhcnRDb2RlKCkgIT0gaW5mby5nZXRTdGFydENvZGUoKSkgeworICAgICAgLy8gVGhpcyBzdGF0ZSBpcyByZWFjaGFibGUgaWY6CisgICAgICAvLworICAgICAgLy8gMSkgUmVnaW9uU2VydmVyIEEgc3RhcnRlZAorICAgICAgLy8gMikgUmVnaW9uU2VydmVyIEIgc3RhcnRlZCBvbiB0aGUgc2FtZSBtYWNoaW5lLCB0aGVuIAorICAgICAgLy8gICAgY2xvYmJlcmVkIEEgaW4gcmVnaW9uU2VydmVyU3RhcnR1cC4KKyAgICAgIC8vIDMpIFJlZ2lvblNlcnZlciBBIHJldHVybnMsIGV4cGVjdGluZyB0byB3b3JrIGFzIHVzdWFsLgorICAgICAgLy8KKyAgICAgIC8vIFRoZSBhbnN3ZXIgaXMgdG8gYXNrIEEgdG8gc2h1dCBkb3duIGZvciBnb29kLgorICAgICAgCisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJyZWdpb24gc2VydmVyIHJhY2UgY29uZGl0aW9uIGRldGVjdGVkOiAiICsKKyAgICAgICAgICAgIGluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgIH0KKworICAgICAgc3luY2hyb25pemVkIChzZXJ2ZXJzVG9TZXJ2ZXJJbmZvKSB7CisgICAgICAgIHJlbW92ZVNlcnZlckluZm8oaW5mby5nZXRTZXJ2ZXJOYW1lKCksIGluZm8uZ2V0U2VydmVyQWRkcmVzcygpKTsKKyAgICAgICAgc2VydmVyc1RvU2VydmVySW5mby5ub3RpZnlBbGwoKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgcmV0dXJuIG5ldyBITXNnW117UkVHSU9OU0VSVkVSX1NUT1B9OworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gcHJvY2Vzc1JlZ2lvblNlcnZlckFsbHNXZWxsKGluZm8sIG1vc3RMb2FkZWRSZWdpb25zLCBtc2dzKTsKKyAgICB9CisgIH0KKworICAvKiogUmVnaW9uIHNlcnZlciBpcyBleGl0aW5nICovCisgIHByaXZhdGUgdm9pZCBwcm9jZXNzUmVnaW9uU2VydmVyRXhpdChIU2VydmVySW5mbyBzZXJ2ZXJJbmZvLCBITXNnW10gbXNncykgeworICAgIHN5bmNocm9uaXplZCAoc2VydmVyc1RvU2VydmVySW5mbykgeworICAgICAgdHJ5IHsKKyAgICAgICAgLy8gSFJlZ2lvblNlcnZlciBpcyBzaHV0dGluZyBkb3duLiAKKyAgICAgICAgaWYgKHJlbW92ZVNlcnZlckluZm8oc2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKCksCisgICAgICAgICAgICBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKSkpIHsKKyAgICAgICAgICAvLyBPbmx5IHByb2Nlc3MgdGhlIGV4aXQgbWVzc2FnZSBpZiB0aGUgc2VydmVyIHN0aWxsIGhhcyByZWdpc3RlcmVkIGluZm8uCisgICAgICAgICAgLy8gT3RoZXJ3aXNlIHdlIGNvdWxkIGVuZCB1cCBwcm9jZXNzaW5nIHRoZSBzZXJ2ZXIgZXhpdCB0d2ljZS4KKyAgICAgICAgICBMT0cuaW5mbygiUmVnaW9uIHNlcnZlciAiICsgc2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKCkgKworICAgICAgICAgICAgIjogTVNHX1JFUE9SVF9FWElUSU5HIik7CisgICAgICAgICAgLy8gR2V0IGFsbCB0aGUgcmVnaW9ucyB0aGUgc2VydmVyIHdhcyBzZXJ2aW5nIHJlYXNzaWduZWQKKyAgICAgICAgICAvLyAoaWYgd2UgYXJlIG5vdCBzaHV0dGluZyBkb3duKS4KKyAgICAgICAgICBpZiAoIW1hc3Rlci5jbG9zZWQuZ2V0KCkpIHsKKyAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbXNncy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICBMT0cuaW5mbygiUHJvY2Vzc2luZyAiICsgbXNnc1tpXSArICIgZnJvbSAiICsKKyAgICAgICAgICAgICAgICAgIHNlcnZlckluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgICAgICAgICAgSFJlZ2lvbkluZm8gaW5mbyA9IG1zZ3NbaV0uZ2V0UmVnaW9uSW5mbygpOworICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKG1hc3Rlci5yZWdpb25NYW5hZ2VyKSB7CisgICAgICAgICAgICAgICAgaWYgKGluZm8uaXNSb290UmVnaW9uKCkpIHsKKyAgICAgICAgICAgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLnJlYXNzaWduUm9vdFJlZ2lvbigpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICBpZiAoaW5mby5pc01ldGFUYWJsZSgpKSB7CisgICAgICAgICAgICAgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLm9mZmxpbmVNZXRhUmVnaW9uKGluZm8uZ2V0U3RhcnRLZXkoKSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICBpZiAoIW1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzT2ZmbGluZWQoCisgICAgICAgICAgICAgICAgICAgICAgaW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc2V0VW5hc3NpZ25lZChpbmZvLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLnJlbW92ZVJlZ2lvbihpbmZvKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZXR1cm4gYW55dGhpbmcgdG8gdGhlIHNlcnZlciBiZWNhdXNlIGl0IGlzbid0CisgICAgICAgIC8vIGdvaW5nIHRvIGRvIGFueSBtb3JlIHdvcmsuCisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLm5vdGlmeUFsbCgpOworICAgICAgfQorICAgIH0gICAgCisgIH0KKworICAvKioKKyAgICogIFJlZ2lvblNlcnZlciBpcyBjaGVja2luZyBpbiwgbm8gZXhjZXB0aW9uYWwgY2lyY3Vtc3RhbmNlcworICAgKiBAcGFyYW0gc2VydmVySW5mbworICAgKiBAcGFyYW0gbW9zdExvYWRlZFJlZ2lvbnMKKyAgICogQHBhcmFtIG1zZ3MKKyAgICogQHJldHVybgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIEhNc2dbXSBwcm9jZXNzUmVnaW9uU2VydmVyQWxsc1dlbGwoSFNlcnZlckluZm8gc2VydmVySW5mbywgSFJlZ2lvbkluZm9bXSBtb3N0TG9hZGVkUmVnaW9ucywgSE1zZ1tdIG1zZ3MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAvLyBSZWZyZXNoIHRoZSBpbmZvIG9iamVjdCBhbmQgdGhlIGxvYWQgaW5mb3JtYXRpb24KKyAgICBzZXJ2ZXJBZGRyZXNzVG9TZXJ2ZXJJbmZvLnB1dChzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKSwgc2VydmVySW5mbyk7CisgICAgc2VydmVyc1RvU2VydmVySW5mby5wdXQoc2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKCksIHNlcnZlckluZm8pOworCisgICAgSFNlcnZlckxvYWQgbG9hZCA9IHNlcnZlcnNUb0xvYWQuZ2V0KHNlcnZlckluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICBpZiAobG9hZCAhPSBudWxsKSB7CisgICAgICB0aGlzLm1hc3Rlci5nZXRNZXRyaWNzKCkuaW5jcmVtZW50UmVxdWVzdHMobG9hZC5nZXROdW1iZXJPZlJlcXVlc3RzKCkpOworICAgICAgaWYgKCFsb2FkLmVxdWFscyhzZXJ2ZXJJbmZvLmdldExvYWQoKSkpIHsKKyAgICAgICAgLy8gV2UgaGF2ZSBwcmV2aW91cyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9hZCBvbiB0aGlzIHNlcnZlcgorICAgICAgICAvLyBhbmQgdGhlIGxvYWQgb24gdGhpcyBzZXJ2ZXIgaGFzIGNoYW5nZWQKKyAgICAgICAgc3luY2hyb25pemVkIChsb2FkVG9TZXJ2ZXJzKSB7CisgICAgICAgICAgU2V0PFN0cmluZz4gc2VydmVycyA9IGxvYWRUb1NlcnZlcnMuZ2V0KGxvYWQpOworICAgICAgICAgIC8vIE5vdGUgdGhhdCBzZXJ2ZXJzIHNob3VsZCBuZXZlciBiZSBudWxsIGJlY2F1c2UgbG9hZFRvU2VydmVycworICAgICAgICAgIC8vIGFuZCBzZXJ2ZXJzVG9Mb2FkIGFyZSBtYW5pcHVsYXRlZCBpbiBwYWlycworICAgICAgICAgIHNlcnZlcnMucmVtb3ZlKHNlcnZlckluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgICAgICBsb2FkVG9TZXJ2ZXJzLnB1dChsb2FkLCBzZXJ2ZXJzKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIC8vIFNldCB0aGUgY3VycmVudCBsb2FkIGluZm9ybWF0aW9uCisgICAgbG9hZCA9IHNlcnZlckluZm8uZ2V0TG9hZCgpOworICAgIHNlcnZlcnNUb0xvYWQucHV0KHNlcnZlckluZm8uZ2V0U2VydmVyTmFtZSgpLCBsb2FkKTsKKyAgICBzeW5jaHJvbml6ZWQgKGxvYWRUb1NlcnZlcnMpIHsKKyAgICAgIFNldDxTdHJpbmc+IHNlcnZlcnMgPSBsb2FkVG9TZXJ2ZXJzLmdldChsb2FkKTsKKyAgICAgIGlmIChzZXJ2ZXJzID09IG51bGwpIHsKKyAgICAgICAgc2VydmVycyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKyAgICAgIH0KKyAgICAgIHNlcnZlcnMuYWRkKHNlcnZlckluZm8uZ2V0U2VydmVyTmFtZSgpKTsKKyAgICAgIGxvYWRUb1NlcnZlcnMucHV0KGxvYWQsIHNlcnZlcnMpOworICAgIH0KKworICAgIC8vIE5leHQsIHByb2Nlc3MgbWVzc2FnZXMgZm9yIHRoaXMgc2VydmVyCisgICAgcmV0dXJuIHByb2Nlc3NNc2dzKHNlcnZlckluZm8sIG1vc3RMb2FkZWRSZWdpb25zLCBtc2dzKTsKKyAgfQorCisgIC8qKiAKKyAgICogUHJvY2VzcyBhbGwgdGhlIGluY29taW5nIG1lc3NhZ2VzIGZyb20gYSBzZXJ2ZXIgdGhhdCdzIGNvbnRhY3RlZCB1cy4KKyAgICogCisgICAqIE5vdGUgdGhhdCB3ZSBuZXZlciBuZWVkIHRvIHVwZGF0ZSB0aGUgc2VydmVyJ3MgbG9hZCBpbmZvcm1hdGlvbiBiZWNhdXNlCisgICAqIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBkb25lIGluIHJlZ2lvblNlcnZlclJlcG9ydC4KKyAgICovCisgIHByaXZhdGUgSE1zZ1tdIHByb2Nlc3NNc2dzKEhTZXJ2ZXJJbmZvIHNlcnZlckluZm8sCisgICAgICBIUmVnaW9uSW5mb1tdIG1vc3RMb2FkZWRSZWdpb25zLCBITXNnIGluY29taW5nTXNnc1tdKQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAKKyAgICBBcnJheUxpc3Q8SE1zZz4gcmV0dXJuTXNncyA9IG5ldyBBcnJheUxpc3Q8SE1zZz4oKTsKKyAgICBpZiAoc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJTZXJ2ZXIgYWRkcmVzcyBjYW5ub3QgYmUgbnVsbDsgIiArCisgICAgICAgICJoYmFzZS05NTggZGVidWdnaW5nIik7CisgICAgfQorICAgIC8vIEdldCByZXBvcnRzIG9uIHdoYXQgdGhlIFJlZ2lvblNlcnZlciBkaWQuCisgICAgaW50IG9wZW5pbmdDb3VudCA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbmNvbWluZ01zZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgIEhSZWdpb25JbmZvIHJlZ2lvbiA9IGluY29taW5nTXNnc1tpXS5nZXRSZWdpb25JbmZvKCk7CisgICAgICBMT0cuaW5mbygiUmVjZWl2ZWQgIiArIGluY29taW5nTXNnc1tpXSArICIgZnJvbSAiICsKKyAgICAgICAgICBzZXJ2ZXJJbmZvLmdldFNlcnZlck5hbWUoKSk7CisgICAgICBzd2l0Y2ggKGluY29taW5nTXNnc1tpXS5nZXRUeXBlKCkpIHsKKyAgICAgICAgY2FzZSBNU0dfUkVQT1JUX1BST0NFU1NfT1BFTjoKKyAgICAgICAgICBvcGVuaW5nQ291bnQrKzsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgCisgICAgICAgIGNhc2UgTVNHX1JFUE9SVF9PUEVOOgorICAgICAgICAgIHByb2Nlc3NSZWdpb25PcGVuKHNlcnZlckluZm8sIHJlZ2lvbiwgcmV0dXJuTXNncyk7CisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBNU0dfUkVQT1JUX0NMT1NFOgorICAgICAgICAgIHByb2Nlc3NSZWdpb25DbG9zZShyZWdpb24pOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgTVNHX1JFUE9SVF9TUExJVDoKKyAgICAgICAgICBwcm9jZXNzU3BsaXRSZWdpb24ocmVnaW9uLCBpbmNvbWluZ01zZ3NbKytpXSwgaW5jb21pbmdNc2dzWysraV0sCisgICAgICAgICAgICAgIHJldHVybk1zZ3MpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorICAgICAgICAgICAgIkltcG9zc2libGUgc3RhdGUgZHVyaW5nIG1lc3NhZ2UgcHJvY2Vzc2luZy4gSW5zdHJ1Y3Rpb246ICIgKworICAgICAgICAgICAgaW5jb21pbmdNc2dzW2ldLmdldFR5cGUoKSk7CisgICAgICB9CisgICAgfQorCisgICAgc3luY2hyb25pemVkIChtYXN0ZXIucmVnaW9uTWFuYWdlcikgeworICAgICAgLy8gVGVsbCB0aGUgcmVnaW9uIHNlcnZlciB0byBjbG9zZSByZWdpb25zIHRoYXQgd2UgaGF2ZSBtYXJrZWQgZm9yIGNsb3NpbmcuCisgICAgICBmb3IgKEhSZWdpb25JbmZvIGk6CisgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLmdldE1hcmtlZFRvQ2xvc2Uoc2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKCkpKSB7CisgICAgICAgIHJldHVybk1zZ3MuYWRkKG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVHSU9OX0NMT1NFLCBpKSk7CisgICAgICAgIC8vIFRyYW5zaXRpb24gdGhlIHJlZ2lvbiBmcm9tIHRvQ2xvc2UgdG8gY2xvc2luZyBzdGF0ZQorICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRQZW5kaW5nQ2xvc2UoaS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICB9CisKKyAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCB0aGUgUmVnaW9uU2VydmVyIG91Z2h0IHRvIGRvLCBhbmQgd3JpdGUgYmFjay4KKyAgICAgIAorICAgICAgLy8gU2hvdWxkIHdlIHRlbGwgaXQgY2xvc2UgcmVnaW9ucyBiZWNhdXNlIGl0cyBvdmVybG9hZGVkPyAgSWYgaXRzCisgICAgICAvLyBjdXJyZW50bHkgb3BlbmluZyByZWdpb25zLCBsZWF2ZSBpdCBhbG9uZSB0aWxsIGFsbCBhcmUgb3Blbi4KKyAgICAgIGlmIChvcGVuaW5nQ291bnQgPCB0aGlzLm5vYmFsYW5jaW5nQ291bnQpIHsKKyAgICAgICAgdGhpcy5tYXN0ZXIucmVnaW9uTWFuYWdlci5hc3NpZ25SZWdpb25zKHNlcnZlckluZm8sIG1vc3RMb2FkZWRSZWdpb25zLAorICAgICAgICAgICAgcmV0dXJuTXNncyk7CisgICAgICB9CisgICAgICAvLyBTZW5kIGFueSBwZW5kaW5nIHRhYmxlIGFjdGlvbnMuCisgICAgICB0aGlzLm1hc3Rlci5yZWdpb25NYW5hZ2VyLmFwcGx5QWN0aW9ucyhzZXJ2ZXJJbmZvLCByZXR1cm5Nc2dzKTsKKyAgICB9CisgICAgcmV0dXJuIHJldHVybk1zZ3MudG9BcnJheShuZXcgSE1zZ1tyZXR1cm5Nc2dzLnNpemUoKV0pOworICB9CisgIAorICAvKioKKyAgICogQSByZWdpb24gaGFzIHNwbGl0LgorICAgKgorICAgKiBAcGFyYW0gcmVnaW9uCisgICAqIEBwYXJhbSBzcGxpdEEKKyAgICogQHBhcmFtIHNwbGl0QgorICAgKiBAcGFyYW0gcmV0dXJuTXNncworICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHByb2Nlc3NTcGxpdFJlZ2lvbihIUmVnaW9uSW5mbyByZWdpb24sIEhNc2cgc3BsaXRBLCBITXNnIHNwbGl0QiwKKyAgICAgIEFycmF5TGlzdDxITXNnPiByZXR1cm5Nc2dzKSB7CisKKyAgICBzeW5jaHJvbml6ZWQgKG1hc3Rlci5yZWdpb25NYW5hZ2VyKSB7CisgICAgICAvLyBDYW5jZWwgYW55IGFjdGlvbnMgcGVuZGluZyBmb3IgdGhlIGFmZmVjdGVkIHJlZ2lvbi4KKyAgICAgIC8vIFRoaXMgcHJldmVudHMgdGhlIG1hc3RlciBmcm9tIHNlbmRpbmcgYSBTUExJVCBtZXNzYWdlIGlmIHRoZSB0YWJsZQorICAgICAgLy8gaGFzIGFscmVhZHkgc3BsaXQgYnkgdGhlIHJlZ2lvbiBzZXJ2ZXIuIAorICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuZW5kQWN0aW9ucyhyZWdpb24uZ2V0UmVnaW9uTmFtZSgpKTsKKworICAgICAgSFJlZ2lvbkluZm8gbmV3UmVnaW9uQSA9IHNwbGl0QS5nZXRSZWdpb25JbmZvKCk7CisgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRVbmFzc2lnbmVkKG5ld1JlZ2lvbkEsIGZhbHNlKTsKKworICAgICAgSFJlZ2lvbkluZm8gbmV3UmVnaW9uQiA9IHNwbGl0Qi5nZXRSZWdpb25JbmZvKCk7CisgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRVbmFzc2lnbmVkKG5ld1JlZ2lvbkIsIGZhbHNlKTsKKworICAgICAgaWYgKHJlZ2lvbi5pc01ldGFUYWJsZSgpKSB7CisgICAgICAgIC8vIEEgbWV0YSByZWdpb24gaGFzIHNwbGl0LgorICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5vZmZsaW5lTWV0YVJlZ2lvbihyZWdpb24uZ2V0U3RhcnRLZXkoKSk7CisgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLmluY3JlbWVudE51bU1ldGFSZWdpb25zKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIFJlZ2lvbiBzZXJ2ZXIgaXMgcmVwb3J0aW5nIHRoYXQgYSByZWdpb24gaXMgbm93IG9wZW5lZCAqLworICBwcml2YXRlIHZvaWQgcHJvY2Vzc1JlZ2lvbk9wZW4oSFNlcnZlckluZm8gc2VydmVySW5mbywgCisgICAgSFJlZ2lvbkluZm8gcmVnaW9uLCBBcnJheUxpc3Q8SE1zZz4gcmV0dXJuTXNncykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiBkdXBsaWNhdGVBc3NpZ25tZW50ID0gZmFsc2U7CisgICAgc3luY2hyb25pemVkIChtYXN0ZXIucmVnaW9uTWFuYWdlcikgeworICAgICAgaWYgKCFtYXN0ZXIucmVnaW9uTWFuYWdlci5pc1VuYXNzaWduZWQocmVnaW9uKSAmJgorICAgICAgICAgICFtYXN0ZXIucmVnaW9uTWFuYWdlci5pc1BlbmRpbmdPcGVuKHJlZ2lvbi5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSkpIHsKKyAgICAgICAgaWYgKHJlZ2lvbi5pc1Jvb3RSZWdpb24oKSkgeworICAgICAgICAgIC8vIFJvb3QgcmVnaW9uCisgICAgICAgICAgSFNlcnZlckFkZHJlc3Mgcm9vdFNlcnZlciA9IG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICAgICAgICBpZiAocm9vdFNlcnZlciAhPSBudWxsKSB7CisgICAgICAgICAgICBpZiAocm9vdFNlcnZlci5jb21wYXJlVG8oc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkpID09IDApIHsKKyAgICAgICAgICAgICAgLy8gQSBkdXBsaWNhdGUgb3BlbiByZXBvcnQgZnJvbSB0aGUgY29ycmVjdCBzZXJ2ZXIKKyAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gV2UgcmVjZWl2ZWQgYW4gb3BlbiByZXBvcnQgb24gdGhlIHJvb3QgcmVnaW9uLCBidXQgaXQgaXMKKyAgICAgICAgICAgIC8vIGFzc2lnbmVkIHRvIGEgZGlmZmVyZW50IHNlcnZlcgorICAgICAgICAgICAgZHVwbGljYXRlQXNzaWdubWVudCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIE5vdCByb290IHJlZ2lvbi4gSWYgaXQgaXMgbm90IGEgcGVuZGluZyByZWdpb24sIHRoZW4gd2UgYXJlCisgICAgICAgICAgLy8gZ29pbmcgdG8gdHJlYXQgaXQgYXMgYSBkdXBsaWNhdGUgYXNzaWdubWVudCwgYWx0aG91Z2ggd2UgY2FuJ3QgCisgICAgICAgICAgLy8gdGVsbCBmb3IgY2VydGFpbiB0aGF0J3MgdGhlIGNhc2UuCisgICAgICAgICAgaWYgKG1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzUGVuZGluZ09wZW4oCisgICAgICAgICAgICAgIHJlZ2lvbi5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSkpIHsKKyAgICAgICAgICAgIC8vIEEgZHVwbGljYXRlIHJlcG9ydCBmcm9tIHRoZSBjb3JyZWN0IHNlcnZlcgorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgIH0KKyAgICAgICAgICBkdXBsaWNhdGVBc3NpZ25tZW50ID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIAorICAgICAgaWYgKGR1cGxpY2F0ZUFzc2lnbm1lbnQpIHsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJyZWdpb24gc2VydmVyICIgKyBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKS50b1N0cmluZygpCisgICAgICAgICAgICAgICsgIiBzaG91bGQgbm90IGhhdmUgb3BlbmVkIHJlZ2lvbiAiICsgQnl0ZXMudG9TdHJpbmcocmVnaW9uLmdldFJlZ2lvbk5hbWUoKSkpOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhpcyBSZWdpb24gc2hvdWxkIG5vdCBoYXZlIGJlZW4gb3BlbmVkLgorICAgICAgICAvLyBBc2sgdGhlIHNlcnZlciB0byBzaHV0IGl0IGRvd24sIGJ1dCBkb24ndCByZXBvcnQgaXQgYXMgY2xvc2VkLiAgCisgICAgICAgIC8vIE90aGVyd2lzZSB0aGUgSE1hc3RlciB3aWxsIHRoaW5rIHRoZSBSZWdpb24gd2FzIGNsb3NlZCBvbiBwdXJwb3NlLCAKKyAgICAgICAgLy8gYW5kIHRoZW4gdHJ5IHRvIHJlb3BlbiBpdCBlbHNld2hlcmU7IHRoYXQncyBub3Qgd2hhdCB3ZSB3YW50LgorICAgICAgICByZXR1cm5Nc2dzLmFkZChuZXcgSE1zZyhITXNnLlR5cGUuTVNHX1JFR0lPTl9DTE9TRV9XSVRIT1VUX1JFUE9SVCwKKyAgICAgICAgICAgIHJlZ2lvbiwgIkR1cGxpY2F0ZSBhc3NpZ25tZW50Ii5nZXRCeXRlcygpKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAocmVnaW9uLmlzUm9vdFJlZ2lvbigpKSB7CisgICAgICAgICAgLy8gaXQgd2FzIGFzc2lnbmVkLCBhbmQgaXQncyBub3QgYSBkdXBsaWNhdGUgYXNzaWdubWVudCwgc28gdGFrZSBpdCBvdXQgCisgICAgICAgICAgLy8gb2YgdGhlIHVuYXNzaWduZWQgbGlzdC4KKyAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5yZW1vdmVSZWdpb24ocmVnaW9uKTsKKworICAgICAgICAgIC8vIFN0b3JlIHRoZSBSb290IFJlZ2lvbiBsb2NhdGlvbiAoaW4gbWVtb3J5KQorICAgICAgICAgIEhTZXJ2ZXJBZGRyZXNzIHJvb3RTZXJ2ZXIgPSBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKTsKKyAgICAgICAgICBpZiAobWFzdGVyLnJlZ2lvbk1hbmFnZXIuaW5TYWZlTW9kZSgpKSB7CisgICAgICAgICAgICBtYXN0ZXIuY29ubmVjdGlvbi5zZXRSb290UmVnaW9uTG9jYXRpb24oCisgICAgICAgICAgICAgICAgbmV3IEhSZWdpb25Mb2NhdGlvbihyZWdpb24sIHJvb3RTZXJ2ZXIpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc2V0Um9vdFJlZ2lvbkxvY2F0aW9uKHJvb3RTZXJ2ZXIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGUgdGFibGUgaGFzIGJlZW4gYXNzaWduZWQgYW5kIGlzIHdhaXRpbmcgZm9yIHRoZQorICAgICAgICAgIC8vIG1ldGEgdGFibGUgdG8gYmUgdXBkYXRlZC4KKyAgICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5zZXRPcGVuKHJlZ2lvbi5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICAgICAgLy8gUXVldWUgdXAgYW4gdXBkYXRlIHRvIG5vdGUgdGhlIHJlZ2lvbiBsb2NhdGlvbi4KKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgbWFzdGVyLnRvRG9RdWV1ZS5wdXQoCisgICAgICAgICAgICAgICAgbmV3IFByb2Nlc3NSZWdpb25PcGVuKG1hc3Rlciwgc2VydmVySW5mbywgcmVnaW9uKSk7CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgIlB1dHRpbmcgaW50byB0b0RvUXVldWUgd2FzIGludGVycnVwdGVkLiIsIGUpOworICAgICAgICAgIH0KKyAgICAgICAgfSAKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBwcm9jZXNzUmVnaW9uQ2xvc2UoSFJlZ2lvbkluZm8gcmVnaW9uKSB7CisgICAgc3luY2hyb25pemVkIChtYXN0ZXIucmVnaW9uTWFuYWdlcikgeworICAgICAgaWYgKHJlZ2lvbi5pc1Jvb3RSZWdpb24oKSkgeworICAgICAgICAvLyBSb290IHJlZ2lvbgorICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci51bnNldFJvb3RSZWdpb24oKTsKKyAgICAgICAgaWYgKHJlZ2lvbi5pc09mZmxpbmUoKSkgeworICAgICAgICAgIC8vIENhbid0IHByb2NlZWQgd2l0aG91dCByb290IHJlZ2lvbi4gU2h1dGRvd24uCisgICAgICAgICAgTE9HLmZhdGFsKCJyb290IHJlZ2lvbiBpcyBtYXJrZWQgb2ZmbGluZSIpOworICAgICAgICAgIG1hc3Rlci5zaHV0ZG93bigpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICB9IGVsc2UgaWYgKHJlZ2lvbi5pc01ldGFUYWJsZSgpKSB7CisgICAgICAgIC8vIFJlZ2lvbiBpcyBwYXJ0IG9mIHRoZSBtZXRhIHRhYmxlLiBSZW1vdmUgaXQgZnJvbSBvbmxpbmVNZXRhUmVnaW9ucworICAgICAgICBtYXN0ZXIucmVnaW9uTWFuYWdlci5vZmZsaW5lTWV0YVJlZ2lvbihyZWdpb24uZ2V0U3RhcnRLZXkoKSk7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gb2ZmbGluZVJlZ2lvbiA9CisgICAgICAgIG1hc3Rlci5yZWdpb25NYW5hZ2VyLmlzT2ZmbGluZWQocmVnaW9uLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgIGJvb2xlYW4gcmVhc3NpZ25SZWdpb24gPSAhcmVnaW9uLmlzT2ZmbGluZSgpICYmICFvZmZsaW5lUmVnaW9uOworCisgICAgICAvLyBOT1RFOiBJZiB0aGUgcmVnaW9uIHdhcyBqdXN0IGJlaW5nIGNsb3NlZCBhbmQgbm90IG9mZmxpbmVkLCB3ZSBjYW5ub3QKKyAgICAgIC8vICAgICAgIG1hcmsgdGhlIHJlZ2lvbiB1bmFzc2lnbmVkUmVnaW9ucyBhcyB0aGF0IGNoYW5nZXMgdGhlIG9yZGVyaW5nIG9mCisgICAgICAvLyAgICAgICB0aGUgbWVzc2FnZXMgd2UndmUgcmVjZWl2ZWQuIEluIHRoaXMgY2FzZSwgYSBjbG9zZSBjb3VsZCBiZQorICAgICAgLy8gICAgICAgcHJvY2Vzc2VkIGJlZm9yZSBhbiBvcGVuIHJlc3VsdGluZyBpbiB0aGUgbWFzdGVyIG5vdCBhZ3JlZWluZyBvbgorICAgICAgLy8gICAgICAgdGhlIHJlZ2lvbidzIHN0YXRlLgorICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIuc2V0Q2xvc2VkKHJlZ2lvbi5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICB0cnkgeworICAgICAgICBtYXN0ZXIudG9Eb1F1ZXVlLnB1dChuZXcgUHJvY2Vzc1JlZ2lvbkNsb3NlKG1hc3RlciwgcmVnaW9uLAorICAgICAgICAgICAgb2ZmbGluZVJlZ2lvbiwgcmVhc3NpZ25SZWdpb24pKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlB1dHRpbmcgaW50byB0b0RvUXVldWUgd2FzIGludGVycnVwdGVkLiIsIGUpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqIFVwZGF0ZSBhIHNlcnZlciBsb2FkIGluZm9ybWF0aW9uIGJlY2F1c2UgaXQncyBzaHV0dGluZyBkb3duKi8KKyAgcHJpdmF0ZSBib29sZWFuIHJlbW92ZVNlcnZlckluZm8oZmluYWwgU3RyaW5nIHNlcnZlck5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlckFkZHJlc3MpIHsKKyAgICBib29sZWFuIGluZm9VcGRhdGVkID0gZmFsc2U7CisgICAgc2VydmVyQWRkcmVzc1RvU2VydmVySW5mby5yZW1vdmUoc2VydmVyQWRkcmVzcyk7CisgICAgSFNlcnZlckluZm8gaW5mbyA9IHNlcnZlcnNUb1NlcnZlckluZm8ucmVtb3ZlKHNlcnZlck5hbWUpOworICAgIC8vIE9ubHkgdXBkYXRlIGxvYWQgaW5mb3JtYXRpb24gb25jZS4KKyAgICAvLyBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGEgY291cGxlIG9mIHRpbWVzIGR1cmluZyBzaHV0ZG93bi4KKyAgICBpZiAoaW5mbyAhPSBudWxsKSB7CisgICAgICBMT0cuaW5mbygiUmVtb3Zpbmcgc2VydmVyJ3MgaW5mbyAiICsgc2VydmVyTmFtZSk7CisgICAgICBpZiAobWFzdGVyLmdldFJvb3RSZWdpb25Mb2NhdGlvbigpICE9IG51bGwgJiYKKyAgICAgICAgaW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkuZXF1YWxzKG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKSkpIHsKKyAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIudW5zZXRSb290UmVnaW9uKCk7CisgICAgICB9CisgICAgICBpbmZvVXBkYXRlZCA9IHRydWU7CisKKyAgICAgIC8vIHVwZGF0ZSBsb2FkIGluZm9ybWF0aW9uCisgICAgICBIU2VydmVyTG9hZCBsb2FkID0gc2VydmVyc1RvTG9hZC5yZW1vdmUoc2VydmVyTmFtZSk7CisgICAgICBpZiAobG9hZCAhPSBudWxsKSB7CisgICAgICAgIHN5bmNocm9uaXplZCAobG9hZFRvU2VydmVycykgeworICAgICAgICAgIFNldDxTdHJpbmc+IHNlcnZlcnMgPSBsb2FkVG9TZXJ2ZXJzLmdldChsb2FkKTsKKyAgICAgICAgICBpZiAoc2VydmVycyAhPSBudWxsKSB7CisgICAgICAgICAgICBzZXJ2ZXJzLnJlbW92ZShzZXJ2ZXJOYW1lKTsKKyAgICAgICAgICAgIGxvYWRUb1NlcnZlcnMucHV0KGxvYWQsIHNlcnZlcnMpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gaW5mb1VwZGF0ZWQ7CisgIH0KKyAgCisgIC8qKiAKKyAgICogQ29tcHV0ZSB0aGUgYXZlcmFnZSBsb2FkIGFjcm9zcyBhbGwgcmVnaW9uIHNlcnZlcnMuIAorICAgKiBDdXJyZW50bHksIHRoaXMgdXNlcyBhIHZlcnkgbmFpdmUgY29tcHV0YXRpb24gLSBqdXN0IHVzZXMgdGhlIG51bWJlciBvZiAKKyAgICogcmVnaW9ucyBiZWluZyBzZXJ2ZWQsIGlnbm9yaW5nIHN0YXRzIGFib3V0IG51bWJlciBvZiByZXF1ZXN0cy4KKyAgICogQHJldHVybiB0aGUgYXZlcmFnZSBsb2FkCisgICAqLworICBwdWJsaWMgZG91YmxlIGdldEF2ZXJhZ2VMb2FkKCkgeworICAgIGludCB0b3RhbExvYWQgPSAwOworICAgIGludCBudW1TZXJ2ZXJzID0gMDsKKyAgICBkb3VibGUgYXZlcmFnZUxvYWQgPSAwLjA7CisgICAgc3luY2hyb25pemVkIChzZXJ2ZXJzVG9Mb2FkKSB7CisgICAgICBudW1TZXJ2ZXJzID0gc2VydmVyc1RvTG9hZC5zaXplKCk7CisgICAgICBmb3IgKEhTZXJ2ZXJMb2FkIGxvYWQgOiBzZXJ2ZXJzVG9Mb2FkLnZhbHVlcygpKSB7CisgICAgICAgIHRvdGFsTG9hZCArPSBsb2FkLmdldE51bWJlck9mUmVnaW9ucygpOworICAgICAgfQorICAgICAgYXZlcmFnZUxvYWQgPSBNYXRoLmNlaWwoKGRvdWJsZSl0b3RhbExvYWQgLyAoZG91YmxlKW51bVNlcnZlcnMpOworICAgIH0KKyAgICByZXR1cm4gYXZlcmFnZUxvYWQ7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBzZXJ2ZXJzICovCisgIHB1YmxpYyBpbnQgbnVtU2VydmVycygpIHsKKyAgICByZXR1cm4gc2VydmVyc1RvU2VydmVySW5mby5zaXplKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gbmFtZSBzZXJ2ZXIgbmFtZQorICAgKiBAcmV0dXJuIEhTZXJ2ZXJJbmZvIGZvciB0aGUgZ2l2ZW4gc2VydmVyIGFkZHJlc3MKKyAgICovCisgIHB1YmxpYyBIU2VydmVySW5mbyBnZXRTZXJ2ZXJJbmZvKFN0cmluZyBuYW1lKSB7CisgICAgcmV0dXJuIHNlcnZlcnNUb1NlcnZlckluZm8uZ2V0KG5hbWUpOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiBSZWFkLW9ubHkgbWFwIG9mIHNlcnZlcnMgdG8gc2VydmVyaW5mby4KKyAgICovCisgIHB1YmxpYyBNYXA8U3RyaW5nLCBIU2VydmVySW5mbz4gZ2V0U2VydmVyc1RvU2VydmVySW5mbygpIHsKKyAgICBzeW5jaHJvbml6ZWQgKHNlcnZlcnNUb1NlcnZlckluZm8pIHsKKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoc2VydmVyc1RvU2VydmVySW5mbyk7CisgICAgfQorICB9CisKKyAgcHVibGljIE1hcDxIU2VydmVyQWRkcmVzcywgSFNlcnZlckluZm8+IGdldFNlcnZlckFkZHJlc3NUb1NlcnZlckluZm8oKSB7CisgICAgLy8gd2UgdXNlIHRoaXMgb25lIGJlY2F1c2UgYWxsIHRoZSBwdXRzIHRvIHRoaXMgbWFwIGFyZSBwYXJhbGxlbC9zeW5jZWQgd2l0aCB0aGUgb3RoZXIgbWFwLgorICAgIHN5bmNocm9uaXplZCAoc2VydmVyc1RvU2VydmVySW5mbykgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChzZXJ2ZXJBZGRyZXNzVG9TZXJ2ZXJJbmZvKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBSZWFkLW9ubHkgbWFwIG9mIHNlcnZlcnMgdG8gbG9hZC4KKyAgICovCisgIHB1YmxpYyBNYXA8U3RyaW5nLCBIU2VydmVyTG9hZD4gZ2V0U2VydmVyc1RvTG9hZCgpIHsKKyAgICBzeW5jaHJvbml6ZWQgKHNlcnZlcnNUb0xvYWQpIHsKKyAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAoc2VydmVyc1RvTG9hZCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFdha2VzIHVwIHRocmVhZHMgd2FpdGluZyBvbiBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvCisgICAqLworICBwdWJsaWMgdm9pZCBub3RpZnlTZXJ2ZXJzKCkgeworICAgIHN5bmNocm9uaXplZCAoc2VydmVyc1RvU2VydmVySW5mbykgeworICAgICAgc2VydmVyc1RvU2VydmVySW5mby5ub3RpZnlBbGwoKTsKKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIFdhaXQgb24gcmVnaW9uc2VydmVycyB0byByZXBvcnQgaW4KKyAgICogd2l0aCB7QGxpbmsgI3JlZ2lvblNlcnZlclJlcG9ydChIU2VydmVySW5mbywgSE1zZ1tdKX0gc28gdGhleSBnZXQgbm90aWNlCisgICAqIHRoZSBtYXN0ZXIgaXMgZ29pbmcgZG93bi4gIFdhaXRzIHVudGlsIGFsbCByZWdpb24gc2VydmVycyBjb21lIGJhY2sgd2l0aAorICAgKiBhIE1TR19SRUdJT05TRVJWRVJfU1RPUC4KKyAgICovCisgIHZvaWQgbGV0UmVnaW9uU2VydmVyc1NodXRkb3duKCkgeworICAgIGlmICghbWFzdGVyLmZzT2spIHsKKyAgICAgIC8vIEZvcmdldCB3YWl0aW5nIGZvciB0aGUgcmVnaW9uIHNlcnZlcnMgaWYgdGhlIGZpbGUgc3lzdGVtIGhhcyBnb25lCisgICAgICAvLyBhd2F5LiBKdXN0IGV4aXQgYXMgcXVpY2tseSBhcyBwb3NzaWJsZS4KKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgc3luY2hyb25pemVkIChzZXJ2ZXJzVG9TZXJ2ZXJJbmZvKSB7CisgICAgICB3aGlsZSAoc2VydmVyc1RvU2VydmVySW5mby5zaXplKCkgPiAwKSB7CisgICAgICAgIExPRy5pbmZvKCJXYWl0aW5nIG9uIGZvbGxvd2luZyByZWdpb25zZXJ2ZXIocykgdG8gZ28gZG93biAiICsKKyAgICAgICAgICBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLnZhbHVlcygpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLndhaXQobWFzdGVyLnRocmVhZFdha2VGcmVxdWVuY3kpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqIFdhdGNoZXIgdHJpZ2dlcmVkIHdoZW4gYSBSUyB6bm9kZSBpcyBkZWxldGVkICovCisgIHByaXZhdGUgY2xhc3MgU2VydmVyRXhwaXJlciBpbXBsZW1lbnRzIFdhdGNoZXIgeworICAgIHByaXZhdGUgU3RyaW5nIHNlcnZlcjsKKyAgICBwcml2YXRlIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlckFkZHJlc3M7CisKKyAgICBTZXJ2ZXJFeHBpcmVyKFN0cmluZyBzZXJ2ZXIsIEhTZXJ2ZXJBZGRyZXNzIHNlcnZlckFkZHJlc3MpIHsKKyAgICAgIHRoaXMuc2VydmVyID0gc2VydmVyOworICAgICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gc2VydmVyQWRkcmVzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKFdhdGNoZWRFdmVudCBldmVudCkgeworICAgICAgaWYoZXZlbnQuZ2V0VHlwZSgpLmVxdWFscyhFdmVudFR5cGUuTm9kZURlbGV0ZWQpKSB7CisgICAgICAgIExPRy5pbmZvKHNlcnZlciArICIgem5vZGUgZXhwaXJlZCIpOworICAgICAgICAvLyBSZW1vdmUgdGhlIHNlcnZlciBmcm9tIHRoZSBrbm93biBzZXJ2ZXJzIGxpc3QgYW5kIHVwZGF0ZSBsb2FkIGluZm8KKyAgICAgICAgc2VydmVyQWRkcmVzc1RvU2VydmVySW5mby5yZW1vdmUoc2VydmVyQWRkcmVzcyk7CisgICAgICAgIEhTZXJ2ZXJJbmZvIGluZm8gPSBzZXJ2ZXJzVG9TZXJ2ZXJJbmZvLnJlbW92ZShzZXJ2ZXIpOworICAgICAgICBib29sZWFuIHJvb3RTZXJ2ZXIgPSBmYWxzZTsKKyAgICAgICAgaWYgKGluZm8gIT0gbnVsbCkgeworICAgICAgICAgIEhTZXJ2ZXJBZGRyZXNzIHJvb3QgPSBtYXN0ZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCk7CisgICAgICAgICAgaWYgKHJvb3QgIT0gbnVsbCAmJiByb290LmVxdWFscyhpbmZvLmdldFNlcnZlckFkZHJlc3MoKSkpIHsKKyAgICAgICAgICAgIC8vIE5PVEU6IElmIHRoZSBzZXJ2ZXIgd2FzIHNlcnZpbmcgdGhlIHJvb3QgcmVnaW9uLCB3ZSBjYW5ub3QKKyAgICAgICAgICAgIC8vIHJlYXNzaWduCisgICAgICAgICAgICAvLyBpdCBoZXJlIGJlY2F1c2UgdGhlIG5ldyBzZXJ2ZXIgd2lsbCBzdGFydCBzZXJ2aW5nIHRoZSByb290IHJlZ2lvbgorICAgICAgICAgICAgLy8gYmVmb3JlIFByb2Nlc3NTZXJ2ZXJTaHV0ZG93biBoYXMgYSBjaGFuY2UgdG8gc3BsaXQgdGhlIGxvZyBmaWxlLgorICAgICAgICAgICAgbWFzdGVyLnJlZ2lvbk1hbmFnZXIudW5zZXRSb290UmVnaW9uKCk7CisgICAgICAgICAgICByb290U2VydmVyID0gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgICAgU3RyaW5nIHNlcnZlck5hbWUgPSBIU2VydmVySW5mby5nZXRTZXJ2ZXJOYW1lKGluZm8pOworICAgICAgICAgIEhTZXJ2ZXJMb2FkIGxvYWQgPSBzZXJ2ZXJzVG9Mb2FkLnJlbW92ZShzZXJ2ZXJOYW1lKTsKKyAgICAgICAgICBpZiAobG9hZCAhPSBudWxsKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvYWRUb1NlcnZlcnMpIHsKKyAgICAgICAgICAgICAgU2V0PFN0cmluZz4gc2VydmVycyA9IGxvYWRUb1NlcnZlcnMuZ2V0KGxvYWQpOworICAgICAgICAgICAgICBpZiAoc2VydmVycyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgc2VydmVycy5yZW1vdmUoc2VydmVyTmFtZSk7CisgICAgICAgICAgICAgICAgbG9hZFRvU2VydmVycy5wdXQobG9hZCwgc2VydmVycyk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZGVhZFNlcnZlcnMuYWRkKHNlcnZlcik7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG1hc3Rlci50b0RvUXVldWUucHV0KG5ldyBQcm9jZXNzU2VydmVyU2h1dGRvd24obWFzdGVyLCBpbmZvLAorICAgICAgICAgICAgICAgIHJvb3RTZXJ2ZXIpKTsKKyAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBMT0cuZXJyb3IoImluc2VydCBpbnRvIHRvRG9RdWV1ZSB3YXMgaW50ZXJydXB0ZWQiLCBlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc3luY2hyb25pemVkIChzZXJ2ZXJzVG9TZXJ2ZXJJbmZvKSB7CisgICAgICAgICAgc2VydmVyc1RvU2VydmVySW5mby5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBzZXJ2ZXJOYW1lCisgICAqLworICBwdWJsaWMgdm9pZCByZW1vdmVEZWFkU2VydmVyKFN0cmluZyBzZXJ2ZXJOYW1lKSB7CisgICAgZGVhZFNlcnZlcnMucmVtb3ZlKHNlcnZlck5hbWUpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHNlcnZlck5hbWUKKyAgICogQHJldHVybiB0cnVlIGlmIHNlcnZlciBpcyBkZWFkCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc0RlYWQoU3RyaW5nIHNlcnZlck5hbWUpIHsKKyAgICByZXR1cm4gZGVhZFNlcnZlcnMuY29udGFpbnMoc2VydmVyTmFtZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9UYWJsZURlbGV0ZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1RhYmxlRGVsZXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTI2ZmUzMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9UYWJsZURlbGV0ZS5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlRhYmxlTm90RGlzYWJsZWRFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIAorICogSW5zdGFudGlhdGVkIHRvIGRlbGV0ZSBhIHRhYmxlLiBUYWJsZSBtdXN0IGJlIG9mZmxpbmUuCisgKi8KK2NsYXNzIFRhYmxlRGVsZXRlIGV4dGVuZHMgVGFibGVPcGVyYXRpb24geworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkpOworCisgIFRhYmxlRGVsZXRlKGZpbmFsIEhNYXN0ZXIgbWFzdGVyLCBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcihtYXN0ZXIsIHRhYmxlTmFtZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1NjYW5JdGVtKFN0cmluZyBzZXJ2ZXJOYW1lLAorICAgICAgZmluYWwgSFJlZ2lvbkluZm8gaW5mbykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoaXNFbmFibGVkKGluZm8pKSB7CisgICAgICB0aHJvdyBuZXcgVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbih0YWJsZU5hbWUpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBwb3N0UHJvY2Vzc01ldGEoTWV0YVJlZ2lvbiBtLCBIUmVnaW9uSW50ZXJmYWNlIHNlcnZlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKEhSZWdpb25JbmZvIGk6IHVuc2VydmVkUmVnaW9ucykgeworICAgICAgaWYgKCFCeXRlcy5lcXVhbHModGhpcy50YWJsZU5hbWUsIGkuZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpKSkgeworICAgICAgICAvLyBEb24ndCBkZWxldGUgcmVnaW9ucyB0aGF0IGFyZSBub3QgZnJvbSBvdXIgdGFibGUuCisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgLy8gRGVsZXRlIHRoZSByZWdpb24KKyAgICAgIHRyeSB7CisgICAgICAgIEhSZWdpb24ucmVtb3ZlUmVnaW9uRnJvbU1FVEEoc2VydmVyLCBtLmdldFJlZ2lvbk5hbWUoKSwgaS5nZXRSZWdpb25OYW1lKCkpOworICAgICAgICBIUmVnaW9uLmRlbGV0ZVJlZ2lvbih0aGlzLm1hc3Rlci5mcywgdGhpcy5tYXN0ZXIucm9vdGRpciwgaSk7CisgICAgICAKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLmVycm9yKCJmYWlsZWQgdG8gZGVsZXRlIHJlZ2lvbiAiICsgQnl0ZXMudG9TdHJpbmcoaS5nZXRSZWdpb25OYW1lKCkpLAorICAgICAgICAgIFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8vIGRlbGV0ZSB0aGUgdGFibGUncyBmb2xkZXIgZnJvbSBmcy4KKyAgICBtYXN0ZXIuZnMuZGVsZXRlKG5ldyBQYXRoKG1hc3Rlci5yb290ZGlyLCBCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpKSwgdHJ1ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9UYWJsZU9wZXJhdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1RhYmxlT3BlcmF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjEyN2JkMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9UYWJsZU9wZXJhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVtb3RlRXhjZXB0aW9uSGFuZGxlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5UYWJsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKioKKyAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIG9wZXJhdGlvbnMgdGhhdCBuZWVkIHRvIGV4YW1pbmUgYWxsIEhSZWdpb25JbmZvIAorICogb2JqZWN0cyBpbiBhIHRhYmxlLiAoRm9yIGEgdGFibGUsIG9wZXJhdGUgb24gZWFjaCBvZiBpdHMgcm93cworICogaW4gLk1FVEEuKS4KKyAqLworYWJzdHJhY3QgY2xhc3MgVGFibGVPcGVyYXRpb24gaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgcHJpdmF0ZSBmaW5hbCBTZXQ8TWV0YVJlZ2lvbj4gbWV0YVJlZ2lvbnM7CisgIHByb3RlY3RlZCBmaW5hbCBieXRlIFtdIHRhYmxlTmFtZTsKKyAgcHJvdGVjdGVkIGZpbmFsIFNldDxIUmVnaW9uSW5mbz4gdW5zZXJ2ZWRSZWdpb25zID0gbmV3IEhhc2hTZXQ8SFJlZ2lvbkluZm8+KCk7CisgIHByb3RlY3RlZCBITWFzdGVyIG1hc3RlcjsKKworICBwcm90ZWN0ZWQgVGFibGVPcGVyYXRpb24oZmluYWwgSE1hc3RlciBtYXN0ZXIsIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMubWFzdGVyID0gbWFzdGVyOworICAgIGlmICghdGhpcy5tYXN0ZXIuaXNNYXN0ZXJSdW5uaW5nKCkpIHsKKyAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCk7CisgICAgfQorICAgIC8vIGFkZCB0aGUgZGVsaW1pdGVycy4KKyAgICAvLyBUT0RPIG1heWJlIGNoZWNrIGlmIHRoaXMgaXMgbmVjZXNzYXJ5PworICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworCisgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgTUVUQSB0YWJsZSB0byBjb21lIG9uIGxpbmUgaWYgd2UncmUgZW5hYmxpbmcgaXQKKyAgICBpZiAoIUJ5dGVzLmVxdWFscyhIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSwgdGhpcy50YWJsZU5hbWUpKSB7CisgICAgICAvLyBXZSBjYW4gbm90IGFjY2VzcyBhbnkgbWV0YSByZWdpb24gaWYgdGhleSBoYXZlIG5vdCBhbHJlYWR5IGJlZW4KKyAgICAgIC8vIGFzc2lnbmVkIGFuZCBzY2FubmVkLgorICAgICAgaWYgKG1hc3Rlci5yZWdpb25NYW5hZ2VyLm1ldGFTY2FubmVyVGhyZWFkLndhaXRGb3JNZXRhUmVnaW9uc09yQ2xvc2UoKSkgeworICAgICAgICAvLyBXZSdyZSBzaHV0dGluZyBkb3duLiBGb3JnZXQgaXQuCisgICAgICAgIHRocm93IG5ldyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uKCk7IAorICAgICAgfQorICAgIH0KKyAgICB0aGlzLm1ldGFSZWdpb25zID0gbWFzdGVyLnJlZ2lvbk1hbmFnZXIuZ2V0TWV0YVJlZ2lvbnNGb3JUYWJsZSh0YWJsZU5hbWUpOworICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBQcm9jZXNzVGFibGVPcGVyYXRpb24gZXh0ZW5kcyBSZXRyeWFibGVNZXRhT3BlcmF0aW9uPEJvb2xlYW4+IHsKKyAgICBQcm9jZXNzVGFibGVPcGVyYXRpb24oTWV0YVJlZ2lvbiBtLCBITWFzdGVyIG1hc3RlcikgeworICAgICAgc3VwZXIobSwgbWFzdGVyKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGJvb2xlYW4gdGFibGVFeGlzdHMgPSBmYWxzZTsKKworICAgICAgLy8gT3BlbiBhIHNjYW5uZXIgb24gdGhlIG1ldGEgcmVnaW9uCisgICAgICBieXRlIFtdIHRhYmxlTmFtZU1ldGFTdGFydCA9CisgICAgICAgICAgQnl0ZXMudG9CeXRlcyhCeXRlcy50b1N0cmluZyh0YWJsZU5hbWUpICsgIiwsIik7CisKKyAgICAgIGxvbmcgc2Nhbm5lcklkID0gc2VydmVyLm9wZW5TY2FubmVyKG0uZ2V0UmVnaW9uTmFtZSgpLAorICAgICAgICAgIENPTFVNTl9GQU1JTFlfQVJSQVksIHRhYmxlTmFtZU1ldGFTdGFydCwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKworICAgICAgTGlzdDxieXRlIFtdPiBlbXB0eVJvd3MgPSBuZXcgQXJyYXlMaXN0PGJ5dGUgW10+KCk7CisgICAgICB0cnkgeworICAgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICAgIFJvd1Jlc3VsdCB2YWx1ZXMgPSBzZXJ2ZXIubmV4dChzY2FubmVySWQpOworICAgICAgICAgIGlmKHZhbHVlcyA9PSBudWxsIHx8IHZhbHVlcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSB0aGlzLm1hc3Rlci5nZXRIUmVnaW9uSW5mbyh2YWx1ZXMuZ2V0Um93KCksIHZhbHVlcyk7CisgICAgICAgICAgaWYgKGluZm8gPT0gbnVsbCkgeworICAgICAgICAgICAgZW1wdHlSb3dzLmFkZCh2YWx1ZXMuZ2V0Um93KCkpOworICAgICAgICAgICAgTE9HLmVycm9yKEJ5dGVzLnRvU3RyaW5nKENPTF9SRUdJT05JTkZPKSArICIgbm90IGZvdW5kIG9uICIgKworICAgICAgICAgICAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHZhbHVlcy5nZXRSb3coKSkpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgfQorICAgICAgICAgIFN0cmluZyBzZXJ2ZXJBZGRyZXNzID0gV3JpdGFibGVzLmNlbGxUb1N0cmluZyh2YWx1ZXMuZ2V0KENPTF9TRVJWRVIpKTsKKyAgICAgICAgICBsb25nIHN0YXJ0Q29kZSA9IFdyaXRhYmxlcy5jZWxsVG9Mb25nKHZhbHVlcy5nZXQoQ09MX1NUQVJUQ09ERSkpOyAKKyAgICAgICAgICBTdHJpbmcgc2VydmVyTmFtZSA9IG51bGw7CisgICAgICAgICAgaWYgKHNlcnZlckFkZHJlc3MgIT0gbnVsbCAmJiBzZXJ2ZXJBZGRyZXNzLmxlbmd0aCgpID4gMCkgeworICAgICAgICAgICAgc2VydmVyTmFtZSA9IEhTZXJ2ZXJJbmZvLmdldFNlcnZlck5hbWUoc2VydmVyQWRkcmVzcywgc3RhcnRDb2RlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKEJ5dGVzLmNvbXBhcmVUbyhpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgdGFibGVOYW1lKSA+IDApIHsKKyAgICAgICAgICAgIGJyZWFrOyAvLyBCZXlvbmQgYW55IG1vcmUgZW50cmllcyBmb3IgdGhpcyB0YWJsZQorICAgICAgICAgIH0KKworICAgICAgICAgIHRhYmxlRXhpc3RzID0gdHJ1ZTsKKyAgICAgICAgICBpZiAoIWlzQmVpbmdTZXJ2ZWQoc2VydmVyTmFtZSkgfHwgIWlzRW5hYmxlZChpbmZvKSkgeworICAgICAgICAgICAgdW5zZXJ2ZWRSZWdpb25zLmFkZChpbmZvKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJvY2Vzc1NjYW5JdGVtKHNlcnZlck5hbWUsIGluZm8pOworICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBpZiAoc2Nhbm5lcklkICE9IC0xTCkgeworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzZXJ2ZXIuY2xvc2Uoc2Nhbm5lcklkKTsKKyAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgTE9HLmVycm9yKCJjbG9zaW5nIHNjYW5uZXIiLCBlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgc2Nhbm5lcklkID0gLTFMOworICAgICAgfQorCisgICAgICAvLyBHZXQgcmlkIG9mIGFueSByb3dzIHRoYXQgaGF2ZSBhIG51bGwgSFJlZ2lvbkluZm8KKworICAgICAgaWYgKGVtcHR5Um93cy5zaXplKCkgPiAwKSB7CisgICAgICAgIExPRy53YXJuKCJGb3VuZCAiICsgZW1wdHlSb3dzLnNpemUoKSArCisgICAgICAgICAgICAiIHJvd3Mgd2l0aCBlbXB0eSBIUmVnaW9uSW5mbyB3aGlsZSBzY2FubmluZyBtZXRhIHJlZ2lvbiAiICsKKyAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKG0uZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgICAgIG1hc3Rlci5kZWxldGVFbXB0eU1ldGFSb3dzKHNlcnZlciwgbS5nZXRSZWdpb25OYW1lKCksIGVtcHR5Um93cyk7CisgICAgICB9CisKKyAgICAgIGlmICghdGFibGVFeGlzdHMpIHsKKyAgICAgICAgdGhyb3cgbmV3IFRhYmxlTm90Rm91bmRFeGNlcHRpb24oQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgICB9CisKKyAgICAgIHBvc3RQcm9jZXNzTWV0YShtLCBzZXJ2ZXIpOworICAgICAgdW5zZXJ2ZWRSZWdpb25zLmNsZWFyKCk7CisKKyAgICAgIHJldHVybiBCb29sZWFuLlRSVUU7CisgICAgfQorICB9CisKKyAgdm9pZCBwcm9jZXNzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBQcmV2ZW50IG1ldGEgc2Nhbm5lciBmcm9tIHJ1bm5pbmcKKyAgICBzeW5jaHJvbml6ZWQobWFzdGVyLnJlZ2lvbk1hbmFnZXIubWV0YVNjYW5uZXJUaHJlYWQuc2Nhbm5lckxvY2spIHsKKyAgICAgIGZvciAoTWV0YVJlZ2lvbiBtOiBtZXRhUmVnaW9ucykgeworICAgICAgICBuZXcgUHJvY2Vzc1RhYmxlT3BlcmF0aW9uKG0sIG1hc3RlcikuZG9XaXRoUmV0cmllcygpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgcHJvdGVjdGVkIGJvb2xlYW4gaXNCZWluZ1NlcnZlZChTdHJpbmcgc2VydmVyTmFtZSkgeworICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisgICAgaWYgKHNlcnZlck5hbWUgIT0gbnVsbCAmJiBzZXJ2ZXJOYW1lLmxlbmd0aCgpID4gMCkgeworICAgICAgSFNlcnZlckluZm8gcyA9IG1hc3Rlci5zZXJ2ZXJNYW5hZ2VyLmdldFNlcnZlckluZm8oc2VydmVyTmFtZSk7CisgICAgICByZXN1bHQgPSBzICE9IG51bGw7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0VuYWJsZWQoSFJlZ2lvbkluZm8gaW5mbykgeworICAgIHJldHVybiAhaW5mby5pc09mZmxpbmUoKTsKKyAgfQorCisgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHByb2Nlc3NTY2FuSXRlbShTdHJpbmcgc2VydmVyTmFtZSwgSFJlZ2lvbkluZm8gaW5mbykKKyAgdGhyb3dzIElPRXhjZXB0aW9uOworCisgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHBvc3RQcm9jZXNzTWV0YShNZXRhUmVnaW9uIG0sCisgICAgSFJlZ2lvbkludGVyZmFjZSBzZXJ2ZXIpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvWktNYXN0ZXJBZGRyZXNzV2F0Y2hlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1pLTWFzdGVyQWRkcmVzc1dhdGNoZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNWYwMzNjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL1pLTWFzdGVyQWRkcmVzc1dhdGNoZXIuamF2YQpAQCAtMCwwICsxLDc1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyLlpvb0tlZXBlcldyYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlZEV2ZW50OworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLldhdGNoZXI7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlci5FdmVudC5FdmVudFR5cGU7CisKKy8qKgorICogWm9vS2VlcGVyIHdhdGNoZXIgZm9yIHRoZSBtYXN0ZXIgYWRkcmVzcy4gVXNlZCBieSB0aGUgSE1hc3RlciB0byB3YWl0IGZvcgorICogdGhlIGV2ZW50IHdoZW4gbWFzdGVyIGFkZHJlc3MgWk5vZGUgZ2V0cyBkZWxldGVkLiBXaGVuIG11bHRpcGxlIG1hc3RlcnMgYXJlCisgKiBicm91Z2h0IHVwLCB0aGV5IHJhY2UgdG8gYmVjb21lIG1hc3RlciBieSB3cml0aW5nIHRvIHdyaXRlIHRoZWlyIGFkZHJlc3MgdG8KKyAqIFpvb0tlZXBlci4gV2hvZXZlciB3aW5zIGJlY29tZXMgdGhlIG1hc3RlciwgYW5kIHRoZSByZXN0IHdhaXQgZm9yIHRoYXQKKyAqIGVwaGVtZXJhbCBub2RlIGluIFpvb0tlZXBlciB0byBnZXQgZGVsZXRlZCAobWVhbmluZyB0aGUgbWFzdGVyIHdlbnQgZG93biksIGF0CisgKiB3aGljaCBwb2ludCB0aGV5IHRyeSB0byB3cml0ZSB0byBpdCBhZ2Fpbi4KKyAqLworcHVibGljIGNsYXNzIFpLTWFzdGVyQWRkcmVzc1dhdGNoZXIgaW1wbGVtZW50cyBXYXRjaGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFpLTWFzdGVyQWRkcmVzc1dhdGNoZXIuY2xhc3MpOworCisgIHByaXZhdGUgZmluYWwgWm9vS2VlcGVyV3JhcHBlciB6b29LZWVwZXI7CisKKyAgLyoqCisgICAqIENyZWF0ZSBhIHdhdGNoZXIgd2l0aCBhIFpvb0tlZXBlcldyYXBwZXIgaW5zdGFuY2UuCisgICAqIEBwYXJhbSB6b29LZWVwZXIgWm9vS2VlcGVyV3JhcHBlciB0byB1c2UgdG8gdGFsayB0byBab29LZWVwZXIuCisgICAqLworICBwdWJsaWMgWktNYXN0ZXJBZGRyZXNzV2F0Y2hlcihab29LZWVwZXJXcmFwcGVyIHpvb0tlZXBlcikgeworICAgIHRoaXMuem9vS2VlcGVyID0gem9vS2VlcGVyOworICB9CisKKyAgLyoqCisgICAqIEBzZWUgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlciNwcm9jZXNzKG9yZy5hcGFjaGUuem9va2VlcGVyLldhdGNoZWRFdmVudCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHJvY2VzcyhXYXRjaGVkRXZlbnQgZXZlbnQpIHsKKyAgICBFdmVudFR5cGUgdHlwZSA9IGV2ZW50LmdldFR5cGUoKTsKKyAgICBpZiAodHlwZS5lcXVhbHMoRXZlbnRUeXBlLk5vZGVEZWxldGVkKSkgeworICAgICAgTE9HLmRlYnVnKCJNYXN0ZXIgYWRkcmVzcyBaTm9kZSBkZWxldGVkLCBub3RpZnlpbmcgd2FpdGluZyBtYXN0ZXJzIik7CisgICAgICBub3RpZnlBbGwoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogV2FpdCBmb3IgbWFzdGVyIGFkZHJlc3MgdG8gYmUgYXZhaWxhYmxlLiBUaGlzIHNldHMgYSB3YXRjaCBpbiBab29LZWVwZXIgYW5kCisgICAqIGJsb2NrcyB1bnRpbCB0aGUgbWFzdGVyIGFkZHJlc3MgWk5vZGUgZ2V0cyBkZWxldGVkLgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHdhaXRGb3JNYXN0ZXJBZGRyZXNzQXZhaWxhYmlsaXR5KCkgeworICAgIHdoaWxlICh6b29LZWVwZXIucmVhZE1hc3RlckFkZHJlc3ModGhpcykgIT0gbnVsbCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgTE9HLmRlYnVnKCJXYWl0aW5nIGZvciBtYXN0ZXIgYWRkcmVzcyBaTm9kZSB0byBiZSBkZWxldGVkIik7CisgICAgICAgIHdhaXQoKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9tZXRyaWNzL01hc3Rlck1ldHJpY3MuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9tZXRyaWNzL01hc3Rlck1ldHJpY3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDlkZWViCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFzdGVyL21ldHJpY3MvTWFzdGVyTWV0cmljcy5qYXZhCkBAIC0wLDAgKzEsOTUgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXIubWV0cmljczsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuTWV0cmljc0NvbnRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5NZXRyaWNzUmVjb3JkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuTWV0cmljc1V0aWw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5VcGRhdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuanZtLkp2bU1ldHJpY3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy51dGlsLk1ldHJpY3NJbnRWYWx1ZTsKKworLyoqIAorICogVGhpcyBjbGFzcyBpcyBmb3IgbWFpbnRhaW5pbmcgdGhlIHZhcmlvdXMgbWFzdGVyIHN0YXRpc3RpY3MKKyAqIGFuZCBwdWJsaXNoaW5nIHRoZW0gdGhyb3VnaCB0aGUgbWV0cmljcyBpbnRlcmZhY2VzLgorICogPHA+CisgKiBUaGlzIGNsYXNzIGhhcyBhIG51bWJlciBvZiBtZXRyaWNzIHZhcmlhYmxlcyB0aGF0IGFyZSBwdWJsaWNseSBhY2Nlc3NpYmxlOworICogdGhlc2UgdmFyaWFibGVzIChvYmplY3RzKSBoYXZlIG1ldGhvZHMgdG8gdXBkYXRlIHRoZWlyIHZhbHVlcy4KKyAqLworcHVibGljIGNsYXNzIE1hc3Rlck1ldHJpY3MgaW1wbGVtZW50cyBVcGRhdGVyIHsKKyAgcHJpdmF0ZSBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpKTsKKyAgcHJpdmF0ZSBmaW5hbCBNZXRyaWNzUmVjb3JkIG1ldHJpY3NSZWNvcmQ7CisKKyAgLyoKKyAgICogQ291bnQgb2YgcmVxdWVzdHMgdG8gdGhlIGNsdXN0ZXIgc2luY2UgbGFzdCBjYWxsIHRvIG1ldHJpY3MgdXBkYXRlCisgICAqLworICBwcml2YXRlIGZpbmFsIE1ldHJpY3NJbnRWYWx1ZSBjbHVzdGVyX3JlcXVlc3RzID0KKyAgICBuZXcgTWV0cmljc0ludFZhbHVlKCJjbHVzdGVyX3JlcXVlc3RzIik7CisKKyAgcHVibGljIE1hc3Rlck1ldHJpY3MoKSB7CisgICAgTWV0cmljc0NvbnRleHQgY29udGV4dCA9IE1ldHJpY3NVdGlsLmdldENvbnRleHQoImhiYXNlIik7CisgICAgbWV0cmljc1JlY29yZCA9IE1ldHJpY3NVdGlsLmNyZWF0ZVJlY29yZChjb250ZXh0LCAibWFzdGVyIik7CisgICAgU3RyaW5nIG5hbWUgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKTsKKyAgICBtZXRyaWNzUmVjb3JkLnNldFRhZygiTWFzdGVyIiwgbmFtZSk7CisgICAgY29udGV4dC5yZWdpc3RlclVwZGF0ZXIodGhpcyk7CisgICAgSnZtTWV0cmljcy5pbml0KCJNYXN0ZXIiLCBuYW1lKTsKKyAgICBMT0cuaW5mbygiSW5pdGlhbGl6ZWQiKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB7CisgICAgLy8gbm91Z2h0IHRvIGRvLgorICB9CisgICAgCisgIC8qKgorICAgKiBTaW5jZSB0aGlzIG9iamVjdCBpcyBhIHJlZ2lzdGVyZWQgdXBkYXRlciwgdGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQKKyAgICogcGVyaW9kaWNhbGx5LCBlLmcuIGV2ZXJ5IDUgc2Vjb25kcy4KKyAgICogQHBhcmFtIHVudXNlZCAKKyAgICovCisgIHB1YmxpYyB2b2lkIGRvVXBkYXRlcyhNZXRyaWNzQ29udGV4dCB1bnVzZWQpIHsKKyAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgIHN5bmNocm9uaXplZCh0aGlzLmNsdXN0ZXJfcmVxdWVzdHMpIHsKKyAgICAgICAgdGhpcy5jbHVzdGVyX3JlcXVlc3RzLnB1c2hNZXRyaWMobWV0cmljc1JlY29yZCk7CisgICAgICAgIC8vIFNldCByZXF1ZXN0cyBkb3duIHRvIHplcm8gYWdhaW4uCisgICAgICAgIHRoaXMuY2x1c3Rlcl9yZXF1ZXN0cy5zZXQoMCk7CisgICAgICB9CisgICAgfQorICAgIHRoaXMubWV0cmljc1JlY29yZC51cGRhdGUoKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgcmVzZXRBbGxNaW5NYXgoKSB7CisgICAgLy8gTm90aGluZyB0byBkbworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gQ291bnQgb2YgcmVxdWVzdHMuCisgICAqLworICBwdWJsaWMgaW50IGdldFJlcXVlc3RzKCkgeworICAgIHJldHVybiB0aGlzLmNsdXN0ZXJfcmVxdWVzdHMuZ2V0KCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gaW5jIEhvdyBtdWNoIHRvIGFkZCB0byByZXF1ZXN0cy4KKyAgICovCisgIHB1YmxpYyB2b2lkIGluY3JlbWVudFJlcXVlc3RzKGZpbmFsIGludCBpbmMpIHsKKyAgICBzeW5jaHJvbml6ZWQodGhpcy5jbHVzdGVyX3JlcXVlc3RzKSB7CisgICAgICB0aGlzLmNsdXN0ZXJfcmVxdWVzdHMuc2V0KHRoaXMuY2x1c3Rlcl9yZXF1ZXN0cy5nZXQoKSArIGluYyk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWV0cmljcy9NZXRyaWNzUmF0ZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWV0cmljcy9NZXRyaWNzUmF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2NDliOTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tZXRyaWNzL01ldHJpY3NSYXRlLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1ldHJpY3M7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLk1ldHJpY3NSZWNvcmQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5TdHJpbmdVdGlsczsKKworLyoqCisgKiBQdWJsaXNoZXMgYSByYXRlIGJhc2VkIG9uIGEgY291bnRlciAtIHlvdSBpbmNyZW1lbnQgdGhlIGNvdW50ZXIgZWFjaAorICogdGltZSBhbiBldmVudCBvY2N1cnMgKGVnOiBhbiBSUEMgY2FsbCkgYW5kIHRoaXMgcHVibGlzaGVzIGEgcmF0ZS4KKyAqLworcHVibGljIGNsYXNzIE1ldHJpY3NSYXRlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKCJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tZXRyaWNzIik7CisgIAorICBwcml2YXRlIFN0cmluZyBuYW1lOworICBwcml2YXRlIGludCB2YWx1ZTsKKyAgcHJpdmF0ZSBmbG9hdCBwcmV2UmF0ZTsKKyAgcHJpdmF0ZSBsb25nIHRzOworICAKKyAgcHVibGljIE1ldHJpY3NSYXRlKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICB0aGlzLnZhbHVlID0gMDsKKyAgICB0aGlzLnByZXZSYXRlID0gMDsKKyAgICB0aGlzLnRzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgIH0KKyAgCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbmMoZmluYWwgaW50IGluY3IpIHsKKyAgICB2YWx1ZSArPSBpbmNyOworICB9CisgIAorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgaW5jKCkgeworICAgIHZhbHVlKys7CisgIH0KKyAgCisgIHByaXZhdGUgc3luY2hyb25pemVkIHZvaWQgaW50ZXJ2YWxIZWFydEJlYXQoKSB7CisgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBsb25nIGRpZmYgPSAobm93LXRzKS8xMDAwOworICAgIGlmIChkaWZmID09IDApIGRpZmYgPSAxOyAvLyBzaWdoIHRoaXMgaXMgY3JhcC4KKyAgICB0aGlzLnByZXZSYXRlID0gKGZsb2F0KXZhbHVlIC8gZGlmZjsKKyAgICB0aGlzLnZhbHVlID0gMDsKKyAgICB0aGlzLnRzID0gbm93OworICB9CisgIAorICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcHVzaE1ldHJpYyhmaW5hbCBNZXRyaWNzUmVjb3JkIG1yKSB7CisgICAgaW50ZXJ2YWxIZWFydEJlYXQoKTsKKyAgICB0cnkgeworICAgICAgbXIuc2V0TWV0cmljKG5hbWUsIGdldFByZXZpb3VzSW50ZXJ2YWxWYWx1ZSgpKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmluZm8oInB1c2hNZXRyaWMgZmFpbGVkIGZvciAiICsgbmFtZSArICJcbiIgKyAKKyAgICAgICAgICBTdHJpbmdVdGlscy5zdHJpbmdpZnlFeGNlcHRpb24oZSkpOworICAgIH0KKyAgfQorICBwdWJsaWMgc3luY2hyb25pemVkIGZsb2F0IGdldFByZXZpb3VzSW50ZXJ2YWxWYWx1ZSgpIHsKKyAgICByZXR1cm4gdGhpcy5wcmV2UmF0ZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWV0cmljcy9maWxlL1RpbWVTdGFtcGluZ0ZpbGVDb250ZXh0LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tZXRyaWNzL2ZpbGUvVGltZVN0YW1waW5nRmlsZUNvbnRleHQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNWZmYzZlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWV0cmljcy9maWxlL1RpbWVTdGFtcGluZ0ZpbGVDb250ZXh0LmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tZXRyaWNzLmZpbGU7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OworaW1wb3J0IGphdmEudXRpbC5EYXRlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5Db250ZXh0RmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLmZpbGUuRmlsZUNvbnRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5zcGkuT3V0cHV0UmVjb3JkOworCisvKioKKyAqIEFkZCB0aW1lc3RhbXAgdG8ge0BsaW5rIG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MuZmlsZS5GaWxlQ29udGV4dCNlbWl0UmVjb3JkKFN0cmluZywgU3RyaW5nLCBPdXRwdXRSZWNvcmQpfS4KKyAqLworcHVibGljIGNsYXNzIFRpbWVTdGFtcGluZ0ZpbGVDb250ZXh0IGV4dGVuZHMgRmlsZUNvbnRleHQgeworICAvLyBDb3BpZXMgYnVuY2ggb2YgRmlsZUNvbnRleHQgaGVyZSBiZWNhdXNlIHdyaXRlciBhbmQgZmlsZSBhcmUgcHJpdmF0ZSBpbgorICAvLyBzdXBlcmNsYXNzLgorICBwcml2YXRlIEZpbGUgZmlsZSA9IG51bGw7CisgIHByaXZhdGUgUHJpbnRXcml0ZXIgd3JpdGVyID0gbnVsbDsKKyAgcHJpdmF0ZSBmaW5hbCBTaW1wbGVEYXRlRm9ybWF0IHNkZjsKKyAgCisgIHB1YmxpYyBUaW1lU3RhbXBpbmdGaWxlQ29udGV4dCgpIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuc2RmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQnVCdISDptbTpzcyIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGluaXQoU3RyaW5nIGNvbnRleHROYW1lLCBDb250ZXh0RmFjdG9yeSBmYWN0b3J5KSB7CisgICAgc3VwZXIuaW5pdChjb250ZXh0TmFtZSwgZmFjdG9yeSk7CisgICAgU3RyaW5nIGZpbGVOYW1lID0gZ2V0QXR0cmlidXRlKEZJTEVfTkFNRV9QUk9QRVJUWSk7CisgICAgaWYgKGZpbGVOYW1lICE9IG51bGwpIHsKKyAgICAgIGZpbGUgPSBuZXcgRmlsZShmaWxlTmFtZSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHN0YXJ0TW9uaXRvcmluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGZpbGUgPT0gbnVsbCkgeworICAgICAgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShTeXN0ZW0ub3V0KSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHdyaXRlciA9IG5ldyBQcmludFdyaXRlcihuZXcgRmlsZVdyaXRlcihmaWxlLCB0cnVlKSk7CisgICAgfQorICAgIHN1cGVyLnN0YXJ0TW9uaXRvcmluZygpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHN0b3BNb25pdG9yaW5nKCkgeworICAgIHN1cGVyLnN0b3BNb25pdG9yaW5nKCk7CisgICAgaWYgKHdyaXRlciAhPSBudWxsKSB7CisgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgIHdyaXRlciA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgU3RyaW5nIGlzbzg2MDEoKSB7CisgICAgcmV0dXJuIHRoaXMuc2RmLmZvcm1hdChuZXcgRGF0ZSgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBlbWl0UmVjb3JkKFN0cmluZyBjb250ZXh0TmFtZSwgU3RyaW5nIHJlY29yZE5hbWUsCisgICAgICBPdXRwdXRSZWNvcmQgb3V0UmVjKSB7CisgICAgd3JpdGVyLnByaW50KGlzbzg2MDEoKSk7CisgICAgd3JpdGVyLnByaW50KCIgIik7CisgICAgd3JpdGVyLnByaW50KGNvbnRleHROYW1lKTsKKyAgICB3cml0ZXIucHJpbnQoIi4iKTsKKyAgICB3cml0ZXIucHJpbnQocmVjb3JkTmFtZSk7CisgICAgU3RyaW5nIHNlcGFyYXRvciA9ICI6ICI7CisgICAgZm9yIChTdHJpbmcgdGFnTmFtZSA6IG91dFJlYy5nZXRUYWdOYW1lcygpKSB7CisgICAgICB3cml0ZXIucHJpbnQoc2VwYXJhdG9yKTsKKyAgICAgIHNlcGFyYXRvciA9ICIsICI7CisgICAgICB3cml0ZXIucHJpbnQodGFnTmFtZSk7CisgICAgICB3cml0ZXIucHJpbnQoIj0iKTsKKyAgICAgIHdyaXRlci5wcmludChvdXRSZWMuZ2V0VGFnKHRhZ05hbWUpKTsKKyAgICB9CisgICAgZm9yIChTdHJpbmcgbWV0cmljTmFtZSA6IG91dFJlYy5nZXRNZXRyaWNOYW1lcygpKSB7CisgICAgICB3cml0ZXIucHJpbnQoc2VwYXJhdG9yKTsKKyAgICAgIHNlcGFyYXRvciA9ICIsICI7CisgICAgICB3cml0ZXIucHJpbnQobWV0cmljTmFtZSk7CisgICAgICB3cml0ZXIucHJpbnQoIj0iKTsKKyAgICAgIHdyaXRlci5wcmludChvdXRSZWMuZ2V0TWV0cmljKG1ldHJpY05hbWUpKTsKKyAgICB9CisgICAgd3JpdGVyLnByaW50bG4oKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBmbHVzaCgpIHsKKyAgICB3cml0ZXIuZmx1c2goKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9DaGFuZ2VkUmVhZGVyc09ic2VydmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvQ2hhbmdlZFJlYWRlcnNPYnNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4MzY5Y2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvQ2hhbmdlZFJlYWRlcnNPYnNlcnZlci5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKworLyoqCisgKiBJZiBzZXQgb2YgTWFwRmlsZS5SZWFkZXJzIGluIFN0b3JlIGNoYW5nZSwgaW1wbGVtZW50b3JzIGFyZSBub3RpZmllZC4KKyAqLworcHVibGljIGludGVyZmFjZSBDaGFuZ2VkUmVhZGVyc09ic2VydmVyIHsKKyAgLyoqCisgICAqIE5vdGlmeSBvYnNlcnZlcnMuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHZvaWQgdXBkYXRlUmVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvQ29tcGFjdFNwbGl0VGhyZWFkLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvQ29tcGFjdFNwbGl0VGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU0OGJiNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Db21wYWN0U3BsaXRUaHJlYWQuamF2YQpAQCAtMCwwICsxLDI1MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5MaW5rZWRCbG9ja2luZ1F1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudExvY2s7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlN0cmluZ1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKiogCisgKiBDb21wYWN0IHJlZ2lvbiBvbiByZXF1ZXN0IGFuZCB0aGVuIHJ1biBzcGxpdCBpZiBhcHByb3ByaWF0ZQorICoKKyAqIE5PVEU6IFRoaXMgY2xhc3MgZXh0ZW5kcyBUaHJlYWQgcmF0aGVyIHRoYW4gQ2hvcmUgYmVjYXVzZSB0aGUgc2xlZXAgdGltZQorICogY2FuIGJlIGludGVycnVwdGVkIHdoZW4gdGhlcmUgaXMgc29tZXRoaW5nIHRvIGRvLCByYXRoZXIgdGhhbiB0aGUgQ2hvcmUKKyAqIHNsZWVwIHRpbWUgd2hpY2ggaXMgaW52YXJpYW50LgorICovCitjbGFzcyBDb21wYWN0U3BsaXRUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhDb21wYWN0U3BsaXRUaHJlYWQuY2xhc3MpOworICAKKyAgcHJpdmF0ZSBIVGFibGUgcm9vdCA9IG51bGw7CisgIHByaXZhdGUgSFRhYmxlIG1ldGEgPSBudWxsOworICBwcml2YXRlIGZpbmFsIGxvbmcgZnJlcXVlbmN5OworICBwcml2YXRlIGZpbmFsIFJlZW50cmFudExvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgIAorICBwcml2YXRlIGZpbmFsIEhSZWdpb25TZXJ2ZXIgc2VydmVyOworICBwcml2YXRlIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICAKKyAgcHJpdmF0ZSBmaW5hbCBCbG9ja2luZ1F1ZXVlPEhSZWdpb24+IGNvbXBhY3Rpb25RdWV1ZSA9CisgICAgbmV3IExpbmtlZEJsb2NraW5nUXVldWU8SFJlZ2lvbj4oKTsKKyAgCisgIHByaXZhdGUgZmluYWwgSGFzaFNldDxIUmVnaW9uPiByZWdpb25zSW5RdWV1ZSA9IG5ldyBIYXNoU2V0PEhSZWdpb24+KCk7CisKKyAgcHJpdmF0ZSB2b2xhdGlsZSBpbnQgbGltaXQgPSAxOworCisgIC8qKiBAcGFyYW0gc2VydmVyICovCisgIHB1YmxpYyBDb21wYWN0U3BsaXRUaHJlYWQoSFJlZ2lvblNlcnZlciBzZXJ2ZXIpIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuc2VydmVyID0gc2VydmVyOworICAgIHRoaXMuY29uZiA9IHNlcnZlci5jb25mOworICAgIHRoaXMuZnJlcXVlbmN5ID0KKyAgICAgIGNvbmYuZ2V0TG9uZygiaGJhc2UucmVnaW9uc2VydmVyLnRocmVhZC5zcGxpdGNvbXBhY3RjaGVja2ZyZXF1ZW5jeSIsCisgICAgICAyMCAqIDEwMDApOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcnVuKCkgeworICAgIHdoaWxlICghdGhpcy5zZXJ2ZXIuaXNTdG9wUmVxdWVzdGVkKCkgJiYgdGhpcy5zZXJ2ZXIuaXNJblNhZmVNb2RlKCkpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIFRocmVhZC5zbGVlcCh0aGlzLmZyZXF1ZW5jeSk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9CisgICAgaW50IGNvdW50ID0gMDsKKyAgICB3aGlsZSAoIXRoaXMuc2VydmVyLmlzU3RvcFJlcXVlc3RlZCgpKSB7CisgICAgICBIUmVnaW9uIHIgPSBudWxsOworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKChsaW1pdCA+IDApICYmICgrK2NvdW50ID4gbGltaXQpKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcCh0aGlzLmZyZXF1ZW5jeSk7CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgIH0KKyAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgciA9IGNvbXBhY3Rpb25RdWV1ZS5wb2xsKHRoaXMuZnJlcXVlbmN5LCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpOworICAgICAgICBpZiAociAhPSBudWxsICYmICF0aGlzLnNlcnZlci5pc1N0b3BSZXF1ZXN0ZWQoKSkgeworICAgICAgICAgIHN5bmNocm9uaXplZCAocmVnaW9uc0luUXVldWUpIHsKKyAgICAgICAgICAgIHJlZ2lvbnNJblF1ZXVlLnJlbW92ZShyKTsKKyAgICAgICAgICB9CisgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIERvbid0IGludGVycnVwdCB1cyB3aGlsZSB3ZSBhcmUgd29ya2luZworICAgICAgICAgICAgYnl0ZSBbXSBtaWRLZXkgPSByLmNvbXBhY3RTdG9yZXMoKTsKKyAgICAgICAgICAgIGlmIChtaWRLZXkgIT0gbnVsbCAmJiAhdGhpcy5zZXJ2ZXIuaXNTdG9wUmVxdWVzdGVkKCkpIHsKKyAgICAgICAgICAgICAgc3BsaXQociwgbWlkS2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgTE9HLmVycm9yKCJDb21wYWN0aW9uL1NwbGl0IGZhaWxlZCIgKworICAgICAgICAgICAgKHIgIT0gbnVsbCA/ICgiIGZvciByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHIuZ2V0UmVnaW9uTmFtZSgpKSkgOiAiIiksCisgICAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZXgpKTsKKyAgICAgICAgaWYgKCFzZXJ2ZXIuY2hlY2tGaWxlU3lzdGVtKCkpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIExPRy5lcnJvcigiQ29tcGFjdGlvbiBmYWlsZWQiICsKKyAgICAgICAgICAgIChyICE9IG51bGwgPyAoIiBmb3IgcmVnaW9uICIgKyBCeXRlcy50b1N0cmluZyhyLmdldFJlZ2lvbk5hbWUoKSkpIDogIiIpLAorICAgICAgICAgICAgZXgpOworICAgICAgICBpZiAoIXNlcnZlci5jaGVja0ZpbGVTeXN0ZW0oKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJlZ2lvbnNJblF1ZXVlLmNsZWFyKCk7CisgICAgY29tcGFjdGlvblF1ZXVlLmNsZWFyKCk7CisgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIiBleGl0aW5nIik7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHIgSFJlZ2lvbiBzdG9yZSBiZWxvbmdzIHRvCisgICAqIEBwYXJhbSB3aHkgV2h5IGNvbXBhY3Rpb24gcmVxdWVzdGVkIC0tIHVzZWQgaW4gZGVidWcgbWVzc2FnZXMKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjb21wYWN0aW9uUmVxdWVzdGVkKGZpbmFsIEhSZWdpb24gciwKKyAgICAgIGZpbmFsIFN0cmluZyB3aHkpIHsKKyAgICBjb21wYWN0aW9uUmVxdWVzdGVkKHIsIGZhbHNlLCB3aHkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByIEhSZWdpb24gc3RvcmUgYmVsb25ncyB0bworICAgKiBAcGFyYW0gZm9yY2UgV2hldGhlciBuZXh0IGNvbXBhY3Rpb24gc2hvdWxkIGJlIG1ham9yCisgICAqIEBwYXJhbSB3aHkgV2h5IGNvbXBhY3Rpb24gcmVxdWVzdGVkIC0tIHVzZWQgaW4gZGVidWcgbWVzc2FnZXMKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBjb21wYWN0aW9uUmVxdWVzdGVkKGZpbmFsIEhSZWdpb24gciwKKyAgICAgIGZpbmFsIGJvb2xlYW4gZm9yY2UsIGZpbmFsIFN0cmluZyB3aHkpIHsKKyAgICBpZiAodGhpcy5zZXJ2ZXIuc3RvcFJlcXVlc3RlZC5nZXQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICByLnNldEZvcmNlTWFqb3JDb21wYWN0aW9uKGZvcmNlKTsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiQ29tcGFjdGlvbiAiICsgKGZvcmNlPyAiKG1ham9yKSAiOiAiIikgKworICAgICAgICAicmVxdWVzdGVkIGZvciByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHIuZ2V0UmVnaW9uTmFtZSgpKSArCisgICAgICAgICIvIiArIHIuZ2V0UmVnaW9uSW5mbygpLmdldEVuY29kZWROYW1lKCkgKworICAgICAgICAod2h5ICE9IG51bGwgJiYgIXdoeS5pc0VtcHR5KCk/ICIgYmVjYXVzZTogIiArIHdoeTogIiIpKTsKKyAgICB9CisgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5RdWV1ZSkgeworICAgICAgaWYgKCFyZWdpb25zSW5RdWV1ZS5jb250YWlucyhyKSkgeworICAgICAgICBjb21wYWN0aW9uUXVldWUuYWRkKHIpOworICAgICAgICByZWdpb25zSW5RdWV1ZS5hZGQocik7CisgICAgICB9CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHZvaWQgc3BsaXQoZmluYWwgSFJlZ2lvbiByZWdpb24sIGZpbmFsIGJ5dGUgW10gbWlkS2V5KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIEhSZWdpb25JbmZvIG9sZFJlZ2lvbkluZm8gPSByZWdpb24uZ2V0UmVnaW9uSW5mbygpOworICAgIGZpbmFsIGxvbmcgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgZmluYWwgSFJlZ2lvbltdIG5ld1JlZ2lvbnMgPSByZWdpb24uc3BsaXRSZWdpb24obWlkS2V5KTsKKyAgICBpZiAobmV3UmVnaW9ucyA9PSBudWxsKSB7CisgICAgICAvLyBEaWRuJ3QgbmVlZCB0byBiZSBzcGxpdAorICAgICAgcmV0dXJuOworICAgIH0KKyAgICAKKyAgICAvLyBXaGVuIGEgcmVnaW9uIGlzIHNwbGl0LCB0aGUgTUVUQSB0YWJsZSBuZWVkcyB0byB1cGRhdGVkIGlmIHdlJ3JlCisgICAgLy8gc3BsaXR0aW5nIGEgJ25vcm1hbCcgcmVnaW9uLCBhbmQgdGhlIFJPT1QgdGFibGUgbmVlZHMgdG8gYmUKKyAgICAvLyB1cGRhdGVkIGlmIHdlIGFyZSBzcGxpdHRpbmcgYSBNRVRBIHJlZ2lvbi4KKyAgICBIVGFibGUgdCA9IG51bGw7CisgICAgaWYgKHJlZ2lvbi5nZXRSZWdpb25JbmZvKCkuaXNNZXRhVGFibGUoKSkgeworICAgICAgLy8gV2UgbmVlZCB0byB1cGRhdGUgdGhlIHJvb3QgcmVnaW9uCisgICAgICBpZiAodGhpcy5yb290ID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5yb290ID0gbmV3IEhUYWJsZShjb25mLCBST09UX1RBQkxFX05BTUUpOworICAgICAgfQorICAgICAgdCA9IHJvb3Q7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIEZvciBub3JtYWwgcmVnaW9ucyB3ZSBuZWVkIHRvIHVwZGF0ZSB0aGUgbWV0YSByZWdpb24KKyAgICAgIGlmIChtZXRhID09IG51bGwpIHsKKyAgICAgICAgbWV0YSA9IG5ldyBIVGFibGUoY29uZiwgTUVUQV9UQUJMRV9OQU1FKTsKKyAgICAgIH0KKyAgICAgIHQgPSBtZXRhOworICAgIH0KKworICAgIC8vIE1hcmsgb2xkIHJlZ2lvbiBhcyBvZmZsaW5lIGFuZCBzcGxpdCBpbiBNRVRBLgorICAgIC8vIE5PVEU6IHRoZXJlIGlzIG5vIG5lZWQgZm9yIHJldHJ5IGxvZ2ljIGhlcmUuIEhUYWJsZSBkb2VzIGl0IGZvciB1cy4KKyAgICBvbGRSZWdpb25JbmZvLnNldE9mZmxpbmUodHJ1ZSk7CisgICAgb2xkUmVnaW9uSW5mby5zZXRTcGxpdCh0cnVlKTsKKyAgICAvLyBJbmZvcm0gdGhlIEhSZWdpb25TZXJ2ZXIgdGhhdCB0aGUgcGFyZW50IEhSZWdpb24gaXMgbm8tbG9uZ2VyIG9ubGluZS4KKyAgICB0aGlzLnNlcnZlci5yZW1vdmVGcm9tT25saW5lUmVnaW9ucyhvbGRSZWdpb25JbmZvKTsKKyAgICAKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUob2xkUmVnaW9uSW5mby5nZXRSZWdpb25OYW1lKCkpOworICAgIHVwZGF0ZS5wdXQoQ09MX1JFR0lPTklORk8sIFdyaXRhYmxlcy5nZXRCeXRlcyhvbGRSZWdpb25JbmZvKSk7CisgICAgdXBkYXRlLnB1dChDT0xfU1BMSVRBLCBXcml0YWJsZXMuZ2V0Qnl0ZXMobmV3UmVnaW9uc1swXS5nZXRSZWdpb25JbmZvKCkpKTsKKyAgICB1cGRhdGUucHV0KENPTF9TUExJVEIsIFdyaXRhYmxlcy5nZXRCeXRlcyhuZXdSZWdpb25zWzFdLmdldFJlZ2lvbkluZm8oKSkpOworICAgIHQuY29tbWl0KHVwZGF0ZSk7CisgICAgCisgICAgLy8gQWRkIG5ldyByZWdpb25zIHRvIE1FVEEKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG5ld1JlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShuZXdSZWdpb25zW2ldLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgICB1cGRhdGUucHV0KENPTF9SRUdJT05JTkZPLCBXcml0YWJsZXMuZ2V0Qnl0ZXMoCisgICAgICAgIG5ld1JlZ2lvbnNbaV0uZ2V0UmVnaW9uSW5mbygpKSk7CisgICAgICB0LmNvbW1pdCh1cGRhdGUpOworICAgIH0KKyAgICAgICAgCisgICAgLy8gTm93IHRlbGwgdGhlIG1hc3RlciBhYm91dCB0aGUgbmV3IHJlZ2lvbnMKKyAgICBzZXJ2ZXIucmVwb3J0U3BsaXQob2xkUmVnaW9uSW5mbywgbmV3UmVnaW9uc1swXS5nZXRSZWdpb25JbmZvKCksCisgICAgICBuZXdSZWdpb25zWzFdLmdldFJlZ2lvbkluZm8oKSk7CisgICAgTE9HLmluZm8oInJlZ2lvbiBzcGxpdCwgTUVUQSB1cGRhdGVkLCBhbmQgcmVwb3J0IHRvIG1hc3RlciBhbGwiICsKKyAgICAgICIgc3VjY2Vzc2Z1bC4gT2xkIHJlZ2lvbj0iICsgb2xkUmVnaW9uSW5mby50b1N0cmluZygpICsKKyAgICAgICIsIG5ldyByZWdpb25zOiAiICsgbmV3UmVnaW9uc1swXS50b1N0cmluZygpICsgIiwgIiArCisgICAgICBuZXdSZWdpb25zWzFdLnRvU3RyaW5nKCkgKyAiLiBTcGxpdCB0b29rICIgKworICAgICAgU3RyaW5nVXRpbHMuZm9ybWF0VGltZURpZmYoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCksIHN0YXJ0VGltZSkpOworICAgIAorICAgIC8vIERvIG5vdCBzZXJ2ZSB0aGUgbmV3IHJlZ2lvbnMuIExldCB0aGUgTWFzdGVyIGFzc2lnbiB0aGVtLgorICB9CisKKyAgLyoqCisgICAqIFNldHMgdGhlIG51bWJlciBvZiBjb21wYWN0aW9ucyBhbGxvd2VkIHBlciBjeWNsZS4KKyAgICogQHBhcmFtIGxpbWl0IHRoZSBudW1iZXIgb2YgY29tcGFjdGlvbnMgYWxsb3dlZCwgb3IgLTEgdG8gdW5saW1pdAorICAgKi8KKyAgdm9pZCBzZXRMaW1pdChpbnQgbGltaXQpIHsKKyAgICB0aGlzLmxpbWl0ID0gbGltaXQ7CisgIH0KKworICBpbnQgZ2V0TGltaXQoKSB7CisgICAgcmV0dXJuIHRoaXMubGltaXQ7CisgIH0KKworICAvKioKKyAgICogT25seSBpbnRlcnJ1cHQgb25jZSBpdCdzIGRvbmUgd2l0aCBhIHJ1biB0aHJvdWdoIHRoZSB3b3JrIGxvb3AuCisgICAqLyAKKyAgdm9pZCBpbnRlcnJ1cHRJZk5lY2Vzc2FyeSgpIHsKKyAgICBpZiAobG9jay50cnlMb2NrKCkpIHsKKyAgICAgIHRoaXMuaW50ZXJydXB0KCk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0ZhaWxlZExvZ0Nsb3NlRXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvRmFpbGVkTG9nQ2xvc2VFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZDJkZmFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0ZhaWxlZExvZ0Nsb3NlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIHdoZW4gd2UgZmFpbCBjbG9zZSBvZiB0aGUgd3JpdGUtYWhlYWQtbG9nIGZpbGUuCisgKiBQYWNrYWdlIHByaXZhdGUuICBPbmx5IHVzZWQgaW5zaWRlIHRoaXMgcGFja2FnZS4KKyAqLworY2xhc3MgRmFpbGVkTG9nQ2xvc2VFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDE3NTkxNTI4NDE0NjI5OTA5MjVMOworCisgIHB1YmxpYyBGYWlsZWRMb2dDbG9zZUV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgcHVibGljIEZhaWxlZExvZ0Nsb3NlRXhjZXB0aW9uKFN0cmluZyBhcmcwKSB7CisgICAgc3VwZXIoYXJnMCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9GbHVzaFJlcXVlc3Rlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0ZsdXNoUmVxdWVzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU5NjJhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9GbHVzaFJlcXVlc3Rlci5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworLyoqCisgKiBJbXBsZW1lbnRvcnMgb2YgdGhpcyBpbnRlcmZhY2Ugd2FudCB0byBiZSBub3RpZmllZCB3aGVuIGFuIEhSZWdpb24KKyAqIGRldGVybWluZXMgdGhhdCBhIGNhY2hlIGZsdXNoIGlzIG5lZWRlZC4gQSBGbHVzaFJlcXVlc3RlciAob3IgbnVsbCkKKyAqIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBIUmVnaW9uIGNvbnN0cnVjdG9yIHNvIGl0IGtub3dzIHdobyB0byBjYWxsIHdoZW4gaXQKKyAqIGhhcyBhIGZpbGxlZCBtZW1jYWNoZS4KKyAqLworcHVibGljIGludGVyZmFjZSBGbHVzaFJlcXVlc3RlciB7CisgIC8qKgorICAgKiBUZWxsIHRoZSBsaXN0ZW5lciB0aGUgY2FjaGUgbmVlZHMgdG8gYmUgZmx1c2hlZC4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb24gdGhlIEhSZWdpb24gcmVxdWVzdGluZyB0aGUgY2FjaGUgZmx1c2gKKyAgICovCisgIHZvaWQgcmVxdWVzdChIUmVnaW9uIHJlZ2lvbik7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0hBYnN0cmFjdFNjYW5uZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9IQWJzdHJhY3RTY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODRmNDJhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9IQWJzdHJhY3RTY2FubmVyLmphdmEKQEAgLTAsMCArMSwyMTQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk5hdmlnYWJsZVNldDsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkNvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEFic3RyYWN0IGJhc2UgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBJbnRlcm5hbFNjYW5uZXIuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBIQWJzdHJhY3RTY2FubmVyIGltcGxlbWVudHMgSW50ZXJuYWxTY2FubmVyIHsKKyAgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOworCisgIC8vIFBhdHRlcm4gdG8gZGV0ZXJtaW5lIGlmIGEgY29sdW1uIGtleSBpcyBhIHJlZ2V4CisgIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIGlzUmVnZXhQYXR0ZXJuID0KKyAgICBQYXR0ZXJuLmNvbXBpbGUoIl4uKltcXFxcK3xeJiokXFxbXFxdXFx9eykoXSsuKiQiKTsKKworICAvKiogVGhlIGtpbmQgb2YgbWF0Y2ggd2UgYXJlIGRvaW5nIG9uIGEgY29sdW1uOiAqLworICBwcml2YXRlIHN0YXRpYyBlbnVtIE1BVENIX1RZUEUgeworICAgIC8qKiBKdXN0IGNoZWNrIHRoZSBjb2x1bW4gZmFtaWx5IG5hbWUgKi8KKyAgICBGQU1JTFlfT05MWSwKKyAgICAvKiogQ29sdW1uIGZhbWlseSArIG1hdGNoZXMgcmVnZXggKi8KKyAgICBSRUdFWCwKKyAgICAvKiogTGl0ZXJhbCBtYXRjaGluZyAqLworICAgIFNJTVBMRQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PENvbHVtbk1hdGNoZXI+IG1hdGNoZXJzID0gbmV3IEFycmF5TGlzdDxDb2x1bW5NYXRjaGVyPigpOworCisgIC8vIFRydWUgd2hlbiBzY2FubmluZyBpcyBkb25lCisgIHByb3RlY3RlZCB2b2xhdGlsZSBib29sZWFuIHNjYW5uZXJDbG9zZWQgPSBmYWxzZTsKKworICAvLyBUaGUgdGltZXN0YW1wIHRvIG1hdGNoIGVudHJpZXMgYWdhaW5zdAorICBwcm90ZWN0ZWQgZmluYWwgbG9uZyB0aW1lc3RhbXA7CisKKyAgcHJpdmF0ZSBib29sZWFuIHdpbGRjYXJkTWF0Y2ggPSBmYWxzZTsKKyAgcHJpdmF0ZSBib29sZWFuIG11bHRpcGxlTWF0Y2hlcnMgPSBmYWxzZTsKKworICAvKiogQ29uc3RydWN0b3IgZm9yIGFic3RyYWN0IGJhc2UgY2xhc3MgKi8KKyAgcHJvdGVjdGVkIEhBYnN0cmFjdFNjYW5uZXIoZmluYWwgbG9uZyB0aW1lc3RhbXAsCisgICAgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IGNvbHVtbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgZm9yIChieXRlIFtdIGNvbHVtbjogY29sdW1ucykgeworICAgICAgQ29sdW1uTWF0Y2hlciBtYXRjaGVyID0gbmV3IENvbHVtbk1hdGNoZXIoY29sdW1uKTsKKyAgICAgIHRoaXMud2lsZGNhcmRNYXRjaCA9IG1hdGNoZXIuaXNXaWxkQ2FyZE1hdGNoKCk7CisgICAgICBtYXRjaGVycy5hZGQobWF0Y2hlcik7CisgICAgICB0aGlzLm11bHRpcGxlTWF0Y2hlcnMgPSAhbWF0Y2hlcnMuaXNFbXB0eSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBGb3IgYSBwYXJ0aWN1bGFyIGNvbHVtbiwgZmluZCBhbGwgdGhlIG1hdGNoZXJzIGRlZmluZWQgZm9yIHRoZSBjb2x1bW4uCisgICAqIENvbXBhcmUgdGhlIGNvbHVtbiBmYW1pbHkgYW5kIGNvbHVtbiBrZXkgdXNpbmcgdGhlIG1hdGNoZXJzLiBUaGUgZmlyc3Qgb25lCisgICAqIHRoYXQgbWF0Y2hlcyByZXR1cm5zIHRydWUuIElmIG5vIG1hdGNoZXJzIGFyZSBzdWNjZXNzZnVsLCByZXR1cm4gZmFsc2UuCisgICAqIAorICAgKiBAcGFyYW0ga3YgS2V5VmFsdWUgdG8gdGVzdAorICAgKiBAcmV0dXJuIHRydWUgaWYgYW55IG9mIHRoZSBtYXRjaGVycyBmb3IgdGhlIGNvbHVtbiBtYXRjaCB0aGUgY29sdW1uIGZhbWlseQorICAgKiBhbmQgdGhlIGNvbHVtbiBrZXkuCisgICAqICAgICAgICAgICAgICAgICAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJvdGVjdGVkIGJvb2xlYW4gY29sdW1uTWF0Y2goZmluYWwgS2V5VmFsdWUga3YpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKG1hdGNoZXJzID09IG51bGwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgZm9yKGludCBtID0gMDsgbSA8IHRoaXMubWF0Y2hlcnMuc2l6ZSgpOyBtKyspIHsKKyAgICAgIGlmICh0aGlzLm1hdGNoZXJzLmdldChtKS5tYXRjaGVzKGt2KSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZFNjYW5uZXIoKSB7CisgICAgcmV0dXJuIHRoaXMud2lsZGNhcmRNYXRjaDsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gaXNNdWx0aXBsZU1hdGNoU2Nhbm5lcigpIHsKKyAgICByZXR1cm4gdGhpcy5tdWx0aXBsZU1hdGNoZXJzOworICB9CisKKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gbmV4dChMaXN0PEtleVZhbHVlPiByZXN1bHRzKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisKKyAgLyoqCisgICAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgY29sdW1uIG1hdGNoaW5nIGZ1bmN0aW9ucyB0aGF0IGFyZSBtb3JlIHNvcGhpc3RpY2F0ZWQKKyAgICogdGhhbiBhIHNpbXBsZSBzdHJpbmcgY29tcGFyZS4gVGhlcmUgYXJlIHRocmVlIHR5cGVzIG9mIG1hdGNoaW5nOgorICAgKiA8b2w+CisgICAqIDxsaT5NYXRjaCBvbiB0aGUgY29sdW1uIGZhbWlseSBuYW1lIG9ubHk8L2xpPgorICAgKiA8bGk+TWF0Y2ggb24gdGhlIGNvbHVtbiBmYW1pbHkgKyBjb2x1bW4ga2V5IHJlZ2V4PC9saT4KKyAgICogPGxpPlNpbXBsZSBtYXRjaDogY29tcGFyZSBjb2x1bW4gZmFtaWx5ICsgY29sdW1uIGtleSBsaXRlcmFsbHk8L2xpPgorICAgKiA8L3VsPgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ29sdW1uTWF0Y2hlciB7CisgICAgcHJpdmF0ZSBib29sZWFuIHdpbGRDYXJkbWF0Y2g7CisgICAgcHJpdmF0ZSBNQVRDSF9UWVBFIG1hdGNoVHlwZTsKKyAgICBwcml2YXRlIGJ5dGUgW10gZmFtaWx5OworICAgIHByaXZhdGUgUGF0dGVybiBjb2x1bW5NYXRjaGVyOworICAgIC8vIENvbHVtbiB3aXRob3V0IGRlbGltaXRlciBzbyBlYXN5IGNvbXBhcmUgdG8gS2V5VmFsdWUgY29sdW1uCisgICAgcHJpdmF0ZSBieXRlIFtdIGNvbDsKKyAgICBwcml2YXRlIGludCBmYW1pbHlsZW5ndGggPSAwOworICAKKyAgICBDb2x1bW5NYXRjaGVyKGZpbmFsIGJ5dGUgW10gY29sKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgYnl0ZSBbXVtdIHBhcnNlID0gcGFyc2VDb2x1bW4oY29sKTsKKyAgICAgIC8vIE1ha2UgdXAgY29sdW1uIHdpdGhvdXQgZGVsaW1pdGVyCisgICAgICBieXRlIFtdIGNvbHVtbldpdGhvdXREZWxpbWl0ZXIgPQorICAgICAgICBuZXcgYnl0ZSBbcGFyc2VbMF0ubGVuZ3RoICsgcGFyc2VbMV0ubGVuZ3RoXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkocGFyc2VbMF0sIDAsIGNvbHVtbldpdGhvdXREZWxpbWl0ZXIsIDAsIHBhcnNlWzBdLmxlbmd0aCk7CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBhcnNlWzFdLCAwLCBjb2x1bW5XaXRob3V0RGVsaW1pdGVyLCBwYXJzZVswXS5sZW5ndGgsCisgICAgICAgIHBhcnNlWzFdLmxlbmd0aCk7CisgICAgICAvLyBGaXJzdCBwb3NpdGlvbiBoYXMgZmFtaWx5LiAgU2Vjb25kIGhhcyBxdWFsaWZpZXIuCisgICAgICBieXRlIFtdIHF1YWxpZmllciA9IHBhcnNlWzFdOworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKHF1YWxpZmllciA9PSBudWxsIHx8IHF1YWxpZmllci5sZW5ndGggPT0gMCkgeworICAgICAgICAgIHRoaXMubWF0Y2hUeXBlID0gTUFUQ0hfVFlQRS5GQU1JTFlfT05MWTsKKyAgICAgICAgICB0aGlzLmZhbWlseSA9IHBhcnNlWzBdOworICAgICAgICAgIHRoaXMud2lsZENhcmRtYXRjaCA9IHRydWU7CisgICAgICAgIH0gZWxzZSBpZiAoaXNSZWdleFBhdHRlcm4ubWF0Y2hlcihCeXRlcy50b1N0cmluZyhxdWFsaWZpZXIpKS5tYXRjaGVzKCkpIHsKKyAgICAgICAgICB0aGlzLm1hdGNoVHlwZSA9IE1BVENIX1RZUEUuUkVHRVg7CisgICAgICAgICAgdGhpcy5jb2x1bW5NYXRjaGVyID0KKyAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZShCeXRlcy50b1N0cmluZyhjb2x1bW5XaXRob3V0RGVsaW1pdGVyKSk7CisgICAgICAgICAgdGhpcy53aWxkQ2FyZG1hdGNoID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0aGlzLm1hdGNoVHlwZSA9IE1BVENIX1RZUEUuU0lNUExFOworICAgICAgICAgIHRoaXMuY29sID0gY29sdW1uV2l0aG91dERlbGltaXRlcjsKKyAgICAgICAgICB0aGlzLmZhbWlseWxlbmd0aCA9IHBhcnNlWzBdLmxlbmd0aDsKKyAgICAgICAgICB0aGlzLndpbGRDYXJkbWF0Y2ggPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvbHVtbjogIiArIEJ5dGVzLnRvU3RyaW5nKGNvbCkgKyAiOiAiICsKKyAgICAgICAgICBlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIEBwYXJhbSBrdgorICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgYm9vbGVhbiBtYXRjaGVzKGZpbmFsIEtleVZhbHVlIGt2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHRoaXMubWF0Y2hUeXBlID09IE1BVENIX1RZUEUuU0lNUExFKSB7CisgICAgICAgIHJldHVybiBrdi5tYXRjaGluZ0NvbHVtbk5vRGVsaW1pdGVyKHRoaXMuY29sLCB0aGlzLmZhbWlseWxlbmd0aCk7CisgICAgICB9IGVsc2UgaWYodGhpcy5tYXRjaFR5cGUgPT0gTUFUQ0hfVFlQRS5GQU1JTFlfT05MWSkgeworICAgICAgICByZXR1cm4ga3YubWF0Y2hpbmdGYW1pbHkodGhpcy5mYW1pbHkpOworICAgICAgfSBlbHNlIGlmICh0aGlzLm1hdGNoVHlwZSA9PSBNQVRDSF9UWVBFLlJFR0VYKSB7CisgICAgICAgIC8vIFBhc3MgYSBjb2x1bW4gd2l0aG91dCB0aGUgZGVsaW1pdGVyIHNpbmNlIHRoYXRzIHdoYXRzIHdlJ3JlCisgICAgICAgIC8vIGV4cGVjdGVkIHRvIG1hdGNoLgorICAgICAgICBpbnQgbyA9IGt2LmdldENvbHVtbk9mZnNldCgpOworICAgICAgICBpbnQgbCA9IGt2LmdldENvbHVtbkxlbmd0aChvKTsKKyAgICAgICAgU3RyaW5nIGNvbHVtbk1pbnVzUXVhbGlmaWVyID0gQnl0ZXMudG9TdHJpbmcoa3YuZ2V0QnVmZmVyKCksIG8sIGwpOworICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5NYXRjaGVyLm1hdGNoZXIoY29sdW1uTWludXNRdWFsaWZpZXIpLm1hdGNoZXMoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBtYXRjaCB0eXBlOiAiICsgdGhpcy5tYXRjaFR5cGUpOworICAgICAgfQorICAgIH0KKworICAgIGJvb2xlYW4gaXNXaWxkQ2FyZE1hdGNoKCkgeworICAgICAgcmV0dXJuIHRoaXMud2lsZENhcmRtYXRjaDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gYyBDb2x1bW4gbmFtZQorICAgICAqIEByZXR1cm4gUmV0dXJuIGFycmF5IG9mIHNpemUgdHdvIHdob3NlIGZpcnN0IGVsZW1lbnQgaGFzIHRoZSBmYW1pbHkKKyAgICAgKiBwcmVmaXggb2YgcGFzc2VkIGNvbHVtbiA8Y29kZT5jPC9jb2RlPiBhbmQgd2hvc2Ugc2Vjb25kIGVsZW1lbnQgaXMgdGhlCisgICAgICogY29sdW1uIHF1YWxpZmllci4KKyAgICAgKiBAdGhyb3dzIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbiAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJ5dGUgW11bXSBwYXJzZUNvbHVtbihmaW5hbCBieXRlIFtdIGMpCisgICAgdGhyb3dzIENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBmaW5hbCBieXRlIFtdW10gcmVzdWx0ID0gbmV3IGJ5dGUgWzJdW107CisgICAgICAvLyBUT0RPOiBDaGFuZ2UgdGhpcyBzbyBkb24ndCBkbyBwYXJzZSBidXQgaW5zdGVhZCB1c2UgdGhlIGNvbXBhcmF0b3IKKyAgICAgIC8vIGluc2lkZSBpbiBLZXlWYWx1ZSB3aGljaCBqdXN0IGxvb2tzIGF0IGNvbHVtbiBmYW1pbHkuCisgICAgICBmaW5hbCBpbnQgaW5kZXggPSBLZXlWYWx1ZS5nZXRGYW1pbHlEZWxpbWl0ZXJJbmRleChjLCAwLCBjLmxlbmd0aCk7CisgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKKyAgICAgICAgdGhyb3cgbmV3IENvbHVtbk5hbWVQYXJzZUV4Y2VwdGlvbigiSW1wb3NzaWJsZSBjb2x1bW4gbmFtZTogIiArIGMpOworICAgICAgfQorICAgICAgcmVzdWx0WzBdID0gbmV3IGJ5dGUgW2luZGV4XTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYywgMCwgcmVzdWx0WzBdLCAwLCBpbmRleCk7CisgICAgICBmaW5hbCBpbnQgbGVuID0gYy5sZW5ndGggLSAoaW5kZXggKyAxKTsKKyAgICAgIHJlc3VsdFsxXSA9IG5ldyBieXRlW2xlbl07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KGMsIGluZGV4ICsgMSAvKlNraXAgZGVsaW1pdGVyKi8sIHJlc3VsdFsxXSwgMCwKKyAgICAgICAgbGVuKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0hMb2cuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9ITG9nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNmMmE5OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9ITG9nLmphdmEKQEAgLTAsMCArMSw5NTAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRTa2lwTGlzdE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljTG9uZzsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5Mb2NrOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudExvY2s7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuU3luY2FibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5GU1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlNlcXVlbmNlRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5TZXF1ZW5jZUZpbGUuQ29tcHJlc3Npb25UeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlNlcXVlbmNlRmlsZS5NZXRhZGF0YTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5TZXF1ZW5jZUZpbGUuUmVhZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkRlZmF1bHRDb2RlYzsKKworLyoqCisgKiBITG9nIHN0b3JlcyBhbGwgdGhlIGVkaXRzIHRvIHRoZSBIU3RvcmUuCisgKgorICogSXQgcGVyZm9ybXMgbG9nZmlsZS1yb2xsaW5nLCBzbyBleHRlcm5hbCBjYWxsZXJzIGFyZSBub3QgYXdhcmUgdGhhdCB0aGUKKyAqIHVuZGVybHlpbmcgZmlsZSBpcyBiZWluZyByb2xsZWQuCisgKgorICogPHA+CisgKiBBIHNpbmdsZSBITG9nIGlzIHVzZWQgYnkgc2V2ZXJhbCBIUmVnaW9ucyBzaW11bHRhbmVvdXNseS4KKyAqCisgKiA8cD4KKyAqIEVhY2ggSFJlZ2lvbiBpcyBpZGVudGlmaWVkIGJ5IGEgdW5pcXVlIGxvbmcgPGNvZGU+aW50PC9jb2RlPi4gSFJlZ2lvbnMgZG8KKyAqIG5vdCBuZWVkIHRvIGRlY2xhcmUgdGhlbXNlbHZlcyBiZWZvcmUgdXNpbmcgdGhlIEhMb2c7IHRoZXkgc2ltcGx5IGluY2x1ZGUKKyAqIHRoZWlyIEhSZWdpb24taWQgaW4gdGhlIDxjb2RlPmFwcGVuZDwvY29kZT4gb3IKKyAqIDxjb2RlPmNvbXBsZXRlQ2FjaGVGbHVzaDwvY29kZT4gY2FsbHMuCisgKgorICogPHA+CisgKiBBbiBITG9nIGNvbnNpc3RzIG9mIG11bHRpcGxlIG9uLWRpc2sgZmlsZXMsIHdoaWNoIGhhdmUgYSBjaHJvbm9sb2dpY2FsIG9yZGVyLgorICogQXMgZGF0YSBpcyBmbHVzaGVkIHRvIG90aGVyIChiZXR0ZXIpIG9uLWRpc2sgc3RydWN0dXJlcywgdGhlIGxvZyBiZWNvbWVzCisgKiBvYnNvbGV0ZS4gV2UgY2FuIGRlc3Ryb3kgYWxsIHRoZSBsb2cgbWVzc2FnZXMgZm9yIGEgZ2l2ZW4gSFJlZ2lvbi1pZCB1cCB0bworICogdGhlIG1vc3QtcmVjZW50IENBQ0hFRkxVU0ggbWVzc2FnZSBmcm9tIHRoYXQgSFJlZ2lvbi4KKyAqCisgKiA8cD4KKyAqIEl0J3Mgb25seSBwcmFjdGljYWwgdG8gZGVsZXRlIGVudGlyZSBmaWxlcy4gVGh1cywgd2UgZGVsZXRlIGFuIGVudGlyZSBvbi1kaXNrCisgKiBmaWxlIEYgd2hlbiBhbGwgb2YgdGhlIG1lc3NhZ2VzIGluIEYgaGF2ZSBhIGxvZy1zZXF1ZW5jZS1pZCB0aGF0J3Mgb2xkZXIKKyAqIChzbWFsbGVyKSB0aGFuIHRoZSBtb3N0LXJlY2VudCBDQUNIRUZMVVNIIG1lc3NhZ2UgZm9yIGV2ZXJ5IEhSZWdpb24gdGhhdCBoYXMKKyAqIGEgbWVzc2FnZSBpbiBGLgorICoKKyAqIDxwPgorICogU3luY2hyb25pemVkIG1ldGhvZHMgY2FuIG5ldmVyIGV4ZWN1dGUgaW4gcGFyYWxsZWwuIEhvd2V2ZXIsIGJldHdlZW4gdGhlCisgKiBzdGFydCBvZiBhIGNhY2hlIGZsdXNoIGFuZCB0aGUgY29tcGxldGlvbiBwb2ludCwgYXBwZW5kcyBhcmUgYWxsb3dlZCBidXQgbG9nCisgKiByb2xsaW5nIGlzIG5vdC4gVG8gcHJldmVudCBsb2cgcm9sbGluZyB0YWtpbmcgcGxhY2UgZHVyaW5nIHRoaXMgcGVyaW9kLCBhCisgKiBzZXBhcmF0ZSByZWVudHJhbnQgbG9jayBpcyB1c2VkLgorICoKKyAqLworcHVibGljIGNsYXNzIEhMb2cgaW1wbGVtZW50cyBIQ29uc3RhbnRzLCBTeW5jYWJsZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhITG9nLmNsYXNzKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhMT0dfREFURklMRSA9ICJobG9nLmRhdC4iOworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBNRVRBQ09MVU1OID0gQnl0ZXMudG9CeXRlcygiTUVUQUNPTFVNTjoiKTsKKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gTUVUQVJPVyA9IEJ5dGVzLnRvQnl0ZXMoIk1FVEFST1ciKTsKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlU3lzdGVtIGZzOworICBwcml2YXRlIGZpbmFsIFBhdGggZGlyOworICBwcml2YXRlIGZpbmFsIENvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBmaW5hbCBMb2dSb2xsTGlzdGVuZXIgbGlzdGVuZXI7CisgIHByaXZhdGUgZmluYWwgaW50IG1heGxvZ2VudHJpZXM7CisgIHByaXZhdGUgZmluYWwgbG9uZyBvcHRpb25hbEZsdXNoSW50ZXJ2YWw7CisgIHByaXZhdGUgZmluYWwgbG9uZyBibG9ja3NpemU7CisgIHByaXZhdGUgZmluYWwgaW50IGZsdXNobG9nZW50cmllczsKKyAgcHJpdmF0ZSBmaW5hbCBBdG9taWNJbnRlZ2VyIHVuZmx1c2hlZEVudHJpZXMgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBsb25nIGxhc3RMb2dGbHVzaFRpbWU7CisKKyAgLyoKKyAgICogQ3VycmVudCBsb2cgZmlsZS4KKyAgICovCisgIFNlcXVlbmNlRmlsZS5Xcml0ZXIgd3JpdGVyOworCisgIC8qCisgICAqIE1hcCBvZiBhbGwgbG9nIGZpbGVzIGJ1dCB0aGUgY3VycmVudCBvbmUuIAorICAgKi8KKyAgZmluYWwgU29ydGVkTWFwPExvbmcsIFBhdGg+IG91dHB1dGZpbGVzID0KKyAgICBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRTb3J0ZWRNYXAobmV3IFRyZWVNYXA8TG9uZywgUGF0aD4oKSk7CisKKyAgLyoKKyAgICogTWFwIG9mIHJlZ2lvbiB0byBsYXN0IHNlcXVlbmNlL2VkaXQgaWQuIAorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50U2tpcExpc3RNYXA8Ynl0ZSBbXSwgTG9uZz4gbGFzdFNlcVdyaXR0ZW4gPQorICAgIG5ldyBDb25jdXJyZW50U2tpcExpc3RNYXA8Ynl0ZSBbXSwgTG9uZz4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisKKyAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGNsb3NlZCA9IGZhbHNlOworCisgIHByaXZhdGUgZmluYWwgQXRvbWljTG9uZyBsb2dTZXFOdW0gPSBuZXcgQXRvbWljTG9uZygwKTsKKworICBwcml2YXRlIHZvbGF0aWxlIGxvbmcgZmlsZW51bSA9IDA7CisgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyBvbGRfZmlsZW51bSA9IC0xOworICAKKyAgcHJpdmF0ZSBmaW5hbCBBdG9taWNJbnRlZ2VyIG51bUVudHJpZXMgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKKworICAvLyBUaGlzIGxvY2sgcHJldmVudHMgc3RhcnRpbmcgYSBsb2cgcm9sbCBkdXJpbmcgYSBjYWNoZSBmbHVzaC4KKyAgLy8gc3luY2hyb25pemVkIGlzIGluc3VmZmljaWVudCBiZWNhdXNlIGEgY2FjaGUgZmx1c2ggc3BhbnMgdHdvIG1ldGhvZCBjYWxscy4KKyAgcHJpdmF0ZSBmaW5hbCBMb2NrIGNhY2hlRmx1c2hMb2NrID0gbmV3IFJlZW50cmFudExvY2soKTsKKworICAvLyBXZSBzeW5jaHJvbml6ZSBvbiB1cGRhdGVMb2NrIHRvIHByZXZlbnQgdXBkYXRlcyBhbmQgdG8gcHJldmVudCBhIGxvZyByb2xsCisgIC8vIGR1cmluZyBhbiB1cGRhdGUKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgdXBkYXRlTG9jayA9IG5ldyBPYmplY3QoKTsKKyAgCisgIC8qCisgICAqIElmIG1vcmUgdGhhbiB0aGlzIG1hbnkgbG9ncywgZm9yY2UgZmx1c2ggb2Ygb2xkZXN0IHJlZ2lvbiB0byBvbGRlc3QgZWRpdAorICAgKiBnb2VzIHRvIGRpc2suICBJZiB0b28gbWFueSBhbmQgd2UgY3Jhc2gsIHRoZW4gd2lsbCB0YWtlIGZvcmV2ZXIgcmVwbGF5aW5nLgorICAgKiBLZWVwIHRoZSBudW1iZXIgb2YgbG9ncyB0aWR5LgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4TG9nczsKKworICBzdGF0aWMgYnl0ZSBbXSBDT01QTEVURV9DQUNIRV9GTFVTSDsKKyAgc3RhdGljIHsKKyAgICB0cnkgeworICAgICAgQ09NUExFVEVfQ0FDSEVfRkxVU0ggPSAiSEJBU0U6OkNBQ0hFRkxVU0giLmdldEJ5dGVzKFVURjhfRU5DT0RJTkcpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgYXNzZXJ0KGZhbHNlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGFuIGVkaXQgbG9nIGF0IHRoZSBnaXZlbiA8Y29kZT5kaXI8L2NvZGU+IGxvY2F0aW9uLgorICAgKgorICAgKiBZb3Ugc2hvdWxkIG5ldmVyIGhhdmUgdG8gbG9hZCBhbiBleGlzdGluZyBsb2cuIElmIHRoZXJlIGlzIGEgbG9nIGF0CisgICAqIHN0YXJ0dXAsIGl0IHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgYW5kIGRlbGV0ZWQgYnkgdGhlIHRpbWUgdGhlCisgICAqIEhMb2cgb2JqZWN0IGlzIHN0YXJ0ZWQgdXAuCisgICAqCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gZGlyCisgICAqIEBwYXJhbSBjb25mCisgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSExvZyhmaW5hbCBGaWxlU3lzdGVtIGZzLCBmaW5hbCBQYXRoIGRpciwgZmluYWwgQ29uZmlndXJhdGlvbiBjb25mLAorICAgIGZpbmFsIExvZ1JvbGxMaXN0ZW5lciBsaXN0ZW5lcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuZnMgPSBmczsKKyAgICB0aGlzLmRpciA9IGRpcjsKKyAgICB0aGlzLmNvbmYgPSBjb25mOworICAgIHRoaXMubGlzdGVuZXIgPSBsaXN0ZW5lcjsKKyAgICB0aGlzLm1heGxvZ2VudHJpZXMgPQorICAgICAgY29uZi5nZXRJbnQoImhiYXNlLnJlZ2lvbnNlcnZlci5tYXhsb2dlbnRyaWVzIiwgMTAwMDAwKTsKKyAgICB0aGlzLmZsdXNobG9nZW50cmllcyA9CisgICAgICBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmZsdXNobG9nZW50cmllcyIsIDEwMCk7CisgICAgdGhpcy5ibG9ja3NpemUgPSBjb25mLmdldExvbmcoImhiYXNlLnJlZ2lvbnNlcnZlci5obG9nLmJsb2Nrc2l6ZSIsCisgICAgICB0aGlzLmZzLmdldERlZmF1bHRCbG9ja1NpemUoKSk7CisgICAgdGhpcy5vcHRpb25hbEZsdXNoSW50ZXJ2YWwgPQorICAgICAgY29uZi5nZXRMb25nKCJoYmFzZS5yZWdpb25zZXJ2ZXIub3B0aW9uYWxsb2dmbHVzaGludGVydmFsIiwgMTAgKiAxMDAwKTsKKyAgICB0aGlzLmxhc3RMb2dGbHVzaFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBpZiAoZnMuZXhpc3RzKGRpcikpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVGFyZ2V0IEhMb2cgZGlyZWN0b3J5IGFscmVhZHkgZXhpc3RzOiAiICsgZGlyKTsKKyAgICB9CisgICAgZnMubWtkaXJzKGRpcik7CisgICAgdGhpcy5tYXhMb2dzID0gY29uZi5nZXRJbnQoImhiYXNlLnJlZ2lvbnNlcnZlci5tYXhsb2dzIiwgNjQpOworICAgIExPRy5pbmZvKCJITG9nIGNvbmZpZ3VyYXRpb246IGJsb2Nrc2l6ZT0iICsgdGhpcy5ibG9ja3NpemUgKworICAgICAgIiwgbWF4bG9nZW50cmllcz0iICsgdGhpcy5tYXhsb2dlbnRyaWVzICsgIiwgZmx1c2hsb2dlbnRyaWVzPSIgKworICAgICAgdGhpcy5mbHVzaGxvZ2VudHJpZXMgKyAiLCBvcHRpb25hbGxvZ2ZsdXNoaW50ZXJuYWw9IiArCisgICAgICB0aGlzLm9wdGlvbmFsRmx1c2hJbnRlcnZhbCArICJtcyIpOworICAgIHJvbGxXcml0ZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBBY2Nlc3NvciBmb3IgdGVzdHMuIE5vdCBhIHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkuCisgICAqIEByZXR1cm4gQ3VycmVudCBzdGF0ZSBvZiB0aGUgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nIGZpbGUgaWQuCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRGaWxlbnVtKCkgeworICAgIHJldHVybiB0aGlzLmZpbGVudW07CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBjb21wcmVzc2lvbiB0eXBlIGZvciB0aGUgaGxvZyBmaWxlcy4KKyAgICogQ29tbWl0IGxvZ3MgU0hPVUxEIE5PVCBiZSBjb21wcmVzc2VkLiAgWW91J2xsIGxvc2UgZWRpdHMgaWYgdGhlIGNvbXByZXNzaW9uCisgICAqIHJlY29yZCBpcyBub3QgY29tcGxldGUuICBJbiBnemlwLCByZWNvcmQgaXMgMzJrIHNvIHlvdSBjb3VsZCBsb3NlIHVwIHRvCisgICAqIDMyayBvZiBlZGl0cyAoQWxsIG9mIHRoaXMgaXMgbW9vdCB0aWxsIHdlIGhhdmUgc3luYy9mbHVzaCBpbiBoZGZzIGJ1dAorICAgKiBzdGlsbC4uLikuCisgICAqIEBwYXJhbSBjIENvbmZpZ3VyYXRpb24gdG8gdXNlLgorICAgKiBAcmV0dXJuIHRoZSBraW5kIG9mIGNvbXByZXNzaW9uIHRvIHVzZQorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgQ29tcHJlc3Npb25UeXBlIGdldENvbXByZXNzaW9uVHlwZShmaW5hbCBDb25maWd1cmF0aW9uIGMpIHsKKyAgICBTdHJpbmcgbmFtZSA9IGMuZ2V0KCJoYmFzZS5pby5zZXFmaWxlLmNvbXByZXNzaW9uLnR5cGUiKTsKKyAgICByZXR1cm4gbmFtZSA9PSBudWxsPyBDb21wcmVzc2lvblR5cGUuTk9ORTogQ29tcHJlc3Npb25UeXBlLnZhbHVlT2YobmFtZSk7CisgIH0KKworICAvKioKKyAgICogQ2FsbGVkIGJ5IEhSZWdpb25TZXJ2ZXIgd2hlbiBpdCBvcGVucyBhIG5ldyByZWdpb24gdG8gZW5zdXJlIHRoYXQgbG9nCisgICAqIHNlcXVlbmNlIG51bWJlcnMgYXJlIGFsd2F5cyBncmVhdGVyIHRoYW4gdGhlIGxhdGVzdCBzZXF1ZW5jZSBudW1iZXIgb2YgdGhlCisgICAqIHJlZ2lvbiBiZWluZyBicm91Z2h0IG9uLWxpbmUuCisgICAqCisgICAqIEBwYXJhbSBuZXd2YWx1ZSBXZSdsbCBzZXQgbG9nIGVkaXQvc2VxdWVuY2UgbnVtYmVyIHRvIHRoaXMgdmFsdWUgaWYgaXQKKyAgICogaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHZhbHVlLgorICAgKi8KKyAgdm9pZCBzZXRTZXF1ZW5jZU51bWJlcihmaW5hbCBsb25nIG5ld3ZhbHVlKSB7CisgICAgZm9yIChsb25nIGlkID0gdGhpcy5sb2dTZXFOdW0uZ2V0KCk7IGlkIDwgbmV3dmFsdWUgJiYKKyAgICAgICAgIXRoaXMubG9nU2VxTnVtLmNvbXBhcmVBbmRTZXQoaWQsIG5ld3ZhbHVlKTsgaWQgPSB0aGlzLmxvZ1NlcU51bS5nZXQoKSkgeworICAgICAgLy8gVGhpcyBjb3VsZCBzcGluIG9uIG9jY2FzaW9uIGJ1dCBiZXR0ZXIgdGhlIG9jY2FzaW9uYWwgc3BpbiB0aGFuIGxvY2tpbmcKKyAgICAgIC8vIGV2ZXJ5IGluY3JlbWVudCBvZiBzZXF1ZW5jZSBudW1iZXIuCisgICAgICBMT0cuZGVidWcoIkNoYW5nZSBzZXF1ZW5jZSBudW1iZXIgZnJvbSAiICsgbG9nU2VxTnVtICsgIiB0byAiICsgbmV3dmFsdWUpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEByZXR1cm4gbG9nIHNlcXVlbmNlIG51bWJlcgorICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0U2VxdWVuY2VOdW1iZXIoKSB7CisgICAgcmV0dXJuIGxvZ1NlcU51bS5nZXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBSb2xsIHRoZSBsb2cgd3JpdGVyLiBUaGF0IGlzLCBzdGFydCB3cml0aW5nIGxvZyBtZXNzYWdlcyB0byBhIG5ldyBmaWxlLgorICAgKgorICAgKiBCZWNhdXNlIGEgbG9nIGNhbm5vdCBiZSByb2xsZWQgZHVyaW5nIGEgY2FjaGUgZmx1c2gsIGFuZCBhIGNhY2hlIGZsdXNoCisgICAqIHNwYW5zIHR3byBtZXRob2QgY2FsbHMsIGEgc3BlY2lhbCBsb2NrIG5lZWRzIHRvIGJlIG9idGFpbmVkIHNvIHRoYXQgYSBjYWNoZQorICAgKiBmbHVzaCBjYW5ub3Qgc3RhcnQgd2hlbiB0aGUgbG9nIGlzIGJlaW5nIHJvbGxlZCBhbmQgdGhlIGxvZyBjYW5ub3QgYmUKKyAgICogcm9sbGVkIGR1cmluZyBhIGNhY2hlIGZsdXNoLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2QgY2Fubm90IGJlIHN5bmNocm9uaXplZCBiZWNhdXNlIGl0IGlzIHBvc3NpYmxlIHRoYXQKKyAgICogc3RhcnRDYWNoZUZsdXNoIHJ1bnMsIG9idGFpbmluZyB0aGUgY2FjaGVGbHVzaExvY2ssIHRoZW4gdGhpcyBtZXRob2QgY291bGQKKyAgICogc3RhcnQgd2hpY2ggd291bGQgb2J0YWluIHRoZSBsb2NrIG9uIHRoaXMgYnV0IGJsb2NrIG9uIG9idGFpbmluZyB0aGUKKyAgICogY2FjaGVGbHVzaExvY2sgYW5kIHRoZW4gY29tcGxldGVDYWNoZUZsdXNoIGNvdWxkIGJlIGNhbGxlZCB3aGljaCB3b3VsZCB3YWl0CisgICAqIGZvciB0aGUgbG9jayBvbiB0aGlzIGFuZCBjb25zZXF1ZW50bHkgbmV2ZXIgcmVsZWFzZSB0aGUgY2FjaGVGbHVzaExvY2sKKyAgICoKKyAgICogQHJldHVybiBJZiBsb3RzIG9mIGxvZ3MsIGZsdXNoIHRoZSByZXR1cm5lZCByZWdpb24gc28gbmV4dCB0aW1lIHRocm91Z2gKKyAgICogd2UgY2FuIGNsZWFuIGxvZ3MuIFJldHVybnMgbnVsbCBpZiBub3RoaW5nIHRvIGZsdXNoLgorICAgKiBAdGhyb3dzIEZhaWxlZExvZ0Nsb3NlRXhjZXB0aW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBieXRlIFtdIHJvbGxXcml0ZXIoKSB0aHJvd3MgRmFpbGVkTG9nQ2xvc2VFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICBieXRlIFtdIHJlZ2lvblRvRmx1c2ggPSBudWxsOworICAgIHRoaXMuY2FjaGVGbHVzaExvY2subG9jaygpOworICAgIHRyeSB7CisgICAgICBpZiAoY2xvc2VkKSB7CisgICAgICAgIHJldHVybiByZWdpb25Ub0ZsdXNoOworICAgICAgfQorICAgICAgc3luY2hyb25pemVkICh1cGRhdGVMb2NrKSB7CisgICAgICAgIC8vIENsZWFuIHVwIGN1cnJlbnQgd3JpdGVyLgorICAgICAgICBQYXRoIG9sZEZpbGUgPSBjbGVhbnVwQ3VycmVudFdyaXRlcigpOworICAgICAgICAvLyBDcmVhdGUgYSBuZXcgb25lLgorICAgICAgICB0aGlzLm9sZF9maWxlbnVtID0gdGhpcy5maWxlbnVtOworICAgICAgICB0aGlzLmZpbGVudW0gPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgUGF0aCBuZXdQYXRoID0gY29tcHV0ZUZpbGVuYW1lKHRoaXMuZmlsZW51bSk7CisKKyAgICAgICAgdGhpcy53cml0ZXIgPSBTZXF1ZW5jZUZpbGUuY3JlYXRlV3JpdGVyKHRoaXMuZnMsIHRoaXMuY29uZiwgbmV3UGF0aCwKKyAgICAgICAgICBITG9nS2V5LmNsYXNzLCBLZXlWYWx1ZS5jbGFzcywKKyAgICAgICAgICBmcy5nZXRDb25mKCkuZ2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNDA5NiksCisgICAgICAgICAgZnMuZ2V0RGVmYXVsdFJlcGxpY2F0aW9uKCksIHRoaXMuYmxvY2tzaXplLAorICAgICAgICAgIFNlcXVlbmNlRmlsZS5Db21wcmVzc2lvblR5cGUuTk9ORSwgbmV3IERlZmF1bHRDb2RlYygpLCBudWxsLAorICAgICAgICAgIG5ldyBNZXRhZGF0YSgpKTsKKworICAgICAgICBMT0cuaW5mbygob2xkRmlsZSAhPSBudWxsPworICAgICAgICAgICJDbG9zZWQgIiArIG9sZEZpbGUgKyAiLCBlbnRyaWVzPSIgKyB0aGlzLm51bUVudHJpZXMuZ2V0KCkgKyAiLiAiOiAiIikgKworICAgICAgICAgICJOZXcgbG9nIHdyaXRlcjogIiArIEZTVXRpbHMuZ2V0UGF0aChuZXdQYXRoKSk7CisKKyAgICAgICAgLy8gQ2FuIHdlIGRlbGV0ZSBhbnkgb2YgdGhlIG9sZCBsb2cgZmlsZXM/CisgICAgICAgIGlmICh0aGlzLm91dHB1dGZpbGVzLnNpemUoKSA+IDApIHsKKyAgICAgICAgICBpZiAodGhpcy5sYXN0U2VxV3JpdHRlbi5zaXplKCkgPD0gMCkgeworICAgICAgICAgICAgTE9HLmRlYnVnKCJMYXN0IHNlcXVlbmNlIHdyaXR0ZW4gaXMgZW1wdHkuIERlbGV0aW5nIGFsbCBvbGQgaGxvZ3MiKTsKKyAgICAgICAgICAgIC8vIElmIHNvLCB0aGVuIG5vIG5ldyB3cml0ZXMgaGF2ZSBjb21lIGluIHNpbmNlIGFsbCByZWdpb25zIHdlcmUKKyAgICAgICAgICAgIC8vIGZsdXNoZWQgKGFuZCByZW1vdmVkIGZyb20gdGhlIGxhc3RTZXFXcml0dGVuIG1hcCkuIE1lYW5zIGNhbgorICAgICAgICAgICAgLy8gcmVtb3ZlIGFsbCBidXQgY3VycmVudGx5IG9wZW4gbG9nIGZpbGUuCisgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxMb25nLCBQYXRoPiBlIDogdGhpcy5vdXRwdXRmaWxlcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICAgIGRlbGV0ZUxvZ0ZpbGUoZS5nZXRWYWx1ZSgpLCBlLmdldEtleSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHRoaXMub3V0cHV0ZmlsZXMuY2xlYXIoKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVnaW9uVG9GbHVzaCA9IGNsZWFuT2xkTG9ncygpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aGlzLm51bUVudHJpZXMuc2V0KDApOworICAgICAgICB1cGRhdGVMb2NrLm5vdGlmeUFsbCgpOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmNhY2hlRmx1c2hMb2NrLnVubG9jaygpOworICAgIH0KKyAgICByZXR1cm4gcmVnaW9uVG9GbHVzaDsKKyAgfQorICAKKyAgLyoKKyAgICogQ2xlYW4gdXAgb2xkIGNvbW1pdCBsb2dzLgorICAgKiBAcmV0dXJuIElmIGxvdHMgb2YgbG9ncywgZmx1c2ggdGhlIHJldHVybmVkIHJlZ2lvbiBzbyBuZXh0IHRpbWUgdGhyb3VnaAorICAgKiB3ZSBjYW4gY2xlYW4gbG9ncy4gUmV0dXJucyBudWxsIGlmIG5vdGhpbmcgdG8gZmx1c2guCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgYnl0ZSBbXSBjbGVhbk9sZExvZ3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW10gcmVnaW9uVG9GbHVzaCA9IG51bGw7CisgICAgTG9uZyBvbGRlc3RPdXRzdGFuZGluZ1NlcU51bSA9IGdldE9sZGVzdE91dHN0YW5kaW5nU2VxTnVtKCk7CisgICAgLy8gR2V0IHRoZSBzZXQgb2YgYWxsIGxvZyBmaWxlcyB3aG9zZSBmaW5hbCBJRCBpcyBvbGRlciB0aGFuIG9yCisgICAgLy8gZXF1YWwgdG8gdGhlIG9sZGVzdCBwZW5kaW5nIHJlZ2lvbiBvcGVyYXRpb24KKyAgICBUcmVlU2V0PExvbmc+IHNlcXVlbmNlTnVtYmVycyA9CisgICAgICBuZXcgVHJlZVNldDxMb25nPih0aGlzLm91dHB1dGZpbGVzLmhlYWRNYXAoCisgICAgICAgIChMb25nLnZhbHVlT2Yob2xkZXN0T3V0c3RhbmRpbmdTZXFOdW0ubG9uZ1ZhbHVlKCkgKyAxTCkpKS5rZXlTZXQoKSk7CisgICAgLy8gTm93IHJlbW92ZSBvbGQgbG9nIGZpbGVzIChpZiBhbnkpCisgICAgYnl0ZSBbXSBvbGRlc3RSZWdpb24gPSBudWxsOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgLy8gRmluZCByZWdpb24gYXNzb2NpYXRlZCB3aXRoIG9sZGVzdCBrZXkgLS0gaGVscHMgZGVidWdnaW5nLgorICAgICAgb2xkZXN0UmVnaW9uID0gZ2V0T2xkZXN0UmVnaW9uKG9sZGVzdE91dHN0YW5kaW5nU2VxTnVtKTsKKyAgICAgIExPRy5kZWJ1ZygiRm91bmQgIiArIHNlcXVlbmNlTnVtYmVycy5zaXplKCkgKyAiIGxvZ3MgdG8gcmVtb3ZlICIgKworICAgICAgICAiIG91dCBvZiB0b3RhbCAiICsgdGhpcy5vdXRwdXRmaWxlcy5zaXplKCkgKyAiOyAiICsKKyAgICAgICAgIm9sZGVzdCBvdXRzdGFuZGluZyBzZXFudW0gaXMgIiArIG9sZGVzdE91dHN0YW5kaW5nU2VxTnVtICsKKyAgICAgICAgIiBmcm9tIHJlZ2lvbiAiICsgQnl0ZXMudG9TdHJpbmcob2xkZXN0UmVnaW9uKSk7CisgICAgfQorICAgIGlmIChzZXF1ZW5jZU51bWJlcnMuc2l6ZSgpID4gMCkgeworICAgICAgZm9yIChMb25nIHNlcSA6IHNlcXVlbmNlTnVtYmVycykgeworICAgICAgICBkZWxldGVMb2dGaWxlKHRoaXMub3V0cHV0ZmlsZXMucmVtb3ZlKHNlcSksIHNlcSk7CisgICAgICB9CisgICAgfQorICAgIGludCBjb3VudE9mTG9ncyA9IHRoaXMub3V0cHV0ZmlsZXMuc2l6ZSgpIC0gc2VxdWVuY2VOdW1iZXJzLnNpemUoKTsKKyAgICBpZiAoY291bnRPZkxvZ3MgPiB0aGlzLm1heExvZ3MpIHsKKyAgICAgIHJlZ2lvblRvRmx1c2ggPSBvbGRlc3RSZWdpb24gIT0gbnVsbD8KKyAgICAgICAgb2xkZXN0UmVnaW9uOiBnZXRPbGRlc3RSZWdpb24ob2xkZXN0T3V0c3RhbmRpbmdTZXFOdW0pOworICAgICAgTE9HLmluZm8oIlRvbyBtYW55IGxvZ3M6IGxvZ3M9IiArIGNvdW50T2ZMb2dzICsgIiwgbWF4bG9ncz0iICsKKyAgICAgICAgdGhpcy5tYXhMb2dzICsgIjsgZm9yY2luZyBmbHVzaCBvZiByZWdpb24gd2l0aCBvbGRlc3QgZWRpdHM6ICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhyZWdpb25Ub0ZsdXNoKSk7CisgICAgfQorICAgIHJldHVybiByZWdpb25Ub0ZsdXNoOworICB9CisKKyAgLyoKKyAgICogQHJldHVybiBMb2dzIG9sZGVyIHRoYW4gdGhpcyBpZCBhcmUgc2FmZSB0byByZW1vdmUuCisgICAqLworICBwcml2YXRlIExvbmcgZ2V0T2xkZXN0T3V0c3RhbmRpbmdTZXFOdW0oKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLm1pbih0aGlzLmxhc3RTZXFXcml0dGVuLnZhbHVlcygpKTsKKyAgfQorCisgIHByaXZhdGUgYnl0ZSBbXSBnZXRPbGRlc3RSZWdpb24oZmluYWwgTG9uZyBvbGRlc3RPdXRzdGFuZGluZ1NlcU51bSkgeworICAgIGJ5dGUgW10gb2xkZXN0UmVnaW9uID0gbnVsbDsKKyAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBMb25nPiBlOiB0aGlzLmxhc3RTZXFXcml0dGVuLmVudHJ5U2V0KCkpIHsKKyAgICAgIGlmIChlLmdldFZhbHVlKCkubG9uZ1ZhbHVlKCkgPT0gb2xkZXN0T3V0c3RhbmRpbmdTZXFOdW0ubG9uZ1ZhbHVlKCkpIHsKKyAgICAgICAgb2xkZXN0UmVnaW9uID0gZS5nZXRLZXkoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBvbGRlc3RSZWdpb247CisgIH0KKworICAvKgorICAgKiBDbGVhbnMgdXAgY3VycmVudCB3cml0ZXIgY2xvc2luZyBhbmQgYWRkaW5nIHRvIG91dHB1dGZpbGVzLgorICAgKiBQcmVzdW1lcyB3ZSdyZSBvcGVyYXRpbmcgaW5zaWRlIGFuIHVwZGF0ZUxvY2sgc2NvcGUuCisgICAqIEByZXR1cm4gUGF0aCB0byBjdXJyZW50IHdyaXRlciBvciBudWxsIGlmIG5vbmUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgUGF0aCBjbGVhbnVwQ3VycmVudFdyaXRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBvbGRGaWxlID0gbnVsbDsKKyAgICBpZiAodGhpcy53cml0ZXIgIT0gbnVsbCkgeworICAgICAgLy8gQ2xvc2UgdGhlIGN1cnJlbnQgd3JpdGVyLCBnZXQgYSBuZXcgb25lLgorICAgICAgdHJ5IHsKKyAgICAgICAgdGhpcy53cml0ZXIuY2xvc2UoKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gRmFpbGVkIGNsb3NlIG9mIGxvZyBmaWxlLiAgTWVhbnMgd2UncmUgbG9zaW5nIGVkaXRzLiAgRm9yIG5vdywKKyAgICAgICAgLy8gc2h1dCBvdXJzZWx2ZXMgZG93biB0byBtaW5pbWl6ZSBsb3NzLiAgQWx0ZXJuYXRpdmUgaXMgdG8gdHJ5IGFuZAorICAgICAgICAvLyBrZWVwIGdvaW5nLiAgU2VlIEhCQVNFLTkzMC4KKyAgICAgICAgRmFpbGVkTG9nQ2xvc2VFeGNlcHRpb24gZmxjZSA9CisgICAgICAgICAgbmV3IEZhaWxlZExvZ0Nsb3NlRXhjZXB0aW9uKCIjIiArIHRoaXMuZmlsZW51bSk7CisgICAgICAgIGZsY2UuaW5pdENhdXNlKGUpOworICAgICAgICB0aHJvdyBlOyAKKyAgICAgIH0KKyAgICAgIG9sZEZpbGUgPSBjb21wdXRlRmlsZW5hbWUob2xkX2ZpbGVudW0pOworICAgICAgaWYgKGZpbGVudW0gPiAwKSB7CisgICAgICAgIHRoaXMub3V0cHV0ZmlsZXMucHV0KExvbmcudmFsdWVPZih0aGlzLmxvZ1NlcU51bS5nZXQoKSAtIDEpLCBvbGRGaWxlKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG9sZEZpbGU7CisgIH0KKworICBwcml2YXRlIHZvaWQgZGVsZXRlTG9nRmlsZShmaW5hbCBQYXRoIHAsIGZpbmFsIExvbmcgc2Vxbm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTE9HLmluZm8oInJlbW92aW5nIG9sZCBsb2cgZmlsZSAiICsgRlNVdGlscy5nZXRQYXRoKHApICsKKyAgICAgICIgd2hvc2UgaGlnaGVzdCBzZXF1ZW5jZS9lZGl0IGlkIGlzICIgKyBzZXFubyk7CisgICAgdGhpcy5mcy5kZWxldGUocCwgdHJ1ZSk7CisgIH0KKworICAvKioKKyAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGNvbXB1dGVzIGEgbmV3IGZpbGVuYW1lIHdpdGggYSBnaXZlbgorICAgKiBmaWxlLW51bWJlci4KKyAgICogQHBhcmFtIGZuCisgICAqIEByZXR1cm4gUGF0aAorICAgKi8KKyAgcHVibGljIFBhdGggY29tcHV0ZUZpbGVuYW1lKGZpbmFsIGxvbmcgZm4pIHsKKyAgICByZXR1cm4gbmV3IFBhdGgoZGlyLCBITE9HX0RBVEZJTEUgKyBmbik7CisgIH0KKworICAvKioKKyAgICogU2h1dCBkb3duIHRoZSBsb2cgYW5kIGRlbGV0ZSB0aGUgbG9nIGRpcmVjdG9yeQorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBjbG9zZUFuZERlbGV0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2xvc2UoKTsKKyAgICBmcy5kZWxldGUoZGlyLCB0cnVlKTsKKyAgfQorCisgIC8qKgorICAgKiBTaHV0IGRvd24gdGhlIGxvZy4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNhY2hlRmx1c2hMb2NrLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgc3luY2hyb25pemVkICh1cGRhdGVMb2NrKSB7CisgICAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZTsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJjbG9zaW5nIGxvZyB3cml0ZXIgaW4gIiArIHRoaXMuZGlyLnRvU3RyaW5nKCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMud3JpdGVyLmNsb3NlKCk7CisgICAgICAgIHVwZGF0ZUxvY2subm90aWZ5QWxsKCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGNhY2hlRmx1c2hMb2NrLnVubG9jaygpOworICAgIH0KKyAgfQorCisKKyAgLyoqIEFwcGVuZCBhbiBlbnRyeSB3aXRob3V0IGEgcm93IHRvIHRoZSBsb2cuCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKiBAcGFyYW0gbG9nRWRpdAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBhcHBlbmQoSFJlZ2lvbkluZm8gcmVnaW9uSW5mbywgS2V5VmFsdWUgbG9nRWRpdCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmFwcGVuZChyZWdpb25JbmZvLCBuZXcgYnl0ZVswXSwgbG9nRWRpdCk7CisgIH0KKworICAvKiogQXBwZW5kIGFuIGVudHJ5IHRvIHRoZSBsb2cuCisgICAqIAorICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBsb2dFZGl0CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGFwcGVuZChIUmVnaW9uSW5mbyByZWdpb25JbmZvLCBieXRlIFtdIHJvdywgS2V5VmFsdWUgbG9nRWRpdCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5jbG9zZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IGFwcGVuZDsgbG9nIGlzIGNsb3NlZCIpOworICAgIH0KKyAgICBieXRlIFtdIHJlZ2lvbk5hbWUgPSByZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKTsKKyAgICBieXRlIFtdIHRhYmxlTmFtZSA9IHJlZ2lvbkluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpOworICAgIHN5bmNocm9uaXplZCAodXBkYXRlTG9jaykgeworICAgICAgbG9uZyBzZXFOdW0gPSBvYnRhaW5TZXFOdW0oKTsKKyAgICAgIC8vIFRoZSAnbGFzdFNlcVdyaXR0ZW4nIG1hcCBob2xkcyB0aGUgc2VxdWVuY2UgbnVtYmVyIG9mIHRoZSBvbGRlc3QKKyAgICAgIC8vIHdyaXRlIGZvciBlYWNoIHJlZ2lvbi4gV2hlbiB0aGUgY2FjaGUgaXMgZmx1c2hlZCwgdGhlIGVudHJ5IGZvciB0aGUKKyAgICAgIC8vIHJlZ2lvbiBiZWluZyBmbHVzaGVkIGlzIHJlbW92ZWQgaWYgdGhlIHNlcXVlbmNlIG51bWJlciBvZiB0aGUgZmx1c2gKKyAgICAgIC8vIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgdmFsdWUgaW4gbGFzdFNlcVdyaXR0ZW4uCisgICAgICB0aGlzLmxhc3RTZXFXcml0dGVuLnB1dElmQWJzZW50KHJlZ2lvbk5hbWUsIExvbmcudmFsdWVPZihzZXFOdW0pKTsKKyAgICAgIEhMb2dLZXkgbG9nS2V5ID0gbmV3IEhMb2dLZXkocmVnaW9uTmFtZSwgdGFibGVOYW1lLCBzZXFOdW0pOworICAgICAgYm9vbGVhbiBzeW5jID0gcmVnaW9uSW5mby5pc01ldGFSZWdpb24oKSB8fCByZWdpb25JbmZvLmlzUm9vdFJlZ2lvbigpOworICAgICAgZG9Xcml0ZShsb2dLZXksIGxvZ0VkaXQsIHN5bmMpOworICAgICAgdGhpcy5udW1FbnRyaWVzLmluY3JlbWVudEFuZEdldCgpOworICAgICAgdXBkYXRlTG9jay5ub3RpZnlBbGwoKTsKKyAgICB9CisKKyAgICBpZiAodGhpcy5udW1FbnRyaWVzLmdldCgpID4gdGhpcy5tYXhsb2dlbnRyaWVzKSB7CisgICAgICBpZiAobGlzdGVuZXIgIT0gbnVsbCkgeworICAgICAgICBsaXN0ZW5lci5sb2dSb2xsUmVxdWVzdGVkKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEFwcGVuZCBhIHNldCBvZiBlZGl0cyB0byB0aGUgbG9nLiBMb2cgZWRpdHMgYXJlIGtleWVkIGJ5IHJlZ2lvbk5hbWUsCisgICAqIHJvd25hbWUsIGFuZCBsb2ctc2VxdWVuY2UtaWQuCisgICAqCisgICAqIExhdGVyLCBpZiB3ZSBzb3J0IGJ5IHRoZXNlIGtleXMsIHdlIG9idGFpbiBhbGwgdGhlIHJlbGV2YW50IGVkaXRzIGZvciBhCisgICAqIGdpdmVuIGtleS1yYW5nZSBvZiB0aGUgSFJlZ2lvbiAoVE9ETykuIEFueSBlZGl0cyB0aGF0IGRvIG5vdCBoYXZlIGEKKyAgICogbWF0Y2hpbmcge0BsaW5rIEhDb25zdGFudHMjQ09NUExFVEVfQ0FDSEVGTFVTSH0gbWVzc2FnZSBjYW4gYmUgZGlzY2FyZGVkLgorICAgKgorICAgKiA8cD4KKyAgICogTG9ncyBjYW5ub3QgYmUgcmVzdGFydGVkIG9uY2UgY2xvc2VkLCBvciBvbmNlIHRoZSBITG9nIHByb2Nlc3MgZGllcy4gRWFjaAorICAgKiB0aW1lIHRoZSBITG9nIHN0YXJ0cywgaXQgbXVzdCBjcmVhdGUgYSBuZXcgbG9nLiBUaGlzIG1lYW5zIHRoYXQgb3RoZXIKKyAgICogc3lzdGVtcyBzaG91bGQgcHJvY2VzcyB0aGUgbG9nIGFwcHJvcHJpYXRlbHkgdXBvbiBlYWNoIHN0YXJ0dXAgKGFuZCBwcmlvcgorICAgKiB0byBpbml0aWFsaXppbmcgSExvZykuCisgICAqCisgICAqIHN5bmNocm9uaXplZCBwcmV2ZW50cyBhcHBlbmRzIGR1cmluZyB0aGUgY29tcGxldGlvbiBvZiBhIGNhY2hlIGZsdXNoIG9yIGZvcgorICAgKiB0aGUgZHVyYXRpb24gb2YgYSBsb2cgcm9sbC4KKyAgICoKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcGFyYW0gZWRpdHMKKyAgICogQHBhcmFtIHN5bmMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgdm9pZCBhcHBlbmQoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHRhYmxlTmFtZSwgTGlzdDxLZXlWYWx1ZT4gZWRpdHMsCisgICAgYm9vbGVhbiBzeW5jKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLmNsb3NlZCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDYW5ub3QgYXBwZW5kOyBsb2cgaXMgY2xvc2VkIik7CisgICAgfQorICAgIGxvbmcgc2VxTnVtIFtdID0gb2J0YWluU2VxTnVtKGVkaXRzLnNpemUoKSk7CisgICAgc3luY2hyb25pemVkICh0aGlzLnVwZGF0ZUxvY2spIHsKKyAgICAgIC8vIFRoZSAnbGFzdFNlcVdyaXR0ZW4nIG1hcCBob2xkcyB0aGUgc2VxdWVuY2UgbnVtYmVyIG9mIHRoZSBvbGRlc3QKKyAgICAgIC8vIHdyaXRlIGZvciBlYWNoIHJlZ2lvbi4gV2hlbiB0aGUgY2FjaGUgaXMgZmx1c2hlZCwgdGhlIGVudHJ5IGZvciB0aGUKKyAgICAgIC8vIHJlZ2lvbiBiZWluZyBmbHVzaGVkIGlzIHJlbW92ZWQgaWYgdGhlIHNlcXVlbmNlIG51bWJlciBvZiB0aGUgZmx1c2gKKyAgICAgIC8vIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgdmFsdWUgaW4gbGFzdFNlcVdyaXR0ZW4uCisgICAgICB0aGlzLmxhc3RTZXFXcml0dGVuLnB1dElmQWJzZW50KHJlZ2lvbk5hbWUsIExvbmcudmFsdWVPZihzZXFOdW1bMF0pKTsKKyAgICAgIGludCBjb3VudGVyID0gMDsKKyAgICAgIGZvciAoS2V5VmFsdWUga3Y6IGVkaXRzKSB7CisgICAgICAgIEhMb2dLZXkgbG9nS2V5ID0gbmV3IEhMb2dLZXkocmVnaW9uTmFtZSwgdGFibGVOYW1lLCBzZXFOdW1bY291bnRlcisrXSk7CisgICAgICAgIGRvV3JpdGUobG9nS2V5LCBrdiwgc3luYyk7CisgICAgICAgIHRoaXMubnVtRW50cmllcy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgIH0KKyAgICAgIHVwZGF0ZUxvY2subm90aWZ5QWxsKCk7CisgICAgfQorICAgIGlmICh0aGlzLm51bUVudHJpZXMuZ2V0KCkgPiB0aGlzLm1heGxvZ2VudHJpZXMpIHsKKyAgICAgICAgcmVxdWVzdExvZ1JvbGwoKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBzeW5jKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsYXN0TG9nRmx1c2hUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgdGhpcy53cml0ZXIuc3luYygpOworICAgIHRoaXMudW5mbHVzaGVkRW50cmllcy5zZXQoMCk7CisgIH0KKworICB2b2lkIG9wdGlvbmFsU3luYygpIHsKKyAgICBpZiAoIXRoaXMuY2xvc2VkKSB7CisgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgc3luY2hyb25pemVkICh1cGRhdGVMb2NrKSB7CisgICAgICAgIGlmICgoKG5vdyAtIHRoaXMub3B0aW9uYWxGbHVzaEludGVydmFsKSA+CisgICAgICAgICAgICB0aGlzLmxhc3RMb2dGbHVzaFRpbWUpICYmIHRoaXMudW5mbHVzaGVkRW50cmllcy5nZXQoKSA+IDApIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgc3luYygpOworICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIExPRy5lcnJvcigiRXJyb3IgZmx1c2hpbmcgSExvZyIsIGUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgbG9uZyB0b29rID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBub3c7CisgICAgICBpZiAodG9vayA+IDEwMDApIHsKKyAgICAgICAgTE9HLndhcm4oVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiIHRvb2sgIiArIHRvb2sgKworICAgICAgICAgICJtcyBvcHRpb25hbCBzeW5jJ2luZyBITG9nOyBlZGl0Y291bnQ9IiArIHRoaXMubnVtRW50cmllcy5nZXQoKSk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHZvaWQgcmVxdWVzdExvZ1JvbGwoKSB7CisgICAgaWYgKHRoaXMubGlzdGVuZXIgIT0gbnVsbCkgeworICAgICAgdGhpcy5saXN0ZW5lci5sb2dSb2xsUmVxdWVzdGVkKCk7CisgICAgfQorICB9CisgIAorICBwcml2YXRlIHZvaWQgZG9Xcml0ZShITG9nS2V5IGxvZ0tleSwgS2V5VmFsdWUgbG9nRWRpdCwgYm9vbGVhbiBzeW5jKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgdGhpcy53cml0ZXIuYXBwZW5kKGxvZ0tleSwgbG9nRWRpdCk7CisgICAgICBpZiAoc3luYyB8fCB0aGlzLnVuZmx1c2hlZEVudHJpZXMuaW5jcmVtZW50QW5kR2V0KCkgPj0gZmx1c2hsb2dlbnRyaWVzKSB7CisgICAgICAgIHN5bmMoKTsKKyAgICAgIH0KKyAgICAgIGxvbmcgdG9vayA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gbm93OworICAgICAgaWYgKHRvb2sgPiAxMDAwKSB7CisgICAgICAgIExPRy53YXJuKFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpICsgIiB0b29rICIgKyB0b29rICsKKyAgICAgICAgICAibXMgYXBwZW5kaW5nIGFuIGVkaXQgdG8gSExvZzsgZWRpdGNvdW50PSIgKyB0aGlzLm51bUVudHJpZXMuZ2V0KCkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiQ291bGQgbm90IGFwcGVuZC4gUmVxdWVzdGluZyBjbG9zZSBvZiBsb2ciLCBlKTsKKyAgICAgIHJlcXVlc3RMb2dSb2xsKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCisgIC8qKiBAcmV0dXJuIEhvdyBtYW55IGl0ZW1zIGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgbG9nICovCisgIGludCBnZXROdW1FbnRyaWVzKCkgeworICAgIHJldHVybiBudW1FbnRyaWVzLmdldCgpOworICB9CisKKyAgLyoqCisgICAqIE9idGFpbiBhIGxvZyBzZXF1ZW5jZSBudW1iZXIuCisgICAqLworICBwcml2YXRlIGxvbmcgb2J0YWluU2VxTnVtKCkgeworICAgIHJldHVybiB0aGlzLmxvZ1NlcU51bS5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgbG9nIGZpbGVzIGluIHVzZSAqLworICBpbnQgZ2V0TnVtTG9nRmlsZXMoKSB7CisgICAgcmV0dXJuIG91dHB1dGZpbGVzLnNpemUoKTsKKyAgfQorCisgIC8qCisgICAqIE9idGFpbiBhIHNwZWNpZmllZCBudW1iZXIgb2Ygc2VxdWVuY2UgbnVtYmVycworICAgKgorICAgKiBAcGFyYW0gbnVtIG51bWJlciBvZiBzZXF1ZW5jZSBudW1iZXJzIHRvIG9idGFpbgorICAgKiBAcmV0dXJuIGFycmF5IG9mIHNlcXVlbmNlIG51bWJlcnMKKyAgICovCisgIHByaXZhdGUgbG9uZyBbXSBvYnRhaW5TZXFOdW0oaW50IG51bSkgeworICAgIGxvbmcgW10gcmVzdWx0cyA9IG5ldyBsb25nW251bV07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07IGkrKykgeworICAgICAgcmVzdWx0c1tpXSA9IHRoaXMubG9nU2VxTnVtLmluY3JlbWVudEFuZEdldCgpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0czsKKyAgfQorCisgIC8qKgorICAgKiBCeSBhY3F1aXJpbmcgYSBsb2cgc2VxdWVuY2UgSUQsIHdlIGNhbiBhbGxvdyBsb2cgbWVzc2FnZXMgdG8gY29udGludWUgd2hpbGUKKyAgICogd2UgZmx1c2ggdGhlIGNhY2hlLgorICAgKgorICAgKiBBY3F1aXJlIGEgbG9jayBzbyB0aGF0IHdlIGRvIG5vdCByb2xsIHRoZSBsb2cgYmV0d2VlbiB0aGUgc3RhcnQgYW5kCisgICAqIGNvbXBsZXRpb24gb2YgYSBjYWNoZS1mbHVzaC4gT3RoZXJ3aXNlIHRoZSBsb2ctc2VxLWlkIGZvciB0aGUgZmx1c2ggd2lsbAorICAgKiBub3QgYXBwZWFyIGluIHRoZSBjb3JyZWN0IGxvZ2ZpbGUuCisgICAqCisgICAqIEByZXR1cm4gc2VxdWVuY2UgSUQgdG8gcGFzcyB7QGxpbmsgI2NvbXBsZXRlQ2FjaGVGbHVzaChUZXh0LCBUZXh0LCBsb25nKX0KKyAgICogQHNlZSAjY29tcGxldGVDYWNoZUZsdXNoKFRleHQsIFRleHQsIGxvbmcpCisgICAqIEBzZWUgI2Fib3J0Q2FjaGVGbHVzaCgpCisgICAqLworICBsb25nIHN0YXJ0Q2FjaGVGbHVzaCgpIHsKKyAgICB0aGlzLmNhY2hlRmx1c2hMb2NrLmxvY2soKTsKKyAgICByZXR1cm4gb2J0YWluU2VxTnVtKCk7CisgIH0KKworICAvKioKKyAgICogQ29tcGxldGUgdGhlIGNhY2hlIGZsdXNoCisgICAqCisgICAqIFByb3RlY3RlZCBieSBjYWNoZUZsdXNoTG9jaworICAgKgorICAgKiBAcGFyYW0gcmVnaW9uTmFtZQorICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAqIEBwYXJhbSBsb2dTZXFJZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICB2b2lkIGNvbXBsZXRlQ2FjaGVGbHVzaChmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgIGZpbmFsIGxvbmcgbG9nU2VxSWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGlmICh0aGlzLmNsb3NlZCkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBzeW5jaHJvbml6ZWQgKHVwZGF0ZUxvY2spIHsKKyAgICAgICAgdGhpcy53cml0ZXIuYXBwZW5kKG5ldyBITG9nS2V5KHJlZ2lvbk5hbWUsIHRhYmxlTmFtZSwgbG9nU2VxSWQpLAorICAgICAgICAgIGNvbXBsZXRlQ2FjaGVGbHVzaExvZ0VkaXQoKSk7CisgICAgICAgIHRoaXMubnVtRW50cmllcy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgTG9uZyBzZXEgPSB0aGlzLmxhc3RTZXFXcml0dGVuLmdldChyZWdpb25OYW1lKTsKKyAgICAgICAgaWYgKHNlcSAhPSBudWxsICYmIGxvZ1NlcUlkID49IHNlcS5sb25nVmFsdWUoKSkgeworICAgICAgICAgIHRoaXMubGFzdFNlcVdyaXR0ZW4ucmVtb3ZlKHJlZ2lvbk5hbWUpOworICAgICAgICB9CisgICAgICAgIHVwZGF0ZUxvY2subm90aWZ5QWxsKCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMuY2FjaGVGbHVzaExvY2sudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBLZXlWYWx1ZSBjb21wbGV0ZUNhY2hlRmx1c2hMb2dFZGl0KCkgeworICAgIHJldHVybiBuZXcgS2V5VmFsdWUoTUVUQVJPVywgTUVUQUNPTFVNTiwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCksCisgICAgICBDT01QTEVURV9DQUNIRV9GTFVTSCk7CisgIH0KKworICAvKioKKyAgICogQWJvcnQgYSBjYWNoZSBmbHVzaC4KKyAgICogQ2FsbCBpZiB0aGUgZmx1c2ggZmFpbHMuIE5vdGUgdGhhdCB0aGUgb25seSByZWNvdmVyeSBmb3IgYW4gYWJvcnRlZCBmbHVzaAorICAgKiBjdXJyZW50bHkgaXMgYSByZXN0YXJ0IG9mIHRoZSByZWdpb25zZXJ2ZXIgc28gdGhlIHNuYXBzaG90IGNvbnRlbnQgZHJvcHBlZAorICAgKiBieSB0aGUgZmFpbHVyZSBnZXRzIHJlc3RvcmVkIHRvIHRoZSBtZW1jYWNoZS4KKyAgICovCisgIHZvaWQgYWJvcnRDYWNoZUZsdXNoKCkgeworICAgIHRoaXMuY2FjaGVGbHVzaExvY2sudW5sb2NrKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNvbHVtbiBpcyBhIG1ldGEgY29sdW1uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNNZXRhQ29sdW1uKGJ5dGUgW10gY29sdW1uKSB7CisgICAgcmV0dXJuIEJ5dGVzLmVxdWFscyhNRVRBQ09MVU1OLCBjb2x1bW4pOworICB9CisgIAorICAvKioKKyAgICogU3BsaXQgdXAgYSBidW5jaCBvZiByZWdpb25zZXJ2ZXIgY29tbWl0IGxvZyBmaWxlcyB0aGF0IGFyZSBubyBsb25nZXIKKyAgICogYmVpbmcgd3JpdHRlbiB0bywgaW50byBuZXcgZmlsZXMsIG9uZSBwZXIgcmVnaW9uIGZvciByZWdpb24gdG8gcmVwbGF5IG9uCisgICAqIHN0YXJ0dXAuIERlbGV0ZSB0aGUgb2xkIGxvZyBmaWxlcyB3aGVuIGZpbmlzaGVkLgorICAgKgorICAgKiBAcGFyYW0gcm9vdERpciBxdWFsaWZpZWQgcm9vdCBkaXJlY3Rvcnkgb2YgdGhlIEhCYXNlIGluc3RhbmNlCisgICAqIEBwYXJhbSBzcmNEaXIgRGlyZWN0b3J5IG9mIGxvZyBmaWxlcyB0byBzcGxpdDogZS5nLgorICAgKiAgICAgICAgICAgICAgICA8Y29kZT4ke1JPT1RESVJ9L2xvZ19IT1NUX1BPUlQ8L2NvZGU+CisgICAqIEBwYXJhbSBmcyBGaWxlU3lzdGVtCisgICAqIEBwYXJhbSBjb25mIEhCYXNlQ29uZmlndXJhdGlvbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgc3BsaXRMb2coZmluYWwgUGF0aCByb290RGlyLCBmaW5hbCBQYXRoIHNyY0RpciwKKyAgICAgIGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIENvbmZpZ3VyYXRpb24gY29uZikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWZzLmV4aXN0cyhzcmNEaXIpKSB7CisgICAgICAvLyBOb3RoaW5nIHRvIGRvCisgICAgICByZXR1cm47CisgICAgfQorICAgIEZpbGVTdGF0dXMgW10gbG9nZmlsZXMgPSBmcy5saXN0U3RhdHVzKHNyY0Rpcik7CisgICAgaWYgKGxvZ2ZpbGVzID09IG51bGwgfHwgbG9nZmlsZXMubGVuZ3RoID09IDApIHsKKyAgICAgIC8vIE5vdGhpbmcgdG8gZG8KKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgTE9HLmluZm8oIlNwbGl0dGluZyAiICsgbG9nZmlsZXMubGVuZ3RoICsgIiBsb2cocykgaW4gIiArCisgICAgICBzcmNEaXIudG9TdHJpbmcoKSk7CisgICAgc3BsaXRMb2cocm9vdERpciwgbG9nZmlsZXMsIGZzLCBjb25mKTsKKyAgICB0cnkgeworICAgICAgZnMuZGVsZXRlKHNyY0RpciwgdHJ1ZSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgZSA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKTsKKyAgICAgIElPRXhjZXB0aW9uIGlvID0gbmV3IElPRXhjZXB0aW9uKCJDYW5ub3QgZGVsZXRlOiAiICsgc3JjRGlyKTsKKyAgICAgIGlvLmluaXRDYXVzZShlKTsKKyAgICAgIHRocm93IGlvOworICAgIH0KKyAgICBMT0cuaW5mbygibG9nIGZpbGUgc3BsaXR0aW5nIGNvbXBsZXRlZCBmb3IgIiArIHNyY0Rpci50b1N0cmluZygpKTsKKyAgfQorICAKKyAgLyoKKyAgICogQHBhcmFtIHJvb3REaXIKKyAgICogQHBhcmFtIGxvZ2ZpbGVzCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gY29uZgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHN0YXRpYyB2b2lkIHNwbGl0TG9nKGZpbmFsIFBhdGggcm9vdERpciwgZmluYWwgRmlsZVN0YXR1cyBbXSBsb2dmaWxlcywKKyAgICBmaW5hbCBGaWxlU3lzdGVtIGZzLCBmaW5hbCBDb25maWd1cmF0aW9uIGNvbmYpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWFwPGJ5dGUgW10sIFNlcXVlbmNlRmlsZS5Xcml0ZXI+IGxvZ1dyaXRlcnMgPQorICAgICAgbmV3IFRyZWVNYXA8Ynl0ZSBbXSwgU2VxdWVuY2VGaWxlLldyaXRlcj4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgdHJ5IHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbG9nZmlsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJTcGxpdHRpbmcgIiArIChpICsgMSkgKyAiIG9mICIgKyBsb2dmaWxlcy5sZW5ndGggKyAiOiAiICsKKyAgICAgICAgICAgIGxvZ2ZpbGVzW2ldLmdldFBhdGgoKSArICIsIGxlbmd0aD0iICsgbG9nZmlsZXNbaV0uZ2V0TGVuKCkpOworICAgICAgICB9CisgICAgICAgIC8vIENoZWNrIGZvciBwb3NzaWJseSBlbXB0eSBmaWxlLiBXaXRoIGFwcGVuZHMsIGN1cnJlbnRseSBIYWRvb3AgcmVwb3J0cworICAgICAgICAvLyBhIHplcm8gbGVuZ3RoIGV2ZW4gaWYgdGhlIGZpbGUgaGFzIGJlZW4gc3luYydkLiBSZXZpc2l0IGlmIAorICAgICAgICAvLyBIQURPT1AtNDc1MSBpcyBjb21taXR0ZWQuCisgICAgICAgIGxvbmcgbGVuZ3RoID0gbG9nZmlsZXNbaV0uZ2V0TGVuKCk7CisgICAgICAgIEhMb2dLZXkga2V5ID0gbmV3IEhMb2dLZXkoKTsKKyAgICAgICAgS2V5VmFsdWUgdmFsID0gbmV3IEtleVZhbHVlKCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgU2VxdWVuY2VGaWxlLlJlYWRlciBpbiA9CisgICAgICAgICAgICBuZXcgU2VxdWVuY2VGaWxlLlJlYWRlcihmcywgbG9nZmlsZXNbaV0uZ2V0UGF0aCgpLCBjb25mKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgICAgICAgIGZvciAoOyBpbi5uZXh0KGtleSwgdmFsKTsgY291bnQrKykgeworICAgICAgICAgICAgICBieXRlIFtdIHRhYmxlTmFtZSA9IGtleS5nZXRUYWJsZW5hbWUoKTsKKyAgICAgICAgICAgICAgYnl0ZSBbXSByZWdpb25OYW1lID0ga2V5LmdldFJlZ2lvbk5hbWUoKTsKKyAgICAgICAgICAgICAgU2VxdWVuY2VGaWxlLldyaXRlciB3ID0gbG9nV3JpdGVycy5nZXQocmVnaW9uTmFtZSk7CisgICAgICAgICAgICAgIGlmICh3ID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBQYXRoIGxvZ2ZpbGUgPSBuZXcgUGF0aCgKKyAgICAgICAgICAgICAgICAgICAgSFJlZ2lvbi5nZXRSZWdpb25EaXIoCisgICAgICAgICAgICAgICAgICAgICAgICBIVGFibGVEZXNjcmlwdG9yLmdldFRhYmxlRGlyKHJvb3REaXIsIHRhYmxlTmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICBIUmVnaW9uSW5mby5lbmNvZGVSZWdpb25OYW1lKHJlZ2lvbk5hbWUpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEhSRUdJT05fT0xETE9HRklMRV9OQU1FKTsKKyAgICAgICAgICAgICAgICBQYXRoIG9sZGxvZ2ZpbGUgPSBudWxsOworICAgICAgICAgICAgICAgIFNlcXVlbmNlRmlsZS5SZWFkZXIgb2xkID0gbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoZnMuZXhpc3RzKGxvZ2ZpbGUpKSB7CisgICAgICAgICAgICAgICAgICBMT0cud2FybigiT2xkIGxvZyBmaWxlICIgKyBsb2dmaWxlICsKKyAgICAgICAgICAgICAgICAgICIgYWxyZWFkeSBleGlzdHMuIENvcHlpbmcgZXhpc3RpbmcgZmlsZSB0byBuZXcgZmlsZSIpOworICAgICAgICAgICAgICAgICAgb2xkbG9nZmlsZSA9IG5ldyBQYXRoKGxvZ2ZpbGUudG9TdHJpbmcoKSArICIub2xkIik7CisgICAgICAgICAgICAgICAgICBmcy5yZW5hbWUobG9nZmlsZSwgb2xkbG9nZmlsZSk7CisgICAgICAgICAgICAgICAgICBvbGQgPSBuZXcgU2VxdWVuY2VGaWxlLlJlYWRlcihmcywgb2xkbG9nZmlsZSwgY29uZik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHcgPSBTZXF1ZW5jZUZpbGUuY3JlYXRlV3JpdGVyKGZzLCBjb25mLCBsb2dmaWxlLCBITG9nS2V5LmNsYXNzLAorICAgICAgICAgICAgICAgICAgS2V5VmFsdWUuY2xhc3MsIGdldENvbXByZXNzaW9uVHlwZShjb25mKSk7CisgICAgICAgICAgICAgICAgLy8gVXNlIGNvcHkgb2YgcmVnaW9uTmFtZTsgcmVnaW9uTmFtZSBvYmplY3QgaXMgcmV1c2VkIGluc2lkZSBpbgorICAgICAgICAgICAgICAgIC8vIEhTdG9yZUtleS5nZXRSZWdpb25OYW1lIHNvIGl0cyBjb250ZW50IGNoYW5nZXMgYXMgd2UgaXRlcmF0ZS4KKyAgICAgICAgICAgICAgICBsb2dXcml0ZXJzLnB1dChyZWdpb25OYW1lLCB3KTsKKyAgICAgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgIExPRy5kZWJ1ZygiQ3JlYXRpbmcgbmV3IGxvZyBmaWxlIHdyaXRlciBmb3IgcGF0aCAiICsgbG9nZmlsZSArCisgICAgICAgICAgICAgICAgICAgICAgIiBhbmQgcmVnaW9uICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb25OYW1lKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKG9sZCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAvLyBDb3B5IGZyb20gZXhpc3RpbmcgbG9nIGZpbGUKKyAgICAgICAgICAgICAgICAgIEhMb2dLZXkgb2xka2V5ID0gbmV3IEhMb2dLZXkoKTsKKyAgICAgICAgICAgICAgICAgIEtleVZhbHVlIG9sZHZhbCA9IG5ldyBLZXlWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgZm9yICg7IG9sZC5uZXh0KG9sZGtleSwgb2xkdmFsKTsgY291bnQrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkgJiYgY291bnQgPiAwICYmIGNvdW50ICUgMTAwMDAgPT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgIExPRy5kZWJ1ZygiQ29waWVkICIgKyBjb3VudCArICIgZWRpdHMiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB3LmFwcGVuZChvbGRrZXksIG9sZHZhbCk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICBvbGQuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICAgIGZzLmRlbGV0ZShvbGRsb2dmaWxlLCB0cnVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgdy5hcHBlbmQoa2V5LCB2YWwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICAgIExPRy5kZWJ1ZygiQXBwbGllZCAiICsgY291bnQgKyAiIHRvdGFsIGVkaXRzIGZyb20gIiArCisgICAgICAgICAgICAgICAgICBsb2dmaWxlc1tpXS5nZXRQYXRoKCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZSA9IFJlbW90ZUV4Y2VwdGlvbkhhbmRsZXIuY2hlY2tJT0V4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBFT0ZFeGNlcHRpb24pKSB7CisgICAgICAgICAgICAgIExPRy53YXJuKCJFeGNlcHRpb24gcHJvY2Vzc2luZyAiICsgbG9nZmlsZXNbaV0uZ2V0UGF0aCgpICsKKyAgICAgICAgICAgICAgICAgICIgLS0gY29udGludWluZy4gUG9zc2libGUgREFUQSBMT1NTISIsIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICBMT0cud2FybigiQ2xvc2UgaW4gZmluYWxseSB0aHJldyBleGNlcHRpb24gLS0gY29udGludWluZyIsIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBpbnB1dCBmaWxlIG5vdyBzbyB3ZSBkbyBub3QgcmVwbGF5IGVkaXRzLiAgV2UgY291bGQKKyAgICAgICAgICAgIC8vIGhhdmUgZ290dGVuIGhlcmUgYmVjYXVzZSBvZiBhbiBleGNlcHRpb24uICBJZiBzbywgcHJvYmFibHkKKyAgICAgICAgICAgIC8vIG5vdGhpbmcgd2UgY2FuIGRvIGFib3V0IGl0LiBSZXBsYXlpbmcgaXQsIGl0IGNvdWxkIHdvcmsgYnV0IHdlCisgICAgICAgICAgICAvLyBjb3VsZCBiZSBzdHVjayByZXBsYXlpbmcgZm9yIGV2ZXIuIEp1c3QgY29udGludWUgdGhvdWdoIHdlCisgICAgICAgICAgICAvLyBjb3VsZCBoYXZlIGxvc3Qgc29tZSBlZGl0cy4KKyAgICAgICAgICAgIGZzLmRlbGV0ZShsb2dmaWxlc1tpXS5nZXRQYXRoKCksIHRydWUpOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIGlmIChsZW5ndGggPD0gMCkgeworICAgICAgICAgICAgTE9HLndhcm4oIkVtcHR5IGxvZywgY29udGludWluZzogIiArIGxvZ2ZpbGVzW2ldKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgIH0KKyAgICAgICAgICB0aHJvdyBlOworICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGZvciAoU2VxdWVuY2VGaWxlLldyaXRlciB3IDogbG9nV3JpdGVycy52YWx1ZXMoKSkgeworICAgICAgICB3LmNsb3NlKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgSExvZyBkaXJlY3RvcnkgbmFtZQorICAgKiAKKyAgICogQHBhcmFtIGluZm8gSFNlcnZlckluZm8gZm9yIHNlcnZlcgorICAgKiBAcmV0dXJuIHRoZSBITG9nIGRpcmVjdG9yeSBuYW1lCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRITG9nRGlyZWN0b3J5TmFtZShIU2VydmVySW5mbyBpbmZvKSB7CisgICAgcmV0dXJuIGdldEhMb2dEaXJlY3RvcnlOYW1lKEhTZXJ2ZXJJbmZvLmdldFNlcnZlck5hbWUoaW5mbykpOworICB9CisgIAorICAvKioKKyAgICogQ29uc3RydWN0IHRoZSBITG9nIGRpcmVjdG9yeSBuYW1lCisgICAqIAorICAgKiBAcGFyYW0gc2VydmVyQWRkcmVzcworICAgKiBAcGFyYW0gc3RhcnRDb2RlCisgICAqIEByZXR1cm4gdGhlIEhMb2cgZGlyZWN0b3J5IG5hbWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEhMb2dEaXJlY3RvcnlOYW1lKFN0cmluZyBzZXJ2ZXJBZGRyZXNzLAorICAgICAgbG9uZyBzdGFydENvZGUpIHsKKyAgICBpZiAoc2VydmVyQWRkcmVzcyA9PSBudWxsIHx8IHNlcnZlckFkZHJlc3MubGVuZ3RoKCkgPT0gMCkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIHJldHVybiBnZXRITG9nRGlyZWN0b3J5TmFtZSgKKyAgICAgICAgSFNlcnZlckluZm8uZ2V0U2VydmVyTmFtZShzZXJ2ZXJBZGRyZXNzLCBzdGFydENvZGUpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgSExvZyBkaXJlY3RvcnkgbmFtZQorICAgKiAKKyAgICogQHBhcmFtIHNlcnZlck5hbWUKKyAgICogQHJldHVybiB0aGUgSExvZyBkaXJlY3RvcnkgbmFtZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0SExvZ0RpcmVjdG9yeU5hbWUoU3RyaW5nIHNlcnZlck5hbWUpIHsKKyAgICBTdHJpbmdCdWlsZGVyIGRpck5hbWUgPSBuZXcgU3RyaW5nQnVpbGRlcihIQ29uc3RhbnRzLkhSRUdJT05fTE9HRElSX05BTUUpOworICAgIGRpck5hbWUuYXBwZW5kKCIvIik7CisgICAgZGlyTmFtZS5hcHBlbmQoc2VydmVyTmFtZSk7CisgICAgcmV0dXJuIGRpck5hbWUudG9TdHJpbmcoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgdXNhZ2UoKSB7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogamF2YSBvcmcuYXBhY2hlLmhiYXNlLkhMb2ciICsKKyAgICAgICAgIiB7LS1kdW1wIDxsb2dmaWxlPi4uLiB8IC0tc3BsaXQgPGxvZ2Rpcj4uLi59Iik7CisgIH0KKworICAvKioKKyAgICogUGFzcyBvbmUgb3IgbW9yZSBsb2cgZmlsZSBuYW1lcyBhbmQgaXQgd2lsbCBlaXRoZXIgZHVtcCBvdXQgYSB0ZXh0IHZlcnNpb24KKyAgICogb24gPGNvZGU+c3Rkb3V0PC9jb2RlPiBvciBzcGxpdCB0aGUgc3BlY2lmaWVkIGxvZyBmaWxlcy4KKyAgICoKKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7CisgICAgICB1c2FnZSgpOworICAgICAgU3lzdGVtLmV4aXQoLTEpOworICAgIH0KKyAgICBib29sZWFuIGR1bXAgPSB0cnVlOworICAgIGlmIChhcmdzWzBdLmNvbXBhcmVUbygiLS1kdW1wIikgIT0gMCkgeworICAgICAgaWYgKGFyZ3NbMF0uY29tcGFyZVRvKCItLXNwbGl0IikgPT0gMCkgeworICAgICAgICBkdW1wID0gZmFsc2U7CisKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHVzYWdlKCk7CisgICAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICAgIH0KKyAgICB9CisgICAgQ29uZmlndXJhdGlvbiBjb25mID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIEZpbGVTeXN0ZW0gZnMgPSBGaWxlU3lzdGVtLmdldChjb25mKTsKKyAgICBQYXRoIGJhc2VEaXIgPSBuZXcgUGF0aChjb25mLmdldChIQkFTRV9ESVIpKTsKKworICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgeworICAgICAgUGF0aCBsb2dQYXRoID0gbmV3IFBhdGgoYXJnc1tpXSk7CisgICAgICBpZiAoIWZzLmV4aXN0cyhsb2dQYXRoKSkgeworICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKGFyZ3NbaV0gKyAiIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICB9CisgICAgICBpZiAoZHVtcCkgeworICAgICAgICBpZiAoIWZzLmlzRmlsZShsb2dQYXRoKSkgeworICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihhcmdzW2ldICsgIiBpcyBub3QgYSBmaWxlIik7CisgICAgICAgIH0KKyAgICAgICAgUmVhZGVyIGxvZyA9IG5ldyBTZXF1ZW5jZUZpbGUuUmVhZGVyKGZzLCBsb2dQYXRoLCBjb25mKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBITG9nS2V5IGtleSA9IG5ldyBITG9nS2V5KCk7CisgICAgICAgICAgS2V5VmFsdWUgdmFsID0gbmV3IEtleVZhbHVlKCk7CisgICAgICAgICAgd2hpbGUgKGxvZy5uZXh0KGtleSwgdmFsKSkgeworICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGtleS50b1N0cmluZygpICsgIiAiICsgdmFsLnRvU3RyaW5nKCkpOworICAgICAgICAgIH0KKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICBsb2cuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKCFmcy5nZXRGaWxlU3RhdHVzKGxvZ1BhdGgpLmlzRGlyKCkpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oYXJnc1tpXSArICIgaXMgbm90IGEgZGlyZWN0b3J5Iik7CisgICAgICAgIH0KKyAgICAgICAgc3BsaXRMb2coYmFzZURpciwgbG9nUGF0aCwgZnMsIGNvbmYpOworICAgICAgfQorICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0hMb2dLZXkuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9ITG9nS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU2YWRlZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9ITG9nS2V5LmphdmEKQEAgLTAsMCArMSwxMzcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLio7CisKK2ltcG9ydCBqYXZhLmlvLio7CisKKy8qKgorICogQSBLZXkgZm9yIGFuIGVudHJ5IGluIHRoZSBjaGFuZ2UgbG9nLgorICogCisgKiBUaGUgbG9nIGludGVybWluZ2xlcyBlZGl0cyB0byBtYW55IHRhYmxlcyBhbmQgcm93cywgc28gZWFjaCBsb2cgZW50cnkgCisgKiBpZGVudGlmaWVzIHRoZSBhcHByb3ByaWF0ZSB0YWJsZSBhbmQgcm93LiAgV2l0aGluIGEgdGFibGUgYW5kIHJvdywgdGhleSdyZSAKKyAqIGFsc28gc29ydGVkLgorICogCisgKiA8cD5Tb21lIFRyYW5zYWN0aW9uYWwgZWRpdHMgKFNUQVJULCBDT01NSVQsIEFCT1JUKSB3aWxsIG5vdCBoYXZlIGFuCisgKiBhc3NvY2lhdGVkIHJvdy4KKyAqLworcHVibGljIGNsYXNzIEhMb2dLZXkgaW1wbGVtZW50cyBXcml0YWJsZUNvbXBhcmFibGU8SExvZ0tleT4geworICBwcml2YXRlIGJ5dGUgW10gcmVnaW9uTmFtZTsKKyAgcHJpdmF0ZSBieXRlIFtdIHRhYmxlbmFtZTsKKyAgcHJpdmF0ZSBsb25nIGxvZ1NlcU51bTsKKworICAvKiogQ3JlYXRlIGFuIGVtcHR5IGtleSB1c2VmdWwgd2hlbiBkZXNlcmlhbGl6aW5nICovCisgIHB1YmxpYyBITG9nS2V5KCkgeworICAgIHRoaXMobnVsbCwgbnVsbCwgMEwpOworICB9CisgIAorICAvKioKKyAgICogQ3JlYXRlIHRoZSBsb2cga2V5IQorICAgKiBXZSBtYWludGFpbiB0aGUgdGFibGVuYW1lIG1haW5seSBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLgorICAgKiBBIHJlZ2lvbk5hbWUgaXMgYWx3YXlzIGEgc3ViLXRhYmxlIG9iamVjdC4KKyAgICoKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgIC0gbmFtZSBvZiByZWdpb24KKyAgICogQHBhcmFtIHRhYmxlbmFtZSAgIC0gbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gbG9nU2VxTnVtICAgLSBsb2cgc2VxdWVuY2UgbnVtYmVyCisgICAqLworICBwdWJsaWMgSExvZ0tleShmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIGJ5dGUgW10gdGFibGVuYW1lLAorICAgICAgbG9uZyBsb2dTZXFOdW0pIHsKKyAgICB0aGlzLnJlZ2lvbk5hbWUgPSByZWdpb25OYW1lOworICAgIHRoaXMudGFibGVuYW1lID0gdGFibGVuYW1lOworICAgIHRoaXMubG9nU2VxTnVtID0gbG9nU2VxTnVtOworICB9CisKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIEEgYnVuY2ggb2YgYWNjZXNzb3JzCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgIC8qKiBAcmV0dXJuIHJlZ2lvbiBuYW1lICovCisgIHB1YmxpYyBieXRlIFtdIGdldFJlZ2lvbk5hbWUoKSB7CisgICAgcmV0dXJuIHJlZ2lvbk5hbWU7CisgIH0KKyAgCisgIC8qKiBAcmV0dXJuIHRhYmxlIG5hbWUgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0VGFibGVuYW1lKCkgeworICAgIHJldHVybiB0YWJsZW5hbWU7CisgIH0KKworICAvKiogQHJldHVybiBsb2cgc2VxdWVuY2UgbnVtYmVyICovCisgIHB1YmxpYyBsb25nIGdldExvZ1NlcU51bSgpIHsKKyAgICByZXR1cm4gbG9nU2VxTnVtOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9TdHJpbmcodGFibGVuYW1lKSArICIvIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbk5hbWUpICsgIi8iICsKKyAgICAgIGxvZ1NlcU51bTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CisgICAgaWYgKHRoaXMgPT0gb2JqKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKG9iaiA9PSBudWxsIHx8IGdldENsYXNzKCkgIT0gb2JqLmdldENsYXNzKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIGNvbXBhcmVUbygoSExvZ0tleSlvYmopID09IDA7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIGludCByZXN1bHQgPSB0aGlzLnJlZ2lvbk5hbWUuaGFzaENvZGUoKTsKKyAgICByZXN1bHQgXj0gdGhpcy5sb2dTZXFOdW07CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8vCisgIC8vIENvbXBhcmFibGUKKyAgLy8KKworICBwdWJsaWMgaW50IGNvbXBhcmVUbyhITG9nS2V5IG8pIHsKKyAgICBpbnQgcmVzdWx0ID0gQnl0ZXMuY29tcGFyZVRvKHRoaXMucmVnaW9uTmFtZSwgby5yZWdpb25OYW1lKTsKKyAgICBpZihyZXN1bHQgPT0gMCkgeworICAgICAgaWYgKHRoaXMubG9nU2VxTnVtIDwgby5sb2dTZXFOdW0pIHsKKyAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICB9IGVsc2UgaWYgKHRoaXMubG9nU2VxTnVtID4gby5sb2dTZXFOdW0pIHsKKyAgICAgICAgcmVzdWx0ID0gMTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8vCisgIC8vIFdyaXRhYmxlCisgIC8vCisKKyAgcHVibGljIHZvaWQgd3JpdGUoRGF0YU91dHB1dCBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQnl0ZXMud3JpdGVCeXRlQXJyYXkob3V0LCB0aGlzLnJlZ2lvbk5hbWUpOworICAgIEJ5dGVzLndyaXRlQnl0ZUFycmF5KG91dCwgdGhpcy50YWJsZW5hbWUpOworICAgIG91dC53cml0ZUxvbmcobG9nU2VxTnVtKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5yZWdpb25OYW1lID0gQnl0ZXMucmVhZEJ5dGVBcnJheShpbik7CisgICAgdGhpcy50YWJsZW5hbWUgPSBCeXRlcy5yZWFkQnl0ZUFycmF5KGluKTsKKyAgICB0aGlzLmxvZ1NlcU51bSA9IGluLnJlYWRMb25nKCk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvSFJlZ2lvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0hSZWdpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWZmMWIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0hSZWdpb24uamF2YQpAQCAtMCwwICsxLDI2OTMgQEAKKyAvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudFNraXBMaXN0TWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudFJlYWRXcml0ZUxvY2s7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRG9Ob3RSZXRyeUlPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkRyb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVnaW9uSGlzdG9yaWFuOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlZhbHVlT3Zlck1heExlbmd0aEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoT3BlcmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGJhc2VNYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUmVmZXJlbmNlLlJhbmdlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5GU1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Qcm9ncmVzc2FibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5TdHJpbmdVdGlsczsKKworLyoqCisgKiBIUmVnaW9uIHN0b3JlcyBkYXRhIGZvciBhIGNlcnRhaW4gcmVnaW9uIG9mIGEgdGFibGUuICBJdCBzdG9yZXMgYWxsIGNvbHVtbnMKKyAqIGZvciBlYWNoIHJvdy4gQSBnaXZlbiB0YWJsZSBjb25zaXN0cyBvZiBvbmUgb3IgbW9yZSBIUmVnaW9ucy4KKyAqCisgKiA8cD5XZSBtYWludGFpbiBtdWx0aXBsZSBIU3RvcmVzIGZvciBhIHNpbmdsZSBIUmVnaW9uLgorICogCisgKiA8cD5BbiBIU3RvcmUgaXMgYSBzZXQgb2Ygcm93cyB3aXRoIHNvbWUgY29sdW1uIGRhdGE7IHRvZ2V0aGVyLAorICogdGhleSBtYWtlIHVwIGFsbCB0aGUgZGF0YSBmb3IgdGhlIHJvd3MuICAKKyAqCisgKiA8cD5FYWNoIEhSZWdpb24gaGFzIGEgJ3N0YXJ0S2V5JyBhbmQgJ2VuZEtleScuCisgKiA8cD5UaGUgZmlyc3QgaXMgaW5jbHVzaXZlLCB0aGUgc2Vjb25kIGlzIGV4Y2x1c2l2ZSAoZXhjZXB0IGZvcgorICogdGhlIGZpbmFsIHJlZ2lvbikgIFRoZSBlbmRLZXkgb2YgcmVnaW9uIDAgaXMgdGhlIHNhbWUgYXMKKyAqIHN0YXJ0S2V5IGZvciByZWdpb24gMSAoaWYgaXQgZXhpc3RzKS4gIFRoZSBzdGFydEtleSBmb3IgdGhlCisgKiBmaXJzdCByZWdpb24gaXMgbnVsbC4gVGhlIGVuZEtleSBmb3IgdGhlIGZpbmFsIHJlZ2lvbiBpcyBudWxsLgorICoKKyAqIDxwPkxvY2tpbmcgYXQgdGhlIEhSZWdpb24gbGV2ZWwgc2VydmVzIG9ubHkgb25lIHB1cnBvc2U6IHByZXZlbnRpbmcgdGhlCisgKiByZWdpb24gZnJvbSBiZWluZyBjbG9zZWQgKGFuZCBjb25zZXF1ZW50bHkgc3BsaXQpIHdoaWxlIG90aGVyIG9wZXJhdGlvbnMKKyAqIGFyZSBvbmdvaW5nLiBFYWNoIHJvdyBsZXZlbCBvcGVyYXRpb24gb2J0YWlucyBib3RoIGEgcm93IGxvY2sgYW5kIGEgcmVnaW9uCisgKiByZWFkIGxvY2sgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgb3BlcmF0aW9uLiBXaGlsZSBhIHNjYW5uZXIgaXMgYmVpbmcKKyAqIGNvbnN0cnVjdGVkLCBnZXRTY2FubmVyIGhvbGRzIGEgcmVhZCBsb2NrLiBJZiB0aGUgc2Nhbm5lciBpcyBzdWNjZXNzZnVsbHkKKyAqIGNvbnN0cnVjdGVkLCBpdCBob2xkcyBhIHJlYWQgbG9jayB1bnRpbCBpdCBpcyBjbG9zZWQuIEEgY2xvc2UgdGFrZXMgb3V0IGEKKyAqIHdyaXRlIGxvY2sgYW5kIGNvbnNlcXVlbnRseSB3aWxsIGJsb2NrIGZvciBvbmdvaW5nIG9wZXJhdGlvbnMgYW5kIHdpbGwgYmxvY2sKKyAqIG5ldyBvcGVyYXRpb25zIGZyb20gc3RhcnRpbmcgd2hpbGUgdGhlIGNsb3NlIGlzIGluIHByb2dyZXNzLgorICogCisgKiA8cD5BbiBIUmVnaW9uIGlzIGRlZmluZWQgYnkgaXRzIHRhYmxlIGFuZCBpdHMga2V5IGV4dGVudC4KKyAqIAorICogPHA+SXQgY29uc2lzdHMgb2YgYXQgbGVhc3Qgb25lIEhTdG9yZS4gIFRoZSBudW1iZXIgb2YgSFN0b3JlcyBzaG91bGQgYmUgCisgKiBjb25maWd1cmFibGUsIHNvIHRoYXQgZGF0YSB3aGljaCBpcyBhY2Nlc3NlZCB0b2dldGhlciBpcyBzdG9yZWQgaW4gdGhlIHNhbWUKKyAqIEhTdG9yZS4gIFJpZ2h0IG5vdywgd2UgYXBwcm94aW1hdGUgdGhhdCBieSBidWlsZGluZyBhIHNpbmdsZSBIU3RvcmUgZm9yIAorICogZWFjaCBjb2x1bW4gZmFtaWx5LiAgKFRoaXMgY29uZmlnIGluZm8gd2lsbCBiZSBjb21tdW5pY2F0ZWQgdmlhIHRoZSAKKyAqIHRhYmxlZGVzYy4pCisgKiAKKyAqIDxwPlRoZSBIVGFibGVEZXNjcmlwdG9yIGNvbnRhaW5zIG1ldGFpbmZvIGFib3V0IHRoZSBIUmVnaW9uJ3MgdGFibGUuCisgKiByZWdpb25OYW1lIGlzIGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoaXMgSFJlZ2lvbi4gKHN0YXJ0S2V5LCBlbmRLZXldCisgKiBkZWZpbmVzIHRoZSBrZXlzcGFjZSBmb3IgdGhpcyBIUmVnaW9uLgorICovCitwdWJsaWMgY2xhc3MgSFJlZ2lvbiBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhSZWdpb24uY2xhc3MpOworICBzdGF0aWMgZmluYWwgU3RyaW5nIFNQTElURElSID0gInNwbGl0cyI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUVSR0VESVIgPSAibWVyZ2VzIjsKKyAgZmluYWwgQXRvbWljQm9vbGVhbiBjbG9zZWQgPSBuZXcgQXRvbWljQm9vbGVhbihmYWxzZSk7CisgIC8qIENsb3NpbmcgY2FuIHRha2Ugc29tZSB0aW1lOyB1c2UgdGhlIGNsb3NpbmcgZmxhZyBpZiB0aGVyZSBpcyBzdHVmZiB3ZSBkb24ndCB3YW50CisgICAqIHRvIGRvIHdoaWxlIGluIGNsb3Npbmcgc3RhdGU7IGUuZy4gbGlrZSBvZmZlciB0aGlzIHJlZ2lvbiB1cCB0byB0aGUgbWFzdGVyIGFzIGEgcmVnaW9uCisgICAqIHRvIGNsb3NlIGlmIHRoZSBjYXJyeWluZyByZWdpb25zZXJ2ZXIgaXMgb3ZlcmxvYWRlZC4gIE9uY2Ugc2V0LCBpdCBpcyBuZXZlciBjbGVhcmVkLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBBdG9taWNCb29sZWFuIGNsb3NpbmcgPSBuZXcgQXRvbWljQm9vbGVhbihmYWxzZSk7CisgIHByaXZhdGUgZmluYWwgUmVnaW9uSGlzdG9yaWFuIGhpc3RvcmlhbjsKKworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy8gTWVtYmVycworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICBwcml2YXRlIGZpbmFsIE1hcDxJbnRlZ2VyLCBieXRlIFtdPiBsb2Nrc1RvUm93cyA9CisgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPEludGVnZXIsIGJ5dGUgW10+KCk7CisgIHByb3RlY3RlZCBmaW5hbCBNYXA8Ynl0ZSBbXSwgU3RvcmU+IHN0b3JlcyA9CisgICAgbmV3IENvbmN1cnJlbnRTa2lwTGlzdE1hcDxieXRlIFtdLCBTdG9yZT4oS2V5VmFsdWUuRkFNSUxZX0NPTVBBUkFUT1IpOworICBmaW5hbCBBdG9taWNMb25nIG1lbWNhY2hlU2l6ZSA9IG5ldyBBdG9taWNMb25nKDApOworCisgIC8vIFRoaXMgaXMgdGhlIHRhYmxlIHN1YmRpcmVjdG9yeS4KKyAgZmluYWwgUGF0aCBiYXNlZGlyOworICBmaW5hbCBITG9nIGxvZzsKKyAgZmluYWwgRmlsZVN5c3RlbSBmczsKKyAgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisgIGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm87CisgIGZpbmFsIFBhdGggcmVnaW9uZGlyOworICBwcml2YXRlIGZpbmFsIFBhdGggcmVnaW9uQ29tcGFjdGlvbkRpcjsKKyAgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGNvbXBhcmF0b3I7CisgIHByaXZhdGUgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGNvbXBhcmF0b3JJZ25vcmVUaW1lc3RhbXA7CisKKyAgLyoKKyAgICogU2V0IHRoaXMgd2hlbiBzY2hlZHVsaW5nIGNvbXBhY3Rpb24gaWYgd2FudCB0aGUgbmV4dCBjb21wYWN0aW9uIHRvIGJlIGEKKyAgICogbWFqb3IgY29tcGFjdGlvbi4gIENsZWFyZWQgZWFjaCB0aW1lIHRocm91Z2ggY29tcGFjdGlvbiBjb2RlLgorICAgKi8KKyAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGZvcmNlTWFqb3JDb21wYWN0aW9uID0gZmFsc2U7CisKKyAgLyoKKyAgICogRGF0YSBzdHJ1Y3R1cmUgb2Ygd3JpdGUgc3RhdGUgZmxhZ3MgdXNlZCBjb29yZGluYXRpbmcgZmx1c2hlcywKKyAgICogY29tcGFjdGlvbnMgYW5kIGNsb3Nlcy4KKyAgICovCisgIHN0YXRpYyBjbGFzcyBXcml0ZVN0YXRlIHsKKyAgICAvLyBTZXQgd2hpbGUgYSBtZW1jYWNoZSBmbHVzaCBpcyBoYXBwZW5pbmcuCisgICAgdm9sYXRpbGUgYm9vbGVhbiBmbHVzaGluZyA9IGZhbHNlOworICAgIC8vIFNldCB3aGVuIGEgZmx1c2ggaGFzIGJlZW4gcmVxdWVzdGVkLgorICAgIHZvbGF0aWxlIGJvb2xlYW4gZmx1c2hSZXF1ZXN0ZWQgPSBmYWxzZTsKKyAgICAvLyBTZXQgd2hpbGUgYSBjb21wYWN0aW9uIGlzIHJ1bm5pbmcuCisgICAgdm9sYXRpbGUgYm9vbGVhbiBjb21wYWN0aW5nID0gZmFsc2U7CisgICAgLy8gR2V0cyBzZXQgaW4gY2xvc2UuIElmIHNldCwgY2Fubm90IGNvbXBhY3Qgb3IgZmx1c2ggYWdhaW4uCisgICAgdm9sYXRpbGUgYm9vbGVhbiB3cml0ZXNFbmFibGVkID0gdHJ1ZTsKKyAgICAvLyBTZXQgaWYgcmVnaW9uIGlzIHJlYWQtb25seQorICAgIHZvbGF0aWxlIGJvb2xlYW4gcmVhZE9ubHkgPSBmYWxzZTsKKyAgICAKKyAgICAvKioKKyAgICAgKiBTZXQgZmxhZ3MgdGhhdCBtYWtlIHRoaXMgcmVnaW9uIHJlYWQtb25seS4KKyAgICAgKi8KKyAgICBzeW5jaHJvbml6ZWQgdm9pZCBzZXRSZWFkT25seShmaW5hbCBib29sZWFuIG9uT2ZmKSB7CisgICAgICB0aGlzLndyaXRlc0VuYWJsZWQgPSAhb25PZmY7CisgICAgICB0aGlzLnJlYWRPbmx5ID0gb25PZmY7CisgICAgfQorICAgIAorICAgIGJvb2xlYW4gaXNSZWFkT25seSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnJlYWRPbmx5OworICAgIH0KKworICAgIGJvb2xlYW4gaXNGbHVzaFJlcXVlc3RlZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLmZsdXNoUmVxdWVzdGVkOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9sYXRpbGUgV3JpdGVTdGF0ZSB3cml0ZXN0YXRlID0gbmV3IFdyaXRlU3RhdGUoKTsKKworICBmaW5hbCBpbnQgbWVtY2FjaGVGbHVzaFNpemU7CisgIHByaXZhdGUgdm9sYXRpbGUgbG9uZyBsYXN0Rmx1c2hUaW1lOworICBmaW5hbCBGbHVzaFJlcXVlc3RlciBmbHVzaExpc3RlbmVyOworICBwcml2YXRlIGZpbmFsIGludCBibG9ja2luZ01lbWNhY2hlU2l6ZTsKKyAgZmluYWwgbG9uZyB0aHJlYWRXYWtlRnJlcXVlbmN5OworICAvLyBVc2VkIHRvIGd1YXJkIHNwbGl0cyBhbmQgY2xvc2VzCisgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jayBzcGxpdHNBbmRDbG9zZXNMb2NrID0KKyAgICBuZXcgUmVlbnRyYW50UmVhZFdyaXRlTG9jaygpOworICBwcml2YXRlIGZpbmFsIFJlZW50cmFudFJlYWRXcml0ZUxvY2sgbmV3U2Nhbm5lckxvY2sgPSAKKyAgICBuZXcgUmVlbnRyYW50UmVhZFdyaXRlTG9jaygpOworCisgIC8vIFN0b3AgdXBkYXRlcyBsb2NrCisgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jayB1cGRhdGVzTG9jayA9CisgICAgbmV3IFJlZW50cmFudFJlYWRXcml0ZUxvY2soKTsKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgc3BsaXRMb2NrID0gbmV3IE9iamVjdCgpOworICBwcml2YXRlIGxvbmcgbWluU2VxdWVuY2VJZDsKKyAgZmluYWwgQXRvbWljSW50ZWdlciBhY3RpdmVTY2FubmVyQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKKyAgCisgIC8qKgorICAgKiBOYW1lIG9mIHRoZSByZWdpb24gaW5mbyBmaWxlIHRoYXQgcmVzaWRlcyBqdXN0IHVuZGVyIHRoZSByZWdpb24gZGlyZWN0b3J5LgorICAgKi8KKyAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgUkVHSU9OSU5GT19GSUxFID0gIi5yZWdpb25pbmZvIjsKKworICAvKioKKyAgICogUkVHSU9OSU5GT19GSUxFIGFzIGJ5dGUgYXJyYXkuCisgICAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgW10gUkVHSU9OSU5GT19GSUxFX0JZVEVTID0KKyAgICBCeXRlcy50b0J5dGVzKFJFR0lPTklORk9fRklMRSk7CisKKyAgLyoqCisgICAqIEhSZWdpb24gY29uc3RydWN0b3IuCisgICAqCisgICAqIEBwYXJhbSBiYXNlZGlyIHF1YWxpZmllZCBwYXRoIG9mIGRpcmVjdG9yeSB3aGVyZSByZWdpb24gc2hvdWxkIGJlIGxvY2F0ZWQsCisgICAqIHVzdWFsbHkgdGhlIHRhYmxlIGRpcmVjdG9yeS4KKyAgICogQHBhcmFtIGxvZyBUaGUgSExvZyBpcyB0aGUgb3V0Ym91bmQgbG9nIGZvciBhbnkgdXBkYXRlcyB0byB0aGUgSFJlZ2lvbgorICAgKiAoVGhlcmUncyBhIHNpbmdsZSBITG9nIGZvciBhbGwgdGhlIEhSZWdpb25zIG9uIGEgc2luZ2xlIEhSZWdpb25TZXJ2ZXIuKQorICAgKiBUaGUgbG9nIGZpbGUgaXMgYSBsb2dmaWxlIGZyb20gdGhlIHByZXZpb3VzIGV4ZWN1dGlvbiB0aGF0J3MKKyAgICogY3VzdG9tLWNvbXB1dGVkIGZvciB0aGlzIEhSZWdpb24uIFRoZSBIUmVnaW9uU2VydmVyIGNvbXB1dGVzIGFuZCBzb3J0cyB0aGUKKyAgICogYXBwcm9wcmlhdGUgbG9nIGluZm8gZm9yIHRoaXMgSFJlZ2lvbi4gSWYgdGhlcmUgaXMgYSBwcmV2aW91cyBsb2cgZmlsZQorICAgKiAoaW1wbHlpbmcgdGhhdCB0aGUgSFJlZ2lvbiBoYXMgYmVlbiB3cml0dGVuLXRvIGJlZm9yZSksIHRoZW4gcmVhZCBpdCBmcm9tCisgICAqIHRoZSBzdXBwbGllZCBwYXRoLgorICAgKiBAcGFyYW0gZnMgaXMgdGhlIGZpbGVzeXN0ZW0uICAKKyAgICogQHBhcmFtIGNvbmYgaXMgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MuCisgICAqIEBwYXJhbSByZWdpb25JbmZvIC0gSFJlZ2lvbkluZm8gdGhhdCBkZXNjcmliZXMgdGhlIHJlZ2lvbgorICAgKiBpcyBuZXcpLCB0aGVuIHJlYWQgdGhlbSBmcm9tIHRoZSBzdXBwbGllZCBwYXRoLgorICAgKiBAcGFyYW0gZmx1c2hMaXN0ZW5lciBhbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIENhY2hlRmx1c2hMaXN0ZW5lciBvciBudWxsCisgICAqIG1ha2luZyBwcm9ncmVzcyB0byBtYXN0ZXIgLS0gb3RoZXJ3aXNlIG1hc3RlciBtaWdodCB0aGluayByZWdpb24gZGVwbG95CisgICAqIGZhaWxlZC4gIENhbiBiZSBudWxsLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIEhSZWdpb24oUGF0aCBiYXNlZGlyLCBITG9nIGxvZywgRmlsZVN5c3RlbSBmcywgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIAorICAgICAgSFJlZ2lvbkluZm8gcmVnaW9uSW5mbywgRmx1c2hSZXF1ZXN0ZXIgZmx1c2hMaXN0ZW5lcikgeworICAgIHRoaXMuYmFzZWRpciA9IGJhc2VkaXI7CisgICAgdGhpcy5jb21wYXJhdG9yID0gcmVnaW9uSW5mby5nZXRDb21wYXJhdG9yKCk7CisgICAgdGhpcy5jb21wYXJhdG9ySWdub3JlVGltZXN0YW1wID0KKyAgICAgIHRoaXMuY29tcGFyYXRvci5nZXRDb21wYXJhdG9ySWdub3JpbmdUaW1lc3RhbXBzKCk7CisgICAgdGhpcy5sb2cgPSBsb2c7CisgICAgdGhpcy5mcyA9IGZzOworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgdGhpcy5yZWdpb25JbmZvID0gcmVnaW9uSW5mbzsKKyAgICB0aGlzLmZsdXNoTGlzdGVuZXIgPSBmbHVzaExpc3RlbmVyOworICAgIHRoaXMudGhyZWFkV2FrZUZyZXF1ZW5jeSA9IGNvbmYuZ2V0TG9uZyhUSFJFQURfV0FLRV9GUkVRVUVOQ1ksIDEwICogMTAwMCk7CisgICAgU3RyaW5nIGVuY29kZWROYW1lU3RyID0gSW50ZWdlci50b1N0cmluZyh0aGlzLnJlZ2lvbkluZm8uZ2V0RW5jb2RlZE5hbWUoKSk7CisgICAgdGhpcy5yZWdpb25kaXIgPSBuZXcgUGF0aChiYXNlZGlyLCBlbmNvZGVkTmFtZVN0cik7CisgICAgdGhpcy5oaXN0b3JpYW4gPSBSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKTsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIC8vIFdyaXRlIG91dCByZWdpb24gbmFtZSBhcyBzdHJpbmcgYW5kIGl0cyBlbmNvZGVkIG5hbWUuCisgICAgICBMT0cuZGVidWcoIk9wZW5pbmcgcmVnaW9uICIgKyB0aGlzICsgIiwgZW5jb2RlZD0iICsKKyAgICAgICAgdGhpcy5yZWdpb25JbmZvLmdldEVuY29kZWROYW1lKCkpOworICAgIH0KKyAgICB0aGlzLnJlZ2lvbkNvbXBhY3Rpb25EaXIgPQorICAgICAgbmV3IFBhdGgoZ2V0Q29tcGFjdGlvbkRpcihiYXNlZGlyKSwgZW5jb2RlZE5hbWVTdHIpOworICAgIGludCBmbHVzaFNpemUgPSByZWdpb25JbmZvLmdldFRhYmxlRGVzYygpLmdldE1lbWNhY2hlRmx1c2hTaXplKCk7CisgICAgaWYgKGZsdXNoU2l6ZSA9PSBIVGFibGVEZXNjcmlwdG9yLkRFRkFVTFRfTUVNQ0FDSEVfRkxVU0hfU0laRSkgeworICAgICAgZmx1c2hTaXplID0gY29uZi5nZXRJbnQoImhiYXNlLmhyZWdpb24ubWVtY2FjaGUuZmx1c2guc2l6ZSIsCisgICAgICAgICAgICAgICAgICAgICAgSFRhYmxlRGVzY3JpcHRvci5ERUZBVUxUX01FTUNBQ0hFX0ZMVVNIX1NJWkUpOworICAgIH0KKyAgICB0aGlzLm1lbWNhY2hlRmx1c2hTaXplID0gZmx1c2hTaXplOworICAgIHRoaXMuYmxvY2tpbmdNZW1jYWNoZVNpemUgPSB0aGlzLm1lbWNhY2hlRmx1c2hTaXplICoKKyAgICAgIGNvbmYuZ2V0SW50KCJoYmFzZS5ocmVnaW9uLm1lbWNhY2hlLmJsb2NrLm11bHRpcGxpZXIiLCAxKTsKKyAgfQorCisgIC8qKgorICAgKiBJbml0aWFsaXplIHRoaXMgcmVnaW9uIGFuZCBnZXQgaXQgcmVhZHkgdG8gcm9sbC4KKyAgICogQ2FsbGVkIGFmdGVyIGNvbnN0cnVjdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSBpbml0aWFsRmlsZXMKKyAgICogQHBhcmFtIHJlcG9ydGVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGluaXRpYWxpemUoUGF0aCBpbml0aWFsRmlsZXMsIGZpbmFsIFByb2dyZXNzYWJsZSByZXBvcnRlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQYXRoIG9sZExvZ0ZpbGUgPSBuZXcgUGF0aChyZWdpb25kaXIsIEhSRUdJT05fT0xETE9HRklMRV9OQU1FKTsKKworICAgIC8vIE1vdmUgcHJlZmFiIEhTdG9yZSBmaWxlcyBpbnRvIHBsYWNlIChpZiBhbnkpLiAgVGhpcyBwaWNrcyB1cCBzcGxpdCBmaWxlcworICAgIC8vIGFuZCBhbnkgbWVyZ2VzIGZyb20gc3BsaXRzIGFuZCBtZXJnZXMgZGlycy4KKyAgICBpZiAoaW5pdGlhbEZpbGVzICE9IG51bGwgJiYgZnMuZXhpc3RzKGluaXRpYWxGaWxlcykpIHsKKyAgICAgIGZzLnJlbmFtZShpbml0aWFsRmlsZXMsIHRoaXMucmVnaW9uZGlyKTsKKyAgICB9CisKKyAgICAvLyBXcml0ZSBIUkkgdG8gYSBmaWxlIGluIGNhc2Ugd2UgbmVlZCB0byByZWNvdmVyIC5NRVRBLgorICAgIGNoZWNrUmVnaW9uaW5mb09uRmlsZXN5c3RlbSgpOworCisgICAgLy8gTG9hZCBpbiBhbGwgdGhlIEhTdG9yZXMuCisgICAgbG9uZyBtYXhTZXFJZCA9IC0xOworICAgIGxvbmcgbWluU2VxSWQgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICBmb3IgKEhDb2x1bW5EZXNjcmlwdG9yIGMgOiB0aGlzLnJlZ2lvbkluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0RmFtaWxpZXMoKSkgeworICAgICAgU3RvcmUgc3RvcmUgPSBpbnN0YW50aWF0ZUhTdG9yZSh0aGlzLmJhc2VkaXIsIGMsIG9sZExvZ0ZpbGUsIHJlcG9ydGVyKTsKKyAgICAgIHRoaXMuc3RvcmVzLnB1dChjLmdldE5hbWUoKSwgc3RvcmUpOworICAgICAgbG9uZyBzdG9yZVNlcUlkID0gc3RvcmUuZ2V0TWF4U2VxdWVuY2VJZCgpOworICAgICAgaWYgKHN0b3JlU2VxSWQgPiBtYXhTZXFJZCkgeworICAgICAgICBtYXhTZXFJZCA9IHN0b3JlU2VxSWQ7CisgICAgICB9CisgICAgICBpZiAoc3RvcmVTZXFJZCA8IG1pblNlcUlkKSB7CisgICAgICAgIG1pblNlcUlkID0gc3RvcmVTZXFJZDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBQbGF5IGxvZyBpZiBvbmUuICBEZWxldGUgd2hlbiBkb25lLgorICAgIGRvUmVjb25zdHJ1Y3Rpb25Mb2cob2xkTG9nRmlsZSwgbWluU2VxSWQsIG1heFNlcUlkLCByZXBvcnRlcik7CisgICAgaWYgKGZzLmV4aXN0cyhvbGRMb2dGaWxlKSkgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiRGVsZXRpbmcgb2xkIGxvZyBmaWxlOiAiICsgb2xkTG9nRmlsZSk7CisgICAgICB9CisgICAgICBmcy5kZWxldGUob2xkTG9nRmlsZSwgZmFsc2UpOworICAgIH0KKyAgICAKKyAgICAvLyBBZGQgb25lIHRvIHRoZSBjdXJyZW50IG1heGltdW0gc2VxdWVuY2UgaWQgc28gbmV3IGVkaXRzIGFyZSBiZXlvbmQuCisgICAgdGhpcy5taW5TZXF1ZW5jZUlkID0gbWF4U2VxSWQgKyAxOworCisgICAgLy8gR2V0IHJpZCBvZiBhbnkgc3BsaXRzIG9yIG1lcmdlcyB0aGF0IHdlcmUgbG9zdCBpbi1wcm9ncmVzcworICAgIEZTVXRpbHMuZGVsZXRlRGlyZWN0b3J5KHRoaXMuZnMsIG5ldyBQYXRoKHJlZ2lvbmRpciwgU1BMSVRESVIpKTsKKyAgICBGU1V0aWxzLmRlbGV0ZURpcmVjdG9yeSh0aGlzLmZzLCBuZXcgUGF0aChyZWdpb25kaXIsIE1FUkdFRElSKSk7CisKKyAgICAvLyBTZWUgaWYgcmVnaW9uIGlzIG1lYW50IHRvIHJ1biByZWFkLW9ubHkuCisgICAgaWYgKHRoaXMucmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKS5pc1JlYWRPbmx5KCkpIHsKKyAgICAgIHRoaXMud3JpdGVzdGF0ZS5zZXRSZWFkT25seSh0cnVlKTsKKyAgICB9CisKKyAgICAvLyBIUmVnaW9uIGlzIHJlYWR5IHRvIGdvIQorICAgIHRoaXMud3JpdGVzdGF0ZS5jb21wYWN0aW5nID0gZmFsc2U7CisgICAgdGhpcy5sYXN0Rmx1c2hUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgTE9HLmluZm8oInJlZ2lvbiAiICsgdGhpcyArICIvIiArIHRoaXMucmVnaW9uSW5mby5nZXRFbmNvZGVkTmFtZSgpICsKKyAgICAgICIgYXZhaWxhYmxlOyBzZXF1ZW5jZSBpZCBpcyAiICsgdGhpcy5taW5TZXF1ZW5jZUlkKTsKKyAgfQorCisgIC8qCisgICAqIFdyaXRlIG91dCBhbiBpbmZvIGZpbGUgdW5kZXIgdGhlIHJlZ2lvbiBkaXJlY3RvcnkuICBVc2VmdWwgcmVjb3ZlcmluZworICAgKiBtYW5nbGVkIHJlZ2lvbnMuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja1JlZ2lvbmluZm9PbkZpbGVzeXN0ZW0oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIE5hbWUgb2YgdGhpcyBmaWxlIGhhcyB0d28gbGVhZGluZyBhbmQgdHJhaWxpbmcgdW5kZXJzY29yZXMgc28gaXQgZG9lc24ndAorICAgIC8vIGNsYXNoIHcvIGEgc3RvcmUvZmFtaWx5IG5hbWUuICBUaGVyZSBpcyBwb3NzaWJpbGl0eSwgYnV0IGFzc3VtcHRpb24gaXMKKyAgICAvLyB0aGF0IGl0cyBzbGltIChkb24ndCB3YW50IHRvIHVzZSBjb250cm9sIGNoYXJhY3RlciBpbiBmaWxlbmFtZSBiZWNhdXNlCisgICAgLy8gCisgICAgUGF0aCByZWdpb25pbmZvID0gbmV3IFBhdGgodGhpcy5yZWdpb25kaXIsIFJFR0lPTklORk9fRklMRSk7CisgICAgaWYgKHRoaXMuZnMuZXhpc3RzKHJlZ2lvbmluZm8pICYmCisgICAgICAgIHRoaXMuZnMuZ2V0RmlsZVN0YXR1cyhyZWdpb25pbmZvKS5nZXRMZW4oKSA+IDApIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgRlNEYXRhT3V0cHV0U3RyZWFtIG91dCA9IHRoaXMuZnMuY3JlYXRlKHJlZ2lvbmluZm8sIHRydWUpOworICAgIHRyeSB7CisgICAgICB0aGlzLnJlZ2lvbkluZm8ud3JpdGUob3V0KTsKKyAgICAgIG91dC53cml0ZSgnXG4nKTsKKyAgICAgIG91dC53cml0ZSgnXG4nKTsKKyAgICAgIG91dC53cml0ZShCeXRlcy50b0J5dGVzKHRoaXMucmVnaW9uSW5mby50b1N0cmluZygpKSk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG91dC5jbG9zZSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFVwZGF0ZXMgdG8gdGhpcyByZWdpb24gbmVlZCB0byBoYXZlIGEgc2VxdWVuY2UgaWQgdGhhdCBpcyA+PSB0bworICAgKiB0aGUgdGhpcyBudW1iZXIuCisgICAqLworICBsb25nIGdldE1pblNlcXVlbmNlSWQoKSB7CisgICAgcmV0dXJuIHRoaXMubWluU2VxdWVuY2VJZDsKKyAgfQorICAKKyAgLyoqIEByZXR1cm4gYSBIUmVnaW9uSW5mbyBvYmplY3QgZm9yIHRoaXMgcmVnaW9uICovCisgIHB1YmxpYyBIUmVnaW9uSW5mbyBnZXRSZWdpb25JbmZvKCkgeworICAgIHJldHVybiB0aGlzLnJlZ2lvbkluZm87CisgIH0KKworICAvKiogQHJldHVybiB0cnVlIGlmIHJlZ2lvbiBpcyBjbG9zZWQgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNDbG9zZWQoKSB7CisgICAgcmV0dXJuIHRoaXMuY2xvc2VkLmdldCgpOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiBUcnVlIGlmIGNsb3NpbmcgcHJvY2VzcyBoYXMgc3RhcnRlZC4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzQ2xvc2luZygpIHsKKyAgICByZXR1cm4gdGhpcy5jbG9zaW5nLmdldCgpOworICB9CisKKyAgLyoqCisgICAqIENsb3NlIGRvd24gdGhpcyBIUmVnaW9uLiAgRmx1c2ggdGhlIGNhY2hlLCBzaHV0IGRvd24gZWFjaCBIU3RvcmUsIGRvbid0IAorICAgKiBzZXJ2aWNlIGFueSBtb3JlIGNhbGxzLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBjb3VsZCB0YWtlIHNvbWUgdGltZSB0byBleGVjdXRlLCBzbyBkb24ndCBjYWxsIGl0IGZyb20gYSAKKyAgICogdGltZS1zZW5zaXRpdmUgdGhyZWFkLgorICAgKiAKKyAgICogQHJldHVybiBWZWN0b3Igb2YgYWxsIHRoZSBzdG9yYWdlIGZpbGVzIHRoYXQgdGhlIEhSZWdpb24ncyBjb21wb25lbnQgCisgICAqIEhTdG9yZXMgbWFrZSB1c2Ugb2YuICBJdCdzIGEgbGlzdCBvZiBhbGwgSFN0b3JlRmlsZSBvYmplY3RzLiBSZXR1cm5zIGVtcHR5CisgICAqIHZlY3RvciBpZiBhbHJlYWR5IGNsb3NlZCBhbmQgbnVsbCBpZiBqdWRnZWQgdGhhdCBpdCBzaG91bGQgbm90IGNsb3NlLgorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIExpc3Q8U3RvcmVGaWxlPiBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNsb3NlKGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBDbG9zZSBkb3duIHRoaXMgSFJlZ2lvbi4gIEZsdXNoIHRoZSBjYWNoZSB1bmxlc3MgYWJvcnQgcGFyYW1ldGVyIGlzIHRydWUsCisgICAqIFNodXQgZG93biBlYWNoIEhTdG9yZSwgZG9uJ3Qgc2VydmljZSBhbnkgbW9yZSBjYWxscy4KKyAgICoKKyAgICogVGhpcyBtZXRob2QgY291bGQgdGFrZSBzb21lIHRpbWUgdG8gZXhlY3V0ZSwgc28gZG9uJ3QgY2FsbCBpdCBmcm9tIGEgCisgICAqIHRpbWUtc2Vuc2l0aXZlIHRocmVhZC4KKyAgICogCisgICAqIEBwYXJhbSBhYm9ydCB0cnVlIGlmIHNlcnZlciBpcyBhYm9ydGluZyAob25seSBkdXJpbmcgdGVzdGluZykKKyAgICogQHJldHVybiBWZWN0b3Igb2YgYWxsIHRoZSBzdG9yYWdlIGZpbGVzIHRoYXQgdGhlIEhSZWdpb24ncyBjb21wb25lbnQgCisgICAqIEhTdG9yZXMgbWFrZSB1c2Ugb2YuICBJdCdzIGEgbGlzdCBvZiBIU3RvcmVGaWxlIG9iamVjdHMuICBDYW4gYmUgbnVsbCBpZgorICAgKiB3ZSBhcmUgbm90IHRvIGNsb3NlIGF0IHRoaXMgdGltZSBvciB3ZSBhcmUgYWxyZWFkeSBjbG9zZWQuCisgICAqIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBMaXN0PFN0b3JlRmlsZT4gY2xvc2UoZmluYWwgYm9vbGVhbiBhYm9ydCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoaXNDbG9zZWQoKSkgeworICAgICAgTE9HLndhcm4oInJlZ2lvbiAiICsgdGhpcyArICIgYWxyZWFkeSBjbG9zZWQiKTsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICB0aGlzLmNsb3Npbmcuc2V0KHRydWUpOworICAgIHN5bmNocm9uaXplZCAoc3BsaXRMb2NrKSB7CisgICAgICBzeW5jaHJvbml6ZWQgKHdyaXRlc3RhdGUpIHsKKyAgICAgICAgLy8gRGlzYWJsZSBjb21wYWN0aW5nIGFuZCBmbHVzaGluZyBieSBiYWNrZ3JvdW5kIHRocmVhZHMgZm9yIHRoaXMKKyAgICAgICAgLy8gcmVnaW9uLgorICAgICAgICB3cml0ZXN0YXRlLndyaXRlc0VuYWJsZWQgPSBmYWxzZTsKKyAgICAgICAgTE9HLmRlYnVnKCJDbG9zaW5nICIgKyB0aGlzICsgIjogY29tcGFjdGlvbnMgJiBmbHVzaGVzIGRpc2FibGVkICIpOworICAgICAgICB3aGlsZSAod3JpdGVzdGF0ZS5jb21wYWN0aW5nIHx8IHdyaXRlc3RhdGUuZmx1c2hpbmcpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIndhaXRpbmcgZm9yIiArCisgICAgICAgICAgICAgICh3cml0ZXN0YXRlLmNvbXBhY3RpbmcgPyAiIGNvbXBhY3Rpb24iIDogIiIpICsKKyAgICAgICAgICAgICAgKHdyaXRlc3RhdGUuZmx1c2hpbmcgPworICAgICAgICAgICAgICAgICAgKHdyaXRlc3RhdGUuY29tcGFjdGluZyA/ICIsIiA6ICIiKSArICIgY2FjaGUgZmx1c2giIDoKKyAgICAgICAgICAgICAgICAgICAgIiIpICsgIiB0byBjb21wbGV0ZSBmb3IgcmVnaW9uICIgKyB0aGlzKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgd3JpdGVzdGF0ZS53YWl0KCk7CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWV4KSB7CisgICAgICAgICAgICAvLyBjb250aW51ZQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgbmV3U2Nhbm5lckxvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgICAgdHJ5IHsKKyAgICAgICAgLy8gV2FpdCBmb3IgYWN0aXZlIHNjYW5uZXJzIHRvIGZpbmlzaC4gVGhlIHdyaXRlIGxvY2sgd2UgaG9sZCB3aWxsCisgICAgICAgIC8vIHByZXZlbnQgbmV3IHNjYW5uZXJzIGZyb20gYmVpbmcgY3JlYXRlZC4KKyAgICAgICAgc3luY2hyb25pemVkIChhY3RpdmVTY2FubmVyQ291bnQpIHsKKyAgICAgICAgICB3aGlsZSAoYWN0aXZlU2Nhbm5lckNvdW50LmdldCgpICE9IDApIHsKKyAgICAgICAgICAgIExPRy5kZWJ1Zygid2FpdGluZyBmb3IgIiArIGFjdGl2ZVNjYW5uZXJDb3VudC5nZXQoKSArCisgICAgICAgICAgICAgICAgIiBzY2FubmVycyB0byBmaW5pc2giKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgIGFjdGl2ZVNjYW5uZXJDb3VudC53YWl0KCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgICAgICBMT0cuZGVidWcoIlVwZGF0ZXMgZGlzYWJsZWQgZm9yIHJlZ2lvbiwgbm8gb3V0c3RhbmRpbmcgc2Nhbm5lcnMgb24gIiArCisgICAgICAgICAgdGhpcyk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgLy8gV3JpdGUgbG9jayBtZWFucyBubyBtb3JlIHJvdyBsb2NrcyBjYW4gYmUgZ2l2ZW4gb3V0LiAgV2FpdCBvbgorICAgICAgICAgIC8vIG91dHN0YW5kaW5nIHJvdyBsb2NrcyB0byBjb21lIGluIGJlZm9yZSB3ZSBjbG9zZSBzbyB3ZSBkbyBub3QgZHJvcAorICAgICAgICAgIC8vIG91dHN0YW5kaW5nIHVwZGF0ZXMuCisgICAgICAgICAgd2FpdE9uUm93TG9ja3MoKTsKKyAgICAgICAgICBMT0cuZGVidWcoIk5vIG1vcmUgcm93IGxvY2tzIG91dHN0YW5kaW5nIG9uIHJlZ2lvbiAiICsgdGhpcyk7CisgIAorICAgICAgICAgIC8vIERvbid0IGZsdXNoIHRoZSBjYWNoZSBpZiB3ZSBhcmUgYWJvcnRpbmcKKyAgICAgICAgICBpZiAoIWFib3J0KSB7CisgICAgICAgICAgICBpbnRlcm5hbEZsdXNoY2FjaGUoKTsKKyAgICAgICAgICB9CisgIAorICAgICAgICAgIExpc3Q8U3RvcmVGaWxlPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFN0b3JlRmlsZT4oKTsKKyAgICAgICAgICBmb3IgKFN0b3JlIHN0b3JlOiBzdG9yZXMudmFsdWVzKCkpIHsKKyAgICAgICAgICAgIHJlc3VsdC5hZGRBbGwoc3RvcmUuY2xvc2UoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIHRoaXMuY2xvc2VkLnNldCh0cnVlKTsKKyAgICAgICAgICBMT0cuaW5mbygiQ2xvc2VkICIgKyB0aGlzKTsKKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sud3JpdGVMb2NrKCkudW5sb2NrKCk7CisgICAgICAgIH0KKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIG5ld1NjYW5uZXJMb2NrLndyaXRlTG9jaygpLnVubG9jaygpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAvLyBIUmVnaW9uIGFjY2Vzc29ycworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAvKiogQHJldHVybiBzdGFydCBrZXkgZm9yIHJlZ2lvbiAqLworICBwdWJsaWMgYnl0ZSBbXSBnZXRTdGFydEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFN0YXJ0S2V5KCk7CisgIH0KKworICAvKiogQHJldHVybiBlbmQga2V5IGZvciByZWdpb24gKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0RW5kS2V5KCkgeworICAgIHJldHVybiB0aGlzLnJlZ2lvbkluZm8uZ2V0RW5kS2V5KCk7CisgIH0KKworICAvKiogQHJldHVybiByZWdpb24gaWQgKi8KKyAgcHVibGljIGxvbmcgZ2V0UmVnaW9uSWQoKSB7CisgICAgcmV0dXJuIHRoaXMucmVnaW9uSW5mby5nZXRSZWdpb25JZCgpOworICB9CisKKyAgLyoqIEByZXR1cm4gcmVnaW9uIG5hbWUgKi8KKyAgcHVibGljIGJ5dGUgW10gZ2V0UmVnaW9uTmFtZSgpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIEhUYWJsZURlc2NyaXB0b3IgZm9yIHRoaXMgcmVnaW9uICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlRGVzYygpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFRhYmxlRGVzYygpOworICB9CisKKyAgLyoqIEByZXR1cm4gSExvZyBpbiB1c2UgZm9yIHRoaXMgcmVnaW9uICovCisgIHB1YmxpYyBITG9nIGdldExvZygpIHsKKyAgICByZXR1cm4gdGhpcy5sb2c7CisgIH0KKworICAvKiogQHJldHVybiBDb25maWd1cmF0aW9uIG9iamVjdCAqLworICBwdWJsaWMgSEJhc2VDb25maWd1cmF0aW9uIGdldENvbmYoKSB7CisgICAgcmV0dXJuIHRoaXMuY29uZjsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHJlZ2lvbiBkaXJlY3RvcnkgUGF0aCAqLworICBwdWJsaWMgUGF0aCBnZXRSZWdpb25EaXIoKSB7CisgICAgcmV0dXJuIHRoaXMucmVnaW9uZGlyOworICB9CisKKyAgLyoqIEByZXR1cm4gRmlsZVN5c3RlbSBiZWluZyB1c2VkIGJ5IHRoaXMgcmVnaW9uICovCisgIHB1YmxpYyBGaWxlU3lzdGVtIGdldEZpbGVzeXN0ZW0oKSB7CisgICAgcmV0dXJuIHRoaXMuZnM7CisgIH0KKworICAvKiogQHJldHVybiB0aGUgbGFzdCB0aW1lIHRoZSByZWdpb24gd2FzIGZsdXNoZWQgKi8KKyAgcHVibGljIGxvbmcgZ2V0TGFzdEZsdXNoVGltZSgpIHsKKyAgICByZXR1cm4gdGhpcy5sYXN0Rmx1c2hUaW1lOworICB9CisgIAorICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy8gSFJlZ2lvbiBtYWludGVuYW5jZS4gIAorICAvLworICAvLyBUaGVzZSBtZXRob2RzIGFyZSBtZWFudCB0byBiZSBjYWxsZWQgcGVyaW9kaWNhbGx5IGJ5IHRoZSBIUmVnaW9uU2VydmVyIGZvciAKKyAgLy8gdXBrZWVwLgorICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAvKiogQHJldHVybiByZXR1cm5zIHNpemUgb2YgbGFyZ2VzdCBIU3RvcmUuICovCisgIHB1YmxpYyBsb25nIGdldExhcmdlc3RIU3RvcmVTaXplKCkgeworICAgIGxvbmcgc2l6ZSA9IDA7CisgICAgZm9yIChTdG9yZSBoOiBzdG9yZXMudmFsdWVzKCkpIHsKKyAgICAgIGxvbmcgc3RvcmVTaXplID0gaC5nZXRTaXplKCk7CisgICAgICBpZiAoc3RvcmVTaXplID4gc2l6ZSkgeworICAgICAgICBzaXplID0gc3RvcmVTaXplOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIC8qCisgICAqIFNwbGl0IHRoZSBIUmVnaW9uIHRvIGNyZWF0ZSB0d28gYnJhbmQtbmV3IG9uZXMuICBUaGlzIGFsc28gY2xvc2VzCisgICAqIGN1cnJlbnQgSFJlZ2lvbi4gIFNwbGl0IHNob3VsZCBiZSBmYXN0IHNpbmNlIHdlIGRvbid0IHJld3JpdGUgc3RvcmUgZmlsZXMKKyAgICogYnV0IGluc3RlYWQgY3JlYXRlIG5ldyAncmVmZXJlbmNlJyBzdG9yZSBmaWxlcyB0aGF0IHJlYWQgb2ZmIHRoZSB0b3AgYW5kCisgICAqIGJvdHRvbSByYW5nZXMgb2YgcGFyZW50IHN0b3JlIGZpbGVzLgorICAgKiBAcGFyYW0gc3BsaXRSb3cgcm93IG9uIHdoaWNoIHRvIHNwbGl0IHJlZ2lvbgorICAgKiBAcmV0dXJuIHR3byBicmFuZC1uZXcgKGFuZCBvcGVuKSBIUmVnaW9ucyBvciBudWxsIGlmIGEgc3BsaXQgaXMgbm90IG5lZWRlZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBIUmVnaW9uIFtdIHNwbGl0UmVnaW9uKGZpbmFsIGJ5dGUgW10gc3BsaXRSb3cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3luY2hyb25pemVkIChzcGxpdExvY2spIHsKKyAgICAgIGlmIChjbG9zZWQuZ2V0KCkpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICAvLyBBZGQgc3RhcnQvZW5kIGtleSBjaGVja2luZzogaGJhc2UtNDI4LgorICAgICAgYnl0ZSBbXSBzdGFydEtleSA9IHRoaXMucmVnaW9uSW5mby5nZXRTdGFydEtleSgpOworICAgICAgYnl0ZSBbXSBlbmRLZXkgPSB0aGlzLnJlZ2lvbkluZm8uZ2V0RW5kS2V5KCk7CisgICAgICBpZiAodGhpcy5jb21wYXJhdG9yLm1hdGNoaW5nUm93cyhzdGFydEtleSwgMCwgc3RhcnRLZXkubGVuZ3RoLAorICAgICAgICAgIHNwbGl0Um93LCAwLCBzcGxpdFJvdy5sZW5ndGgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiU3RhcnRrZXkgYW5kIG1pZGtleSBhcmUgc2FtZSwgbm90IHNwbGl0dGluZyIpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbXBhcmF0b3IubWF0Y2hpbmdSb3dzKHNwbGl0Um93LCAwLCBzcGxpdFJvdy5sZW5ndGgsCisgICAgICAgICAgZW5kS2V5LCAwLCBlbmRLZXkubGVuZ3RoKSkgeworICAgICAgICBMT0cuZGVidWcoIkVuZGtleSBhbmQgbWlka2V5IGFyZSBzYW1lLCBub3Qgc3BsaXR0aW5nIik7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgTE9HLmluZm8oIlN0YXJ0aW5nIHNwbGl0IG9mIHJlZ2lvbiAiICsgdGhpcyk7CisgICAgICBQYXRoIHNwbGl0cyA9IG5ldyBQYXRoKHRoaXMucmVnaW9uZGlyLCBTUExJVERJUik7CisgICAgICBpZighdGhpcy5mcy5leGlzdHMoc3BsaXRzKSkgeworICAgICAgICB0aGlzLmZzLm1rZGlycyhzcGxpdHMpOworICAgICAgfQorICAgICAgLy8gQ2FsY3VsYXRlIHJlZ2lvbmlkIHRvIHVzZS4gIENhbid0IGJlIGxlc3MgdGhhbiB0aGF0IG9mIHBhcmVudCBlbHNlCisgICAgICAvLyBpdCdsbCBpbnNlcnQgaW50byB3cm9uZyBsb2NhdGlvbiBvdmVyIGluIC5NRVRBLiB0YWJsZTogSEJBU0UtNzEwLgorICAgICAgbG9uZyByaWQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgIGlmIChyaWQgPCB0aGlzLnJlZ2lvbkluZm8uZ2V0UmVnaW9uSWQoKSkgeworICAgICAgICBMT0cud2FybigiQ2xvY2sgc2tldzsgcGFyZW50IHJlZ2lvbnMgaWQgaXMgIiArCisgICAgICAgICAgdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbklkKCkgKyAiIGJ1dCBjdXJyZW50IHRpbWUgaGVyZSBpcyAiICsgcmlkKTsKKyAgICAgICAgcmlkID0gdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbklkKCkgKyAxOworICAgICAgfQorICAgICAgSFJlZ2lvbkluZm8gcmVnaW9uQUluZm8gPSBuZXcgSFJlZ2lvbkluZm8odGhpcy5yZWdpb25JbmZvLmdldFRhYmxlRGVzYygpLAorICAgICAgICBzdGFydEtleSwgc3BsaXRSb3csIGZhbHNlLCByaWQpOworICAgICAgUGF0aCBkaXJBID0KKyAgICAgICAgbmV3IFBhdGgoc3BsaXRzLCBJbnRlZ2VyLnRvU3RyaW5nKHJlZ2lvbkFJbmZvLmdldEVuY29kZWROYW1lKCkpKTsKKyAgICAgIGlmKGZzLmV4aXN0cyhkaXJBKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbm5vdCBzcGxpdDsgdGFyZ2V0IGZpbGUgY29sbGlzaW9uIGF0ICIgKyBkaXJBKTsKKyAgICAgIH0KKyAgICAgIEhSZWdpb25JbmZvIHJlZ2lvbkJJbmZvID0gbmV3IEhSZWdpb25JbmZvKHRoaXMucmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKSwKKyAgICAgICAgc3BsaXRSb3csIGVuZEtleSwgZmFsc2UsIHJpZCk7CisgICAgICBQYXRoIGRpckIgPQorICAgICAgICBuZXcgUGF0aChzcGxpdHMsIEludGVnZXIudG9TdHJpbmcocmVnaW9uQkluZm8uZ2V0RW5jb2RlZE5hbWUoKSkpOworICAgICAgaWYodGhpcy5mcy5leGlzdHMoZGlyQikpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDYW5ub3Qgc3BsaXQ7IHRhcmdldCBmaWxlIGNvbGxpc2lvbiBhdCAiICsgZGlyQik7CisgICAgICB9CisKKyAgICAgIC8vIE5vdyBjbG9zZSB0aGUgSFJlZ2lvbi4gIENsb3NlIHJldHVybnMgYWxsIHN0b3JlIGZpbGVzIG9yIG51bGwgaWYgbm90CisgICAgICAvLyBzdXBwb3NlZCB0byBjbG9zZSAoPyBXaGF0IHRvIGRvIGluIHRoaXMgY2FzZT8gSW1wbGVtZW50IGFib3J0IG9mIGNsb3NlPykKKyAgICAgIC8vIENsb3NlIGFsc28gZG9lcyB3YWl0IG9uIG91dHN0YW5kaW5nIHJvd3MgYW5kIGNhbGxzIGEgZmx1c2gganVzdC1pbi1jYXNlLgorICAgICAgTGlzdDxTdG9yZUZpbGU+IGhzdG9yZUZpbGVzVG9TcGxpdCA9IGNsb3NlKGZhbHNlKTsKKyAgICAgIGlmIChoc3RvcmVGaWxlc1RvU3BsaXQgPT0gbnVsbCkgeworICAgICAgICBMT0cud2FybigiQ2xvc2UgY2FtZSBiYWNrIG51bGwgKEltcGxlbWVudCBhYm9ydCBvZiBjbG9zZT8pIik7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJjbG9zZSByZXR1cm5lZCBlbXB0eSB2ZWN0b3Igb2YgSFN0b3JlRmlsZXMiKTsKKyAgICAgIH0KKworICAgICAgLy8gU3BsaXQgZWFjaCBzdG9yZSBmaWxlLgorICAgICAgZm9yKFN0b3JlRmlsZSBoOiBoc3RvcmVGaWxlc1RvU3BsaXQpIHsKKyAgICAgICAgU3RvcmVGaWxlLnNwbGl0KGZzLAorICAgICAgICAgIFN0b3JlLmdldFN0b3JlSG9tZWRpcihzcGxpdHMsIHJlZ2lvbkFJbmZvLmdldEVuY29kZWROYW1lKCksCisgICAgICAgICAgICBoLmdldEZhbWlseSgpKSwKKyAgICAgICAgICBoLCBzcGxpdFJvdywgUmFuZ2UuYm90dG9tKTsKKyAgICAgICAgU3RvcmVGaWxlLnNwbGl0KGZzLAorICAgICAgICAgIFN0b3JlLmdldFN0b3JlSG9tZWRpcihzcGxpdHMsIHJlZ2lvbkJJbmZvLmdldEVuY29kZWROYW1lKCksCisgICAgICAgICAgICBoLmdldEZhbWlseSgpKSwKKyAgICAgICAgICBoLCBzcGxpdFJvdywgUmFuZ2UudG9wKTsKKyAgICAgIH0KKworICAgICAgLy8gRG9uZSEKKyAgICAgIC8vIE9wZW5pbmcgdGhlIHJlZ2lvbiBjb3BpZXMgdGhlIHNwbGl0cyBmaWxlcyBmcm9tIHRoZSBzcGxpdHMgZGlyZWN0b3J5CisgICAgICAvLyB1bmRlciBlYWNoIHJlZ2lvbi4KKyAgICAgIEhSZWdpb24gcmVnaW9uQSA9IG5ldyBIUmVnaW9uKGJhc2VkaXIsIGxvZywgZnMsIGNvbmYsIHJlZ2lvbkFJbmZvLCBudWxsKTsKKyAgICAgIHJlZ2lvbkEuaW5pdGlhbGl6ZShkaXJBLCBudWxsKTsKKyAgICAgIHJlZ2lvbkEuY2xvc2UoKTsKKyAgICAgIEhSZWdpb24gcmVnaW9uQiA9IG5ldyBIUmVnaW9uKGJhc2VkaXIsIGxvZywgZnMsIGNvbmYsIHJlZ2lvbkJJbmZvLCBudWxsKTsKKyAgICAgIHJlZ2lvbkIuaW5pdGlhbGl6ZShkaXJCLCBudWxsKTsKKyAgICAgIHJlZ2lvbkIuY2xvc2UoKTsKKworICAgICAgLy8gQ2xlYW51cAorICAgICAgYm9vbGVhbiBkZWxldGVkID0gZnMuZGVsZXRlKHNwbGl0cywgdHJ1ZSk7IC8vIEdldCByaWQgb2Ygc3BsaXRzIGRpcmVjdG9yeQorICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiQ2xlYW5lZCB1cCAiICsgRlNVdGlscy5nZXRQYXRoKHNwbGl0cykgKyAiICIgKyBkZWxldGVkKTsKKyAgICAgIH0KKyAgICAgIEhSZWdpb24gcmVnaW9uc1tdID0gbmV3IEhSZWdpb24gW10ge3JlZ2lvbkEsIHJlZ2lvbkJ9OworICAgICAgdGhpcy5oaXN0b3JpYW4uYWRkUmVnaW9uU3BsaXQodGhpcy5yZWdpb25JbmZvLAorICAgICAgICByZWdpb25BLmdldFJlZ2lvbkluZm8oKSwgcmVnaW9uQi5nZXRSZWdpb25JbmZvKCkpOworICAgICAgcmV0dXJuIHJlZ2lvbnM7CisgICAgfQorICB9CisgIAorICAvKgorICAgKiBAcGFyYW0gZGlyCisgICAqIEByZXR1cm4gY29tcGFjdGlvbiBkaXJlY3RvcnkgZm9yIHRoZSBwYXNzZWQgaW4gPGNvZGU+ZGlyPC9jb2RlPgorICAgKi8KKyAgc3RhdGljIFBhdGggZ2V0Q29tcGFjdGlvbkRpcihmaW5hbCBQYXRoIGRpcikgeworICAgcmV0dXJuIG5ldyBQYXRoKGRpciwgSFJFR0lPTl9DT01QQUNUSU9ORElSX05BTUUpOworICB9CisKKyAgLyoKKyAgICogRG8gcHJlcGFyYXRpb24gZm9yIHBlbmRpbmcgY29tcGFjdGlvbi4KKyAgICogQ2xlYW4gb3V0IGFueSB2ZXN0aWdlcyBvZiBwcmV2aW91cyBmYWlsZWQgY29tcGFjdGlvbnMuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgdm9pZCBkb1JlZ2lvbkNvbXBhY3Rpb25QcmVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkb1JlZ2lvbkNvbXBhY3Rpb25DbGVhbnVwKCk7CisgIH0KKyAgCisgIC8qCisgICAqIFJlbW92ZXMgdGhlIGNvbXBhY3Rpb24gZGlyZWN0b3J5IGZvciB0aGlzIFN0b3JlLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgZG9SZWdpb25Db21wYWN0aW9uQ2xlYW51cCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRlNVdGlscy5kZWxldGVEaXJlY3RvcnkodGhpcy5mcywgdGhpcy5yZWdpb25Db21wYWN0aW9uRGlyKTsKKyAgfQorCisgIHZvaWQgc2V0Rm9yY2VNYWpvckNvbXBhY3Rpb24oZmluYWwgYm9vbGVhbiBiKSB7CisgICAgdGhpcy5mb3JjZU1ham9yQ29tcGFjdGlvbiA9IGI7CisgIH0KKworICBib29sZWFuIGdldEZvcmNlTWFqb3JDb21wYWN0aW9uKCkgeworICAgIHJldHVybiB0aGlzLmZvcmNlTWFqb3JDb21wYWN0aW9uOworICB9CisKKyAgLyoqCisgICAqIENhbGxlZCBieSBjb21wYWN0aW9uIHRocmVhZCBhbmQgYWZ0ZXIgcmVnaW9uIGlzIG9wZW5lZCB0byBjb21wYWN0IHRoZQorICAgKiBIU3RvcmVzIGlmIG5lY2Vzc2FyeS4KKyAgICoKKyAgICogPHA+VGhpcyBvcGVyYXRpb24gY291bGQgYmxvY2sgZm9yIGEgbG9uZyB0aW1lLCBzbyBkb24ndCBjYWxsIGl0IGZyb20gYSAKKyAgICogdGltZS1zZW5zaXRpdmUgdGhyZWFkLgorICAgKgorICAgKiBOb3RlIHRoYXQgbm8gbG9ja2luZyBpcyBuZWNlc3NhcnkgYXQgdGhpcyBsZXZlbCBiZWNhdXNlIGNvbXBhY3Rpb24gb25seQorICAgKiBjb25mbGljdHMgd2l0aCBhIHJlZ2lvbiBzcGxpdCwgYW5kIHRoYXQgY2Fubm90IGhhcHBlbiBiZWNhdXNlIHRoZSByZWdpb24KKyAgICogc2VydmVyIGRvZXMgdGhlbSBzZXF1ZW50aWFsbHkgYW5kIG5vdCBpbiBwYXJhbGxlbC4KKyAgICogCisgICAqIEByZXR1cm4gbWlkIGtleSBpZiBzcGxpdCBpcyBuZWVkZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJ5dGUgW10gY29tcGFjdFN0b3JlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiBtYWpvckNvbXBhY3Rpb24gPSB0aGlzLmZvcmNlTWFqb3JDb21wYWN0aW9uOworICAgIHRoaXMuZm9yY2VNYWpvckNvbXBhY3Rpb24gPSBmYWxzZTsKKyAgICByZXR1cm4gY29tcGFjdFN0b3JlcyhtYWpvckNvbXBhY3Rpb24pOworICB9CisKKyAgLyoKKyAgICogQ2FsbGVkIGJ5IGNvbXBhY3Rpb24gdGhyZWFkIGFuZCBhZnRlciByZWdpb24gaXMgb3BlbmVkIHRvIGNvbXBhY3QgdGhlCisgICAqIEhTdG9yZXMgaWYgbmVjZXNzYXJ5LgorICAgKgorICAgKiA8cD5UaGlzIG9wZXJhdGlvbiBjb3VsZCBibG9jayBmb3IgYSBsb25nIHRpbWUsIHNvIGRvbid0IGNhbGwgaXQgZnJvbSBhIAorICAgKiB0aW1lLXNlbnNpdGl2ZSB0aHJlYWQuCisgICAqCisgICAqIE5vdGUgdGhhdCBubyBsb2NraW5nIGlzIG5lY2Vzc2FyeSBhdCB0aGlzIGxldmVsIGJlY2F1c2UgY29tcGFjdGlvbiBvbmx5CisgICAqIGNvbmZsaWN0cyB3aXRoIGEgcmVnaW9uIHNwbGl0LCBhbmQgdGhhdCBjYW5ub3QgaGFwcGVuIGJlY2F1c2UgdGhlIHJlZ2lvbgorICAgKiBzZXJ2ZXIgZG9lcyB0aGVtIHNlcXVlbnRpYWxseSBhbmQgbm90IGluIHBhcmFsbGVsLgorICAgKiAKKyAgICogQHBhcmFtIG1ham9yQ29tcGFjdGlvbiBUcnVlIHRvIGZvcmNlIGEgbWFqb3IgY29tcGFjdGlvbiByZWdhcmRsZXNzIG9mIHRocmVzaG9sZHMKKyAgICogQHJldHVybiBzcGxpdCByb3cgaWYgc3BsaXQgaXMgbmVlZGVkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIGJ5dGUgW10gY29tcGFjdFN0b3JlcyhmaW5hbCBib29sZWFuIG1ham9yQ29tcGFjdGlvbikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzcGxpdHNBbmRDbG9zZXNMb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBieXRlIFtdIHNwbGl0Um93ID0gbnVsbDsKKyAgICAgIGlmICh0aGlzLmNsb3NlZC5nZXQoKSkgeworICAgICAgICByZXR1cm4gc3BsaXRSb3c7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHdyaXRlc3RhdGUpIHsKKyAgICAgICAgICBpZiAoIXdyaXRlc3RhdGUuY29tcGFjdGluZyAmJiB3cml0ZXN0YXRlLndyaXRlc0VuYWJsZWQpIHsKKyAgICAgICAgICAgIHdyaXRlc3RhdGUuY29tcGFjdGluZyA9IHRydWU7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJOT1QgY29tcGFjdGluZyByZWdpb24gIiArIHRoaXMgKworICAgICAgICAgICAgICAgICI6IGNvbXBhY3Rpbmc9IiArIHdyaXRlc3RhdGUuY29tcGFjdGluZyArICIsIHdyaXRlc0VuYWJsZWQ9IiArCisgICAgICAgICAgICAgICAgd3JpdGVzdGF0ZS53cml0ZXNFbmFibGVkKTsKKyAgICAgICAgICAgICAgcmV0dXJuIHNwbGl0Um93OworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBMT0cuaW5mbygiU3RhcnRpbmciICsgKG1ham9yQ29tcGFjdGlvbj8gIiBtYWpvciAiIDogIiAiKSArIAorICAgICAgICAgICAgImNvbXBhY3Rpb24gb24gcmVnaW9uICIgKyB0aGlzKTsKKyAgICAgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgZG9SZWdpb25Db21wYWN0aW9uUHJlcCgpOworICAgICAgICBsb25nIG1heFNpemUgPSAtMTsKKyAgICAgICAgZm9yIChTdG9yZSBzdG9yZTogc3RvcmVzLnZhbHVlcygpKSB7CisgICAgICAgICAgZmluYWwgU3RvcmUuU3RvcmVTaXplIHNzID0gc3RvcmUuY29tcGFjdChtYWpvckNvbXBhY3Rpb24pOworICAgICAgICAgIGlmIChzcyAhPSBudWxsICYmIHNzLmdldFNpemUoKSA+IG1heFNpemUpIHsKKyAgICAgICAgICAgIG1heFNpemUgPSBzcy5nZXRTaXplKCk7CisgICAgICAgICAgICBzcGxpdFJvdyA9IHNzLmdldFNwbGl0Um93KCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGRvUmVnaW9uQ29tcGFjdGlvbkNsZWFudXAoKTsKKyAgICAgICAgU3RyaW5nIHRpbWVUYWtlbiA9IFN0cmluZ1V0aWxzLmZvcm1hdFRpbWVEaWZmKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLCAKKyAgICAgICAgICAgIHN0YXJ0VGltZSk7CisgICAgICAgIExPRy5pbmZvKCJjb21wYWN0aW9uIGNvbXBsZXRlZCBvbiByZWdpb24gIiArIHRoaXMgKyAiIGluICIgKyB0aW1lVGFrZW4pOworICAgICAgICB0aGlzLmhpc3Rvcmlhbi5hZGRSZWdpb25Db21wYWN0aW9uKHJlZ2lvbkluZm8sIHRpbWVUYWtlbik7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKHdyaXRlc3RhdGUpIHsKKyAgICAgICAgICB3cml0ZXN0YXRlLmNvbXBhY3RpbmcgPSBmYWxzZTsKKyAgICAgICAgICB3cml0ZXN0YXRlLm5vdGlmeUFsbCgpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gc3BsaXRSb3c7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRmx1c2ggdGhlIGNhY2hlLgorICAgKiAKKyAgICogV2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgdGhlIGNhY2hlIHdpbGwgYmUgZmx1c2hlZCB1bmxlc3M6CisgICAqIDxvbD4KKyAgICogICA8bGk+dGhlIGNhY2hlIGlzIGVtcHR5PC9saT4KKyAgICogICA8bGk+dGhlIHJlZ2lvbiBpcyBjbG9zZWQuPC9saT4KKyAgICogICA8bGk+YSBmbHVzaCBpcyBhbHJlYWR5IGluIHByb2dyZXNzPC9saT4KKyAgICogICA8bGk+d3JpdGVzIGFyZSBkaXNhYmxlZDwvbGk+CisgICAqIDwvb2w+CisgICAqCisgICAqIDxwPlRoaXMgbWV0aG9kIG1heSBibG9jayBmb3Igc29tZSB0aW1lLCBzbyBpdCBzaG91bGQgbm90IGJlIGNhbGxlZCBmcm9tIGEgCisgICAqIHRpbWUtc2Vuc2l0aXZlIHRocmVhZC4KKyAgICogCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBjYWNoZSB3YXMgZmx1c2hlZAorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAdGhyb3dzIERyb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbiBUaHJvd24gd2hlbiByZXBsYXkgb2YgaGxvZyBpcyByZXF1aXJlZAorICAgKiBiZWNhdXNlIGEgU25hcHNob3Qgd2FzIG5vdCBwcm9wZXJseSBwZXJzaXN0ZWQuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBmbHVzaGNhY2hlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5jbG9zZWQuZ2V0KCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgc3luY2hyb25pemVkICh3cml0ZXN0YXRlKSB7CisgICAgICBpZiAoIXdyaXRlc3RhdGUuZmx1c2hpbmcgJiYgd3JpdGVzdGF0ZS53cml0ZXNFbmFibGVkKSB7CisgICAgICAgIHRoaXMud3JpdGVzdGF0ZS5mbHVzaGluZyA9IHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZihMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygiTk9UIGZsdXNoaW5nIG1lbWNhY2hlIGZvciByZWdpb24gIiArIHRoaXMgKworICAgICAgICAgICAgIiwgZmx1c2hpbmc9IiArCisgICAgICAgICAgICAgIHdyaXRlc3RhdGUuZmx1c2hpbmcgKyAiLCB3cml0ZXNFbmFibGVkPSIgKworICAgICAgICAgICAgICB3cml0ZXN0YXRlLndyaXRlc0VuYWJsZWQpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBmYWxzZTsgIAorICAgICAgfQorICAgIH0KKyAgICB0cnkgeworICAgICAgLy8gUHJldmVudCBzcGxpdHMgYW5kIGNsb3NlcworICAgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiBpbnRlcm5hbEZsdXNoY2FjaGUoKTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgc3luY2hyb25pemVkICh3cml0ZXN0YXRlKSB7CisgICAgICAgIHdyaXRlc3RhdGUuZmx1c2hpbmcgPSBmYWxzZTsKKyAgICAgICAgdGhpcy53cml0ZXN0YXRlLmZsdXNoUmVxdWVzdGVkID0gZmFsc2U7CisgICAgICAgIHdyaXRlc3RhdGUubm90aWZ5QWxsKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEZsdXNoaW5nIHRoZSBjYWNoZSBpcyBhIGxpdHRsZSB0cmlja3kuIFdlIGhhdmUgYSBsb3Qgb2YgdXBkYXRlcyBpbiB0aGUKKyAgICogSE1lbWNhY2hlLCBhbGwgb2Ygd2hpY2ggaGF2ZSBhbHNvIGJlZW4gd3JpdHRlbiB0byB0aGUgbG9nLiBXZSBuZWVkIHRvCisgICAqIHdyaXRlIHRob3NlIHVwZGF0ZXMgaW4gdGhlIEhNZW1jYWNoZSBvdXQgdG8gZGlzaywgd2hpbGUgYmVpbmcgYWJsZSB0bworICAgKiBwcm9jZXNzIHJlYWRzL3dyaXRlcyBhcyBtdWNoIGFzIHBvc3NpYmxlIGR1cmluZyB0aGUgZmx1c2ggb3BlcmF0aW9uLiBBbHNvLAorICAgKiB0aGUgbG9nIGhhcyB0byBzdGF0ZSBjbGVhcmx5IHRoZSBwb2ludCBpbiB0aW1lIGF0IHdoaWNoIHRoZSBITWVtY2FjaGUgd2FzCisgICAqIGZsdXNoZWQuIChUaGF0IHdheSwgZHVyaW5nIHJlY292ZXJ5LCB3ZSBrbm93IHdoZW4gd2UgY2FuIHJlbHkgb24gdGhlCisgICAqIG9uLWRpc2sgZmx1c2hlZCBzdHJ1Y3R1cmVzIGFuZCB3aGVuIHdlIGhhdmUgdG8gcmVjb3ZlciB0aGUgSE1lbWNhY2hlIGZyb20KKyAgICogdGhlIGxvZy4pCisgICAqIAorICAgKiA8cD5Tbywgd2UgaGF2ZSBhIHRocmVlLXN0ZXAgcHJvY2VzczoKKyAgICogCisgICAqIDx1bD48bGk+QS4gRmx1c2ggdGhlIG1lbWNhY2hlIHRvIHRoZSBvbi1kaXNrIHN0b3Jlcywgbm90aW5nIHRoZSBjdXJyZW50CisgICAqIHNlcXVlbmNlIElEIGZvciB0aGUgbG9nLjxsaT4KKyAgICogCisgICAqIDxsaT5CLiBXcml0ZSBhIEZMVVNIQ0FDSEUtQ09NUExFVEUgbWVzc2FnZSB0byB0aGUgbG9nLCB1c2luZyB0aGUgc2VxdWVuY2UKKyAgICogSUQgdGhhdCB3YXMgY3VycmVudCBhdCB0aGUgdGltZSBvZiBtZW1jYWNoZS1mbHVzaC48L2xpPgorICAgKiAKKyAgICogPGxpPkMuIEdldCByaWQgb2YgdGhlIG1lbWNhY2hlIHN0cnVjdHVyZXMgdGhhdCBhcmUgbm93IHJlZHVuZGFudCwgYXMKKyAgICogdGhleSd2ZSBiZWVuIGZsdXNoZWQgdG8gdGhlIG9uLWRpc2sgSFN0b3Jlcy48L2xpPgorICAgKiA8L3VsPgorICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBwcm90ZWN0ZWQsIGJ1dCBjYW4gYmUgYWNjZXNzZWQgdmlhIHNldmVyYWwgcHVibGljCisgICAqIHJvdXRlcy4KKyAgICogCisgICAqIDxwPiBUaGlzIG1ldGhvZCBtYXkgYmxvY2sgZm9yIHNvbWUgdGltZS4KKyAgICogCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcmVnaW9uIG5lZWRzIGNvbXBhY3RpbmcKKyAgICogCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHRocm93cyBEcm9wcGVkU25hcHNob3RFeGNlcHRpb24gVGhyb3duIHdoZW4gcmVwbGF5IG9mIGhsb2cgaXMgcmVxdWlyZWQKKyAgICogYmVjYXVzZSBhIFNuYXBzaG90IHdhcyBub3QgcHJvcGVybHkgcGVyc2lzdGVkLgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGludGVybmFsRmx1c2hjYWNoZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAvLyBDbGVhciBmbHVzaCBmbGFnLgorICAgIC8vIFJlY29yZCBsYXRlc3QgZmx1c2ggdGltZQorICAgIHRoaXMubGFzdEZsdXNoVGltZSA9IHN0YXJ0VGltZTsKKyAgICAvLyBJZiBub3RoaW5nIHRvIGZsdXNoLCByZXR1cm4gYW5kIGF2b2lkIGxvZ2dpbmcgc3RhcnQvc3RvcCBmbHVzaC4KKyAgICBpZiAodGhpcy5tZW1jYWNoZVNpemUuZ2V0KCkgPD0gMCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiU3RhcnRlZCBtZW1jYWNoZSBmbHVzaCBmb3IgcmVnaW9uICIgKyB0aGlzICsKKyAgICAgICAgIi4gQ3VycmVudCByZWdpb24gbWVtY2FjaGUgc2l6ZSAiICsKKyAgICAgICAgICBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHRoaXMubWVtY2FjaGVTaXplLmdldCgpKSk7CisgICAgfQorCisgICAgLy8gU3RvcCB1cGRhdGVzIHdoaWxlIHdlIHNuYXBzaG90IHRoZSBtZW1jYWNoZSBvZiBhbGwgc3RvcmVzLiBXZSBvbmx5IGhhdmUKKyAgICAvLyB0byBkbyB0aGlzIGZvciBhIG1vbWVudC4gIEl0cyBxdWljay4gIFRoZSBzdWJzZXF1ZW50IHNlcXVlbmNlIGlkIHRoYXQKKyAgICAvLyBnb2VzIGludG8gdGhlIEhMb2cgYWZ0ZXIgd2UndmUgZmx1c2hlZCBhbGwgdGhlc2Ugc25hcHNob3RzIGFsc28gZ29lcworICAgIC8vIGludG8gdGhlIGluZm8gZmlsZSB0aGF0IHNpdHMgYmVzaWRlIHRoZSBmbHVzaGVkIGZpbGVzLgorICAgIC8vIFdlIGFsc28gc2V0IHRoZSBtZW1jYWNoZSBzaXplIHRvIHplcm8gaGVyZSBiZWZvcmUgd2UgYWxsb3cgdXBkYXRlcworICAgIC8vIGFnYWluIHNvIGl0cyB2YWx1ZSB3aWxsIHJlcHJlc2VudCB0aGUgc2l6ZSBvZiB0aGUgdXBkYXRlcyByZWNlaXZlZAorICAgIC8vIGR1cmluZyB0aGUgZmx1c2gKKyAgICBsb25nIHNlcXVlbmNlSWQgPSAtMUw7CisgICAgbG9uZyBjb21wbGV0ZVNlcXVlbmNlSWQgPSAtMUw7CisgICAgdGhpcy51cGRhdGVzTG9jay53cml0ZUxvY2soKS5sb2NrKCk7CisgICAgLy8gR2V0IGN1cnJlbnQgc2l6ZSBvZiBtZW1jYWNoZXMuCisgICAgZmluYWwgbG9uZyBjdXJyZW50TWVtY2FjaGVTaXplID0gdGhpcy5tZW1jYWNoZVNpemUuZ2V0KCk7CisgICAgdHJ5IHsKKyAgICAgIGZvciAoU3RvcmUgczogc3RvcmVzLnZhbHVlcygpKSB7CisgICAgICAgIHMuc25hcHNob3QoKTsKKyAgICAgIH0KKyAgICAgIHNlcXVlbmNlSWQgPSBsb2cuc3RhcnRDYWNoZUZsdXNoKCk7CisgICAgICBjb21wbGV0ZVNlcXVlbmNlSWQgPSB0aGlzLmdldENvbXBsZXRlQ2FjaGVGbHVzaFNlcXVlbmNlSWQoc2VxdWVuY2VJZCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMudXBkYXRlc0xvY2sud3JpdGVMb2NrKCkudW5sb2NrKCk7CisgICAgfQorCisgICAgLy8gQW55IGZhaWx1cmUgZnJvbSBoZXJlIG9uIG91dCB3aWxsIGJlIGNhdGFzdHJvcGhpYyByZXF1aXJpbmcgc2VydmVyCisgICAgLy8gcmVzdGFydCBzbyBobG9nIGNvbnRlbnQgY2FuIGJlIHJlcGxheWVkIGFuZCBwdXQgYmFjayBpbnRvIHRoZSBtZW1jYWNoZS4KKyAgICAvLyBPdGhlcndpc2UsIHRoZSBzbmFwc2hvdCBjb250ZW50IHdoaWxlIGJhY2tlZCB1cCBpbiB0aGUgaGxvZywgaXQgd2lsbCBub3QKKyAgICAvLyBiZSBwYXJ0IG9mIHRoZSBjdXJyZW50IHJ1bm5pbmcgc2VydmVycyBzdGF0ZS4KKyAgICBib29sZWFuIGNvbXBhY3Rpb25SZXF1ZXN0ZWQgPSBmYWxzZTsKKyAgICB0cnkgeworICAgICAgLy8gQS4gIEZsdXNoIG1lbWNhY2hlIHRvIGFsbCB0aGUgSFN0b3Jlcy4KKyAgICAgIC8vIEtlZXAgcnVubmluZyB2ZWN0b3Igb2YgYWxsIHN0b3JlIGZpbGVzIHRoYXQgaW5jbHVkZXMgYm90aCBvbGQgYW5kIHRoZQorICAgICAgLy8ganVzdC1tYWRlIG5ldyBmbHVzaCBzdG9yZSBmaWxlLgorICAgICAgZm9yIChTdG9yZSBoc3RvcmU6IHN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBib29sZWFuIG5lZWRzQ29tcGFjdGlvbiA9IGhzdG9yZS5mbHVzaENhY2hlKGNvbXBsZXRlU2VxdWVuY2VJZCk7CisgICAgICAgIGlmIChuZWVkc0NvbXBhY3Rpb24pIHsKKyAgICAgICAgICBjb21wYWN0aW9uUmVxdWVzdGVkID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgLy8gU2V0IGRvd24gdGhlIG1lbWNhY2hlIHNpemUgYnkgYW1vdW50IG9mIGZsdXNoLgorICAgICAgdGhpcy5tZW1jYWNoZVNpemUuYWRkQW5kR2V0KC1jdXJyZW50TWVtY2FjaGVTaXplKTsKKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgLy8gQW4gZXhjZXB0aW9uIGhlcmUgbWVhbnMgdGhhdCB0aGUgc25hcHNob3Qgd2FzIG5vdCBwZXJzaXN0ZWQuCisgICAgICAvLyBUaGUgaGxvZyBuZWVkcyB0byBiZSByZXBsYXllZCBzbyBpdHMgY29udGVudCBpcyByZXN0b3JlZCB0byBtZW1jYWNoZS4KKyAgICAgIC8vIEN1cnJlbnRseSwgb25seSBhIHNlcnZlciByZXN0YXJ0IHdpbGwgZG8gdGhpcy4KKyAgICAgIC8vIFdlIHVzZWQgdG8gb25seSBjYXRjaCBJT0VzIGJ1dCBpdHMgcG9zc2libGUgdGhhdCB3ZSdkIGdldCBvdGhlcgorICAgICAgLy8gZXhjZXB0aW9ucyAtLSBlLmcuIEhCQVNFLTY1OSB3YXMgYWJvdXQgYW4gTlBFIC0tIHNvIG5vdyB3ZSBjYXRjaAorICAgICAgLy8gYWxsIGFuZCBzdW5kcnkuCisgICAgICB0aGlzLmxvZy5hYm9ydENhY2hlRmx1c2goKTsKKyAgICAgIERyb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbiBkc2UgPSBuZXcgRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uKCJyZWdpb246ICIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGdldFJlZ2lvbk5hbWUoKSkpOworICAgICAgZHNlLmluaXRDYXVzZSh0KTsKKyAgICAgIHRocm93IGRzZTsKKyAgICB9CisKKyAgICAvLyBJZiB3ZSBnZXQgdG8gaGVyZSwgdGhlIEhTdG9yZXMgaGF2ZSBiZWVuIHdyaXR0ZW4uIElmIHdlIGdldCBhbgorICAgIC8vIGVycm9yIGluIGNvbXBsZXRlQ2FjaGVGbHVzaCBpdCB3aWxsIHJlbGVhc2UgdGhlIGxvY2sgaXQgaXMgaG9sZGluZworCisgICAgLy8gQi4gIFdyaXRlIGEgRkxVU0hDQUNIRS1DT01QTEVURSBtZXNzYWdlIHRvIHRoZSBsb2cuCisgICAgLy8gICAgIFRoaXMgdGVsbHMgZnV0dXJlIHJlYWRlcnMgdGhhdCB0aGUgSFN0b3JlcyB3ZXJlIGVtaXR0ZWQgY29ycmVjdGx5LAorICAgIC8vICAgICBhbmQgdGhhdCBhbGwgdXBkYXRlcyB0byB0aGUgbG9nIGZvciB0aGlzIHJlZ2lvbk5hbWUgdGhhdCBoYXZlIGxvd2VyIAorICAgIC8vICAgICBsb2ctc2VxdWVuY2UtaWRzIGNhbiBiZSBzYWZlbHkgaWdub3JlZC4KKyAgICB0aGlzLmxvZy5jb21wbGV0ZUNhY2hlRmx1c2goZ2V0UmVnaW9uTmFtZSgpLAorICAgICAgICByZWdpb25JbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgY29tcGxldGVTZXF1ZW5jZUlkKTsKKworICAgIC8vIEMuIEZpbmFsbHkgbm90aWZ5IGFueW9uZSB3YWl0aW5nIG9uIG1lbWNhY2hlIHRvIGNsZWFyOgorICAgIC8vIGUuZy4gY2hlY2tSZXNvdXJjZXMoKS4KKyAgICBzeW5jaHJvbml6ZWQgKHRoaXMpIHsKKyAgICAgIG5vdGlmeUFsbCgpOworICAgIH0KKyAgICAKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICBTdHJpbmcgdGltZVRha2VuID0gU3RyaW5nVXRpbHMuZm9ybWF0VGltZURpZmYobm93LCBzdGFydFRpbWUpOworICAgICAgTE9HLmRlYnVnKCJGaW5pc2hlZCBtZW1jYWNoZSBmbHVzaCBvZiB+IiArCisgICAgICAgIFN0cmluZ1V0aWxzLmh1bWFuUmVhZGFibGVJbnQoY3VycmVudE1lbWNhY2hlU2l6ZSkgKyAiIGZvciByZWdpb24gIiArCisgICAgICAgIHRoaXMgKyAiIGluICIgKyAobm93IC0gc3RhcnRUaW1lKSArICJtcywgc2VxdWVuY2UgaWQ9IiArIHNlcXVlbmNlSWQgKworICAgICAgICAiLCBjb21wYWN0aW9uIHJlcXVlc3RlZD0iICsgY29tcGFjdGlvblJlcXVlc3RlZCk7CisgICAgICBpZiAoIXJlZ2lvbkluZm8uaXNNZXRhUmVnaW9uKCkpIHsKKyAgICAgICAgdGhpcy5oaXN0b3JpYW4uYWRkUmVnaW9uRmx1c2gocmVnaW9uSW5mbywgdGltZVRha2VuKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGNvbXBhY3Rpb25SZXF1ZXN0ZWQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHNlcXVlbmNlIG51bWJlciB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBjYWNoZSBmbHVzaC4gVXNlZCBieQorICAgKiBUcmFuc2FjdGlvbmFsUmVnaW9uIHRvIG5vdCBjb21wbGV0ZSBwZW5kaW5nIHRyYW5zYWN0aW9ucy4KKyAgICogCisgICAqIAorICAgKiBAcGFyYW0gY3VycmVudFNlcXVlbmNlSWQKKyAgICogQHJldHVybiBzZXF1ZW5jZSBpZCB0byBjb21wbGV0ZSB0aGUgY2FjaGUgZmx1c2ggd2l0aAorICAgKi8gCisgIHByb3RlY3RlZCBsb25nIGdldENvbXBsZXRlQ2FjaGVGbHVzaFNlcXVlbmNlSWQobG9uZyBjdXJyZW50U2VxdWVuY2VJZCkgeworICAgIHJldHVybiBjdXJyZW50U2VxdWVuY2VJZDsKKyAgfQorICAKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIGdldCgpIG1ldGhvZHMgZm9yIGNsaWVudCB1c2UuCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgIC8qKgorICAgKiBGZXRjaCBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBhIHNpbmdsZSBkYXRhIGl0ZW0sIHdpdGggdGltZXN0YW1wLgorICAgKgorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIHRzCisgICAqIEBwYXJhbSBudgorICAgKiBAcmV0dXJuIFJlc3VsdHMgb3IgbnVsbCBpZiBub25lLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgTGlzdDxLZXlWYWx1ZT4gZ2V0KGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGJ5dGVbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdHMsCisgICAgICBmaW5hbCBpbnQgbnYpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgdGltZXN0YW1wID0gdHMgPT0gLTE/IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCA6IHRzOworICAgIGludCBudW1WZXJzaW9ucyA9IG52ID09IC0xPyAxIDogbnY7CisgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgaWYgKHRoaXMuY2xvc2VkLmdldCgpKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUmVnaW9uICIgKyB0aGlzICsgIiBjbG9zZWQiKTsKKyAgICAgIH0KKyAgICAgIC8vIE1ha2Ugc3VyZSB0aGlzIGlzIGEgdmFsaWQgcm93IGFuZCB2YWxpZCBjb2x1bW4KKyAgICAgIGNoZWNrUm93KHJvdyk7CisgICAgICBjaGVja0NvbHVtbihjb2x1bW4pOworICAgICAgLy8gRG9uJ3QgbmVlZCBhIHJvdyBsb2NrIGZvciBhIHNpbXBsZSBnZXQKKyAgICAgIExpc3Q8S2V5VmFsdWU+IHJlc3VsdCA9IGdldFN0b3JlKGNvbHVtbikuCisgICAgICAgIGdldChLZXlWYWx1ZS5jcmVhdGVGaXJzdE9uUm93KHJvdywgY29sdW1uLCB0aW1lc3RhbXApLCBudW1WZXJzaW9ucyk7CisgICAgICAvLyBHdWFyYW50ZWUgdGhhdCB3ZSByZXR1cm4gbnVsbCBpbnN0ZWFkIG9mIGEgemVyby1sZW5ndGggYXJyYXksIAorICAgICAgLy8gaWYgdGhlcmUgYXJlIG5vIHJlc3VsdHMgdG8gcmV0dXJuLgorICAgICAgcmV0dXJuIChyZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuaXNFbXB0eSgpKT8gbnVsbCA6IHJlc3VsdDsKKyAgICB9IGZpbmFsbHkgeworICAgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBEYXRhIHN0cnVjdHVyZSB3aXRoIGEgY291bnRlciB0aGF0IGlzIGFjY2Vzc2libGUgcmF0aGVyIHRoYW4gY3JlYXRlIGEKKyAgICogbmV3IEludGVnZXIgZXZlcnkgdGltZSB3ZSB3YW50IHRvIHVwIHRoZSBjb3VudGVyLiAgSW5pdGlhbGl6ZXMgYXQgY291bnQgMS4KKyAgICovCisgIHN0YXRpYyBjbGFzcyBDb3VudGVyIHsKKyAgICBpbnQgY291bnRlciA9IDE7CisgIH0KKworICAvKgorICAgKiBDaGVjayB0byBzZWUgaWYgd2UndmUgbm90IGdvbmUgb3ZlciB0aHJlc2hvbGQgZm9yIHRoaXMgcGFydGljdWxhcgorICAgKiBjb2x1bW4uCisgICAqIEBwYXJhbSBrdgorICAgKiBAcGFyYW0gdmVyc2lvbnMKKyAgICogQHBhcmFtIHZlcnNpb25zQ291bnQKKyAgICogQHJldHVybiBUcnVlIGlmIGl0cyBvayB0byBhZGQgY3VycmVudCB2YWx1ZS4KKyAgICovCisgIHN0YXRpYyBib29sZWFuIG9rVG9BZGRSZXN1bHQoZmluYWwgS2V5VmFsdWUga3YsIGZpbmFsIGludCB2ZXJzaW9ucywKKyAgICAgIGZpbmFsIE1hcDxLZXlWYWx1ZSwgSFJlZ2lvbi5Db3VudGVyPiB2ZXJzaW9uc0NvdW50KSB7CisgICAgaWYgKHZlcnNpb25zQ291bnQgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGlmICh2ZXJzaW9uc0NvdW50LmNvbnRhaW5zS2V5KGt2KSkgeworICAgICAgaWYgKHZlcnNpb25zQ291bnQuZ2V0KGt2KS5jb3VudGVyIDwgdmVyc2lvbnMpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKgorICAgKiBVc2VkIGFkZGluZyBpdGVtIGZvdW5kIHRvIGxpc3Qgb2YgcmVzdWx0cyBnZXR0aW5nLgorICAgKiBAcGFyYW0ga3YKKyAgICogQHBhcmFtIHZlcnNpb25zQ291bnQKKyAgICogQHBhcmFtIHJlc3VsdHMKKyAgICovCisgIHN0YXRpYyB2b2lkIGFkZFJlc3VsdChmaW5hbCBLZXlWYWx1ZSBrdiwKKyAgICAgIGZpbmFsIE1hcDxLZXlWYWx1ZSwgSFJlZ2lvbi5Db3VudGVyPiB2ZXJzaW9uc0NvdW50LAorICAgICAgZmluYWwgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cykgeworICAgIC8vIERvbid0IGFkZCBpZiBhbHJlYWR5IHByZXNlbnQ7IGkuZS4gaWdub3JlIHNlY29uZCBlbnRyeS4KKyAgICBpZiAocmVzdWx0cy5jb250YWlucyhrdikpIHJldHVybjsKKyAgICByZXN1bHRzLmFkZChrdik7CisgICAgaWYgKHZlcnNpb25zQ291bnQgPT0gbnVsbCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoIXZlcnNpb25zQ291bnQuY29udGFpbnNLZXkoa3YpKSB7CisgICAgICB2ZXJzaW9uc0NvdW50LnB1dChrdiwgbmV3IEhSZWdpb24uQ291bnRlcigpKTsKKyAgICB9IGVsc2UgeworICAgICAgdmVyc2lvbnNDb3VudC5nZXQoa3YpLmNvdW50ZXIrKzsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gdmVyc2lvbnMgTnVtYmVyIG9mIHZlcnNpb25zIHRvIGdldC4KKyAgICogQHBhcmFtIHZlcnNpb25zQ291bnQgTWF5IGJlIG51bGwuCisgICAqIEBwYXJhbSBjb2x1bW5zIENvbHVtbnMgd2Ugd2FudCB0byBmZXRjaC4KKyAgICogQHJldHVybiBUcnVlIGlmIGhhcyBlbm91Z2ggdmVyc2lvbnMuCisgICAqLworICBzdGF0aWMgYm9vbGVhbiBoYXNFbm91Z2hWZXJzaW9ucyhmaW5hbCBpbnQgdmVyc2lvbnMsCisgICAgICBmaW5hbCBNYXA8S2V5VmFsdWUsIEhSZWdpb24uQ291bnRlcj4gdmVyc2lvbnNDb3VudCwKKyAgICAgIGZpbmFsIFNldDxieXRlIFtdPiBjb2x1bW5zKSB7CisgICAgaWYgKGNvbHVtbnMgPT0gbnVsbCB8fCB2ZXJzaW9uc0NvdW50ID09IG51bGwpIHsKKyAgICAgIC8vIFdhbnRzIGFsbCBjb2x1bW5zIHNvIGp1c3Qga2VlcCBnb2luZworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoY29sdW1ucy5zaXplKCkgPiB2ZXJzaW9uc0NvdW50LnNpemUoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAodmVyc2lvbnMgPT0gMSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIC8vIE5lZWQgdG8gbG9vayBhdCBlYWNoIHRvIG1ha2Ugc3VyZSBhdCBsZWFzdCB2ZXJzaW9ucy4KKyAgICBmb3IgKE1hcC5FbnRyeTxLZXlWYWx1ZSwgSFJlZ2lvbi5Db3VudGVyPiBlOiB2ZXJzaW9uc0NvdW50LmVudHJ5U2V0KCkpIHsKKyAgICAgIGlmIChlLmdldFZhbHVlKCkuY291bnRlciA8IHZlcnNpb25zKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogRmV0Y2ggYWxsIHRoZSBjb2x1bW5zIGZvciB0aGUgaW5kaWNhdGVkIHJvdyBhdCBhIHNwZWNpZmllZCB0aW1lc3RhbXAuCisgICAqIFJldHVybnMgYSBIYmFzZU1hcFdyaXRhYmxlIHRoYXQgbWFwcyBjb2x1bW4gbmFtZXMgdG8gdmFsdWVzLgorICAgKgorICAgKiBXZSBzaG91bGQgZXZlbnR1YWxseSB1c2UgQmxvb20gZmlsdGVycyBoZXJlLCB0byByZWR1Y2UgcnVubmluZyB0aW1lLiAgSWYgCisgICAqIHRoZSBkYXRhYmFzZSBoYXMgbWFueSBjb2x1bW4gZmFtaWxpZXMgYW5kIGlzIHZlcnkgc3BhcnNlLCB0aGVuIHdlIGNvdWxkIGJlIAorICAgKiBjaGVja2luZyBtYW55IGZpbGVzIG5lZWRsZXNzbHkuICBBIHNtYWxsIEJsb29tIGZvciBlYWNoIHJvdyB3b3VsZCBoZWxwIHVzIAorICAgKiBkZXRlcm1pbmUgd2hpY2ggY29sdW1uIGdyb3VwcyBhcmUgdXNlZnVsIGZvciB0aGF0IHJvdy4gIFRoYXQgd291bGQgbGV0IHVzIAorICAgKiBhdm9pZCBhIGJ1bmNoIG9mIGRpc2sgYWN0aXZpdHkuCisgICAqCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1ucyB5b3UnZCBsaWtlIHRvIHJldHJpZXZlLiBXaGVuIG51bGwsIGdldCBhbGwuCisgICAqIEBwYXJhbSB0cworICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgbnVtYmVyIG9mIHZlcnNpb25zIHRvIHJldHJpZXZlCisgICAqIEBwYXJhbSBsb2NraWQKKyAgICogQHJldHVybiBIYmFzZU1hcFdyaXRhYmxlPGNvbHVtbk5hbWUsIENlbGw+IHZhbHVlcworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPiBnZXRGdWxsKGZpbmFsIGJ5dGUgW10gcm93LAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IGNvbHVtbnMsIGZpbmFsIGxvbmcgdHMsCisgICAgICBmaW5hbCBpbnQgbnVtVmVyc2lvbnMsIGZpbmFsIEludGVnZXIgbG9ja2lkKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBDaGVjayBjb2x1bW5zIHBhc3NlZAorICAgIGlmIChjb2x1bW5zICE9IG51bGwpIHsKKyAgICAgIGZvciAoYnl0ZSBbXSBjb2x1bW46IGNvbHVtbnMpIHsKKyAgICAgICAgY2hlY2tDb2x1bW4oY29sdW1uKTsKKyAgICAgIH0KKyAgICB9CisgICAgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICBNYXA8S2V5VmFsdWUsIENvdW50ZXI+IHZlcnNpb25Db3VudGVyID0KKyAgICAgIG5ldyBUcmVlTWFwPEtleVZhbHVlLCBDb3VudGVyPih0aGlzLmNvbXBhcmF0b3JJZ25vcmVUaW1lc3RhbXApOworICAgIEludGVnZXIgbGlkID0gZ2V0TG9jayhsb2NraWQscm93KTsKKyAgICBIYXNoU2V0PFN0b3JlPiBzdG9yZVNldCA9IG5ldyBIYXNoU2V0PFN0b3JlPigpOworICAgIHRyeSB7CisgICAgICAvLyBHZXQgdGhlIGNvbmNlcm5lZCBjb2x1bW5zIG9yIGFsbCBvZiB0aGVtCisgICAgICBpZiAoY29sdW1ucyAhPSBudWxsKSB7CisgICAgICAgIGZvciAoYnl0ZVtdIGJzIDogY29sdW1ucykgeworICAgICAgICAgIFN0b3JlIHN0b3JlID0gc3RvcmVzLmdldChicyk7CisgICAgICAgICAgaWYgKHN0b3JlICE9IG51bGwpIHsKKyAgICAgICAgICAgIHN0b3JlU2V0LmFkZChzdG9yZSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBzdG9yZVNldC5hZGRBbGwoc3RvcmVzLnZhbHVlcygpKTsKKyAgICAgIH0KKyAgICAgIGxvbmcgdGltZXN0YW1wID0KKyAgICAgICAgKHRzID09IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk/IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOiB0czsKKyAgICAgIEtleVZhbHVlIGtleSA9IEtleVZhbHVlLmNyZWF0ZUZpcnN0T25Sb3cocm93LCB0aW1lc3RhbXApOworICAgICAgLy8gRm9yIGVhY2ggY29sdW1uIG5hbWUgdGhhdCBpcyBqdXN0IGEgY29sdW1uIGZhbWlseSwgb3BlbiB0aGUgc3RvcmUKKyAgICAgIC8vIHJlbGF0ZWQgdG8gaXQgYW5kIGZldGNoIGV2ZXJ5dGhpbmcgZm9yIHRoYXQgcm93LiBIQkFTRS02MzEKKyAgICAgIC8vIEFsc28gcmVtb3ZlIGVhY2ggc3RvcmUgZnJvbSBzdG9yZVNldCBzbyB0aGF0IHRoZXNlIHN0b3JlcworICAgICAgLy8gd29uJ3QgYmUgb3BlbmVkIGZvciBubyByZWFzb24uIEhCQVNFLTc4MworICAgICAgaWYgKGNvbHVtbnMgIT0gbnVsbCkgeworICAgICAgICBmb3IgKGJ5dGUgW10gYnMgOiBjb2x1bW5zKSB7CisgICAgICAgICAgLy8gVE9ETzogRml4IHNvIHdlIHVzZSBjb21wYXJhdG9yIGluIEtleVZhbHVlIHRoYXQgbG9va3MgYXQKKyAgICAgICAgICAvLyBjb2x1bW4gZmFtaWx5IHBvcnRpb24gb25seS4KKyAgICAgICAgICBpZiAoS2V5VmFsdWUuZ2V0RmFtaWx5RGVsaW1pdGVySW5kZXgoYnMsIDAsIGJzLmxlbmd0aCkgPT0gKGJzLmxlbmd0aCAtIDEpKSB7CisgICAgICAgICAgICBTdG9yZSBzdG9yZSA9IHN0b3Jlcy5nZXQoYnMpOworICAgICAgICAgICAgc3RvcmUuZ2V0RnVsbChrZXksIG51bGwsIG51bGwsIG51bVZlcnNpb25zLCB2ZXJzaW9uQ291bnRlciwKKyAgICAgICAgICAgICAga2V5dmFsdWVzLCB0aW1lc3RhbXApOworICAgICAgICAgICAgc3RvcmVTZXQucmVtb3ZlKHN0b3JlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGZvciAoU3RvcmUgdGFyZ2V0U3RvcmU6IHN0b3JlU2V0KSB7CisgICAgICAgIHRhcmdldFN0b3JlLmdldEZ1bGwoa2V5LCBjb2x1bW5zLCBudWxsLCBudW1WZXJzaW9ucywgdmVyc2lvbkNvdW50ZXIsCisgICAgICAgICAga2V5dmFsdWVzLCB0aW1lc3RhbXApOworICAgICAgfQorICAgICAgCisgICAgICByZXR1cm4gQ2VsbC5jcmVhdGVDZWxscyhrZXl2YWx1ZXMpOworICAgIH0gZmluYWxseSB7CisgICAgICBpZihsb2NraWQgPT0gbnVsbCkgcmVsZWFzZVJvd0xvY2sobGlkKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJuIGFsbCB0aGUgZGF0YSBmb3IgdGhlIHJvdyB0aGF0IG1hdGNoZXMgPGk+cm93PC9pPiBleGFjdGx5LCAKKyAgICogb3IgdGhlIG9uZSB0aGF0IGltbWVkaWF0ZWx5IHByZWNlZWRzIGl0LCBhdCBvciBpbW1lZGlhdGVseSBiZWZvcmUgCisgICAqIDxpPnRzPC9pPi4KKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcmV0dXJuIG1hcCBvZiB2YWx1ZXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgUm93UmVzdWx0IGdldENsb3Nlc3RSb3dCZWZvcmUoZmluYWwgYnl0ZSBbXSByb3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICByZXR1cm4gZ2V0Q2xvc2VzdFJvd0JlZm9yZShyb3csIEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJuIGFsbCB0aGUgZGF0YSBmb3IgdGhlIHJvdyB0aGF0IG1hdGNoZXMgPGk+cm93PC9pPiBleGFjdGx5LCAKKyAgICogb3IgdGhlIG9uZSB0aGF0IGltbWVkaWF0ZWx5IHByZWNlZWRzIGl0LCBhdCBvciBpbW1lZGlhdGVseSBiZWZvcmUgCisgICAqIDxpPnRzPC9pPi4KKyAgICogCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uRmFtaWx5IE11c3QgaW5jbHVkZSB0aGUgY29sdW1uIGZhbWlseSBkZWxpbWl0ZXIgY2hhcmFjdGVyLgorICAgKiBAcmV0dXJuIG1hcCBvZiB2YWx1ZXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRDbG9zZXN0Um93QmVmb3JlKGZpbmFsIGJ5dGUgW10gcm93LAorICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uRmFtaWx5KQorICB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgLy8gbG9vayBhY3Jvc3MgYWxsIHRoZSBIU3RvcmVzIGZvciB0aGlzIHJlZ2lvbiBhbmQgZGV0ZXJtaW5lIHdoYXQgdGhlCisgICAgLy8gY2xvc2VzdCBrZXkgaXMgYWNyb3NzIGFsbCBjb2x1bW4gZmFtaWxpZXMsIHNpbmNlIHRoZSBkYXRhIG1heSBiZSBzcGFyc2UKKyAgICBLZXlWYWx1ZSBrZXkgPSBudWxsOworICAgIGNoZWNrUm93KHJvdyk7CisgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgU3RvcmUgc3RvcmUgPSBnZXRTdG9yZShjb2x1bW5GYW1pbHkpOworICAgICAgS2V5VmFsdWUga3YgPSBuZXcgS2V5VmFsdWUocm93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgICAgLy8gZ2V0IHRoZSBjbG9zZXN0IGtleS4gKEhTdG9yZS5nZXRSb3dLZXlBdE9yQmVmb3JlIGNhbiByZXR1cm4gbnVsbCkKKyAgICAgIGtleSA9IHN0b3JlLmdldFJvd0tleUF0T3JCZWZvcmUoa3YpOworICAgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAvLyBUaGlzIHdpbGwgZ2V0IGFsbCByZXN1bHRzIGZvciB0aGlzIHN0b3JlLiAgVE9ETzogRG8gSSBoYXZlIHRvIG1ha2UgYQorICAgICAgLy8gbmV3IGtleT8KKyAgICAgIGlmICghdGhpcy5jb21wYXJhdG9yLm1hdGNoaW5nUm93cyhrdiwga2V5KSkgeworICAgICAgICBrdiA9IG5ldyBLZXlWYWx1ZShrZXkuZ2V0Um93KCksIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgICAgICB9CisgICAgICBzdG9yZS5nZXRGdWxsKGt2LCBudWxsLCBudWxsLCAxLCBudWxsLCByZXN1bHRzLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAvLyBDb252ZXJ0IHRvIFJvd1Jlc3VsdC4gIFRPRE86IFJlbW92ZSBuZWVkIHRvIGRvIHRoaXMuCisgICAgICByZXR1cm4gUm93UmVzdWx0LmNyZWF0ZVJvd1Jlc3VsdChyZXN1bHRzKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gYW4gaXRlcmF0b3IgdGhhdCBzY2FucyBvdmVyIHRoZSBIUmVnaW9uLCByZXR1cm5pbmcgdGhlIGluZGljYXRlZCAKKyAgICogY29sdW1ucyBmb3Igb25seSB0aGUgcm93cyB0aGF0IG1hdGNoIHRoZSBkYXRhIGZpbHRlci4gIFRoaXMgSXRlcmF0b3IgbXVzdAorICAgKiBiZSBjbG9zZWQgYnkgdGhlIGNhbGxlci4KKyAgICoKKyAgICogQHBhcmFtIGNvbHMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuIEEgY29sdW1uIHF1YWxpZmllciBpcyBqdWRnZWQgdG8KKyAgICogYmUgYSByZWdleCBpZiBpdCBjb250YWlucyBhdCBsZWFzdCBvbmUgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOgorICAgKiA8Y29kZT5cK3xeJiokW11dfXspKDwvY29kZT4uCisgICAqIEBwYXJhbSBmaXJzdFJvdyByb3cgd2hpY2ggaXMgdGhlIHN0YXJ0aW5nIHBvaW50IG9mIHRoZSBzY2FuCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgb25seSByZXR1cm4gcm93cyB3aG9zZSB0aW1lc3RhbXAgaXMgPD0gdGhpcyB2YWx1ZQorICAgKiBAcGFyYW0gZmlsdGVyIHJvdyBmaWx0ZXIKKyAgICogQHJldHVybiBJbnRlcm5hbFNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEludGVybmFsU2Nhbm5lciBnZXRTY2FubmVyKGJ5dGVbXVtdIGNvbHMsIGJ5dGUgW10gZmlyc3RSb3csCisgICAgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG5ld1NjYW5uZXJMb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBpZiAodGhpcy5jbG9zZWQuZ2V0KCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZWdpb24gIiArIHRoaXMgKyAiIGNsb3NlZCIpOworICAgICAgfQorICAgICAgSGFzaFNldDxTdG9yZT4gc3RvcmVTZXQgPSBuZXcgSGFzaFNldDxTdG9yZT4oKTsKKyAgICAgIE5hdmlnYWJsZVNldDxieXRlIFtdPiBjb2x1bW5zID0KKyAgICAgICAgbmV3IFRyZWVTZXQ8Ynl0ZSBbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgICAvLyBCZWxvdyB3ZSBtYWtlIHVwIHNldCBvZiBzdG9yZXMgd2Ugd2FudCBzY2FubmVycyBvbiBhbmQgd2UgZmlsbCBvdXQgdGhlCisgICAgICAvLyBsaXN0IG9mIGNvbHVtbnMuCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgY29sdW1ucy5hZGQoY29sc1tpXSk7CisgICAgICAgIFN0b3JlIHMgPSBzdG9yZXMuZ2V0KGNvbHNbaV0pOworICAgICAgICBpZiAocyAhPSBudWxsKSB7CisgICAgICAgICAgc3RvcmVTZXQuYWRkKHMpOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gbmV3IEhTY2FubmVyKGNvbHVtbnMsIGZpcnN0Um93LCB0aW1lc3RhbXAsCisgICAgICAgIHN0b3JlU2V0LnRvQXJyYXkobmV3IFN0b3JlIFtzdG9yZVNldC5zaXplKCldKSwgZmlsdGVyKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgbmV3U2Nhbm5lckxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy8gc2V0KCkgbWV0aG9kcyBmb3IgY2xpZW50IHVzZS4KKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIAorICAvKioKKyAgICogQHBhcmFtIGIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoQmF0Y2hVcGRhdGUgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmJhdGNoVXBkYXRlKGIsIG51bGwsIHRydWUpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGIKKyAgICogQHBhcmFtIHdyaXRlVG9XQUwKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoQmF0Y2hVcGRhdGUgYiwgYm9vbGVhbiB3cml0ZVRvV0FMKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuYmF0Y2hVcGRhdGUoYiwgbnVsbCwgd3JpdGVUb1dBTCk7CisgIH0KKworICAKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEBwYXJhbSBsb2NraWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoQmF0Y2hVcGRhdGUgYiwgSW50ZWdlciBsb2NraWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5iYXRjaFVwZGF0ZShiLCBsb2NraWQsIHRydWUpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGIKKyAgICogQHBhcmFtIGxvY2tpZAorICAgKiBAcGFyYW0gd3JpdGVUb1dBTCBpZiB0cnVlLCB0aGVuIHdlIHdyaXRlIHRoaXMgdXBkYXRlIHRvIHRoZSBsb2cKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoQmF0Y2hVcGRhdGUgYiwgSW50ZWdlciBsb2NraWQsIGJvb2xlYW4gd3JpdGVUb1dBTCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja1JlYWRPbmx5KCk7CisgICAgdmFsaWRhdGVWYWx1ZXNMZW5ndGgoYik7CisKKyAgICAvLyBEbyBhIHJvdWdoIGNoZWNrIHRoYXQgd2UgaGF2ZSByZXNvdXJjZXMgdG8gYWNjZXB0IGEgd3JpdGUuICBUaGUgY2hlY2sgaXMKKyAgICAvLyAncm91Z2gnIGluIHRoYXQgYmV0d2VlbiB0aGUgcmVzb3VyY2UgY2hlY2sgYW5kIHRoZSBjYWxsIHRvIG9idGFpbiBhIAorICAgIC8vIHJlYWQgbG9jaywgcmVzb3VyY2VzIG1heSBydW4gb3V0LiAgRm9yIG5vdywgdGhlIHRob3VnaHQgaXMgdGhhdCB0aGlzCisgICAgLy8gd2lsbCBiZSBleHRyZW1lbHkgcmFyZTsgd2UnbGwgZGVhbCB3aXRoIGl0IHdoZW4gaXQgaGFwcGVucy4KKyAgICBjaGVja1Jlc291cmNlcygpOworICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIFdlIG9idGFpbiBhIHBlci1yb3cgbG9jaywgc28gb3RoZXIgY2xpZW50cyB3aWxsIGJsb2NrIHdoaWxlIG9uZSBjbGllbnQKKyAgICAgIC8vIHBlcmZvcm1zIGFuIHVwZGF0ZS4gVGhlIHJlYWQgbG9jayBpcyByZWxlYXNlZCBieSB0aGUgY2xpZW50IGNhbGxpbmcKKyAgICAgIC8vICNjb21taXQgb3IgI2Fib3J0IG9yIGlmIHRoZSBIUmVnaW9uU2VydmVyIGxlYXNlIG9uIHRoZSBsb2NrIGV4cGlyZXMuCisgICAgICAvLyBTZWUgSFJlZ2lvblNlcnZlciNSZWdpb25MaXN0ZW5lciBmb3IgaG93IHRoZSBleHBpcmUgb24gSFJlZ2lvblNlcnZlcgorICAgICAgLy8gaW52b2tlcyBhIEhSZWdpb24jYWJvcnQuCisgICAgICBieXRlIFtdIHJvdyA9IGIuZ2V0Um93KCk7CisgICAgICAvLyBJZiB3ZSBkaWQgbm90IHBhc3MgYW4gZXhpc3Rpbmcgcm93IGxvY2ssIG9idGFpbiBhIG5ldyBvbmUKKyAgICAgIEludGVnZXIgbGlkID0gZ2V0TG9jayhsb2NraWQsIHJvdyk7CisgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgbG9uZyBjb21taXRUaW1lID0gYi5nZXRUaW1lc3RhbXAoKSA9PSBMQVRFU1RfVElNRVNUQU1QPworICAgICAgICBub3c6IGIuZ2V0VGltZXN0YW1wKCk7CisgICAgICBTZXQ8Ynl0ZSBbXT4gbGF0ZXN0VGltZXN0YW1wRGVsZXRlcyA9IG51bGw7CisgICAgICBMaXN0PEtleVZhbHVlPiBlZGl0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICB0cnkgeworICAgICAgICBmb3IgKEJhdGNoT3BlcmF0aW9uIG9wOiBiKSB7CisgICAgICAgICAgYnl0ZSBbXSBjb2x1bW4gPSBvcC5nZXRDb2x1bW4oKTsKKyAgICAgICAgICBjaGVja0NvbHVtbihjb2x1bW4pOworICAgICAgICAgIEtleVZhbHVlIGt2ID0gbnVsbDsKKyAgICAgICAgICBpZiAob3AuaXNQdXQoKSkgeworICAgICAgICAgICAga3YgPSBuZXcgS2V5VmFsdWUocm93LCBjb2x1bW4sIGNvbW1pdFRpbWUsIG9wLmdldFZhbHVlKCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBJdHMgYSBkZWxldGUuCisgICAgICAgICAgICBpZiAoYi5nZXRUaW1lc3RhbXAoKSA9PSBMQVRFU1RfVElNRVNUQU1QKSB7CisgICAgICAgICAgICAgIC8vIFNhdmUgb2ZmIHRoZXNlIGRlbGV0ZXMgb2YgdGhlIG1vc3QgcmVjZW50IHRoaW5nIGFkZGVkIG9uIHRoZQorICAgICAgICAgICAgICAvLyBmYW1pbHkuCisgICAgICAgICAgICAgIGlmIChsYXRlc3RUaW1lc3RhbXBEZWxldGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBsYXRlc3RUaW1lc3RhbXBEZWxldGVzID0KKyAgICAgICAgICAgICAgICAgIG5ldyBUcmVlU2V0PGJ5dGUgW10+KEJ5dGVzLkJZVEVTX1JBV0NPTVBBUkFUT1IpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGxhdGVzdFRpbWVzdGFtcERlbGV0ZXMuYWRkKG9wLmdldENvbHVtbigpKTsKKyAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBJdHMgYW4gZXhwbGljaXQgdGltZXN0YW1wIGRlbGV0ZQorICAgICAgICAgICAga3YgPSBuZXcgS2V5VmFsdWUocm93LCBjb2x1bW4sIGNvbW1pdFRpbWUsIEtleVZhbHVlLlR5cGUuRGVsZXRlLAorICAgICAgICAgICAgICBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVkpOworICAgICAgICAgIH0KKyAgICAgICAgICBlZGl0cy5hZGQoa3YpOworICAgICAgICB9CisgICAgICAgIGlmICghZWRpdHMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgdXBkYXRlKGVkaXRzLCB3cml0ZVRvV0FMKTsKKyAgICAgICAgfQorICAgICAgICBpZiAobGF0ZXN0VGltZXN0YW1wRGVsZXRlcyAhPSBudWxsICYmCisgICAgICAgICAgICAhbGF0ZXN0VGltZXN0YW1wRGVsZXRlcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAvLyBXZSBoYXZlIHNvbWUgTEFURVNUX1RJTUVTVEFNUCBkZWxldGVzIHRvIHJ1bi4gIENhbid0IGRvIHRoZW0gaW5saW5lCisgICAgICAgICAgLy8gYXMgZWRpdHMuICBOZWVkIHRvIGRvIGluZGl2aWR1YWxseSBhZnRlciBmaWd1cmluZyB3aGljaCBpcyBsYXRlc3QKKyAgICAgICAgICAvLyB0aW1lc3RhbXAgdG8gZGVsZXRlLgorICAgICAgICAgIGZvciAoYnl0ZSBbXSBjb2x1bW46IGxhdGVzdFRpbWVzdGFtcERlbGV0ZXMpIHsKKyAgICAgICAgICAgIGRlbGV0ZU11bHRpcGxlKHJvdywgY29sdW1uLCBMQVRFU1RfVElNRVNUQU1QLCAxKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIGlmKGxvY2tpZCA9PSBudWxsKSByZWxlYXNlUm93TG9jayhsaWQpOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzcGxpdHNBbmRDbG9zZXNMb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFBlcmZvcm1zIGFuIGF0b21pYyBjaGVjayBhbmQgc2F2ZSBvcGVyYXRpb24uIENoZWNrcyBpZgorICAgKiB0aGUgc3BlY2lmaWVkIGV4cGVjdGVkIHZhbHVlcyBoYXZlIGNoYW5nZWQsIGFuZCBpZiBub3QKKyAgICogYXBwbGllcyB0aGUgdXBkYXRlLgorICAgKiAKKyAgICogQHBhcmFtIGIgdGhlIHVwZGF0ZSB0byBhcHBseQorICAgKiBAcGFyYW0gZXhwZWN0ZWRWYWx1ZXMgdGhlIGV4cGVjdGVkIHZhbHVlcyB0byBjaGVjaworICAgKiBAcGFyYW0gbG9ja2lkCisgICAqIEBwYXJhbSB3cml0ZVRvV0FMIHdoZXRoZXIgb3Igbm90IHRvIHdyaXRlIHRvIHRoZSB3cml0ZSBhaGVhZCBsb2cKKyAgICogQHJldHVybiB0cnVlIGlmIHVwZGF0ZSB3YXMgYXBwbGllZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBjaGVja0FuZFNhdmUoQmF0Y2hVcGRhdGUgYiwKKyAgICBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSwgYnl0ZVtdPiBleHBlY3RlZFZhbHVlcywgSW50ZWdlciBsb2NraWQsCisgICAgYm9vbGVhbiB3cml0ZVRvV0FMKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFRoaXMgaXMgYmFzaWNhbGx5IGEgY29weSBvZiBiYXRjaFVwZGF0ZSB3aXRoIHRoZSBhdG9taWMgY2hlY2sgYW5kIHNhdmUKKyAgICAvLyBhZGRlZCBpbi4gU28geW91IHNob3VsZCByZWFkIHRoaXMgbWV0aG9kIHdpdGggYmF0Y2hVcGRhdGUuIEkgd2lsbAorICAgIC8vIGNvbW1lbnQgdGhlIGFyZWFzIHRoYXQgSSBoYXZlIGNoYW5nZWQgd2hlcmUgSSBoYXZlIG5vdCBjaGFuZ2VkLCB5b3UKKyAgICAvLyBzaG91bGQgcmVhZCB0aGUgY29tbWVudHMgZnJvbSB0aGUgYmF0Y2hVcGRhdGUgbWV0aG9kCisgICAgYm9vbGVhbiBzdWNjZXNzID0gdHJ1ZTsKKyAgICBjaGVja1JlYWRPbmx5KCk7CisgICAgdmFsaWRhdGVWYWx1ZXNMZW5ndGgoYik7CisgICAgY2hlY2tSZXNvdXJjZXMoKTsKKyAgICBzcGxpdHNBbmRDbG9zZXNMb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBieXRlW10gcm93ID0gYi5nZXRSb3coKTsKKyAgICAgIEludGVnZXIgbGlkID0gZ2V0TG9jayhsb2NraWQscm93KTsKKyAgICAgIHRyeSB7CisgICAgICAgIE5hdmlnYWJsZVNldDxieXRlIFtdPiBrZXlTZXQgPQorICAgICAgICAgIG5ldyBUcmVlU2V0PGJ5dGUgW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgICAgICBrZXlTZXQuYWRkQWxsKGV4cGVjdGVkVmFsdWVzLmtleVNldCgpKTsKKyAgICAgICAgTWFwPGJ5dGVbXSxDZWxsPiBhY3R1YWxWYWx1ZXMgPSBnZXRGdWxsKHJvdywga2V5U2V0LAorICAgICAgICAgIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSxsaWQpOworICAgICAgICBmb3IgKGJ5dGVbXSBrZXkgOiBrZXlTZXQpIHsKKyAgICAgICAgICAvLyBJZiB0ZXN0IGZhaWxzIGV4aXQKKyAgICAgICAgICBpZighQnl0ZXMuZXF1YWxzKGFjdHVhbFZhbHVlcy5nZXQoa2V5KS5nZXRWYWx1ZSgpLAorICAgICAgICAgICAgICBleHBlY3RlZFZhbHVlcy5nZXQoa2V5KSkpIHsKKyAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc3VjY2VzcykgeworICAgICAgICAgIGxvbmcgY29tbWl0VGltZSA9IChiLmdldFRpbWVzdGFtcCgpID09IExBVEVTVF9USU1FU1RBTVApPworICAgICAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk6IGIuZ2V0VGltZXN0YW1wKCk7CisgICAgICAgICAgU2V0PGJ5dGUgW10+IGxhdGVzdFRpbWVzdGFtcERlbGV0ZXMgPSBudWxsOworICAgICAgICAgIExpc3Q8S2V5VmFsdWU+IGVkaXRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgICAgICBmb3IgKEJhdGNoT3BlcmF0aW9uIG9wOiBiKSB7CisgICAgICAgICAgICBieXRlIFtdIGNvbHVtbiA9IG9wLmdldENvbHVtbigpOworICAgICAgICAgICAgS2V5VmFsdWUga3YgPSBudWxsOworICAgICAgICAgICAgaWYgKG9wLmlzUHV0KCkpIHsKKyAgICAgICAgICAgICAga3YgPSBuZXcgS2V5VmFsdWUocm93LCBjb2x1bW4sIGNvbW1pdFRpbWUsIG9wLmdldFZhbHVlKCkpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgLy8gSXRzIGEgZGVsZXRlLgorICAgICAgICAgICAgICBpZiAoYi5nZXRUaW1lc3RhbXAoKSA9PSBMQVRFU1RfVElNRVNUQU1QKSB7CisgICAgICAgICAgICAgICAgLy8gU2F2ZSBvZmYgdGhlc2UgZGVsZXRlcyBvZiB0aGUgbW9zdCByZWNlbnQgdGhpbmcgYWRkZWQgb24KKyAgICAgICAgICAgICAgICAvLyB0aGUgZmFtaWx5LgorICAgICAgICAgICAgICAgIGlmIChsYXRlc3RUaW1lc3RhbXBEZWxldGVzID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgIGxhdGVzdFRpbWVzdGFtcERlbGV0ZXMgPQorICAgICAgICAgICAgICAgICAgICBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19SQVdDT01QQVJBVE9SKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgbGF0ZXN0VGltZXN0YW1wRGVsZXRlcy5hZGQob3AuZ2V0Q29sdW1uKCkpOworICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8vIEl0cyBhbiBleHBsaWNpdCB0aW1lc3RhbXAgZGVsZXRlCisgICAgICAgICAgICAgICAga3YgPSBuZXcgS2V5VmFsdWUocm93LCBjb2x1bW4sIGNvbW1pdFRpbWUsCisgICAgICAgICAgICAgICAgICBLZXlWYWx1ZS5UeXBlLkRlbGV0ZSwgSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZWRpdHMuYWRkKGt2KTsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKCFlZGl0cy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHVwZGF0ZShlZGl0cywgd3JpdGVUb1dBTCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChsYXRlc3RUaW1lc3RhbXBEZWxldGVzICE9IG51bGwgJiYKKyAgICAgICAgICAgICAgIWxhdGVzdFRpbWVzdGFtcERlbGV0ZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAvLyBXZSBoYXZlIHNvbWUgTEFURVNUX1RJTUVTVEFNUCBkZWxldGVzIHRvIHJ1bi4gIENhbid0IGRvIHRoZW0gaW5saW5lCisgICAgICAgICAgICAvLyBhcyBlZGl0cy4gIE5lZWQgdG8gZG8gaW5kaXZpZHVhbGx5IGFmdGVyIGZpZ3VyaW5nIHdoaWNoIGlzIGxhdGVzdAorICAgICAgICAgICAgLy8gdGltZXN0YW1wIHRvIGRlbGV0ZS4KKyAgICAgICAgICAgIGZvciAoYnl0ZSBbXSBjb2x1bW46IGxhdGVzdFRpbWVzdGFtcERlbGV0ZXMpIHsKKyAgICAgICAgICAgICAgZGVsZXRlTXVsdGlwbGUocm93LCBjb2x1bW4sIExBVEVTVF9USU1FU1RBTVAsIDEpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgaWYobG9ja2lkID09IG51bGwpIHJlbGVhc2VSb3dMb2NrKGxpZCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNwbGl0c0FuZENsb3Nlc0xvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgICAgcmV0dXJuIHN1Y2Nlc3M7CisgIH0KKworICAvKgorICAgKiBVdGlsaXR5IG1ldGhvZCB0byB2ZXJpZnkgdmFsdWVzIGxlbmd0aAorICAgKiBAcGFyYW0gYmF0Y2hVcGRhdGUgVGhlIHVwZGF0ZSB0byB2ZXJpZnkKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBUaHJvd24gaWYgYSB2YWx1ZSBpcyB0b28gbG9uZworICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlVmFsdWVzTGVuZ3RoKEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoSXRlcmF0b3I8QmF0Y2hPcGVyYXRpb24+IGl0ZXIgPSAKKyAgICAgIGJhdGNoVXBkYXRlLml0ZXJhdG9yKCk7IGl0ZXIuaGFzTmV4dCgpOykgeworICAgICAgQmF0Y2hPcGVyYXRpb24gb3BlcmF0aW9uID0gaXRlci5uZXh0KCk7CisgICAgICBpZiAob3BlcmF0aW9uLmdldFZhbHVlKCkgIT0gbnVsbCkgeworICAgICAgICBIQ29sdW1uRGVzY3JpcHRvciBmYW0gPSB0aGlzLnJlZ2lvbkluZm8uZ2V0VGFibGVEZXNjKCkuCisgICAgICAgICAgZ2V0RmFtaWx5KG9wZXJhdGlvbi5nZXRDb2x1bW4oKSk7CisgICAgICAgIGlmIChmYW0gIT0gbnVsbCkgeworICAgICAgICAgIGludCBtYXhMZW5ndGggPSBmYW0uZ2V0TWF4VmFsdWVMZW5ndGgoKTsKKyAgICAgICAgICBpZiAob3BlcmF0aW9uLmdldFZhbHVlKCkubGVuZ3RoID4gbWF4TGVuZ3RoKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgVmFsdWVPdmVyTWF4TGVuZ3RoRXhjZXB0aW9uKCJWYWx1ZSBpbiBjb2x1bW4gIgorICAgICAgICAgICAgICAgICsgQnl0ZXMudG9TdHJpbmcob3BlcmF0aW9uLmdldENvbHVtbigpKSArICIgaXMgdG9vIGxvbmcuICIKKyAgICAgICAgICAgICAgICArIG9wZXJhdGlvbi5nZXRWYWx1ZSgpLmxlbmd0aCArICIgaW5zdGVhZCBvZiAiICsgbWF4TGVuZ3RoKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKgorICAgKiBDaGVjayBpZiByZXNvdXJjZXMgdG8gc3VwcG9ydCBhbiB1cGRhdGUuCisgICAqIAorICAgKiBIZXJlIHdlIHN5bmNocm9uaXplIG9uIEhSZWdpb24sIGEgYnJvYWQgc2NvcGVkIGxvY2suICBJdHMgYXBwcm9wcmlhdGUKKyAgICogZ2l2ZW4gd2UncmUgZmlndXJpbmcgaW4gaGVyZSB3aGV0aGVyIHRoaXMgcmVnaW9uIGlzIGFibGUgdG8gdGFrZSBvbgorICAgKiB3cml0ZXMuICBUaGlzIGlzIG9ubHkgbWV0aG9kIHdpdGggYSBzeW5jaHJvbml6ZSAoYXQgdGltZSBvZiB3cml0aW5nKSwKKyAgICogdGhpcyBhbmQgdGhlIHN5bmNocm9uaXplIG9uICd0aGlzJyBpbnNpZGUgaW4gaW50ZXJuYWxGbHVzaENhY2hlIHRvIHNlbmQKKyAgICogdGhlIG5vdGlmeS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja1Jlc291cmNlcygpIHsKKyAgICBib29sZWFuIGJsb2NrZWQgPSBmYWxzZTsKKyAgICB3aGlsZSAodGhpcy5tZW1jYWNoZVNpemUuZ2V0KCkgPiB0aGlzLmJsb2NraW5nTWVtY2FjaGVTaXplKSB7CisgICAgICByZXF1ZXN0Rmx1c2goKTsKKyAgICAgIGlmICghYmxvY2tlZCkgeworICAgICAgICBMT0cuaW5mbygiQmxvY2tpbmcgdXBkYXRlcyBmb3IgJyIgKyBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSArCisgICAgICAgICAgIicgb24gcmVnaW9uICIgKyBCeXRlcy50b1N0cmluZyhnZXRSZWdpb25OYW1lKCkpICsKKyAgICAgICAgICAiOiBNZW1jYWNoZSBzaXplICIgKworICAgICAgICAgIFN0cmluZ1V0aWxzLmh1bWFuUmVhZGFibGVJbnQodGhpcy5tZW1jYWNoZVNpemUuZ2V0KCkpICsKKyAgICAgICAgICAiIGlzID49IHRoYW4gYmxvY2tpbmcgIiArCisgICAgICAgICAgU3RyaW5nVXRpbHMuaHVtYW5SZWFkYWJsZUludCh0aGlzLmJsb2NraW5nTWVtY2FjaGVTaXplKSArICIgc2l6ZSIpOworICAgICAgfQorICAgICAgYmxvY2tlZCA9IHRydWU7CisgICAgICBzeW5jaHJvbml6ZWQodGhpcykgeworICAgICAgICB0cnkgeworICAgICAgICAgIHdhaXQodGhyZWFkV2FrZUZyZXF1ZW5jeSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvLyBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBpZiAoYmxvY2tlZCkgeworICAgICAgTE9HLmluZm8oIlVuYmxvY2tpbmcgdXBkYXRlcyBmb3IgcmVnaW9uICIgKyB0aGlzICsgIiAnIgorICAgICAgICAgICsgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiJyIpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgb2YgdGhlIHNhbWUgYWdlIGFzIHRoZSBwYXNzZWQgdGltZXN0YW1wIG9yIG9sZGVyLgorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIHRzIERlbGV0ZSBhbGwgZW50cmllcyB0aGF0IGhhdmUgdGhpcyB0aW1lc3RhbXAgb3Igb2xkZXIKKyAgICogQHBhcmFtIGxvY2tpZCBSb3cgbG9jaworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIGJ5dGUgW10gY29sdW1uLCBmaW5hbCBsb25nIHRzLAorICAgICAgZmluYWwgSW50ZWdlciBsb2NraWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tDb2x1bW4oY29sdW1uKTsKKyAgICBjaGVja1JlYWRPbmx5KCk7CisgICAgSW50ZWdlciBsaWQgPSBnZXRMb2NrKGxvY2tpZCxyb3cpOworICAgIHRyeSB7CisgICAgICAvLyBEZWxldGUgQUxMIHZlcnNpb25zIHJhdGhlciB0aGFuIGNvbHVtbiBmYW1pbHkgVkVSU0lPTlMuICBJZiB3ZSBqdXN0IGRpZAorICAgICAgLy8gVkVSU0lPTlMsIHRoZW4gaWYgMiogVkVSU0lPTiBjZWxscywgc3Vic2VxdWVudCBnZXRzIHdvdWxkIGdldCBvbGQgc3R1ZmYuCisgICAgICBkZWxldGVNdWx0aXBsZShyb3csIGNvbHVtbiwgdHMsIEFMTF9WRVJTSU9OUyk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmKGxvY2tpZCA9PSBudWxsKSByZWxlYXNlUm93TG9jayhsaWQpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIG9mIHRoZSBzYW1lIGFnZSBhcyB0aGUgcGFzc2VkIHRpbWVzdGFtcCBvciBvbGRlci4KKyAgICogQHBhcmFtIHJvdworICAgKiBAcGFyYW0gdHMgRGVsZXRlIGFsbCBlbnRyaWVzIHRoYXQgaGF2ZSB0aGlzIHRpbWVzdGFtcCBvciBvbGRlcgorICAgKiBAcGFyYW0gbG9ja2lkIFJvdyBsb2NrCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgbG9uZyB0cywgZmluYWwgSW50ZWdlciBsb2NraWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tSZWFkT25seSgpOworICAgIEludGVnZXIgbGlkID0gZ2V0TG9jayhsb2NraWQsIHJvdyk7CisgICAgbG9uZyB0aW1lID0gdHM7CisgICAgaWYgKHRzID09IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkgeworICAgICAgdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIH0KKyAgICBLZXlWYWx1ZSBrdiA9IEtleVZhbHVlLmNyZWF0ZUZpcnN0T25Sb3cocm93LCB0aW1lKTsKKyAgICB0cnkgeworICAgICAgZm9yIChTdG9yZSBzdG9yZSA6IHN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgICBzdG9yZS5nZXRGdWxsKGt2LCBudWxsLCBudWxsLCBBTExfVkVSU0lPTlMsIG51bGwsIGtleXZhbHVlcywgdGltZSk7CisgICAgICAgIExpc3Q8S2V5VmFsdWU+IGVkaXRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgICAgZm9yIChLZXlWYWx1ZSBrZXk6IGtleXZhbHVlcykgeworICAgICAgICAgIC8vIFRoaXMgaXMgVUdMWS4gQ09QWSBPRiBLRVkgUEFSVCBPRiBLZXlWYWx1ZS4KKyAgICAgICAgICBlZGl0cy5hZGQoa2V5LmNsb25lRGVsZXRlKCkpOworICAgICAgICB9CisgICAgICAgIHVwZGF0ZShlZGl0cyk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChsb2NraWQgPT0gbnVsbCkgcmVsZWFzZVJvd0xvY2sobGlkKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbnMgd2l0aCB0aW1lc3RhbXBzCisgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LiAKKyAgICogCisgICAqIEBwYXJhbSByb3cgVGhlIHJvdyB0byBvcGVyYXRlIG9uCisgICAqIEBwYXJhbSBjb2x1bW5SZWdleCBUaGUgY29sdW1uIHJlZ2V4IAorICAgKiBAcGFyYW0gdGltZXN0YW1wIFRpbWVzdGFtcCB0byBtYXRjaAorICAgKiBAcGFyYW0gbG9ja2lkIFJvdyBsb2NrCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbEJ5UmVnZXgoZmluYWwgYnl0ZSBbXSByb3csIGZpbmFsIFN0cmluZyBjb2x1bW5SZWdleCwgCisgICAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgSW50ZWdlciBsb2NraWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tSZWFkT25seSgpOworICAgIFBhdHRlcm4gY29sdW1uUGF0dGVybiA9IFBhdHRlcm4uY29tcGlsZShjb2x1bW5SZWdleCk7CisgICAgSW50ZWdlciBsaWQgPSBnZXRMb2NrKGxvY2tpZCwgcm93KTsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIEtleVZhbHVlIGt2ID0gbmV3IEtleVZhbHVlKHJvdywgdGltZXN0YW1wKTsKKyAgICB0cnkgeworICAgICAgZm9yIChTdG9yZSBzdG9yZSA6IHN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgICBzdG9yZS5nZXRGdWxsKGt2LCBudWxsLCBjb2x1bW5QYXR0ZXJuLCBBTExfVkVSU0lPTlMsIG51bGwsIGtleXZhbHVlcywKKyAgICAgICAgICBub3cpOworICAgICAgICBMaXN0PEtleVZhbHVlPiBlZGl0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgIGZvciAoS2V5VmFsdWUga2V5OiBrZXl2YWx1ZXMpIHsKKyAgICAgICAgICBlZGl0cy5hZGQoa2V5LmNsb25lRGVsZXRlKCkpOworICAgICAgICB9CisgICAgICAgIHVwZGF0ZShlZGl0cyk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmKGxvY2tpZCA9PSBudWxsKSByZWxlYXNlUm93TG9jayhsaWQpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBEZWxldGUgYWxsIGNlbGxzIGZvciBhIHJvdyB3aXRoIG1hdGNoaW5nIGNvbHVtbiBmYW1pbHkgd2l0aCB0aW1lc3RhbXBzCisgICAqIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKgorICAgKiBAcGFyYW0gcm93IFRoZSByb3cgdG8gb3BlcmF0ZSBvbgorICAgKiBAcGFyYW0gZmFtaWx5IFRoZSBjb2x1bW4gZmFtaWx5IHRvIG1hdGNoCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEBwYXJhbSBsb2NraWQgUm93IGxvY2sKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5KGJ5dGUgW10gcm93LCBieXRlIFtdIGZhbWlseSwgbG9uZyB0aW1lc3RhbXAsCisgICAgICBmaW5hbCBJbnRlZ2VyIGxvY2tpZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgIGNoZWNrUmVhZE9ubHkoKTsKKyAgICBJbnRlZ2VyIGxpZCA9IGdldExvY2sobG9ja2lkLCByb3cpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIGZpbmQgdGhlIEhTdG9yZSBmb3IgdGhlIGNvbHVtbiBmYW1pbHkKKyAgICAgIFN0b3JlIHN0b3JlID0gZ2V0U3RvcmUoZmFtaWx5KTsKKyAgICAgIC8vIGZpbmQgYWxsIHRoZSBrZXlzIHRoYXQgbWF0Y2ggb3VyIGNyaXRlcmlhCisgICAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgc3RvcmUuZ2V0RnVsbChuZXcgS2V5VmFsdWUocm93LCB0aW1lc3RhbXApLCBudWxsLCBudWxsLCBBTExfVkVSU0lPTlMsCisgICAgICAgIG51bGwsIGtleXZhbHVlcywgbm93KTsKKyAgICAgIC8vIGRlbGV0ZSBhbGwgdGhlIGNlbGxzCisgICAgICBMaXN0PEtleVZhbHVlPiBlZGl0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBmb3IgKEtleVZhbHVlIGt2OiBrZXl2YWx1ZXMpIHsKKyAgICAgICAgZWRpdHMuYWRkKGt2LmNsb25lRGVsZXRlKCkpOworICAgICAgfQorICAgICAgdXBkYXRlKGVkaXRzKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYobG9ja2lkID09IG51bGwpIHJlbGVhc2VSb3dMb2NrKGxpZCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIERlbGV0ZSBhbGwgY2VsbHMgZm9yIGEgcm93IHdpdGggYWxsIHRoZSBtYXRjaGluZyBjb2x1bW4gZmFtaWxpZXMgYnkKKyAgICogZmFtaWx5UmVnZXggd2l0aCB0aW1lc3RhbXBzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA8aT50aW1lc3RhbXA8L2k+LgorICAgKiAKKyAgICogQHBhcmFtIHJvdyBUaGUgcm93IHRvIG9wZXJhdGUgb24KKyAgICogQHBhcmFtIGZhbWlseVJlZ2V4IFRoZSBjb2x1bW4gZmFtaWx5IHJlZ2V4IGZvciBtYXRjaGluZy4gVGhpcyByZWdleAorICAgKiBleHByZXNzaW9uIGp1c3QgbWF0Y2ggdGhlIGZhbWlseSBuYW1lLCBpdCBkaWRuJ3QgaW5jbHVkZSA8Y29kZT46PGNvZGU+CisgICAqIEBwYXJhbSB0aW1lc3RhbXAgVGltZXN0YW1wIHRvIG1hdGNoCisgICAqIEBwYXJhbSBsb2NraWQgUm93IGxvY2sKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmFtaWx5QnlSZWdleChieXRlIFtdIHJvdywgU3RyaW5nIGZhbWlseVJlZ2V4LAorICAgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIEludGVnZXIgbG9ja2lkKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrUmVhZE9ubHkoKTsKKyAgICAvLyBjb25zdHJ1Y3QgdGhlIGZhbWlseSByZWdleCBwYXR0ZXJuCisgICAgUGF0dGVybiBmYW1pbHlQYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKGZhbWlseVJlZ2V4KTsKKyAgICBJbnRlZ2VyIGxpZCA9IGdldExvY2sobG9ja2lkLCByb3cpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgS2V5VmFsdWUga3YgPSBuZXcgS2V5VmFsdWUocm93LCB0aW1lc3RhbXApOworICAgIHRyeSB7CisgICAgICBmb3IoU3RvcmUgc3RvcmU6IHN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBTdHJpbmcgZmFtaWx5TmFtZSA9IEJ5dGVzLnRvU3RyaW5nKHN0b3JlLmdldEZhbWlseSgpLmdldE5hbWUoKSk7CisgICAgICAgIC8vIGNoZWNrIHRoZSBmYW1pbHkgbmFtZSBtYXRjaCB0aGUgZmFtaWx5IHBhdHRlcm4uCisgICAgICAgIGlmKCEoZmFtaWx5UGF0dGVybi5tYXRjaGVyKGZhbWlseU5hbWUpLm1hdGNoZXMoKSkpIAorICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAKKyAgICAgICAgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgICAgc3RvcmUuZ2V0RnVsbChrdiwgbnVsbCwgbnVsbCwgQUxMX1ZFUlNJT05TLCBudWxsLCBrZXl2YWx1ZXMsIG5vdyk7CisgICAgICAgIExpc3Q8S2V5VmFsdWU+IGVkaXRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgICAgZm9yIChLZXlWYWx1ZSBrOiBrZXl2YWx1ZXMpIHsKKyAgICAgICAgICBlZGl0cy5hZGQoay5jbG9uZURlbGV0ZSgpKTsKKyAgICAgICAgfQorICAgICAgICB1cGRhdGUoZWRpdHMpOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBpZihsb2NraWQgPT0gbnVsbCkgcmVsZWFzZVJvd0xvY2sobGlkKTsKKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIERlbGV0ZSBvbmUgb3IgbWFueSBjZWxscy4KKyAgICogVXNlZCB0byBzdXBwb3J0IHtAbGluayAjZGVsZXRlQWxsKGJ5dGUgW10sIGJ5dGUgW10sIGxvbmcpfSBhbmQgZGVsZXRpb24gb2YKKyAgICogbGF0ZXN0IGNlbGwuCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcGFyYW0gdHMgVGltZXN0YW1wIHRvIHN0YXJ0IHNlYXJjaCBvbi4KKyAgICogQHBhcmFtIHZlcnNpb25zIEhvdyBtYW55IHZlcnNpb25zIHRvIGRlbGV0ZS4gUGFzcworICAgKiB7QGxpbmsgSENvbnN0YW50cyNBTExfVkVSU0lPTlN9IHRvIGRlbGV0ZSBhbGwuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgdm9pZCBkZWxldGVNdWx0aXBsZShmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sCisgICAgICBmaW5hbCBsb25nIHRzLCBmaW5hbCBpbnQgdmVyc2lvbnMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tSZWFkT25seSgpOworICAgIC8vIFdlIHVzZWQgdG8gaGF2ZSBhIGdldEtleXMgbWV0aG9kIHRoYXQgcHVycG9ydGVkbHkgb25seSBnb3QgdGhlIGtleXMgYW5kCisgICAgLy8gbm90IHRoZSBrZXlzIGFuZCB2YWx1ZXMuICBXZSBub3cganVzdCBkbyBnZXRGdWxsLiAgRm9yIG1lbWNhY2hlIHZhbHVlcywKKyAgICAvLyBzaG91bGRuJ3QgbWF0dGVyIGlmIHdlIGdldCBrZXkgYW5kIHZhbHVlIHNpbmNlIGl0J2xsIGJlIHRoZSBlbnRyeSB0aGF0CisgICAgLy8gaXMgaW4gbWVtY2FjaGUuICBGb3IgdGhlIGtleXZhbHVlcyBmcm9tIHN0b3JlZmlsZSwgY291bGQgYmUgc2F2aW5nIGlmCisgICAgLy8gd2Ugb25seSByZXR1cm5lZCBrZXkgY29tcG9uZW50LiBUT0RPLgorICAgIExpc3Q8S2V5VmFsdWU+IGtleXMgPSBnZXQocm93LCBjb2x1bW4sIHRzLCB2ZXJzaW9ucyk7CisgICAgaWYgKGtleXMgIT0gbnVsbCAmJiBrZXlzLnNpemUoKSA+IDApIHsKKyAgICAgIC8vIEkgdGhpbmsgdGhlIGJlbG93IGVkaXRzIGRvbid0IGhhdmUgdG8gYmUgc3RvcnRlZC4gIEl0cyBkZWxldGVzLgorICAgICAgLy8gaGV5IGRvbid0IGhhdmUgdG8gZ28gaW4gaW4gZXhhY3Qgc29ydGVkIG9yZGVyICh3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5CisgICAgICAvLyBhYm91dCB0aGUgbWV0YSBvciByb290IHNvcnQgY29tcGFyYXRvciBoZXJlKS4KKyAgICAgIExpc3Q8S2V5VmFsdWU+IGVkaXRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGZvciAoS2V5VmFsdWUga2V5OiBrZXlzKSB7CisgICAgICAgIGVkaXRzLmFkZChrZXkuY2xvbmVEZWxldGUoKSk7CisgICAgICB9CisgICAgICB1cGRhdGUoZWRpdHMpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBhbnkgY2VsbHMgZm9yIGEgZ2l2ZW4gY29vcmRpbmF0ZS4KKyAgICogCisgICAqIEBwYXJhbSByb3cgdGhlIHJvdworICAgKiBAcGFyYW0gY29sdW1uIHRoZSBjb2x1bW4sIG9yIG51bGwKKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aGUgdGltZXN0YW1wLCBvciBIQ29uc3RhbnRzLkxBVEVTVF9WRVJTSU9OIGZvciBhbnkKKyAgICogQHBhcmFtIGxvY2tpZCB0aGUgZXhpc3RpbmcgbG9jaywgb3IgbnVsbCAKKyAgICogQHJldHVybiB0cnVlIGlmIGNlbGxzIGV4aXN0IGZvciB0aGUgcm93LCBmYWxzZSBvdGhlcndpc2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGJ5dGVbXSBjb2x1bW4sIAorICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBJbnRlZ2VyIGxvY2tpZCkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tSb3cocm93KTsKKyAgICBJbnRlZ2VyIGxpZCA9IGdldExvY2sobG9ja2lkLCByb3cpOworICAgIHRyeSB7CisgICAgICBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gY29sdW1ucyA9IG51bGw7CisgICAgICBpZiAoY29sdW1uICE9IG51bGwpIHsKKyAgICAgICAgY29sdW1ucyA9IG5ldyBUcmVlU2V0PGJ5dGUgW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgICAgICBjb2x1bW5zLmFkZChjb2x1bW4pOworICAgICAgfQorICAgICAgcmV0dXJuICFnZXRGdWxsKHJvdywgY29sdW1ucywgdGltZXN0YW1wLCAxLCBsaWQpLmlzRW1wdHkoKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKGxvY2tpZCA9PSBudWxsKSByZWxlYXNlUm93TG9jayhsaWQpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFRocm93cyBleGNlcHRpb24gaWYgcmVnaW9uIGlzIGluIHJlYWQtb25seSBtb2RlLgorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgY2hlY2tSZWFkT25seSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMud3JpdGVzdGF0ZS5pc1JlYWRPbmx5KCkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigicmVnaW9uIGlzIHJlYWQgb25seSIpOworICAgIH0KKyAgfQorCisgIC8qKiAKKyAgICogQWRkIHVwZGF0ZXMgZmlyc3QgdG8gdGhlIGhsb2cgYW5kIHRoZW4gYWRkIHZhbHVlcyB0byBtZW1jYWNoZS4KKyAgICogV2FybmluZzogQXNzdW1wdGlvbiBpcyBjYWxsZXIgaGFzIGxvY2sgb24gcGFzc2VkIGluIHJvdy4KKyAgICogQHBhcmFtIGVkaXRzIENlbGwgdXBkYXRlcyBieSBjb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHVwZGF0ZShmaW5hbCBMaXN0PEtleVZhbHVlPiBlZGl0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLnVwZGF0ZShlZGl0cywgdHJ1ZSk7CisgIH0KKworICAvKiogCisgICAqIEFkZCB1cGRhdGVzIGZpcnN0IHRvIHRoZSBobG9nIChpZiB3cml0ZVRvV2FsKSBhbmQgdGhlbiBhZGQgdmFsdWVzIHRvIG1lbWNhY2hlLgorICAgKiBXYXJuaW5nOiBBc3N1bXB0aW9uIGlzIGNhbGxlciBoYXMgbG9jayBvbiBwYXNzZWQgaW4gcm93LgorICAgKiBAcGFyYW0gd3JpdGVUb1dBTCBpZiB0cnVlLCB0aGVuIHdlIHNob3VsZCB3cml0ZSB0byB0aGUgbG9nCisgICAqIEBwYXJhbSB1cGRhdGVzQnlDb2x1bW4gQ2VsbCB1cGRhdGVzIGJ5IGNvbHVtbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgdXBkYXRlKGZpbmFsIExpc3Q8S2V5VmFsdWU+IGVkaXRzLCBib29sZWFuIHdyaXRlVG9XQUwpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGVkaXRzID09IG51bGwgfHwgZWRpdHMuaXNFbXB0eSgpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGJvb2xlYW4gZmx1c2ggPSBmYWxzZTsKKyAgICB0aGlzLnVwZGF0ZXNMb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBpZiAod3JpdGVUb1dBTCkgeworICAgICAgICB0aGlzLmxvZy5hcHBlbmQocmVnaW9uSW5mby5nZXRSZWdpb25OYW1lKCksCisgICAgICAgICAgcmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCksIGVkaXRzLAorICAgICAgICAgIChyZWdpb25JbmZvLmlzTWV0YVJlZ2lvbigpIHx8IHJlZ2lvbkluZm8uaXNSb290UmVnaW9uKCkpKTsKKyAgICAgIH0KKyAgICAgIGxvbmcgc2l6ZSA9IDA7CisgICAgICBmb3IgKEtleVZhbHVlIGt2OiBlZGl0cykgeworICAgICAgICAvLyBUT0RPOiBGaXggLS0gZG8gSSBoYXZlIHRvIGRvIGEgZ2V0Q29sdW1uIGhlcmU/CisgICAgICAgIHNpemUgPSB0aGlzLm1lbWNhY2hlU2l6ZS5hZGRBbmRHZXQoZ2V0U3RvcmUoa3YuZ2V0Q29sdW1uKCkpLmFkZChrdikpOworICAgICAgfQorICAgICAgZmx1c2ggPSBpc0ZsdXNoU2l6ZShzaXplKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy51cGRhdGVzTG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgICBpZiAoZmx1c2gpIHsKKyAgICAgIC8vIFJlcXVlc3QgYSBjYWNoZSBmbHVzaC4gIERvIGl0IG91dHNpZGUgdXBkYXRlIGxvY2suCisgICAgICByZXF1ZXN0Rmx1c2goKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgcmVxdWVzdEZsdXNoKCkgeworICAgIGlmICh0aGlzLmZsdXNoTGlzdGVuZXIgPT0gbnVsbCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBzeW5jaHJvbml6ZWQgKHdyaXRlc3RhdGUpIHsKKyAgICAgIGlmICh0aGlzLndyaXRlc3RhdGUuaXNGbHVzaFJlcXVlc3RlZCgpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIHdyaXRlc3RhdGUuZmx1c2hSZXF1ZXN0ZWQgPSB0cnVlOworICAgIH0KKyAgICAvLyBNYWtlIHJlcXVlc3Qgb3V0c2lkZSBvZiBzeW5jaHJvbml6ZSBibG9jazsgSEJBU0UtODE4LgorICAgIHRoaXMuZmx1c2hMaXN0ZW5lci5yZXF1ZXN0KHRoaXMpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJGbHVzaCByZXF1ZXN0ZWQgb24gIiArIHRoaXMpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSBzaXplCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBzaXplIGlzIG92ZXIgdGhlIGZsdXNoIHRocmVzaG9sZAorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGlzRmx1c2hTaXplKGZpbmFsIGxvbmcgc2l6ZSkgeworICAgIHJldHVybiBzaXplID4gdGhpcy5tZW1jYWNoZUZsdXNoU2l6ZTsKKyAgfQorICAKKyAgLy8gRG8gYW55IHJlY29uc3RydWN0aW9uIG5lZWRlZCBmcm9tIHRoZSBsb2cKKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByb3RlY3RlZCB2b2lkIGRvUmVjb25zdHJ1Y3Rpb25Mb2coUGF0aCBvbGRMb2dGaWxlLCBsb25nIG1pblNlcUlkLCBsb25nIG1heFNlcUlkLAorICAgIFByb2dyZXNzYWJsZSByZXBvcnRlcikKKyAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAvLyBOb3RoaW5nIHRvIGRvIChSZXBsYXlpbmcgaXMgZG9uZSBpbiBIU3RvcmVzKQorICB9CisKKyAgcHJvdGVjdGVkIFN0b3JlIGluc3RhbnRpYXRlSFN0b3JlKFBhdGggYmFzZURpciwgCisgICAgSENvbHVtbkRlc2NyaXB0b3IgYywgUGF0aCBvbGRMb2dGaWxlLCBQcm9ncmVzc2FibGUgcmVwb3J0ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBTdG9yZShiYXNlRGlyLCB0aGlzLnJlZ2lvbkluZm8sIGMsIHRoaXMuZnMsIG9sZExvZ0ZpbGUsCisgICAgICB0aGlzLmNvbmYsIHJlcG9ydGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gSFN0b3JlIGluc3RhbmNlLgorICAgKiBVc2Ugd2l0aCBjYXV0aW9uLiAgRXhwb3NlZCBmb3IgdXNlIG9mIGZpeHVwIHV0aWxpdGllcy4KKyAgICogQHBhcmFtIGNvbHVtbiBOYW1lIG9mIGNvbHVtbiBmYW1pbHkgaG9zdGVkIGJ5IHRoaXMgcmVnaW9uLgorICAgKiBAcmV0dXJuIFN0b3JlIHRoYXQgZ29lcyB3aXRoIHRoZSBmYW1pbHkgb24gcGFzc2VkIDxjb2RlPmNvbHVtbjwvY29kZT4uCisgICAqIFRPRE86IE1ha2UgdGhpcyBsb29rdXAgZmFzdGVyLgorICAgKi8KKyAgcHVibGljIFN0b3JlIGdldFN0b3JlKGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgcmV0dXJuIHRoaXMuc3RvcmVzLmdldChjb2x1bW4pOyAKKyAgfQorCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAvLyBTdXBwb3J0IGNvZGUKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgLyoqIE1ha2Ugc3VyZSB0aGlzIGlzIGEgdmFsaWQgcm93IGZvciB0aGUgSFJlZ2lvbiAqLworICBwcml2YXRlIHZvaWQgY2hlY2tSb3coZmluYWwgYnl0ZSBbXSByb3cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYoIXJvd0lzSW5SYW5nZShyZWdpb25JbmZvLCByb3cpKSB7CisgICAgICB0aHJvdyBuZXcgV3JvbmdSZWdpb25FeGNlcHRpb24oIlJlcXVlc3RlZCByb3cgb3V0IG9mIHJhbmdlIGZvciAiICsKKyAgICAgICAgICAiSFJlZ2lvbiAiICsgdGhpcyArICIsIHN0YXJ0S2V5PSciICsKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyhyZWdpb25JbmZvLmdldFN0YXJ0S2V5KCkpICsgIicsIGdldEVuZEtleSgpPSciICsKKyAgICAgICAgICBCeXRlcy50b1N0cmluZyhyZWdpb25JbmZvLmdldEVuZEtleSgpKSArICInLCByb3c9JyIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHJvdykgKyAiJyIpOworICAgIH0KKyAgfQorICAKKyAgLyoKKyAgICogTWFrZSBzdXJlIHRoaXMgaXMgYSB2YWxpZCBjb2x1bW4gZm9yIHRoZSBjdXJyZW50IHRhYmxlCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lCisgICAqIEB0aHJvd3MgTm9TdWNoQ29sdW1uRmFtaWx5RXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgY2hlY2tDb2x1bW4oZmluYWwgYnl0ZSBbXSBjb2x1bW4pCisgIHRocm93cyBOb1N1Y2hDb2x1bW5GYW1pbHlFeGNlcHRpb24geworICAgIGlmIChjb2x1bW4gPT0gbnVsbCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoIXJlZ2lvbkluZm8uZ2V0VGFibGVEZXNjKCkuaGFzRmFtaWx5KGNvbHVtbikpIHsKKyAgICAgIHRocm93IG5ldyBOb1N1Y2hDb2x1bW5GYW1pbHlFeGNlcHRpb24oIkNvbHVtbiBmYW1pbHkgb24gIiArCisgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGNvbHVtbikgKyAiIGRvZXMgbm90IGV4aXN0IGluIHJlZ2lvbiAiICsgdGhpcworICAgICAgICAgICsgIiBpbiB0YWJsZSAiICsgcmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIE9idGFpbiBhIGxvY2sgb24gdGhlIGdpdmVuIHJvdy4gIEJsb2NrcyB1bnRpbCBzdWNjZXNzLgorICAgKgorICAgKiBJIGtub3cgaXQncyBzdHJhbmdlIHRvIGhhdmUgdHdvIG1hcHBpbmdzOgorICAgKiA8cHJlPgorICAgKiAgIFJPV1MgID09PiBMT0NLUworICAgKiA8L3ByZT4KKyAgICogYXMgd2VsbCBhcworICAgKiA8cHJlPgorICAgKiAgIExPQ0tTID09PiBST1dTCisgICAqIDwvcHJlPgorICAgKgorICAgKiBCdXQgaXQgYWN0cyBhcyBhIGd1YXJkIG9uIHRoZSBjbGllbnQ7IGEgbWlzd3JpdHRlbiBjbGllbnQganVzdCBjYW4ndAorICAgKiBzdWJtaXQgdGhlIG5hbWUgb2YgYSByb3cgYW5kIHN0YXJ0IHdyaXRpbmcgdG8gaXQ7IGl0IG11c3Qga25vdyB0aGUgY29ycmVjdAorICAgKiBsb2NraWQsIHdoaWNoIG1hdGNoZXMgdGhlIGxvY2sgbGlzdCBpbiBtZW1vcnkuCisgICAqIAorICAgKiA8cD5JdCB3b3VsZCBiZSBtb3JlIG1lbW9yeS1lZmZpY2llbnQgdG8gYXNzdW1lIGEgY29ycmVjdGx5LXdyaXR0ZW4gY2xpZW50LCAKKyAgICogd2hpY2ggbWF5YmUgd2UnbGwgZG8gaW4gdGhlIGZ1dHVyZS4KKyAgICogCisgICAqIEBwYXJhbSByb3cgTmFtZSBvZiByb3cgdG8gbG9jay4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGUgaGVsZCBsb2NrLgorICAgKi8KKyAgSW50ZWdlciBvYnRhaW5Sb3dMb2NrKGZpbmFsIGJ5dGUgW10gcm93KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrUm93KHJvdyk7CisgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgaWYgKHRoaXMuY2xvc2VkLmdldCgpKSB7CisgICAgICAgIHRocm93IG5ldyBOb3RTZXJ2aW5nUmVnaW9uRXhjZXB0aW9uKCJSZWdpb24gIiArIHRoaXMgKyAiIGNsb3NlZCIpOworICAgICAgfQorICAgICAgSW50ZWdlciBrZXkgPSBCeXRlcy5tYXBLZXkocm93KTsKKyAgICAgIHN5bmNocm9uaXplZCAobG9ja3NUb1Jvd3MpIHsKKyAgICAgICAgd2hpbGUgKGxvY2tzVG9Sb3dzLmNvbnRhaW5zS2V5KGtleSkpIHsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgbG9ja3NUb1Jvd3Mud2FpdCgpOworICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CisgICAgICAgICAgICAvLyBFbXB0eQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb2Nrc1RvUm93cy5wdXQoa2V5LCByb3cpOworICAgICAgICBsb2Nrc1RvUm93cy5ub3RpZnlBbGwoKTsKKyAgICAgICAgcmV0dXJuIGtleTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFVzZWQgYnkgdW5pdCB0ZXN0cy4KKyAgICogQHBhcmFtIGxvY2tpZAorICAgKiBAcmV0dXJuIFJvdyB0aGF0IGdvZXMgd2l0aCA8Y29kZT5sb2NraWQ8L2NvZGU+CisgICAqLworICBieXRlIFtdIGdldFJvd0Zyb21Mb2NrKGZpbmFsIEludGVnZXIgbG9ja2lkKSB7CisgICAgcmV0dXJuIGxvY2tzVG9Sb3dzLmdldChsb2NraWQpOworICB9CisgIAorICAvKiogCisgICAqIFJlbGVhc2UgdGhlIHJvdyBsb2NrIQorICAgKiBAcGFyYW0gcm93IE5hbWUgb2Ygcm93IHdob3NlIGxvY2sgd2UgYXJlIHRvIHJlbGVhc2UKKyAgICovCisgIHZvaWQgcmVsZWFzZVJvd0xvY2soZmluYWwgSW50ZWdlciBsb2NraWQpIHsKKyAgICBzeW5jaHJvbml6ZWQgKGxvY2tzVG9Sb3dzKSB7CisgICAgICBsb2Nrc1RvUm93cy5yZW1vdmUobG9ja2lkKTsKKyAgICAgIGxvY2tzVG9Sb3dzLm5vdGlmeUFsbCgpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFNlZSBpZiByb3cgaXMgY3VycmVudGx5IGxvY2tlZC4KKyAgICogQHBhcmFtIGxvY2tpZAorICAgKiBAcmV0dXJuIGJvb2xlYW4KKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiBpc1Jvd0xvY2tlZChmaW5hbCBJbnRlZ2VyIGxvY2tpZCkgeworICAgIHN5bmNocm9uaXplZCAobG9ja3NUb1Jvd3MpIHsKKyAgICAgIGlmKGxvY2tzVG9Sb3dzLmNvbnRhaW5zS2V5KGxvY2tpZCkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogUmV0dXJucyBleGlzdGluZyByb3cgbG9jayBpZiBmb3VuZCwgb3RoZXJ3aXNlCisgICAqIG9idGFpbnMgYSBuZXcgcm93IGxvY2sgYW5kIHJldHVybnMgaXQuCisgICAqIEBwYXJhbSBsb2NraWQKKyAgICogQHJldHVybiBsb2NraWQKKyAgICovCisgIHByaXZhdGUgSW50ZWdlciBnZXRMb2NrKEludGVnZXIgbG9ja2lkLCBieXRlIFtdIHJvdykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSW50ZWdlciBsaWQgPSBudWxsOworICAgIGlmIChsb2NraWQgPT0gbnVsbCkgeworICAgICAgbGlkID0gb2J0YWluUm93TG9jayhyb3cpOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoIWlzUm93TG9ja2VkKGxvY2tpZCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJbnZhbGlkIHJvdyBsb2NrIik7CisgICAgICB9CisgICAgICBsaWQgPSBsb2NraWQ7CisgICAgfQorICAgIHJldHVybiBsaWQ7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCB3YWl0T25Sb3dMb2NrcygpIHsKKyAgICBzeW5jaHJvbml6ZWQgKGxvY2tzVG9Sb3dzKSB7CisgICAgICB3aGlsZSAodGhpcy5sb2Nrc1RvUm93cy5zaXplKCkgPiAwKSB7CisgICAgICAgIExPRy5kZWJ1Zygid2FpdGluZyBmb3IgIiArIHRoaXMubG9ja3NUb1Jvd3Muc2l6ZSgpICsgIiByb3cgbG9ja3MiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICB0aGlzLmxvY2tzVG9Sb3dzLndhaXQoKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIENhdGNoLiBMZXQgd2hpbGUgdGVzdCBkZXRlcm1pbmUgbG9vcC1lbmQuCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKKyAgICByZXR1cm4gdGhpcy5oYXNoQ29kZSgpID09ICgoSFJlZ2lvbilvKS5oYXNoQ29kZSgpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKS5oYXNoQ29kZSgpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gdGhpcy5yZWdpb25JbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpOworICB9CisKKyAgLyoqIEByZXR1cm4gUGF0aCBvZiByZWdpb24gYmFzZSBkaXJlY3RvcnkgKi8KKyAgcHVibGljIFBhdGggZ2V0QmFzZURpcigpIHsKKyAgICByZXR1cm4gdGhpcy5iYXNlZGlyOworICB9CisKKyAgLyoqCisgICAqIEhTY2FubmVyIGlzIGFuIGl0ZXJhdG9yIHRocm91Z2ggYSBidW5jaCBvZiByb3dzIGluIGFuIEhSZWdpb24uCisgICAqLworICBwcml2YXRlIGNsYXNzIEhTY2FubmVyIGltcGxlbWVudHMgSW50ZXJuYWxTY2FubmVyIHsKKyAgICBwcml2YXRlIEludGVybmFsU2Nhbm5lcltdIHNjYW5uZXJzOworICAgIHByaXZhdGUgTGlzdDxLZXlWYWx1ZT4gW10gcmVzdWx0U2V0czsKKyAgICBwcml2YXRlIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXI7CisKKyAgICAvKiogQ3JlYXRlIGFuIEhTY2FubmVyIHdpdGggYSBoYW5kbGUgb24gbWFueSBIU3RvcmVzLiAqLworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIEhTY2FubmVyKGZpbmFsIE5hdmlnYWJsZVNldDxieXRlIFtdPiBjb2x1bW5zLCBieXRlIFtdIGZpcnN0Um93LAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIFN0b3JlIFtdIHN0b3JlcywgZmluYWwgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy5maWx0ZXIgPSBmaWx0ZXI7CisgICAgICB0aGlzLnNjYW5uZXJzID0gbmV3IEludGVybmFsU2Nhbm5lcltzdG9yZXMubGVuZ3RoXTsKKyAgICAgIHRyeSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RvcmVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgLy8gT25seSBwYXNzIHJlbGV2YW50IGNvbHVtbnMgdG8gZWFjaCBzdG9yZQorICAgICAgICAgIE5hdmlnYWJsZVNldDxieXRlW10+IGNvbHVtblN1YnNldCA9CisgICAgICAgICAgICBuZXcgVHJlZVNldDxieXRlW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgICAgICAgIGZvciAoYnl0ZSBbXSBjOiBjb2x1bW5zKSB7CisgICAgICAgICAgICBpZiAoS2V5VmFsdWUuRkFNSUxZX0NPTVBBUkFUT1IuY29tcGFyZShzdG9yZXNbaV0uc3RvcmVOYW1lLCBjKSA9PSAwKSB7CisgICAgICAgICAgICAgIGNvbHVtblN1YnNldC5hZGQoYyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmID0gZmlsdGVyOworICAgICAgICAgIGlmIChmICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIE5lZWQgdG8gcmVwbGljYXRlIGZpbHRlcnMuCisgICAgICAgICAgICAvLyBBdCBsZWFzdCBXaGlsZU1hdGNoUm93RmlsdGVyIHdpbGwgbWVzcyB1cCB0aGUgc2NhbiBpZiBvbmx5CisgICAgICAgICAgICAvLyBvbmUgc2hhcmVkIGFjcm9zcyBtYW55IHJvd3MuIFNlZSBIQURPT1AtMjQ2Ny4KKyAgICAgICAgICAgIGYgPSAoUm93RmlsdGVySW50ZXJmYWNlKSBXcml0YWJsZVV0aWxzLmNsb25lKGZpbHRlciwgY29uZik7CisgICAgICAgICAgfQorICAgICAgICAgIHNjYW5uZXJzW2ldID0gc3RvcmVzW2ldLmdldFNjYW5uZXIodGltZXN0YW1wLCBjb2x1bW5TdWJzZXQsIGZpcnN0Um93LCBmKTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICBpZiAoc2Nhbm5lcnNbaV0gIT0gbnVsbCkgeworICAgICAgICAgICAgY2xvc2VTY2FubmVyKGkpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB0aHJvdyBlOworICAgICAgfQorCisgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBrZXkgaW4gZWFjaCBzdG9yZS4KKyAgICAgIC8vIEFsbCByZXN1bHRzIHdpbGwgbWF0Y2ggdGhlIHJlcXVpcmVkIGNvbHVtbi1zZXQgYW5kIHNjYW5UaW1lLgorICAgICAgdGhpcy5yZXN1bHRTZXRzID0gbmV3IExpc3Rbc2Nhbm5lcnMubGVuZ3RoXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgcmVzdWx0U2V0c1tpXSA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgIGlmKHNjYW5uZXJzW2ldICE9IG51bGwgJiYgIXNjYW5uZXJzW2ldLm5leHQocmVzdWx0U2V0c1tpXSkpIHsKKyAgICAgICAgICBjbG9zZVNjYW5uZXIoaSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLy8gQXMgd2UgaGF2ZSBub3cgc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCBpbml0aWFsaXphdGlvbiwgaW5jcmVtZW50IHRoZQorICAgICAgLy8gYWN0aXZlU2Nhbm5lciBjb3VudC4KKyAgICAgIGFjdGl2ZVNjYW5uZXJDb3VudC5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGJvb2xlYW4gbW9yZVRvRm9sbG93ID0gZmFsc2U7CisgICAgICBib29sZWFuIGZpbHRlcmVkID0gZmFsc2U7CisgICAgICBkbyB7CisgICAgICAgIC8vIEZpbmQgdGhlIGxvd2VzdCBrZXkgYWNyb3NzIGFsbCBzdG9yZXMuCisgICAgICAgIEtleVZhbHVlIGNob3NlbiA9IG51bGw7CisgICAgICAgIGxvbmcgY2hvc2VuVGltZXN0YW1wID0gLTE7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5zY2FubmVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgIGlmICh0aGlzLnJlc3VsdFNldHNbaV0gPT0gbnVsbCB8fCB0aGlzLnJlc3VsdFNldHNbaV0uaXNFbXB0eSgpKSB7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICB9CisgICAgICAgICAgS2V5VmFsdWUga3YgPSB0aGlzLnJlc3VsdFNldHNbaV0uZ2V0KDApOworICAgICAgICAgIGlmIChjaG9zZW4gPT0gbnVsbCB8fAorICAgICAgICAgICAgICAgKGNvbXBhcmF0b3IuY29tcGFyZVJvd3Moa3YsIGNob3NlbikgPCAwKSB8fAorICAgICAgICAgICAgICAgKChjb21wYXJhdG9yLmNvbXBhcmVSb3dzKGt2LCBjaG9zZW4pID09IDApICYmCisgICAgICAgICAgICAgICAgIChrdi5nZXRUaW1lc3RhbXAoKSA+IGNob3NlblRpbWVzdGFtcCkpKSB7CisgICAgICAgICAgICBjaG9zZW4gPSBrdjsKKyAgICAgICAgICAgIGNob3NlblRpbWVzdGFtcCA9IGNob3Nlbi5nZXRUaW1lc3RhbXAoKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvLyBTdG9yZSByZXN1bHRzIGZyb20gZWFjaCBzdWItc2Nhbm5lci4KKyAgICAgICAgaWYgKGNob3NlblRpbWVzdGFtcCA+PSAwKSB7CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzY2FubmVycy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaWYgKHRoaXMucmVzdWx0U2V0c1tpXSA9PSBudWxsIHx8IHRoaXMucmVzdWx0U2V0c1tpXS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBLZXlWYWx1ZSBrdiA9IHRoaXMucmVzdWx0U2V0c1tpXS5nZXQoMCk7CisgICAgICAgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlUm93cyhrdiwgY2hvc2VuKSA9PSAwKSB7CisgICAgICAgICAgICAgIHJlc3VsdHMuYWRkQWxsKHRoaXMucmVzdWx0U2V0c1tpXSk7CisgICAgICAgICAgICAgIHJlc3VsdFNldHNbaV0uY2xlYXIoKTsKKyAgICAgICAgICAgICAgaWYgKCFzY2FubmVyc1tpXS5uZXh0KHJlc3VsdFNldHNbaV0pKSB7CisgICAgICAgICAgICAgICAgY2xvc2VTY2FubmVyKGkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbW9yZVRvRm9sbG93ID0gY2hvc2VuVGltZXN0YW1wID49IDA7CisgICAgICAgIGlmIChyZXN1bHRzID09IG51bGwgfHwgcmVzdWx0cy5zaXplKCkgPD0gMCkgeworICAgICAgICAgIC8vIElmIHdlIGdvdCBubyByZXN1bHRzLCB0aGVuIHRoZXJlIGlzIG5vIG1vcmUgdG8gZm9sbG93LgorICAgICAgICAgIG1vcmVUb0ZvbGxvdyA9IGZhbHNlOworICAgICAgICB9CisKKyAgICAgICAgZmlsdGVyZWQgPSBmaWx0ZXIgPT0gbnVsbCA/IGZhbHNlIDogZmlsdGVyLmZpbHRlclJvdyhyZXN1bHRzKTsKKyAgICAgICAgaWYgKGZpbHRlciAhPSBudWxsICYmIGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSkgeworICAgICAgICAgIG1vcmVUb0ZvbGxvdyA9IGZhbHNlOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAobW9yZVRvRm9sbG93KSB7CisgICAgICAgICAgaWYgKGZpbHRlciAhPSBudWxsKSB7CisgICAgICAgICAgICBmaWx0ZXIucm93UHJvY2Vzc2VkKGZpbHRlcmVkLCBjaG9zZW4uZ2V0QnVmZmVyKCksIGNob3Nlbi5nZXRSb3dPZmZzZXQoKSwKKyAgICAgICAgICAgICAgY2hvc2VuLmdldFJvd0xlbmd0aCgpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKGZpbHRlcmVkKSB7CisgICAgICAgICAgICByZXN1bHRzLmNsZWFyKCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IHdoaWxlKGZpbHRlcmVkICYmIG1vcmVUb0ZvbGxvdyk7CisKKyAgICAgIC8vIE1ha2Ugc3VyZSBzY2FubmVycyBjbG9zZWQgaWYgbm8gbW9yZSByZXN1bHRzCisgICAgICBpZiAoIW1vcmVUb0ZvbGxvdykgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNjYW5uZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgaWYgKG51bGwgIT0gc2Nhbm5lcnNbaV0pIHsKKyAgICAgICAgICAgIGNsb3NlU2Nhbm5lcihpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIAorICAgICAgcmV0dXJuIG1vcmVUb0ZvbGxvdzsKKyAgICB9CisKKyAgICAvKiogU2h1dCBkb3duIGEgc2luZ2xlIHNjYW5uZXIgKi8KKyAgICB2b2lkIGNsb3NlU2Nhbm5lcihpbnQgaSkgeworICAgICAgdHJ5IHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBzY2FubmVyc1tpXS5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLndhcm4oIkZhaWxlZCBjbG9zaW5nIHNjYW5uZXIgIiArIGksIGUpOworICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzY2FubmVyc1tpXSA9IG51bGw7CisgICAgICAgIC8vIFRoZXNlIGRhdGEgbWVtYmVycyBjYW4gYmUgbnVsbCBpZiBleGNlcHRpb24gaW4gY29uc3RydWN0b3IKKyAgICAgICAgaWYgKHJlc3VsdFNldHMgIT0gbnVsbCkgeworICAgICAgICAgIHJlc3VsdFNldHNbaV0gPSBudWxsOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgICB0cnkgeworICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICBpZihzY2FubmVyc1tpXSAhPSBudWxsKSB7CisgICAgICAgICAgICBjbG9zZVNjYW5uZXIoaSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKGFjdGl2ZVNjYW5uZXJDb3VudCkgeworICAgICAgICAgIGludCBjb3VudCA9IGFjdGl2ZVNjYW5uZXJDb3VudC5kZWNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgICBpZiAoY291bnQgPCAwKSB7CisgICAgICAgICAgICBMT0cuZXJyb3IoImFjdGl2ZSBzY2FubmVyIGNvdW50IGxlc3MgdGhhbiB6ZXJvOiAiICsgY291bnQgKworICAgICAgICAgICAgICAgICIgcmVzZXR0aW5nIHRvIHplcm8iKTsKKyAgICAgICAgICAgIGFjdGl2ZVNjYW5uZXJDb3VudC5zZXQoMCk7CisgICAgICAgICAgICBjb3VudCA9IDA7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgICAgICBhY3RpdmVTY2FubmVyQ291bnQubm90aWZ5QWxsKCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNXaWxkY2FyZFNjYW5uZXIoKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlVuaW1wbGVtZW50ZWQgb24gSFNjYW5uZXIiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc011bHRpcGxlTWF0Y2hTY2FubmVyKCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJVbmltcGxlbWVudGVkIG9uIEhTY2FubmVyIik7CisgICAgfSAgCisgIH0KKyAgCisgIC8vIFV0aWxpdHkgbWV0aG9kcworCisgIC8qKgorICAgKiBDb252ZW5pZW5jZSBtZXRob2QgY3JlYXRpbmcgbmV3IEhSZWdpb25zLiBVc2VkIGJ5IGNyZWF0ZVRhYmxlIGFuZCBieSB0aGUKKyAgICogYm9vdHN0cmFwIGNvZGUgaW4gdGhlIEhNYXN0ZXIgY29uc3RydWN0b3IuCisgICAqIE5vdGUsIHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4ge0BsaW5rIEhMb2d9IGZvciB0aGUgY3JlYXRlZCByZWdpb24uIEl0CisgICAqIG5lZWRzIHRvIGJlIGNsb3NlZCBleHBsaWNpdGx5LiAgVXNlIHtAbGluayBIUmVnaW9uI2dldExvZygpfSB0byBnZXQKKyAgICogYWNjZXNzLgorICAgKiBAcGFyYW0gaW5mbyBJbmZvIGZvciByZWdpb24gdG8gY3JlYXRlLgorICAgKiBAcGFyYW0gcm9vdERpciBSb290IGRpcmVjdG9yeSBmb3IgSEJhc2UgaW5zdGFuY2UKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHJldHVybiBuZXcgSFJlZ2lvbgorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIUmVnaW9uIGNyZWF0ZUhSZWdpb24oZmluYWwgSFJlZ2lvbkluZm8gaW5mbywgZmluYWwgUGF0aCByb290RGlyLAorICAgIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBhdGggdGFibGVEaXIgPQorICAgICAgSFRhYmxlRGVzY3JpcHRvci5nZXRUYWJsZURpcihyb290RGlyLCBpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSk7CisgICAgUGF0aCByZWdpb25EaXIgPSBIUmVnaW9uLmdldFJlZ2lvbkRpcih0YWJsZURpciwgaW5mby5nZXRFbmNvZGVkTmFtZSgpKTsKKyAgICBGaWxlU3lzdGVtIGZzID0gRmlsZVN5c3RlbS5nZXQoY29uZik7CisgICAgZnMubWtkaXJzKHJlZ2lvbkRpcik7CisgICAgLy8gTm90ZSBpbiBoaXN0b3JpYW4gdGhlIGNyZWF0aW9uIG9mIG5ldyByZWdpb24uCisgICAgaWYgKCFpbmZvLmlzTWV0YVJlZ2lvbigpKSB7CisgICAgICBSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKS5hZGRSZWdpb25DcmVhdGlvbihpbmZvKTsKKyAgICB9CisgICAgSFJlZ2lvbiByZWdpb24gPSBuZXcgSFJlZ2lvbih0YWJsZURpciwKKyAgICAgIG5ldyBITG9nKGZzLCBuZXcgUGF0aChyZWdpb25EaXIsIEhSRUdJT05fTE9HRElSX05BTUUpLCBjb25mLCBudWxsKSwKKyAgICAgIGZzLCBjb25mLCBpbmZvLCBudWxsKTsKKyAgICByZWdpb24uaW5pdGlhbGl6ZShudWxsLCBudWxsKTsKKyAgICByZXR1cm4gcmVnaW9uOworICB9CisgIAorICAvKioKKyAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIG9wZW4gYSBIUmVnaW9uIG91dHNpZGUgb2YgYW4gSFJlZ2lvblNlcnZlciBjb250ZXh0LgorICAgKiBAcGFyYW0gaW5mbyBJbmZvIGZvciByZWdpb24gdG8gYmUgb3BlbmVkLgorICAgKiBAcGFyYW0gcm9vdERpciBSb290IGRpcmVjdG9yeSBmb3IgSEJhc2UgaW5zdGFuY2UKKyAgICogQHBhcmFtIGxvZyBITG9nIGZvciByZWdpb24gdG8gdXNlLiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwKKyAgICogSExvZyNzZXRTZXF1ZW5jZU51bWJlcihsb25nKSBwYXNzaW5nIHRoZSByZXN1bHQgb2YgdGhlIGNhbGwgdG8KKyAgICogSFJlZ2lvbiNnZXRNaW5TZXF1ZW5jZUlkKCkgdG8gZW5zdXJlIHRoZSBsb2cgaWQgaXMgcHJvcGVybHkga2VwdAorICAgKiB1cC4gIEhSZWdpb25TdG9yZSBkb2VzIHRoaXMgZXZlcnkgdGltZSBpdCBvcGVucyBhIG5ldyByZWdpb24uCisgICAqIEBwYXJhbSBjb25mCisgICAqIEByZXR1cm4gbmV3IEhSZWdpb24KKyAgICogCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFJlZ2lvbiBvcGVuSFJlZ2lvbihmaW5hbCBIUmVnaW9uSW5mbyBpbmZvLCBmaW5hbCBQYXRoIHJvb3REaXIsCisgICAgZmluYWwgSExvZyBsb2csIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJPcGVuaW5nIHJlZ2lvbjogIiArIGluZm8pOworICAgIH0KKyAgICBpZiAoaW5mbyA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlBhc3NlZCByZWdpb24gaW5mbyBpcyBudWxsIik7CisgICAgfQorICAgIEhSZWdpb24gciA9IG5ldyBIUmVnaW9uKAorICAgICAgICBIVGFibGVEZXNjcmlwdG9yLmdldFRhYmxlRGlyKHJvb3REaXIsIGluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpKSwKKyAgICAgICAgbG9nLCBGaWxlU3lzdGVtLmdldChjb25mKSwgY29uZiwgaW5mbywgbnVsbCk7CisgICAgci5pbml0aWFsaXplKG51bGwsIG51bGwpOworICAgIGlmIChsb2cgIT0gbnVsbCkgeworICAgICAgbG9nLnNldFNlcXVlbmNlTnVtYmVyKHIuZ2V0TWluU2VxdWVuY2VJZCgpKTsKKyAgICB9CisgICAgcmV0dXJuIHI7CisgIH0KKyAgCisgIC8qKgorICAgKiBJbnNlcnRzIGEgbmV3IHJlZ2lvbidzIG1ldGEgaW5mb3JtYXRpb24gaW50byB0aGUgcGFzc2VkCisgICAqIDxjb2RlPm1ldGE8L2NvZGU+IHJlZ2lvbi4gVXNlZCBieSB0aGUgSE1hc3RlciBib290c3RyYXAgY29kZSBhZGRpbmcKKyAgICogbmV3IHRhYmxlIHRvIFJPT1QgdGFibGUuCisgICAqIAorICAgKiBAcGFyYW0gbWV0YSBNRVRBIEhSZWdpb24gdG8gYmUgdXBkYXRlZAorICAgKiBAcGFyYW0gciBIUmVnaW9uIHRvIGFkZCB0byA8Y29kZT5tZXRhPC9jb2RlPgorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgYWRkUmVnaW9uVG9NRVRBKEhSZWdpb24gbWV0YSwgSFJlZ2lvbiByKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBtZXRhLmNoZWNrUmVzb3VyY2VzKCk7CisgICAgLy8gVGhlIHJvdyBrZXkgaXMgdGhlIHJlZ2lvbiBuYW1lCisgICAgYnl0ZSBbXSByb3cgPSByLmdldFJlZ2lvbk5hbWUoKTsKKyAgICBJbnRlZ2VyIGxpZCA9IG1ldGEub2J0YWluUm93TG9jayhyb3cpOworICAgIHRyeSB7CisgICAgICBMaXN0PEtleVZhbHVlPiBlZGl0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBlZGl0cy5hZGQobmV3IEtleVZhbHVlKHJvdywgQ09MX1JFR0lPTklORk8sIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLAorICAgICAgICBXcml0YWJsZXMuZ2V0Qnl0ZXMoci5nZXRSZWdpb25JbmZvKCkpKSk7CisgICAgICBtZXRhLnVwZGF0ZShlZGl0cyk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG1ldGEucmVsZWFzZVJvd0xvY2sobGlkKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRGVsZXRlIGEgcmVnaW9uJ3MgbWV0YSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBwYXNzZWQKKyAgICogPGNvZGU+bWV0YTwvY29kZT4gcmVnaW9uLiAgUmVtb3ZlcyBjb250ZW50IGluIHRoZSAnaW5mbycgY29sdW1uIGZhbWlseS4KKyAgICogRG9lcyBub3QgcmVtb3ZlIHJlZ2lvbiBoaXN0b3JpYW4gaW5mby4KKyAgICogCisgICAqIEBwYXJhbSBzcnZyIE1FVEEgc2VydmVyIHRvIGJlIHVwZGF0ZWQKKyAgICogQHBhcmFtIG1ldGFSZWdpb25OYW1lIE1ldGEgcmVnaW9uIG5hbWUKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgSFJlZ2lvbiB0byByZW1vdmUgZnJvbSA8Y29kZT5tZXRhPC9jb2RlPgorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlUmVnaW9uRnJvbU1FVEEoZmluYWwgSFJlZ2lvbkludGVyZmFjZSBzcnZyLAorICAgIGZpbmFsIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUsIGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzcnZyLmRlbGV0ZUZhbWlseShtZXRhUmVnaW9uTmFtZSwgcmVnaW9uTmFtZSwgSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCAtMUwpOworICB9CisKKyAgLyoqCisgICAqIFV0aWxpdHkgbWV0aG9kIHVzZWQgYnkgSE1hc3RlciBtYXJraW5nIHJlZ2lvbnMgb2ZmbGluZWQuCisgICAqIEBwYXJhbSBzcnZyIE1FVEEgc2VydmVyIHRvIGJlIHVwZGF0ZWQKKyAgICogQHBhcmFtIG1ldGFSZWdpb25OYW1lIE1ldGEgcmVnaW9uIG5hbWUKKyAgICogQHBhcmFtIGluZm8gSFJlZ2lvbiB0byB1cGRhdGUgaW4gPGNvZGU+bWV0YTwvY29kZT4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG9mZmxpbmVSZWdpb25Jbk1FVEEoZmluYWwgSFJlZ2lvbkludGVyZmFjZSBzcnZyLAorICAgIGZpbmFsIGJ5dGUgW10gbWV0YVJlZ2lvbk5hbWUsIGZpbmFsIEhSZWdpb25JbmZvIGluZm8pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShpbmZvLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgaW5mby5zZXRPZmZsaW5lKHRydWUpOworICAgIGIucHV0KENPTF9SRUdJT05JTkZPLCBXcml0YWJsZXMuZ2V0Qnl0ZXMoaW5mbykpOworICAgIGIuZGVsZXRlKENPTF9TRVJWRVIpOworICAgIGIuZGVsZXRlKENPTF9TVEFSVENPREUpOworICAgIC8vIElmIGNhcnJ5aW5nIHNwbGl0cywgdGhleSdsbCBiZSBpbiBwbGFjZSB3aGVuIHdlIHNob3cgdXAgb24gbmV3CisgICAgLy8gc2VydmVyLgorICAgIHNydnIuYmF0Y2hVcGRhdGUobWV0YVJlZ2lvbk5hbWUsIGIsIC0xTCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDbGVhbiBDT0xfU0VSVkVSIGFuZCBDT0xfU1RBUlRDT0RFIGZvciBwYXNzZWQgPGNvZGU+aW5mbzwvY29kZT4gaW4KKyAgICogPGNvZGU+Lk1FVEEuPC9jb2RlPgorICAgKiBAcGFyYW0gc3J2cgorICAgKiBAcGFyYW0gbWV0YVJlZ2lvbk5hbWUKKyAgICogQHBhcmFtIGluZm8KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGNsZWFuUmVnaW9uSW5NRVRBKGZpbmFsIEhSZWdpb25JbnRlcmZhY2Ugc3J2ciwKKyAgICBmaW5hbCBieXRlIFtdIG1ldGFSZWdpb25OYW1lLCBmaW5hbCBIUmVnaW9uSW5mbyBpbmZvKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUoaW5mby5nZXRSZWdpb25OYW1lKCkpOworICAgIGIuZGVsZXRlKENPTF9TRVJWRVIpOworICAgIGIuZGVsZXRlKENPTF9TVEFSVENPREUpOworICAgIC8vIElmIGNhcnJ5aW5nIHNwbGl0cywgdGhleSdsbCBiZSBpbiBwbGFjZSB3aGVuIHdlIHNob3cgdXAgb24gbmV3CisgICAgLy8gc2VydmVyLgorICAgIHNydnIuYmF0Y2hVcGRhdGUobWV0YVJlZ2lvbk5hbWUsIGIsIExBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZXMgYWxsIHRoZSBmaWxlcyBmb3IgYSBIUmVnaW9uCisgICAqIAorICAgKiBAcGFyYW0gZnMgdGhlIGZpbGUgc3lzdGVtIG9iamVjdAorICAgKiBAcGFyYW0gcm9vdGRpciBxdWFsaWZpZWQgcGF0aCBvZiBIQmFzZSByb290IGRpcmVjdG9yeQorICAgKiBAcGFyYW0gaW5mbyBIUmVnaW9uSW5mbyBmb3IgcmVnaW9uIHRvIGJlIGRlbGV0ZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGRlbGV0ZVJlZ2lvbihGaWxlU3lzdGVtIGZzLCBQYXRoIHJvb3RkaXIsIEhSZWdpb25JbmZvIGluZm8pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZXRlUmVnaW9uKGZzLCBIUmVnaW9uLmdldFJlZ2lvbkRpcihyb290ZGlyLCBpbmZvKSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGRlbGV0ZVJlZ2lvbihGaWxlU3lzdGVtIGZzLCBQYXRoIHJlZ2lvbmRpcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiREVMRVRJTkcgcmVnaW9uICIgKyByZWdpb25kaXIudG9TdHJpbmcoKSk7CisgICAgfQorICAgIGlmICghZnMuZGVsZXRlKHJlZ2lvbmRpciwgdHJ1ZSkpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgZGVsZXRlIG9mICIgKyByZWdpb25kaXIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgUGF0aCBvZiB0aGUgSFJlZ2lvbgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlZGlyIHF1YWxpZmllZCBwYXRoIGZvciB0YWJsZQorICAgKiBAcGFyYW0gbmFtZSBFTkNPREVEIHJlZ2lvbiBuYW1lCisgICAqIEByZXR1cm4gUGF0aCBvZiBIUmVnaW9uIGRpcmVjdG9yeQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBQYXRoIGdldFJlZ2lvbkRpcihmaW5hbCBQYXRoIHRhYmxlZGlyLCBmaW5hbCBpbnQgbmFtZSkgeworICAgIHJldHVybiBuZXcgUGF0aCh0YWJsZWRpciwgSW50ZWdlci50b1N0cmluZyhuYW1lKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21wdXRlcyB0aGUgUGF0aCBvZiB0aGUgSFJlZ2lvbgorICAgKiAKKyAgICogQHBhcmFtIHJvb3RkaXIgcXVhbGlmaWVkIHBhdGggb2YgSEJhc2Ugcm9vdCBkaXJlY3RvcnkKKyAgICogQHBhcmFtIGluZm8gSFJlZ2lvbkluZm8gZm9yIHRoZSByZWdpb24KKyAgICogQHJldHVybiBxdWFsaWZpZWQgcGF0aCBvZiByZWdpb24gZGlyZWN0b3J5CisgICAqLworICBwdWJsaWMgc3RhdGljIFBhdGggZ2V0UmVnaW9uRGlyKGZpbmFsIFBhdGggcm9vdGRpciwgZmluYWwgSFJlZ2lvbkluZm8gaW5mbykgeworICAgIHJldHVybiBuZXcgUGF0aCgKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IuZ2V0VGFibGVEaXIocm9vdGRpciwgaW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCkpLAorICAgICAgSW50ZWdlci50b1N0cmluZyhpbmZvLmdldEVuY29kZWROYW1lKCkpKTsKKyAgfQorCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgcm93IGlzIHdpdGhpbiB0aGUgcm93IHJhbmdlIHNwZWNpZmllZCBieSB0aGUKKyAgICogc3BlY2lmaWVkIEhSZWdpb25JbmZvCisgICAqICAKKyAgICogQHBhcmFtIGluZm8gSFJlZ2lvbkluZm8gdGhhdCBzcGVjaWZpZXMgdGhlIHJvdyByYW5nZQorICAgKiBAcGFyYW0gcm93IHJvdyB0byBiZSBjaGVja2VkCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgcm93IGlzIHdpdGhpbiB0aGUgcmFuZ2Ugc3BlY2lmaWVkIGJ5IHRoZSBIUmVnaW9uSW5mbworICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIHJvd0lzSW5SYW5nZShIUmVnaW9uSW5mbyBpbmZvLCBmaW5hbCBieXRlIFtdIHJvdykgeworICAgIHJldHVybiAoKGluZm8uZ2V0U3RhcnRLZXkoKS5sZW5ndGggPT0gMCkgfHwKKyAgICAgICAgKEJ5dGVzLmNvbXBhcmVUbyhpbmZvLmdldFN0YXJ0S2V5KCksIHJvdykgPD0gMCkpICYmCisgICAgICAgICgoaW5mby5nZXRFbmRLZXkoKS5sZW5ndGggPT0gMCkgfHwKKyAgICAgICAgICAgIChCeXRlcy5jb21wYXJlVG8oaW5mby5nZXRFbmRLZXkoKSwgcm93KSA+IDApKTsKKyAgfQorCisgIC8qKgorICAgKiBNYWtlIHRoZSBkaXJlY3RvcmllcyBmb3IgYSBzcGVjaWZpYyBjb2x1bW4gZmFtaWx5CisgICAqIAorICAgKiBAcGFyYW0gZnMgdGhlIGZpbGUgc3lzdGVtCisgICAqIEBwYXJhbSB0YWJsZWRpciBiYXNlIGRpcmVjdG9yeSB3aGVyZSByZWdpb24gd2lsbCBsaXZlICh1c3VhbGx5IHRoZSB0YWJsZSBkaXIpCisgICAqIEBwYXJhbSBocmkKKyAgICogQHBhcmFtIGNvbEZhbWlseSB0aGUgY29sdW1uIGZhbWlseQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFrZUNvbHVtbkZhbWlseURpcnMoRmlsZVN5c3RlbSBmcywgUGF0aCB0YWJsZWRpciwKKyAgICBmaW5hbCBIUmVnaW9uSW5mbyBocmksIGJ5dGUgW10gY29sRmFtaWx5KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBhdGggZGlyID0gU3RvcmUuZ2V0U3RvcmVIb21lZGlyKHRhYmxlZGlyLCBocmkuZ2V0RW5jb2RlZE5hbWUoKSwgY29sRmFtaWx5KTsKKyAgICBpZiAoIWZzLm1rZGlycyhkaXIpKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGNyZWF0ZSAiICsgZGlyKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogTWVyZ2UgdHdvIEhSZWdpb25zLiAgVGhlIHJlZ2lvbnMgbXVzdCBiZSBhZGphY2VudCBhbmQgbXVzdCBub3Qgb3ZlcmxhcC4KKyAgICogCisgICAqIEBwYXJhbSBzcmNBCisgICAqIEBwYXJhbSBzcmNCCisgICAqIEByZXR1cm4gbmV3IG1lcmdlZCBIUmVnaW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFJlZ2lvbiBtZXJnZUFkamFjZW50KGZpbmFsIEhSZWdpb24gc3JjQSwgZmluYWwgSFJlZ2lvbiBzcmNCKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gYSA9IHNyY0E7CisgICAgSFJlZ2lvbiBiID0gc3JjQjsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHNyY0EgY29tZXMgZmlyc3Q7IGltcG9ydGFudCBmb3Iga2V5LW9yZGVyaW5nIGR1cmluZworICAgIC8vIHdyaXRlIG9mIHRoZSBtZXJnZWQgZmlsZS4KKyAgICBpZiAoc3JjQS5nZXRTdGFydEtleSgpID09IG51bGwpIHsKKyAgICAgIGlmIChzcmNCLmdldFN0YXJ0S2V5KCkgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbm5vdCBtZXJnZSB0d28gcmVnaW9ucyB3aXRoIG51bGwgc3RhcnQga2V5Iik7CisgICAgICB9CisgICAgICAvLyBBJ3Mgc3RhcnQga2V5IGlzIG51bGwgYnV0IEIncyBpc24ndC4gQXNzdW1lIEEgY29tZXMgYmVmb3JlIEIKKyAgICB9IGVsc2UgaWYgKChzcmNCLmdldFN0YXJ0S2V5KCkgPT0gbnVsbCkgfHwKKyAgICAgIChCeXRlcy5jb21wYXJlVG8oc3JjQS5nZXRTdGFydEtleSgpLCBzcmNCLmdldFN0YXJ0S2V5KCkpID4gMCkpIHsKKyAgICAgIGEgPSBzcmNCOworICAgICAgYiA9IHNyY0E7CisgICAgfQorCisgICAgaWYgKCEoQnl0ZXMuY29tcGFyZVRvKGEuZ2V0RW5kS2V5KCksIGIuZ2V0U3RhcnRLZXkoKSkgPT0gMCkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ2Fubm90IG1lcmdlIG5vbi1hZGphY2VudCByZWdpb25zIik7CisgICAgfQorICAgIHJldHVybiBtZXJnZShhLCBiKTsKKyAgfQorCisgIC8qKgorICAgKiBNZXJnZSB0d28gcmVnaW9ucyB3aGV0aGVyIHRoZXkgYXJlIGFkamFjZW50IG9yIG5vdC4KKyAgICogCisgICAqIEBwYXJhbSBhIHJlZ2lvbiBhCisgICAqIEBwYXJhbSBiIHJlZ2lvbiBiCisgICAqIEByZXR1cm4gbmV3IG1lcmdlZCByZWdpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIUmVnaW9uIG1lcmdlKEhSZWdpb24gYSwgSFJlZ2lvbiBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghYS5nZXRSZWdpb25JbmZvKCkuZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZUFzU3RyaW5nKCkuZXF1YWxzKAorICAgICAgICBiLmdldFJlZ2lvbkluZm8oKS5nZXRUYWJsZURlc2MoKS5nZXROYW1lQXNTdHJpbmcoKSkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUmVnaW9ucyBkbyBub3QgYmVsb25nIHRvIHRoZSBzYW1lIHRhYmxlIik7CisgICAgfQorCisgICAgRmlsZVN5c3RlbSBmcyA9IGEuZ2V0RmlsZXN5c3RlbSgpOworCisgICAgLy8gTWFrZSBzdXJlIGVhY2ggcmVnaW9uJ3MgY2FjaGUgaXMgZW1wdHkKKyAgICAKKyAgICBhLmZsdXNoY2FjaGUoKTsKKyAgICBiLmZsdXNoY2FjaGUoKTsKKyAgICAKKyAgICAvLyBDb21wYWN0IGVhY2ggcmVnaW9uIHNvIHdlIG9ubHkgaGF2ZSBvbmUgc3RvcmUgZmlsZSBwZXIgZmFtaWx5CisgICAgCisgICAgYS5jb21wYWN0U3RvcmVzKHRydWUpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJGaWxlcyBmb3IgcmVnaW9uOiAiICsgYSk7CisgICAgICBsaXN0UGF0aHMoZnMsIGEuZ2V0UmVnaW9uRGlyKCkpOworICAgIH0KKyAgICBiLmNvbXBhY3RTdG9yZXModHJ1ZSk7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoIkZpbGVzIGZvciByZWdpb246ICIgKyBiKTsKKyAgICAgIGxpc3RQYXRocyhmcywgYi5nZXRSZWdpb25EaXIoKSk7CisgICAgfQorICAgIAorICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mID0gYS5nZXRDb25mKCk7CisgICAgSFRhYmxlRGVzY3JpcHRvciB0YWJsZWRlc2MgPSBhLmdldFRhYmxlRGVzYygpOworICAgIEhMb2cgbG9nID0gYS5nZXRMb2coKTsKKyAgICBQYXRoIGJhc2VkaXIgPSBhLmdldEJhc2VEaXIoKTsKKyAgICAvLyBQcmVzdW1lIGJvdGggYXJlIG9mIHNhbWUgcmVnaW9uIHR5cGUgLS0gaS5lLiBib3RoIHVzZXIgb3IgY2F0YWxvZyAKKyAgICAvLyB0YWJsZSByZWdpb25zLiAgVGhpcyB3YXkgY2FuIHVzZSBjb21wYXJhdG9yLgorICAgIGZpbmFsIGJ5dGUgW10gc3RhcnRLZXkgPSBhLmNvbXBhcmF0b3IubWF0Y2hpbmdSb3dzKGEuZ2V0U3RhcnRLZXkoKSwgMCwKKyAgICAgICAgICBhLmdldFN0YXJ0S2V5KCkubGVuZ3RoLAorICAgICAgICBFTVBUWV9CWVRFX0FSUkFZLCAwLCBFTVBUWV9CWVRFX0FSUkFZLmxlbmd0aCkgfHwKKyAgICAgIGIuY29tcGFyYXRvci5tYXRjaGluZ1Jvd3MoYi5nZXRTdGFydEtleSgpLCAwLCBiLmdldFN0YXJ0S2V5KCkubGVuZ3RoLAorICAgICAgICBFTVBUWV9CWVRFX0FSUkFZLCAwLCBFTVBUWV9CWVRFX0FSUkFZLmxlbmd0aCk/CisgICAgICAgIEVNUFRZX0JZVEVfQVJSQVk6CisgICAgICAgICAgYS5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKGEuZ2V0U3RhcnRLZXkoKSwgMCwgYS5nZXRTdGFydEtleSgpLmxlbmd0aCwgCisgICAgICAgICAgYi5nZXRTdGFydEtleSgpLCAwLCBiLmdldFN0YXJ0S2V5KCkubGVuZ3RoKSA8PSAwPworICAgICAgICBhLmdldFN0YXJ0S2V5KCk6IGIuZ2V0U3RhcnRLZXkoKTsKKyAgICBmaW5hbCBieXRlIFtdIGVuZEtleSA9IGEuY29tcGFyYXRvci5tYXRjaGluZ1Jvd3MoYS5nZXRFbmRLZXkoKSwgMCwKKyAgICAgICAgYS5nZXRFbmRLZXkoKS5sZW5ndGgsIEVNUFRZX0JZVEVfQVJSQVksIDAsIEVNUFRZX0JZVEVfQVJSQVkubGVuZ3RoKSB8fAorICAgICAgYS5jb21wYXJhdG9yLm1hdGNoaW5nUm93cyhiLmdldEVuZEtleSgpLCAwLCBiLmdldEVuZEtleSgpLmxlbmd0aCwKKyAgICAgICAgRU1QVFlfQllURV9BUlJBWSwgMCwgRU1QVFlfQllURV9BUlJBWS5sZW5ndGgpPworICAgICAgICBFTVBUWV9CWVRFX0FSUkFZOgorICAgICAgICBhLmNvbXBhcmF0b3IuY29tcGFyZVJvd3MoYS5nZXRFbmRLZXkoKSwgMCwgYS5nZXRFbmRLZXkoKS5sZW5ndGgsCisgICAgICAgICAgICBiLmdldEVuZEtleSgpLCAwLCBiLmdldEVuZEtleSgpLmxlbmd0aCkgPD0gMD8KKyAgICAgICAgICAgICAgICBiLmdldEVuZEtleSgpOiBhLmdldEVuZEtleSgpOworCisgICAgSFJlZ2lvbkluZm8gbmV3UmVnaW9uSW5mbyA9IG5ldyBIUmVnaW9uSW5mbyh0YWJsZWRlc2MsIHN0YXJ0S2V5LCBlbmRLZXkpOworICAgIExPRy5pbmZvKCJDcmVhdGluZyBuZXcgcmVnaW9uICIgKyBuZXdSZWdpb25JbmZvLnRvU3RyaW5nKCkpOworICAgIGludCBlbmNvZGVkTmFtZSA9IG5ld1JlZ2lvbkluZm8uZ2V0RW5jb2RlZE5hbWUoKTsgCisgICAgUGF0aCBuZXdSZWdpb25EaXIgPSBIUmVnaW9uLmdldFJlZ2lvbkRpcihhLmdldEJhc2VEaXIoKSwgZW5jb2RlZE5hbWUpOworICAgIGlmKGZzLmV4aXN0cyhuZXdSZWdpb25EaXIpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbm5vdCBtZXJnZTsgdGFyZ2V0IGZpbGUgY29sbGlzaW9uIGF0ICIgKworICAgICAgICAgIG5ld1JlZ2lvbkRpcik7CisgICAgfQorICAgIGZzLm1rZGlycyhuZXdSZWdpb25EaXIpOworCisgICAgTE9HLmluZm8oInN0YXJ0aW5nIG1lcmdlIG9mIHJlZ2lvbnM6ICIgKyBhICsgIiBhbmQgIiArIGIgKworICAgICAgIiBpbnRvIG5ldyByZWdpb24gIiArIG5ld1JlZ2lvbkluZm8udG9TdHJpbmcoKSArCisgICAgICAgICIgd2l0aCBzdGFydCBrZXkgPCIgKyBCeXRlcy50b1N0cmluZyhzdGFydEtleSkgKyAiPiBhbmQgZW5kIGtleSA8IiArCisgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGVuZEtleSkgKyAiPiIpOworCisgICAgLy8gTW92ZSBIU3RvcmVGaWxlcyB1bmRlciBuZXcgcmVnaW9uIGRpcmVjdG9yeQorICAgIE1hcDxieXRlIFtdLCBMaXN0PFN0b3JlRmlsZT4+IGJ5RmFtaWx5ID0KKyAgICAgIG5ldyBUcmVlTWFwPGJ5dGUgW10sIExpc3Q8U3RvcmVGaWxlPj4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgYnlGYW1pbHkgPSBmaWxlc0J5RmFtaWx5KGJ5RmFtaWx5LCBhLmNsb3NlKCkpOworICAgIGJ5RmFtaWx5ID0gZmlsZXNCeUZhbWlseShieUZhbWlseSwgYi5jbG9zZSgpKTsKKyAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBMaXN0PFN0b3JlRmlsZT4+IGVzIDogYnlGYW1pbHkuZW50cnlTZXQoKSkgeworICAgICAgYnl0ZSBbXSBjb2xGYW1pbHkgPSBlcy5nZXRLZXkoKTsKKyAgICAgIG1ha2VDb2x1bW5GYW1pbHlEaXJzKGZzLCBiYXNlZGlyLCBuZXdSZWdpb25JbmZvLCBjb2xGYW1pbHkpOworICAgICAgLy8gQmVjYXVzZSB3ZSBjb21wYWN0ZWQgdGhlIHNvdXJjZSByZWdpb25zIHdlIHNob3VsZCBoYXZlIG5vIG1vcmUgdGhhbiB0d28KKyAgICAgIC8vIEhTdG9yZUZpbGVzIHBlciBmYW1pbHkgYW5kIHRoZXJlIHdpbGwgYmUgbm8gcmVmZXJlbmNlIHN0b3JlCisgICAgICBMaXN0PFN0b3JlRmlsZT4gc3JjRmlsZXMgPSBlcy5nZXRWYWx1ZSgpOworICAgICAgaWYgKHNyY0ZpbGVzLnNpemUoKSA9PSAyKSB7CisgICAgICAgIGxvbmcgc2VxQSA9IHNyY0ZpbGVzLmdldCgwKS5nZXRNYXhTZXF1ZW5jZUlkKCk7CisgICAgICAgIGxvbmcgc2VxQiA9IHNyY0ZpbGVzLmdldCgxKS5nZXRNYXhTZXF1ZW5jZUlkKCk7CisgICAgICAgIGlmIChzZXFBID09IHNlcUIpIHsKKyAgICAgICAgICAvLyBDYW4ndCBoYXZlIHNhbWUgc2VxdWVuY2VpZCBzaW5jZSBvbiBvcGVuIG9mIGEgc3RvcmUsIHRoaXMgaXMgd2hhdAorICAgICAgICAgIC8vIGRpc3Rpbmd1c2hlcyB0aGUgZmlsZXMgKHNlZSB0aGUgbWFwIG9mIHN0b3JlcyBob3cgaXRzIGtleWVkIGJ5CisgICAgICAgICAgLy8gc2VxdWVuY2VpZCkuCisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGaWxlcyBoYXZlIHNhbWUgc2VxdWVuY2VpZDogIiArIHNlcUEpOworICAgICAgICB9CisgICAgICB9CisgICAgICBmb3IgKFN0b3JlRmlsZSBoc2Y6IHNyY0ZpbGVzKSB7CisgICAgICAgIFN0b3JlRmlsZS5yZW5hbWUoZnMsIGhzZi5nZXRQYXRoKCksCisgICAgICAgICAgU3RvcmVGaWxlLmdldFVuaXF1ZUZpbGUoZnMsIFN0b3JlLmdldFN0b3JlSG9tZWRpcihiYXNlZGlyLAorICAgICAgICAgICAgbmV3UmVnaW9uSW5mby5nZXRFbmNvZGVkTmFtZSgpLCBjb2xGYW1pbHkpKSk7CisgICAgICB9CisgICAgfQorICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJGaWxlcyBmb3IgbmV3IHJlZ2lvbiIpOworICAgICAgbGlzdFBhdGhzKGZzLCBuZXdSZWdpb25EaXIpOworICAgIH0KKyAgICBIUmVnaW9uIGRzdFJlZ2lvbiA9IG5ldyBIUmVnaW9uKGJhc2VkaXIsIGxvZywgZnMsIGNvbmYsIG5ld1JlZ2lvbkluZm8sIG51bGwpOworICAgIGRzdFJlZ2lvbi5pbml0aWFsaXplKG51bGwsIG51bGwpOworICAgIGRzdFJlZ2lvbi5jb21wYWN0U3RvcmVzKCk7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoIkZpbGVzIGZvciBuZXcgcmVnaW9uIik7CisgICAgICBsaXN0UGF0aHMoZnMsIGRzdFJlZ2lvbi5nZXRSZWdpb25EaXIoKSk7CisgICAgfQorICAgIGRlbGV0ZVJlZ2lvbihmcywgYS5nZXRSZWdpb25EaXIoKSk7CisgICAgZGVsZXRlUmVnaW9uKGZzLCBiLmdldFJlZ2lvbkRpcigpKTsKKworICAgIExPRy5pbmZvKCJtZXJnZSBjb21wbGV0ZWQuIE5ldyByZWdpb24gaXMgIiArIGRzdFJlZ2lvbik7CisKKyAgICByZXR1cm4gZHN0UmVnaW9uOworICB9CisKKyAgLyoKKyAgICogRmlsbHMgYSBtYXAgd2l0aCBhIHZlY3RvciBvZiBzdG9yZSBmaWxlcyBrZXllZCBieSBjb2x1bW4gZmFtaWx5LiAKKyAgICogQHBhcmFtIGJ5RmFtaWx5IE1hcCB0byBmaWxsLgorICAgKiBAcGFyYW0gc3RvcmVGaWxlcyBTdG9yZSBmaWxlcyB0byBwcm9jZXNzLgorICAgKiBAcGFyYW0gZmFtaWx5CisgICAqIEByZXR1cm4gUmV0dXJucyA8Y29kZT5ieUZhbWlseTwvY29kZT4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIE1hcDxieXRlIFtdLCBMaXN0PFN0b3JlRmlsZT4+IGZpbGVzQnlGYW1pbHkoCisgICAgICBNYXA8Ynl0ZSBbXSwgTGlzdDxTdG9yZUZpbGU+PiBieUZhbWlseSwgTGlzdDxTdG9yZUZpbGU+IHN0b3JlRmlsZXMpIHsKKyAgICBmb3IgKFN0b3JlRmlsZSBzcmM6IHN0b3JlRmlsZXMpIHsKKyAgICAgIGJ5dGUgW10gZmFtaWx5ID0gc3JjLmdldEZhbWlseSgpOworICAgICAgTGlzdDxTdG9yZUZpbGU+IHYgPSBieUZhbWlseS5nZXQoZmFtaWx5KTsKKyAgICAgIGlmICh2ID09IG51bGwpIHsKKyAgICAgICAgdiA9IG5ldyBBcnJheUxpc3Q8U3RvcmVGaWxlPigpOworICAgICAgICBieUZhbWlseS5wdXQoZmFtaWx5LCB2KTsKKyAgICAgIH0KKyAgICAgIHYuYWRkKHNyYyk7CisgICAgfQorICAgIHJldHVybiBieUZhbWlseTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRydWUgaWYgbmVlZHMgYSBtb2pvciBjb21wYWN0aW9uLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgYm9vbGVhbiBpc01ham9yQ29tcGFjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZm9yIChTdG9yZSBzdG9yZTogdGhpcy5zdG9yZXMudmFsdWVzKCkpIHsKKyAgICAgIGlmIChzdG9yZS5pc01ham9yQ29tcGFjdGlvbigpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKgorICAgKiBMaXN0IHRoZSBmaWxlcyB1bmRlciB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeQorICAgKiAKKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBkaXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsaXN0UGF0aHMoRmlsZVN5c3RlbSBmcywgUGF0aCBkaXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBGaWxlU3RhdHVzW10gc3RhdHMgPSBmcy5saXN0U3RhdHVzKGRpcik7CisgICAgICBpZiAoc3RhdHMgPT0gbnVsbCB8fCBzdGF0cy5sZW5ndGggPT0gMCkgeworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIFN0cmluZyBwYXRoID0gc3RhdHNbaV0uZ2V0UGF0aCgpLnRvU3RyaW5nKCk7CisgICAgICAgIGlmIChzdGF0c1tpXS5pc0RpcigpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJkICIgKyBwYXRoKTsKKyAgICAgICAgICBsaXN0UGF0aHMoZnMsIHN0YXRzW2ldLmdldFBhdGgoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJmICIgKyBwYXRoICsgIiBzaXplPSIgKyBzdGF0c1tpXS5nZXRMZW4oKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwdWJsaWMgbG9uZyBpbmNyZW1lbnRDb2x1bW5WYWx1ZShieXRlW10gcm93LCBieXRlW10gY29sdW1uLCBsb25nIGFtb3VudCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja1Jvdyhyb3cpOworICAgIGNoZWNrQ29sdW1uKGNvbHVtbik7CisgICAgCisgICAgSW50ZWdlciBsaWQgPSBvYnRhaW5Sb3dMb2NrKHJvdyk7CisgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgS2V5VmFsdWUga3YgPSBuZXcgS2V5VmFsdWUocm93LCBjb2x1bW4pOworICAgICAgbG9uZyB0cyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgYnl0ZSBbXSB2YWx1ZSA9IG51bGw7CisKKyAgICAgIFN0b3JlIHN0b3JlID0gZ2V0U3RvcmUoY29sdW1uKTsKKworICAgICAgTGlzdDxLZXlWYWx1ZT4gYzsKKyAgICAgIC8vIFRyeSB0aGUgbWVtY2FjaGUgZmlyc3QuCisgICAgICBzdG9yZS5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgICAgdHJ5IHsKKyAgICAgICAgYyA9IHN0b3JlLm1lbWNhY2hlLmdldChrdiwgMSk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzdG9yZS5sb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgICB9CisgICAgICAvLyBQaWNrIHRoZSBsYXRlc3QgdmFsdWUgb3V0IG9mIExpc3Q8Q2VsbD4gYzoKKyAgICAgIGlmIChjLnNpemUoKSA+PSAxKSB7CisgICAgICAgIC8vIFVzZSB0aGUgbWVtY2FjaGUgdGltZXN0YW1wIHZhbHVlLgorICAgICAgICBMT0cuZGVidWcoIk92ZXJ3cml0aW5nIHRoZSBtZW1jYWNoZSB2YWx1ZSBmb3IgIiArIEJ5dGVzLnRvU3RyaW5nKHJvdykgKworICAgICAgICAgICIvIiArIEJ5dGVzLnRvU3RyaW5nKGNvbHVtbikpOworICAgICAgICB0cyA9IGMuZ2V0KDApLmdldFRpbWVzdGFtcCgpOworICAgICAgICB2YWx1ZSA9IGMuZ2V0KDApLmdldFZhbHVlKCk7CisgICAgICB9CisKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIC8vIENoZWNrIHRoZSBzdG9yZSAoaW5jbHVkaW5nIGRpc2spIGZvciB0aGUgcHJldmlvdXMgdmFsdWUuCisgICAgICAgIGMgPSBzdG9yZS5nZXQoa3YsIDEpOworICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuc2l6ZSgpID09IDEpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIlVzaW5nIEhGaWxlIHByZXZpb3VzIHZhbHVlIGZvciAiICsgQnl0ZXMudG9TdHJpbmcocm93KSArCisgICAgICAgICAgICAiLyIgKyBCeXRlcy50b1N0cmluZyhjb2x1bW4pKTsKKyAgICAgICAgICB2YWx1ZSA9IGMuZ2V0KDApLmdldFZhbHVlKCk7CisgICAgICAgIH0gZWxzZSBpZiAoYyAhPSBudWxsICYmIGMuc2l6ZSgpID4gMSkgeworICAgICAgICAgIHRocm93IG5ldyBEb05vdFJldHJ5SU9FeGNlcHRpb24oIm1vcmUgdGhhbiAxIHZhbHVlIHJldHVybmVkIGluICIgKworICAgICAgICAgICAgImluY3JlbWVudENvbHVtblZhbHVlIGZyb20gU3RvcmUiKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgCisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAvLyBEb2Vzbid0IGV4aXN0CisgICAgICAgIExPRy5kZWJ1ZygiQ3JlYXRpbmcgbmV3IGNvdW50ZXIgdmFsdWUgZm9yICIgKyBCeXRlcy50b1N0cmluZyhyb3cpICsKKyAgICAgICAgICAiLyIrIEJ5dGVzLnRvU3RyaW5nKGNvbHVtbikpOworICAgICAgICB2YWx1ZSA9IEJ5dGVzLnRvQnl0ZXMoYW1vdW50KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChhbW91bnQgPT0gMCkgcmV0dXJuIEJ5dGVzLnRvTG9uZyh2YWx1ZSk7CisgICAgICAgIHZhbHVlID0gQnl0ZXMuaW5jcmVtZW50Qnl0ZXModmFsdWUsIGFtb3VudCk7CisgICAgICB9CisKKyAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUocm93LCB0cyk7CisgICAgICBiLnB1dChjb2x1bW4sIHZhbHVlKTsKKyAgICAgIGJhdGNoVXBkYXRlKGIsIGxpZCwgdHJ1ZSk7CisgICAgICByZXR1cm4gQnl0ZXMudG9Mb25nKHZhbHVlKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgc3BsaXRzQW5kQ2xvc2VzTG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgICAgcmVsZWFzZVJvd0xvY2sobGlkKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9IUmVnaW9uU2VydmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvSFJlZ2lvblNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkYWNlODgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvSFJlZ2lvblNlcnZlci5qYXZhCkBAIC0wLDAgKzEsMjQ1NiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLlRocmVhZC5VbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuTWFuYWdlbWVudEZhY3Rvcnk7CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuTWVtb3J5VXNhZ2U7CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuUnVudGltZU1YQmVhbjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5GaWVsZDsKK2ltcG9ydCBqYXZhLm5ldC5CaW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRTb2NrZXRBZGRyZXNzOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5hdmlnYWJsZVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljQm9vbGVhbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRSZWFkV3JpdGVMb2NrOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5DaG9yZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5ITXNnOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25Mb2NhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVySW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyTG9hZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkxlYXNlTGlzdGVuZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTGVhc2VzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkxvY2FsSEJhc2VDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVnaW9uSGlzdG9yaWFuOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVW5rbm93blJvd0xvY2tFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVW5rbm93blNjYW5uZXJFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZy5UeXBlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkxlYXNlcy5MZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2VydmVyQ29ubmVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2VydmVyQ29ubmVjdGlvbk1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlTWFwV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IQmFzZVJQQzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSEJhc2VSUENFcnJvckhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLkhCYXNlUlBDUHJvdG9jb2xWZXJzaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IQmFzZVNlcnZlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSE1hc3RlclJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIubWV0cmljcy5SZWdpb25TZXJ2ZXJNZXRyaWNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5GU1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuSW5mb1NlcnZlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlNsZWVwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5UaHJlYWRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnpvb2tlZXBlci5ab29LZWVwZXJXcmFwcGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLk1hcFdyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm5ldC5ETlM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Qcm9ncmVzc2FibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5TdHJpbmdVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVkRXZlbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVyLkV2ZW50LkV2ZW50VHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVyLkV2ZW50LktlZXBlclN0YXRlOworCisvKioKKyAqIEhSZWdpb25TZXJ2ZXIgbWFrZXMgYSBzZXQgb2YgSFJlZ2lvbnMgYXZhaWxhYmxlIHRvIGNsaWVudHMuICBJdCBjaGVja3MgaW4gd2l0aAorICogdGhlIEhNYXN0ZXIuIFRoZXJlIGFyZSBtYW55IEhSZWdpb25TZXJ2ZXJzIGluIGEgc2luZ2xlIEhCYXNlIGRlcGxveW1lbnQuCisgKi8KK3B1YmxpYyBjbGFzcyBIUmVnaW9uU2VydmVyIGltcGxlbWVudHMgSENvbnN0YW50cywgSFJlZ2lvbkludGVyZmFjZSwKKyAgICBIQmFzZVJQQ0Vycm9ySGFuZGxlciwgUnVubmFibGUsIFdhdGNoZXIgeworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhSZWdpb25TZXJ2ZXIuY2xhc3MpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBITXNnIFJFUE9SVF9FWElUSU5HID0gbmV3IEhNc2coVHlwZS5NU0dfUkVQT1JUX0VYSVRJTkcpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBITXNnIFJFUE9SVF9RVUlFU0NFRCA9IG5ldyBITXNnKFR5cGUuTVNHX1JFUE9SVF9RVUlFU0NFRCk7CisgIAorICAvLyBTZXQgd2hlbiBhIHJlcG9ydCB0byB0aGUgbWFzdGVyIGNvbWVzIGJhY2sgd2l0aCBhIG1lc3NhZ2UgYXNraW5nIHVzIHRvCisgIC8vIHNodXRkb3duLiAgQWxzbyBzZXQgYnkgY2FsbCB0byBzdG9wIHdoZW4gZGVidWdnaW5nIG9yIHJ1bm5pbmcgdW5pdCB0ZXN0cworICAvLyBvZiBIUmVnaW9uU2VydmVyIGluIGlzb2xhdGlvbi4gV2UgdXNlIEF0b21pY0Jvb2xlYW4gcmF0aGVyIHRoYW4KKyAgLy8gcGxhaW4gYm9vbGVhbiBzbyB3ZSBjYW4gcGFzcyBhIHJlZmVyZW5jZSB0byBDaG9yZSB0aHJlYWRzLiAgT3RoZXJ3aXNlLAorICAvLyBDaG9yZSB0aHJlYWRzIG5lZWQgdG8ga25vdyBhYm91dCB0aGUgaG9zdGluZyBjbGFzcy4KKyAgcHJvdGVjdGVkIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcFJlcXVlc3RlZCA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKyAgCisgIHByb3RlY3RlZCBmaW5hbCBBdG9taWNCb29sZWFuIHF1aWVzY2VkID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworCisgIHByb3RlY3RlZCBmaW5hbCBBdG9taWNCb29sZWFuIHNhZmVNb2RlID0gbmV3IEF0b21pY0Jvb2xlYW4odHJ1ZSk7CisKKyAgLy8gR28gZG93biBoYXJkLiAgVXNlZCBpZiBmaWxlIHN5c3RlbSBiZWNvbWVzIHVuYXZhaWxhYmxlIGFuZCBhbHNvIGluCisgIC8vIGRlYnVnZ2luZyBhbmQgdW5pdCB0ZXN0cy4KKyAgcHJvdGVjdGVkIHZvbGF0aWxlIGJvb2xlYW4gYWJvcnRSZXF1ZXN0ZWQ7CisgIAorICAvLyBJZiBmYWxzZSwgdGhlIGZpbGUgc3lzdGVtIGhhcyBiZWNvbWUgdW5hdmFpbGFibGUKKyAgcHJvdGVjdGVkIHZvbGF0aWxlIGJvb2xlYW4gZnNPazsKKyAgCisgIHByb3RlY3RlZCBIU2VydmVySW5mbyBzZXJ2ZXJJbmZvOworICBwcm90ZWN0ZWQgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisKKyAgcHJpdmF0ZSBmaW5hbCBTZXJ2ZXJDb25uZWN0aW9uIGNvbm5lY3Rpb247CisgIHByb3RlY3RlZCBmaW5hbCBBdG9taWNCb29sZWFuIGhhdmVSb290UmVnaW9uID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworICBwcml2YXRlIEZpbGVTeXN0ZW0gZnM7CisgIHByaXZhdGUgUGF0aCByb290RGlyOworICBwcml2YXRlIGZpbmFsIFJhbmRvbSByYW5kID0gbmV3IFJhbmRvbSgpOworCisgIC8vIEtleSBpcyBCeXRlcy5oYXNoQ29kZSBvZiByZWdpb24gbmFtZSBieXRlIGFycmF5IGFuZCB0aGUgdmFsdWUgaXMgSFJlZ2lvbgorICAvLyBpbiBib3RoIG9mIHRoZSBtYXBzIGJlbG93LiAgVXNlIEJ5dGVzLm1hcEtleShieXRlIFtdKSBnZW5lcmF0aW5nIGtleSBmb3IKKyAgLy8gYmVsb3cgbWFwcy4KKyAgcHJvdGVjdGVkIGZpbmFsIE1hcDxJbnRlZ2VyLCBIUmVnaW9uPiBvbmxpbmVSZWdpb25zID0KKyAgICBuZXcgQ29uY3VycmVudEhhc2hNYXA8SW50ZWdlciwgSFJlZ2lvbj4oKTsKKworICBwcm90ZWN0ZWQgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jayBsb2NrID0gbmV3IFJlZW50cmFudFJlYWRXcml0ZUxvY2soKTsKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PEhNc2c+IG91dGJvdW5kTXNncyA9CisgICAgQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTGlzdChuZXcgQXJyYXlMaXN0PEhNc2c+KCkpOworCisgIGZpbmFsIGludCBudW1SZXRyaWVzOworICBwcm90ZWN0ZWQgZmluYWwgaW50IHRocmVhZFdha2VGcmVxdWVuY3k7CisgIHByaXZhdGUgZmluYWwgaW50IG1zZ0ludGVydmFsOworICBwcml2YXRlIGZpbmFsIGludCBzZXJ2ZXJMZWFzZVRpbWVvdXQ7CisKKyAgcHJvdGVjdGVkIGZpbmFsIGludCBudW1SZWdpb25zVG9SZXBvcnQ7CisgIAorICAvLyBSZW1vdGUgSE1hc3RlcgorICBwcml2YXRlIEhNYXN0ZXJSZWdpb25JbnRlcmZhY2UgaGJhc2VNYXN0ZXI7CisKKyAgLy8gU2VydmVyIHRvIGhhbmRsZSBjbGllbnQgcmVxdWVzdHMuICBEZWZhdWx0IGFjY2VzcyBzbyBjYW4gYmUgYWNjZXNzZWQgYnkKKyAgLy8gdW5pdCB0ZXN0cy4KKyAgSEJhc2VTZXJ2ZXIgc2VydmVyOworICAKKyAgLy8gTGVhc2VzCisgIHByaXZhdGUgTGVhc2VzIGxlYXNlczsKKyAgCisgIC8vIFJlcXVlc3QgY291bnRlcgorICBwcml2YXRlIHZvbGF0aWxlIEF0b21pY0ludGVnZXIgcmVxdWVzdENvdW50ID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKworICAvLyBJbmZvIHNlcnZlci4gIERlZmF1bHQgYWNjZXNzIHNvIGNhbiBiZSB1c2VkIGJ5IHVuaXQgdGVzdHMuICBSRUdJT05TRVJWRVIKKyAgLy8gaXMgbmFtZSBvZiB0aGUgd2ViYXBwIGFuZCB0aGUgYXR0cmlidXRlIG5hbWUgdXNlZCBzdHVmZmluZyB0aGlzIGluc3RhbmNlCisgIC8vIGludG8gd2ViIGNvbnRleHQuCisgIEluZm9TZXJ2ZXIgaW5mb1NlcnZlcjsKKyAgCisgIC8qKiByZWdpb24gc2VydmVyIHByb2Nlc3MgbmFtZSAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBSRUdJT05TRVJWRVIgPSAicmVnaW9uc2VydmVyIjsKKyAgCisgIC8qCisgICAqIFNwYWNlIGlzIHJlc2VydmVkIGluIEhSUyBjb25zdHJ1Y3RvciBhbmQgdGhlbiByZWxlYXNlZCB3aGVuIGFib3J0aW5nCisgICAqIHRvIHJlY292ZXIgZnJvbSBhbiBPT01FLiBTZWUgSEJBU0UtNzA2LiAgVE9ETzogTWFrZSB0aGlzIHBlcmNlbnRhZ2Ugb2YgdGhlCisgICAqIGhlYXAgb3IgYSBtaW5pbXVtLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBMaW5rZWRMaXN0PGJ5dGVbXT4gcmVzZXJ2ZWRTcGFjZSA9IG5ldyBMaW5rZWRMaXN0PGJ5dGUgW10+KCk7CisgIAorICBwcml2YXRlIFJlZ2lvblNlcnZlck1ldHJpY3MgbWV0cmljczsKKworICAvLyBDb21wYWN0aW9ucworICBDb21wYWN0U3BsaXRUaHJlYWQgY29tcGFjdFNwbGl0VGhyZWFkOworCisgIC8vIENhY2hlIGZsdXNoaW5nICAKKyAgTWVtY2FjaGVGbHVzaGVyIGNhY2hlRmx1c2hlcjsKKyAgCisgIC8qIENoZWNrIGZvciBtYWpvciBjb21wYWN0aW9ucy4KKyAgICovCisgIENob3JlIG1ham9yQ29tcGFjdGlvbkNoZWNrZXI7CisKKyAgLy8gSExvZyBhbmQgSExvZyByb2xsZXIuICBsb2cgaXMgcHJvdGVjdGVkIHJhdGhlciB0aGFuIHByaXZhdGUgdG8gYXZvaWQKKyAgLy8gZWNsaXBzZSB3YXJuaW5nIHdoZW4gYWNjZXNzZWQgYnkgaW5uZXIgY2xhc3NlcworICBwcm90ZWN0ZWQgdm9sYXRpbGUgSExvZyBsb2c7CisgIExvZ1JvbGxlciBsb2dSb2xsZXI7CisgIExvZ0ZsdXNoZXIgbG9nRmx1c2hlcjsKKyAgCisgIC8vIGxpbWl0IGNvbXBhY3Rpb25zIHdoaWxlIHN0YXJ0aW5nIHVwCisgIENvbXBhY3Rpb25MaW1pdFRocmVhZCBjb21wYWN0aW9uTGltaXRUaHJlYWQ7CisKKyAgLy8gZmxhZyBzZXQgYWZ0ZXIgd2UncmUgZG9uZSBzZXR0aW5nIHVwIHNlcnZlciB0aHJlYWRzICh1c2VkIGZvciB0ZXN0aW5nKQorICBwcm90ZWN0ZWQgdm9sYXRpbGUgYm9vbGVhbiBpc09ubGluZTsKKworICBmaW5hbCBNYXA8U3RyaW5nLCBJbnRlcm5hbFNjYW5uZXI+IHNjYW5uZXJzID0KKyAgICBuZXcgQ29uY3VycmVudEhhc2hNYXA8U3RyaW5nLCBJbnRlcm5hbFNjYW5uZXI+KCk7CisKKyAgcHJpdmF0ZSBab29LZWVwZXJXcmFwcGVyIHpvb0tlZXBlcldyYXBwZXI7CisKKyAgLy8gQSBzbGVlcGVyIHRoYXQgc2xlZXBzIGZvciBtc2dJbnRlcnZhbC4KKyAgcHJpdmF0ZSBmaW5hbCBTbGVlcGVyIHNsZWVwZXI7CisKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIHJwY1RpbWVvdXQ7CisKKyAgLy8gQWRkcmVzcyBwYXNzZWQgaW4gdG8gY29uc3RydWN0b3IuCisgIHByaXZhdGUgZmluYWwgSFNlcnZlckFkZHJlc3MgYWRkcmVzczsKKworICAvLyBUaGUgbWFpbiByZWdpb24gc2VydmVyIHRocmVhZC4KKyAgcHJpdmF0ZSBUaHJlYWQgcmVnaW9uU2VydmVyVGhyZWFkOworCisgIC8vIFJ1biBIREZTIHNodXRkb3duIHRocmVhZCBvbiBleGl0IGlmIHRoaXMgaXMgc2V0LiBXZSBjbGVhciB0aGlzIG91dCB3aGVuCisgIC8vIGRvaW5nIGEgcmVzdGFydCgpIHRvIHByZXZlbnQgY2xvc2luZyBvZiBIREZTLgorICBwcml2YXRlIGZpbmFsIEF0b21pY0Jvb2xlYW4gc2h1dGRvd25IREZTID0gbmV3IEF0b21pY0Jvb2xlYW4odHJ1ZSk7CisKKyAgLyoqCisgICAqIFN0YXJ0cyBhIEhSZWdpb25TZXJ2ZXIgYXQgdGhlIGRlZmF1bHQgbG9jYXRpb24KKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25TZXJ2ZXIoSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcyhuZXcgSFNlcnZlckFkZHJlc3MoY29uZi5nZXQoUkVHSU9OU0VSVkVSX0FERFJFU1MsCisgICAgICAgIERFRkFVTFRfUkVHSU9OU0VSVkVSX0FERFJFU1MpKSwgY29uZik7CisgIH0KKyAgCisgIC8qKgorICAgKiBTdGFydHMgYSBIUmVnaW9uU2VydmVyIGF0IHRoZSBzcGVjaWZpZWQgbG9jYXRpb24KKyAgICogQHBhcmFtIGFkZHJlc3MKKyAgICogQHBhcmFtIGNvbmYKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb25TZXJ2ZXIoSFNlcnZlckFkZHJlc3MgYWRkcmVzcywgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5hZGRyZXNzID0gYWRkcmVzczsKKyAgICB0aGlzLmFib3J0UmVxdWVzdGVkID0gZmFsc2U7CisgICAgdGhpcy5mc09rID0gdHJ1ZTsKKyAgICB0aGlzLmNvbmYgPSBjb25mOworICAgIHRoaXMuY29ubmVjdGlvbiA9IFNlcnZlckNvbm5lY3Rpb25NYW5hZ2VyLmdldENvbm5lY3Rpb24oY29uZik7CisKKyAgICB0aGlzLmlzT25saW5lID0gZmFsc2U7CisgICAgCisgICAgLy8gQ29uZmlnJ2VkIHBhcmFtcworICAgIHRoaXMubnVtUmV0cmllcyA9ICBjb25mLmdldEludCgiaGJhc2UuY2xpZW50LnJldHJpZXMubnVtYmVyIiwgMik7CisgICAgdGhpcy50aHJlYWRXYWtlRnJlcXVlbmN5ID0gY29uZi5nZXRJbnQoVEhSRUFEX1dBS0VfRlJFUVVFTkNZLCAxMCAqIDEwMDApOworICAgIHRoaXMubXNnSW50ZXJ2YWwgPSBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm1zZ2ludGVydmFsIiwgMyAqIDEwMDApOworICAgIHRoaXMuc2VydmVyTGVhc2VUaW1lb3V0ID0KKyAgICAgIGNvbmYuZ2V0SW50KCJoYmFzZS5tYXN0ZXIubGVhc2UucGVyaW9kIiwgMTIwICogMTAwMCk7CisKKyAgICBzbGVlcGVyID0gbmV3IFNsZWVwZXIodGhpcy5tc2dJbnRlcnZhbCwgdGhpcy5zdG9wUmVxdWVzdGVkKTsKKworICAgIC8vIFRhc2sgdGhyZWFkIHRvIHByb2Nlc3MgcmVxdWVzdHMgZnJvbSBNYXN0ZXIKKyAgICB0aGlzLndvcmtlciA9IG5ldyBXb3JrZXIoKTsKKworICAgIHRoaXMubnVtUmVnaW9uc1RvUmVwb3J0ID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm51bXJlZ2lvbnN0b3JlcG9ydCIsIDEwKTsgICAgICAKKworICAgIHRoaXMucnBjVGltZW91dCA9IGNvbmYuZ2V0TG9uZygiaGJhc2UucmVnaW9uc2VydmVyLmxlYXNlLnBlcmlvZCIsIDYwMDAwKTsKKworICAgIHJlaW5pdGlhbGl6ZSgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYWxsIG9mIHRoZSBzdGF0ZSB0aGF0IG5lZWRzIHRvIGJlIHJlY29uc3RydWN0ZWQgaW4gY2FzZSB3ZSBhcmUKKyAgICogZG9pbmcgYSByZXN0YXJ0LiBUaGlzIGlzIHNoYXJlZCBiZXR3ZWVuIHRoZSBjb25zdHJ1Y3RvciBhbmQgcmVzdGFydCgpLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgcmVpbml0aWFsaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhYm9ydFJlcXVlc3RlZCA9IGZhbHNlOworICAgIHN0b3BSZXF1ZXN0ZWQuc2V0KGZhbHNlKTsKKyAgICBzaHV0ZG93bkhERlMuc2V0KHRydWUpOworCisgICAgLy8gU2VydmVyIHRvIGhhbmRsZSBjbGllbnQgcmVxdWVzdHMKKyAgICB0aGlzLnNlcnZlciA9IEhCYXNlUlBDLmdldFNlcnZlcih0aGlzLCBhZGRyZXNzLmdldEJpbmRBZGRyZXNzKCksIAorICAgICAgYWRkcmVzcy5nZXRQb3J0KCksIGNvbmYuZ2V0SW50KCJoYmFzZS5yZWdpb25zZXJ2ZXIuaGFuZGxlci5jb3VudCIsIDEwKSwKKyAgICAgIGZhbHNlLCBjb25mKTsKKyAgICB0aGlzLnNlcnZlci5zZXRFcnJvckhhbmRsZXIodGhpcyk7CisgICAgU3RyaW5nIG1hY2hpbmVOYW1lID0gRE5TLmdldERlZmF1bHRIb3N0KAorICAgICAgICBjb25mLmdldCgiaGJhc2UucmVnaW9uc2VydmVyLmRucy5pbnRlcmZhY2UiLCJkZWZhdWx0IiksCisgICAgICAgIGNvbmYuZ2V0KCJoYmFzZS5yZWdpb25zZXJ2ZXIuZG5zLm5hbWVzZXJ2ZXIiLCJkZWZhdWx0IikpOworICAgIC8vIEFkZHJlc3MgaXMgZ2l2aW4gYSBkZWZhdWx0IElQIGZvciB0aGUgbW9tZW50LiBXaWxsIGJlIGNoYW5nZWQgYWZ0ZXIKKyAgICAvLyBjYWxsaW5nIHRoZSBtYXN0ZXIuCisgICAgdGhpcy5zZXJ2ZXJJbmZvID0gbmV3IEhTZXJ2ZXJJbmZvKG5ldyBIU2VydmVyQWRkcmVzcygKKyAgICAgIG5ldyBJbmV0U29ja2V0QWRkcmVzcyhhZGRyZXNzLmdldEJpbmRBZGRyZXNzKCksCisgICAgICB0aGlzLnNlcnZlci5nZXRMaXN0ZW5lckFkZHJlc3MoKS5nZXRQb3J0KCkpKSwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCksCisgICAgICB0aGlzLmNvbmYuZ2V0SW50KCJoYmFzZS5yZWdpb25zZXJ2ZXIuaW5mby5wb3J0IiwgNjAwMzApLCBtYWNoaW5lTmFtZSk7CisgICAgaWYgKHRoaXMuc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJTZXJ2ZXIgYWRkcmVzcyBjYW5ub3QgYmUgbnVsbDsgIiArCisgICAgICAgICJoYmFzZS05NTggZGVidWdnaW5nIik7CisgICAgfQorCisgICAgcmVpbml0aWFsaXplVGhyZWFkcygpOworCisgICAgcmVpbml0aWFsaXplWm9vS2VlcGVyKCk7CisKKyAgICBpbnQgbmJCbG9ja3MgPSBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm5icmVzZXJ2YXRpb25ibG9ja3MiLCA0KTsKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgbmJCbG9ja3M7IGkrKykgIHsKKyAgICAgIHJlc2VydmVkU3BhY2UuYWRkKG5ldyBieXRlW0RFRkFVTFRfU0laRV9SRVNFUlZBVElPTl9CTE9DS10pOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWluaXRpYWxpemVab29LZWVwZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHpvb0tlZXBlcldyYXBwZXIgPSBuZXcgWm9vS2VlcGVyV3JhcHBlcihjb25mKTsKKyAgICB3YXRjaE1hc3RlckFkZHJlc3MoKTsKKworICAgIGJvb2xlYW4gc3RhcnRDb2RlT2sgPSBmYWxzZTsgCisgICAgd2hpbGUoIXN0YXJ0Q29kZU9rKSB7CisgICAgICBzZXJ2ZXJJbmZvLnNldFN0YXJ0Q29kZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICBzdGFydENvZGVPayA9IHpvb0tlZXBlcldyYXBwZXIud3JpdGVSU0xvY2F0aW9uKHNlcnZlckluZm8pOworICAgICAgaWYoIXN0YXJ0Q29kZU9rKSB7CisgICAgICAgIExPRy5kZWJ1ZygiU3RhcnQgY29kZSBhbHJlYWR5IHRha2VuLCB0cnlpbmcgYW5vdGhlciBvbmUiKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgcmVpbml0aWFsaXplVGhyZWFkcygpIHsKKyAgICB0aGlzLndvcmtlclRocmVhZCA9IG5ldyBUaHJlYWQod29ya2VyKTsKKworICAgIC8vIENhY2hlIGZsdXNoaW5nIHRocmVhZC4KKyAgICB0aGlzLmNhY2hlRmx1c2hlciA9IG5ldyBNZW1jYWNoZUZsdXNoZXIoY29uZiwgdGhpcyk7CisgICAgCisgICAgLy8gQ29tcGFjdGlvbiB0aHJlYWQKKyAgICB0aGlzLmNvbXBhY3RTcGxpdFRocmVhZCA9IG5ldyBDb21wYWN0U3BsaXRUaHJlYWQodGhpcyk7CisgICAgCisgICAgLy8gTG9nIHJvbGxpbmcgdGhyZWFkCisgICAgdGhpcy5sb2dSb2xsZXIgPSBuZXcgTG9nUm9sbGVyKHRoaXMpOworICAgIAorICAgIC8vIExvZyBmbHVzaGluZyB0aHJlYWQKKyAgICB0aGlzLmxvZ0ZsdXNoZXIgPQorICAgICAgbmV3IExvZ0ZsdXNoZXIodGhpcy50aHJlYWRXYWtlRnJlcXVlbmN5LCB0aGlzLnN0b3BSZXF1ZXN0ZWQpOworICAgIAorICAgIC8vIEJhY2tncm91bmQgdGhyZWFkIHRvIGNoZWNrIGZvciBtYWpvciBjb21wYWN0aW9uczsgbmVlZGVkIGlmIHJlZ2lvbgorICAgIC8vIGhhcyBub3QgZ290dGVuIHVwZGF0ZXMgaW4gYSB3aGlsZS4gIE1ha2UgaXQgcnVuIGF0IGEgbGVzc2VyIGZyZXF1ZW5jeS4KKyAgICBpbnQgbXVsdGlwbGllciA9IHRoaXMuY29uZi5nZXRJbnQoVEhSRUFEX1dBS0VfRlJFUVVFTkNZICsKKyAgICAgICAgIi5tdWx0aXBsaWVyIiwgMTAwMCk7CisgICAgdGhpcy5tYWpvckNvbXBhY3Rpb25DaGVja2VyID0gbmV3IE1ham9yQ29tcGFjdGlvbkNoZWNrZXIodGhpcywKKyAgICAgIHRoaXMudGhyZWFkV2FrZUZyZXF1ZW5jeSAqIG11bHRpcGxpZXIsICB0aGlzLnN0b3BSZXF1ZXN0ZWQpOworCisgICAgdGhpcy5sZWFzZXMgPSBuZXcgTGVhc2VzKAorICAgICAgICBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmxlYXNlLnBlcmlvZCIsIDYwICogMTAwMCksCisgICAgICAgIHRoaXMudGhyZWFkV2FrZUZyZXF1ZW5jeSk7CisgIH0KKworICAvKioKKyAgICogV2UgcmVnaXN0ZXIgb3Vyc2VsdmVzIGFzIGEgd2F0Y2hlciBvbiB0aGUgbWFzdGVyIGFkZHJlc3MgWk5vZGUuIFRoaXMgaXMKKyAgICogY2FsbGVkIGJ5IFpvb0tlZXBlciB3aGVuIHdlIGdldCBhbiBldmVudCBvbiB0aGF0IFpOb2RlLiBXaGVuIHRoaXMgbWV0aG9kCisgICAqIGlzIGNhbGxlZCBpdCBtZWFucyBlaXRoZXIgb3VyIG1hc3RlciBoYXMgZGllZCwgb3IgYSBuZXcgb25lIGhhcyBjb21lIHVwLgorICAgKiBFaXRoZXIgd2F5IHdlIG5lZWQgdG8gdXBkYXRlIG91ciBrbm93bGVkZ2Ugb2YgdGhlIG1hc3Rlci4KKyAgICogQHBhcmFtIGV2ZW50IFdhdGNoZWRFdmVudCBmcm9tIFpvb0tlZXBlci4KKyAgICovCisgIHB1YmxpYyB2b2lkIHByb2Nlc3MoV2F0Y2hlZEV2ZW50IGV2ZW50KSB7CisgICAgRXZlbnRUeXBlIHR5cGUgPSBldmVudC5nZXRUeXBlKCk7CisgICAgS2VlcGVyU3RhdGUgc3RhdGUgPSBldmVudC5nZXRTdGF0ZSgpOworICAgIExPRy5pbmZvKCJHb3QgWm9vS2VlcGVyIGV2ZW50LCBzdGF0ZTogIiArIHN0YXRlICsgIiwgdHlwZTogIiArCisgICAgICAgICAgICAgIHR5cGUgKyAiLCBwYXRoOiAiICsgZXZlbnQuZ2V0UGF0aCgpKTsKKworICAgIC8vIElnbm9yZSBldmVudHMgaWYgd2UncmUgc2h1dHRpbmcgZG93bi4KKyAgICBpZiAoc3RvcFJlcXVlc3RlZC5nZXQoKSkgeworICAgICAgTE9HLmRlYnVnKCJJZ25vcmluZyBab29LZWVwZXIgZXZlbnQgd2hpbGUgc2h1dHRpbmcgZG93biIpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChzdGF0ZSA9PSBLZWVwZXJTdGF0ZS5FeHBpcmVkKSB7CisgICAgICBMT0cuZXJyb3IoIlpvb0tlZXBlciBzZXNzaW9uIGV4cGlyZWQiKTsKKyAgICAgIHJlc3RhcnQoKTsKKyAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRXZlbnRUeXBlLk5vZGVDcmVhdGVkKSB7CisgICAgICBnZXRNYXN0ZXIoKTsKKworICAgICAgLy8gWm9vS2VlcGVyIHdhdGNoZXMgYXJlIG9uZSB0aW1lIG9ubHksIHNvIHdlIG5lZWQgdG8gcmUtcmVnaXN0ZXIgb3VyIHdhdGNoLgorICAgICAgd2F0Y2hNYXN0ZXJBZGRyZXNzKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdhdGNoTWFzdGVyQWRkcmVzcygpIHsKKyAgICB3aGlsZSAoIXN0b3BSZXF1ZXN0ZWQuZ2V0KCkgJiYgIXpvb0tlZXBlcldyYXBwZXIud2F0Y2hNYXN0ZXJBZGRyZXNzKHRoaXMpKSB7CisgICAgICBMT0cud2FybigiVW5hYmxlIHRvIHNldCB3YXRjaGVyIG9uIFpvb0tlZXBlciBtYXN0ZXIgYWRkcmVzcy4gUmV0cnlpbmcuIik7CisgICAgICBzbGVlcGVyLnNsZWVwKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlc3RhcnQoKSB7CisgICAgTE9HLmluZm8oIlJlc3RhcnRpbmcgUmVnaW9uIFNlcnZlciIpOworCisgICAgc2h1dGRvd25IREZTLnNldChmYWxzZSk7CisgICAgYWJvcnQoKTsKKyAgICBUaHJlYWRzLnNodXRkb3duKHJlZ2lvblNlcnZlclRocmVhZCk7CisKKyAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKKyAgICB3aGlsZSAoIWRvbmUpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHJlaW5pdGlhbGl6ZSgpOworICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJFcnJvciB0cnlpbmcgdG8gcmVpbml0aWFsaXplIFpvb0tlZXBlciIsIGUpOworICAgICAgfQorICAgIH0KKworICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZCh0aGlzKTsKKyAgICBTdHJpbmcgbmFtZSA9IHJlZ2lvblNlcnZlclRocmVhZC5nZXROYW1lKCk7CisgICAgdC5zZXROYW1lKG5hbWUpOworICAgIHQuc3RhcnQoKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIFpvb0tlZXBlcldyYXBwZXIgdXNlZCBieSBSZWdpb25TZXJ2ZXIuICovCisgIHB1YmxpYyBab29LZWVwZXJXcmFwcGVyIGdldFpvb0tlZXBlcldyYXBwZXIoKSB7CisgICAgcmV0dXJuIHpvb0tlZXBlcldyYXBwZXI7CisgIH0KKworICAvKioKKyAgICogVGhlIEhSZWdpb25TZXJ2ZXIgc3RpY2tzIGluIHRoaXMgbG9vcCB1bnRpbCBjbG9zZWQuIEl0IHJlcGVhdGVkbHkgY2hlY2tzCisgICAqIGluIHdpdGggdGhlIEhNYXN0ZXIsIHNlbmRpbmcgaGVhcnRiZWF0cyAmIHJlcG9ydHMsIGFuZCByZWNlaXZpbmcgSFJlZ2lvbiAKKyAgICogbG9hZC91bmxvYWQgaW5zdHJ1Y3Rpb25zLgorICAgKi8KKyAgcHVibGljIHZvaWQgcnVuKCkgeworICAgIHJlZ2lvblNlcnZlclRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7CisgICAgYm9vbGVhbiBxdWllc2NlUmVxdWVzdGVkID0gZmFsc2U7CisgICAgdHJ5IHsKKyAgICAgIGluaXQocmVwb3J0Rm9yRHV0eSgpKTsKKyAgICAgIGxvbmcgbGFzdE1zZyA9IDA7CisgICAgICAvLyBOb3cgYXNrIG1hc3RlciB3aGF0IGl0IHdhbnRzIHVzIHRvIGRvIGFuZCB0ZWxsIGl0IHdoYXQgd2UgaGF2ZSBkb25lCisgICAgICBmb3IgKGludCB0cmllcyA9IDA7ICFzdG9wUmVxdWVzdGVkLmdldCgpICYmIGlzSGVhbHRoeSgpOykgeworICAgICAgICAvLyBUcnkgdG8gZ2V0IHRoZSByb290IHJlZ2lvbiBsb2NhdGlvbiBmcm9tIHRoZSBtYXN0ZXIuCisgICAgICAgIGlmICghaGF2ZVJvb3RSZWdpb24uZ2V0KCkpIHsKKyAgICAgICAgICBIU2VydmVyQWRkcmVzcyByb290U2VydmVyID0gem9vS2VlcGVyV3JhcHBlci5yZWFkUm9vdFJlZ2lvbkxvY2F0aW9uKCk7CisgICAgICAgICAgaWYgKHJvb3RTZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gQnkgc2V0dGluZyB0aGUgcm9vdCByZWdpb24gbG9jYXRpb24sIHdlIGJ5cGFzcyB0aGUgd2FpdCBpbXBvc2VkIG9uCisgICAgICAgICAgICAvLyBIVGFibGUgZm9yIGFsbCByZWdpb25zIGJlaW5nIGFzc2lnbmVkLgorICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnNldFJvb3RSZWdpb25Mb2NhdGlvbigKKyAgICAgICAgICAgICAgICBuZXcgSFJlZ2lvbkxvY2F0aW9uKEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTywgcm9vdFNlcnZlcikpOworICAgICAgICAgICAgaGF2ZVJvb3RSZWdpb24uc2V0KHRydWUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBpZiAobGFzdE1zZyAhPSAwICYmIChub3cgLSBsYXN0TXNnKSA+PSBzZXJ2ZXJMZWFzZVRpbWVvdXQpIHsKKyAgICAgICAgICAvLyBJdCBoYXMgYmVlbiB3YXkgdG9vIGxvbmcgc2luY2Ugd2UgbGFzdCByZXBvcnRlZCB0byB0aGUgbWFzdGVyLgorICAgICAgICAgIExPRy53YXJuKCJ1bmFibGUgdG8gcmVwb3J0IHRvIG1hc3RlciBmb3IgIiArIChub3cgLSBsYXN0TXNnKSArCisgICAgICAgICAgICAiIG1pbGxpc2Vjb25kcyAtIHJldHJ5aW5nIik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChub3cgLSBsYXN0TXNnKSA+PSBtc2dJbnRlcnZhbCkgeworICAgICAgICAgIEhNc2cgb3V0Ym91bmRBcnJheVtdID0gbnVsbDsKKyAgICAgICAgICBzeW5jaHJvbml6ZWQodGhpcy5vdXRib3VuZE1zZ3MpIHsKKyAgICAgICAgICAgIG91dGJvdW5kQXJyYXkgPQorICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kTXNncy50b0FycmF5KG5ldyBITXNnW291dGJvdW5kTXNncy5zaXplKCldKTsKKyAgICAgICAgICAgIHRoaXMub3V0Ym91bmRNc2dzLmNsZWFyKCk7CisgICAgICAgICAgfQorICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBkb01ldHJpY3MoKTsKKyAgICAgICAgICAgIE1lbW9yeVVzYWdlIG1lbW9yeSA9CisgICAgICAgICAgICAgICAgTWFuYWdlbWVudEZhY3RvcnkuZ2V0TWVtb3J5TVhCZWFuKCkuZ2V0SGVhcE1lbW9yeVVzYWdlKCk7CisgICAgICAgICAgICBIU2VydmVyTG9hZCBoc2wgPSBuZXcgSFNlcnZlckxvYWQocmVxdWVzdENvdW50LmdldCgpLAorICAgICAgICAgICAgICAoaW50KShtZW1vcnkuZ2V0VXNlZCgpLzEwMjQvMTAyNCksCisgICAgICAgICAgICAgIChpbnQpKG1lbW9yeS5nZXRNYXgoKS8xMDI0LzEwMjQpKTsKKyAgICAgICAgICAgIGZvciAoSFJlZ2lvbiByOiBvbmxpbmVSZWdpb25zLnZhbHVlcygpKSB7CisgICAgICAgICAgICAgIGhzbC5hZGRSZWdpb25JbmZvKGNyZWF0ZVJlZ2lvbkxvYWQocikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy5zZXJ2ZXJJbmZvLnNldExvYWQoaHNsKTsKKyAgICAgICAgICAgIHRoaXMucmVxdWVzdENvdW50LnNldCgwKTsKKyAgICAgICAgICAgIEhNc2cgbXNnc1tdID0gaGJhc2VNYXN0ZXIucmVnaW9uU2VydmVyUmVwb3J0KAorICAgICAgICAgICAgICBzZXJ2ZXJJbmZvLCBvdXRib3VuZEFycmF5LCBnZXRNb3N0TG9hZGVkUmVnaW9ucygpKTsKKyAgICAgICAgICAgIGxhc3RNc2cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgICAgIGlmICh0aGlzLnF1aWVzY2VkLmdldCgpICYmIG9ubGluZVJlZ2lvbnMuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgICAgLy8gV2UndmUganVzdCB0b2xkIHRoZSBtYXN0ZXIgd2UncmUgZXhpdGluZyBiZWNhdXNlIHdlIGFyZW4ndAorICAgICAgICAgICAgICAvLyBzZXJ2aW5nIGFueSByZWdpb25zLiBTbyBzZXQgdGhlIHN0b3AgYml0IGFuZCBleGl0LgorICAgICAgICAgICAgICBMT0cuaW5mbygiU2VydmVyIHF1aWVzY2VkIGFuZCBub3Qgc2VydmluZyBhbnkgcmVnaW9ucy4gIiArCisgICAgICAgICAgICAgICAgIlN0YXJ0aW5nIHNodXRkb3duIik7CisgICAgICAgICAgICAgIHN0b3BSZXF1ZXN0ZWQuc2V0KHRydWUpOworICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kTXNncy5jbGVhcigpOworICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gUXVldWUgdXAgdGhlIEhNYXN0ZXIncyBpbnN0cnVjdGlvbiBzdHJlYW0gZm9yIHByb2Nlc3NpbmcKKyAgICAgICAgICAgIGJvb2xlYW4gcmVzdGFydCA9IGZhbHNlOworICAgICAgICAgICAgZm9yKGludCBpID0gMDsKKyAgICAgICAgICAgICAgICAhcmVzdGFydCAmJiAhc3RvcFJlcXVlc3RlZC5nZXQoKSAmJiBpIDwgbXNncy5sZW5ndGg7CisgICAgICAgICAgICAgICAgaSsrKSB7CisgICAgICAgICAgICAgIExPRy5pbmZvKG1zZ3NbaV0udG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgIGlmIChzYWZlTW9kZS5nZXQoKSkgeworICAgICAgICAgICAgICAgIGlmICh6b29LZWVwZXJXcmFwcGVyLmNoZWNrT3V0T2ZTYWZlTW9kZSgpKSB7CisgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24udW5zZXRSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoc2FmZU1vZGUpIHsKKyAgICAgICAgICAgICAgICAgICAgc2FmZU1vZGUuc2V0KGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgc2FmZU1vZGUubm90aWZ5QWxsKCk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIHN3aXRjaChtc2dzW2ldLmdldFR5cGUoKSkgeworICAgICAgICAgICAgICBjYXNlIE1TR19DQUxMX1NFUlZFUl9TVEFSVFVQOgorICAgICAgICAgICAgICAgIC8vIFdlIHRoZSBNU0dfQ0FMTF9TRVJWRVJfU1RBUlRVUCBvbiBzdGFydHVwIGJ1dCB3ZSBjYW4gYWxzbworICAgICAgICAgICAgICAgIC8vIGdldCBpdCB3aGVuIHRoZSBtYXN0ZXIgaXMgcGFuaWNraW5nIGJlY2F1c2UgZm9yIGluc3RhbmNlCisgICAgICAgICAgICAgICAgLy8gdGhlIEhERlMgaGFzIGJlZW4geWFua2VkIG91dCBmcm9tIHVuZGVyIGl0LiAgQmUgd2FyeSBvZgorICAgICAgICAgICAgICAgIC8vIHRoaXMgbWVzc2FnZS4KKyAgICAgICAgICAgICAgICBpZiAoY2hlY2tGaWxlU3lzdGVtKCkpIHsKKyAgICAgICAgICAgICAgICAgIGNsb3NlQWxsUmVnaW9ucygpOworICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbG9nLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBMT0cuZXJyb3IoImVycm9yIGNsb3NpbmcgYW5kIGRlbGV0aW5nIEhMb2ciLCBlKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHNlcnZlckluZm8uc2V0U3RhcnRDb2RlKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgICAgICAgICAgICAgICAgbG9nID0gc2V0dXBITG9nKCk7CisgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nRmx1c2hlci5zZXRITG9nKGxvZyk7CisgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuYWJvcnRSZXF1ZXN0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3BSZXF1ZXN0ZWQuc2V0KHRydWUpOworICAgICAgICAgICAgICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKGUpOyAKKyAgICAgICAgICAgICAgICAgICAgTE9HLmZhdGFsKCJlcnJvciByZXN0YXJ0aW5nIHNlcnZlciIsIGUpOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIHJlcG9ydEZvckR1dHkoKTsKKyAgICAgICAgICAgICAgICAgIHJlc3RhcnQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICBMT0cuZmF0YWwoImZpbGUgc3lzdGVtIGF2YWlsYWJsZSBjaGVjayBmYWlsZWQuICIgKworICAgICAgICAgICAgICAgICAgIlNodXR0aW5nIGRvd24gc2VydmVyLiIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05TRVJWRVJfU1RPUDoKKyAgICAgICAgICAgICAgICBzdG9wUmVxdWVzdGVkLnNldCh0cnVlKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05TRVJWRVJfUVVJRVNDRToKKyAgICAgICAgICAgICAgICBpZiAoIXF1aWVzY2VSZXF1ZXN0ZWQpIHsKKyAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHRvRG8ucHV0KG5ldyBUb0RvRW50cnkobXNnc1tpXSkpOworICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiUHV0dGluZyBpbnRvIG1zZ1F1ZXVlIHdhcyAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJpbnRlcnJ1cHRlZC4iLCBlKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIHF1aWVzY2VSZXF1ZXN0ZWQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGlmIChmc09rKSB7CisgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0b0RvLnB1dChuZXcgVG9Eb0VudHJ5KG1zZ3NbaV0pKTsKKyAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlB1dHRpbmcgaW50byBtc2dRdWV1ZSB3YXMgIiArCisgICAgICAgICAgICAgICAgICAgICAgICAiaW50ZXJydXB0ZWQuIiwgZSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyBSZXNldCB0cmllcyBjb3VudCBpZiB3ZSBoYWQgYSBzdWNjZXNzZnVsIHRyYW5zYWN0aW9uLgorICAgICAgICAgICAgdHJpZXMgPSAwOworCisgICAgICAgICAgICBpZiAocmVzdGFydCB8fCB0aGlzLnN0b3BSZXF1ZXN0ZWQuZ2V0KCkpIHsKKyAgICAgICAgICAgICAgdG9Eby5jbGVhcigpOworICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgeworICAgICAgICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKChJT0V4Y2VwdGlvbikgZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodHJpZXMgPCB0aGlzLm51bVJldHJpZXMpIHsKKyAgICAgICAgICAgICAgTE9HLndhcm4oIlByb2Nlc3NpbmcgbWVzc2FnZSAoUmV0cnk6ICIgKyB0cmllcyArICIpIiwgZSk7CisgICAgICAgICAgICAgIHRyaWVzKys7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMT0cuZXJyb3IoIkV4Y2VlZGVkIG1heCByZXRyaWVzOiAiICsgdGhpcy5udW1SZXRyaWVzLCBlKTsKKyAgICAgICAgICAgICAgaWYgKGNoZWNrRmlsZVN5c3RlbSgpKSB7CisgICAgICAgICAgICAgICAgLy8gRmlsZXN5c3RlbSBpcyBPSy4gIFNvbWV0aGluZyBpcyB1cCB3LyBaSyBvciBtYXN0ZXIuICBTbGVlcAorICAgICAgICAgICAgICAgIC8vIGEgbGl0dGxlIHdoaWxlIGlmIG9ubHkgdG8gc3RvcCBvdXIgbG9nZ2luZyBtYW55IHRpbWVzIGEKKyAgICAgICAgICAgICAgICAvLyBtaWxsaXNlY29uZC4KKyAgICAgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0aGlzLnN0b3BSZXF1ZXN0ZWQuZ2V0KCkpIHsKKyAgICAgICAgICAgICAgICBMT0cuaW5mbygiU3RvcCB3YXMgcmVxdWVzdGVkLCBjbGVhcmluZyB0aGUgdG9EbyAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICJkZXNwaXRlIG9mIHRoZSBleGNlcHRpb24iKTsKKyAgICAgICAgICAgICAgICB0b0RvLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIERvIHNvbWUgaG91c2VrZWVwaW5nIGJlZm9yZSBnb2luZyB0byBzbGVlcAorICAgICAgICBob3VzZWtlZXBpbmcoKTsKKyAgICAgICAgc2xlZXBlci5zbGVlcChsYXN0TXNnKTsKKyAgICAgIH0gLy8gZm9yCisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIGlmICghY2hlY2tPT01FKHQpKSB7CisgICAgICAgIExPRy5mYXRhbCgiVW5oYW5kbGVkIGV4Y2VwdGlvbi4gQWJvcnRpbmcuLi4iLCB0KTsKKyAgICAgICAgYWJvcnQoKTsKKyAgICAgIH0KKyAgICB9CisgICAgUmVnaW9uSGlzdG9yaWFuLmdldEluc3RhbmNlKCkub2ZmbGluZSgpOworICAgIHRoaXMubGVhc2VzLmNsb3NlQWZ0ZXJMZWFzZXNFeHBpcmUoKTsKKyAgICB0aGlzLndvcmtlci5zdG9wKCk7CisgICAgdGhpcy5zZXJ2ZXIuc3RvcCgpOworICAgIGlmICh0aGlzLmluZm9TZXJ2ZXIgIT0gbnVsbCkgeworICAgICAgTE9HLmluZm8oIlN0b3BwaW5nIGluZm9TZXJ2ZXIiKTsKKyAgICAgIHRyeSB7CisgICAgICAgIHRoaXMuaW5mb1NlcnZlci5zdG9wKCk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFNlbmQgaW50ZXJydXB0cyB0byB3YWtlIHVwIHRocmVhZHMgaWYgc2xlZXBpbmcgc28gdGhleSBub3RpY2Ugc2h1dGRvd24uCisgICAgLy8gVE9ETzogU2hvdWxkIHdlIGNoZWNrIHRoZXkgYXJlIGFsaXZlPyAgSWYgT09NRSBjb3VsZCBoYXZlIGV4aXRlZCBhbHJlYWR5CisgICAgY2FjaGVGbHVzaGVyLmludGVycnVwdElmTmVjZXNzYXJ5KCk7CisgICAgbG9nRmx1c2hlci5pbnRlcnJ1cHQoKTsKKyAgICBjb21wYWN0U3BsaXRUaHJlYWQuaW50ZXJydXB0SWZOZWNlc3NhcnkoKTsKKyAgICBsb2dSb2xsZXIuaW50ZXJydXB0SWZOZWNlc3NhcnkoKTsKKyAgICB0aGlzLm1ham9yQ29tcGFjdGlvbkNoZWNrZXIuaW50ZXJydXB0KCk7CisKKyAgICBpZiAoYWJvcnRSZXF1ZXN0ZWQpIHsKKyAgICAgIGlmICh0aGlzLmZzT2spIHsKKyAgICAgICAgLy8gT25seSB0cnkgdG8gY2xlYW4gdXAgaWYgdGhlIGZpbGUgc3lzdGVtIGlzIGF2YWlsYWJsZQorICAgICAgICB0cnkgeworICAgICAgICAgIGlmICh0aGlzLmxvZyAhPSBudWxsKSB7CisgICAgICAgICAgICB0aGlzLmxvZy5jbG9zZSgpOworICAgICAgICAgICAgTE9HLmluZm8oIk9uIGFib3J0LCBjbG9zZWQgaGxvZyIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoIlVuYWJsZSB0byBjbG9zZSBsb2cgaW4gYWJvcnQiLAorICAgICAgICAgICAgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja1Rocm93YWJsZShlKSk7CisgICAgICAgIH0KKyAgICAgICAgY2xvc2VBbGxSZWdpb25zKCk7IC8vIERvbid0IGxlYXZlIGFueSBvcGVuIGZpbGUgaGFuZGxlcworICAgICAgfQorICAgICAgTE9HLmluZm8oImFib3J0aW5nIHNlcnZlciBhdDogIiArCisgICAgICAgIHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLnRvU3RyaW5nKCkpOworICAgIH0gZWxzZSB7CisgICAgICBBcnJheUxpc3Q8SFJlZ2lvbj4gY2xvc2VkUmVnaW9ucyA9IGNsb3NlQWxsUmVnaW9ucygpOworICAgICAgdHJ5IHsKKyAgICAgICAgbG9nLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICBMT0cuZXJyb3IoIkNsb3NlIGFuZCBkZWxldGUgZmFpbGVkIiwKKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrVGhyb3dhYmxlKGUpKTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIEhNc2dbXSBleGl0TXNnID0gbmV3IEhNc2dbY2xvc2VkUmVnaW9ucy5zaXplKCkgKyAxXTsKKyAgICAgICAgZXhpdE1zZ1swXSA9IFJFUE9SVF9FWElUSU5HOworICAgICAgICAvLyBUZWxsIHRoZSBtYXN0ZXIgd2hhdCByZWdpb25zIHdlIGFyZS93ZXJlIHNlcnZpbmcKKyAgICAgICAgaW50IGkgPSAxOworICAgICAgICBmb3IgKEhSZWdpb24gcmVnaW9uOiBjbG9zZWRSZWdpb25zKSB7CisgICAgICAgICAgZXhpdE1zZ1tpKytdID0gbmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRVBPUlRfQ0xPU0UsCisgICAgICAgICAgICAgIHJlZ2lvbi5nZXRSZWdpb25JbmZvKCkpOworICAgICAgICB9CisKKyAgICAgICAgTE9HLmluZm8oInRlbGxpbmcgbWFzdGVyIHRoYXQgcmVnaW9uIHNlcnZlciBpcyBzaHV0dGluZyBkb3duIGF0OiAiICsKKyAgICAgICAgICAgIHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLnRvU3RyaW5nKCkpOworICAgICAgICBoYmFzZU1hc3Rlci5yZWdpb25TZXJ2ZXJSZXBvcnQoc2VydmVySW5mbywgZXhpdE1zZywgKEhSZWdpb25JbmZvW10pbnVsbCk7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHNlbmQgZXhpdGluZyBtZXNzYWdlIHRvIG1hc3RlcjogIiwKKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrVGhyb3dhYmxlKGUpKTsKKyAgICAgIH0KKyAgICAgIExPRy5pbmZvKCJzdG9wcGluZyBzZXJ2ZXIgYXQ6ICIgKworICAgICAgICBzZXJ2ZXJJbmZvLmdldFNlcnZlckFkZHJlc3MoKS50b1N0cmluZygpKTsKKyAgICB9CisgICAgaWYgKHRoaXMuaGJhc2VNYXN0ZXIgIT0gbnVsbCkgeworICAgICAgSEJhc2VSUEMuc3RvcFByb3h5KHRoaXMuaGJhc2VNYXN0ZXIpOworICAgICAgdGhpcy5oYmFzZU1hc3RlciA9IG51bGw7CisgICAgfQorICAgIGpvaW4oKTsKKworICAgIGlmIChzaHV0ZG93bkhERlMuZ2V0KCkpIHsKKyAgICAgIHJ1blRocmVhZCh0aGlzLmhkZnNTaHV0ZG93blRocmVhZCwKKyAgICAgICAgICB0aGlzLmNvbmYuZ2V0TG9uZygiaGJhc2UuZGZzLnNodXRkb3duLndhaXQiLCAzMDAwMCkpOworICAgIH0KKworICAgIExPRy5pbmZvKFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpICsgIiBleGl0aW5nIik7CisgIH0KKworICAvKioKKyAgICogUnVuIGFuZCB3YWl0IG9uIHBhc3NlZCB0aHJlYWQgaW4gSFJTIGNvbnRleHQuCisgICAqIEBwYXJhbSB0CisgICAqIEBwYXJhbSBkZnNTaHV0ZG93bldhaXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHJ1blRocmVhZChmaW5hbCBUaHJlYWQgdCwgZmluYWwgbG9uZyBkZnNTaHV0ZG93bldhaXQpIHsKKyAgICBpZiAodCA9PSAgbnVsbCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICB0LnN0YXJ0KCk7CisgICAgVGhyZWFkcy5zaHV0ZG93bih0LCBkZnNTaHV0ZG93bldhaXQpOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgaGRmcyBzaHV0ZG93biB0aHJlYWQgdG8gcnVuIG9uIGV4aXQuICBQYXNzIG51bGwgdG8gZGlzYWJsZQorICAgKiBydW5uaW5nIG9mIHRoZSBzaHV0ZG93biB0ZXN0LiAgTmVlZGVkIGJ5IHRlc3RzLgorICAgKiBAcGFyYW0gdCBUaHJlYWQgdG8gcnVuLiAgUGFzcyBudWxsIHRvIGRpc2FibGUgdGVzdHMuCisgICAqIEByZXR1cm4gUHJldmlvdXMgb2NjdXBhbnQgb2YgdGhlIHNodXRkb3duIHRocmVhZCBwb3NpdGlvbi4KKyAgICovCisgIHB1YmxpYyBUaHJlYWQgc2V0SERGU1NodXRkb3duVGhyZWFkT25FeGl0KGZpbmFsIFRocmVhZCB0KSB7CisgICAgVGhyZWFkIG9sZCA9IHRoaXMuaGRmc1NodXRkb3duVGhyZWFkOworICAgIHRoaXMuaGRmc1NodXRkb3duVGhyZWFkID0gdDsKKyAgICByZXR1cm4gb2xkOworICB9CisKKyAgLyoKKyAgICogUnVuIGluaXQuIFNldHMgdXAgaGxvZyBhbmQgc3RhcnRzIHVwIGFsbCBzZXJ2ZXIgdGhyZWFkcy4KKyAgICogQHBhcmFtIGMgRXh0cmEgY29uZmlndXJhdGlvbi4KKyAgICovCisgIHByb3RlY3RlZCB2b2lkIGluaXQoZmluYWwgTWFwV3JpdGFibGUgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgZm9yIChNYXAuRW50cnk8V3JpdGFibGUsIFdyaXRhYmxlPiBlOiBjLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgU3RyaW5nIGtleSA9IGUuZ2V0S2V5KCkudG9TdHJpbmcoKTsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gZS5nZXRWYWx1ZSgpLnRvU3RyaW5nKCk7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygiQ29uZmlnIGZyb20gbWFzdGVyOiAiICsga2V5ICsgIj0iICsgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY29uZi5zZXQoa2V5LCB2YWx1ZSk7CisgICAgICB9CisgICAgICAvLyBNYXN0ZXIgbWF5IGhhdmUgc2VudCB1cyBhIG5ldyBhZGRyZXNzIHdpdGggdGhlIG90aGVyIGNvbmZpZ3MuCisgICAgICAvLyBVcGRhdGUgb3VyIGFkZHJlc3MgaW4gdGhpcyBjYXNlLiBTZWUgSEJBU0UtNzE5CisgICAgICBpZihjb25mLmdldCgiaGJhc2UucmVnaW9uc2VydmVyLmFkZHJlc3MiKSAhPSBudWxsKQorICAgICAgICBzZXJ2ZXJJbmZvLnNldFNlcnZlckFkZHJlc3MobmV3IEhTZXJ2ZXJBZGRyZXNzCisgICAgICAgICAgICAoY29uZi5nZXQoImhiYXNlLnJlZ2lvbnNlcnZlci5hZGRyZXNzIiksIAorICAgICAgICAgICAgc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkuZ2V0UG9ydCgpKSk7CisgICAgICAvLyBNYXN0ZXIgc2VudCB1cyBoYmFzZS5yb290ZGlyIHRvIHVzZS4gU2hvdWxkIGJlIGZ1bGx5IHF1YWxpZmllZAorICAgICAgLy8gcGF0aCB3aXRoIGZpbGUgc3lzdGVtIHNwZWNpZmljYXRpb24gaW5jbHVkZWQuICBTZXQgJ2ZzLmRlZmF1bHQubmFtZScKKyAgICAgIC8vIHRvIG1hdGNoIHRoZSBmaWxlc3lzdGVtIG9uIGhiYXNlLnJvb3RkaXIgZWxzZSB1bmRlcmx5aW5nIGhhZG9vcCBoZGZzCisgICAgICAvLyBhY2Nlc3NvcnMgd2lsbCBiZSBnb2luZyBhZ2FpbnN0IHdyb25nIGZpbGVzeXN0ZW0gKHVubGVzcyBhbGwgaXMgc2V0CisgICAgICAvLyB0byBkZWZhdWx0cykuCisgICAgICB0aGlzLmNvbmYuc2V0KCJmcy5kZWZhdWx0Lm5hbWUiLCB0aGlzLmNvbmYuZ2V0KCJoYmFzZS5yb290ZGlyIikpOworICAgICAgdGhpcy5mcyA9IEZpbGVTeXN0ZW0uZ2V0KHRoaXMuY29uZik7CisKKyAgICAgIC8vIFJlZ2lzdGVyIHNodXRkb3duIGhvb2sgZm9yIEhSZWdpb25TZXJ2ZXIsIHJ1bnMgYW4gb3JkZXJseSBzaHV0ZG93bgorICAgICAgLy8gd2hlbiBhIGtpbGwgc2lnbmFsIGlzIHJlY2lldmVkCisgICAgICBSdW50aW1lLmdldFJ1bnRpbWUoKS5hZGRTaHV0ZG93bkhvb2sobmV3IFNodXRkb3duVGhyZWFkKHRoaXMsCisgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSkpOworICAgICAgdGhpcy5oZGZzU2h1dGRvd25UaHJlYWQgPSBzdXBwcmVzc0hkZnNTaHV0ZG93bkhvb2soKTsKKworICAgICAgdGhpcy5yb290RGlyID0gbmV3IFBhdGgodGhpcy5jb25mLmdldChIQ29uc3RhbnRzLkhCQVNFX0RJUikpOworICAgICAgdGhpcy5sb2cgPSBzZXR1cEhMb2coKTsKKyAgICAgIHRoaXMubG9nRmx1c2hlci5zZXRITG9nKGxvZyk7CisgICAgICAvLyBJbml0IGluIGhlcmUgcmF0aGVyIHRoYW4gaW4gY29uc3RydWN0b3IgYWZ0ZXIgdGhyZWFkIG5hbWUgaGFzIGJlZW4gc2V0CisgICAgICB0aGlzLm1ldHJpY3MgPSBuZXcgUmVnaW9uU2VydmVyTWV0cmljcygpOworICAgICAgc3RhcnRTZXJ2aWNlVGhyZWFkcygpOworICAgICAgaXNPbmxpbmUgPSB0cnVlOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICB0aGlzLmlzT25saW5lID0gZmFsc2U7CisgICAgICB0aGlzLnN0b3BSZXF1ZXN0ZWQuc2V0KHRydWUpOworICAgICAgdGhyb3cgY29udmVydFRocm93YWJsZVRvSU9FKGNsZWFudXAoZSwgIkZhaWxlZCBpbml0IiksCisgICAgICAgICJSZWdpb24gc2VydmVyIHN0YXJ0dXAgZmFpbGVkIik7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogQHBhcmFtIHIgUmVnaW9uIHRvIGdldCBSZWdpb25Mb2FkIGZvci4KKyAgICogQHJldHVybiBSZWdpb25Mb2FkIGluc3RhbmNlLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIEhTZXJ2ZXJMb2FkLlJlZ2lvbkxvYWQgY3JlYXRlUmVnaW9uTG9hZChmaW5hbCBIUmVnaW9uIHIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIG5hbWUgPSByLmdldFJlZ2lvbk5hbWUoKTsKKyAgICBpbnQgc3RvcmVzID0gMDsKKyAgICBpbnQgc3RvcmVmaWxlcyA9IDA7CisgICAgaW50IG1lbWNhY2hlU2l6ZU1CID0gKGludCkoci5tZW1jYWNoZVNpemUuZ2V0KCkvMTAyNC8xMDI0KTsKKyAgICBpbnQgc3RvcmVmaWxlSW5kZXhTaXplTUIgPSAwOworICAgIHN5bmNocm9uaXplZCAoci5zdG9yZXMpIHsKKyAgICAgIHN0b3JlcyArPSByLnN0b3Jlcy5zaXplKCk7CisgICAgICBmb3IgKFN0b3JlIHN0b3JlOiByLnN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBzdG9yZWZpbGVzICs9IHN0b3JlLmdldFN0b3JlZmlsZXNDb3VudCgpOworICAgICAgICBzdG9yZWZpbGVJbmRleFNpemVNQiArPSAKKyAgICAgICAgICAoaW50KShzdG9yZS5nZXRTdG9yZWZpbGVzSW5kZXhTaXplKCkvMTAyNC8xMDI0KTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIG5ldyBIU2VydmVyTG9hZC5SZWdpb25Mb2FkKG5hbWUsIHN0b3Jlcywgc3RvcmVmaWxlcywgbWVtY2FjaGVTaXplTUIsCisgICAgICBzdG9yZWZpbGVJbmRleFNpemVNQik7CisgIH0KKyAKKyAgLyoqCisgICAqIEBwYXJhbSByZWdpb25OYW1lCisgICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgUmVnaW9uTG9hZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJMb2FkLlJlZ2lvbkxvYWQgY3JlYXRlUmVnaW9uTG9hZChmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNyZWF0ZVJlZ2lvbkxvYWQodGhpcy5vbmxpbmVSZWdpb25zLmdldChCeXRlcy5tYXBLZXkocmVnaW9uTmFtZSkpKTsKKyAgfQorCisgIC8qCisgICAqIENsZWFudXAgYWZ0ZXIgVGhyb3dhYmxlIGNhdWdodCBpbnZva2luZyBtZXRob2QuICBDb252ZXJ0cyA8Y29kZT50PC9jb2RlPgorICAgKiB0byBJT0UgaWYgaXQgaXNuJ3QgYWxyZWFkeS4KKyAgICogQHBhcmFtIHQgVGhyb3dhYmxlCisgICAqIEByZXR1cm4gVGhyb3dhYmxlIGNvbnZlcnRlZCB0byBhbiBJT0U7IG1ldGhvZHMgY2FuIG9ubHkgbGV0IG91dCBJT0VzLgorICAgKi8KKyAgcHJpdmF0ZSBUaHJvd2FibGUgY2xlYW51cChmaW5hbCBUaHJvd2FibGUgdCkgeworICAgIHJldHVybiBjbGVhbnVwKHQsIG51bGwpOworICB9CisKKyAgLyoKKyAgICogQ2xlYW51cCBhZnRlciBUaHJvd2FibGUgY2F1Z2h0IGludm9raW5nIG1ldGhvZC4gIENvbnZlcnRzIDxjb2RlPnQ8L2NvZGU+CisgICAqIHRvIElPRSBpZiBpdCBpc24ndCBhbHJlYWR5LgorICAgKiBAcGFyYW0gdCBUaHJvd2FibGUKKyAgICogQHBhcmFtIG1zZyBNZXNzYWdlIHRvIGxvZyBpbiBlcnJvci4gIENhbiBiZSBudWxsLgorICAgKiBAcmV0dXJuIFRocm93YWJsZSBjb252ZXJ0ZWQgdG8gYW4gSU9FOyBtZXRob2RzIGNhbiBvbmx5IGxldCBvdXQgSU9Fcy4KKyAgICovCisgIHByaXZhdGUgVGhyb3dhYmxlIGNsZWFudXAoZmluYWwgVGhyb3dhYmxlIHQsIGZpbmFsIFN0cmluZyBtc2cpIHsKKyAgICBpZiAobXNnID09IG51bGwpIHsKKyAgICAgIExPRy5lcnJvcihSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrVGhyb3dhYmxlKHQpKTsKKyAgICB9IGVsc2UgeworICAgICAgTE9HLmVycm9yKG1zZywgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja1Rocm93YWJsZSh0KSk7CisgICAgfQorICAgIGlmICghY2hlY2tPT01FKHQpKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gdAorICAgKiBAcmV0dXJuIE1ha2UgPGNvZGU+dDwvY29kZT4gYW4gSU9FIGlmIGl0IGlzbid0IGFscmVhZHkuCisgICAqLworICBwcml2YXRlIElPRXhjZXB0aW9uIGNvbnZlcnRUaHJvd2FibGVUb0lPRShmaW5hbCBUaHJvd2FibGUgdCkgeworICAgIHJldHVybiBjb252ZXJ0VGhyb3dhYmxlVG9JT0UodCwgbnVsbCk7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gdAorICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdG8gcHV0IGluIG5ldyBJT0UgaWYgcGFzc2VkIDxjb2RlPnQ8L2NvZGU+IGlzIG5vdCBhbiBJT0UKKyAgICogQHJldHVybiBNYWtlIDxjb2RlPnQ8L2NvZGU+IGFuIElPRSBpZiBpdCBpc24ndCBhbHJlYWR5LgorICAgKi8KKyAgcHJpdmF0ZSBJT0V4Y2VwdGlvbiBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoZmluYWwgVGhyb3dhYmxlIHQsCisgICAgICBmaW5hbCBTdHJpbmcgbXNnKSB7CisgICAgcmV0dXJuICh0IGluc3RhbmNlb2YgSU9FeGNlcHRpb24/IChJT0V4Y2VwdGlvbil0OgorICAgICAgbXNnID09IG51bGwgfHwgbXNnLmxlbmd0aCgpID09IDA/CisgICAgICAgIG5ldyBJT0V4Y2VwdGlvbih0KTogbmV3IElPRXhjZXB0aW9uKG1zZywgdCkpOworICB9CisgIC8qCisgICAqIENoZWNrIGlmIGFuIE9PTUUgYW5kIGlmIHNvLCBjYWxsIGFib3J0LgorICAgKiBAcGFyYW0gZQorICAgKiBAcmV0dXJuIFRydWUgaWYgd2UgT09NRSdkIGFuZCBhcmUgYWJvcnRpbmcuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBjaGVja09PTUUoZmluYWwgVGhyb3dhYmxlIGUpIHsKKyAgICBib29sZWFuIHN0b3AgPSBmYWxzZTsKKyAgICBpZiAoZSBpbnN0YW5jZW9mIE91dE9mTWVtb3J5RXJyb3IgfHwKKyAgICAgIChlLmdldENhdXNlKCkgIT0gbnVsbCAmJiBlLmdldENhdXNlKCkgaW5zdGFuY2VvZiBPdXRPZk1lbW9yeUVycm9yKSB8fAorICAgICAgKGUuZ2V0TWVzc2FnZSgpICE9IG51bGwgJiYKKyAgICAgICAgZS5nZXRNZXNzYWdlKCkuY29udGFpbnMoImphdmEubGFuZy5PdXRPZk1lbW9yeUVycm9yIikpKSB7CisgICAgICBMT0cuZmF0YWwoIk91dE9mTWVtb3J5RXJyb3IsIGFib3J0aW5nLiIsIGUpOworICAgICAgYWJvcnQoKTsKKyAgICAgIHN0b3AgPSB0cnVlOworICAgIH0KKyAgICByZXR1cm4gc3RvcDsKKyAgfQorICAKKyAgCisgIC8qKgorICAgKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBmaWxlIHN5c3RlbSBpcyBzdGlsbCBhY2Nlc3NpYmxlLgorICAgKiBJZiBub3QsIHNldHMgYWJvcnRSZXF1ZXN0ZWQgYW5kIHN0b3BSZXF1ZXN0ZWQKKyAgICogCisgICAqIEByZXR1cm4gZmFsc2UgaWYgZmlsZSBzeXN0ZW0gaXMgbm90IGF2YWlsYWJsZQorICAgKi8KKyAgcHJvdGVjdGVkIGJvb2xlYW4gY2hlY2tGaWxlU3lzdGVtKCkgeworICAgIGlmICh0aGlzLmZzT2sgJiYgdGhpcy5mcyAhPSBudWxsKSB7CisgICAgICB0cnkgeworICAgICAgICBGU1V0aWxzLmNoZWNrRmlsZVN5c3RlbUF2YWlsYWJsZSh0aGlzLmZzKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLmZhdGFsKCJTaHV0dGluZyBkb3duIEhSZWdpb25TZXJ2ZXI6IGZpbGUgc3lzdGVtIG5vdCBhdmFpbGFibGUiLCBlKTsKKyAgICAgICAgYWJvcnQoKTsKKyAgICAgICAgdGhpcy5mc09rID0gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0aGlzLmZzT2s7CisgIH0KKworICAvKioKKyAgICogVGhyZWFkIGZvciB0b2dnbGluZyBzYWZlbW9kZSBhZnRlciBzb21lIGNvbmZpZ3VyYWJsZSBpbnRlcnZhbC4KKyAgICovCisgIHByaXZhdGUgY2xhc3MgQ29tcGFjdGlvbkxpbWl0VGhyZWFkIGV4dGVuZHMgVGhyZWFkIHsKKyAgICBwcm90ZWN0ZWQgQ29tcGFjdGlvbkxpbWl0VGhyZWFkKCkge30KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgIC8vIEZpcnN0IHdhaXQgdW50aWwgd2UgZXhpdCBzYWZlIG1vZGUKKyAgICAgIHN5bmNocm9uaXplZCAoc2FmZU1vZGUpIHsKKyAgICAgICAgd2hpbGUoc2FmZU1vZGUuZ2V0KCkpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIldhaXRpbmcgdG8gZXhpdCBzYWZlIG1vZGUiKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgc2FmZU1vZGUud2FpdCgpOworICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBub3cgdGhhdCBzYWZlbW9kZSBpcyBvZmYsIHNsb3dseSBpbmNyZWFzZSB0aGUgcGVyLWN5Y2xlIGNvbXBhY3Rpb24KKyAgICAgIC8vIGxpbWl0LCBmaW5hbGx5IHNldHRpbmcgaXQgdG8gdW5saW1pdGVkICgtMSkKKworICAgICAgaW50IGNvbXBhY3Rpb25DaGVja0ludGVydmFsID0gCisgICAgICAgIGNvbmYuZ2V0SW50KCJoYmFzZS5yZWdpb25zZXJ2ZXIudGhyZWFkLnNwbGl0Y29tcGFjdGNoZWNrZnJlcXVlbmN5IiwKKyAgICAgICAgICAgIDIwICogMTAwMCk7CisgICAgICBmaW5hbCBpbnQgbGltaXRTdGVwc1tdID0geworICAgICAgICAxLCAxLCAxLCAxLAorICAgICAgICAyLCAyLCAyLCAyLCAyLCAyLAorICAgICAgICAzLCAzLCAzLCAzLCAzLCAzLCAzLCAzLCAKKyAgICAgICAgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwKKyAgICAgICAgLTEKKyAgICAgIH07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpbWl0U3RlcHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgLy8gSnVzdCBsb2cgY2hhbmdlcy4KKyAgICAgICAgaWYgKGNvbXBhY3RTcGxpdFRocmVhZC5nZXRMaW1pdCgpICE9IGxpbWl0U3RlcHNbaV0gJiYKKyAgICAgICAgICAgIExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJzZXR0aW5nIGNvbXBhY3Rpb24gbGltaXQgdG8gIiArIGxpbWl0U3RlcHNbaV0pOworICAgICAgICB9CisgICAgICAgIGNvbXBhY3RTcGxpdFRocmVhZC5zZXRMaW1pdChsaW1pdFN0ZXBzW2ldKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoY29tcGFjdGlvbkNoZWNrSW50ZXJ2YWwpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgIC8vIHVubGltaXQgY29tcGFjdGlvbnMgYmVmb3JlIGV4aXRpbmcKKyAgICAgICAgICBjb21wYWN0U3BsaXRUaHJlYWQuc2V0TGltaXQoLTEpOworICAgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgICAgTE9HLmRlYnVnKHRoaXMuZ2V0TmFtZSgpICsgIiBleGl0aW5nIG9uIGludGVycnVwdCIpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIExPRy5pbmZvKCJjb21wYWN0aW9ucyBubyBsb25nZXIgbGltaXRlZCIpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIFRocmVhZCB0byBzaHV0ZG93biB0aGUgcmVnaW9uIHNlcnZlciBpbiBhbiBvcmRlcmx5IG1hbm5lci4gIFRoaXMgdGhyZWFkCisgICAqIGlzIHJlZ2lzdGVyZWQgYXMgYSBzaHV0ZG93biBob29rIGluIHRoZSBIUmVnaW9uU2VydmVyIGNvbnN0cnVjdG9yIGFuZCBpcworICAgKiBvbmx5IGNhbGxlZCB3aGVuIHRoZSBIUmVnaW9uU2VydmVyIHJlY2VpdmVzIGEga2lsbCBzaWduYWwuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTaHV0ZG93blRocmVhZCBleHRlbmRzIFRocmVhZCB7CisgICAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uU2VydmVyIGluc3RhbmNlOworICAgIHByaXZhdGUgZmluYWwgVGhyZWFkIG1haW5UaHJlYWQ7CisgICAgCisgICAgLyoqCisgICAgICogQHBhcmFtIGluc3RhbmNlCisgICAgICogQHBhcmFtIG1haW5UaHJlYWQKKyAgICAgKi8KKyAgICBwdWJsaWMgU2h1dGRvd25UaHJlYWQoSFJlZ2lvblNlcnZlciBpbnN0YW5jZSwgVGhyZWFkIG1haW5UaHJlYWQpIHsKKyAgICAgIHRoaXMuaW5zdGFuY2UgPSBpbnN0YW5jZTsKKyAgICAgIHRoaXMubWFpblRocmVhZCA9IG1haW5UaHJlYWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgTE9HLmluZm8oIlN0YXJ0aW5nIHNodXRkb3duIHRocmVhZC4iKTsKKyAgICAgIAorICAgICAgLy8gdGVsbCB0aGUgcmVnaW9uIHNlcnZlciB0byBzdG9wCisgICAgICBpbnN0YW5jZS5zdG9wKCk7CisKKyAgICAgIC8vIFdhaXQgZm9yIG1haW4gdGhyZWFkIHRvIGV4aXQuCisgICAgICBUaHJlYWRzLnNodXRkb3duKG1haW5UaHJlYWQpOworCisgICAgICBMT0cuaW5mbygiU2h1dGRvd24gdGhyZWFkIGNvbXBsZXRlIik7CisgICAgfSAgICAKKyAgfQorCisgIC8vIFdlIG5lZWQgdG8gY2FsbCBIREZTIHNodXRkb3duIHdoZW4gd2UgYXJlIGRvbmUgc2h1dHRpbmcgZG93bgorICBwcml2YXRlIFRocmVhZCBoZGZzU2h1dGRvd25UaHJlYWQ7CisKKyAgLyoKKyAgICogSW5uZXIgY2xhc3MgdGhhdCBydW5zIG9uIGEgbG9uZyBwZXJpb2QgY2hlY2tpbmcgaWYgcmVnaW9ucyBuZWVkIG1ham9yCisgICAqIGNvbXBhY3Rpb24uCisgICAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNYWpvckNvbXBhY3Rpb25DaGVja2VyIGV4dGVuZHMgQ2hvcmUgeworICAgIHByaXZhdGUgZmluYWwgSFJlZ2lvblNlcnZlciBpbnN0YW5jZTsKKworICAgIE1ham9yQ29tcGFjdGlvbkNoZWNrZXIoZmluYWwgSFJlZ2lvblNlcnZlciBoLAorICAgICAgICBmaW5hbCBpbnQgc2xlZXBUaW1lLCBmaW5hbCBBdG9taWNCb29sZWFuIHN0b3BwZXIpIHsKKyAgICAgIHN1cGVyKHNsZWVwVGltZSwgc3RvcHBlcik7CisgICAgICB0aGlzLmluc3RhbmNlID0gaDsKKyAgICAgIExPRy5pbmZvKCJSdW5zIGV2ZXJ5ICIgKyBzbGVlcFRpbWUgKyAibXMiKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCBjaG9yZSgpIHsKKyAgICAgIFNldDxJbnRlZ2VyPiBrZXlzID0gdGhpcy5pbnN0YW5jZS5vbmxpbmVSZWdpb25zLmtleVNldCgpOworICAgICAgZm9yIChJbnRlZ2VyIGk6IGtleXMpIHsKKyAgICAgICAgSFJlZ2lvbiByID0gdGhpcy5pbnN0YW5jZS5vbmxpbmVSZWdpb25zLmdldChpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBpZiAociAhPSBudWxsICYmIHIuaXNNYWpvckNvbXBhY3Rpb24oKSkgeworICAgICAgICAgICAgLy8gUXVldWUgYSBjb21wYWN0aW9uLiAgV2lsbCByZWNvZ25pemUgaWYgbWFqb3IgaXMgbmVlZGVkLgorICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5jb21wYWN0U3BsaXRUaHJlYWQuCisgICAgICAgICAgICAgIGNvbXBhY3Rpb25SZXF1ZXN0ZWQociwgZ2V0TmFtZSgpICsgIiByZXF1ZXN0cyBtYWpvciBjb21wYWN0aW9uIik7CisgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLndhcm4oIkZhaWxlZCBtYWpvciBjb21wYWN0aW9uIGNoZWNrIG9uICIgKyByLCBlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFNvLCBIREZTIGNhY2hlcyBGaWxlU3lzdGVtcyBzbyB3aGVuIHlvdSBjYWxsIEZpbGVTeXN0ZW0uZ2V0IGl0J3MgZmFzdC4gSW4KKyAgICogb3JkZXIgdG8gbWFrZSBzdXJlIHRoaW5ncyBhcmUgY2xlYW5lZCB1cCwgaXQgYWxzbyBjcmVhdGVzIGEgc2h1dGRvd24gaG9vaworICAgKiBzbyB0aGF0IGFsbCBmaWxlc3lzdGVtcyBjYW4gYmUgY2xvc2VkIHdoZW4gdGhlIHByb2Nlc3MgaXMgdGVybWluYXRlZC4gVGhpcworICAgKiBjb252ZW5pZW50bHkgcnVucyBjb25jdXJyZW50bHkgd2l0aCBvdXIgb3duIHNodXRkb3duIGhhbmRsZXIsIGFuZAorICAgKiB0aGVyZWZvcmUgY2F1c2VzIGFsbCB0aGUgZmlsZXN5c3RlbXMgdG8gYmUgY2xvc2VkIGJlZm9yZSB0aGUgc2VydmVyIGNhbiBkbworICAgKiBhbGwgaXRzIG5lY2Vzc2FyeSBjbGVhbnVwLgorICAgKgorICAgKiBUaGUgY3JhenkgZGlydHkgcmVmbGVjdGlvbiBpbiB0aGlzIG1ldGhvZCBzbmVha3MgaW50byB0aGUgRmlsZVN5c3RlbSBjYWNoZQorICAgKiBhbmQgZ3JhYnMgdGhlIHNodXRkb3duIGhvb2ssIHJlbW92ZXMgaXQgZnJvbSB0aGUgbGlzdCBvZiBhY3RpdmUgc2h1dGRvd24KKyAgICogaG9va3MsIGFuZCBoYW5ncyBvbnRvIGl0IHVudGlsIGxhdGVyLiBUaGVuLCBhZnRlciB3ZSdyZSBwcm9wZXJseSBkb25lIHdpdGgKKyAgICogb3VyIGdyYWNlZnVsIHNodXRkb3duLCB3ZSBjYW4gZXhlY3V0ZSB0aGUgaGRmcyBob29rIG1hbnVhbGx5IHRvIG1ha2Ugc3VyZQorICAgKiBsb29zZSBlbmRzIGFyZSB0aWVkIHVwLgorICAgKgorICAgKiBUaGlzIHNlZW1zIHF1aXRlIGZyYWdpbGUgYW5kIHN1c2NlcHRpYmxlIHRvIGJyZWFraW5nIGlmIEhhZG9vcCBjaGFuZ2VzCisgICAqIGFueXRoaW5nIGFib3V0IHRoZSB3YXkgdGhpcyBjbGVhbnVwIGlzIG1hbmFnZWQuIEtlZXAgYW4gZXllIG9uIHRoaW5ncy4KKyAgICovCisgIHByaXZhdGUgVGhyZWFkIHN1cHByZXNzSGRmc1NodXRkb3duSG9vaygpIHsKKyAgICB0cnkgeworICAgICAgRmllbGQgZmllbGQgPSBGaWxlU3lzdGVtLmNsYXNzLmdldERlY2xhcmVkRmllbGQgKCJjbGllbnRGaW5hbGl6ZXIiKTsKKyAgICAgIGZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7CisgICAgICBUaHJlYWQgaGRmc0NsaWVudEZpbmFsaXplciA9IChUaHJlYWQpZmllbGQuZ2V0KG51bGwpOworICAgICAgaWYgKGhkZnNDbGllbnRGaW5hbGl6ZXIgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiY2xpZW50IGZpbmFsaXplciBpcyBudWxsLCBjYW4ndCBzdXBwcmVzcyEiKTsKKyAgICAgIH0KKyAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLnJlbW92ZVNodXRkb3duSG9vayhoZGZzQ2xpZW50RmluYWxpemVyKTsKKyAgICAgIHJldHVybiBoZGZzQ2xpZW50RmluYWxpemVyOworICAgICAgCisgICAgfSBjYXRjaCAoTm9TdWNoRmllbGRFeGNlcHRpb24gbnNmZSkgeworICAgICAgTE9HLmZhdGFsKCJDb3VsZG4ndCBmaW5kIGZpZWxkICdjbGllbnRGaW5hbGl6ZXInIGluIEZpbGVTeXN0ZW0hIiwgbnNmZSk7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIHRvIHN1cHByZXNzIEhERlMgc2h1dGRvd24gaG9vayIpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gaWFlKSB7CisgICAgICBMT0cuZmF0YWwoIkNvdWxkbid0IGFjY2VzcyBmaWVsZCAnY2xpZW50RmluYWxpemVyJyBpbiBGaWxlU3lzdGVtISIsIGlhZSk7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIHRvIHN1cHByZXNzIEhERlMgc2h1dGRvd24gaG9vayIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXBvcnQgdGhlIHN0YXR1cyBvZiB0aGUgc2VydmVyLiBBIHNlcnZlciBpcyBvbmxpbmUgb25jZSBhbGwgdGhlIHN0YXJ0dXAgCisgICAqIGlzIGNvbXBsZXRlZCAoc2V0dGluZyB1cCBmaWxlc3lzdGVtLCBzdGFydGluZyBzZXJ2aWNlIHRocmVhZHMsIGV0Yy4pLiBUaGlzCisgICAqIG1ldGhvZCBpcyBkZXNpZ25lZCBtb3N0bHkgdG8gYmUgdXNlZnVsIGluIHRlc3RzLgorICAgKiBAcmV0dXJuIHRydWUgaWYgb25saW5lLCBmYWxzZSBpZiBub3QuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc09ubGluZSgpIHsKKyAgICByZXR1cm4gaXNPbmxpbmU7CisgIH0KKyAgICAKKyAgcHJpdmF0ZSBITG9nIHNldHVwSExvZygpIHRocm93cyBSZWdpb25TZXJ2ZXJSdW5uaW5nRXhjZXB0aW9uLAorICAgIElPRXhjZXB0aW9uIHsKKyAgICAKKyAgICBQYXRoIGxvZ2RpciA9IG5ldyBQYXRoKHJvb3REaXIsIEhMb2cuZ2V0SExvZ0RpcmVjdG9yeU5hbWUoc2VydmVySW5mbykpOworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgTE9HLmRlYnVnKCJMb2cgZGlyICIgKyBsb2dkaXIpOworICAgIH0KKyAgICBpZiAoZnMuZXhpc3RzKGxvZ2RpcikpIHsKKyAgICAgIHRocm93IG5ldyBSZWdpb25TZXJ2ZXJSdW5uaW5nRXhjZXB0aW9uKCJyZWdpb24gc2VydmVyIGFscmVhZHkgIiArCisgICAgICAgICJydW5uaW5nIGF0ICIgKyB0aGlzLnNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLnRvU3RyaW5nKCkgKworICAgICAgICAiIGJlY2F1c2UgbG9nZGlyICIgKyBsb2dkaXIudG9TdHJpbmcoKSArICIgZXhpc3RzIik7CisgICAgfQorICAgIEhMb2cgbmV3bG9nID0gbmV3IEhMb2coZnMsIGxvZ2RpciwgY29uZiwgbG9nUm9sbGVyKTsKKyAgICByZXR1cm4gbmV3bG9nOworICB9CisgIAorICAvKgorICAgKiBAcGFyYW0gaW50ZXJ2YWwgSW50ZXJ2YWwgc2luY2UgbGFzdCB0aW1lIG1ldHJpY3Mgd2VyZSBjYWxsZWQuCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBkb01ldHJpY3MoKSB7CisgICAgdGhpcy5tZXRyaWNzLnJlZ2lvbnMuc2V0KHRoaXMub25saW5lUmVnaW9ucy5zaXplKCkpOworICAgIHRoaXMubWV0cmljcy5pbmNyZW1lbnRSZXF1ZXN0cyh0aGlzLnJlcXVlc3RDb3VudC5nZXQoKSk7CisgICAgLy8gSXMgdGhpcyB0b28gZXhwZW5zaXZlIGV2ZXJ5IHRocmVlIHNlY29uZHMgZ2V0dGluZyBhIGxvY2sgb24gb25saW5lUmVnaW9ucworICAgIC8vIGFuZCB0aGVuIHBlciBzdG9yZSBjYXJyaWVkPyAgQ2FuIEkgbWFrZSBtZXRyaWNzIGJlIHNsb3BwaWVyIGFuZCBhdm9pZAorICAgIC8vIHRoZSBzeW5jaHJvbml6YXRpb25zPworICAgIGludCBzdG9yZXMgPSAwOworICAgIGludCBzdG9yZWZpbGVzID0gMDsKKyAgICBsb25nIG1lbWNhY2hlU2l6ZSA9IDA7CisgICAgbG9uZyBzdG9yZWZpbGVJbmRleFNpemUgPSAwOworICAgIHN5bmNocm9uaXplZCAodGhpcy5vbmxpbmVSZWdpb25zKSB7CisgICAgICBmb3IgKE1hcC5FbnRyeTxJbnRlZ2VyLCBIUmVnaW9uPiBlOiB0aGlzLm9ubGluZVJlZ2lvbnMuZW50cnlTZXQoKSkgeworICAgICAgICBIUmVnaW9uIHIgPSBlLmdldFZhbHVlKCk7CisgICAgICAgIG1lbWNhY2hlU2l6ZSArPSByLm1lbWNhY2hlU2l6ZS5nZXQoKTsKKyAgICAgICAgc3luY2hyb25pemVkIChyLnN0b3JlcykgeworICAgICAgICAgIHN0b3JlcyArPSByLnN0b3Jlcy5zaXplKCk7CisgICAgICAgICAgZm9yKE1hcC5FbnRyeTxieXRlIFtdLCBTdG9yZT4gZWU6IHIuc3RvcmVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgIFN0b3JlIHN0b3JlID0gZWUuZ2V0VmFsdWUoKTsgCisgICAgICAgICAgICBzdG9yZWZpbGVzICs9IHN0b3JlLmdldFN0b3JlZmlsZXNDb3VudCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgc3RvcmVmaWxlSW5kZXhTaXplICs9IHN0b3JlLmdldFN0b3JlZmlsZXNJbmRleFNpemUoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgIExPRy53YXJuKCJlcnJvciBnZXR0aW5nIHN0b3JlIGZpbGUgaW5kZXggc2l6ZSBmb3IgIiArIHN0b3JlICsKKyAgICAgICAgICAgICAgICAiOiAiICsgU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGV4KSk7ICAKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgdGhpcy5tZXRyaWNzLnN0b3Jlcy5zZXQoc3RvcmVzKTsKKyAgICB0aGlzLm1ldHJpY3Muc3RvcmVmaWxlcy5zZXQoc3RvcmVmaWxlcyk7CisgICAgdGhpcy5tZXRyaWNzLm1lbWNhY2hlU2l6ZU1CLnNldCgoaW50KShtZW1jYWNoZVNpemUvKDEwMjQqMTAyNCkpKTsKKyAgICB0aGlzLm1ldHJpY3Muc3RvcmVmaWxlSW5kZXhTaXplTUIuc2V0KChpbnQpKHN0b3JlZmlsZUluZGV4U2l6ZS8oMTAyNCoxMDI0KSkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmVnaW9uIHNlcnZlciBtZXRyaWNzIGluc3RhbmNlLgorICAgKi8KKyAgcHVibGljIFJlZ2lvblNlcnZlck1ldHJpY3MgZ2V0TWV0cmljcygpIHsKKyAgICByZXR1cm4gdGhpcy5tZXRyaWNzOworICB9CisKKyAgLyoKKyAgICogU3RhcnQgbWFpbnRhbmVuY2UgVGhyZWFkcywgU2VydmVyLCBXb3JrZXIgYW5kIGxlYXNlIGNoZWNrZXIgdGhyZWFkcy4KKyAgICogSW5zdGFsbCBhbiBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgdGhhdCBjYWxscyBhYm9ydCBvZiBSZWdpb25TZXJ2ZXIgaWYgd2UKKyAgICogZ2V0IGFuIHVuaGFuZGxlZCBleGNlcHRpb24uICBXZSBjYW5ub3Qgc2V0IHRoZSBoYW5kbGVyIG9uIGFsbCB0aHJlYWRzLgorICAgKiBTZXJ2ZXIncyBpbnRlcm5hbCBMaXN0ZW5lciB0aHJlYWQgaXMgb2ZmIGxpbWl0cy4gIEZvciBTZXJ2ZXIsIGlmIGFuIE9PTUUsCisgICAqIGl0IHdhaXRzIGEgd2hpbGUgdGhlbiByZXRyaWVzLiAgTWVhbnRpbWUsIGEgZmx1c2ggb3IgYSBjb21wYWN0aW9uIHRoYXQKKyAgICogdHJpZXMgdG8gcnVuIHNob3VsZCB0cmlnZ2VyIHNhbWUgY3JpdGljYWwgY29uZGl0aW9uIGFuZCB0aGUgc2h1dGRvd24gd2lsbAorICAgKiBydW4uICBPbiBpdHMgd2F5IG91dCwgdGhpcyBzZXJ2ZXIgd2lsbCBzaHV0IGRvd24gU2VydmVyLiAgTGVhc2VzIGFyZSBzb3J0CisgICAqIG9mIGluYmV0d2Vlbi4gSXQgaGFzIGFuIGludGVybmFsIHRocmVhZCB0aGF0IHdoaWxlIGl0IGluaGVyaXRzIGZyb20KKyAgICogQ2hvcmUsIGl0IGtlZXBzIGl0cyBvd24gaW50ZXJuYWwgc3RvcCBtZWNoYW5pc20gc28gbmVlZHMgdG8gYmUgc3RvcHBlZAorICAgKiBieSB0aGlzIGhvc3Rpbmcgc2VydmVyLiAgV29ya2VyIGxvZ3MgdGhlIGV4Y2VwdGlvbiBhbmQgZXhpdHMuCisgICAqLworICBwcml2YXRlIHZvaWQgc3RhcnRTZXJ2aWNlVGhyZWFkcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU3RyaW5nIG4gPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKTsKKyAgICBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgaGFuZGxlciA9IG5ldyBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoKSB7CisgICAgICBwdWJsaWMgdm9pZCB1bmNhdWdodEV4Y2VwdGlvbihUaHJlYWQgdCwgVGhyb3dhYmxlIGUpIHsKKyAgICAgICAgYWJvcnQoKTsKKyAgICAgICAgTE9HLmZhdGFsKCJTZXQgc3RvcCBmbGFnIGluICIgKyB0LmdldE5hbWUoKSwgZSk7CisgICAgICB9CisgICAgfTsKKyAgICBUaHJlYWRzLnNldERhZW1vblRocmVhZFJ1bm5pbmcodGhpcy5sb2dSb2xsZXIsIG4gKyAiLmxvZ1JvbGxlciIsCisgICAgICAgIGhhbmRsZXIpOworICAgIFRocmVhZHMuc2V0RGFlbW9uVGhyZWFkUnVubmluZyh0aGlzLmxvZ0ZsdXNoZXIsIG4gKyAiLmxvZ0ZsdXNoZXIiLAorICAgICAgICBoYW5kbGVyKTsKKyAgICBUaHJlYWRzLnNldERhZW1vblRocmVhZFJ1bm5pbmcodGhpcy5jYWNoZUZsdXNoZXIsIG4gKyAiLmNhY2hlRmx1c2hlciIsCisgICAgICBoYW5kbGVyKTsKKyAgICBUaHJlYWRzLnNldERhZW1vblRocmVhZFJ1bm5pbmcodGhpcy5jb21wYWN0U3BsaXRUaHJlYWQsIG4gKyAiLmNvbXBhY3RvciIsCisgICAgICAgIGhhbmRsZXIpOworICAgIFRocmVhZHMuc2V0RGFlbW9uVGhyZWFkUnVubmluZyh0aGlzLndvcmtlclRocmVhZCwgbiArICIud29ya2VyIiwgaGFuZGxlcik7CisgICAgVGhyZWFkcy5zZXREYWVtb25UaHJlYWRSdW5uaW5nKHRoaXMubWFqb3JDb21wYWN0aW9uQ2hlY2tlciwKKyAgICAgICAgbiArICIubWFqb3JDb21wYWN0aW9uQ2hlY2tlciIsIGhhbmRsZXIpOworICAgIAorICAgIC8vIExlYXNlcyBpcyBub3QgYSBUaHJlYWQuIEludGVybmFsbHkgaXQgcnVucyBhIGRhZW1vbiB0aHJlYWQuICBJZiBpdCBnZXRzCisgICAgLy8gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbiwgaXQgd2lsbCBqdXN0IGV4aXQuCisgICAgdGhpcy5sZWFzZXMuc2V0TmFtZShuICsgIi5sZWFzZUNoZWNrZXIiKTsKKyAgICB0aGlzLmxlYXNlcy5zdGFydCgpOworICAgIC8vIFB1dCB1cCBpbmZvIHNlcnZlci4KKyAgICBpbnQgcG9ydCA9IHRoaXMuY29uZi5nZXRJbnQoImhiYXNlLnJlZ2lvbnNlcnZlci5pbmZvLnBvcnQiLCA2MDAzMCk7CisgICAgLy8gLTEgaXMgZm9yIGRpc2FibGluZyBpbmZvIHNlcnZlcgorICAgIGlmIChwb3J0ID49IDApIHsKKyAgICAgIFN0cmluZyBhZGRyID0gdGhpcy5jb25mLmdldCgiaGJhc2UubWFzdGVyLmluZm8uYmluZEFkZHJlc3MiLCAiMC4wLjAuMCIpOworICAgICAgLy8gY2hlY2sgaWYgYXV0byBwb3J0IGJpbmQgZW5hYmxlZAorICAgICAgYm9vbGVhbiBhdXRvID0gdGhpcy5jb25mLmdldEJvb2xlYW4oImhiYXNlLnJlZ2lvbnNlcnZlci5pbmZvLnBvcnQuYXV0byIsCisgICAgICAgICAgZmFsc2UpOworICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICB0aGlzLmluZm9TZXJ2ZXIgPSBuZXcgSW5mb1NlcnZlcigicmVnaW9uc2VydmVyIiwgYWRkciwgcG9ydCwgZmFsc2UpOworICAgICAgICAgIHRoaXMuaW5mb1NlcnZlci5zZXRBdHRyaWJ1dGUoInJlZ2lvbnNlcnZlciIsIHRoaXMpOworICAgICAgICAgIHRoaXMuaW5mb1NlcnZlci5zdGFydCgpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9IGNhdGNoIChCaW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBpZiAoIWF1dG8peworICAgICAgICAgICAgLy8gYXV0byBiaW5kIGRpc2FibGVkIHRocm93IEJpbmRFeGNlcHRpb24KKyAgICAgICAgICAgIHRocm93IGU7CisgICAgICAgICAgfQorICAgICAgICAgIC8vIGF1dG8gYmluZCBlbmFibGVkLCB0cnkgdG8gdXNlIGFub3RoZXIgcG9ydAorICAgICAgICAgIExPRy5pbmZvKCJGYWlsZWQgYmluZGluZyBodHRwIGluZm8gc2VydmVyIHRvIHBvcnQ6ICIgKyBwb3J0KTsKKyAgICAgICAgICBwb3J0Kys7CisgICAgICAgICAgLy8gdXBkYXRlIEhSUyBzZXJ2ZXIgaW5mbworICAgICAgICAgIHNlcnZlckluZm8uc2V0SW5mb1BvcnQocG9ydCk7CisgICAgICAgIH0KKyAgICAgIH0gCisgICAgfQorCisgICAgLy8gU2V0IHVwIHRoZSBzYWZlIG1vZGUgaGFuZGxlciBpZiBzYWZlIG1vZGUgaGFzIGJlZW4gY29uZmlndXJlZC4KKyAgICBpZiAoIWNvbmYuZ2V0Qm9vbGVhbigiaGJhc2UucmVnaW9uc2VydmVyLnNhZmVtb2RlIiwgdHJ1ZSkpIHsKKyAgICAgIHNhZmVNb2RlLnNldChmYWxzZSk7CisgICAgICBjb21wYWN0U3BsaXRUaHJlYWQuc2V0TGltaXQoLTEpOworICAgICAgTE9HLmRlYnVnKCJza2lwcGluZyBzYWZlIG1vZGUiKTsKKyAgICB9IGVsc2UgeworICAgICAgdGhpcy5jb21wYWN0aW9uTGltaXRUaHJlYWQgPSBuZXcgQ29tcGFjdGlvbkxpbWl0VGhyZWFkKCk7CisgICAgICBUaHJlYWRzLnNldERhZW1vblRocmVhZFJ1bm5pbmcodGhpcy5jb21wYWN0aW9uTGltaXRUaHJlYWQsIG4gKyAiLnNhZmVNb2RlIiwKKyAgICAgICAgaGFuZGxlcik7CisgICAgfQorCisgICAgLy8gU3RhcnQgU2VydmVyLiAgVGhpcyBzZXJ2aWNlIGlzIGxpa2UgbGVhc2VzIGluIHRoYXQgaXQgaW50ZXJuYWxseSBydW5zCisgICAgLy8gYSB0aHJlYWQuCisgICAgdGhpcy5zZXJ2ZXIuc3RhcnQoKTsKKyAgICBMT0cuaW5mbygiSFJlZ2lvblNlcnZlciBzdGFydGVkIGF0OiAiICsKKyAgICAgICAgc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkudG9TdHJpbmcoKSk7CisgIH0KKworICAvKgorICAgKiBWZXJpZnkgdGhhdCBzZXJ2ZXIgaXMgaGVhbHRoeQorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGlzSGVhbHRoeSgpIHsKKyAgICBpZiAoIWZzT2spIHsKKyAgICAgIC8vIEZpbGUgc3lzdGVtIHByb2JsZW0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgLy8gVmVyaWZ5IHRoYXQgYWxsIHRocmVhZHMgYXJlIGFsaXZlCisgICAgaWYgKCEobGVhc2VzLmlzQWxpdmUoKSAmJiBjb21wYWN0U3BsaXRUaHJlYWQuaXNBbGl2ZSgpICYmCisgICAgICAgIGNhY2hlRmx1c2hlci5pc0FsaXZlKCkgJiYgbG9nUm9sbGVyLmlzQWxpdmUoKSAmJgorICAgICAgICB3b3JrZXJUaHJlYWQuaXNBbGl2ZSgpICYmIHRoaXMubWFqb3JDb21wYWN0aW9uQ2hlY2tlci5pc0FsaXZlKCkpKSB7CisgICAgICAvLyBPbmUgb3IgbW9yZSB0aHJlYWRzIGFyZSBubyBsb25nZXIgYWxpdmUgLSBzaHV0IGRvd24KKyAgICAgIHN0b3AoKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKgorICAgKiBSdW4gc29tZSBob3VzZWtlZXBpbmcgdGFza3MgYmVmb3JlIHdlIGdvIGludG8gJ2hpYmVybmF0aW9uJyBzbGVlcGluZyBhdAorICAgKiB0aGUgZW5kIG9mIHRoZSBtYWluIEhSZWdpb25TZXJ2ZXIgcnVuIGxvb3AuCisgICAqLworICBwcml2YXRlIHZvaWQgaG91c2VrZWVwaW5nKCkgeworICAgIC8vIElmIHRoZSB0b2RvIGxpc3QgaGFzID4gMCBtZXNzYWdlcywgaXRlcmF0ZSBsb29raW5nIGZvciBvcGVuIHJlZ2lvbgorICAgIC8vIG1lc3NhZ2VzLiBTZW5kIHRoZSBtYXN0ZXIgYSBtZXNzYWdlIHRoYXQgd2UncmUgd29ya2luZyBvbiBpdHMKKyAgICAvLyBwcm9jZXNzaW5nIHNvIGl0IGRvZXNuJ3QgYXNzaWduIHRoZSByZWdpb24gZWxzZXdoZXJlLgorICAgIGlmICh0aGlzLnRvRG8uaXNFbXB0eSgpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIC8vIFRoaXMgaXRlcmF0b3IgaXMgJ3NhZmUnLiAgV2UgYXJlIGd1YXJhbnRlZWQgYSB2aWV3IG9uIHN0YXRlIG9mIHRoZQorICAgIC8vIHF1ZXVlIGF0IHRpbWUgaXRlcmF0b3Igd2FzIHRha2VuIG91dC4gIEFwcGFyZW50bHkgZ29lcyBmcm9tIG9sZGVzdC4KKyAgICBmb3IgKFRvRG9FbnRyeSBlOiB0aGlzLnRvRG8pIHsKKyAgICAgIEhNc2cgbXNnID0gZS5tc2c7CisgICAgICBpZiAobXNnID09IG51bGwpIHsKKyAgICAgICAgTE9HLndhcm4oIk1lc3NhZ2UgaXMgZW1wdHk6ICIgKyBlKTsKKyAgICAgIH0KKyAgICAgIGlmIChlLm1zZy5pc1R5cGUoSE1zZy5UeXBlLk1TR19SRUdJT05fT1BFTikpIHsKKyAgICAgICAgYWRkUHJvY2Vzc2luZ01lc3NhZ2UoZS5tc2cuZ2V0UmVnaW9uSW5mbygpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKiogQHJldHVybiB0aGUgSExvZyAqLworICBITG9nIGdldExvZygpIHsKKyAgICByZXR1cm4gdGhpcy5sb2c7CisgIH0KKworICAvKioKKyAgICogU2V0cyBhIGZsYWcgdGhhdCB3aWxsIGNhdXNlIGFsbCB0aGUgSFJlZ2lvblNlcnZlciB0aHJlYWRzIHRvIHNodXQgZG93bgorICAgKiBpbiBhbiBvcmRlcmx5IGZhc2hpb24uICBVc2VkIGJ5IHVuaXQgdGVzdHMuCisgICAqLworICBwdWJsaWMgdm9pZCBzdG9wKCkgeworICAgIHRoaXMuc3RvcFJlcXVlc3RlZC5zZXQodHJ1ZSk7CisgICAgc3luY2hyb25pemVkKHRoaXMpIHsKKyAgICAgIG5vdGlmeUFsbCgpOyAvLyBXYWtlcyBydW4oKSBpZiBpdCBpcyBzbGVlcGluZworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIENhdXNlIHRoZSBzZXJ2ZXIgdG8gZXhpdCB3aXRob3V0IGNsb3NpbmcgdGhlIHJlZ2lvbnMgaXQgaXMgc2VydmluZywgdGhlCisgICAqIGxvZyBpdCBpcyB1c2luZyBhbmQgd2l0aG91dCBub3RpZnlpbmcgdGhlIG1hc3Rlci4KKyAgICogVXNlZCB1bml0IHRlc3RpbmcgYW5kIG9uIGNhdGFzdHJvcGhpYyBldmVudHMgc3VjaCBhcyBIREZTIGlzIHlhbmtlZCBvdXQKKyAgICogZnJvbSB1bmRlciBoYmFzZSBvciB3ZSBPT01FLgorICAgKi8KKyAgcHVibGljIHZvaWQgYWJvcnQoKSB7CisgICAgdGhpcy5hYm9ydFJlcXVlc3RlZCA9IHRydWU7CisgICAgdGhpcy5yZXNlcnZlZFNwYWNlLmNsZWFyKCk7CisgICAgTE9HLmluZm8oIkR1bXAgb2YgbWV0cmljczogIiArIHRoaXMubWV0cmljcy50b1N0cmluZygpKTsKKyAgICBzdG9wKCk7CisgIH0KKworICAvKiogCisgICAqIFdhaXQgb24gYWxsIHRocmVhZHMgdG8gZmluaXNoLgorICAgKiBQcmVzdW1wdGlvbiBpcyB0aGF0IGFsbCBjbG9zZXMgYW5kIHN0b3BzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZC4KKyAgICovCisgIHZvaWQgam9pbigpIHsKKyAgICBUaHJlYWRzLnNodXRkb3duKHRoaXMubWFqb3JDb21wYWN0aW9uQ2hlY2tlcik7CisgICAgVGhyZWFkcy5zaHV0ZG93bih0aGlzLndvcmtlclRocmVhZCk7CisgICAgVGhyZWFkcy5zaHV0ZG93bih0aGlzLmNhY2hlRmx1c2hlcik7CisgICAgVGhyZWFkcy5zaHV0ZG93bih0aGlzLmNvbXBhY3RTcGxpdFRocmVhZCk7CisgICAgVGhyZWFkcy5zaHV0ZG93bih0aGlzLmxvZ1JvbGxlcik7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gZ2V0TWFzdGVyKCkgeworICAgIEhTZXJ2ZXJBZGRyZXNzIG1hc3RlckFkZHJlc3MgPSBudWxsOworICAgIHdoaWxlIChtYXN0ZXJBZGRyZXNzID09IG51bGwpIHsKKyAgICAgIGlmIChzdG9wUmVxdWVzdGVkLmdldCgpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIG1hc3RlckFkZHJlc3MgPSB6b29LZWVwZXJXcmFwcGVyLnJlYWRNYXN0ZXJBZGRyZXNzT3JUaHJvdygpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cud2FybigiVW5hYmxlIHRvIHJlYWQgbWFzdGVyIGFkZHJlc3MgZnJvbSBab29LZWVwZXIuIFJldHJ5aW5nLiIgKworICAgICAgICAgICAgICAgICAiIEVycm9yIHdhczoiLCBlKTsKKyAgICAgICAgc2xlZXBlci5zbGVlcCgpOworICAgICAgfQorICAgIH0KKworICAgIExPRy5pbmZvKCJUZWxsaW5nIG1hc3RlciBhdCAiICsgbWFzdGVyQWRkcmVzcyArICIgdGhhdCB3ZSBhcmUgdXAiKTsKKyAgICBITWFzdGVyUmVnaW9uSW50ZXJmYWNlIG1hc3RlciA9IG51bGw7CisgICAgd2hpbGUgKCFzdG9wUmVxdWVzdGVkLmdldCgpICYmIG1hc3RlciA9PSBudWxsKSB7CisgICAgICB0cnkgeworICAgICAgICAvLyBEbyBpbml0aWFsIFJQQyBzZXR1cC4gIFRoZSBmaW5hbCBhcmd1bWVudCBpbmRpY2F0ZXMgdGhhdCB0aGUgUlBDCisgICAgICAgIC8vIHNob3VsZCByZXRyeSBpbmRlZmluaXRlbHkuCisgICAgICAgIG1hc3RlciA9IChITWFzdGVyUmVnaW9uSW50ZXJmYWNlKUhCYXNlUlBDLndhaXRGb3JQcm94eSgKKyAgICAgICAgICAgIEhNYXN0ZXJSZWdpb25JbnRlcmZhY2UuY2xhc3MsIEhCYXNlUlBDUHJvdG9jb2xWZXJzaW9uLnZlcnNpb25JRCwKKyAgICAgICAgICAgIG1hc3RlckFkZHJlc3MuZ2V0SW5ldFNvY2tldEFkZHJlc3MoKSwKKyAgICAgICAgICAgIHRoaXMuY29uZiwgLTEsIHRoaXMucnBjVGltZW91dCk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy53YXJuKCJVbmFibGUgdG8gY29ubmVjdCB0byBtYXN0ZXIuIFJldHJ5aW5nLiBFcnJvciB3YXM6IiwgZSk7CisgICAgICAgIHNsZWVwZXIuc2xlZXAoKTsKKyAgICAgIH0KKyAgICB9CisgICAgdGhpcy5oYmFzZU1hc3RlciA9IG1hc3RlcjsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qCisgICAqIExldCB0aGUgbWFzdGVyIGtub3cgd2UncmUgaGVyZQorICAgKiBSdW4gaW5pdGlhbGl6YXRpb24gdXNpbmcgcGFyYW1ldGVycyBwYXNzZWQgdXMgYnkgdGhlIG1hc3Rlci4KKyAgICovCisgIHByaXZhdGUgTWFwV3JpdGFibGUgcmVwb3J0Rm9yRHV0eSgpIHsKKyAgICBpZiAoIWdldE1hc3RlcigpKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgTWFwV3JpdGFibGUgcmVzdWx0ID0gbnVsbDsKKyAgICBsb25nIGxhc3RNc2cgPSAwOworICAgIHdoaWxlKCFzdG9wUmVxdWVzdGVkLmdldCgpKSB7CisgICAgICB0cnkgeworICAgICAgICB0aGlzLnJlcXVlc3RDb3VudC5zZXQoMCk7CisgICAgICAgIE1lbW9yeVVzYWdlIG1lbW9yeSA9CisgICAgICAgICAgTWFuYWdlbWVudEZhY3RvcnkuZ2V0TWVtb3J5TVhCZWFuKCkuZ2V0SGVhcE1lbW9yeVVzYWdlKCk7CisgICAgICAgIEhTZXJ2ZXJMb2FkIGhzbCA9IG5ldyBIU2VydmVyTG9hZCgwLCAoaW50KW1lbW9yeS5nZXRVc2VkKCkvMTAyNC8xMDI0LAorICAgICAgICAgIChpbnQpbWVtb3J5LmdldE1heCgpLzEwMjQvMTAyNCk7CisgICAgICAgIHRoaXMuc2VydmVySW5mby5zZXRMb2FkKGhzbCk7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkKKyAgICAgICAgICBMT0cuZGVidWcoInNlbmRpbmcgaW5pdGlhbCBzZXJ2ZXIgbG9hZDogIiArIGhzbCk7CisgICAgICAgIGxhc3RNc2cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgICAgcmVzdWx0ID0gdGhpcy5oYmFzZU1hc3Rlci5yZWdpb25TZXJ2ZXJTdGFydHVwKHNlcnZlckluZm8pOworICAgICAgICBicmVhazsKKyAgICAgIH0gY2F0Y2ggKExlYXNlcy5MZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5pbmZvKCJMZWFzZSAiICsgZS5nZXROYW1lKCkgKyAiIGFscmVhZHkgaGVsZCBvbiBtYXN0ZXIuIENoZWNrICIgKworICAgICAgICAgICJETlMgY29uZmlndXJhdGlvbiBzbyB0aGF0IGFsbCByZWdpb24gc2VydmVycyBhcmUiICsKKyAgICAgICAgICAicmVwb3J0aW5nIHRoZWlyIHRydWUgSVBzIGFuZCBub3QgMTI3LjAuMC4xLiBPdGhlcndpc2UsIHRoaXMiICsKKyAgICAgICAgICAicHJvYmxlbSBzaG91bGQgcmVzb2x2ZSBpdHNlbGYgYWZ0ZXIgdGhlIGxlYXNlIHBlcmlvZCBvZiAiICsKKyAgICAgICAgICB0aGlzLmNvbmYuZ2V0KCJoYmFzZS5tYXN0ZXIubGVhc2UucGVyaW9kIikKKyAgICAgICAgICArICIgc2Vjb25kcyBleHBpcmVzIG92ZXIgb24gdGhlIG1hc3RlciIpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cud2FybigiZXJyb3IgdGVsbGluZyBtYXN0ZXIgd2UgYXJlIHVwIiwgZSk7CisgICAgICB9CisgICAgICBzbGVlcGVyLnNsZWVwKGxhc3RNc2cpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyogQWRkIHRvIHRoZSBvdXRib3VuZCBtZXNzYWdlIGJ1ZmZlciAqLworICBwcml2YXRlIHZvaWQgcmVwb3J0T3BlbihIUmVnaW9uSW5mbyByZWdpb24pIHsKKyAgICBvdXRib3VuZE1zZ3MuYWRkKG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVQT1JUX09QRU4sIHJlZ2lvbikpOworICB9CisKKyAgLyogQWRkIHRvIHRoZSBvdXRib3VuZCBtZXNzYWdlIGJ1ZmZlciAqLworICBwcml2YXRlIHZvaWQgcmVwb3J0Q2xvc2UoSFJlZ2lvbkluZm8gcmVnaW9uKSB7CisgICAgcmVwb3J0Q2xvc2UocmVnaW9uLCBudWxsKTsKKyAgfQorCisgIC8qIEFkZCB0byB0aGUgb3V0Ym91bmQgbWVzc2FnZSBidWZmZXIgKi8KKyAgcHJpdmF0ZSB2b2lkIHJlcG9ydENsb3NlKGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbiwgZmluYWwgYnl0ZVtdIG1lc3NhZ2UpIHsKKyAgICBvdXRib3VuZE1zZ3MuYWRkKG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVQT1JUX0NMT1NFLCByZWdpb24sIG1lc3NhZ2UpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEFkZCB0byB0aGUgb3V0Ym91bmQgbWVzc2FnZSBidWZmZXIKKyAgICogCisgICAqIFdoZW4gYSByZWdpb24gc3BsaXRzLCB3ZSBuZWVkIHRvIHRlbGwgdGhlIG1hc3RlciB0aGF0IHRoZXJlIGFyZSB0d28gbmV3IAorICAgKiByZWdpb25zIHRoYXQgbmVlZCB0byBiZSBhc3NpZ25lZC4KKyAgICogCisgICAqIFdlIGRvIG5vdCBuZWVkIHRvIGluZm9ybSB0aGUgbWFzdGVyIGFib3V0IHRoZSBvbGQgcmVnaW9uLCBiZWNhdXNlIHdlJ3ZlCisgICAqIHVwZGF0ZWQgdGhlIG1ldGEgb3Igcm9vdCByZWdpb25zLCBhbmQgdGhlIG1hc3RlciB3aWxsIHBpY2sgdGhhdCB1cCBvbiBpdHMKKyAgICogbmV4dCByZXNjYW4gb2YgdGhlIHJvb3Qgb3IgbWV0YSB0YWJsZXMuCisgICAqLworICB2b2lkIHJlcG9ydFNwbGl0KEhSZWdpb25JbmZvIG9sZFJlZ2lvbiwgSFJlZ2lvbkluZm8gbmV3UmVnaW9uQSwKKyAgICAgIEhSZWdpb25JbmZvIG5ld1JlZ2lvbkIpIHsKKyAgICBvdXRib3VuZE1zZ3MuYWRkKG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVQT1JUX1NQTElULCBvbGRSZWdpb24sCisgICAgICAoIkRhdWdodGVyczsgIiArCisgICAgICAgIG5ld1JlZ2lvbkEuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKyAiLCAiICsKKyAgICAgICAgbmV3UmVnaW9uQi5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSkuZ2V0Qnl0ZXMoKSkpOworICAgIG91dGJvdW5kTXNncy5hZGQobmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRVBPUlRfT1BFTiwgbmV3UmVnaW9uQSkpOworICAgIG91dGJvdW5kTXNncy5hZGQobmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRVBPUlRfT1BFTiwgbmV3UmVnaW9uQikpOworICB9CisKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIEhNYXN0ZXItZ2l2ZW4gb3BlcmF0aW9ucworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICAvKgorICAgKiBEYXRhIHN0cnVjdHVyZSB0byBob2xkIGEgSE1zZyBhbmQgcmV0cmllcyBjb3VudC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFRvRG9FbnRyeSB7CisgICAgcHJvdGVjdGVkIHZvbGF0aWxlIGludCB0cmllczsKKyAgICBwcm90ZWN0ZWQgZmluYWwgSE1zZyBtc2c7CisKKyAgICBUb0RvRW50cnkoZmluYWwgSE1zZyBtc2cpIHsKKyAgICAgIHRoaXMudHJpZXMgPSAwOworICAgICAgdGhpcy5tc2cgPSBtc2c7CisgICAgfQorICB9CisKKyAgZmluYWwgQmxvY2tpbmdRdWV1ZTxUb0RvRW50cnk+IHRvRG8gPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxUb0RvRW50cnk+KCk7CisgIHByaXZhdGUgV29ya2VyIHdvcmtlcjsKKyAgcHJpdmF0ZSBUaHJlYWQgd29ya2VyVGhyZWFkOworICAKKyAgLyoqIFRocmVhZCB0aGF0IHBlcmZvcm1zIGxvbmcgcnVubmluZyByZXF1ZXN0cyBmcm9tIHRoZSBtYXN0ZXIgKi8KKyAgY2xhc3MgV29ya2VyIGltcGxlbWVudHMgUnVubmFibGUgeworICAgIHZvaWQgc3RvcCgpIHsKKyAgICAgIHN5bmNocm9uaXplZCh0b0RvKSB7CisgICAgICAgIHRvRG8ubm90aWZ5QWxsKCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHdoaWxlKCFzdG9wUmVxdWVzdGVkLmdldCgpKSB7CisgICAgICAgICAgVG9Eb0VudHJ5IGUgPSBudWxsOworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBlID0gdG9Eby5wb2xsKHRocmVhZFdha2VGcmVxdWVuY3ksIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisgICAgICAgICAgICBpZihlID09IG51bGwgfHwgc3RvcFJlcXVlc3RlZC5nZXQoKSkgeworICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIExPRy5pbmZvKCJXb3JrZXI6ICIgKyBlLm1zZyk7CisgICAgICAgICAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgICAgICAgICBIUmVnaW9uSW5mbyBpbmZvID0gZS5tc2cuZ2V0UmVnaW9uSW5mbygpOworICAgICAgICAgICAgc3dpdGNoKGUubXNnLmdldFR5cGUoKSkgeworCisgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05TRVJWRVJfUVVJRVNDRToKKyAgICAgICAgICAgICAgY2xvc2VVc2VyUmVnaW9ucygpOworICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBNU0dfUkVHSU9OX09QRU46CisgICAgICAgICAgICAgIC8vIE9wZW4gYSByZWdpb24KKyAgICAgICAgICAgICAgaWYgKCFoYXZlUm9vdFJlZ2lvbi5nZXQoKSAmJiAhaW5mby5pc1Jvb3RSZWdpb24oKSkgeworICAgICAgICAgICAgICAgIC8vIHJvb3QgcmVnaW9uIGlzIG5vdCBvbmxpbmUgeWV0LiByZXF1ZXVlIHRoaXMgdGFzaworICAgICAgICAgICAgICAgIExPRy5pbmZvKCJwdXR0aW5nIHJlZ2lvbiBvcGVuIHJlcXVlc3QgYmFjayBpbnRvIHF1ZXVlIGJlY2F1c2UiICsKKyAgICAgICAgICAgICAgICAgICAgIiByb290IHJlZ2lvbiBpcyBub3QgeWV0IGF2YWlsYWJsZSIpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICB0b0RvLnB1dChlKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgICAgICAgTE9HLndhcm4oImluc2VydGlvbiBpbnRvIHRvRG8gcXVldWUgd2FzIGludGVycnVwdGVkIiwgZXgpOworICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIG9wZW5SZWdpb24oaW5mbyk7CisgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05fQ0xPU0U6CisgICAgICAgICAgICAgIC8vIENsb3NlIGEgcmVnaW9uCisgICAgICAgICAgICAgIGNsb3NlUmVnaW9uKGUubXNnLmdldFJlZ2lvbkluZm8oKSwgdHJ1ZSk7CisgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05fQ0xPU0VfV0lUSE9VVF9SRVBPUlQ6CisgICAgICAgICAgICAgIC8vIENsb3NlIGEgcmVnaW9uLCBkb24ndCByZXBseQorICAgICAgICAgICAgICBjbG9zZVJlZ2lvbihlLm1zZy5nZXRSZWdpb25JbmZvKCksIGZhbHNlKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTVNHX1JFR0lPTl9TUExJVDoKKyAgICAgICAgICAgICAgcmVnaW9uID0gZ2V0UmVnaW9uKGluZm8uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICAgICAgICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICAgICAgICAgICAgcmVnaW9uLnJlZ2lvbkluZm8uc2hvdWxkU3BsaXQodHJ1ZSk7CisgICAgICAgICAgICAgIC8vIGZvcmNlIGEgY29tcGFjdGlvbjsgc3BsaXQgd2lsbCBiZSBzaWRlLWVmZmVjdC4KKyAgICAgICAgICAgICAgY29tcGFjdFNwbGl0VGhyZWFkLmNvbXBhY3Rpb25SZXF1ZXN0ZWQocmVnaW9uLAorICAgICAgICAgICAgICAgIGUubXNnLmdldFR5cGUoKS5uYW1lKCkpOworICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBNU0dfUkVHSU9OX01BSk9SX0NPTVBBQ1Q6CisgICAgICAgICAgICBjYXNlIE1TR19SRUdJT05fQ09NUEFDVDoKKyAgICAgICAgICAgICAgLy8gQ29tcGFjdCBhIHJlZ2lvbgorICAgICAgICAgICAgICByZWdpb24gPSBnZXRSZWdpb24oaW5mby5nZXRSZWdpb25OYW1lKCkpOworICAgICAgICAgICAgICBjb21wYWN0U3BsaXRUaHJlYWQuY29tcGFjdGlvblJlcXVlc3RlZChyZWdpb24sCisgICAgICAgICAgICAgICAgZS5tc2cuaXNUeXBlKFR5cGUuTVNHX1JFR0lPTl9NQUpPUl9DT01QQUNUKSwKKyAgICAgICAgICAgICAgICBlLm1zZy5nZXRUeXBlKCkubmFtZSgpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgIAorICAgICAgICAgICAgY2FzZSBNU0dfUkVHSU9OX0ZMVVNIOgorICAgICAgICAgICAgICByZWdpb24gPSBnZXRSZWdpb24oaW5mby5nZXRSZWdpb25OYW1lKCkpOworICAgICAgICAgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoCisgICAgICAgICAgICAgICAgICAiSW1wb3NzaWJsZSBzdGF0ZSBkdXJpbmcgbXNnIHByb2Nlc3NpbmcuICBJbnN0cnVjdGlvbjogIgorICAgICAgICAgICAgICAgICAgKyBlLm1zZy50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgICAgICAgIGV4ID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKChJT0V4Y2VwdGlvbikgZXgpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYoZSAhPSBudWxsICYmIGUudHJpZXMgPCBudW1SZXRyaWVzKSB7CisgICAgICAgICAgICAgIExPRy53YXJuKGV4KTsKKyAgICAgICAgICAgICAgZS50cmllcysrOworICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRvRG8ucHV0KGUpOworICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJQdXR0aW5nIGludG8gbXNnUXVldWUgd2FzICIgKworICAgICAgICAgICAgICAgICAgICAiaW50ZXJydXB0ZWQuIiwgZXgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMT0cuZXJyb3IoInVuYWJsZSB0byBwcm9jZXNzIG1lc3NhZ2UiICsKKyAgICAgICAgICAgICAgICAgIChlICE9IG51bGwgPyAoIjogIiArIGUubXNnLnRvU3RyaW5nKCkpIDogIiIpLCBleCk7CisgICAgICAgICAgICAgIGlmICghY2hlY2tGaWxlU3lzdGVtKCkpIHsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBjYXRjaChUaHJvd2FibGUgdCkgeworICAgICAgICBpZiAoIWNoZWNrT09NRSh0KSkgeworICAgICAgICAgIExPRy5mYXRhbCgiVW5oYW5kbGVkIGV4Y2VwdGlvbiIsIHQpOworICAgICAgICB9CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBMT0cuaW5mbygid29ya2VyIHRocmVhZCBleGl0aW5nIik7CisgICAgICB9CisgICAgfQorICB9CisgIAorICB2b2lkIG9wZW5SZWdpb24oZmluYWwgSFJlZ2lvbkluZm8gcmVnaW9uSW5mbykgeworICAgIC8vIElmIGhpc3RvcmlhbiBpcyBub3Qgb25saW5lIGFuZCB0aGlzIGlzIG5vdCBhIG1ldGEgcmVnaW9uLCBvbmxpbmUgaXQuCisgICAgaWYgKCFyZWdpb25JbmZvLmlzTWV0YVJlZ2lvbigpICYmCisgICAgICAgICFSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKS5pc09ubGluZSgpKSB7CisgICAgICBSZWdpb25IaXN0b3JpYW4uZ2V0SW5zdGFuY2UoKS5vbmxpbmUodGhpcy5jb25mKTsKKyAgICB9CisgICAgSW50ZWdlciBtYXBLZXkgPSBCeXRlcy5tYXBLZXkocmVnaW9uSW5mby5nZXRSZWdpb25OYW1lKCkpOworICAgIEhSZWdpb24gcmVnaW9uID0gdGhpcy5vbmxpbmVSZWdpb25zLmdldChtYXBLZXkpOworICAgIGlmIChyZWdpb24gPT0gbnVsbCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgcmVnaW9uID0gaW5zdGFudGlhdGVSZWdpb24ocmVnaW9uSW5mbyk7CisgICAgICAgIC8vIFN0YXJ0dXAgYSBjb21wYWN0aW9uIGVhcmx5IGlmIG9uZSBpcyBuZWVkZWQuCisgICAgICAgIHRoaXMuY29tcGFjdFNwbGl0VGhyZWFkLgorICAgICAgICAgIGNvbXBhY3Rpb25SZXF1ZXN0ZWQocmVnaW9uLCAiUmVnaW9uIG9wZW4gY2hlY2siKTsKKyAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CisgICAgICAgIFRocm93YWJsZSB0ID0gY2xlYW51cChlLAorICAgICAgICAgICJFcnJvciBvcGVuaW5nICIgKyByZWdpb25JbmZvLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgICAgLy8gVE9ETzogYWRkIGFuIGV4dHJhIGZpZWxkIGluIEhSZWdpb25JbmZvIHRvIGluZGljYXRlIHRoYXQgdGhlcmUgaXMKKyAgICAgICAgLy8gYW4gZXJyb3IuIFdlIGNhbid0IGRvIHRoYXQgbm93IGJlY2F1c2UgdGhhdCB3b3VsZCBiZSBhbiBpbmNvbXBhdGlibGUKKyAgICAgICAgLy8gY2hhbmdlIHRoYXQgd291bGQgcmVxdWlyZSBhIG1pZ3JhdGlvbgorICAgICAgICByZXBvcnRDbG9zZShyZWdpb25JbmZvLCBTdHJpbmdVdGlscy5zdHJpbmdpZnlFeGNlcHRpb24odCkuZ2V0Qnl0ZXMoKSk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIHRoaXMubG9jay53cml0ZUxvY2soKS5sb2NrKCk7CisgICAgICB0cnkgeworICAgICAgICB0aGlzLmxvZy5zZXRTZXF1ZW5jZU51bWJlcihyZWdpb24uZ2V0TWluU2VxdWVuY2VJZCgpKTsKKyAgICAgICAgdGhpcy5vbmxpbmVSZWdpb25zLnB1dChtYXBLZXksIHJlZ2lvbik7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkudW5sb2NrKCk7CisgICAgICB9CisgICAgfQorICAgIHJlcG9ydE9wZW4ocmVnaW9uSW5mbyk7IAorICB9CisgIAorICBwcm90ZWN0ZWQgSFJlZ2lvbiBpbnN0YW50aWF0ZVJlZ2lvbihmaW5hbCBIUmVnaW9uSW5mbyByZWdpb25JbmZvKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHIgPSBuZXcgSFJlZ2lvbihIVGFibGVEZXNjcmlwdG9yLmdldFRhYmxlRGlyKHJvb3REaXIsIHJlZ2lvbkluZm8KKyAgICAgICAgLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSksIHRoaXMubG9nLCB0aGlzLmZzLCBjb25mLCByZWdpb25JbmZvLAorICAgICAgICB0aGlzLmNhY2hlRmx1c2hlcik7CisgICAgci5pbml0aWFsaXplKG51bGwsICBuZXcgUHJvZ3Jlc3NhYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcHJvZ3Jlc3MoKSB7CisgICAgICAgIGFkZFByb2Nlc3NpbmdNZXNzYWdlKHJlZ2lvbkluZm8pOworICAgICAgfQorICAgIH0pOworICAgIHJldHVybiByOyAKKyAgfQorICAKKyAgLyoqCisgICAqIEFkZCBhIE1TR19SRVBPUlRfUFJPQ0VTU19PUEVOIHRvIHRoZSBvdXRib3VuZCBxdWV1ZS4KKyAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoaWxlIHJlZ2lvbiBpcyBpbiB0aGUgcXVldWUgb2YgcmVnaW9ucyB0byBwcm9jZXNzCisgICAqIGFuZCB0aGVuIHdoaWxlIHRoZSByZWdpb24gaXMgYmVpbmcgb3BlbmVkLCBpdCBpcyBjYWxsZWQgZnJvbSB0aGUgV29ya2VyCisgICAqIHRocmVhZCB0aGF0IGlzIHJ1bm5pbmcgdGhlIHJlZ2lvbiBvcGVuLgorICAgKiBAcGFyYW0gaHJpIFJlZ2lvbiB0byBhZGQgdGhlIG1lc3NhZ2UgZm9yCisgICAqLworICBwdWJsaWMgdm9pZCBhZGRQcm9jZXNzaW5nTWVzc2FnZShmaW5hbCBIUmVnaW9uSW5mbyBocmkpIHsKKyAgICBnZXRPdXRib3VuZE1zZ3MoKS5hZGQobmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRVBPUlRfUFJPQ0VTU19PUEVOLCBocmkpKTsKKyAgfQorCisgIHZvaWQgY2xvc2VSZWdpb24oZmluYWwgSFJlZ2lvbkluZm8gaHJpLCBmaW5hbCBib29sZWFuIHJlcG9ydFdoZW5Db21wbGV0ZWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByZWdpb24gPSB0aGlzLnJlbW92ZUZyb21PbmxpbmVSZWdpb25zKGhyaSk7CisgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICByZWdpb24uY2xvc2UoKTsKKyAgICAgIGlmKHJlcG9ydFdoZW5Db21wbGV0ZWQpIHsKKyAgICAgICAgcmVwb3J0Q2xvc2UoaHJpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKiogQ2FsbGVkIGVpdGhlciB3aGVuIHRoZSBtYXN0ZXIgdGVsbHMgdXMgdG8gcmVzdGFydCBvciBmcm9tIHN0b3AoKSAqLworICBBcnJheUxpc3Q8SFJlZ2lvbj4gY2xvc2VBbGxSZWdpb25zKCkgeworICAgIEFycmF5TGlzdDxIUmVnaW9uPiByZWdpb25zVG9DbG9zZSA9IG5ldyBBcnJheUxpc3Q8SFJlZ2lvbj4oKTsKKyAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICByZWdpb25zVG9DbG9zZS5hZGRBbGwob25saW5lUmVnaW9ucy52YWx1ZXMoKSk7CisgICAgICBvbmxpbmVSZWdpb25zLmNsZWFyKCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay53cml0ZUxvY2soKS51bmxvY2soKTsKKyAgICB9CisgICAgZm9yKEhSZWdpb24gcmVnaW9uOiByZWdpb25zVG9DbG9zZSkgeworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiY2xvc2luZyByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbi5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIHJlZ2lvbi5jbG9zZShhYm9ydFJlcXVlc3RlZCk7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICBjbGVhbnVwKGUsICJFcnJvciBjbG9zaW5nICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb24uZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZWdpb25zVG9DbG9zZTsKKyAgfQorICAKKyAgLyoKKyAgICogVGhyZWFkIHRvIHJ1biBjbG9zZSBvZiBhIHJlZ2lvbi4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFJlZ2lvbkNsb3NlclRocmVhZCBleHRlbmRzIFRocmVhZCB7CisgICAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uIHI7CisKKyAgICBwcm90ZWN0ZWQgUmVnaW9uQ2xvc2VyVGhyZWFkKGZpbmFsIEhSZWdpb24gcikgeworICAgICAgc3VwZXIoVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkgKyAiLnJlZ2lvbkNsb3Nlci4iICsgci50b1N0cmluZygpKTsKKyAgICAgIHRoaXMuciA9IHI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJDbG9zaW5nIHJlZ2lvbiAiICsgci50b1N0cmluZygpKTsKKyAgICAgICAgfQorICAgICAgICByLmNsb3NlKCk7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgZSkgeworICAgICAgICBMT0cuZXJyb3IoIkVycm9yIGNsb3NpbmcgcmVnaW9uICIgKyByLnRvU3RyaW5nKCksCisgICAgICAgICAgUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja1Rocm93YWJsZShlKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIENhbGxlZCBhcyB0aGUgZmlyc3Qgc3RhZ2Ugb2YgY2x1c3RlciBzaHV0ZG93bi4gKi8KKyAgdm9pZCBjbG9zZVVzZXJSZWdpb25zKCkgeworICAgIEFycmF5TGlzdDxIUmVnaW9uPiByZWdpb25zVG9DbG9zZSA9IG5ldyBBcnJheUxpc3Q8SFJlZ2lvbj4oKTsKKyAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBzeW5jaHJvbml6ZWQgKG9ubGluZVJlZ2lvbnMpIHsKKyAgICAgICAgZm9yIChJdGVyYXRvcjxNYXAuRW50cnk8SW50ZWdlciwgSFJlZ2lvbj4+IGkgPQorICAgICAgICAgICAgb25saW5lUmVnaW9ucy5lbnRyeVNldCgpLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgeworICAgICAgICAgIE1hcC5FbnRyeTxJbnRlZ2VyLCBIUmVnaW9uPiBlID0gaS5uZXh0KCk7CisgICAgICAgICAgSFJlZ2lvbiByID0gZS5nZXRWYWx1ZSgpOworICAgICAgICAgIGlmICghci5nZXRSZWdpb25JbmZvKCkuaXNNZXRhUmVnaW9uKCkpIHsKKyAgICAgICAgICAgIHJlZ2lvbnNUb0Nsb3NlLmFkZChyKTsKKyAgICAgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay53cml0ZUxvY2soKS51bmxvY2soKTsKKyAgICB9CisgICAgLy8gUnVuIHJlZ2lvbiBjbG9zZXMgaW4gcGFyYWxsZWwuCisgICAgU2V0PFRocmVhZD4gdGhyZWFkcyA9IG5ldyBIYXNoU2V0PFRocmVhZD4oKTsKKyAgICB0cnkgeworICAgICAgZm9yIChmaW5hbCBIUmVnaW9uIHIgOiByZWdpb25zVG9DbG9zZSkgeworICAgICAgICBSZWdpb25DbG9zZXJUaHJlYWQgdCA9IG5ldyBSZWdpb25DbG9zZXJUaHJlYWQocik7CisgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgdGhyZWFkcy5hZGQodCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGZvciAoVGhyZWFkIHQgOiB0aHJlYWRzKSB7CisgICAgICAgIHdoaWxlICh0LmlzQWxpdmUoKSkgeworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0LmpvaW4oKTsKKyAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICB0aGlzLnF1aWVzY2VkLnNldCh0cnVlKTsKKyAgICBpZiAob25saW5lUmVnaW9ucy5zaXplKCkgPT0gMCkgeworICAgICAgb3V0Ym91bmRNc2dzLmFkZChSRVBPUlRfRVhJVElORyk7CisgICAgfSBlbHNlIHsKKyAgICAgIG91dGJvdW5kTXNncy5hZGQoUkVQT1JUX1FVSUVTQ0VEKTsKKyAgICB9CisgIH0KKworICAvLworICAvLyBIUmVnaW9uSW50ZXJmYWNlCisgIC8vCisKKyAgcHVibGljIEhSZWdpb25JbmZvIGdldFJlZ2lvbkluZm8oZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lKQorICB0aHJvd3MgTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbiB7CisgICAgcmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgIHJldHVybiBnZXRSZWdpb24ocmVnaW9uTmFtZSkuZ2V0UmVnaW9uSW5mbygpOworICB9CisKKyAgcHVibGljIENlbGwgW10gZ2V0KGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSwgZmluYWwgYnl0ZSBbXSByb3csCisgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIHJlcXVlc3RDb3VudC5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cyA9CisgICAgICAgIGdldFJlZ2lvbihyZWdpb25OYW1lKS5nZXQocm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOworICAgICAgcmV0dXJuIENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHJlc3VsdHMpOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICB0aHJvdyBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoY2xlYW51cCh0KSk7CisgICAgfQorICB9CisKKyAgcHVibGljIFJvd1Jlc3VsdCBnZXRSb3coZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLCBmaW5hbCBieXRlIFtdIHJvdywgCisgICAgZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMsIGZpbmFsIGxvbmcgdHMsCisgICAgZmluYWwgaW50IG51bVZlcnNpb25zLCBmaW5hbCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICByZXF1ZXN0Q291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIGNvbnZlcnQgdGhlIGNvbHVtbnMgYXJyYXkgaW50byBhIHNldCBzbyBpdCdzIGVhc3kgdG8gY2hlY2sgbGF0ZXIuCisgICAgICBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gY29sdW1uU2V0ID0gbnVsbDsKKyAgICAgIGlmIChjb2x1bW5zICE9IG51bGwpIHsKKyAgICAgICAgY29sdW1uU2V0ID0gbmV3IFRyZWVTZXQ8Ynl0ZSBbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgICAgIGNvbHVtblNldC5hZGRBbGwoQXJyYXlzLmFzTGlzdChjb2x1bW5zKSk7CisgICAgICB9CisgICAgICBIUmVnaW9uIHJlZ2lvbiA9IGdldFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgICAgIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgQ2VsbD4gcmVzdWx0ID0KKyAgICAgICAgcmVnaW9uLmdldEZ1bGwocm93LCBjb2x1bW5TZXQsIHRzLCBudW1WZXJzaW9ucywgZ2V0TG9ja0Zyb21JZChsb2NrSWQpKTsKKyAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuaXNFbXB0eSgpKQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIHJldHVybiBuZXcgUm93UmVzdWx0KHJvdywgcmVzdWx0KTsKKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgdGhyb3cgY29udmVydFRocm93YWJsZVRvSU9FKGNsZWFudXAodCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Q2xvc2VzdFJvd0JlZm9yZShmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIAorICAgIGZpbmFsIGJ5dGUgW10gcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbkZhbWlseSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICByZXF1ZXN0Q291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIGxvY2F0ZSB0aGUgcmVnaW9uIHdlJ3JlIG9wZXJhdGluZyBvbgorICAgICAgSFJlZ2lvbiByZWdpb24gPSBnZXRSZWdpb24ocmVnaW9uTmFtZSk7CisgICAgICAvLyBhc2sgdGhlIHJlZ2lvbiBmb3IgYWxsIHRoZSBkYXRhIAorICAgICAgUm93UmVzdWx0IHJyID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUocm93LCBjb2x1bW5GYW1pbHkpOworICAgICAgcmV0dXJuIHJyOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICB0aHJvdyBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoY2xlYW51cCh0KSk7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgUm93UmVzdWx0IG5leHQoZmluYWwgbG9uZyBzY2FubmVySWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUm93UmVzdWx0W10gcnJzID0gbmV4dChzY2FubmVySWQsIDEpOworICAgIHJldHVybiBycnMubGVuZ3RoID09IDAgPyBudWxsIDogcnJzWzBdOworICB9CisKKyAgcHVibGljIFJvd1Jlc3VsdCBbXSBuZXh0KGZpbmFsIGxvbmcgc2Nhbm5lcklkLCBpbnQgbmJSb3dzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIExpc3Q8TGlzdDxLZXlWYWx1ZT4+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PExpc3Q8S2V5VmFsdWU+PigpOworICAgIHRyeSB7CisgICAgICBTdHJpbmcgc2Nhbm5lck5hbWUgPSBTdHJpbmcudmFsdWVPZihzY2FubmVySWQpOworICAgICAgSW50ZXJuYWxTY2FubmVyIHMgPSBzY2FubmVycy5nZXQoc2Nhbm5lck5hbWUpOworICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgVW5rbm93blNjYW5uZXJFeGNlcHRpb24oIk5hbWU6ICIgKyBzY2FubmVyTmFtZSk7CisgICAgICB9CisgICAgICB0aGlzLmxlYXNlcy5yZW5ld0xlYXNlKHNjYW5uZXJOYW1lKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmJSb3dzOyBpKyspIHsKKyAgICAgICAgcmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgICAgICAvLyBDb2xsZWN0IHZhbHVlcyB0byBiZSByZXR1cm5lZCBoZXJlCisgICAgICAgIExpc3Q8S2V5VmFsdWU+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgIHdoaWxlIChzLm5leHQodmFsdWVzKSkgeworICAgICAgICAgIGlmICghdmFsdWVzLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgLy8gUm93IGhhcyBzb21ldGhpbmcgaW4gaXQuIFJldHVybiB0aGUgdmFsdWUuCisgICAgICAgICAgICByZXN1bHRzLmFkZCh2YWx1ZXMpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gUm93UmVzdWx0LmNyZWF0ZVJvd1Jlc3VsdEFycmF5KHJlc3VsdHMpOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICB0aHJvdyBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoY2xlYW51cCh0KSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLCBCYXRjaFVwZGF0ZSBiLCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoYi5nZXRSb3coKSA9PSBudWxsKQorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidXBkYXRlIGhhcyBudWxsIHJvdyIpOworICAgIAorICAgIGNoZWNrT3BlbigpOworICAgIHRoaXMucmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgIEhSZWdpb24gcmVnaW9uID0gZ2V0UmVnaW9uKHJlZ2lvbk5hbWUpOworICAgIHRyeSB7CisgICAgICBjYWNoZUZsdXNoZXIucmVjbGFpbU1lbWNhY2hlTWVtb3J5KCk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYiwgZ2V0TG9ja0Zyb21JZChiLmdldFJvd0xvY2soKSkpOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICB0aHJvdyBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoY2xlYW51cCh0KSk7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgaW50IGJhdGNoVXBkYXRlcyhmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwgZmluYWwgQmF0Y2hVcGRhdGUgW10gYikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgaSA9IDA7CisgICAgY2hlY2tPcGVuKCk7CisgICAgdHJ5IHsKKyAgICAgIEhSZWdpb24gcmVnaW9uID0gZ2V0UmVnaW9uKHJlZ2lvbk5hbWUpOworICAgICAgdGhpcy5jYWNoZUZsdXNoZXIucmVjbGFpbU1lbWNhY2hlTWVtb3J5KCk7CisgICAgICBJbnRlZ2VyW10gbG9ja3MgPSBuZXcgSW50ZWdlcltiLmxlbmd0aF07CisgICAgICBmb3IgKGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykgeworICAgICAgICB0aGlzLnJlcXVlc3RDb3VudC5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgbG9ja3NbaV0gPSBnZXRMb2NrRnJvbUlkKGJbaV0uZ2V0Um93TG9jaygpKTsKKyAgICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJbaV0sIGxvY2tzW2ldKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoKFdyb25nUmVnaW9uRXhjZXB0aW9uIGV4KSB7CisgICAgICByZXR1cm4gaTsKKyAgICB9IGNhdGNoIChOb3RTZXJ2aW5nUmVnaW9uRXhjZXB0aW9uIGV4KSB7CisgICAgICByZXR1cm4gaTsKKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgdGhyb3cgY29udmVydFRocm93YWJsZVRvSU9FKGNsZWFudXAodCkpOworICAgIH0KKyAgICByZXR1cm4gLTE7CisgIH0KKyAgCisgIHB1YmxpYyBib29sZWFuIGNoZWNrQW5kU2F2ZShmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIEJhdGNoVXBkYXRlIGIsCisgICAgICBmaW5hbCBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSxieXRlW10+IGV4cGVjdGVkVmFsdWVzKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChiLmdldFJvdygpID09IG51bGwpCisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJ1cGRhdGUgaGFzIG51bGwgcm93Iik7CisgICAgY2hlY2tPcGVuKCk7CisgICAgdGhpcy5yZXF1ZXN0Q291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgSFJlZ2lvbiByZWdpb24gPSBnZXRSZWdpb24ocmVnaW9uTmFtZSk7CisgICAgdHJ5IHsKKyAgICAgIGNhY2hlRmx1c2hlci5yZWNsYWltTWVtY2FjaGVNZW1vcnkoKTsKKyAgICAgIHJldHVybiByZWdpb24uY2hlY2tBbmRTYXZlKGIsCisgICAgICAgIGV4cGVjdGVkVmFsdWVzLGdldExvY2tGcm9tSWQoYi5nZXRSb3dMb2NrKCkpLCB0cnVlKTsKKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgdGhyb3cgY29udmVydFRocm93YWJsZVRvSU9FKGNsZWFudXAodCkpOworICAgIH0KKyAgfQorCisgIC8vCisgIC8vIHJlbW90ZSBzY2FubmVyIGludGVyZmFjZQorICAvLworCisgIHB1YmxpYyBsb25nIG9wZW5TY2FubmVyKGJ5dGUgW10gcmVnaW9uTmFtZSwgYnl0ZSBbXVtdIGNvbHMsIGJ5dGUgW10gZmlyc3RSb3csCisgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tPcGVuKCk7CisgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbnVsbDsKKyAgICBpZiAocmVnaW9uTmFtZSA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInJlZ2lvbk5hbWUgaXMgbnVsbCIpOworICAgIH0gZWxzZSBpZiAoY29scyA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNvbHVtbnMgdG8gc2NhbiBpcyBudWxsIik7CisgICAgfSBlbHNlIGlmIChmaXJzdFJvdyA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZpcnN0Um93IGZvciBzY2FubmVyIGlzIG51bGwiKTsKKyAgICB9CisgICAgaWYgKG5wZSAhPSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgYXJndW1lbnRzIHRvIG9wZW5TY2FubmVyIiwgbnBlKTsKKyAgICB9CisgICAgcmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICBIUmVnaW9uIHIgPSBnZXRSZWdpb24ocmVnaW9uTmFtZSk7CisgICAgICBJbnRlcm5hbFNjYW5uZXIgcyA9CisgICAgICAgIHIuZ2V0U2Nhbm5lcihjb2xzLCBmaXJzdFJvdywgdGltZXN0YW1wLCBmaWx0ZXIpOworICAgICAgbG9uZyBzY2FubmVySWQgPSBhZGRTY2FubmVyKHMpOworICAgICAgcmV0dXJuIHNjYW5uZXJJZDsKKyAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgdGhyb3cgY29udmVydFRocm93YWJsZVRvSU9FKGNsZWFudXAodCwgIkZhaWxlZCBvcGVuU2Nhbm5lciIpKTsKKyAgICB9CisgIH0KKyAgCisgIHByb3RlY3RlZCBsb25nIGFkZFNjYW5uZXIoSW50ZXJuYWxTY2FubmVyIHMpIHRocm93cyBMZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbiB7CisgICAgbG9uZyBzY2FubmVySWQgPSAtMUw7CisgICAgc2Nhbm5lcklkID0gcmFuZC5uZXh0TG9uZygpOworICAgIFN0cmluZyBzY2FubmVyTmFtZSA9IFN0cmluZy52YWx1ZU9mKHNjYW5uZXJJZCk7CisgICAgc3luY2hyb25pemVkKHNjYW5uZXJzKSB7CisgICAgICBzY2FubmVycy5wdXQoc2Nhbm5lck5hbWUsIHMpOworICAgIH0KKyAgICB0aGlzLmxlYXNlcy4KKyAgICAgIGNyZWF0ZUxlYXNlKHNjYW5uZXJOYW1lLCBuZXcgU2Nhbm5lckxpc3RlbmVyKHNjYW5uZXJOYW1lKSk7CisgICAgcmV0dXJuIHNjYW5uZXJJZDsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgY2xvc2UoZmluYWwgbG9uZyBzY2FubmVySWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGNoZWNrT3BlbigpOworICAgICAgcmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgICAgU3RyaW5nIHNjYW5uZXJOYW1lID0gU3RyaW5nLnZhbHVlT2Yoc2Nhbm5lcklkKTsKKyAgICAgIEludGVybmFsU2Nhbm5lciBzID0gbnVsbDsKKyAgICAgIHN5bmNocm9uaXplZChzY2FubmVycykgeworICAgICAgICBzID0gc2Nhbm5lcnMucmVtb3ZlKHNjYW5uZXJOYW1lKTsKKyAgICAgIH0KKyAgICAgIGlmKHMgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgVW5rbm93blNjYW5uZXJFeGNlcHRpb24oc2Nhbm5lck5hbWUpOworICAgICAgfQorICAgICAgcy5jbG9zZSgpOworICAgICAgdGhpcy5sZWFzZXMuY2FuY2VsTGVhc2Uoc2Nhbm5lck5hbWUpOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICB0aHJvdyBjb252ZXJ0VGhyb3dhYmxlVG9JT0UoY2xlYW51cCh0KSk7CisgICAgfQorICB9CisKKyAgLyoqIAorICAgKiBJbnN0YW50aWF0ZWQgYXMgYSBzY2FubmVyIGxlYXNlLgorICAgKiBJZiB0aGUgbGVhc2UgdGltZXMgb3V0LCB0aGUgc2Nhbm5lciBpcyBjbG9zZWQKKyAgICovCisgIHByaXZhdGUgY2xhc3MgU2Nhbm5lckxpc3RlbmVyIGltcGxlbWVudHMgTGVhc2VMaXN0ZW5lciB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc2Nhbm5lck5hbWU7CisgICAgCisgICAgU2Nhbm5lckxpc3RlbmVyKGZpbmFsIFN0cmluZyBuKSB7CisgICAgICB0aGlzLnNjYW5uZXJOYW1lID0gbjsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgbGVhc2VFeHBpcmVkKCkgeworICAgICAgTE9HLmluZm8oIlNjYW5uZXIgIiArIHRoaXMuc2Nhbm5lck5hbWUgKyAiIGxlYXNlIGV4cGlyZWQiKTsKKyAgICAgIEludGVybmFsU2Nhbm5lciBzID0gbnVsbDsKKyAgICAgIHN5bmNocm9uaXplZChzY2FubmVycykgeworICAgICAgICBzID0gc2Nhbm5lcnMucmVtb3ZlKHRoaXMuc2Nhbm5lck5hbWUpOworICAgICAgfQorICAgICAgaWYgKHMgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiQ2xvc2luZyBzY2FubmVyIiwgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8vCisgIC8vIE1ldGhvZHMgdGhhdCBkbyB0aGUgYWN0dWFsIHdvcmsgZm9yIHRoZSByZW1vdGUgQVBJCisgIC8vCisgIAorICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lLCBmaW5hbCBieXRlIFtdIHJvdywKKyAgICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uLCBmaW5hbCBsb25nIHRpbWVzdGFtcCwgZmluYWwgbG9uZyBsb2NrSWQpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gcmVnaW9uID0gZ2V0UmVnaW9uKHJlZ2lvbk5hbWUpOworICAgIHJlZ2lvbi5kZWxldGVBbGwocm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgZ2V0TG9ja0Zyb21JZChsb2NrSWQpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBieXRlIFtdIHJlZ2lvbk5hbWUsIGZpbmFsIGJ5dGUgW10gcm93LAorICAgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIGxvbmcgbG9ja0lkKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IGdldFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgICByZWdpb24uZGVsZXRlQWxsKHJvdywgdGltZXN0YW1wLCBnZXRMb2NrRnJvbUlkKGxvY2tJZCkpOworICB9CisKKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsQnlSZWdleChieXRlW10gcmVnaW9uTmFtZSwgYnl0ZVtdIHJvdywgU3RyaW5nIGNvbFJlZ2V4LAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGxvbmcgbG9ja0lkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGdldFJlZ2lvbihyZWdpb25OYW1lKS5kZWxldGVBbGxCeVJlZ2V4KHJvdywgY29sUmVnZXgsIHRpbWVzdGFtcCwgCisgICAgICAgIGdldExvY2tGcm9tSWQobG9ja0lkKSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBkZWxldGVGYW1pbHkoYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdywgYnl0ZSBbXSBmYW1pbHksIAorICAgIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9ueworICAgIGdldFJlZ2lvbihyZWdpb25OYW1lKS5kZWxldGVGYW1pbHkocm93LCBmYW1pbHksIHRpbWVzdGFtcCwKKyAgICAgICAgZ2V0TG9ja0Zyb21JZChsb2NrSWQpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUZhbWlseUJ5UmVnZXgoYnl0ZVtdIHJlZ2lvbk5hbWUsIGJ5dGVbXSByb3csIFN0cmluZyBmYW1pbHlSZWdleCwKKyAgICAgIGxvbmcgdGltZXN0YW1wLCBsb25nIGxvY2tJZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBnZXRSZWdpb24ocmVnaW9uTmFtZSkuZGVsZXRlRmFtaWx5QnlSZWdleChyb3csIGZhbWlseVJlZ2V4LCB0aW1lc3RhbXAsIAorICAgICAgICBnZXRMb2NrRnJvbUlkKGxvY2tJZCkpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKGJ5dGVbXSByZWdpb25OYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uLAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGxvbmcgbG9ja0lkKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSZWdpb24ocmVnaW9uTmFtZSkuZXhpc3RzKHJvdywgY29sdW1uLCB0aW1lc3RhbXAsIAorICAgICAgZ2V0TG9ja0Zyb21JZChsb2NrSWQpKTsKKyAgfQorCisgIHB1YmxpYyBsb25nIGxvY2tSb3coYnl0ZSBbXSByZWdpb25OYW1lLCBieXRlIFtdIHJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBudWxsOworICAgIGlmKHJlZ2lvbk5hbWUgPT0gbnVsbCkgeworICAgICAgbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJyZWdpb25OYW1lIGlzIG51bGwiKTsKKyAgICB9IGVsc2UgaWYocm93ID09IG51bGwpIHsKKyAgICAgIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicm93IHRvIGxvY2sgaXMgbnVsbCIpOworICAgIH0KKyAgICBpZihucGUgIT0gbnVsbCkgeworICAgICAgSU9FeGNlcHRpb24gaW8gPSBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgYXJndW1lbnRzIHRvIGxvY2tSb3ciKTsKKyAgICAgIGlvLmluaXRDYXVzZShucGUpOworICAgICAgdGhyb3cgaW87CisgICAgfQorICAgIHJlcXVlc3RDb3VudC5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgSFJlZ2lvbiByZWdpb24gPSBnZXRSZWdpb24ocmVnaW9uTmFtZSk7CisgICAgICBJbnRlZ2VyIHIgPSByZWdpb24ub2J0YWluUm93TG9jayhyb3cpOworICAgICAgbG9uZyBsb2NrSWQgPSBhZGRSb3dMb2NrKHIscmVnaW9uKTsKKyAgICAgIExPRy5kZWJ1ZygiUm93IGxvY2sgIiArIGxvY2tJZCArICIgZXhwbGljaXRseSBhY3F1aXJlZCBieSBjbGllbnQiKTsKKyAgICAgIHJldHVybiBsb2NrSWQ7CisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIHRocm93IGNvbnZlcnRUaHJvd2FibGVUb0lPRShjbGVhbnVwKHQsCisgICAgICAgICJFcnJvciBvYnRhaW5pbmcgcm93IGxvY2sgKGZzT2s6ICIgKyB0aGlzLmZzT2sgKyAiKSIpKTsKKyAgICB9CisgIH0KKworICBwcm90ZWN0ZWQgbG9uZyBhZGRSb3dMb2NrKEludGVnZXIgciwgSFJlZ2lvbiByZWdpb24pIHRocm93cyBMZWFzZVN0aWxsSGVsZEV4Y2VwdGlvbiB7CisgICAgbG9uZyBsb2NrSWQgPSAtMUw7CisgICAgbG9ja0lkID0gcmFuZC5uZXh0TG9uZygpOworICAgIFN0cmluZyBsb2NrTmFtZSA9IFN0cmluZy52YWx1ZU9mKGxvY2tJZCk7CisgICAgc3luY2hyb25pemVkKHJvd2xvY2tzKSB7CisgICAgICByb3dsb2Nrcy5wdXQobG9ja05hbWUsIHIpOworICAgIH0KKyAgICB0aGlzLmxlYXNlcy4KKyAgICAgIGNyZWF0ZUxlYXNlKGxvY2tOYW1lLCBuZXcgUm93TG9ja0xpc3RlbmVyKGxvY2tOYW1lLCByZWdpb24pKTsKKyAgICByZXR1cm4gbG9ja0lkOworICB9CisKKyAgLyoqCisgICAqIE1ldGhvZCB0byBnZXQgdGhlIEludGVnZXIgbG9jayBpZGVudGlmaWVyIHVzZWQgaW50ZXJuYWxseQorICAgKiBmcm9tIHRoZSBsb25nIGxvY2sgaWRlbnRpZmllciB1c2VkIGJ5IHRoZSBjbGllbnQuCisgICAqIEBwYXJhbSBsb2NrSWQgbG9uZyByb3cgbG9jayBpZGVudGlmaWVyIGZyb20gY2xpZW50CisgICAqIEByZXR1cm4gaW50SWQgSW50ZWdlciByb3cgbG9jayB1c2VkIGludGVybmFsbHkgaW4gSFJlZ2lvbgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIFRocm93biBpZiB0aGlzIGlzIG5vdCBhIHZhbGlkIGNsaWVudCBsb2NrIGlkLgorICAgKi8KKyAgcHJpdmF0ZSBJbnRlZ2VyIGdldExvY2tGcm9tSWQobG9uZyBsb2NrSWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYobG9ja0lkID09IC0xTCkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIFN0cmluZyBsb2NrTmFtZSA9IFN0cmluZy52YWx1ZU9mKGxvY2tJZCk7CisgICAgSW50ZWdlciBybCA9IG51bGw7CisgICAgc3luY2hyb25pemVkKHJvd2xvY2tzKSB7CisgICAgICBybCA9IHJvd2xvY2tzLmdldChsb2NrTmFtZSk7CisgICAgfQorICAgIGlmKHJsID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCByb3cgbG9jayIpOworICAgIH0KKyAgICB0aGlzLmxlYXNlcy5yZW5ld0xlYXNlKGxvY2tOYW1lKTsKKyAgICByZXR1cm4gcmw7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bmxvY2tSb3coYnl0ZSBbXSByZWdpb25OYW1lLCBsb25nIGxvY2tJZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBOdWxsUG9pbnRlckV4Y2VwdGlvbiBucGUgPSBudWxsOworICAgIGlmKHJlZ2lvbk5hbWUgPT0gbnVsbCkgeworICAgICAgbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJyZWdpb25OYW1lIGlzIG51bGwiKTsKKyAgICB9IGVsc2UgaWYobG9ja0lkID09IC0xTCkgeworICAgICAgbnBlID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJsb2NrSWQgaXMgbnVsbCIpOworICAgIH0KKyAgICBpZihucGUgIT0gbnVsbCkgeworICAgICAgSU9FeGNlcHRpb24gaW8gPSBuZXcgSU9FeGNlcHRpb24oIkludmFsaWQgYXJndW1lbnRzIHRvIHVubG9ja1JvdyIpOworICAgICAgaW8uaW5pdENhdXNlKG5wZSk7CisgICAgICB0aHJvdyBpbzsKKyAgICB9CisgICAgcmVxdWVzdENvdW50LmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICBIUmVnaW9uIHJlZ2lvbiA9IGdldFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgICAgIFN0cmluZyBsb2NrTmFtZSA9IFN0cmluZy52YWx1ZU9mKGxvY2tJZCk7CisgICAgICBJbnRlZ2VyIHIgPSBudWxsOworICAgICAgc3luY2hyb25pemVkKHJvd2xvY2tzKSB7CisgICAgICAgIHIgPSByb3dsb2Nrcy5yZW1vdmUobG9ja05hbWUpOworICAgICAgfQorICAgICAgaWYociA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBVbmtub3duUm93TG9ja0V4Y2VwdGlvbihsb2NrTmFtZSk7CisgICAgICB9CisgICAgICByZWdpb24ucmVsZWFzZVJvd0xvY2socik7CisgICAgICB0aGlzLmxlYXNlcy5jYW5jZWxMZWFzZShsb2NrTmFtZSk7CisgICAgICBMT0cuZGVidWcoIlJvdyBsb2NrICIgKyBsb2NrSWQgKyAiIGhhcyBiZWVuIGV4cGxpY2l0bHkgcmVsZWFzZWQgYnkgY2xpZW50Iik7CisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIHRocm93IGNvbnZlcnRUaHJvd2FibGVUb0lPRShjbGVhbnVwKHQpKTsKKyAgICB9CisgIH0KKworICBNYXA8U3RyaW5nLCBJbnRlZ2VyPiByb3dsb2NrcyA9CisgICAgbmV3IENvbmN1cnJlbnRIYXNoTWFwPFN0cmluZywgSW50ZWdlcj4oKTsKKworICAvKioKKyAgICogSW5zdGFudGlhdGVkIGFzIGEgcm93IGxvY2sgbGVhc2UuCisgICAqIElmIHRoZSBsZWFzZSB0aW1lcyBvdXQsIHRoZSByb3cgbG9jayBpcyByZWxlYXNlZAorICAgKi8KKyAgcHJpdmF0ZSBjbGFzcyBSb3dMb2NrTGlzdGVuZXIgaW1wbGVtZW50cyBMZWFzZUxpc3RlbmVyIHsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBsb2NrTmFtZTsKKyAgICBwcml2YXRlIGZpbmFsIEhSZWdpb24gcmVnaW9uOworCisgICAgUm93TG9ja0xpc3RlbmVyKGZpbmFsIFN0cmluZyBsb2NrTmFtZSwgZmluYWwgSFJlZ2lvbiByZWdpb24pIHsKKyAgICAgIHRoaXMubG9ja05hbWUgPSBsb2NrTmFtZTsKKyAgICAgIHRoaXMucmVnaW9uID0gcmVnaW9uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGxlYXNlRXhwaXJlZCgpIHsKKyAgICAgIExPRy5pbmZvKCJSb3cgTG9jayAiICsgdGhpcy5sb2NrTmFtZSArICIgbGVhc2UgZXhwaXJlZCIpOworICAgICAgSW50ZWdlciByID0gbnVsbDsKKyAgICAgIHN5bmNocm9uaXplZChyb3dsb2NrcykgeworICAgICAgICByID0gcm93bG9ja3MucmVtb3ZlKHRoaXMubG9ja05hbWUpOworICAgICAgfQorICAgICAgaWYociAhPSBudWxsKSB7CisgICAgICAgIHJlZ2lvbi5yZWxlYXNlUm93TG9jayhyKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBJbmZvIG9uIHRoaXMgc2VydmVyLgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJJbmZvIGdldFNlcnZlckluZm8oKSB7CisgICAgcmV0dXJuIHRoaXMuc2VydmVySW5mbzsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBpbmZvIHNlcnZlciAqLworICBwdWJsaWMgSW5mb1NlcnZlciBnZXRJbmZvU2VydmVyKCkgeworICAgIHJldHVybiBpbmZvU2VydmVyOworICB9CisgIAorICAvKioKKyAgICogQHJldHVybiB0cnVlIGlmIGEgc3RvcCBoYXMgYmVlbiByZXF1ZXN0ZWQuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBpc1N0b3BSZXF1ZXN0ZWQoKSB7CisgICAgcmV0dXJuIHN0b3BSZXF1ZXN0ZWQuZ2V0KCk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSByZWdpb24gc2VydmVyIGlzIGluIHNhZmUgbW9kZQorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNJblNhZmVNb2RlKCkgeworICAgIHJldHVybiBzYWZlTW9kZS5nZXQoKTsKKyAgfQorCisgIC8qKgorICAgKiAKKyAgICogQHJldHVybiB0aGUgY29uZmlndXJhdGlvbgorICAgKi8KKyAgcHVibGljIEhCYXNlQ29uZmlndXJhdGlvbiBnZXRDb25maWd1cmF0aW9uKCkgeworICAgIHJldHVybiBjb25mOworICB9CisKKyAgLyoqIEByZXR1cm4gdGhlIHdyaXRlIGxvY2sgZm9yIHRoZSBzZXJ2ZXIgKi8KKyAgUmVlbnRyYW50UmVhZFdyaXRlTG9jay5Xcml0ZUxvY2sgZ2V0V3JpdGVMb2NrKCkgeworICAgIHJldHVybiBsb2NrLndyaXRlTG9jaygpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gSW1tdXRhYmxlIGxpc3Qgb2YgdGhpcyBzZXJ2ZXJzIHJlZ2lvbnMuCisgICAqLworICBwdWJsaWMgQ29sbGVjdGlvbjxIUmVnaW9uPiBnZXRPbmxpbmVSZWdpb25zKCkgeworICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKG9ubGluZVJlZ2lvbnMudmFsdWVzKCkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVGhlIEhSZWdpb25JbmZvcyBmcm9tIG9ubGluZSByZWdpb25zIHNvcnRlZAorICAgKi8KKyAgcHVibGljIFNvcnRlZFNldDxIUmVnaW9uSW5mbz4gZ2V0U29ydGVkT25saW5lUmVnaW9uSW5mb3MoKSB7CisgICAgU29ydGVkU2V0PEhSZWdpb25JbmZvPiByZXN1bHQgPSBuZXcgVHJlZVNldDxIUmVnaW9uSW5mbz4oKTsKKyAgICBzeW5jaHJvbml6ZWQodGhpcy5vbmxpbmVSZWdpb25zKSB7CisgICAgICBmb3IgKEhSZWdpb24gcjogdGhpcy5vbmxpbmVSZWdpb25zLnZhbHVlcygpKSB7CisgICAgICAgIHJlc3VsdC5hZGQoci5nZXRSZWdpb25JbmZvKCkpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogVGhpcyBtZXRob2QgcmVtb3ZlcyBIUmVnaW9uIGNvcnJlc3BvbmRpbmcgdG8gaHJpIGZyb20gdGhlIE1hcCBvZiBvbmxpbmVSZWdpb25zLiAgCisgICAqIAorICAgKiBAcGFyYW0gaHJpIHRoZSBIUmVnaW9uSW5mbyBjb3JyZXNwb25kaW5nIHRvIHRoZSBIUmVnaW9uIHRvLWJlLXJlbW92ZWQuCisgICAqIEByZXR1cm4gdGhlIHJlbW92ZWQgSFJlZ2lvbiwgb3IgbnVsbCBpZiB0aGUgSFJlZ2lvbiB3YXMgbm90IGluIG9ubGluZVJlZ2lvbnMuCisgICAqLworICBIUmVnaW9uIHJlbW92ZUZyb21PbmxpbmVSZWdpb25zKEhSZWdpb25JbmZvIGhyaSkgeworICAgIHRoaXMubG9jay53cml0ZUxvY2soKS5sb2NrKCk7CisgICAgSFJlZ2lvbiB0b1JldHVybiA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIHRvUmV0dXJuID0gb25saW5lUmVnaW9ucy5yZW1vdmUoQnl0ZXMubWFwS2V5KGhyaS5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgICByZXR1cm4gdG9SZXR1cm47CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBBIG5ldyBNYXAgb2Ygb25saW5lIHJlZ2lvbnMgc29ydGVkIGJ5IHJlZ2lvbiBzaXplIHdpdGggdGhlIGZpcnN0CisgICAqIGVudHJ5IGJlaW5nIHRoZSBiaWdnZXN0LgorICAgKi8KKyAgcHVibGljIFNvcnRlZE1hcDxMb25nLCBIUmVnaW9uPiBnZXRDb3B5T2ZPbmxpbmVSZWdpb25zU29ydGVkQnlTaXplKCkgeworICAgIC8vIHdlJ2xsIHNvcnQgdGhlIHJlZ2lvbnMgaW4gcmV2ZXJzZQorICAgIFNvcnRlZE1hcDxMb25nLCBIUmVnaW9uPiBzb3J0ZWRSZWdpb25zID0gbmV3IFRyZWVNYXA8TG9uZywgSFJlZ2lvbj4oCisgICAgICAgIG5ldyBDb21wYXJhdG9yPExvbmc+KCkgeworICAgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShMb25nIGEsIExvbmcgYikgeworICAgICAgICAgICAgcmV0dXJuIC0xICogYS5jb21wYXJlVG8oYik7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgICAvLyBDb3B5IG92ZXIgYWxsIHJlZ2lvbnMuIFJlZ2lvbnMgYXJlIHNvcnRlZCBieSBzaXplIHdpdGggYmlnZ2VzdCBmaXJzdC4KKyAgICBzeW5jaHJvbml6ZWQgKHRoaXMub25saW5lUmVnaW9ucykgeworICAgICAgZm9yIChIUmVnaW9uIHJlZ2lvbiA6IHRoaXMub25saW5lUmVnaW9ucy52YWx1ZXMoKSkgeworICAgICAgICBzb3J0ZWRSZWdpb25zLnB1dChMb25nLnZhbHVlT2YocmVnaW9uLm1lbWNhY2hlU2l6ZS5nZXQoKSksIHJlZ2lvbik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBzb3J0ZWRSZWdpb25zOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUKKyAgICogQHJldHVybiBIUmVnaW9uIGZvciB0aGUgcGFzc2VkIDxjb2RlPnJlZ2lvbk5hbWU8L2NvZGU+IG9yIG51bGwgaWYgbmFtZWQKKyAgICogcmVnaW9uIGlzIG5vdCBtZW1iZXIgb2YgdGhlIG9ubGluZSByZWdpb25zLgorICAgKi8KKyAgcHVibGljIEhSZWdpb24gZ2V0T25saW5lUmVnaW9uKGZpbmFsIGJ5dGUgW10gcmVnaW9uTmFtZSkgeworICAgIHJldHVybiBvbmxpbmVSZWdpb25zLmdldChCeXRlcy5tYXBLZXkocmVnaW9uTmFtZSkpOworICB9CisKKyAgLyoqIEByZXR1cm4gdGhlIHJlcXVlc3QgY291bnQgKi8KKyAgcHVibGljIEF0b21pY0ludGVnZXIgZ2V0UmVxdWVzdENvdW50KCkgeworICAgIHJldHVybiB0aGlzLnJlcXVlc3RDb3VudDsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHJlZmVyZW5jZSB0byBGbHVzaFJlcXVlc3RlciAqLworICBwdWJsaWMgRmx1c2hSZXF1ZXN0ZXIgZ2V0Rmx1c2hSZXF1ZXN0ZXIoKSB7CisgICAgcmV0dXJuIHRoaXMuY2FjaGVGbHVzaGVyOworICB9CisgIAorICAvKiogCisgICAqIFByb3RlY3RlZCB1dGlsaXR5IG1ldGhvZCBmb3Igc2FmZWx5IG9idGFpbmluZyBhbiBIUmVnaW9uIGhhbmRsZS4KKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUgTmFtZSBvZiBvbmxpbmUge0BsaW5rIEhSZWdpb259IHRvIHJldHVybgorICAgKiBAcmV0dXJuIHtAbGluayBIUmVnaW9ufSBmb3IgPGNvZGU+cmVnaW9uTmFtZTwvY29kZT4KKyAgICogQHRocm93cyBOb3RTZXJ2aW5nUmVnaW9uRXhjZXB0aW9uCisgICAqLworICBwcm90ZWN0ZWQgSFJlZ2lvbiBnZXRSZWdpb24oZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lKQorICB0aHJvd3MgTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworICAgIHRoaXMubG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgcmVnaW9uID0gb25saW5lUmVnaW9ucy5nZXQoSW50ZWdlci52YWx1ZU9mKEJ5dGVzLmhhc2hDb2RlKHJlZ2lvbk5hbWUpKSk7CisgICAgICBpZiAocmVnaW9uID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE5vdFNlcnZpbmdSZWdpb25FeGNlcHRpb24ocmVnaW9uTmFtZSk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVnaW9uOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSB0b3AgTiBtb3N0IGxvYWRlZCByZWdpb25zIHRoaXMgc2VydmVyIGlzIHNlcnZpbmcgc28gd2UgY2FuCisgICAqIHRlbGwgdGhlIG1hc3RlciB3aGljaCByZWdpb25zIGl0IGNhbiByZWFsbG9jYXRlIGlmIHdlJ3JlIG92ZXJsb2FkZWQuCisgICAqIFRPRE86IGFjdHVhbGx5IGNhbGN1bGF0ZSB3aGljaCByZWdpb25zIGFyZSBtb3N0IGxvYWRlZC4gKFJpZ2h0IG5vdywgd2UncmUKKyAgICoganVzdCBncmFiYmluZyB0aGUgZmlyc3QgTiByZWdpb25zIGJlaW5nIHNlcnZlZCByZWdhcmRsZXNzIG9mIGxvYWQuKQorICAgKi8KKyAgcHJvdGVjdGVkIEhSZWdpb25JbmZvW10gZ2V0TW9zdExvYWRlZFJlZ2lvbnMoKSB7CisgICAgQXJyYXlMaXN0PEhSZWdpb25JbmZvPiByZWdpb25zID0gbmV3IEFycmF5TGlzdDxIUmVnaW9uSW5mbz4oKTsKKyAgICBzeW5jaHJvbml6ZWQgKG9ubGluZVJlZ2lvbnMpIHsKKyAgICAgIGZvciAoSFJlZ2lvbiByIDogb25saW5lUmVnaW9ucy52YWx1ZXMoKSkgeworICAgICAgICBpZiAoci5pc0Nsb3NlZCgpIHx8IHIuaXNDbG9zaW5nKCkpIHsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAocmVnaW9ucy5zaXplKCkgPCBudW1SZWdpb25zVG9SZXBvcnQpIHsKKyAgICAgICAgICByZWdpb25zLmFkZChyLmdldFJlZ2lvbkluZm8oKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlZ2lvbnMudG9BcnJheShuZXcgSFJlZ2lvbkluZm9bcmVnaW9ucy5zaXplKCldKTsKKyAgfQorICAKKyAgLyoqICAKKyAgICogQ2FsbGVkIHRvIHZlcmlmeSB0aGF0IHRoaXMgc2VydmVyIGlzIHVwIGFuZCBydW5uaW5nLgorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgY2hlY2tPcGVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5zdG9wUmVxdWVzdGVkLmdldCgpIHx8IHRoaXMuYWJvcnRSZXF1ZXN0ZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU2VydmVyIG5vdCBydW5uaW5nIiArCisgICAgICAgICh0aGlzLmFib3J0UmVxdWVzdGVkPyAiLCBhYm9ydGluZyI6ICIiKSk7CisgICAgfQorICAgIGlmICghZnNPaykgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGaWxlIHN5c3RlbSBub3QgYXZhaWxhYmxlIik7CisgICAgfQorICB9CisgCisgIC8qKgorICAgKiBAcmV0dXJuIFJldHVybnMgbGlzdCBvZiBub24tY2xvc2VkIHJlZ2lvbnMgaG9zdGVkIG9uIHRoaXMgc2VydmVyLiAgSWYgbm8KKyAgICogcmVnaW9ucyB0byBjaGVjaywgcmV0dXJucyBhbiBlbXB0eSBsaXN0LgorICAgKi8KKyAgcHJvdGVjdGVkIFNldDxIUmVnaW9uPiBnZXRSZWdpb25zVG9DaGVjaygpIHsKKyAgICBIYXNoU2V0PEhSZWdpb24+IHJlZ2lvbnNUb0NoZWNrID0gbmV3IEhhc2hTZXQ8SFJlZ2lvbj4oKTsKKyAgICAvL1RPRE86IGlzIHRoaXMgbG9ja2luZyBuZWNlc3Nhcnk/IAorICAgIGxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIHJlZ2lvbnNUb0NoZWNrLmFkZEFsbCh0aGlzLm9ubGluZVJlZ2lvbnMudmFsdWVzKCkpOworICAgIH0gZmluYWxseSB7CisgICAgICBsb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICAgIC8vIFB1cmdlIGNsb3NlZCByZWdpb25zLgorICAgIGZvciAoZmluYWwgSXRlcmF0b3I8SFJlZ2lvbj4gaSA9IHJlZ2lvbnNUb0NoZWNrLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgeworICAgICAgSFJlZ2lvbiByID0gaS5uZXh0KCk7CisgICAgICBpZiAoci5pc0Nsb3NlZCgpKSB7CisgICAgICAgIGkucmVtb3ZlKCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZWdpb25zVG9DaGVjazsKKyAgfQorCisgIHB1YmxpYyBsb25nIGdldFByb3RvY29sVmVyc2lvbihmaW5hbCBTdHJpbmcgcHJvdG9jb2wsIAorICAgICAgZmluYWwgbG9uZyBjbGllbnRWZXJzaW9uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAgCisgICAgaWYgKHByb3RvY29sLmVxdWFscyhIUmVnaW9uSW50ZXJmYWNlLmNsYXNzLmdldE5hbWUoKSkpIHsKKyAgICAgIHJldHVybiBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi52ZXJzaW9uSUQ7CisgICAgfQorICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5rbm93biBwcm90b2NvbCB0byBuYW1lIG5vZGU6ICIgKyBwcm90b2NvbCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIFF1ZXVlIHRvIHdoaWNoIHlvdSBjYW4gYWRkIG91dGJvdW5kIG1lc3NhZ2VzLgorICAgKi8KKyAgcHJvdGVjdGVkIExpc3Q8SE1zZz4gZ2V0T3V0Ym91bmRNc2dzKCkgeworICAgIHJldHVybiB0aGlzLm91dGJvdW5kTXNnczsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIHRvdGFsIHNpemUgb2YgYWxsIG1lbWNhY2hlcyBpbiBldmVyeSByZWdpb24uCisgICAqIEByZXR1cm4gbWVtY2FjaGUgc2l6ZSBpbiBieXRlcworICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0R2xvYmFsTWVtY2FjaGVTaXplKCkgeworICAgIGxvbmcgdG90YWwgPSAwOworICAgIHN5bmNocm9uaXplZCAob25saW5lUmVnaW9ucykgeworICAgICAgZm9yIChIUmVnaW9uIHJlZ2lvbiA6IG9ubGluZVJlZ2lvbnMudmFsdWVzKCkpIHsKKyAgICAgICAgdG90YWwgKz0gcmVnaW9uLm1lbWNhY2hlU2l6ZS5nZXQoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRvdGFsOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSBsZWFzZXMuCisgICAqLworICBwcm90ZWN0ZWQgTGVhc2VzIGdldExlYXNlcygpIHsKKyAgICByZXR1cm4gbGVhc2VzOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSByb290RGlyLgorICAgKi8KKyAgcHJvdGVjdGVkIFBhdGggZ2V0Um9vdERpcigpIHsKKyAgICByZXR1cm4gcm9vdERpcjsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFJldHVybiB0aGUgZnMuCisgICAqLworICBwcm90ZWN0ZWQgRmlsZVN5c3RlbSBnZXRGaWxlU3lzdGVtKCkgeworICAgIHJldHVybiBmczsKKyAgfQorCisgIC8vCisgIC8vIE1haW4gcHJvZ3JhbSBhbmQgc3VwcG9ydCByb3V0aW5lcworICAvLworCisgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRVc2FnZUFuZEV4aXQoKSB7CisgICAgcHJpbnRVc2FnZUFuZEV4aXQobnVsbCk7CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIHZvaWQgcHJpbnRVc2FnZUFuZEV4aXQoZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBpZiAobWVzc2FnZSAhPSBudWxsKSB7CisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obWVzc2FnZSk7CisgICAgfQorICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IGphdmEgIiArCisgICAgICAgICJvcmcuYXBhY2hlLmhiYXNlLkhSZWdpb25TZXJ2ZXIgWy0tYmluZD1ob3N0bmFtZTpwb3J0XSBzdGFydCIpOworICAgIFN5c3RlbS5leGl0KDApOworICB9CisgIAorICAvKioKKyAgICogRG8gY2xhc3MgbWFpbi4KKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHBhcmFtIHJlZ2lvblNlcnZlckNsYXNzIEhSZWdpb25TZXJ2ZXIgdG8gaW5zdGFudGlhdGUuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZG9NYWluKGZpbmFsIFN0cmluZyBbXSBhcmdzLAorICAgICAgZmluYWwgQ2xhc3M8PyBleHRlbmRzIEhSZWdpb25TZXJ2ZXI+IHJlZ2lvblNlcnZlckNsYXNzKSB7CisgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgeworICAgICAgcHJpbnRVc2FnZUFuZEV4aXQoKTsKKyAgICB9CisgICAgQ29uZmlndXJhdGlvbiBjb25mID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIAorICAgIC8vIFByb2Nlc3MgY29tbWFuZC1saW5lIGFyZ3MuIFRPRE86IEJldHRlciBjbWQtbGluZSBwcm9jZXNzaW5nCisgICAgLy8gKGJ1dCBob3BlZnVsbHkgc29tZXRoaW5nIG5vdCBhcyBwYWluZnVsIGFzIGNsaSBvcHRpb25zKS4KKyAgICBmaW5hbCBTdHJpbmcgYWRkcmVzc0FyZ0tleSA9ICItLWJpbmQ9IjsKKyAgICBmb3IgKFN0cmluZyBjbWQ6IGFyZ3MpIHsKKyAgICAgIGlmIChjbWQuc3RhcnRzV2l0aChhZGRyZXNzQXJnS2V5KSkgeworICAgICAgICBjb25mLnNldChSRUdJT05TRVJWRVJfQUREUkVTUywgY21kLnN1YnN0cmluZyhhZGRyZXNzQXJnS2V5Lmxlbmd0aCgpKSk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgCisgICAgICBpZiAoY21kLmVxdWFscygic3RhcnQiKSkgeworICAgICAgICB0cnkgeworICAgICAgICAgIC8vIElmICdsb2NhbCcsIGRvbid0IHN0YXJ0IGEgcmVnaW9uIHNlcnZlciBoZXJlLiAgRGVmZXIgdG8KKyAgICAgICAgICAvLyBMb2NhbEhCYXNlQ2x1c3Rlci4gIEl0IG1hbmFnZXMgJ2xvY2FsJyBjbHVzdGVycy4KKyAgICAgICAgICBpZiAoTG9jYWxIQmFzZUNsdXN0ZXIuaXNMb2NhbChjb25mKSkgeworICAgICAgICAgICAgTE9HLndhcm4oIk5vdCBzdGFydGluZyBhIGRpc3RpbmN0IHJlZ2lvbiBzZXJ2ZXIgYmVjYXVzZSAiICsKKyAgICAgICAgICAgICAgImhiYXNlLm1hc3RlciBpcyBzZXQgdG8gJ2xvY2FsJyBtb2RlIik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFJ1bnRpbWVNWEJlYW4gcnVudGltZSA9IE1hbmFnZW1lbnRGYWN0b3J5LmdldFJ1bnRpbWVNWEJlYW4oKTsKKyAgICAgICAgICAgIGlmIChydW50aW1lICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgTE9HLmluZm8oInZtSW5wdXRBcmd1bWVudHM9IiArIHJ1bnRpbWUuZ2V0SW5wdXRBcmd1bWVudHMoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBDb25zdHJ1Y3Rvcjw/IGV4dGVuZHMgSFJlZ2lvblNlcnZlcj4gYyA9CisgICAgICAgICAgICAgIHJlZ2lvblNlcnZlckNsYXNzLmdldENvbnN0cnVjdG9yKEhCYXNlQ29uZmlndXJhdGlvbi5jbGFzcyk7CisgICAgICAgICAgICBIUmVnaW9uU2VydmVyIGhycyA9IGMubmV3SW5zdGFuY2UoY29uZik7CisgICAgICAgICAgICBUaHJlYWQgdCA9IG5ldyBUaHJlYWQoaHJzKTsKKyAgICAgICAgICAgIHQuc2V0TmFtZSgicmVnaW9uc2VydmVyIiArIGhycy5zZXJ2ZXIuZ2V0TGlzdGVuZXJBZGRyZXNzKCkpOworICAgICAgICAgICAgdC5zdGFydCgpOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoICJDYW4gbm90IHN0YXJ0IHJlZ2lvbiBzZXJ2ZXIgYmVjYXVzZSAiKworICAgICAgICAgICAgICBTdHJpbmdVdGlscy5zdHJpbmdpZnlFeGNlcHRpb24odCkgKTsKKyAgICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICAKKyAgICAgIGlmIChjbWQuZXF1YWxzKCJzdG9wIikpIHsKKyAgICAgICAgcHJpbnRVc2FnZUFuZEV4aXQoIlRvIHNodXRkb3duIHRoZSByZWdpb25zZXJ2ZXIgcnVuICIgKworICAgICAgICAgICJiaW4vaGJhc2UtZGFlbW9uLnNoIHN0b3AgcmVnaW9uc2VydmVyIG9yIHNlbmQgYSBraWxsIHNpZ25hbCB0byIgKworICAgICAgICAgICJ0aGUgcmVnaW9uc2VydmVyIHBpZCIpOworICAgICAgfQorICAgICAgCisgICAgICAvLyBQcmludCBvdXQgdXNhZ2UgaWYgd2UgZ2V0IHRvIGhlcmUuCisgICAgICBwcmludFVzYWdlQW5kRXhpdCgpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgW10gYXJncykgeworICAgIENvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICBDbGFzczw/IGV4dGVuZHMgSFJlZ2lvblNlcnZlcj4gcmVnaW9uU2VydmVyQ2xhc3MgPSAoQ2xhc3M8PyBleHRlbmRzIEhSZWdpb25TZXJ2ZXI+KSBjb25mCisgICAgICAgIC5nZXRDbGFzcyhIQ29uc3RhbnRzLlJFR0lPTl9TRVJWRVJfSU1QTCwgSFJlZ2lvblNlcnZlci5jbGFzcyk7CisgICAgZG9NYWluKGFyZ3MsIHJlZ2lvblNlcnZlckNsYXNzKTsKKyAgfQorCisgIC8qKiB7QGluaGVyaXREb2N9ICovCisgIHB1YmxpYyBsb25nIGluY3JlbWVudENvbHVtblZhbHVlKGJ5dGVbXSByZWdpb25OYW1lLCBieXRlW10gcm93LAorICAgICAgYnl0ZVtdIGNvbHVtbiwgbG9uZyBhbW91bnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tPcGVuKCk7CisgICAgCisgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbnVsbDsKKyAgICBpZiAocmVnaW9uTmFtZSA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInJlZ2lvbk5hbWUgaXMgbnVsbCIpOworICAgIH0gZWxzZSBpZiAocm93ID09IG51bGwpIHsKKyAgICAgIG5wZSA9IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigicm93IGlzIG51bGwiKTsKKyAgICB9IGVsc2UgaWYgKGNvbHVtbiA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNvbHVtbiBpcyBudWxsIik7CisgICAgfQorICAgIGlmIChucGUgIT0gbnVsbCkgeworICAgICAgSU9FeGNlcHRpb24gaW8gPSBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgIkludmFsaWQgYXJndW1lbnRzIHRvIGluY3JlbWVudENvbHVtblZhbHVlIiwgbnBlKTsKKyAgICAgIHRocm93IGlvOworICAgIH0KKyAgICByZXF1ZXN0Q291bnQuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgdHJ5IHsKKyAgICAgIEhSZWdpb24gcmVnaW9uID0gZ2V0UmVnaW9uKHJlZ2lvbk5hbWUpOworICAgICAgcmV0dXJuIHJlZ2lvbi5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgYW1vdW50KTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICAgIAorICAgIAorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvSW50ZXJuYWxTY2FubmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvSW50ZXJuYWxTY2FubmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWZmMjNiZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9JbnRlcm5hbFNjYW5uZXIuamF2YQpAQCAtMCwwICsxLDY1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworCisvKioKKyAqIEludGVybmFsIHNjYW5uZXJzIGRpZmZlciBmcm9tIGNsaWVudC1zaWRlIHNjYW5uZXJzIGluIHRoYXQgdGhleSBvcGVyYXRlIG9uCisgKiBIU3RvcmVLZXlzIGFuZCBieXRlW10gaW5zdGVhZCBvZiBSb3dSZXN1bHRzLiBUaGlzIGlzIGJlY2F1c2UgdGhleSBhcmUgCisgKiBhY3R1YWxseSBjbG9zZSB0byBob3cgdGhlIGRhdGEgaXMgcGh5c2ljYWxseSBzdG9yZWQsIGFuZCB0aGVyZWZvcmUgaXQgaXMgbW9yZQorICogY29udmVuaWVudCB0byBpbnRlcmFjdCB3aXRoIHRoZW0gdGhhdCB3YXkuIEl0IGlzIGFsc28gbXVjaCBlYXNpZXIgdG8gbWVyZ2UgCisgKiB0aGUgcmVzdWx0cyBhY3Jvc3MgU29ydGVkTWFwcyB0aGFuIFJvd1Jlc3VsdHMuIAorICoKKyAqIDxwPkFkZGl0aW9uYWxseSwgd2UgbmVlZCB0byBiZSBhYmxlIHRvIGRldGVybWluZSBpZiB0aGUgc2Nhbm5lciBpcyBkb2luZworICogd2lsZGNhcmQgY29sdW1uIG1hdGNoZXMgKHdoZW4gb25seSBhIGNvbHVtbiBmYW1pbHkgaXMgc3BlY2lmaWVkIG9yIGlmIGEKKyAqIGNvbHVtbiByZWdleCBpcyBzcGVjaWZpZWQpIG9yIGlmIG11bHRpcGxlIG1lbWJlcnMgb2YgdGhlIHNhbWUgY29sdW1uIGZhbWlseQorICogd2VyZSBzcGVjaWZpZWQuIElmIHNvLCB3ZSBuZWVkIHRvIGlnbm9yZSB0aGUgdGltZXN0YW1wIHRvIGVuc3VyZSB0aGF0IHdlIGdldAorICogYWxsIHRoZSBmYW1pbHkgbWVtYmVycywgYXMgdGhleSBtYXkgaGF2ZSBiZWVuIGxhc3QgdXBkYXRlZCBhdCBkaWZmZXJlbnQKKyAqIHRpbWVzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEludGVybmFsU2Nhbm5lciBleHRlbmRzIENsb3NlYWJsZSB7CisgIC8qKgorICAgKiBHcmFiIHRoZSBuZXh0IHJvdydzIHdvcnRoIG9mIHZhbHVlcy4gVGhlIHNjYW5uZXIgd2lsbCByZXR1cm4gdGhlIG1vc3QKKyAgICogcmVjZW50IGRhdGEgdmFsdWUgZm9yIGVhY2ggcm93IHRoYXQgaXMgbm90IG5ld2VyIHRoYW4gdGhlIHRhcmdldCB0aW1lCisgICAqIHBhc3NlZCB3aGVuIHRoZSBzY2FubmVyIHdhcyBjcmVhdGVkLgorICAgKiBAcGFyYW0gcmVzdWx0cworICAgKiBAcmV0dXJuIHRydWUgaWYgZGF0YSB3YXMgcmV0dXJuZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gbmV4dChMaXN0PEtleVZhbHVlPiByZXN1bHRzKQorICB0aHJvd3MgSU9FeGNlcHRpb247CisgIAorICAvKioKKyAgICogQ2xvc2VzIHRoZSBzY2FubmVyIGFuZCByZWxlYXNlcyBhbnkgcmVzb3VyY2VzIGl0IGhhcyBhbGxvY2F0ZWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247ICAKKyAgCisgIC8qKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNjYW5uZXIgaXMgbWF0Y2hpbmcgYSBjb2x1bW4gZmFtaWx5IG9yIHJlZ2V4ICovCisgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmRTY2FubmVyKCk7CisgIAorICAvKiogQHJldHVybiB0cnVlIGlmIHRoZSBzY2FubmVyIGlzIG1hdGNoaW5nIG11bHRpcGxlIGNvbHVtbiBmYW1pbHkgbWVtYmVycyAqLworICBwdWJsaWMgYm9vbGVhbiBpc011bHRpcGxlTWF0Y2hTY2FubmVyKCk7Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0xvZ0ZsdXNoZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Mb2dGbHVzaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTYyMDQ1OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Mb2dGbHVzaGVyLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkNob3JlOworCisvKioKKyAqIExvZ0ZsdXNoZXIgaXMgYSBDaG9yZSB0aGF0IHdha2VzIGV2ZXJ5IHRocmVhZFdha2VJbnRlcnZhbCBhbmQgY2FsbHMKKyAqIHRoZSBITG9nIHRvIGRvIGFuIG9wdGlvbmFsIHN5bmMgaWYgdGhlcmUgYXJlIHVuZmx1c2hlZCBlbnRyaWVzLCBhbmQgdGhlCisgKiBvcHRpb25hbEZsdXNoSW50ZXJ2YWwgaGFzIHBhc3NlZCBzaW5jZSB0aGUgbGFzdCBmbHVzaC4KKyAqLworcHVibGljIGNsYXNzIExvZ0ZsdXNoZXIgZXh0ZW5kcyBDaG9yZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTG9nRmx1c2hlci5jbGFzcyk7CisgIAorICBwcml2YXRlIGZpbmFsIEF0b21pY1JlZmVyZW5jZTxITG9nPiBsb2cgPQorICAgIG5ldyBBdG9taWNSZWZlcmVuY2U8SExvZz4obnVsbCk7CisgIAorICBMb2dGbHVzaGVyKGZpbmFsIGludCBwZXJpb2QsIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcCkgeworICAgIHN1cGVyKHBlcmlvZCwgc3RvcCk7CisgIH0KKyAgCisgIHZvaWQgc2V0SExvZyhITG9nIGxvZykgeworICAgIHN5bmNocm9uaXplZCAobG9nKSB7CisgICAgICB0aGlzLmxvZy5zZXQobG9nKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgY2hvcmUoKSB7CisgICAgc3luY2hyb25pemVkIChsb2cpIHsKKyAgICAgIEhMb2cgaGxvZyA9IGxvZy5nZXQoKTsKKyAgICAgIGlmIChobG9nICE9IG51bGwpIHsKKyAgICAgICAgaGxvZy5vcHRpb25hbFN5bmMoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTG9nUm9sbExpc3RlbmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTG9nUm9sbExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg4YzlmZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Mb2dSb2xsTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKKy8qKgorICogTWVjaGFuaXNtIGJ5IHdoaWNoIHRoZSBITG9nIHJlcXVlc3RzIGEgbG9nIHJvbGwKKyAqLworcHVibGljIGludGVyZmFjZSBMb2dSb2xsTGlzdGVuZXIgeworICAvKiogUmVxdWVzdCB0aGF0IHRoZSBsb2cgYmUgcm9sbGVkICovCisgIHB1YmxpYyB2b2lkIGxvZ1JvbGxSZXF1ZXN0ZWQoKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Mb2dSb2xsZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Mb2dSb2xsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzlkZjAxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0xvZ1JvbGxlci5qYXZhCkBAIC0wLDAgKzEsMTMwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljQm9vbGVhbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVtb3RlRXhjZXB0aW9uSGFuZGxlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFJ1bnMgcGVyaW9kaWNhbGx5IHRvIGRldGVybWluZSBpZiB0aGUgSExvZyBzaG91bGQgYmUgcm9sbGVkLgorICogCisgKiBOT1RFOiBUaGlzIGNsYXNzIGV4dGVuZHMgVGhyZWFkIHJhdGhlciB0aGFuIENob3JlIGJlY2F1c2UgdGhlIHNsZWVwIHRpbWUKKyAqIGNhbiBiZSBpbnRlcnJ1cHRlZCB3aGVuIHRoZXJlIGlzIHNvbWV0aGluZyB0byBkbywgcmF0aGVyIHRoYW4gdGhlIENob3JlCisgKiBzbGVlcCB0aW1lIHdoaWNoIGlzIGludmFyaWFudC4KKyAqLworY2xhc3MgTG9nUm9sbGVyIGV4dGVuZHMgVGhyZWFkIGltcGxlbWVudHMgTG9nUm9sbExpc3RlbmVyIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhMb2dSb2xsZXIuY2xhc3MpOyAgCisgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50TG9jayByb2xsTG9jayA9IG5ldyBSZWVudHJhbnRMb2NrKCk7CisgIHByaXZhdGUgZmluYWwgQXRvbWljQm9vbGVhbiByb2xsTG9nID0gbmV3IEF0b21pY0Jvb2xlYW4oZmFsc2UpOworICBwcml2YXRlIGZpbmFsIEhSZWdpb25TZXJ2ZXIgc2VydmVyOworICAKKyAgLyoqIEBwYXJhbSBzZXJ2ZXIgKi8KKyAgcHVibGljIExvZ1JvbGxlcihmaW5hbCBIUmVnaW9uU2VydmVyIHNlcnZlcikgeworICAgIHN1cGVyKCk7CisgICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcnVuKCkgeworICAgIHdoaWxlICghc2VydmVyLmlzU3RvcFJlcXVlc3RlZCgpKSB7CisgICAgICBpZiAoIXJvbGxMb2cuZ2V0KCkpIHsKKyAgICAgICAgc3luY2hyb25pemVkIChyb2xsTG9nKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHJvbGxMb2cud2FpdChzZXJ2ZXIudGhyZWFkV2FrZUZyZXF1ZW5jeSk7CisgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgcm9sbExvY2subG9jaygpOyAgICAgICAgICAvLyBEb24ndCBpbnRlcnJ1cHQgdXMuIFdlJ3JlIHdvcmtpbmcKKyAgICAgIHRyeSB7CisgICAgICAgIGJ5dGUgW10gcmVnaW9uVG9GbHVzaCA9IHNlcnZlci5nZXRMb2coKS5yb2xsV3JpdGVyKCk7CisgICAgICAgIGlmIChyZWdpb25Ub0ZsdXNoICE9IG51bGwpIHsKKyAgICAgICAgICBzY2hlZHVsZUZsdXNoKHJlZ2lvblRvRmx1c2gpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChGYWlsZWRMb2dDbG9zZUV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5mYXRhbCgiRm9yY2luZyBzZXJ2ZXIgc2h1dGRvd24iLCBlKTsKKyAgICAgICAgc2VydmVyLmNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgICBzZXJ2ZXIuYWJvcnQoKTsKKyAgICAgIH0gY2F0Y2ggKGphdmEubmV0LkNvbm5lY3RFeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuZmF0YWwoIkZvcmNpbmcgc2VydmVyIHNodXRkb3duIiwgZSk7CisgICAgICAgIHNlcnZlci5jaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgICAgc2VydmVyLmFib3J0KCk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICBMT0cuZmF0YWwoIkxvZyByb2xsaW5nIGZhaWxlZCB3aXRoIGlvZTogIiwKKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZXgpKTsKKyAgICAgICAgc2VydmVyLmNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgICAvLyBBYm9ydCBpZiB3ZSBnZXQgaGVyZS4gIFdlIHByb2JhYmx5IHdvbid0IHJlY292ZXIgYW4gSU9FLiBIQkFTRS0xMTMyCisgICAgICAgIHNlcnZlci5hYm9ydCgpOworICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIExPRy5lcnJvcigiTG9nIHJvbGxpbmcgZmFpbGVkIiwgZXgpOworICAgICAgICBzZXJ2ZXIuY2hlY2tGaWxlU3lzdGVtKCk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICByb2xsTG9nLnNldChmYWxzZSk7CisgICAgICAgIHJvbGxMb2NrLnVubG9jaygpOworICAgICAgfQorICAgIH0KKyAgICBMT0cuaW5mbygiTG9nUm9sbGVyIGV4aXRpbmcuIik7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBzY2hlZHVsZUZsdXNoKGZpbmFsIGJ5dGUgW10gcmVnaW9uKSB7CisgICAgYm9vbGVhbiBzY2hlZHVsZWQgPSBmYWxzZTsKKyAgICBIUmVnaW9uIHIgPSB0aGlzLnNlcnZlci5nZXRPbmxpbmVSZWdpb24ocmVnaW9uKTsKKyAgICBGbHVzaFJlcXVlc3RlciByZXF1ZXN0ZXIgPSBudWxsOworICAgIGlmIChyICE9IG51bGwpIHsKKyAgICAgIHJlcXVlc3RlciA9IHRoaXMuc2VydmVyLmdldEZsdXNoUmVxdWVzdGVyKCk7CisgICAgICBpZiAocmVxdWVzdGVyICE9IG51bGwpIHsKKyAgICAgICAgcmVxdWVzdGVyLnJlcXVlc3Qocik7CisgICAgICAgIHNjaGVkdWxlZCA9IHRydWU7CisgICAgICB9CisgICAgfQorICAgIGlmICghc2NoZWR1bGVkKSB7CisgICAgTE9HLndhcm4oIkZhaWxlZCB0byBzY2hlZHVsZSBmbHVzaCBvZiAiICsKKyAgICAgIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbikgKyAicj0iICsgciArICIsIHJlcXVlc3Rlcj0iICsgcmVxdWVzdGVyKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBsb2dSb2xsUmVxdWVzdGVkKCkgeworICAgIHN5bmNocm9uaXplZCAocm9sbExvZykgeworICAgICAgcm9sbExvZy5zZXQodHJ1ZSk7CisgICAgICByb2xsTG9nLm5vdGlmeUFsbCgpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIENhbGxlZCBieSByZWdpb24gc2VydmVyIHRvIHdha2UgdXAgdGhpcyB0aHJlYWQgaWYgaXQgc2xlZXBpbmcuCisgICAqIEl0IGlzIHNsZWVwaW5nIGlmIHJvbGxMb2NrIGlzIG5vdCBoZWxkLgorICAgKi8KKyAgcHVibGljIHZvaWQgaW50ZXJydXB0SWZOZWNlc3NhcnkoKSB7CisgICAgdHJ5IHsKKyAgICAgIHJvbGxMb2NrLmxvY2soKTsKKyAgICAgIHRoaXMuaW50ZXJydXB0KCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHJvbGxMb2NrLnVubG9jaygpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL0xydUhhc2hNYXAuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9McnVIYXNoTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZhMjNmYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9McnVIYXNoTWFwLmphdmEKQEAgLTAsMCArMSwxMDk5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5IZWFwU2l6ZTsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworCisvKioKKyAqIFRoZSBMcnVIYXNoTWFwIGlzIGEgbWVtb3J5LWF3YXJlIEhhc2hNYXAgd2l0aCBhIGNvbmZpZ3VyYWJsZSBtYXhpbXVtCisgKiBtZW1vcnkgZm9vdHByaW50LgorICogPHA+CisgKiBJdCBtYWludGFpbnMgYW4gb3JkZXJlZCBsaXN0IG9mIGFsbCBlbnRyaWVzIGluIHRoZSBtYXAgb3JkZXJlZCBieSAKKyAqIGFjY2VzcyB0aW1lLiAgV2hlbiBzcGFjZSBuZWVkcyB0byBiZSBmcmVlZCBiZWNhc2UgdGhlIG1heGltdW0gaGFzIGJlZW4gCisgKiByZWFjaGVkLCBvciB0aGUgYXBwbGljYXRpb24gaGFzIGFza2VkIHRvIGZyZWUgbWVtb3J5LCBlbnRyaWVzIHdpbGwgYmUKKyAqIGV2aWN0ZWQgYWNjb3JkaW5nIHRvIGFuIExSVSAobGVhc3QtcmVjZW50bHktdXNlZCkgYWxnb3JpdGhtLiAgVGhhdCBpcywKKyAqIHRob3NlIGVudHJpZXMgd2hpY2ggaGF2ZSBub3QgYmVlbiBhY2Nlc3NlZCB0aGUgbG9uZ2VzdCB3aWxsIGJlIGV2aWN0ZWQKKyAqIGZpcnN0LgorICogPHA+CisgKiBCb3RoIHRoZSBLZXkgYW5kIFZhbHVlIE9iamVjdHMgdXNlZCBmb3IgdGhpcyBjbGFzcyBtdXN0IGV4dGVuZAorICogPGNvZGU+SGVhcFNpemU8L2NvZGU+IGluIG9yZGVyIHRvIHRyYWNrIGhlYXAgdXNhZ2UuCisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgY29udGFpbnMgaW50ZXJuYWwgc3luY2hyb25pemF0aW9uIGFuZCBpcyB0aHJlYWQtc2FmZS4KKyAqLworcHVibGljIGNsYXNzIExydUhhc2hNYXA8SyBleHRlbmRzIEhlYXBTaXplLCBWIGV4dGVuZHMgSGVhcFNpemU+CitpbXBsZW1lbnRzIEhlYXBTaXplLCBNYXA8SyxWPiB7CisKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhMcnVIYXNoTWFwLmNsYXNzKTsKKyAgCisgIC8qKiBUaGUgZGVmYXVsdCBzaXplIChpbiBieXRlcykgb2YgdGhlIExSVSAqLyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgREVGQVVMVF9NQVhfTUVNX1VTQUdFID0gNTAwMDA7CisgIC8qKiBUaGUgZGVmYXVsdCBjYXBhY2l0eSBvZiB0aGUgaGFzaCB0YWJsZSAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9JTklUSUFMX0NBUEFDSVRZID0gMTY7CisgIC8qKiBUaGUgbWF4bXVtIGNhcGFjaXR5IG9mIHRoZSBoYXNoIHRhYmxlICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhJTVVNX0NBUEFDSVRZID0gMSA8PCAzMDsKKyAgLyoqIFRoZSBkZWZhdWx0IGxvYWQgZmFjdG9yIHRvIHVzZSAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBmbG9hdCBERUZBVUxUX0xPQURfRkFDVE9SID0gMC43NWY7CisgIAorICAvKiogTWVtb3J5IG92ZXJoZWFkIG9mIHRoaXMgT2JqZWN0IChmb3IgSGVhcFNpemUpICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPVkVSSEVBRCA9IDUgKiBIZWFwU2l6ZS5MT05HICsgMiAqIEhlYXBTaXplLklOVCArCisgICAgMiAqIEhlYXBTaXplLkZMT0FUICsgMyAqIEhlYXBTaXplLlJFRkVSRU5DRSArIDEgKiBIZWFwU2l6ZS5BUlJBWTsKKyAgCisgIC8qKiBMb2FkIGZhY3RvciBhbGxvd2VkICh1c3VhbGx5IDc1JSkgKi8KKyAgcHJpdmF0ZSBmaW5hbCBmbG9hdCBsb2FkRmFjdG9yOworICAvKiogTnVtYmVyIG9mIGtleS92YWxzIGluIHRoZSBtYXAgKi8KKyAgcHJpdmF0ZSBpbnQgc2l6ZTsKKyAgLyoqIFNpemUgYXQgd2hpY2ggd2UgZ3JvdyBoYXNoICovCisgIHByaXZhdGUgaW50IHRocmVzaG9sZDsKKyAgLyoqIEVudHJpZXMgaW4gdGhlIG1hcCAqLworICBwcml2YXRlIEVudHJ5IFtdIGVudHJpZXM7CisKKyAgLyoqIFBvaW50ZXIgdG8gbGVhc3QgcmVjZW50bHkgdXNlZCBlbnRyeSAqLworICBwcml2YXRlIEVudHJ5PEssVj4gaGVhZFB0cjsKKyAgLyoqIFBvaW50ZXIgdG8gbW9zdCByZWNlbnRseSB1c2VkIGVudHJ5ICovCisgIHByaXZhdGUgRW50cnk8SyxWPiB0YWlsUHRyOworCisgIC8qKiBNYXhpbXVtIG1lbW9yeSB1c2FnZSBvZiB0aGlzIG1hcCAqLworICBwcml2YXRlIGxvbmcgbWVtVG90YWwgPSAwOworICAvKiogQW1vdW50IG9mIGF2YWlsYWJsZSBtZW1vcnkgKi8KKyAgcHJpdmF0ZSBsb25nIG1lbUZyZWUgPSAwOworICAKKyAgLyoqIE51bWJlciBvZiBzdWNjZXNzZnVsIChmb3VuZCkgZ2V0KCkgY2FsbHMgKi8KKyAgcHJpdmF0ZSBsb25nIGhpdENvdW50ID0gMDsKKyAgLyoqIE51bWJlciBvZiB1bnN1Y2Nlc3NmdWwgKG5vdCBmb3VuZCkgZ2V0KCkgY2FsbHMgKi8KKyAgcHJpdmF0ZSBsb25nIG1pc3NDb3VudCA9IDA7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcsIGVtcHR5IG1hcCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBjYXBhY2l0eSwKKyAgICogbG9hZCBmYWN0b3IsIGFuZCBtYXhpbXVtIG1lbW9yeSB1c2FnZS4KKyAgICoKKyAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eSB0aGUgaW5pdGlhbCBjYXBhY2l0eQorICAgKiBAcGFyYW0gbG9hZEZhY3RvciB0aGUgbG9hZCBmYWN0b3IKKyAgICogQHBhcmFtIG1heE1lbVVzYWdlIHRoZSBtYXhpbXVtIHRvdGFsIG1lbW9yeSB1c2FnZQorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5pdGlhbCBjYXBhY2l0eSBpcyBsZXNzIHRoYW4gb25lCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbml0aWFsIGNhcGFjaXR5IGlzIGdyZWF0ZXIgdGhhbgorICAgKiB0aGUgbWF4aW11bSBjYXBhY2l0eQorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbG9hZCBmYWN0b3IgaXMgPD0gMAorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbWF4IG1lbW9yeSB1c2FnZSBpcyB0b28gc21hbGwKKyAgICogdG8gc3VwcG9ydCB0aGUgYmFzZSBvdmVyaGVhZAorICAgKi8KKyAgcHVibGljIExydUhhc2hNYXAoaW50IGluaXRpYWxDYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvciwKKyAgbG9uZyBtYXhNZW1Vc2FnZSkgeworICAgIGlmIChpbml0aWFsQ2FwYWNpdHkgPCAxKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbml0aWFsIGNhcGFjaXR5IG11c3QgYmUgPiAwIik7CisgICAgfQorICAgIGlmIChpbml0aWFsQ2FwYWNpdHkgPiBNQVhJTVVNX0NBUEFDSVRZKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbml0aWFsIGNhcGFjaXR5IGlzIHRvbyBsYXJnZSIpOworICAgIH0KKyAgICBpZiAobG9hZEZhY3RvciA8PSAwIHx8IEZsb2F0LmlzTmFOKGxvYWRGYWN0b3IpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJMb2FkIGZhY3RvciBtdXN0IGJlID4gMCIpOworICAgIH0KKyAgICBpZiAobWF4TWVtVXNhZ2UgPD0gKE9WRVJIRUFEICsgaW5pdGlhbENhcGFjaXR5ICogSGVhcFNpemUuUkVGRVJFTkNFKSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTWF4IG1lbW9yeSB1c2FnZSB0b28gc21hbGwgdG8gIiArCisgICAgICAic3VwcG9ydCBiYXNlIG92ZXJoZWFkIik7CisgICAgfQorICAKKyAgICAvKiogRmluZCBhIHBvd2VyIG9mIDIgPj0gaW5pdGlhbENhcGFjaXR5ICovCisgICAgaW50IGNhcGFjaXR5ID0gY2FsY3VsYXRlQ2FwYWNpdHkoaW5pdGlhbENhcGFjaXR5KTsKKyAgICB0aGlzLmxvYWRGYWN0b3IgPSBsb2FkRmFjdG9yOworICAgIHRoaXMudGhyZXNob2xkID0gY2FsY3VsYXRlVGhyZXNob2xkKGNhcGFjaXR5LGxvYWRGYWN0b3IpOworICAgIHRoaXMuZW50cmllcyA9IG5ldyBFbnRyeVtjYXBhY2l0eV07CisgICAgdGhpcy5tZW1GcmVlID0gbWF4TWVtVXNhZ2U7CisgICAgdGhpcy5tZW1Ub3RhbCA9IG1heE1lbVVzYWdlOworICAgIGluaXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIGEgbmV3LCBlbXB0eSBtYXAgd2l0aCB0aGUgc3BlY2lmaWVkIGluaXRpYWwgY2FwYWNpdHkgYW5kCisgICAqIGxvYWQgZmFjdG9yLCBhbmQgZGVmYXVsdCBtYXhpbXVtIG1lbW9yeSB1c2FnZS4KKyAgICoKKyAgICogQHBhcmFtIGluaXRpYWxDYXBhY2l0eSB0aGUgaW5pdGlhbCBjYXBhY2l0eQorICAgKiBAcGFyYW0gbG9hZEZhY3RvciB0aGUgbG9hZCBmYWN0b3IKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIG9uZQorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5pdGlhbCBjYXBhY2l0eSBpcyBncmVhdGVyIHRoYW4KKyAgICogdGhlIG1heGltdW0gY2FwYWNpdHkKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvYWQgZmFjdG9yIGlzIDw9IDAKKyAgICovCisgIHB1YmxpYyBMcnVIYXNoTWFwKGludCBpbml0aWFsQ2FwYWNpdHksIGZsb2F0IGxvYWRGYWN0b3IpIHsKKyAgICB0aGlzKGluaXRpYWxDYXBhY2l0eSwgbG9hZEZhY3RvciwgREVGQVVMVF9NQVhfTUVNX1VTQUdFKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcsIGVtcHR5IG1hcCB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBjYXBhY2l0eSBhbmQKKyAgICogd2l0aCB0aGUgZGVmYXVsdCBsb2FkIGZhY3RvciBhbmQgbWF4aW11bSBtZW1vcnkgdXNhZ2UuCisgICAqCisgICAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkgdGhlIGluaXRpYWwgY2FwYWNpdHkKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIG9uZQorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5pdGlhbCBjYXBhY2l0eSBpcyBncmVhdGVyIHRoYW4KKyAgICogdGhlIG1heGltdW0gY2FwYWNpdHkKKyAgICovCisgIHB1YmxpYyBMcnVIYXNoTWFwKGludCBpbml0aWFsQ2FwYWNpdHkpIHsKKyAgICB0aGlzKGluaXRpYWxDYXBhY2l0eSwgREVGQVVMVF9MT0FEX0ZBQ1RPUiwgREVGQVVMVF9NQVhfTUVNX1VTQUdFKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIGEgbmV3LCBlbXB0eSBtYXAgd2l0aCB0aGUgc3BlY2lmaWVkIG1heGltdW0gbWVtb3J5IHVzYWdlCisgICAqIGFuZCB3aXRoIGRlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSBhbmQgbG9hZCBmYWN0b3IuCisgICAqCisgICAqIEBwYXJhbSBtYXhNZW1Vc2FnZSB0aGUgbWF4aW11bSB0b3RhbCBtZW1vcnkgdXNhZ2UKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIG1heCBtZW1vcnkgdXNhZ2UgaXMgdG9vIHNtYWxsCisgICAqIHRvIHN1cHBvcnQgdGhlIGJhc2Ugb3ZlcmhlYWQKKyAgICovCisgIHB1YmxpYyBMcnVIYXNoTWFwKGxvbmcgbWF4TWVtVXNhZ2UpIHsKKyAgICB0aGlzKERFRkFVTFRfSU5JVElBTF9DQVBBQ0lUWSwgREVGQVVMVF9MT0FEX0ZBQ1RPUiwKKyAgICBtYXhNZW1Vc2FnZSk7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgbWFwIHdpdGggdGhlIGRlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSwgCisgICAqIGxvYWQgZmFjdG9yIGFuZCBtYXhpbXVtIG1lbW9yeSB1c2FnZS4KKyAgICovCisgIHB1YmxpYyBMcnVIYXNoTWFwKCkgeworICAgIHRoaXMoREVGQVVMVF9JTklUSUFMX0NBUEFDSVRZLCBERUZBVUxUX0xPQURfRkFDVE9SLAorICAgIERFRkFVTFRfTUFYX01FTV9VU0FHRSk7CisgIH0KKyAgCisgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLyoqCisgICAqIEdldCB0aGUgY3VycmVudGx5IGF2YWlsYWJsZSBtZW1vcnkgZm9yIHRoaXMgTFJVIGluIGJ5dGVzLgorICAgKiBUaGlzIGlzIChtYXhBbGxvd2VkIC0gY3VycmVudGx5VXNlZCkuCisgICAqCisgICAqIEByZXR1cm4gY3VycmVudGx5IGF2YWlsYWJsZSBieXRlcworICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0TWVtRnJlZSgpIHsKKyAgICByZXR1cm4gbWVtRnJlZTsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgbWF4aW11bSBtZW1vcnkgYWxsb3dlZCBmb3IgdGhpcyBMUlUgaW4gYnl0ZXMuCisgICAqCisgICAqIEByZXR1cm4gbWF4aW11bSBhbGxvd2VkIGJ5dGVzCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRNZW1NYXgoKSB7CisgICAgcmV0dXJuIG1lbVRvdGFsOworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSBjdXJyZW50bHkgdXNlZCBtZW1vcnkgZm9yIHRoaXMgTFJVIGluIGJ5dGVzLgorICAgKgorICAgKiBAcmV0dXJuIGN1cnJlbnRseSB1c2VkIG1lbW9yeSBpbiBieXRlcworICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0TWVtVXNlZCgpIHsKKyAgICByZXR1cm4gKG1lbVRvdGFsIC0gbWVtRnJlZSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIG51bWJlciBvZiBoaXRzIHRvIHRoZSBtYXAuICBUaGlzIGlzIHRoZSBudW1iZXIgb2YgdGltZXMKKyAgICogYSBjYWxsIHRvIGdldCgpIHJldHVybnMgYSBtYXRjaGVkIGtleS4KKyAgICoKKyAgICogQHJldHVybiBudW1iZXIgb2YgaGl0cworICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0SGl0Q291bnQoKSB7CisgICAgcmV0dXJuIGhpdENvdW50OworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSBudW1iZXIgb2YgbWlzc2VzIHRvIHRoZSBtYXAuICBUaGlzIGlzIHRoZSBudW1iZXIgb2YgdGltZXMKKyAgICogYSBjYWxsIHRvIGdldCgpIHJldHVybnMgbnVsbC4KKyAgICoKKyAgICogQHJldHVybiBudW1iZXIgb2YgbWlzc2VzCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRNaXNzQ291bnQoKSB7CisgICAgcmV0dXJuIG1pc3NDb3VudDsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgaGl0IHJhdGlvLiAgVGhpcyBpcyB0aGUgbnVtYmVyIG9mIGhpdHMgZGl2aWRlZCBieSB0aGUKKyAgICogdG90YWwgbnVtYmVyIG9mIHJlcXVlc3RzLgorICAgKgorICAgKiBAcmV0dXJuIGhpdCByYXRpbyAoZG91YmxlIGJldHdlZW4gMCBhbmQgMSkKKyAgICovCisgIHB1YmxpYyBkb3VibGUgZ2V0SGl0UmF0aW8oKSB7CisgICAgcmV0dXJuIChkb3VibGUpKChkb3VibGUpaGl0Q291bnQvCisgICAgICAoKGRvdWJsZSkoaGl0Q291bnQrbWlzc0NvdW50KSkpOworICB9CisgIAorICAvKioKKyAgICogRnJlZSB0aGUgcmVxdWVzdGVkIGFtb3VudCBvZiBtZW1vcnkgZnJvbSB0aGUgTFJVIG1hcC4KKyAgICoKKyAgICogVGhpcyB3aWxsIGRvIExSVSBldmljdGlvbiBmcm9tIHRoZSBtYXAgdW50aWwgYXQgbGVhc3QgYXMgbXVjaAorICAgKiBtZW1vcnkgYXMgcmVxdWVzdGVkIGlzIGZyZWVkLiAgVGhpcyBkb2VzIG5vdCBhZmZlY3QgdGhlIG1heGltdW0KKyAgICogbWVtb3J5IHVzYWdlIHBhcmFtZXRlci4KKyAgICoKKyAgICogQHBhcmFtIHJlcXVlc3RlZEFtb3VudCBtZW1vcnkgdG8gZnJlZSBmcm9tIExSVSBpbiBieXRlcworICAgKiBAcmV0dXJuIGFjdHVhbCBhbW91bnQgb2YgbWVtb3J5IGZyZWVkIGluIGJ5dGVzCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIGxvbmcgZnJlZU1lbW9yeShsb25nIHJlcXVlc3RlZEFtb3VudCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbG9uZyBtaW5NZW1vcnkgPSBnZXRNaW5pbXVtVXNhZ2UoKTsKKyAgICBpZihyZXF1ZXN0ZWRBbW91bnQgPiAoZ2V0TWVtVXNlZCgpIC0gZ2V0TWluaW11bVVzYWdlKCkpKSB7CisgICAgICByZXR1cm4gY2xlYXJBbGwoKTsKKyAgICB9CisgICAgbG9uZyBmcmVlZE1lbW9yeSA9IDA7CisgICAgd2hpbGUoZnJlZWRNZW1vcnkgPCByZXF1ZXN0ZWRBbW91bnQpIHsKKyAgICAgIGZyZWVkTWVtb3J5ICs9IGV2aWN0RnJvbUxydSgpOworICAgIH0KKyAgICByZXR1cm4gZnJlZWRNZW1vcnk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUaGUgdG90YWwgbWVtb3J5IHVzYWdlIG9mIHRoaXMgbWFwCisgICAqCisgICAqIEByZXR1cm4gbWVtb3J5IHVzYWdlIG9mIG1hcCBpbiBieXRlcworICAgKi8KKyAgcHVibGljIGxvbmcgaGVhcFNpemUoKSB7CisgICAgcmV0dXJuIChtZW1Ub3RhbCAtIG1lbUZyZWUpOworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBSZXRyaWV2ZXMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KKyAgICoKKyAgICogSWYgYW4gZW50cnkgaXMgZm91bmQsIGl0IGlzIHVwZGF0ZWQgaW4gdGhlIExSVSBhcyB0aGUgbW9zdCByZWNlbnRseQorICAgKiB1c2VkIChsYXN0IHRvIGJlIGV2aWN0ZWQpIGVudHJ5IGluIHRoZSBtYXAuCisgICAqCisgICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAgKiBAcmV0dXJuIHRoZSBhc3NvY2lhdGVkIHZhbHVlLCBvciBudWxsIGlmIG5vbmUgZm91bmQKKyAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBrZXkgaXMgbnVsbAorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCBWIGdldChPYmplY3Qga2V5KSB7CisgICAgY2hlY2tLZXkoKEspa2V5KTsKKyAgICBpbnQgaGFzaCA9IGhhc2goa2V5KTsKKyAgICBpbnQgaSA9IGhhc2hJbmRleChoYXNoLCBlbnRyaWVzLmxlbmd0aCk7CisgICAgRW50cnk8SyxWPiBlID0gZW50cmllc1tpXTsgCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGlmIChlID09IG51bGwpIHsKKyAgICAgICAgbWlzc0NvdW50Kys7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKGUuaGFzaCA9PSBoYXNoICYmIGlzRXF1YWwoa2V5LCBlLmtleSkpICB7CisgICAgICAgIC8vIEhpdCEgIFVwZGF0ZSBwb3NpdGlvbiBpbiBMUlUKKyAgICAgICAgaGl0Q291bnQrKzsKKyAgICAgICAgdXBkYXRlTHJ1KGUpOworICAgICAgICByZXR1cm4gZS52YWx1ZTsKKyAgICAgIH0KKyAgICAgIGUgPSBlLm5leHQ7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEluc2VydCBhIGtleS12YWx1ZSBtYXBwaW5nIGludG8gdGhlIG1hcC4KKyAgICoKKyAgICogRW50cnkgd2lsbCBiZSBpbnNlcnRlZCBhcyB0aGUgbW9zdCByZWNlbnRseSB1c2VkLgorICAgKgorICAgKiBCb3RoIHRoZSBrZXkgYW5kIHZhbHVlIGFyZSByZXF1aXJlZCB0byBiZSBPYmplY3RzIGFuZCBtdXN0CisgICAqIGltcGxlbWVudCB0aGUgSGVhcFNpemUgaW50ZXJmYWNlLgorICAgKgorICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZQorICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSB0aGF0IHdhcyBwcmV2aW91c2x5IG1hcHBlZCB0byB0aGlzIGtleSwgbnVsbCBpZiBub25lCisgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgZWl0aGVyIG9iamVjdHMgZG8gbm90IAorICAgKiBpbXBsZW1lbnQgSGVhcFNpemUKKyAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUga2V5IG9yIHZhbHVlIGlzIG51bGwKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICBjaGVja0tleShrZXkpOworICAgIGNoZWNrVmFsdWUodmFsdWUpOworICAgIGludCBoYXNoID0gaGFzaChrZXkpOworICAgIGludCBpID0gaGFzaEluZGV4KGhhc2gsIGVudHJpZXMubGVuZ3RoKTsKKyAgICAKKyAgICAvLyBGb3Igb2xkIHZhbHVlcworICAgIGZvciAoRW50cnk8SyxWPiBlID0gZW50cmllc1tpXTsgZSAhPSBudWxsOyBlID0gZS5uZXh0KSB7CisgICAgICBpZiAoZS5oYXNoID09IGhhc2ggJiYgaXNFcXVhbChrZXksIGUua2V5KSkgeworICAgICAgICBWIG9sZFZhbHVlID0gZS52YWx1ZTsKKyAgICAgICAgbG9uZyBtZW1DaGFuZ2UgPSBlLnJlcGxhY2VWYWx1ZSh2YWx1ZSk7CisgICAgICAgIGNoZWNrQW5kRnJlZU1lbW9yeShtZW1DaGFuZ2UpOworICAgICAgICAvLyBJZiByZXBsYWNpbmcgYW4gb2xkIHZhbHVlIGZvciB0aGlzIGtleSwgdXBkYXRlIGluIExSVQorICAgICAgICB1cGRhdGVMcnUoZSk7CisgICAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgbG9uZyBtZW1DaGFuZ2UgPSBhZGRFbnRyeShoYXNoLCBrZXksIHZhbHVlLCBpKTsKKyAgICBjaGVja0FuZEZyZWVNZW1vcnkobWVtQ2hhbmdlKTsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorICAKKyAgLyoqCisgICAqIERlbGV0ZXMgdGhlIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQga2V5IGlmIGl0IGV4aXN0cy4KKyAgICoKKyAgICogQHBhcmFtIGtleSB0aGUga2V5IG9mIHRoZSBlbnRyeSB0byBiZSByZW1vdmVkIGZyb20gdGhlIG1hcAorICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXksIG9yIG51bGwKKyAgICogaWYgbm8gbWFwcGluZyBleGlzdHMuCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIFYgcmVtb3ZlKE9iamVjdCBrZXkpIHsKKyAgICBFbnRyeTxLLFY+IGUgPSByZW1vdmVFbnRyeUZvcktleSgoSylrZXkpOworICAgIGlmKGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CisgICAgLy8gQWRkIGZyZWVkIG1lbW9yeSBiYWNrIHRvIGF2YWlsYWJsZQorICAgIG1lbUZyZWUgKz0gZS5oZWFwU2l6ZSgpOworICAgIHJldHVybiBlLnZhbHVlOworICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIHNpemUgKG51bWJlciBvZiBlbnRyaWVzKSBvZiB0aGUgbWFwLgorICAgKgorICAgKiBAcmV0dXJuIHNpemUgb2YgdGhlIG1hcAorICAgKi8KKyAgcHVibGljIGludCBzaXplKCkgeworICAgIHJldHVybiBzaXplOworICB9CisKKyAgLyoqCisgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBtYXAgaXMgY3VycmVudGx5IGVtcHR5LgorICAgKgorICAgKiBAcmV0dXJuIHRydWUgaWYgc2l6ZSBvZiBtYXAgaXMgemVybworICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKKyAgICByZXR1cm4gc2l6ZSA9PSAwOworICB9CisKKyAgLyoqCisgICAqIENsZWFycyBhbGwgZW50cmllcyBmcm9tIHRoZSBtYXAuCisgICAqCisgICAqIFRoaXMgZnJlZXMgYWxsIGVudHJpZXMsIHRyYWNraW5nIG1lbW9yeSB1c2FnZSBhbG9uZyB0aGUgd2F5LgorICAgKiBBbGwgcmVmZXJlbmNlcyB0byBlbnRyaWVzIGFyZSByZW1vdmVkIHNvIHRoZXkgY2FuIGJlIEdDJ2QuCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xlYXIoKSB7CisgICAgbWVtRnJlZSArPSBjbGVhckFsbCgpOworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBDaGVja3Mgd2hldGhlciB0aGVyZSBpcyBhIHZhbHVlIGluIHRoZSBtYXAgZm9yIHRoZSBzcGVjaWZpZWQga2V5LgorICAgKgorICAgKiBEb2VzIG5vdCBhZmZlY3QgdGhlIExSVS4KKyAgICoKKyAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIGNoZWNrCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWFwIGNvbnRhaW5zIGEgdmFsdWUgZm9yIHRoaXMga2V5LCBmYWxzZSBpZiBub3QKKyAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUga2V5IGlzIG51bGwKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBjb250YWluc0tleShPYmplY3Qga2V5KSB7CisgICAgY2hlY2tLZXkoKEspa2V5KTsKKyAgICBpbnQgaGFzaCA9IGhhc2goa2V5KTsKKyAgICBpbnQgaSA9IGhhc2hJbmRleChoYXNoLCBlbnRyaWVzLmxlbmd0aCk7CisgICAgRW50cnkgZSA9IGVudHJpZXNbaV07IAorICAgIHdoaWxlIChlICE9IG51bGwpIHsKKyAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBpc0VxdWFsKGtleSwgZS5rZXkpKSAKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGUgPSBlLm5leHQ7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3Mgd2hldGhlciB0aGlzIGlzIGEgbWFwcGluZyB3aGljaCBjb250YWlucyB0aGUgc3BlY2lmaWVkIHZhbHVlLgorICAgKiAKKyAgICogRG9lcyBub3QgYWZmZWN0IHRoZSBMUlUuICBUaGlzIGlzIGFuIGluZWZmaWNpZW50IG9wZXJhdGlvbi4KKyAgICoKKyAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBjaGVjaworICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG1hcCBjb250YWlucyBhbiBlbnRyeSBmb3IgdGhpcyB2YWx1ZSwgZmFsc2UKKyAgICogaWYgbm90CisgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHZhbHVlIGlzIG51bGwKKyAgICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgYm9vbGVhbiBjb250YWluc1ZhbHVlKE9iamVjdCB2YWx1ZSkgeworICAgIGNoZWNrVmFsdWUoKFYpdmFsdWUpOworICAgIEVudHJ5W10gdGFiID0gZW50cmllczsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRhYi5sZW5ndGggOyBpKyspCisgICAgICBmb3IgKEVudHJ5IGUgPSB0YWJbaV0gOyBlICE9IG51bGwgOyBlID0gZS5uZXh0KQorICAgICAgICAgIGlmICh2YWx1ZS5lcXVhbHMoZS52YWx1ZSkpCisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBFbmZvcmNlcyBrZXkgY29uc3RyYWludHMuICBOdWxsIGtleXMgYXJlIG5vdCBwZXJtaXR0ZWQgYW5kIGtleSBtdXN0CisgICAqIGltcGxlbWVudCBIZWFwU2l6ZS4gIEl0IHNob3VsZCBub3QgYmUgbmVjZXNzYXJ5IHRvIHZlcmlmeSB0aGUgc2Vjb25kCisgICAqIGNvbnN0cmFpbnQgYmVjYXVzZSB0aGF0J3MgZW5mb3JjZWQgb24gaW5zdGFudGlhdGlvbj8KKyAgICoKKyAgICogQ2FuIGFkZCBvdGhlciBjb25zdHJhaW50cyBpbiB0aGUgZnV0dXJlLgorICAgKgorICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUga2V5IGlzIG51bGwKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUga2V5IGNsYXNzIGRvZXMgbm90CisgICAqIGltcGxlbWVudCB0aGUgSGVhcFNpemUgaW50ZXJmYWNlCisgICAqLworICBwcml2YXRlIHZvaWQgY2hlY2tLZXkoSyBrZXkpIHsKKyAgICBpZihrZXkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJudWxsIGtleXMgYXJlIG5vdCBhbGxvd2VkIik7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogRW5mb3JjZXMgdmFsdWUgY29uc3RyYWludHMuICBOdWxsIHZhbHVlcyBhcmUgbm90IHBlcm1pdHRlZCBhbmQgdmFsdWUgbXVzdAorICAgKiBpbXBsZW1lbnQgSGVhcFNpemUuICBJdCBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeSB0byB2ZXJpZnkgdGhlIHNlY29uZAorICAgKiBjb25zdHJhaW50IGJlY2F1c2UgdGhhdCdzIGVuZm9yY2VkIG9uIGluc3RhbnRpYXRpb24/CisgICAqCisgICAqIENhbiBhZGQgb3RoZXIgY29udHJhaW50cyBpbiB0aGUgZnV0dXJlLgorICAgKgorICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlCisgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIHZhbHVlIGlzIG51bGwKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGUgdmFsdWUgY2xhc3MgZG9lcyBub3QKKyAgICogaW1wbGVtZW50IHRoZSBIZWFwU2l6ZSBpbnRlcmZhY2UKKyAgICovCisgIHByaXZhdGUgdm9pZCBjaGVja1ZhbHVlKFYgdmFsdWUpIHsKKyAgICBpZih2YWx1ZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm51bGwgdmFsdWVzIGFyZSBub3QgYWxsb3dlZCIpOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIG1pbmltdW0gbWVtb3J5IHVzYWdlIG9mIHRoZSBiYXNlIG1hcCBzdHJ1Y3R1cmUuCisgICAqCisgICAqIEByZXR1cm4gYmFzZWxpbmUgbWVtb3J5IG92ZXJoZWFkIG9mIG9iamVjdCBpbiBieXRlcworICAgKi8KKyAgcHJpdmF0ZSBsb25nIGdldE1pbmltdW1Vc2FnZSgpIHsKKyAgICByZXR1cm4gT1ZFUkhFQUQgKyAoZW50cmllcy5sZW5ndGggKiBIZWFwU2l6ZS5SRUZFUkVOQ0UpOworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBFdmljdHMgYW5kIGZyZWVzIGJhc2VkIG9uIExSVSB1bnRpbCBhdCBsZWFzdCBhcyBtdWNoIG1lbW9yeSBhcyByZXF1ZXN0ZWQKKyAgICogaXMgYXZhaWxhYmxlLgorICAgKgorICAgKiBAcGFyYW0gbWVtTmVlZGVkIHRoZSBhbW91bnQgb2YgbWVtb3J5IG5lZWRlZCBpbiBieXRlcworICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNoZWNrQW5kRnJlZU1lbW9yeShsb25nIG1lbU5lZWRlZCkgeworICAgIHdoaWxlKG1lbUZyZWUgPCBtZW1OZWVkZWQpIHsKKyAgICAgIGV2aWN0RnJvbUxydSgpOworICAgIH0KKyAgICBtZW1GcmVlIC09IG1lbU5lZWRlZDsKKyAgfQorCisgIC8qKgorICAgKiBFdmljdHMgYmFzZWQgb24gTFJVLiAgVGhpcyByZW1vdmVzIGFsbCByZWZlcmVuY2VzIGFuZCB1cGRhdGVzIGF2YWlsYWJsZQorICAgKiBtZW1vcnkuCisgICAqCisgICAqIEByZXR1cm4gYW1vdW50IG9mIG1lbW9yeSBmcmVlZCBpbiBieXRlcworICAgKi8KKyAgcHJpdmF0ZSBsb25nIGV2aWN0RnJvbUxydSgpIHsKKyAgICBsb25nIGZyZWVkID0gaGVhZFB0ci5oZWFwU2l6ZSgpOworICAgIG1lbUZyZWUgKz0gZnJlZWQ7CisgICAgcmVtb3ZlRW50cnkoaGVhZFB0cik7CisgICAgcmV0dXJuIGZyZWVkOworICB9CisgIAorICAvKioKKyAgICogTW92ZXMgdGhlIHNwZWNpZmllZCBlbnRyeSB0byB0aGUgbW9zdCByZWNlbnRseSB1c2VkIHNsb3Qgb2YgdGhlCisgICAqIExSVS4gIFRoaXMgaXMgY2FsbGVkIHdoZW5ldmVyIGFuIGVudHJ5IGlzIGZldGNoZWQuCisgICAqCisgICAqIEBwYXJhbSBlIGVudHJ5IHRoYXQgd2FzIGFjY2Vzc2VkCisgICAqLworICBwcml2YXRlIHZvaWQgdXBkYXRlTHJ1KEVudHJ5PEssVj4gZSkgeworICAgIEVudHJ5PEssVj4gcHJldiA9IGUuZ2V0UHJldlB0cigpOworICAgIEVudHJ5PEssVj4gbmV4dCA9IGUuZ2V0TmV4dFB0cigpOworICAgIGlmKG5leHQgIT0gbnVsbCkgeworICAgICAgaWYocHJldiAhPSBudWxsKSB7CisgICAgICAgIHByZXYuc2V0TmV4dFB0cihuZXh0KTsKKyAgICAgICAgbmV4dC5zZXRQcmV2UHRyKHByZXYpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaGVhZFB0ciA9IG5leHQ7CisgICAgICAgIGhlYWRQdHIuc2V0UHJldlB0cihudWxsKTsKKyAgICAgIH0KKyAgICAgIGUuc2V0TmV4dFB0cihudWxsKTsKKyAgICAgIGUuc2V0UHJldlB0cih0YWlsUHRyKTsKKyAgICAgIHRhaWxQdHIuc2V0TmV4dFB0cihlKTsKKyAgICAgIHRhaWxQdHIgPSBlOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgZW50cnkgZnJvbSB0aGUgbWFwIGFuZCBMUlUgc3RydWN0dXJlLgorICAgKgorICAgKiBAcGFyYW0gZW50cnkgZW50cnkgdG8gYmUgcmVtb3ZlZAorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJlbW92ZUVudHJ5KEVudHJ5PEssVj4gZW50cnkpIHsKKyAgICBLIGsgPSBlbnRyeS5rZXk7CisgICAgaW50IGhhc2ggPSBlbnRyeS5oYXNoOworICAgIGludCBpID0gaGFzaEluZGV4KGhhc2gsIGVudHJpZXMubGVuZ3RoKTsKKyAgICBFbnRyeTxLLFY+IHByZXYgPSBlbnRyaWVzW2ldOworICAgIEVudHJ5PEssVj4gZSA9IHByZXY7CisKKyAgICB3aGlsZSAoZSAhPSBudWxsKSB7CisgICAgICBFbnRyeTxLLFY+IG5leHQgPSBlLm5leHQ7CisgICAgICBpZiAoZS5oYXNoID09IGhhc2ggJiYgaXNFcXVhbChrLCBlLmtleSkpIHsKKyAgICAgICAgICBzaXplLS07CisgICAgICAgICAgaWYgKHByZXYgPT0gZSkgeworICAgICAgICAgICAgZW50cmllc1tpXSA9IG5leHQ7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByZXYubmV4dCA9IG5leHQ7CisgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIEVudHJ5PEssVj4gcHJldlB0ciA9IGUuZ2V0UHJldlB0cigpOworICAgICAgICAgIEVudHJ5PEssVj4gbmV4dFB0ciA9IGUuZ2V0TmV4dFB0cigpOworICAgICAgICAgIAorICAgICAgICAgIGlmKHByZXZQdHIgIT0gbnVsbCAmJiBuZXh0UHRyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByZXZQdHIuc2V0TmV4dFB0cihuZXh0UHRyKTsKKyAgICAgICAgICAgIG5leHRQdHIuc2V0UHJldlB0cihwcmV2UHRyKTsKKyAgICAgICAgICB9IGVsc2UgaWYocHJldlB0ciAhPSBudWxsKSB7CisgICAgICAgICAgICB0YWlsUHRyID0gcHJldlB0cjsKKyAgICAgICAgICAgIHByZXZQdHIuc2V0TmV4dFB0cihudWxsKTsKKyAgICAgICAgICB9IGVsc2UgaWYobmV4dFB0ciAhPSBudWxsKSB7CisgICAgICAgICAgICBoZWFkUHRyID0gbmV4dFB0cjsKKyAgICAgICAgICAgIG5leHRQdHIuc2V0UHJldlB0cihudWxsKTsKKyAgICAgICAgICB9CisgICAgICAgICAgCisgICAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgcHJldiA9IGU7CisgICAgICBlID0gbmV4dDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVtb3ZlcyBhbmQgcmV0dXJucyB0aGUgZW50cnkgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICoga2V5LgorICAgKgorICAgKiBAcGFyYW0ga2V5IGtleSBvZiB0aGUgZW50cnkgdG8gYmUgZGVsZXRlZAorICAgKiBAcmV0dXJuIGVudHJ5IHRoYXQgd2FzIHJlbW92ZWQsIG9yIG51bGwgaWYgbm9uZSBmb3VuZAorICAgKi8KKyAgcHJpdmF0ZSBFbnRyeTxLLFY+IHJlbW92ZUVudHJ5Rm9yS2V5KEsga2V5KSB7CisgICAgaW50IGhhc2ggPSBoYXNoKGtleSk7CisgICAgaW50IGkgPSBoYXNoSW5kZXgoaGFzaCwgZW50cmllcy5sZW5ndGgpOworICAgIEVudHJ5PEssVj4gcHJldiA9IGVudHJpZXNbaV07CisgICAgRW50cnk8SyxWPiBlID0gcHJldjsKKworICAgIHdoaWxlIChlICE9IG51bGwpIHsKKyAgICAgIEVudHJ5PEssVj4gbmV4dCA9IGUubmV4dDsKKyAgICAgIGlmIChlLmhhc2ggPT0gaGFzaCAmJiBpc0VxdWFsKGtleSwgZS5rZXkpKSB7CisgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgIGlmIChwcmV2ID09IGUpIHsKKyAgICAgICAgICAgIGVudHJpZXNbaV0gPSBuZXh0OworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmV2Lm5leHQgPSBuZXh0OworICAgICAgICAgIH0KKyAgICAgICAgICAKKyAgICAgICAgICAvLyBVcGRhdGluZyBMUlUKKyAgICAgICAgICBFbnRyeTxLLFY+IHByZXZQdHIgPSBlLmdldFByZXZQdHIoKTsKKyAgICAgICAgICBFbnRyeTxLLFY+IG5leHRQdHIgPSBlLmdldE5leHRQdHIoKTsKKyAgICAgICAgICBpZihwcmV2UHRyICE9IG51bGwgJiYgbmV4dFB0ciAhPSBudWxsKSB7CisgICAgICAgICAgICBwcmV2UHRyLnNldE5leHRQdHIobmV4dFB0cik7CisgICAgICAgICAgICBuZXh0UHRyLnNldFByZXZQdHIocHJldlB0cik7CisgICAgICAgICAgfSBlbHNlIGlmKHByZXZQdHIgIT0gbnVsbCkgeworICAgICAgICAgICAgdGFpbFB0ciA9IHByZXZQdHI7CisgICAgICAgICAgICBwcmV2UHRyLnNldE5leHRQdHIobnVsbCk7CisgICAgICAgICAgfSBlbHNlIGlmKG5leHRQdHIgIT0gbnVsbCkgeworICAgICAgICAgICAgaGVhZFB0ciA9IG5leHRQdHI7CisgICAgICAgICAgICBuZXh0UHRyLnNldFByZXZQdHIobnVsbCk7CisgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIHJldHVybiBlOworICAgICAgfQorICAgICAgcHJldiA9IGU7CisgICAgICBlID0gbmV4dDsKKyAgICB9CisKKyAgICByZXR1cm4gZTsKKyAgfQorCisgLyoqCisgICogQWRkcyBhIG5ldyBlbnRyeSB3aXRoIHRoZSBzcGVjaWZpZWQga2V5LCB2YWx1ZSwgaGFzaCBjb2RlLCBhbmQKKyAgKiBidWNrZXQgaW5kZXggdG8gdGhlIG1hcC4KKyAgKgorICAqIEFsc28gcHV0cyBpdCBpbiB0aGUgYm90dG9tIChtb3N0LXJlY2VudCkgc2xvdCBvZiB0aGUgbGlzdCBhbmQKKyAgKiBjaGVja3MgdG8gc2VlIGlmIHdlIG5lZWQgdG8gZ3JvdyB0aGUgYXJyYXkuCisgICoKKyAgKiBAcGFyYW0gaGFzaCBoYXNoIHZhbHVlIG9mIGtleQorICAqIEBwYXJhbSBrZXkgdGhlIGtleQorICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUKKyAgKiBAcGFyYW0gYnVja2V0SW5kZXggaW5kZXggaW50byBoYXNoIGFycmF5IHRvIHN0b3JlIHRoaXMgZW50cnkKKyAgKiBAcmV0dXJuIHRoZSBhbW91bnQgb2YgaGVhcCBzaXplIHVzZWQgdG8gc3RvcmUgdGhlIG5ldyBlbnRyeQorICAqLworICBwcml2YXRlIGxvbmcgYWRkRW50cnkoaW50IGhhc2gsIEsga2V5LCBWIHZhbHVlLCBpbnQgYnVja2V0SW5kZXgpIHsKKyAgICBFbnRyeTxLLFY+IGUgPSBlbnRyaWVzW2J1Y2tldEluZGV4XTsKKyAgICBFbnRyeTxLLFY+IG5ld0UgPSBuZXcgRW50cnk8SyxWPihoYXNoLCBrZXksIHZhbHVlLCBlLCB0YWlsUHRyKTsKKyAgICBlbnRyaWVzW2J1Y2tldEluZGV4XSA9IG5ld0U7CisgICAgLy8gYWRkIGFzIG1vc3QgcmVjZW50bHkgdXNlZCBpbiBscnUKKyAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICBoZWFkUHRyID0gbmV3RTsKKyAgICAgIHRhaWxQdHIgPSBuZXdFOworICAgIH0gZWxzZSB7CisgICAgICBuZXdFLnNldFByZXZQdHIodGFpbFB0cik7CisgICAgICB0YWlsUHRyLnNldE5leHRQdHIobmV3RSk7CisgICAgICB0YWlsUHRyID0gbmV3RTsKKyAgICB9CisgICAgLy8gR3JvdyB0YWJsZSBpZiB3ZSBhcmUgcGFzdCB0aGUgdGhyZXNob2xkIG5vdworICAgIGlmIChzaXplKysgPj0gdGhyZXNob2xkKSB7CisgICAgICBncm93VGFibGUoMiAqIGVudHJpZXMubGVuZ3RoKTsKKyAgICB9CisgICAgcmV0dXJuIG5ld0UuaGVhcFNpemUoKTsKKyAgfQorCisgIC8qKgorICAgKiBDbGVhcnMgYWxsIHRoZSBlbnRyaWVzIGluIHRoZSBtYXAuICBUcmFja3MgdGhlIGFtb3VudCBvZiBtZW1vcnkgYmVpbmcKKyAgICogZnJlZWQgYWxvbmcgdGhlIHdheSBhbmQgcmV0dXJucyB0aGUgdG90YWwuCisgICAqCisgICAqIENsZWFucyB1cCBhbGwgcmVmZXJlbmNlcyB0byBhbGxvdyBvbGQgZW50cmllcyB0byBiZSBHQydkLgorICAgKgorICAgKiBAcmV0dXJuIHRvdGFsIG1lbW9yeSBmcmVlZCBpbiBieXRlcworICAgKi8KKyAgcHJpdmF0ZSBsb25nIGNsZWFyQWxsKCkgeworICAgIEVudHJ5IGN1cjsKKyAgICBFbnRyeSBwcmV2OworICAgIGxvbmcgZnJlZWRNZW1vcnkgPSAwOworICAgIGZvcihpbnQgaT0wOyBpPGVudHJpZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIGN1ciA9IGVudHJpZXNbaV07CisgICAgICB3aGlsZShjdXIgIT0gbnVsbCkgeworICAgICAgICBmcmVlZE1lbW9yeSArPSBjdXIuaGVhcFNpemUoKTsKKyAgICAgICAgY3VyID0gY3VyLm5leHQ7CisgICAgICB9CisgICAgICBlbnRyaWVzW2ldID0gbnVsbDsKKyAgICB9CisgICAgaGVhZFB0ciA9IG51bGw7CisgICAgdGFpbFB0ciA9IG51bGw7CisgICAgc2l6ZSA9IDA7CisgICAgcmV0dXJuIGZyZWVkTWVtb3J5OworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBSZWNyZWF0ZXMgdGhlIGVudGlyZSBjb250ZW50cyBvZiB0aGUgaGFzaG1hcCBpbnRvIGEgbmV3IGFycmF5CisgICAqIHdpdGggZG91YmxlIHRoZSBjYXBhY2l0eS4gIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIHRoZSBudW1iZXIgb2YKKyAgICoga2V5cyBpbiB0aGUgbWFwIHJlYWNoZXMgdGhlIGN1cnJlbnQgdGhyZXNob2xkLgorICAgKgorICAgKiBAcGFyYW0gbmV3Q2FwYWNpdHkgdGhlIG5ldyBzaXplIG9mIHRoZSBoYXNoIGVudHJpZXMKKyAgICovCisgIHByaXZhdGUgdm9pZCBncm93VGFibGUoaW50IG5ld0NhcGFjaXR5KSB7CisgICAgRW50cnkgW10gb2xkVGFibGUgPSBlbnRyaWVzOworICAgIGludCBvbGRDYXBhY2l0eSA9IG9sZFRhYmxlLmxlbmd0aDsKKyAgICAKKyAgICAvLyBEbyBub3QgYWxsb3cgZ3Jvd2luZyB0aGUgdGFibGUgYmV5b25kIHRoZSBtYXggY2FwYWNpdHkKKyAgICBpZiAob2xkQ2FwYWNpdHkgPT0gTUFYSU1VTV9DQVBBQ0lUWSkgeworICAgICAgdGhyZXNob2xkID0gSW50ZWdlci5NQVhfVkFMVUU7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gRGV0ZXJtaW5lIGhvdyBtdWNoIGFkZGl0aW9uYWwgc3BhY2Ugd2lsbCBiZSByZXF1aXJlZCB0byBncm93IHRoZSBhcnJheQorICAgIGxvbmcgcmVxdWlyZWRTcGFjZSA9IChuZXdDYXBhY2l0eSAtIG9sZENhcGFjaXR5KSAqIEhlYXBTaXplLlJFRkVSRU5DRTsKKyAgICAKKyAgICAvLyBWZXJpZnkvZW5mb3JjZSB3ZSBoYXZlIHN1ZmZpY2llbnQgbWVtb3J5IHRvIGdyb3cKKyAgICBjaGVja0FuZEZyZWVNZW1vcnkocmVxdWlyZWRTcGFjZSk7CisKKyAgICBFbnRyeSBbXSBuZXdUYWJsZSA9IG5ldyBFbnRyeVtuZXdDYXBhY2l0eV07CisgICAgCisgICAgLy8gVHJhbnNmZXIgZXhpc3RpbmcgZW50cmllcyB0byBuZXcgaGFzaCB0YWJsZQorICAgIGZvcihpbnQgaT0wOyBpIDwgb2xkQ2FwYWNpdHk7IGkrKykgeworICAgICAgRW50cnk8SyxWPiBlbnRyeSA9IG9sZFRhYmxlW2ldOworICAgICAgaWYoZW50cnkgIT0gbnVsbCkgeworICAgICAgICAvLyBTZXQgdG8gbnVsbCBmb3IgR0MKKyAgICAgICAgb2xkVGFibGVbaV0gPSBudWxsOworICAgICAgICBkbyB7CisgICAgICAgICAgRW50cnk8SyxWPiBuZXh0ID0gZW50cnkubmV4dDsKKyAgICAgICAgICBpbnQgaWR4ID0gaGFzaEluZGV4KGVudHJ5Lmhhc2gsIG5ld0NhcGFjaXR5KTsKKyAgICAgICAgICBlbnRyeS5uZXh0ID0gbmV3VGFibGVbaWR4XTsKKyAgICAgICAgICBuZXdUYWJsZVtpZHhdID0gZW50cnk7CisgICAgICAgICAgZW50cnkgPSBuZXh0OworICAgICAgICB9IHdoaWxlKGVudHJ5ICE9IG51bGwpOworICAgICAgfQorICAgIH0KKworICAgIGVudHJpZXMgPSBuZXdUYWJsZTsKKyAgICB0aHJlc2hvbGQgPSAoaW50KShuZXdDYXBhY2l0eSAqIGxvYWRGYWN0b3IpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIHNwZWNpZmllZCBrZXkuCisgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyB0aGUgYWRkaXRpb25hbCBoYXNoaW5nIHJvdXRpbmUKKyAgICogZnJvbSBKREsgMS40LgorICAgKgorICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gZ2V0IGEgaGFzaCB2YWx1ZSBmb3IKKyAgICogQHJldHVybiB0aGUgaGFzaCB2YWx1ZQorICAgKi8KKyAgcHJpdmF0ZSBpbnQgaGFzaChPYmplY3Qga2V5KSB7CisgICAgaW50IGggPSBrZXkuaGFzaENvZGUoKTsKKyAgICBoICs9IH4oaCA8PCA5KTsKKyAgICBoIF49ICAoaCA+Pj4gMTQpOworICAgIGggKz0gIChoIDw8IDQpOworICAgIGggXj0gIChoID4+PiAxMCk7CisgICAgcmV0dXJuIGg7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb21wYXJlcyB0d28gb2JqZWN0cyBmb3IgZXF1YWxpdHkuICBNZXRob2QgdXNlcyBlcXVhbHMgbWV0aG9kIGFuZAorICAgKiBhc3N1bWVzIG5laXRoZXIgdmFsdWUgaXMgbnVsbC4KKyAgICoKKyAgICogQHBhcmFtIHggdGhlIGZpcnN0IHZhbHVlCisgICAqIEBwYXJhbSB5IHRoZSBzZWNvbmQgdmFsdWUKKyAgICogQHJldHVybiB0cnVlIGlmIGVxdWFsCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gaXNFcXVhbChPYmplY3QgeCwgT2JqZWN0IHkpIHsKKyAgICByZXR1cm4gKHggPT0geSB8fCB4LmVxdWFscyh5KSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIHRoZSBpbmRleCBpbnRvIHRoZSBjdXJyZW50IGhhc2ggdGFibGUgZm9yIHRoZSBzcGVjaWZpZWQKKyAgICogaGFzaFZhbHVlLgorICAgKgorICAgKiBAcGFyYW0gaGFzaFZhbHVlIHRoZSBoYXNoIHZhbHVlCisgICAqIEBwYXJhbSBsZW5ndGggdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGhhc2ggYnVja2V0cworICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBoYXNoIGFycmF5IHRvIHVzZQorICAgKi8KKyAgcHJpdmF0ZSBpbnQgaGFzaEluZGV4KGludCBoYXNoVmFsdWUsIGludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gaGFzaFZhbHVlICYgKGxlbmd0aCAtIDEpOworICB9CisKKyAgLyoqCisgICAqIENhbGN1bGF0ZXMgdGhlIGNhcGFjaXR5IG9mIHRoZSBhcnJheSBiYWNraW5nIHRoZSBoYXNoCisgICAqIGJ5IG5vcm1hbGl6aW5nIGNhcGFjaXR5IHRvIGEgcG93ZXIgb2YgMiBhbmQgZW5mb3JjaW5nCisgICAqIGNhcGFjaXR5IGxpbWl0cy4KKyAgICoKKyAgICogQHBhcmFtIHByb3Bvc2VkQ2FwYWNpdHkgdGhlIHByb3Bvc2VkIGNhcGFjaXR5CisgICAqIEByZXR1cm4gdGhlIG5vcm1hbGl6ZWQgY2FwYWNpdHkKKyAgICovCisgIHByaXZhdGUgaW50IGNhbGN1bGF0ZUNhcGFjaXR5KGludCBwcm9wb3NlZENhcGFjaXR5KSB7CisgICAgaW50IG5ld0NhcGFjaXR5ID0gMTsKKyAgICBpZihwcm9wb3NlZENhcGFjaXR5ID4gTUFYSU1VTV9DQVBBQ0lUWSkgeworICAgICAgbmV3Q2FwYWNpdHkgPSBNQVhJTVVNX0NBUEFDSVRZOworICAgIH0gZWxzZSB7CisgICAgICB3aGlsZShuZXdDYXBhY2l0eSA8IHByb3Bvc2VkQ2FwYWNpdHkpIHsKKyAgICAgICAgbmV3Q2FwYWNpdHkgPDw9IDE7CisgICAgICB9CisgICAgICBpZihuZXdDYXBhY2l0eSA+IE1BWElNVU1fQ0FQQUNJVFkpIHsKKyAgICAgICAgbmV3Q2FwYWNpdHkgPSBNQVhJTVVNX0NBUEFDSVRZOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbmV3Q2FwYWNpdHk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDYWxjdWxhdGVzIHRoZSB0aHJlc2hvbGQgb2YgdGhlIG1hcCBnaXZlbiB0aGUgY2FwYWNpdHkgYW5kIGxvYWQKKyAgICogZmFjdG9yLiAgT25jZSB0aGUgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIG1hcCBncm93cyB0byB0aGUKKyAgICogdGhyZXNob2xkIHdlIHdpbGwgZG91YmxlIHRoZSBzaXplIG9mIHRoZSBhcnJheS4KKyAgICoKKyAgICogQHBhcmFtIGNhcGFjaXR5IHRoZSBzaXplIG9mIHRoZSBhcnJheQorICAgKiBAcGFyYW0gZmFjdG9yIHRoZSBsb2FkIGZhY3RvciBvZiB0aGUgaGFzaAorICAgKi8KKyAgcHJpdmF0ZSBpbnQgY2FsY3VsYXRlVGhyZXNob2xkKGludCBjYXBhY2l0eSwgZmxvYXQgZmFjdG9yKSB7CisgICAgcmV0dXJuIChpbnQpKGNhcGFjaXR5ICogZmFjdG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIGluaXRpYWwgaGVhcCB1c2FnZSBvZiB0aGlzIGNsYXNzLiAgSW5jbHVkZXMgY2xhc3MgdmFyaWFibGUKKyAgICogb3ZlcmhlYWQgYW5kIHRoZSBlbnRyeSBhcnJheS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBpbml0KCkgeworICAgIG1lbUZyZWUgLT0gT1ZFUkhFQUQ7CisgICAgbWVtRnJlZSAtPSAoZW50cmllcy5sZW5ndGggKiBIZWFwU2l6ZS5SRUZFUkVOQ0UpOworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBEZWJ1Z2dpbmcgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgTGlzdCBzb3J0ZWQgYnkgYWNjZXNzIHRpbWUuCisgICAqCisgICAqIFRoZSBvcmRlciBpcyBvbGRlc3QgdG8gbmV3ZXN0IChmaXJzdCBpbiBsaXN0IGlzIG5leHQgdG8gYmUgZXZpY3RlZCkuCisgICAqCisgICAqIEByZXR1cm4gU29ydGVkIGxpc3Qgb2YgZW50cmllcworICAgKi8KKyAgcHVibGljIExpc3Q8RW50cnk8SyxWPj4gZW50cnlMcnVMaXN0KCkgeworICAgIExpc3Q8RW50cnk8SyxWPj4gZW50cnlMaXN0ID0gbmV3IEFycmF5TGlzdDxFbnRyeTxLLFY+PigpOworICAgIEVudHJ5PEssVj4gZW50cnkgPSBoZWFkUHRyOworICAgIHdoaWxlKGVudHJ5ICE9IG51bGwpIHsKKyAgICAgIGVudHJ5TGlzdC5hZGQoZW50cnkpOworICAgICAgZW50cnkgPSBlbnRyeS5nZXROZXh0UHRyKCk7CisgICAgfQorICAgIHJldHVybiBlbnRyeUxpc3Q7CisgIH0KKworICAvKioKKyAgICogRGVidWdnaW5nIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIFNldCBvZiBhbGwgZW50cmllcyBpbiB0aGUgaGFzaCB0YWJsZS4KKyAgICoKKyAgICogQHJldHVybiBTZXQgb2YgZW50cmllcyBpbiBoYXNoCisgICAqLworICBwdWJsaWMgU2V0PEVudHJ5PEssVj4+IGVudHJ5VGFibGVTZXQoKSB7CisgICAgU2V0PEVudHJ5PEssVj4+IGVudHJ5U2V0ID0gbmV3IEhhc2hTZXQ8RW50cnk8SyxWPj4oKTsKKyAgICBFbnRyeSBbXSB0YWJsZSA9IGVudHJpZXM7CisgICAgZm9yKGludCBpPTA7aTx0YWJsZS5sZW5ndGg7aSsrKSB7CisgICAgICBmb3IoRW50cnkgZSA9IHRhYmxlW2ldOyBlICE9IG51bGw7IGUgPSBlLm5leHQpIHsKKyAgICAgICAgZW50cnlTZXQuYWRkKGUpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZW50cnlTZXQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIGhlYWQgb2YgdGhlIGxpbmtlZCBsaXN0IChsZWFzdCByZWNlbnRseSB1c2VkKS4KKyAgICoKKyAgICogQHJldHVybiBoZWFkIG9mIGxpbmtlZCBsaXN0CisgICAqLworICBwdWJsaWMgRW50cnkgZ2V0SGVhZFB0cigpIHsKKyAgICByZXR1cm4gaGVhZFB0cjsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgdGFpbCBvZiB0aGUgbGlua2VkIGxpc3QgKG1vc3QgcmVjZW50bHkgdXNlZCkuCisgICAqIAorICAgKiBAcmV0dXJuIHRhaWwgb2YgbGlua2VkIGxpc3QKKyAgICovCisgIHB1YmxpYyBFbnRyeSBnZXRUYWlsUHRyKCkgeworICAgIHJldHVybiB0YWlsUHRyOworICB9CisgIAorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBUbyBiZXN0IG9wdGltaXplIHRoaXMgY2xhc3MsIHNvbWUgb2YgdGhlIG1ldGhvZHMgdGhhdCBhcmUgcGFydCBvZiBhCisgICAqIE1hcCBpbXBsZW1lbnRhdGlvbiBhcmUgbm90IHN1cHBvcnRlZC4gIFRoaXMgaXMgcHJpbWFyaWx5IHJlbGF0ZWQKKyAgICogdG8gYmVpbmcgYWJsZSB0byBnZXQgU2V0cyBhbmQgSXRlcmF0b3JzIG9mIHRoaXMgbWFwIHdoaWNoIHJlcXVpcmUKKyAgICogc2lnbmlmaWNhbnQgb3ZlcmhlYWQgYW5kIGNvZGUgY29tcGxleGl0eSB0byBzdXBwb3J0IGFuZCBhcmUKKyAgICogdW5uZWNlc3NhcnkgZm9yIHRoZSByZXF1aXJlbWVudHMgb2YgdGhpcyBjbGFzcy4KKyAgICovCisgIAorICAvKioKKyAgICogSW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkLgorICAgKi8KKyAgcHVibGljIFNldDxNYXAuRW50cnk8SyxWPj4gZW50cnlTZXQoKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICJlbnRyeVNldCgpIGlzIGludGVudGlvbmFsbHkgdW5pbXBsZW1lbnRlZCIpOworICB9CisKKyAgLyoqCisgICAqIEludGVudGlvbmFsbHkgdW5pbXBsZW1lbnRlZC4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAiZXF1YWxzKE9iamVjdCkgaXMgaW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkIik7CisgIH0KKworICAvKioKKyAgICogSW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkLgorICAgKi8KKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgImhhc2hDb2RlKE9iamVjdCkgaXMgaW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBJbnRlbnRpb25hbGx5IHVuaW1wbGVtZW50ZWQuCisgICAqLworICBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgImtleVNldCgpIGlzIGludGVudGlvbmFsbHkgdW5pbXBsZW1lbnRlZCIpOworICB9CisgIAorICAvKioKKyAgICogSW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgcHV0QWxsKE1hcDw/IGV4dGVuZHMgSywgPyBleHRlbmRzIFY+IG0pIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oCisgICAgInB1dEFsbCgpIGlzIGludGVudGlvbmFsbHkgdW5pbXBsZW1lbnRlZCIpOworICB9CisgIAorICAvKioKKyAgICogSW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkLgorICAgKi8KKyAgcHVibGljIENvbGxlY3Rpb248Vj4gdmFsdWVzKCkgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAidmFsdWVzKCkgaXMgaW50ZW50aW9uYWxseSB1bmltcGxlbWVudGVkIik7CisgIH0KKworICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8qKgorICAgKiBFbnRyeSB0byBzdG9yZSBrZXkvdmFsdWUgbWFwcGluZ3MuCisgICAqIDxwPgorICAgKiBDb250YWlucyBwcmV2aW91cyBhbmQgbmV4dCBwb2ludGVycyBmb3IgdGhlIGRvdWJseSBsaW5rZWQtbGlzdCB3aGljaCBpcworICAgKiB1c2VkIGZvciBMUlUgZXZpY3Rpb24uCisgICAqIDxwPgorICAgKiBJbnN0YW50aWF0aW9ucyBvZiB0aGlzIGNsYXNzIGFyZSBtZW1vcnkgYXdhcmUuICBCb3RoIHRoZSBrZXkgYW5kIHZhbHVlCisgICAqIGNsYXNzZXMgdXNlZCBtdXN0IGFsc28gaW1wbGVtZW50IDxjb2RlPkhlYXBTaXplPC9jb2RlPi4KKyAgICovCisgIHByb3RlY3RlZCBzdGF0aWMgY2xhc3MgRW50cnk8SyBleHRlbmRzIEhlYXBTaXplLCBWIGV4dGVuZHMgSGVhcFNpemU+CisgIGltcGxlbWVudHMgTWFwLkVudHJ5PEssVj4sIEhlYXBTaXplIHsKKyAgICAvKiogVGhlIGJhc2VsaW5lIG92ZXJoZWFkIG1lbW9yeSB1c2FnZSBvZiB0aGlzIGNsYXNzICovCisgICAgc3RhdGljIGZpbmFsIGludCBPVkVSSEVBRCA9IDEgKiBIZWFwU2l6ZS5MT05HICsgNSAqIEhlYXBTaXplLlJFRkVSRU5DRSArIAorICAgICAgMiAqIEhlYXBTaXplLklOVDsKKyAgICAKKyAgICAvKiogVGhlIGtleSAqLworICAgIHByb3RlY3RlZCBmaW5hbCBLIGtleTsKKyAgICAvKiogVGhlIHZhbHVlICovCisgICAgcHJvdGVjdGVkIFYgdmFsdWU7CisgICAgLyoqIFRoZSBoYXNoIHZhbHVlIGZvciB0aGlzIGVudHJpZXMga2V5ICovCisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBoYXNoOworICAgIC8qKiBUaGUgbmV4dCBlbnRyeSBpbiB0aGUgaGFzaCBjaGFpbiAoZm9yIGNvbGxpc2lvbnMpICovCisgICAgcHJvdGVjdGVkIEVudHJ5PEssVj4gbmV4dDsKKyAgICAKKyAgICAvKiogVGhlIHByZXZpb3VzIGVudHJ5IGluIHRoZSBMUlUgbGlzdCAodG93YXJkcyBMUlUpICovCisgICAgcHJvdGVjdGVkIEVudHJ5PEssVj4gcHJldlB0cjsKKyAgICAvKiogVGhlIG5leHQgZW50cnkgaW4gdGhlIExSVSBsaXN0ICh0b3dhcmRzIE1SVSkgKi8KKyAgICBwcm90ZWN0ZWQgRW50cnk8SyxWPiBuZXh0UHRyOworICAgIAorICAgIC8qKiBUaGUgcHJlY29tcHV0ZWQgaGVhcCBzaXplIG9mIHRoaXMgZW50cnkgKi8KKyAgICBwcm90ZWN0ZWQgbG9uZyBoZWFwU2l6ZTsKKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIG5ldyBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBoIHRoZSBoYXNoIHZhbHVlIG9mIHRoZSBrZXkKKyAgICAgKiBAcGFyYW0gayB0aGUga2V5CisgICAgICogQHBhcmFtIHYgdGhlIHZhbHVlCisgICAgICogQHBhcmFtIG5leHRDaGFpblB0ciB0aGUgbmV4dCBlbnRyeSBpbiB0aGUgaGFzaCBjaGFpbiwgbnVsbCBpZiBub25lCisgICAgICogQHBhcmFtIHByZXZMcnVQdHIgdGhlIHByZXZpb3VzIGVudHJ5IGluIHRoZSBMUlUKKyAgICAgKi8KKyAgICBFbnRyeShpbnQgaCwgSyBrLCBWIHYsIEVudHJ5PEssVj4gbmV4dENoYWluUHRyLCBFbnRyeTxLLFY+IHByZXZMcnVQdHIpIHsKKyAgICAgIHZhbHVlID0gdjsKKyAgICAgIG5leHQgPSBuZXh0Q2hhaW5QdHI7CisgICAgICBrZXkgPSBrOworICAgICAgaGFzaCA9IGg7CisgICAgICBwcmV2UHRyID0gcHJldkxydVB0cjsKKyAgICAgIG5leHRQdHIgPSBudWxsOworICAgICAgLy8gUHJlLWNvbXB1dGUgaGVhcCBzaXplCisgICAgICBoZWFwU2l6ZSA9IE9WRVJIRUFEICsgay5oZWFwU2l6ZSgpICsgdi5oZWFwU2l6ZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUga2V5IG9mIHRoaXMgZW50cnkuCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHRoZSBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZW50cnkKKyAgICAgKi8KKyAgICBwdWJsaWMgSyBnZXRLZXkoKSB7CisgICAgICByZXR1cm4ga2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEdldCB0aGUgdmFsdWUgb2YgdGhpcyBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIGN1cnJlbnRseSBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyBWIGdldFZhbHVlKCkgeworICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKyAgCisgICAgLyoqCisgICAgICogU2V0IHRoZSB2YWx1ZSBvZiB0aGlzIGVudHJ5LgorICAgICAqCisgICAgICogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIHVzZSB0aGlzIG1ldGhvZCB3aGVuIGNoYW5naW5nIHRoZSB2YWx1ZS4KKyAgICAgKiBSYXRoZXIsIHVzaW5nIDxjb2RlPnJlcGxhY2VWYWx1ZTwvY29kZT4gd2lsbCByZXR1cm4gdGhlIGRpZmZlcmVuY2UKKyAgICAgKiBpbiBoZWFwIHVzYWdlIGJldHdlZW4gdGhlIHByZXZpb3VzIGFuZCBjdXJyZW50IHZhbHVlcy4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlIHRvIGFzc29jaWF0ZSB3aXRoIHRoaXMgZW50cnkKKyAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBwcmV2aW91c2x5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudHJ5CisgICAgICovCisgICAgcHVibGljIFYgc2V0VmFsdWUoViBuZXdWYWx1ZSkgeworICAgICAgViBvbGRWYWx1ZSA9IHZhbHVlOworICAgICAgdmFsdWUgPSBuZXdWYWx1ZTsKKyAgICAgIHJldHVybiBvbGRWYWx1ZTsKKyAgICB9CisgIAorICAgIC8qKgorICAgICAqIFJlcGxhY2UgdGhlIHZhbHVlIG9mIHRoaXMgZW50cnkuCisgICAgICoKKyAgICAgKiBDb21wdXRlcyBhbmQgcmV0dXJucyB0aGUgZGlmZmVyZW5jZSBpbiBoZWFwIHNpemUgd2hlbiBjaGFuZ2luZworICAgICAqIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBuZXdWYWx1ZSB0aGUgbmV3IHZhbHVlIHRvIGFzc29jaWF0ZSB3aXRoIHRoaXMgZW50cnkKKyAgICAgKiBAcmV0dXJuIHRoZSBjaGFuZ2UgaW4gaGVhcCB1c2FnZSBvZiB0aGlzIGVudHJ5IGluIGJ5dGVzCisgICAgICovCisgICAgcHJvdGVjdGVkIGxvbmcgcmVwbGFjZVZhbHVlKFYgbmV3VmFsdWUpIHsKKyAgICAgIGxvbmcgc2l6ZURpZmYgPSBuZXdWYWx1ZS5oZWFwU2l6ZSgpIC0gdmFsdWUuaGVhcFNpemUoKTsKKyAgICAgIHZhbHVlID0gbmV3VmFsdWU7CisgICAgICBoZWFwU2l6ZSArPSBzaXplRGlmZjsKKyAgICAgIHJldHVybiBzaXplRGlmZjsKKyAgICB9CisgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdHJ1ZSBpcyB0aGUgc3BlY2lmaWVkIGVudHJ5IGhhcyB0aGUgc2FtZSBrZXkgYW5kIHRoZQorICAgICAqIHNhbWUgdmFsdWUgYXMgdGhpcyBlbnRyeS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBvIGVudHJ5IHRvIHRlc3QgYWdhaW5zdCBjdXJyZW50CisgICAgICogQHJldHVybiB0cnVlIGlzIGVudHJpZXMgaGF2ZSBlcXVhbCBrZXkgYW5kIHZhbHVlLCBmYWxzZSBpZiBubworICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgaWYgKCEobyBpbnN0YW5jZW9mIE1hcC5FbnRyeSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgTWFwLkVudHJ5IGUgPSAoTWFwLkVudHJ5KW87CisgICAgICBPYmplY3QgazEgPSBnZXRLZXkoKTsKKyAgICAgIE9iamVjdCBrMiA9IGUuZ2V0S2V5KCk7CisgICAgICBpZiAoazEgPT0gazIgfHwgKGsxICE9IG51bGwgJiYgazEuZXF1YWxzKGsyKSkpIHsKKyAgICAgICAgICBPYmplY3QgdjEgPSBnZXRWYWx1ZSgpOworICAgICAgICAgIE9iamVjdCB2MiA9IGUuZ2V0VmFsdWUoKTsKKyAgICAgICAgICBpZiAodjEgPT0gdjIgfHwgKHYxICE9IG51bGwgJiYgdjEuZXF1YWxzKHYyKSkpIAorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIAorICAgIC8qKiAKKyAgICAgKiBSZXR1cm5zIHRoZSBoYXNoIGNvZGUgb2YgdGhlIGVudHJ5IGJ5IHhvcidpbmcgdGhlIGhhc2ggdmFsdWVzCisgICAgICogb2YgdGhlIGtleSBhbmQgdmFsdWUgb2YgdGhpcyBlbnRyeS4KKyAgICAgKgorICAgICAqIEByZXR1cm4gaGFzaCB2YWx1ZSBvZiB0aGlzIGVudHJ5CisgICAgICovCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAoa2V5Lmhhc2hDb2RlKCkgXiB2YWx1ZS5oYXNoQ29kZSgpKTsKKyAgICB9CisgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbnRyeSBpbiBmb3JtICJrZXk9dmFsdWUiCisgICAgICoKKyAgICAgKiBAcmV0dXJuIHN0cmluZyB2YWx1ZSBvZiBlbnRyeQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gZ2V0S2V5KCkgKyAiPSIgKyBnZXRWYWx1ZSgpOworICAgIH0KKworICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcHJldmlvdXMgcG9pbnRlciBmb3IgdGhlIGVudHJ5IGluIHRoZSBMUlUuCisgICAgICogQHBhcmFtIHByZXZQdHIgcHJldmlvdXMgZW50cnkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRQcmV2UHRyKEVudHJ5PEssVj4gcHJldlB0cil7CisgICAgICB0aGlzLnByZXZQdHIgPSBwcmV2UHRyOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBwb2ludGVyIGZvciB0aGUgZW50cnkgaW4gdGhlIExSVS4KKyAgICAgKiBAcmV0dXJuIHByZXZpb3VzIGVudHJ5CisgICAgICovCisgICAgcHJvdGVjdGVkIEVudHJ5PEssVj4gZ2V0UHJldlB0cigpeworICAgICAgcmV0dXJuIHByZXZQdHI7CisgICAgfSAgICAKKyAgICAKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuZXh0IHBvaW50ZXIgZm9yIHRoZSBlbnRyeSBpbiB0aGUgTFJVLgorICAgICAqIEBwYXJhbSBuZXh0UHRyIG5leHQgZW50cnkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXROZXh0UHRyKEVudHJ5PEssVj4gbmV4dFB0cil7CisgICAgICB0aGlzLm5leHRQdHIgPSBuZXh0UHRyOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IHBvaW50ZXIgZm9yIHRoZSBlbnRyeSBpbiB0ZWggTFJVLgorICAgICAqIEByZXR1cm4gbmV4dCBlbnRyeQorICAgICAqLworICAgIHByb3RlY3RlZCBFbnRyeTxLLFY+IGdldE5leHRQdHIoKXsKKyAgICAgIHJldHVybiBuZXh0UHRyOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBwcmUtY29tcHV0ZWQgYW5kICJkZWVwIiBzaXplIG9mIHRoZSBFbnRyeQorICAgICAqIEByZXR1cm4gc2l6ZSBvZiB0aGUgZW50cnkgaW4gYnl0ZXMKKyAgICAgKi8KKyAgICBwdWJsaWMgbG9uZyBoZWFwU2l6ZSgpIHsKKyAgICAgIHJldHVybiBoZWFwU2l6ZTsKKyAgICB9CisgIH0KK30KKworCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTWVtY2FjaGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9NZW1jYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyZGMyMDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTWVtY2FjaGUuamF2YQpAQCAtMCwwICsxLDc1OCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5NYW5hZ2VtZW50RmFjdG9yeTsKK2ltcG9ydCBqYXZhLmxhbmcubWFuYWdlbWVudC5SdW50aW1lTVhCZWFuOworaW1wb3J0IGphdmEucm1pLlVuZXhwZWN0ZWRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRTa2lwTGlzdFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRSZWFkV3JpdGVMb2NrOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbi5Db3VudGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGhlIE1lbWNhY2hlIGhvbGRzIGluLW1lbW9yeSBtb2RpZmljYXRpb25zIHRvIHRoZSBIUmVnaW9uLiAgTW9kaWZpY2F0aW9ucworICogYXJlIHtAbGluayBLZXlWYWx1ZX1zLiAgV2hlbiBhc2tlZCB0byBmbHVzaCwgY3VycmVudCBtZW1jYWNoZSBpcyBtb3ZlZAorICogdG8gc25hcHNob3QgYW5kIGlzIGNsZWFyZWQuICBXZSBjb250aW51ZSB0byBzZXJ2ZSBlZGl0cyBvdXQgb2YgbmV3IG1lbWNhY2hlCisgKiBhbmQgYmFja2luZyBzbmFwc2hvdCB1bnRpbCBmbHVzaGVyIHJlcG9ydHMgaW4gdGhhdCB0aGUgZmx1c2ggc3VjY2VlZGVkLiBBdAorICogdGhpcyBwb2ludCB3ZSBsZXQgdGhlIHNuYXBzaG90IGdvLgorICogVE9ETzogQWRqdXN0IHNpemUgb2YgdGhlIG1lbWNhY2hlIHdoZW4gd2UgcmVtb3ZlIGl0ZW1zIGJlY2F1c2UgdGhleSBoYXZlCisgKiBiZWVuIGRlbGV0ZWQuCisgKi8KK2NsYXNzIE1lbWNhY2hlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKE1lbWNhY2hlLmNsYXNzKTsKKworICBwcml2YXRlIGZpbmFsIGxvbmcgdHRsOworCisgIC8vIE5vdGUgdGhhdCBzaW5jZSB0aGVzZSBzdHJ1Y3R1cmVzIGFyZSBhbHdheXMgYWNjZXNzZWQgd2l0aCBhIGxvY2sgaGVsZCwKKyAgLy8gbm8gYWRkaXRpb25hbCBzeW5jaHJvbml6YXRpb24gaXMgcmVxdWlyZWQuCisgIAorICAvLyBUaGUgY3VycmVudGx5IGFjdGl2ZSBzb3J0ZWQgc2V0IG9mIGVkaXRzLiAgVXNpbmcgZXhwbGljaXQgdHlwZSBiZWNhdXNlCisgIC8vIGlmIEkgdXNlIE5hdmlnYWJsZVNldCwgSSBsb3NlIHNvbWUgZmFjaWxpdHkgLS0gSSBjYW4ndCBnZXQgYSBOYXZpZ2FibGVTZXQKKyAgLy8gd2hlbiBJIGRvIHRhaWxTZXQgb3IgaGVhZFNldC4KKyAgdm9sYXRpbGUgQ29uY3VycmVudFNraXBMaXN0U2V0PEtleVZhbHVlPiBtZW1jYWNoZTsKKworICAvLyBTbmFwc2hvdCBvZiBtZW1jYWNoZS4gIE1hZGUgZm9yIGZsdXNoZXIuCisgIHZvbGF0aWxlIENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gc25hcHNob3Q7CisKKyAgcHJpdmF0ZSBmaW5hbCBSZWVudHJhbnRSZWFkV3JpdGVMb2NrIGxvY2sgPSBuZXcgUmVlbnRyYW50UmVhZFdyaXRlTG9jaygpOworCisgIGZpbmFsIEtleVZhbHVlLktWQ29tcGFyYXRvciBjb21wYXJhdG9yOworCisgIC8vIFVzZWQgY29tcGFyaW5nIHZlcnNpb25zIC0tIHNhbWUgci9jIGFuZCB0cyBidXQgZGlmZmVyZW50IHR5cGUuCisgIGZpbmFsIEtleVZhbHVlLktWQ29tcGFyYXRvciBjb21wYXJhdG9ySWdub3JlVHlwZTsKKworICAvLyBVc2VkIGNvbXBhcmluZyB2ZXJzaW9ucyAtLSBzYW1lIHIvYyBhbmQgdHlwZSBidXQgZGlmZmVyZW50IHRpbWVzdGFtcC4KKyAgZmluYWwgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGNvbXBhcmF0b3JJZ25vcmVUaW1lc3RhbXA7CisKKyAgLy8gVE9ETzogRml4IHRoaXMgZ3Vlc3MgYnkgc3R1ZHlpbmcganByb2ZpbGVyCisgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBFU1RJTUFURURfS1ZfSEVBUF9UQVggPSA2MDsKKworICAvKioKKyAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gVXNlZCBmb3IgdGVzdHMuCisgICAqLworICBwdWJsaWMgTWVtY2FjaGUoKSB7CisgICAgdGhpcyhIQ29uc3RhbnRzLkZPUkVWRVIsIEtleVZhbHVlLkNPTVBBUkFUT1IpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yLgorICAgKiBAcGFyYW0gdHRsIFRoZSBUVEwgZm9yIGNhY2hlIGVudHJpZXMsIGluIG1pbGxpc2Vjb25kcy4KKyAgICogQHBhcmFtIGMKKyAgICovCisgIHB1YmxpYyBNZW1jYWNoZShmaW5hbCBsb25nIHR0bCwgZmluYWwgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGMpIHsKKyAgICB0aGlzLnR0bCA9IHR0bDsKKyAgICB0aGlzLmNvbXBhcmF0b3IgPSBjOworICAgIHRoaXMuY29tcGFyYXRvcklnbm9yZVRpbWVzdGFtcCA9CisgICAgICB0aGlzLmNvbXBhcmF0b3IuZ2V0Q29tcGFyYXRvcklnbm9yaW5nVGltZXN0YW1wcygpOworICAgIHRoaXMuY29tcGFyYXRvcklnbm9yZVR5cGUgPSB0aGlzLmNvbXBhcmF0b3IuZ2V0Q29tcGFyYXRvcklnbm9yaW5nVHlwZSgpOworICAgIHRoaXMubWVtY2FjaGUgPSBjcmVhdGVTZXQoYyk7CisgICAgdGhpcy5zbmFwc2hvdCA9IGNyZWF0ZVNldChjKTsKKyAgfQorCisgIHN0YXRpYyBDb25jdXJyZW50U2tpcExpc3RTZXQ8S2V5VmFsdWU+IGNyZWF0ZVNldChmaW5hbCBLZXlWYWx1ZS5LVkNvbXBhcmF0b3IgYykgeworICAgIHJldHVybiBuZXcgQ29uY3VycmVudFNraXBMaXN0U2V0PEtleVZhbHVlPihjKTsKKyAgfQorCisgIHZvaWQgZHVtcCgpIHsKKyAgICBmb3IgKEtleVZhbHVlIGt2OiB0aGlzLm1lbWNhY2hlKSB7CisgICAgICBMT0cuaW5mbyhrdik7CisgICAgfQorICAgIGZvciAoS2V5VmFsdWUga3Y6IHRoaXMuc25hcHNob3QpIHsKKyAgICAgIExPRy5pbmZvKGt2KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IE1lbWNhY2hlLgorICAgKiBTbmFwc2hvdCBtdXN0IGJlIGNsZWFyZWQgYnkgY2FsbCB0byB7QGxpbmsgI2NsZWFyU25hcHNob3QoU29ydGVkTWFwKX0KKyAgICogVG8gZ2V0IHRoZSBzbmFwc2hvdCBtYWRlIGJ5IHRoaXMgbWV0aG9kLCB1c2Uge0BsaW5rICNnZXRTbmFwc2hvdH0uCisgICAqLworICB2b2lkIHNuYXBzaG90KCkgeworICAgIHRoaXMubG9jay53cml0ZUxvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIElmIHNuYXBzaG90IGN1cnJlbnRseSBoYXMgZW50cmllcywgdGhlbiBmbHVzaGVyIGZhaWxlZCBvciBkaWRuJ3QgY2FsbAorICAgICAgLy8gY2xlYW51cC4gIExvZyBhIHdhcm5pbmcuCisgICAgICBpZiAoIXRoaXMuc25hcHNob3QuaXNFbXB0eSgpKSB7CisgICAgICAgIExPRy53YXJuKCJTbmFwc2hvdCBjYWxsZWQgYWdhaW4gd2l0aG91dCBjbGVhcmluZyBwcmV2aW91cy4gIiArCisgICAgICAgICAgIkRvaW5nIG5vdGhpbmcuIEFub3RoZXIgb25nb2luZyBmbHVzaCBvciBkaWQgd2UgZmFpbCBsYXN0IGF0dGVtcHQ/Iik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBXZSB1c2VkIHRvIHN5bmNocm9uaXplIG9uIHRoZSBtZW1jYWNoZSBoZXJlIGJ1dCB3ZSdyZSBpbnNpZGUgYQorICAgICAgICAvLyB3cml0ZSBsb2NrIHNvIHJlbW92ZWQgaXQuIENvbW1lbnQgaXMgbGVmdCBpbiBjYXNlIHJlbW92YWwgd2FzIGEKKyAgICAgICAgLy8gbWlzdGFrZS4gU3QuQWNrCisgICAgICAgIGlmICghdGhpcy5tZW1jYWNoZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICB0aGlzLnNuYXBzaG90ID0gdGhpcy5tZW1jYWNoZTsKKyAgICAgICAgICB0aGlzLm1lbWNhY2hlID0gY3JlYXRlU2V0KHRoaXMuY29tcGFyYXRvcik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgc25hcHNob3QuCisgICAqIENhbGxlZCBieSBmbHVzaGVyIHRvIGdldCBjdXJyZW50IHNuYXBzaG90IG1hZGUgYnkgYSBwcmV2aW91cworICAgKiBjYWxsIHRvIHtAbGluayBzbmFwc2hvdH0uCisgICAqIEByZXR1cm4gUmV0dXJuIHNuYXBzaG90LgorICAgKiBAc2VlIHtAbGluayAjc25hcHNob3QoKX0KKyAgICogQHNlZSB7QGxpbmsgI2NsZWFyU25hcHNob3QoTmF2aWdhYmxlU2V0KX0KKyAgICovCisgIENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gZ2V0U25hcHNob3QoKSB7CisgICAgcmV0dXJuIHRoaXMuc25hcHNob3Q7CisgIH0KKworICAvKioKKyAgICogVGhlIHBhc3NlZCBzbmFwc2hvdCB3YXMgc3VjY2Vzc2Z1bGx5IHBlcnNpc3RlZDsgaXQgY2FuIGJlIGxldCBnby4KKyAgICogQHBhcmFtIHNzIFRoZSBzbmFwc2hvdCB0byBjbGVhbiBvdXQuCisgICAqIEB0aHJvd3MgVW5leHBlY3RlZEV4Y2VwdGlvbgorICAgKiBAc2VlIHtAbGluayAjc25hcHNob3QoKX0KKyAgICovCisgIHZvaWQgY2xlYXJTbmFwc2hvdChmaW5hbCBTZXQ8S2V5VmFsdWU+IHNzKQorICB0aHJvd3MgVW5leHBlY3RlZEV4Y2VwdGlvbiB7CisgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgaWYgKHRoaXMuc25hcHNob3QgIT0gc3MpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRFeGNlcHRpb24oIkN1cnJlbnQgc25hcHNob3QgaXMgIiArCisgICAgICAgICAgdGhpcy5zbmFwc2hvdCArICIsIHdhcyBwYXNzZWQgIiArIHNzKTsKKyAgICAgIH0KKyAgICAgIC8vIE9LLiBQYXNzZWQgaW4gc25hcHNob3QgaXMgc2FtZSBhcyBjdXJyZW50IHNuYXBzaG90LiAgSWYgbm90LWVtcHR5LAorICAgICAgLy8gY3JlYXRlIGEgbmV3IHNuYXBzaG90IGFuZCBsZXQgdGhlIG9sZCBvbmUgZ28uCisgICAgICBpZiAoIXNzLmlzRW1wdHkoKSkgeworICAgICAgICB0aGlzLnNuYXBzaG90ID0gY3JlYXRlU2V0KHRoaXMuY29tcGFyYXRvcik7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay53cml0ZUxvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYW4gdXBkYXRlCisgICAqIEBwYXJhbSBrdgorICAgKiBAcmV0dXJuIGFwcHJveGltYXRlIHNpemUgb2YgdGhlIHBhc3NlZCBrZXkgYW5kIHZhbHVlLgorICAgKi8KKyAgbG9uZyBhZGQoZmluYWwgS2V5VmFsdWUga3YpIHsKKyAgICBsb25nIHNpemUgPSAtMTsKKyAgICB0aGlzLmxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIGJvb2xlYW4gbm90cHJlc2VudCA9IHRoaXMubWVtY2FjaGUuYWRkKGt2KTsKKyAgICAgIC8vIGlmIGZhbHNlIHRoZW4gbWVtY2FjaGUgaXMgbm90IGNoYW5nZWQgKGxvb2sgbWVtY2FjaGUuYWRkKGt2KSBkb2NzKQorICAgICAgLy8gbmVlZCB0byByZW1vdmUga3YgYW5kIGFkZCBhZ2FpbiB0byByZXBsYWNlIGl0CisgICAgICBpZiAoIW5vdHByZXNlbnQgJiYgdGhpcy5tZW1jYWNoZS5yZW1vdmUoa3YpKSB7CisgICAgICAgIHRoaXMubWVtY2FjaGUuYWRkKGt2KTsKKyAgICAgIH0KKyAgICAgIHNpemUgPSBoZWFwU2l6ZShrdiwgbm90cHJlc2VudCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIC8qCisgICAqIENhbGN1bGF0ZSBob3cgdGhlIG1lbWNhY2hlIHNpemUgaGFzIGNoYW5nZWQsIGFwcHJveGltYXRlbHkuICBCZSBjYXJlZnVsLgorICAgKiBJZiBjbGFzcyBjaGFuZ2VzLCBiZSBzdXJlIHRvIGNoYW5nZSB0aGUgc2l6ZSBjYWxjdWxhdGlvbi4KKyAgICogQWRkIGluIHRheCBvZiBNYXAuRW50cnkuCisgICAqIEBwYXJhbSBrdgorICAgKiBAcGFyYW0gbm90cHJlc2VudCBUcnVlIGlmIHRoZSBrdiB3YXMgTk9UIHByZXNlbnQgaW4gdGhlIHNldC4KKyAgICogQHJldHVybiBTaXplCisgICAqLworICBsb25nIGhlYXBTaXplKGZpbmFsIEtleVZhbHVlIGt2LCBmaW5hbCBib29sZWFuIG5vdHByZXNlbnQpIHsKKyAgICByZXR1cm4gbm90cHJlc2VudD8KKyAgICAgIC8vIEFkZCBvdmVyaGVhZCBmb3IgdmFsdWUgYnl0ZSBhcnJheSBhbmQgZm9yIE1hcC5FbnRyeSAtLSA1NyBieXRlcworICAgICAgLy8gb24geDY0IGFjY29yZGluZyB0byBqcHJvZmlsZXIuCisgICAgICBFU1RJTUFURURfS1ZfSEVBUF9UQVggKyA1NyArIGt2LmdldExlbmd0aCgpOiAwOyAvLyBHdWVzcyBubyBjaGFuZ2UgaW4gc2l6ZS4KKyAgfQorCisgIC8qKgorICAgKiBMb29rIGJhY2sgdGhyb3VnaCBhbGwgdGhlIGJhY2tsb2cgVHJlZU1hcHMgdG8gZmluZCB0aGUgdGFyZ2V0LgorICAgKiBAcGFyYW0ga3YKKyAgICogQHBhcmFtIG51bVZlcnNpb25zCisgICAqIEByZXR1cm4gU2V0IG9mIEtleVZhbHVlcy4gRW1wdHkgc2l6ZSBub3QgbnVsbCBpZiBubyByZXN1bHRzLgorICAgKi8KKyAgTGlzdDxLZXlWYWx1ZT4gZ2V0KGZpbmFsIEtleVZhbHVlIGt2LCBmaW5hbCBpbnQgbnVtVmVyc2lvbnMpIHsKKyAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICBnZXQoa3YsIG51bVZlcnNpb25zLCByZXN1bHRzLAorICAgICAgbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KHRoaXMuY29tcGFyYXRvcklnbm9yZVR5cGUpLAorICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIHJldHVybiByZXN1bHRzOworICB9CisKKyAgLyoqCisgICAqIExvb2sgYmFjayB0aHJvdWdoIGFsbCB0aGUgYmFja2xvZyBUcmVlTWFwcyB0byBmaW5kIHRoZSB0YXJnZXQuCisgICAqIEBwYXJhbSBrZXkKKyAgICogQHBhcmFtIHZlcnNpb25zCisgICAqIEBwYXJhbSByZXN1bHRzCisgICAqIEBwYXJhbSBkZWxldGVzIFBhc3MgYSBTZXQgdGhhdCBoYXMgYSBDb21wYXJhdG9yIHRoYXQgaWdub3JlcyBrZXkgdHlwZS4KKyAgICogQHBhcmFtIG5vdworICAgKiBAcmV0dXJuIFRydWUgaWYgZW5vdWdoIHZlcnNpb25zLgorICAgKi8KKyAgYm9vbGVhbiBnZXQoZmluYWwgS2V5VmFsdWUga2V5LCBmaW5hbCBpbnQgdmVyc2lvbnMsCisgICAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzLCBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsCisgICAgICBmaW5hbCBsb25nIG5vdykgeworICAgIHRoaXMubG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgaWYgKGdldCh0aGlzLm1lbWNhY2hlLCBrZXksIHZlcnNpb25zLCByZXN1bHRzLCBkZWxldGVzLCBub3cpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgcmV0dXJuIGdldCh0aGlzLnNuYXBzaG90LCBrZXksIHZlcnNpb25zICwgcmVzdWx0cywgZGVsZXRlcywgbm93KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBrdiBGaW5kIHRoZSByb3cgdGhhdCBjb21lcyBhZnRlciB0aGlzIG9uZS4gIElmIG51bGwsIHdlIHJldHVybiB0aGUKKyAgICogZmlyc3QuCisgICAqIEByZXR1cm4gTmV4dCByb3cgb3IgbnVsbCBpZiBub25lIGZvdW5kLgorICAgKi8KKyAgS2V5VmFsdWUgZ2V0TmV4dFJvdyhmaW5hbCBLZXlWYWx1ZSBrdikgeworICAgIHRoaXMubG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIGdldExvd2VzdChnZXROZXh0Um93KGt2LCB0aGlzLm1lbWNhY2hlKSwKKyAgICAgICAgZ2V0TmV4dFJvdyhrdiwgdGhpcy5zbmFwc2hvdCkpOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gYQorICAgKiBAcGFyYW0gYgorICAgKiBAcmV0dXJuIFJldHVybiBsb3dlc3Qgb2YgYSBvciBiIG9yIG51bGwgaWYgYm90aCBhIGFuZCBiIGFyZSBudWxsCisgICAqLworICBwcml2YXRlIEtleVZhbHVlIGdldExvd2VzdChmaW5hbCBLZXlWYWx1ZSBhLCBmaW5hbCBLZXlWYWx1ZSBiKSB7CisgICAgaWYgKGEgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGI7CisgICAgfQorICAgIGlmIChiID09IG51bGwpIHsKKyAgICAgIHJldHVybiBhOworICAgIH0KKyAgICByZXR1cm4gY29tcGFyYXRvci5jb21wYXJlUm93cyhhLCBiKSA8PSAwPyBhOiBiOworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIGt2IEZpbmQgcm93IHRoYXQgZm9sbG93cyB0aGlzIG9uZS4gIElmIG51bGwsIHJldHVybiBmaXJzdC4KKyAgICogQHBhcmFtIHNldCBTZXQgdG8gbG9vayBpbiBmb3IgYSByb3cgYmV5b25kIDxjb2RlPnJvdzwvY29kZT4uCisgICAqIEByZXR1cm4gTmV4dCByb3cgb3IgbnVsbCBpZiBub25lIGZvdW5kLiAgSWYgb25lIGZvdW5kLCB3aWxsIGJlIGEgbmV3CisgICAqIEtleVZhbHVlIC0tIGNhbiBiZSBkZXN0cm95ZWQgYnkgc3Vic2VxdWVudCBjYWxscyB0byB0aGlzIG1ldGhvZC4KKyAgICovCisgIHByaXZhdGUgS2V5VmFsdWUgZ2V0TmV4dFJvdyhmaW5hbCBLZXlWYWx1ZSBrdiwKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gc2V0KSB7CisgICAgS2V5VmFsdWUgcmVzdWx0ID0gbnVsbDsKKyAgICBTb3J0ZWRTZXQ8S2V5VmFsdWU+IHRhaWxzZXQgPSBrdiA9PSBudWxsPyBzZXQ6IHNldC50YWlsU2V0KGt2KTsKKyAgICAvLyBJdGVyYXRlIHVudGlsIHdlIGZhbGwgaW50byB0aGUgbmV4dCByb3c7IGkuZS4gbW92ZSBvZmYgY3VycmVudCByb3cKKyAgICBmb3IgKEtleVZhbHVlIGkgOiB0YWlsc2V0KSB7CisgICAgICBpZiAoY29tcGFyYXRvci5jb21wYXJlUm93cyhpLCBrdikgPD0gMCkKKyAgICAgICAgY29udGludWU7CisgICAgICAvLyBOb3RlOiBOb3Qgc3VwcHJlc3NpbmcgZGVsZXRlcyBvciBleHBpcmVkIGNlbGxzLiAgTmVlZHMgdG8gYmUgaGFuZGxlZAorICAgICAgLy8gYnkgaGlnaGVyIHVwIGZ1bmN0aW9ucy4KKyAgICAgIHJlc3VsdCA9IGk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gYWxsIHRoZSBhdmFpbGFibGUgY29sdW1ucyBmb3IgdGhlIGdpdmVuIGtleS4gIFRoZSBrZXkgaW5kaWNhdGVzIGEgCisgICAqIHJvdyBhbmQgdGltZXN0YW1wLCBidXQgbm90IGEgY29sdW1uIG5hbWUuCisgICAqIEBwYXJhbSBvcmlnaW4gV2hlcmUgdG8gc3RhcnQgc2VhcmNoaW5nLiAgU3BlY2lmaWVzIGEgcm93IGFuZCB0aW1lc3RhbXAuCisgICAqIENvbHVtbnMgYXJlIHNwZWNpZmllZCBpbiBmb2xsb3dpbmcgYXJndW1lbnRzLgorICAgKiBAcGFyYW0gY29sdW1ucyBQYXNzIG51bGwgZm9yIGFsbCBjb2x1bW5zIGVsc2UgdGhlIHdhbnRlZCBzdWJzZXQuCisgICAqIEBwYXJhbSBjb2x1bW5QYXR0ZXJuIENvbHVtbiBwYXR0ZXJuIHRvIG1hdGNoLgorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMgbnVtYmVyIG9mIHZlcnNpb25zIHRvIHJldHJpZXZlCisgICAqIEBwYXJhbSB2ZXJzaW9uc0NvdW50IE1hcCBvZiBLViB0byBDb3VudC4gIFVzZXMgYSBDb21wYXJhdG9yIHRoYXQgZG9lc24ndAorICAgKiBsb29rIGF0IHRpbWVzdGFtcHMgc28gb25seSBSb3cvQ29sdW1uIGFyZSBjb21wYXJlZC4KKyAgICogQHBhcmFtIGRlbGV0ZXMgUGFzcyBhIFNldCB0aGF0IGhhcyBhIENvbXBhcmF0b3IgdGhhdCBpZ25vcmVzIGtleSB0eXBlLgorICAgKiBAcGFyYW0gcmVzdWx0cyBXaGVyZSB0byBzdGljayByb3cgcmVzdWx0cyBmb3VuZC4KKyAgICogQHJldHVybiBUcnVlIGlmIHdlIGZvdW5kIGVub3VnaCByZXN1bHRzIGZvciBwYXNzZWQgPGNvZGU+Y29sdW1uczwvY29kZT4KKyAgICogYW5kIDxjb2RlPm51bVZlcnNpb25zPC9jb2RlPi4KKyAgICovCisgIGJvb2xlYW4gZ2V0RnVsbChmaW5hbCBLZXlWYWx1ZSBrZXksIE5hdmlnYWJsZVNldDxieXRlIFtdPiBjb2x1bW5zLAorICAgICAgZmluYWwgUGF0dGVybiBjb2x1bW5QYXR0ZXJuLAorICAgICAgaW50IG51bVZlcnNpb25zLCBmaW5hbCBNYXA8S2V5VmFsdWUsIEhSZWdpb24uQ291bnRlcj4gdmVyc2lvbnNDb3VudCwKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywKKyAgICAgIGZpbmFsIExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMsIGZpbmFsIGxvbmcgbm93KSB7CisgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICAvLyBVc2VkIHRvIGJlIHN5bmNocm9uaXplZCBidXQgbm93IHdpdGggd2VhayBpdGVyYXRpb24sIG5vIGxvbmdlciBuZWVkZWQuCisgICAgICBpZiAoZ2V0RnVsbCh0aGlzLm1lbWNhY2hlLCBrZXksIGNvbHVtbnMsIGNvbHVtblBhdHRlcm4sIG51bVZlcnNpb25zLAorICAgICAgICB2ZXJzaW9uc0NvdW50LCBkZWxldGVzLCByZXN1bHRzLCBub3cpKSB7CisgICAgICAgIC8vIEhhcyBlbm91Z2ggcmVzdWx0cy4KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZ2V0RnVsbCh0aGlzLnNuYXBzaG90LCBrZXksIGNvbHVtbnMsIGNvbHVtblBhdHRlcm4sIG51bVZlcnNpb25zLAorICAgICAgICB2ZXJzaW9uc0NvdW50LCBkZWxldGVzLCByZXN1bHRzLCBub3cpOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gc2V0CisgICAqIEBwYXJhbSB0YXJnZXQgV2hlcmUgdG8gc3RhcnQgc2VhcmNoaW5nLgorICAgKiBAcGFyYW0gY29sdW1ucworICAgKiBAcGFyYW0gdmVyc2lvbnMKKyAgICogQHBhcmFtIHZlcnNpb25Db3VudGVyCisgICAqIEBwYXJhbSBkZWxldGVzIFBhc3MgYSBTZXQgdGhhdCBoYXMgYSBDb21wYXJhdG9yIHRoYXQgaWdub3JlcyBrZXkgdHlwZS4KKyAgICogQHBhcmFtIGtleXZhbHVlcworICAgKiBAcmV0dXJuIFRydWUgaWYgZW5vdWdoIHJlc3VsdHMgZm91bmQuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gZ2V0RnVsbChmaW5hbCBDb25jdXJyZW50U2tpcExpc3RTZXQ8S2V5VmFsdWU+IHNldCwKKyAgICAgIGZpbmFsIEtleVZhbHVlIHRhcmdldCwgZmluYWwgU2V0PGJ5dGUgW10+IGNvbHVtbnMsCisgICAgICBmaW5hbCBQYXR0ZXJuIGNvbHVtblBhdHRlcm4sCisgICAgICBmaW5hbCBpbnQgdmVyc2lvbnMsIGZpbmFsIE1hcDxLZXlWYWx1ZSwgSFJlZ2lvbi5Db3VudGVyPiB2ZXJzaW9uQ291bnRlciwKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzLAorICAgICAgZmluYWwgbG9uZyBub3cpIHsKKyAgICBib29sZWFuIGhhc0Vub3VnaCA9IGZhbHNlOworICAgIGlmICh0YXJnZXQgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGhhc0Vub3VnaDsKKyAgICB9CisgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiB0YWlsc2V0ID0gc2V0LnRhaWxTZXQodGFyZ2V0KTsKKyAgICBpZiAodGFpbHNldCA9PSBudWxsIHx8IHRhaWxzZXQuaXNFbXB0eSgpKSB7CisgICAgICByZXR1cm4gaGFzRW5vdWdoOworICAgIH0KKyAgICAvLyBUT0RPOiBUaGlzIGxvb3Agc2FtZSBhcyBpbiBIU3RvcmUuZ2V0RnVsbEZyb21TdG9yZUZpbGUuICBNYWtlIHN1cmUgdGhleQorICAgIC8vIGFyZSB0aGUgc2FtZS4KKyAgICBmb3IgKEtleVZhbHVlIGt2OiB0YWlsc2V0KSB7CisgICAgICAvLyBNYWtlIHN1cmUgd2UgaGF2ZSBub3QgcGFzc2VkIG91dCB0aGUgcm93LiAgSWYgdGFyZ2V0IGtleSBoYXMgYQorICAgICAgLy8gY29sdW1uIG9uIGl0LCB0aGVuIHdlIGFyZSBsb29raW5nIGV4cGxpY2l0IGtleStjb2x1bW4gY29tYmluYXRpb24uICBJZgorICAgICAgLy8gd2UndmUgcGFzc2VkIGl0IG91dCwgYWxzbyBicmVhay4KKyAgICAgIGlmICh0YXJnZXQuaXNFbXB0eUNvbHVtbigpPyAhdGhpcy5jb21wYXJhdG9yLm1hdGNoaW5nUm93cyh0YXJnZXQsIGt2KToKKyAgICAgICAgICAhdGhpcy5jb21wYXJhdG9yLm1hdGNoaW5nUm93Q29sdW1uKHRhcmdldCwga3YpKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKCFTdG9yZS5nZXRGdWxsQ2hlY2sodGhpcy5jb21wYXJhdG9yLCB0YXJnZXQsIGt2LCBjb2x1bW5zLCBjb2x1bW5QYXR0ZXJuKSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGlmIChTdG9yZS5kb0tleVZhbHVlKGt2LCB2ZXJzaW9ucywgdmVyc2lvbkNvdW50ZXIsIGNvbHVtbnMsIGRlbGV0ZXMsIG5vdywKKyAgICAgICAgICB0aGlzLnR0bCwga2V5dmFsdWVzLCB0YWlsc2V0KSkgeworICAgICAgICBoYXNFbm91Z2ggPSB0cnVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGhhc0Vub3VnaDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcm93IFJvdyB0byBsb29rIGZvci4KKyAgICogQHBhcmFtIGNhbmRpZGF0ZUtleXMgTWFwIG9mIGNhbmRpZGF0ZSBrZXlzIChBY2N1bXVsYXRpb24gb3ZlciBsb3RzIG9mCisgICAqIGxvb2t1cCBvdmVyIHN0b3JlcyBhbmQgbWVtY2FjaGVzKQorICAgKi8KKyAgdm9pZCBnZXRSb3dLZXlBdE9yQmVmb3JlKGZpbmFsIEtleVZhbHVlIHJvdywKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gY2FuZGlkYXRlS2V5cykgeworICAgIGdldFJvd0tleUF0T3JCZWZvcmUocm93LCBjYW5kaWRhdGVLZXlzLAorICAgICAgbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KHRoaXMuY29tcGFyYXRvciksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0ga3YgUm93IHRvIGxvb2sgZm9yLgorICAgKiBAcGFyYW0gY2FuZGlkYXRlcyBNYXAgb2YgY2FuZGlkYXRlIGtleXMgKEFjY3VtdWxhdGlvbiBvdmVyIGxvdHMgb2YKKyAgICogbG9va3VwIG92ZXIgc3RvcmVzIGFuZCBtZW1jYWNoZXMpLiAgUGFzcyBhIFNldCB3aXRoIGEgQ29tcGFyYXRvciB0aGF0CisgICAqIGlnbm9yZXMga2V5IFR5cGUgc28gd2UgY2FuIGRvIFNldC5yZW1vdmUgdXNpbmcgYSBkZWxldGUsIGkuZS4gYSBLZXlWYWx1ZQorICAgKiB3aXRoIGEgZGlmZmVyZW50IFR5cGUgdG8gdGhlIGNhbmRpZGF0ZSBrZXkuCisgICAqIEBwYXJhbSBkZWxldGVzIFBhc3MgYSBTZXQgdGhhdCBoYXMgYSBDb21wYXJhdG9yIHRoYXQgaWdub3JlcyBrZXkgdHlwZS4KKyAgICovCisgIHZvaWQgZ2V0Um93S2V5QXRPckJlZm9yZShmaW5hbCBLZXlWYWx1ZSBrdiwKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gY2FuZGlkYXRlcywgCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsIGZpbmFsIGxvbmcgbm93KSB7CisgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBnZXRSb3dLZXlBdE9yQmVmb3JlKG1lbWNhY2hlLCBrdiwgY2FuZGlkYXRlcywgZGVsZXRlcywgbm93KTsKKyAgICAgIGdldFJvd0tleUF0T3JCZWZvcmUoc25hcHNob3QsIGt2LCBjYW5kaWRhdGVzLCBkZWxldGVzLCBub3cpOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgZ2V0Um93S2V5QXRPckJlZm9yZShmaW5hbCBDb25jdXJyZW50U2tpcExpc3RTZXQ8S2V5VmFsdWU+IHNldCwKKyAgICAgIGZpbmFsIEtleVZhbHVlIGt2LCBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGNhbmRpZGF0ZXMsCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsIGZpbmFsIGxvbmcgbm93KSB7CisgICAgaWYgKHNldC5pc0VtcHR5KCkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gV2Ugd2FudCB0aGUgZWFybGllc3QgcG9zc2libGUgdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uICBTdGFydCBiZWZvcmUKKyAgICAvLyB0aGUgY2FuZGlkYXRlIGtleSBpbiBjYXNlIGl0IHR1cm5zIG91dCBhIGRlbGV0ZSBjYW1lIGluIGxhdGVyLgorICAgIEtleVZhbHVlIHNlYXJjaCA9IGNhbmRpZGF0ZXMuaXNFbXB0eSgpPyBrdjogY2FuZGlkYXRlcy5maXJzdCgpOworCisgICAgLy8gR2V0IGFsbCB0aGUgZW50cmllcyB0aGF0IGNvbWUgZXF1YWwgb3IgYWZ0ZXIgb3VyIHNlYXJjaCBrZXkKKyAgICBTb3J0ZWRTZXQ8S2V5VmFsdWU+IHRhaWxzZXQgPSBzZXQudGFpbFNldChzZWFyY2gpOworCisgICAgLy8gaWYgdGhlcmUgYXJlIGl0ZW1zIGluIHRoZSB0YWlsIG1hcCwgdGhlcmUncyBlaXRoZXIgYSBkaXJlY3QgbWF0Y2ggdG8KKyAgICAvLyB0aGUgc2VhcmNoIGtleSwgb3IgYSByYW5nZSBvZiB2YWx1ZXMgYmV0d2VlbiB0aGUgZmlyc3QgY2FuZGlkYXRlIGtleQorICAgIC8vIGFuZCB0aGUgdWx0aW1hdGUgc2VhcmNoIGtleSAob3IgdGhlIGVuZCBvZiB0aGUgY2FjaGUpCisgICAgaWYgKCF0YWlsc2V0LmlzRW1wdHkoKSAmJgorICAgICAgICB0aGlzLmNvbXBhcmF0b3IuY29tcGFyZVJvd3ModGFpbHNldC5maXJzdCgpLCBzZWFyY2gpIDw9IDApIHsKKyAgICAgIC8vIEtlZXAgbG9va2luZyBhdCBjZWxscyBhcyBsb25nIGFzIHRoZXkgYXJlIG5vIGdyZWF0ZXIgdGhhbiB0aGUgCisgICAgICAvLyB1bHRpbWF0ZSBzZWFyY2gga2V5IGFuZCB0aGVyZSdzIHN0aWxsIHJlY29yZHMgbGVmdCBpbiB0aGUgbWFwLgorICAgICAgS2V5VmFsdWUgZGVsZXRlZCA9IG51bGw7CisgICAgICBLZXlWYWx1ZSBmb3VuZCA9IG51bGw7CisgICAgICBmb3IgKEl0ZXJhdG9yPEtleVZhbHVlPiBpdGVyYXRvciA9IHRhaWxzZXQuaXRlcmF0b3IoKTsKKyAgICAgICAgaXRlcmF0b3IuaGFzTmV4dCgpICYmIChmb3VuZCA9PSBudWxsIHx8CisgICAgICAgICAgdGhpcy5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKGZvdW5kLCBrdikgPD0gMCk7KSB7CisgICAgICAgIGZvdW5kID0gaXRlcmF0b3IubmV4dCgpOworICAgICAgICBpZiAodGhpcy5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKGZvdW5kLCBrdikgPD0gMCkgeworICAgICAgICAgIGlmIChmb3VuZC5pc0RlbGV0ZVR5cGUoKSkgeworICAgICAgICAgICAgU3RvcmUuaGFuZGxlRGVsZXRlcyhmb3VuZCwgY2FuZGlkYXRlcywgZGVsZXRlcyk7CisgICAgICAgICAgICBpZiAoZGVsZXRlZCA9PSBudWxsKSB7CisgICAgICAgICAgICAgIGRlbGV0ZWQgPSBmb3VuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKFN0b3JlLm5vdEV4cGlyZWRBbmROb3RJbkRlbGV0ZXModGhpcy50dGwsIGZvdW5kLCBub3csIGRlbGV0ZXMpKSB7CisgICAgICAgICAgICAgIGNhbmRpZGF0ZXMuYWRkKGZvdW5kKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIGlmIChkZWxldGVkID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICBkZWxldGVkID0gZm91bmQ7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgLy8gVE9ETzogQ2hlY2sgdGhpcyByZW1vdmVzIHRoZSByaWdodCBrZXkuCisgICAgICAgICAgICAgIC8vIEl0cyBleHBpcmVkLiAgUmVtb3ZlIGl0LgorICAgICAgICAgICAgICBpdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlmIChjYW5kaWRhdGVzLmlzRW1wdHkoKSAmJiBkZWxldGVkICE9IG51bGwpIHsKKyAgICAgICAgZ2V0Um93S2V5QmVmb3JlKHNldCwgZGVsZXRlZCwgY2FuZGlkYXRlcywgZGVsZXRlcywgbm93KTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gVGhlIHRhaWwgZGlkbid0IGNvbnRhaW4gYW55IGtleXMgdGhhdCBtYXRjaGVkIG91ciBjcml0ZXJpYSwgb3Igd2FzIAorICAgICAgLy8gZW1wdHkuIEV4YW1pbmUgYWxsIHRoZSBrZXlzIHRoYXQgcHJvY2VlZCBvdXIgc3BsaXR0aW5nIHBvaW50LgorICAgICAgZ2V0Um93S2V5QmVmb3JlKHNldCwgc2VhcmNoLCBjYW5kaWRhdGVzLCBkZWxldGVzLCBub3cpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIEdldCByb3cga2V5IHRoYXQgY29tZXMgYmVmb3JlIHBhc3NlZCA8Y29kZT5zZWFyY2hfa2V5PC9jb2RlPgorICAgKiBVc2Ugd2hlbiB3ZSBrbm93IHNlYXJjaF9rZXkgaXMgbm90IGluIHRoZSBtYXAgYW5kIHdlIG5lZWQgdG8gc2VhcmNoCisgICAqIGVhcmxpZXIgaW4gdGhlIGNhY2hlLgorICAgKiBAcGFyYW0gc2V0CisgICAqIEBwYXJhbSBzZWFyY2gKKyAgICogQHBhcmFtIGNhbmRpZGF0ZXMKKyAgICogQHBhcmFtIGRlbGV0ZXMgUGFzcyBhIFNldCB0aGF0IGhhcyBhIENvbXBhcmF0b3IgdGhhdCBpZ25vcmVzIGtleSB0eXBlLgorICAgKiBAcGFyYW0gbm93CisgICAqLworICBwcml2YXRlIHZvaWQgZ2V0Um93S2V5QmVmb3JlKENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gc2V0LAorICAgICAgS2V5VmFsdWUgc2VhcmNoLCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGNhbmRpZGF0ZXMsCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsIGZpbmFsIGxvbmcgbm93KSB7CisgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBoZWFkU2V0ID0gc2V0LmhlYWRTZXQoc2VhcmNoKTsKKyAgICAvLyBJZiB3ZSB0cmllZCB0byBjcmVhdGUgYSBoZWFkTWFwIGFuZCBnb3QgYW4gZW1wdHkgbWFwLCB0aGVuIHRoZXJlIGFyZQorICAgIC8vIG5vIGtleXMgYXQgb3IgYmVmb3JlIHRoZSBzZWFyY2gga2V5LCBzbyB3ZSdyZSBkb25lLgorICAgIGlmIChoZWFkU2V0LmlzRW1wdHkoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIElmIHRoZXJlIGFyZW4ndCBhbnkgY2FuZGlkYXRlIGtleXMgYXQgdGhpcyBwb2ludCwgd2UgbmVlZCB0byBzZWFyY2gKKyAgICAvLyBiYWNrd2FyZHMgdW50aWwgd2UgZmluZCBhdCBsZWFzdCBvbmUgY2FuZGlkYXRlIG9yIHJ1biBvdXQgb2YgaGVhZE1hcC4KKyAgICBpZiAoY2FuZGlkYXRlcy5pc0VtcHR5KCkpIHsKKyAgICAgIEtleVZhbHVlIGxhc3RGb3VuZCA9IG51bGw7CisgICAgICBmb3IgKEl0ZXJhdG9yPEtleVZhbHVlPiBpID0gaGVhZFNldC5kZXNjZW5kaW5nSXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CisgICAgICAgIEtleVZhbHVlIGZvdW5kID0gaS5uZXh0KCk7CisgICAgICAgIC8vIGlmIHRoZSBsYXN0IHJvdyB3ZSBmb3VuZCBhIGNhbmRpZGF0ZSBrZXkgZm9yIGlzIGRpZmZlcmVudCB0aGFuCisgICAgICAgIC8vIHRoZSByb3cgb2YgdGhlIGN1cnJlbnQgY2FuZGlkYXRlLCB3ZSBjYW4gc3RvcCBsb29raW5nIC0tIGlmIGl0cworICAgICAgICAvLyBub3QgYSBkZWxldGUgcmVjb3JkLgorICAgICAgICBib29sZWFuIGRlbGV0ZWQgPSBmb3VuZC5pc0RlbGV0ZVR5cGUoKTsKKyAgICAgICAgaWYgKGxhc3RGb3VuZCAhPSBudWxsICYmCisgICAgICAgICAgICB0aGlzLmNvbXBhcmF0b3IubWF0Y2hpbmdSb3dzKGxhc3RGb3VuZCwgZm91bmQpICYmICFkZWxldGVkKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgLy8gSWYgdGhpcyBpc24ndCBhIGRlbGV0ZSwgcmVjb3JkIGl0IGFzIGEgY2FuZGlkYXRlIGtleS4gQWxzbyAKKyAgICAgICAgLy8gdGFrZSBub3RlIG9mIHRoaXMgY2FuZGlkYXRlIHNvIHRoYXQgd2UnbGwga25vdyB3aGVuCisgICAgICAgIC8vIHdlIGNyb3NzIHRoZSByb3cgYm91bmRhcnkgaW50byB0aGUgcHJldmlvdXMgcm93LgorICAgICAgICBpZiAoIWRlbGV0ZWQpIHsKKyAgICAgICAgICBpZiAoU3RvcmUubm90RXhwaXJlZEFuZE5vdEluRGVsZXRlcyh0aGlzLnR0bCwgZm91bmQsIG5vdywgZGVsZXRlcykpIHsKKyAgICAgICAgICAgIGxhc3RGb3VuZCA9IGZvdW5kOworICAgICAgICAgICAgY2FuZGlkYXRlcy5hZGQoZm91bmQpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBJdHMgZXhwaXJlZC4KKyAgICAgICAgICAgIFN0b3JlLmV4cGlyZWRPckRlbGV0ZWQoc2V0LCBmb3VuZCk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFdlIGFyZSBlbmNvdW50ZXJpbmcgaXRlbXMgaW4gcmV2ZXJzZS4gIFdlIG1heSBoYXZlIGp1c3QgYWRkZWQKKyAgICAgICAgICAvLyBhbiBpdGVtIHRvIGNhbmRpZGF0ZXMgdGhhdCB0aGlzIGxhdGVyIGl0ZW0gZGVsZXRlcy4gIENoZWNrLiAgSWYgd2UKKyAgICAgICAgICAvLyBmb3VuZCBzb21ldGhpbmcgaW4gY2FuZGlkYXRlcywgcmVtb3ZlIGl0IGZyb20gdGhlIHNldC4KKyAgICAgICAgICBpZiAoU3RvcmUuaGFuZGxlRGVsZXRlcyhmb3VuZCwgY2FuZGlkYXRlcywgZGVsZXRlcykpIHsKKyAgICAgICAgICAgIHJlbW92ZShzZXQsIGZvdW5kKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgc29tZSBjYW5kaWRhdGUga2V5cywgd2Ugb25seSBuZWVkIHRvIGNvbnNpZGVyCisgICAgICAvLyB0aGUgdmVyeSBsYXN0IHJvdydzIHdvcnRoIG9mIGtleXMgaW4gdGhlIGhlYWRNYXAsIGJlY2F1c2UgYW55IAorICAgICAgLy8gc21hbGxlciBhY2NlcHRhYmxlIGNhbmRpZGF0ZSBrZXlzIHdvdWxkIGhhdmUgY2F1c2VkIHVzIHRvIHN0YXJ0CisgICAgICAvLyBvdXIgc2VhcmNoIGVhcmxpZXIgaW4gdGhlIGxpc3QsIGFuZCB3ZSB3b3VsZG4ndCBiZSBzZWFyY2hpbmcgaGVyZS4KKyAgICAgIFNvcnRlZFNldDxLZXlWYWx1ZT4gcm93VGFpbE1hcCA9IAorICAgICAgICBoZWFkU2V0LnRhaWxTZXQoaGVhZFNldC5sYXN0KCkuY2xvbmVSb3coSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKSk7CisgICAgICBJdGVyYXRvcjxLZXlWYWx1ZT4gaSA9IHJvd1RhaWxNYXAuaXRlcmF0b3IoKTsKKyAgICAgIGRvIHsKKyAgICAgICAgS2V5VmFsdWUgZm91bmQgPSBpLm5leHQoKTsKKyAgICAgICAgaWYgKGZvdW5kLmlzRGVsZXRlVHlwZSgpKSB7CisgICAgICAgICAgU3RvcmUuaGFuZGxlRGVsZXRlcyhmb3VuZCwgY2FuZGlkYXRlcywgZGVsZXRlcyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKHR0bCA9PSBIQ29uc3RhbnRzLkZPUkVWRVIgfHwKKyAgICAgICAgICAgICAgbm93IDwgZm91bmQuZ2V0VGltZXN0YW1wKCkgKyB0dGwgfHwKKyAgICAgICAgICAgICAgIWRlbGV0ZXMuY29udGFpbnMoZm91bmQpKSB7CisgICAgICAgICAgICBjYW5kaWRhdGVzLmFkZChmb3VuZCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFN0b3JlLmV4cGlyZWRPckRlbGV0ZWQoc2V0LCBmb3VuZCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IHdoaWxlIChpLmhhc05leHQoKSk7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogRXhhbWluZSBhIHNpbmdsZSBtYXAgZm9yIHRoZSBkZXNpcmVkIGtleS4KKyAgICoKKyAgICogVE9ETyAtIFRoaXMgaXMga2luZGEgc2xvdy4gIFdlIG5lZWQgYSBkYXRhIHN0cnVjdHVyZSB0aGF0IGFsbG93cyBmb3IgCisgICAqIHByb3hpbWl0eS1zZWFyY2hlcywgbm90IGp1c3QgcHJlY2lzZS1tYXRjaGVzLgorICAgKiAKKyAgICogQHBhcmFtIHNldAorICAgKiBAcGFyYW0ga2V5CisgICAqIEBwYXJhbSByZXN1bHRzCisgICAqIEBwYXJhbSB2ZXJzaW9ucworICAgKiBAcGFyYW0ga2V5dmFsdWVzCisgICAqIEBwYXJhbSBkZWxldGVzIFBhc3MgYSBTZXQgdGhhdCBoYXMgYSBDb21wYXJhdG9yIHRoYXQgaWdub3JlcyBrZXkgdHlwZS4KKyAgICogQHBhcmFtIG5vdworICAgKiBAcmV0dXJuIFRydWUgaWYgZW5vdWdoIHZlcnNpb25zLgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGdldChmaW5hbCBDb25jdXJyZW50U2tpcExpc3RTZXQ8S2V5VmFsdWU+IHNldCwKKyAgICAgIGZpbmFsIEtleVZhbHVlIGtleSwgZmluYWwgaW50IHZlcnNpb25zLAorICAgICAgZmluYWwgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzLAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBkZWxldGVzLAorICAgICAgZmluYWwgbG9uZyBub3cpIHsKKyAgICBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IHRhaWxzZXQgPSBzZXQudGFpbFNldChrZXkpOworICAgIGlmICh0YWlsc2V0LmlzRW1wdHkoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBib29sZWFuIGVub3VnaFZlcnNpb25zID0gZmFsc2U7CisgICAgZm9yIChLZXlWYWx1ZSBrdiA6IHRhaWxzZXQpIHsKKyAgICAgIGlmICh0aGlzLmNvbXBhcmF0b3IubWF0Y2hpbmdSb3dDb2x1bW4oa3YsIGtleSkpIHsKKyAgICAgICAgaWYgKFN0b3JlLmRvS2V5VmFsdWUoa3YsIHZlcnNpb25zLCBkZWxldGVzLCBub3csIHRoaXMudHRsLCBrZXl2YWx1ZXMsCisgICAgICAgICAgICB0YWlsc2V0KSkgeworICAgICAgICAgIGVub3VnaFZlcnNpb25zID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQnkgTC5OLiBIQkFTRS02ODQsIG1hcCBpcyBzb3J0ZWQsIHNvIHdlIGNhbid0IGZpbmQgbWF0Y2ggYW55IG1vcmUuCisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZW5vdWdoVmVyc2lvbnM7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gc2V0CisgICAqIEBwYXJhbSBrdiBUaGlzIGlzIGEgZGVsZXRlIHJlY29yZC4gIFJlbW92ZSBhbnl0aGluZyBiZWhpbmQgdGhpcyBvZiBzYW1lCisgICAqIHIvYy90cy4KKyAgICogQHJldHVybiBUcnVlIGlmIHdlIHJlbW92ZWQgYW55dGhpbmcuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gcmVtb3ZlKGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gc2V0LCBmaW5hbCBLZXlWYWx1ZSBrdikgeworICAgIFNvcnRlZFNldDxLZXlWYWx1ZT4gcyA9IHNldC50YWlsU2V0KGt2KTsKKyAgICBpZiAocy5pc0VtcHR5KCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgYm9vbGVhbiByZW1vdmVkID0gZmFsc2U7CisgICAgZm9yIChLZXlWYWx1ZSBrOiBzKSB7CisgICAgICBpZiAodGhpcy5jb21wYXJhdG9ySWdub3JlVHlwZS5jb21wYXJlKGssIGt2KSA9PSAwKSB7CisgICAgICAgIC8vIFNhbWUgci9jL3RzLiAgUmVtb3ZlIGl0LgorICAgICAgICBzLnJlbW92ZShrKTsKKyAgICAgICAgcmVtb3ZlZCA9IHRydWU7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiByZW1vdmVkOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gYSBzY2FubmVyIG92ZXIgdGhlIGtleXMgaW4gdGhlIE1lbWNhY2hlCisgICAqLworICBJbnRlcm5hbFNjYW5uZXIgZ2V0U2Nhbm5lcihsb25nIHRpbWVzdGFtcCwKKyAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gdGFyZ2V0Q29scywgZmluYWwgYnl0ZSBbXSBmaXJzdFJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBuZXcgTWVtY2FjaGVTY2FubmVyKHRpbWVzdGFtcCwgdGFyZ2V0Q29scywgZmlyc3RSb3cpOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy8gTWVtY2FjaGVTY2FubmVyIGltcGxlbWVudHMgdGhlIEludGVybmFsU2Nhbm5lci4KKyAgLy8gSXQgbGV0cyB0aGUgY2FsbGVyIHNjYW4gdGhlIGNvbnRlbnRzIG9mIHRoZSBNZW1jYWNoZS4KKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgcHJpdmF0ZSBjbGFzcyBNZW1jYWNoZVNjYW5uZXIgZXh0ZW5kcyBIQWJzdHJhY3RTY2FubmVyIHsKKyAgICBwcml2YXRlIEtleVZhbHVlIGN1cnJlbnQ7CisgICAgcHJpdmF0ZSBmaW5hbCBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gY29sdW1uczsKKyAgICBwcml2YXRlIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlczsKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxLZXlWYWx1ZSwgQ291bnRlcj4gdmVyc2lvbkNvdW50ZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworCisgICAgTWVtY2FjaGVTY2FubmVyKGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gY29sdW1ucywKKyAgICAgIGZpbmFsIGJ5dGUgW10gZmlyc3RSb3cpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIENhbGwgdG8gc3VwZXIgd2lsbCBjcmVhdGUgQ29sdW1uTWF0Y2hlcnMgYW5kIHdoZXRoZXIgdGhpcyBpcyBhIHJlZ2V4CisgICAgICAvLyBzY2FubmVyIG9yIG5vdC4gIFdpbGwgYWxzbyBzYXZlIGF3YXkgdGltZXN0YW1wLiAgQWxzbyBzb3J0cyByb3dzLgorICAgICAgc3VwZXIodGltZXN0YW1wLCBjb2x1bW5zKTsKKyAgICAgIHRoaXMuZGVsZXRlcyA9IG5ldyBUcmVlU2V0PEtleVZhbHVlPihjb21wYXJhdG9ySWdub3JlVHlwZSk7CisgICAgICB0aGlzLnZlcnNpb25Db3VudGVyID0KKyAgICAgICAgbmV3IFRyZWVNYXA8S2V5VmFsdWUsIENvdW50ZXI+KGNvbXBhcmF0b3JJZ25vcmVUaW1lc3RhbXApOworICAgICAgdGhpcy5jdXJyZW50ID0gS2V5VmFsdWUuY3JlYXRlRmlyc3RPblJvdyhmaXJzdFJvdywgdGltZXN0YW1wKTsKKyAgICAgIC8vIElmIHdlJ3JlIGJlaW5nIGFza2VkIHRvIHNjYW4gZXhwbGljaXQgY29sdW1ucyByYXRoZXIgdGhhbiBhbGwgaW4gCisgICAgICAvLyBhIGZhbWlseSBvciBjb2x1bW5zIHRoYXQgbWF0Y2ggcmVnZXhlcywgY2FjaGUgdGhlIHNvcnRlZCBhcnJheSBvZgorICAgICAgLy8gY29sdW1ucy4KKyAgICAgIHRoaXMuY29sdW1ucyA9IGlzV2lsZGNhcmRTY2FubmVyKCk/IG51bGw6IGNvbHVtbnM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gbmV4dChmaW5hbCBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh0aGlzLnNjYW5uZXJDbG9zZWQpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgd2hpbGUgKGtleXZhbHVlcy5pc0VtcHR5KCkgJiYgdGhpcy5jdXJyZW50ICE9IG51bGwpIHsKKyAgICAgICAgLy8gRGVsZXRlcyBhcmUgcGVyIHJvdy4KKyAgICAgICAgaWYgKCFkZWxldGVzLmlzRW1wdHkoKSkgeworICAgICAgICAgIGRlbGV0ZXMuY2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXZlcnNpb25Db3VudGVyLmlzRW1wdHkoKSkgeworICAgICAgICAgIHZlcnNpb25Db3VudGVyLmNsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgLy8gVGhlIGdldEZ1bGwgd2lsbCB0YWtlIGNhcmUgb2YgZXhwaXJlZCBhbmQgZGVsZXRlcyBpbnNpZGUgbWVtY2FjaGUuCisgICAgICAgIC8vIFRoZSBmaXJzdCBnZXRGdWxsIHdoZW4gcm93IGlzIHRoZSBzcGVjaWFsIGVtcHR5IGJ5dGVzIHdpbGwgcmV0dXJuCisgICAgICAgIC8vIG5vdGhpbmcgc28gd2UgZ28gYXJvdW5kIGFnYWluLiAgQWx0ZXJuYXRpdmUgaXMgY2FsbGluZyBhIGdldE5leHRSb3cKKyAgICAgICAgLy8gaWYgcm93IGlzIG51bGwgYnV0IHRoYXQgbG9va3MgbGlrZSBpdCB3b3VsZCB0YWtlIHNhbWUgYW1vdW50IG9mIHdvcmsKKyAgICAgICAgLy8gc28gbGVhdmUgaXQgZm9yIG5vdy4KKyAgICAgICAgZ2V0RnVsbCh0aGlzLmN1cnJlbnQsIGlzV2lsZGNhcmRTY2FubmVyKCk/IG51bGw6IHRoaXMuY29sdW1ucywgbnVsbCwgMSwKKyAgICAgICAgICB2ZXJzaW9uQ291bnRlciwgZGVsZXRlcywga2V5dmFsdWVzLCB0aGlzLm5vdyk7CisgICAgICAgIGZvciAoS2V5VmFsdWUgYmI6IGtleXZhbHVlcykgeworICAgICAgICAgIGlmIChpc1dpbGRjYXJkU2Nhbm5lcigpKSB7CisgICAgICAgICAgICAvLyBDaGVjayB0aGUgcmVzdWx0cyBtYXRjaC4gIFdlIG9ubHkgY2hlY2sgY29sdW1ucywgbm90IHRpbWVzdGFtcHMuCisgICAgICAgICAgICAvLyBXZSBwcmVzdW1lIHRoYXQgdGltZXN0YW1wcyBoYXZlIGJlZW4gaGFuZGxlZCBwcm9wZXJseSB3aGVuIHdlCisgICAgICAgICAgICAvLyBjYWxsZWQgZ2V0RnVsbC4KKyAgICAgICAgICAgIGlmICghY29sdW1uTWF0Y2goYmIpKSB7CisgICAgICAgICAgICAgIGtleXZhbHVlcy5yZW1vdmUoYmIpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBBZGQgYW55IGRlbGV0ZXMgZm91bmQgc28gdGhleSBhcmUgYXZhaWxhYmxlIHRvIHRoZSBTdG9yZVNjYW5uZXIjbmV4dC4KKyAgICAgICAgaWYgKCF0aGlzLmRlbGV0ZXMuaXNFbXB0eSgpKSB7CisgICAgICAgICAga2V5dmFsdWVzLmFkZEFsbChkZWxldGVzKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmN1cnJlbnQgPSBnZXROZXh0Um93KHRoaXMuY3VycmVudCk7CisgICAgICAgIC8vIENoYW5nZSBjdXJyZW50IHRvIGJlIGNvbHVtbi1sZXNzIGFuZCB0byBoYXZlIHRoZSBzY2FubmVycycgbm93LiAgV2UKKyAgICAgICAgLy8gZG8gdGhpcyBiZWNhdXNlIGZpcnN0IGl0ZW0gb24gJ25leHQgcm93JyBtYXkgbm90IGhhdmUgdGhlIHNjYW5uZXJzJworICAgICAgICAvLyBub3cgdGltZSB3aGljaCB3aWxsIGNhdXNlIHRyb3VibGUgZG93biBpbiBnZXRGdWxsOyBzYW1lIHJlYXNvbiBubworICAgICAgICAvLyBjb2x1bW4uCisgICAgICAgIGlmICh0aGlzLmN1cnJlbnQgIT0gbnVsbCkgdGhpcy5jdXJyZW50ID0gdGhpcy5jdXJyZW50LmNsb25lUm93KHRoaXMubm93KTsKKyAgICAgIH0KKyAgICAgIHJldHVybiAha2V5dmFsdWVzLmlzRW1wdHkoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICAgIGlmICghc2Nhbm5lckNsb3NlZCkgeworICAgICAgICBzY2FubmVyQ2xvc2VkID0gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ29kZSB0byBoZWxwIGZpZ3VyZSBpZiBvdXIgYXBwcm94aW1hdGlvbiBvZiBvYmplY3QgaGVhcCBzaXplcyBpcyBjbG9zZQorICAgKiBlbm91Z2guICBTZWUgaGJhc2UtOTAwLiAgRmlsbHMgbWVtY2FjaGVzIHRoZW4gd2FpdHMgc28gdXNlciBjYW4gaGVhcAorICAgKiBkdW1wIGFuZCBicmluZyB1cCByZXN1bHRhbnQgaHByb2YgaW4gc29tZXRoaW5nIGxpa2UganByb2ZpbGVyIHdoaWNoCisgICAqIGFsbG93cyB5b3UgZ2V0ICdkZWVwIHNpemUnIG9uIG9iamVjdHMuCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBbXSBhcmdzKQorICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICBSdW50aW1lTVhCZWFuIHJ1bnRpbWUgPSBNYW5hZ2VtZW50RmFjdG9yeS5nZXRSdW50aW1lTVhCZWFuKCk7CisgICAgTE9HLmluZm8oInZtTmFtZT0iICsgcnVudGltZS5nZXRWbU5hbWUoKSArICIsIHZtVmVuZG9yPSIgKworICAgICAgcnVudGltZS5nZXRWbVZlbmRvcigpICsgIiwgdm1WZXJzaW9uPSIgKyBydW50aW1lLmdldFZtVmVyc2lvbigpKTsKKyAgICBMT0cuaW5mbygidm1JbnB1dEFyZ3VtZW50cz0iICsgcnVudGltZS5nZXRJbnB1dEFyZ3VtZW50cygpKTsKKyAgICBNZW1jYWNoZSBtZW1jYWNoZTEgPSBuZXcgTWVtY2FjaGUoKTsKKyAgICAvLyBUT0RPOiB4MzIgdnMgeDY0CisgICAgbG9uZyBzaXplID0gMDsKKyAgICBmaW5hbCBpbnQgY291bnQgPSAxMDAwMDsKKyAgICBieXRlIFtdIGNvbHVtbiA9IEJ5dGVzLnRvQnl0ZXMoImNvbDp1bW4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIC8vIEdpdmUgZWFjaCBpdHMgb3duIHRzCisgICAgICBzaXplICs9IG1lbWNhY2hlMS5hZGQobmV3IEtleVZhbHVlKEJ5dGVzLnRvQnl0ZXMoaSksIGNvbHVtbiwgaSkpOworICAgIH0KKyAgICBMT0cuaW5mbygibWVtY2FjaGUxIGVzdGltYXRlZCBzaXplPSIgKyBzaXplKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIHNpemUgKz0gbWVtY2FjaGUxLmFkZChuZXcgS2V5VmFsdWUoQnl0ZXMudG9CeXRlcyhpKSwgY29sdW1uLCBpKSk7CisgICAgfQorICAgIExPRy5pbmZvKCJtZW1jYWNoZTEgZXN0aW1hdGVkIHNpemUgKDJuZCBsb2FkaW5nIG9mIHNhbWUgZGF0YSk9IiArIHNpemUpOworICAgIC8vIE1ha2UgYSB2YXJpYWJseSBzaXplZCBtZW1jYWNoZS4KKyAgICBNZW1jYWNoZSBtZW1jYWNoZTIgPSBuZXcgTWVtY2FjaGUoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIHNpemUgKz0gbWVtY2FjaGUyLmFkZChuZXcgS2V5VmFsdWUoQnl0ZXMudG9CeXRlcyhpKSwgY29sdW1uLCBpLAorICAgICAgICBuZXcgYnl0ZVtpXSkpOworICAgIH0KKyAgICBMT0cuaW5mbygibWVtY2FjaGUyIGVzdGltYXRlZCBzaXplPSIgKyBzaXplKTsKKyAgICBmaW5hbCBpbnQgc2Vjb25kcyA9IDMwOworICAgIExPRy5pbmZvKCJXYWl0aW5nICIgKyBzZWNvbmRzICsgIiBzZWNvbmRzIHdoaWxlIGhlYXAgZHVtcCBpcyB0YWtlbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2Vjb25kczsgaSsrKSB7CisgICAgICAvLyBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgfQorICAgIExPRy5pbmZvKCJFeGl0aW5nLiIpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTWVtY2FjaGVGbHVzaGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTWVtY2FjaGVGbHVzaGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBhYTQ4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9NZW1jYWNoZUZsdXNoZXIuamF2YQpAQCAtMCwwICsxLDMzNiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLm1hbmFnZW1lbnQuTWFuYWdlbWVudEZhY3Rvcnk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29uY3VycmVudE1vZGlmaWNhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuTGlua2VkQmxvY2tpbmdRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRHJvcHBlZFNuYXBzaG90RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlN0cmluZ1V0aWxzOworCisvKioKKyAqIFRocmVhZCB0aGF0IGZsdXNoZXMgY2FjaGUgb24gcmVxdWVzdAorICoKKyAqIE5PVEU6IFRoaXMgY2xhc3MgZXh0ZW5kcyBUaHJlYWQgcmF0aGVyIHRoYW4gQ2hvcmUgYmVjYXVzZSB0aGUgc2xlZXAgdGltZQorICogY2FuIGJlIGludGVycnVwdGVkIHdoZW4gdGhlcmUgaXMgc29tZXRoaW5nIHRvIGRvLCByYXRoZXIgdGhhbiB0aGUgQ2hvcmUKKyAqIHNsZWVwIHRpbWUgd2hpY2ggaXMgaW52YXJpYW50LgorICogCisgKiBAc2VlIEZsdXNoUmVxdWVzdGVyCisgKi8KK2NsYXNzIE1lbWNhY2hlRmx1c2hlciBleHRlbmRzIFRocmVhZCBpbXBsZW1lbnRzIEZsdXNoUmVxdWVzdGVyIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhNZW1jYWNoZUZsdXNoZXIuY2xhc3MpOworICBwcml2YXRlIGZpbmFsIEJsb2NraW5nUXVldWU8SFJlZ2lvbj4gZmx1c2hRdWV1ZSA9CisgICAgbmV3IExpbmtlZEJsb2NraW5nUXVldWU8SFJlZ2lvbj4oKTsKKyAgCisgIHByaXZhdGUgZmluYWwgSGFzaFNldDxIUmVnaW9uPiByZWdpb25zSW5RdWV1ZSA9IG5ldyBIYXNoU2V0PEhSZWdpb24+KCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIHRocmVhZFdha2VGcmVxdWVuY3k7CisgIHByaXZhdGUgZmluYWwgSFJlZ2lvblNlcnZlciBzZXJ2ZXI7CisgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50TG9jayBsb2NrID0gbmV3IFJlZW50cmFudExvY2soKTsKKworICBwcm90ZWN0ZWQgZmluYWwgbG9uZyBnbG9iYWxNZW1jYWNoZUxpbWl0OworICBwcm90ZWN0ZWQgZmluYWwgbG9uZyBnbG9iYWxNZW1jYWNoZUxpbWl0TG93TWFyazsKKyAgCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgREVGQVVMVF9VUFBFUiA9IDAuNGY7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgZmxvYXQgREVGQVVMVF9MT1dFUiA9IDAuMjVmOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBVUFBFUl9LRVkgPQorICAgICJoYmFzZS5yZWdpb25zZXJ2ZXIuZ2xvYmFsTWVtY2FjaGUudXBwZXJMaW1pdCI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIExPV0VSX0tFWSA9CisgICAgImhiYXNlLnJlZ2lvbnNlcnZlci5nbG9iYWxNZW1jYWNoZS5sb3dlckxpbWl0IjsKKyAgcHJpdmF0ZSBsb25nIGJsb2NraW5nU3RvcmVGaWxlc051bWJlcjsKKyAgcHJpdmF0ZSBsb25nIGJsb2NraW5nV2FpdFRpbWU7CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqIEBwYXJhbSBzZXJ2ZXIKKyAgICovCisgIHB1YmxpYyBNZW1jYWNoZUZsdXNoZXIoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsCisgICAgICBmaW5hbCBIUmVnaW9uU2VydmVyIHNlcnZlcikgeworICAgIHN1cGVyKCk7CisgICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7CisgICAgdGhpcy50aHJlYWRXYWtlRnJlcXVlbmN5ID0KKyAgICAgIGNvbmYuZ2V0TG9uZyhIQ29uc3RhbnRzLlRIUkVBRF9XQUtFX0ZSRVFVRU5DWSwgMTAgKiAxMDAwKTsKKyAgICBsb25nIG1heCA9IE1hbmFnZW1lbnRGYWN0b3J5LmdldE1lbW9yeU1YQmVhbigpLmdldEhlYXBNZW1vcnlVc2FnZSgpLmdldE1heCgpOworICAgIHRoaXMuZ2xvYmFsTWVtY2FjaGVMaW1pdCA9IGdsb2JhbE1lbWNhY2hlTGltaXQobWF4LCBERUZBVUxUX1VQUEVSLAorICAgICAgVVBQRVJfS0VZLCBjb25mKTsKKyAgICBsb25nIGxvd2VyID0gZ2xvYmFsTWVtY2FjaGVMaW1pdChtYXgsIERFRkFVTFRfTE9XRVIsIExPV0VSX0tFWSwgY29uZik7CisgICAgaWYgKGxvd2VyID4gdGhpcy5nbG9iYWxNZW1jYWNoZUxpbWl0KSB7CisgICAgICBsb3dlciA9IHRoaXMuZ2xvYmFsTWVtY2FjaGVMaW1pdDsKKyAgICAgIExPRy5pbmZvKCJTZXR0aW5nIGdsb2JhbE1lbWNhY2hlTGltaXRMb3dNYXJrID09IGdsb2JhbE1lbWNhY2hlTGltaXQgIiArCisgICAgICAgICJiZWNhdXNlIHN1cHBsaWVkICIgKyBMT1dFUl9LRVkgKyAiIHdhcyA+ICIgKyBVUFBFUl9LRVkpOworICAgIH0KKyAgICB0aGlzLmdsb2JhbE1lbWNhY2hlTGltaXRMb3dNYXJrID0gbG93ZXI7CisgICAgdGhpcy5ibG9ja2luZ1N0b3JlRmlsZXNOdW1iZXIgPSAKKyAgICAgIGNvbmYuZ2V0SW50KCJoYmFzZS5oc3RvcmUuYmxvY2tpbmdTdG9yZUZpbGVzIiwgLTEpOworICAgIGlmICh0aGlzLmJsb2NraW5nU3RvcmVGaWxlc051bWJlciA9PSAtMSkgeworICAgICAgdGhpcy5ibG9ja2luZ1N0b3JlRmlsZXNOdW1iZXIgPSAxICsKKyAgICAgICAgY29uZi5nZXRJbnQoImhiYXNlLmhzdG9yZS5jb21wYWN0aW9uVGhyZXNob2xkIiwgMyk7CisgICAgfQorICAgIHRoaXMuYmxvY2tpbmdXYWl0VGltZSA9IGNvbmYuZ2V0SW50KCJoYmFzZS5oc3RvcmUuYmxvY2tpbmdXYWl0VGltZSIsCisgICAgICA5MDAwMCk7IC8vIGRlZmF1bHQgb2YgMTgwIHNlY29uZHMKKyAgICBMT0cuaW5mbygiZ2xvYmFsTWVtY2FjaGVMaW1pdD0iICsKKyAgICAgIFN0cmluZ1V0aWxzLmh1bWFuUmVhZGFibGVJbnQodGhpcy5nbG9iYWxNZW1jYWNoZUxpbWl0KSArCisgICAgICAiLCBnbG9iYWxNZW1jYWNoZUxpbWl0TG93TWFyaz0iICsKKyAgICAgIFN0cmluZ1V0aWxzLmh1bWFuUmVhZGFibGVJbnQodGhpcy5nbG9iYWxNZW1jYWNoZUxpbWl0TG93TWFyaykgKworICAgICAgIiwgbWF4SGVhcD0iICsgU3RyaW5nVXRpbHMuaHVtYW5SZWFkYWJsZUludChtYXgpKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxjdWxhdGUgc2l6ZSB1c2luZyBwYXNzZWQgPGNvZGU+a2V5PC9jb2RlPiBmb3IgY29uZmlndXJlZAorICAgKiBwZXJjZW50YWdlIG9mIDxjb2RlPm1heDwvY29kZT4uCisgICAqIEBwYXJhbSBtYXgKKyAgICogQHBhcmFtIGRlZmF1bHRMaW1pdAorICAgKiBAcGFyYW0ga2V5CisgICAqIEBwYXJhbSBjCisgICAqIEByZXR1cm4gTGltaXQuCisgICAqLworICBzdGF0aWMgbG9uZyBnbG9iYWxNZW1jYWNoZUxpbWl0KGZpbmFsIGxvbmcgbWF4LAorICAgICBmaW5hbCBmbG9hdCBkZWZhdWx0TGltaXQsIGZpbmFsIFN0cmluZyBrZXksIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjKSB7CisgICAgZmxvYXQgbGltaXQgPSBjLmdldEZsb2F0KGtleSwgZGVmYXVsdExpbWl0KTsKKyAgICByZXR1cm4gZ2V0TWVtY2FjaGVMaW1pdChtYXgsIGxpbWl0LCBkZWZhdWx0TGltaXQpOworICB9CisgIAorICBzdGF0aWMgbG9uZyBnZXRNZW1jYWNoZUxpbWl0KGZpbmFsIGxvbmcgbWF4LCBmaW5hbCBmbG9hdCBsaW1pdCwKKyAgICAgIGZpbmFsIGZsb2F0IGRlZmF1bHRMaW1pdCkgeworICAgIGlmIChsaW1pdCA+PSAwLjlmIHx8IGxpbWl0IDwgMC4xZikgeworICAgICAgTE9HLndhcm4oIlNldHRpbmcgZ2xvYmFsIG1lbWNhY2hlIGxpbWl0IHRvIGRlZmF1bHQgb2YgIiArIGRlZmF1bHRMaW1pdCArCisgICAgICAgICIgYmVjYXVzZSBzdXBwbGllZCB2YWx1ZSBvdXRzaWRlIGFsbG93ZWQgcmFuZ2Ugb2YgMC4xIC0+IDAuOSIpOworICAgIH0KKyAgICByZXR1cm4gKGxvbmcpKG1heCAqIGxpbWl0KTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICB3aGlsZSAoIXRoaXMuc2VydmVyLmlzU3RvcFJlcXVlc3RlZCgpICYmIHRoaXMuc2VydmVyLmlzSW5TYWZlTW9kZSgpKSB7CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAodGhyZWFkV2FrZUZyZXF1ZW5jeSk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9CisgICAgd2hpbGUgKCFzZXJ2ZXIuaXNTdG9wUmVxdWVzdGVkKCkpIHsKKyAgICAgIEhSZWdpb24gciA9IG51bGw7CisgICAgICB0cnkgeworICAgICAgICByID0gZmx1c2hRdWV1ZS5wb2xsKHRocmVhZFdha2VGcmVxdWVuY3ksIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisgICAgICAgIGlmIChyID09IG51bGwpIHsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoIWZsdXNoUmVnaW9uKHIsIGZhbHNlKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0gY2F0Y2ggKENvbmN1cnJlbnRNb2RpZmljYXRpb25FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgTE9HLmVycm9yKCJDYWNoZSBmbHVzaCBmYWlsZWQiICsKKyAgICAgICAgICAociAhPSBudWxsID8gKCIgZm9yIHJlZ2lvbiAiICsgQnl0ZXMudG9TdHJpbmcoci5nZXRSZWdpb25OYW1lKCkpKSA6ICIiKSwKKyAgICAgICAgICBleCk7CisgICAgICAgIGlmICghc2VydmVyLmNoZWNrRmlsZVN5c3RlbSgpKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmVnaW9uc0luUXVldWUuY2xlYXIoKTsKKyAgICBmbHVzaFF1ZXVlLmNsZWFyKCk7CisgICAgTE9HLmluZm8oZ2V0TmFtZSgpICsgIiBleGl0aW5nIik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHJlcXVlc3QoSFJlZ2lvbiByKSB7CisgICAgc3luY2hyb25pemVkIChyZWdpb25zSW5RdWV1ZSkgeworICAgICAgaWYgKCFyZWdpb25zSW5RdWV1ZS5jb250YWlucyhyKSkgeworICAgICAgICByZWdpb25zSW5RdWV1ZS5hZGQocik7CisgICAgICAgIGZsdXNoUXVldWUuYWRkKHIpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIE9ubHkgaW50ZXJydXB0IG9uY2UgaXQncyBkb25lIHdpdGggYSBydW4gdGhyb3VnaCB0aGUgd29yayBsb29wLgorICAgKi8gCisgIHZvaWQgaW50ZXJydXB0SWZOZWNlc3NhcnkoKSB7CisgICAgbG9jay5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMuaW50ZXJydXB0KCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgfQorICB9CisgIAorICAvKgorICAgKiBGbHVzaCBhIHJlZ2lvbi4KKyAgICogCisgICAqIEBwYXJhbSByZWdpb24gdGhlIHJlZ2lvbiB0byBiZSBmbHVzaGVkCisgICAqIEBwYXJhbSByZW1vdmVGcm9tUXVldWUgVHJ1ZSBpZiB0aGUgcmVnaW9uIG5lZWRzIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGUKKyAgICogZmx1c2ggcXVldWUuIEZhbHNlIGlmIGNhbGxlZCBmcm9tIHRoZSBtYWluIGZsdXNoZXIgcnVuIGxvb3AgYW5kIHRydWUgaWYKKyAgICogY2FsbGVkIGZyb20gZmx1c2hTb21lUmVnaW9ucyB0byByZWxpZXZlIG1lbW9yeSBwcmVzc3VyZSBmcm9tIHRoZSByZWdpb24KKyAgICogc2VydmVyLiAgSWYgPGNvZGU+dHJ1ZTwvY29kZT4sIHdlIGFyZSBpbiBhIHN0YXRlIG9mIGVtZXJnZW5jeTsgd2UgYXJlIG5vdAorICAgKiB0YWtpbmcgb24gdXBkYXRlcyByZWdpb25zZXJ2ZXItd2lkZSwgbm90IHVudGlsIG1lbW9yeSBpcyBmbHVzaGVkLiAgSW4gdGhpcworICAgKiBjYXNlLCBkbyBub3QgbGV0IGEgY29tcGFjdGlvbiBydW4gaW5saW5lIHdpdGggYmxvY2tlZCB1cGRhdGVzLiBDb21wYWN0aW9ucworICAgKiBjYW4gdGFrZSBhIGxvbmcgdGltZS4gU3RvcHBpbmcgY29tcGFjdGlvbnMsIHRoZXJlIGlzIGEgZGFuZ2VyIHRoYXQgbnVtYmVyCisgICAqIG9mIGZsdXNoZXMgd2lsbCBvdmVyd2hlbG0gY29tcGFjdGlvbiBvbiBhIGJ1c3kgc2VydmVyOyB3ZSdsbCBoYXZlIHRvIHNlZS4KKyAgICogVGhhdCBjb21wYWN0aW9ucyBkbyBub3QgcnVuIHdoZW4gY2FsbGVkIG91dCBvZiBmbHVzaFNvbWVSZWdpb25zIG1lYW5zIHRoYXQKKyAgICogY29tcGFjdGlvbnMgY2FuIGJlIHJlcG9ydGVkIGJ5IHRoZSBoaXN0b3JpYW4gd2l0aG91dCBkYW5nZXIgb2YgZGVhZGxvY2sKKyAgICogKEhCQVNFLTY3MCkuCisgICAqIAorICAgKiA8cD5JbiB0aGUgbWFpbiBydW4gbG9vcCwgcmVnaW9ucyBoYXZlIGFscmVhZHkgYmVlbiByZW1vdmVkIGZyb20gdGhlIGZsdXNoCisgICAqIHF1ZXVlLCBhbmQgaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGZvciB0aGUgcmVsaWVmIG9mIG1lbW9yeSBwcmVzc3VyZSwKKyAgICogdGhpcyBtYXkgbm90IGJlIG5lY2Vzc2FyaWx5IHRydWUuIFdlIHdhbnQgdG8gYXZvaWQgdHJ5aW5nIHRvIHJlbW92ZSAKKyAgICogcmVnaW9uIGZyb20gdGhlIHF1ZXVlIGJlY2F1c2UgaWYgaXQgaGFzIGFscmVhZHkgYmVlbiByZW1vdmVkLCBpdCByZXF1aXJlcyBhCisgICAqIHNlcXVlbnRpYWwgc2NhbiBvZiB0aGUgcXVldWUgdG8gZGV0ZXJtaW5lIHRoYXQgaXQgaXMgbm90IGluIHRoZSBxdWV1ZS4KKyAgICogCisgICAqIDxwPklmIGNhbGxlZCBmcm9tIGZsdXNoU29tZVJlZ2lvbnMsIHRoZSByZWdpb24gbWF5IGJlIGluIHRoZSBxdWV1ZSBidXQKKyAgICogaXQgbWF5IGhhdmUgYmVlbiBkZXRlcm1pbmVkIHRoYXQgdGhlIHJlZ2lvbiBoYWQgYSBzaWduaWZpY2FudCBhbW91bnQgb2YgCisgICAqIG1lbW9yeSBpbiB1c2UgYW5kIG5lZWRlZCB0byBiZSBmbHVzaGVkIHRvIHJlbGlldmUgbWVtb3J5IHByZXNzdXJlLiBJbiB0aGlzCisgICAqIGNhc2UsIGl0cyBmbHVzaCBtYXkgcHJlZW1wdCB0aGUgcGVuZGluZyByZXF1ZXN0IGluIHRoZSBxdWV1ZSwgYW5kIGlmIHNvLAorICAgKiBpdCBuZWVkcyB0byBiZSByZW1vdmVkIGZyb20gdGhlIHF1ZXVlIHRvIGF2b2lkIGZsdXNoaW5nIHRoZSByZWdpb24KKyAgICogbXVsdGlwbGUgdGltZXMuCisgICAqIAorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHJlZ2lvbiB3YXMgc3VjY2Vzc2Z1bGx5IGZsdXNoZWQsIGZhbHNlIG90aGVyd2lzZS4gSWYgCisgICAqIGZhbHNlLCB0aGVyZSB3aWxsIGJlIGFjY29tcGFueWluZyBsb2cgbWVzc2FnZXMgZXhwbGFpbmluZyB3aHkgdGhlIGxvZyB3YXMKKyAgICogbm90IGZsdXNoZWQuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gZmx1c2hSZWdpb24oSFJlZ2lvbiByZWdpb24sIGJvb2xlYW4gcmVtb3ZlRnJvbVF1ZXVlKSB7CisgICAgLy8gV2FpdCB1bnRpbCBpdCBpcyBzYWZlIHRvIGZsdXNoLgorICAgIGJvb2xlYW4gdG9vbWFueTsKKyAgICBkbyB7CisgICAgICB0b29tYW55ID0gZmFsc2U7CisgICAgICBmb3IgKFN0b3JlIGhzdG9yZTogcmVnaW9uLnN0b3Jlcy52YWx1ZXMoKSkgeworICAgICAgICBpbnQgZmlsZXMgPSBoc3RvcmUuZ2V0U3RvcmVmaWxlc0NvdW50KCk7CisgICAgICAgIGlmIChmaWxlcyA+IHRoaXMuYmxvY2tpbmdTdG9yZUZpbGVzTnVtYmVyKSB7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuZGVidWcoIlRvbyBtYW55IHN0b3JlIGZpbGVzIGluIHN0b3JlICIgKyBoc3RvcmUgKyAiOiAiICsKKyAgICAgICAgICAgICAgZmlsZXMgKyAiLCB3YWl0aW5nIik7CisgICAgICAgICAgfQorICAgICAgICAgIHRvb21hbnkgPSB0cnVlOworICAgICAgICAgIHNlcnZlci5jb21wYWN0U3BsaXRUaHJlYWQuY29tcGFjdGlvblJlcXVlc3RlZChyZWdpb24sIGdldE5hbWUoKSk7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFRocmVhZC5zbGVlcChibG9ja2luZ1dhaXRUaW1lKTsKKyAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IHdoaWxlICh0b29tYW55KTsKKyAgICBzeW5jaHJvbml6ZWQgKHJlZ2lvbnNJblF1ZXVlKSB7CisgICAgICAvLyBTZWUgY29tbWVudCBhYm92ZSBmb3IgcmVtb3ZlRnJvbVF1ZXVlIG9uIHdoeSB3ZSBkbyBub3QKKyAgICAgIC8vIHRha2UgdGhlIHJlZ2lvbiBvdXQgb2YgdGhlIHNldC4gSWYgcmVtb3ZlRnJvbVF1ZXVlIGlzIHRydWUsIHJlbW92ZSBpdAorICAgICAgLy8gZnJvbSB0aGUgcXVldWUgdG9vIGlmIGl0IGlzIHRoZXJlLiBUaGlzIGRpZG4ndCB1c2VkIHRvIGJlIGEKKyAgICAgIC8vIGNvbnN0cmFpbnQsIGJ1dCBub3cgdGhhdCBIQkFTRS01MTIgaXMgaW4gcGxheSwgd2UgbmVlZCB0byB0cnkgYW5kCisgICAgICAvLyBsaW1pdCBkb3VibGUtZmx1c2hpbmcgb2YgcmVnaW9ucy4KKyAgICAgIGlmIChyZWdpb25zSW5RdWV1ZS5yZW1vdmUocmVnaW9uKSAmJiByZW1vdmVGcm9tUXVldWUpIHsKKyAgICAgICAgZmx1c2hRdWV1ZS5yZW1vdmUocmVnaW9uKTsKKyAgICAgIH0KKyAgICAgIGxvY2subG9jaygpOworICAgIH0KKyAgICB0cnkgeworICAgICAgLy8gU2VlIGNvbW1lbnQgYWJvdmUgZm9yIHJlbW92ZUZyb21RdWV1ZSBvbiB3aHkgd2UgZG8gbm90CisgICAgICAvLyBjb21wYWN0IGlmIHJlbW92ZUZyb21RdWV1ZSBpcyB0cnVlLiBOb3RlIHRoYXQgcmVnaW9uLmZsdXNoQ2FjaGUoKQorICAgICAgLy8gb25seSByZXR1cm5zIHRydWUgaWYgYSBmbHVzaCBpcyBkb25lIGFuZCBpZiBhIGNvbXBhY3Rpb24gaXMgbmVlZGVkLgorICAgICAgaWYgKHJlZ2lvbi5mbHVzaGNhY2hlKCkgJiYgIXJlbW92ZUZyb21RdWV1ZSkgeworICAgICAgICBzZXJ2ZXIuY29tcGFjdFNwbGl0VGhyZWFkLmNvbXBhY3Rpb25SZXF1ZXN0ZWQocmVnaW9uLCBnZXROYW1lKCkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKERyb3BwZWRTbmFwc2hvdEV4Y2VwdGlvbiBleCkgeworICAgICAgLy8gQ2FjaGUgZmx1c2ggY2FuIGZhaWwgaW4gYSBmZXcgcGxhY2VzLiBJZiBpdCBmYWlscyBpbiBhIGNyaXRpY2FsCisgICAgICAvLyBzZWN0aW9uLCB3ZSBnZXQgYSBEcm9wcGVkU25hcHNob3RFeGNlcHRpb24gYW5kIGEgcmVwbGF5IG9mIGhsb2cKKyAgICAgIC8vIGlzIHJlcXVpcmVkLiBDdXJyZW50bHkgdGhlIG9ubHkgd2F5IHRvIGRvIHRoaXMgaXMgYSByZXN0YXJ0IG9mCisgICAgICAvLyB0aGUgc2VydmVyLiBBYm9ydCBiZWNhdXNlIGhkZnMgaXMgcHJvYmFibHkgYmFkIChIQkFTRS02NDQgaXMgYSBjYXNlCisgICAgICAvLyB3aGVyZSBoZGZzIHdhcyBiYWQgYnV0IHBhc3NlZCB0aGUgaGRmcyBjaGVjaykuCisgICAgICBMT0cuZmF0YWwoIlJlcGxheSBvZiBobG9nIHJlcXVpcmVkLiBGb3JjaW5nIHNlcnZlciBzaHV0ZG93biIsIGV4KTsKKyAgICAgIHNlcnZlci5hYm9ydCgpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICBMT0cuZXJyb3IoIkNhY2hlIGZsdXNoIGZhaWxlZCIKKyAgICAgICAgICArIChyZWdpb24gIT0gbnVsbCA/ICgiIGZvciByZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbi5nZXRSZWdpb25OYW1lKCkpKSA6ICIiKSwKKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZXgpKTsKKyAgICAgIGlmICghc2VydmVyLmNoZWNrRmlsZVN5c3RlbSgpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgbG9jay51bmxvY2soKTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICAKKyAgLyoqCisgICAqIENoZWNrIGlmIHRoZSByZWdpb25zZXJ2ZXIncyBtZW1jYWNoZSBtZW1vcnkgdXNhZ2UgaXMgZ3JlYXRlciB0aGFuIHRoZSAKKyAgICogbGltaXQuIElmIHNvLCBmbHVzaCByZWdpb25zIHdpdGggdGhlIGJpZ2dlc3QgbWVtY2FjaGVzIHVudGlsIHdlJ3JlIGRvd24KKyAgICogdG8gdGhlIGxvd2VyIGxpbWl0LiBUaGlzIG1ldGhvZCBibG9ja3MgY2FsbGVycyB1bnRpbCB3ZSdyZSBkb3duIHRvIGEgc2FmZQorICAgKiBhbW91bnQgb2YgbWVtY2FjaGUgY29uc3VtcHRpb24uCisgICAqLworICBwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVjbGFpbU1lbWNhY2hlTWVtb3J5KCkgeworICAgIGlmIChzZXJ2ZXIuZ2V0R2xvYmFsTWVtY2FjaGVTaXplKCkgPj0gZ2xvYmFsTWVtY2FjaGVMaW1pdCkgeworICAgICAgZmx1c2hTb21lUmVnaW9ucygpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIEVtZXJnZW5jeSEgIE5lZWQgdG8gZmx1c2ggbWVtb3J5LgorICAgKi8KKyAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgdm9pZCBmbHVzaFNvbWVSZWdpb25zKCkgeworICAgIC8vIGtlZXAgZmx1c2hpbmcgdW50aWwgd2UgaGl0IHRoZSBsb3cgd2F0ZXIgbWFyaworICAgIGxvbmcgZ2xvYmFsTWVtY2FjaGVTaXplID0gLTE7CisgICAgQXJyYXlMaXN0PEhSZWdpb24+IHJlZ2lvbnNUb0NvbXBhY3QgPSBuZXcgQXJyYXlMaXN0PEhSZWdpb24+KCk7CisgICAgZm9yIChTb3J0ZWRNYXA8TG9uZywgSFJlZ2lvbj4gbSA9CisgICAgICAgIHRoaXMuc2VydmVyLmdldENvcHlPZk9ubGluZVJlZ2lvbnNTb3J0ZWRCeVNpemUoKTsKKyAgICAgIChnbG9iYWxNZW1jYWNoZVNpemUgPSBzZXJ2ZXIuZ2V0R2xvYmFsTWVtY2FjaGVTaXplKCkpID49CisgICAgICAgIHRoaXMuZ2xvYmFsTWVtY2FjaGVMaW1pdExvd01hcms7KSB7CisgICAgICAvLyBmbHVzaCB0aGUgcmVnaW9uIHdpdGggdGhlIGJpZ2dlc3QgbWVtY2FjaGUKKyAgICAgIGlmIChtLnNpemUoKSA8PSAwKSB7CisgICAgICAgIExPRy5pbmZvKCJObyBvbmxpbmUgcmVnaW9ucyB0byBmbHVzaCB0aG91Z2ggd2UndmUgYmVlbiBhc2tlZCBmbHVzaCAiICsKKyAgICAgICAgICAic29tZTsgZ2xvYmFsTWVtY2FjaGVTaXplPSIgKworICAgICAgICAgIFN0cmluZ1V0aWxzLmh1bWFuUmVhZGFibGVJbnQoZ2xvYmFsTWVtY2FjaGVTaXplKSArCisgICAgICAgICAgIiwgZ2xvYmFsTWVtY2FjaGVMaW1pdExvd01hcms9IiArCisgICAgICAgICAgU3RyaW5nVXRpbHMuaHVtYW5SZWFkYWJsZUludCh0aGlzLmdsb2JhbE1lbWNhY2hlTGltaXRMb3dNYXJrKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgSFJlZ2lvbiBiaWdnZXN0TWVtY2FjaGVSZWdpb24gPSBtLnJlbW92ZShtLmZpcnN0S2V5KCkpOworICAgICAgTE9HLmluZm8oIkZvcmNlZCBmbHVzaGluZyBvZiAiICsgIGJpZ2dlc3RNZW1jYWNoZVJlZ2lvbi50b1N0cmluZygpICsKKyAgICAgICAgIiBiZWNhdXNlIGdsb2JhbCBtZW1jYWNoZSBsaW1pdCBvZiAiICsKKyAgICAgICAgU3RyaW5nVXRpbHMuaHVtYW5SZWFkYWJsZUludCh0aGlzLmdsb2JhbE1lbWNhY2hlTGltaXQpICsKKyAgICAgICAgIiBleGNlZWRlZDsgY3VycmVudGx5ICIgKworICAgICAgICBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KGdsb2JhbE1lbWNhY2hlU2l6ZSkgKyAiIGFuZCBmbHVzaGluZyB0aWxsICIgKworICAgICAgICBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHRoaXMuZ2xvYmFsTWVtY2FjaGVMaW1pdExvd01hcmspKTsKKyAgICAgIGlmICghZmx1c2hSZWdpb24oYmlnZ2VzdE1lbWNhY2hlUmVnaW9uLCB0cnVlKSkgeworICAgICAgICBMT0cud2FybigiRmx1c2ggZmFpbGVkIik7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgcmVnaW9uc1RvQ29tcGFjdC5hZGQoYmlnZ2VzdE1lbWNhY2hlUmVnaW9uKTsKKyAgICB9CisgICAgZm9yIChIUmVnaW9uIHJlZ2lvbiA6IHJlZ2lvbnNUb0NvbXBhY3QpIHsKKyAgICAgIHNlcnZlci5jb21wYWN0U3BsaXRUaHJlYWQuY29tcGFjdGlvblJlcXVlc3RlZChyZWdpb24sIGdldE5hbWUoKSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTm9TdWNoQ29sdW1uRmFtaWx5RXhjZXB0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvTm9TdWNoQ29sdW1uRmFtaWx5RXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjE1MjM3MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Ob1N1Y2hDb2x1bW5GYW1pbHlFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDQxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuRG9Ob3RSZXRyeUlPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biBpZiByZXF1ZXN0IGZvciBub25leGlzdGVudCBjb2x1bW4gZmFtaWx5LgorICovCitwdWJsaWMgY2xhc3MgTm9TdWNoQ29sdW1uRmFtaWx5RXhjZXB0aW9uIGV4dGVuZHMgRG9Ob3RSZXRyeUlPRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTY1Njk5NTI3MzA4MzIzMzEyNzRMOworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBOb1N1Y2hDb2x1bW5GYW1pbHlFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbWVzc2FnZQorICAgKi8KKyAgcHVibGljIE5vU3VjaENvbHVtbkZhbWlseUV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSkgeworICAgIHN1cGVyKG1lc3NhZ2UpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1JlZ2lvblNlcnZlclJ1bm5pbmdFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9SZWdpb25TZXJ2ZXJSdW5uaW5nRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGJkZmVkYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9SZWdpb25TZXJ2ZXJSdW5uaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSw0NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogVGhyb3duIGlmIHRoZSByZWdpb24gc2VydmVyIGxvZyBkaXJlY3RvcnkgZXhpc3RzICh3aGljaCBpbmRpY2F0ZXMgYW5vdGhlcgorICogcmVnaW9uIHNlcnZlciBpcyBydW5uaW5nIGF0IHRoZSBzYW1lIGFkZHJlc3MpCisgKi8KK3B1YmxpYyBjbGFzcyBSZWdpb25TZXJ2ZXJSdW5uaW5nRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTCA8PCAzMSAtIDFMOworICAKKyAgLyoqIERlZmF1bHQgQ29uc3RydWN0b3IgKi8KKyAgcHVibGljIFJlZ2lvblNlcnZlclJ1bm5pbmdFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb25zdHJ1Y3RzIHRoZSBleGNlcHRpb24gYW5kIHN1cHBsaWVzIGEgc3RyaW5nIGFzIHRoZSBtZXNzYWdlCisgICAqIEBwYXJhbSBzIC0gbWVzc2FnZQorICAgKi8KKyAgcHVibGljIFJlZ2lvblNlcnZlclJ1bm5pbmdFeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9TdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4Y2Y0NGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmUuamF2YQpAQCAtMCwwICsxLDE4MDAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkVPRkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlTWFwOworaW1wb3J0IGphdmEudXRpbC5OYXZpZ2FibGVTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRTa2lwTGlzdE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50U2tpcExpc3RTZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29weU9uV3JpdGVBcnJheVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRSZWFkV3JpdGVMb2NrOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVtb3RlRXhjZXB0aW9uSGFuZGxlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlNlcXVlbmNlRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5Db21wcmVzc2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZVNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb24uQ291bnRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuRlNVdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyZXNzYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlN0cmluZ1V0aWxzOworCisvKioKKyAgKiBBIFN0b3JlIGhvbGRzIGEgY29sdW1uIGZhbWlseSBpbiBhIFJlZ2lvbi4gIEl0cyBhIG1lbWNhY2hlIGFuZCBhIHNldCBvZiB6ZXJvCisgICogb3IgbW9yZSBTdG9yZUZpbGVzLCB3aGljaCBzdHJldGNoIGJhY2t3YXJkcyBvdmVyIHRpbWUuCisgICoKKyAgKiA8cD5UaGVyZSdzIG5vIHJlYXNvbiB0byBjb25zaWRlciBhcHBlbmQtbG9nZ2luZyBhdCB0aGlzIGxldmVsOyBhbGwgbG9nZ2luZyAKKyAgKiBhbmQgbG9ja2luZyBpcyBoYW5kbGVkIGF0IHRoZSBIUmVnaW9uIGxldmVsLiAgU3RvcmUganVzdCBwcm92aWRlcworICAqIHNlcnZpY2VzIHRvIG1hbmFnZSBzZXRzIG9mIFN0b3JlRmlsZXMuICBPbmUgb2YgdGhlIG1vc3QgaW1wb3J0YW50IG9mIHRob3NlCisgICogc2VydmljZXMgaXMgY29tcGFjdGlvbiBzZXJ2aWNlcyB3aGVyZSBmaWxlcyBhcmUgYWdncmVnYXRlZCBvbmNlIHRoZXkgcGFzcworICAqIGEgY29uZmlndXJhYmxlIHRocmVzaG9sZC4KKyAgKgorICAqIDxwPlRoZSBvbmx5IHRoaW5nIGhhdmluZyB0byBkbyB3aXRoIGxvZ3MgdGhhdCBTdG9yZSBuZWVkcyB0byBkZWFsIHdpdGggaXMKKyAgKiB0aGUgcmVjb25zdHJ1Y3Rpb25Mb2cuICBUaGlzIGlzIGEgc2VnbWVudCBvZiBhbiBIUmVnaW9uJ3MgbG9nIHRoYXQgbWlnaHQKKyAgKiBOT1QgYmUgcHJlc2VudCB1cG9uIHN0YXJ0dXAuICBJZiB0aGUgcGFyYW0gaXMgTlVMTCwgdGhlcmUncyBub3RoaW5nIHRvIGRvLgorICAqIElmIHRoZSBwYXJhbSBpcyBub24tTlVMTCwgd2UgbmVlZCB0byBwcm9jZXNzIHRoZSBsb2cgdG8gcmVjb25zdHJ1Y3QKKyAgKiBhIFRyZWVNYXAgdGhhdCBtaWdodCBub3QgaGF2ZSBiZWVuIHdyaXR0ZW4gdG8gZGlzayBiZWZvcmUgdGhlIHByb2Nlc3MKKyAgKiBkaWVkLgorICAqCisgICogPHA+SXQncyBhc3N1bWVkIHRoYXQgYWZ0ZXIgdGhpcyBjb25zdHJ1Y3RvciByZXR1cm5zLCB0aGUgcmVjb25zdHJ1Y3Rpb25Mb2cKKyAgKiBmaWxlIHdpbGwgYmUgZGVsZXRlZCAoYnkgd2hvZXZlciBoYXMgaW5zdGFudGlhdGVkIHRoZSBTdG9yZSkuCisgKgorICogPHA+TG9ja2luZyBhbmQgdHJhbnNhY3Rpb25zIGFyZSBoYW5kbGVkIGF0IGEgaGlnaGVyIGxldmVsLiAgVGhpcyBBUEkgc2hvdWxkCisgKiBub3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJ1dCBieSBhbiBIUmVnaW9uIG1hbmFnZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBTdG9yZSBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFN0b3JlLmNsYXNzKTsKKyAgLyoqCisgICAqIENvbXBhcmF0b3IgdGhhdCBsb29rcyBhdCBjb2x1bW5zIGFuZCBjb21wYXJlcyB0aGVpciBmYW1pbHkgcG9ydGlvbnMuCisgICAqIFByZXN1bWVzIGNvbHVtbnMgaGF2ZSBhbHJlYWR5IGJlZW4gY2hlY2tlZCBmb3IgcHJlc2VuY2Ugb2YgZGVsaW1pdGVyLgorICAgKiBJZiBubyBkZWxpbWl0ZXIgcHJlc2VudCwgcHJlc3VtZSB0aGUgYnVmZmVyIGhvbGRzIGEgc3RvcmUgbmFtZSBzbyBubyBuZWVkCisgICAqIG9mIGEgZGVsaW1pdGVyLgorICAgKi8KKyAgcHJvdGVjdGVkIGZpbmFsIE1lbWNhY2hlIG1lbWNhY2hlOworICAvLyBUaGlzIHN0b3JlcyBkaXJlY3RvcnkgaW4gdGhlIGZpbGVzeXN0ZW0uCisgIHByaXZhdGUgZmluYWwgUGF0aCBob21lZGlyOworICBwcml2YXRlIGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbmluZm87CisgIHByaXZhdGUgZmluYWwgSENvbHVtbkRlc2NyaXB0b3IgZmFtaWx5OworICBmaW5hbCBGaWxlU3lzdGVtIGZzOworICBwcml2YXRlIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICAvLyB0dGwgaW4gbWlsbGlzZWNvbmRzLgorICBwcm90ZWN0ZWQgbG9uZyB0dGw7CisgIHByaXZhdGUgbG9uZyBtYWpvckNvbXBhY3Rpb25UaW1lOworICBwcml2YXRlIGludCBtYXhGaWxlc1RvQ29tcGFjdDsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIGRlc2lyZWRNYXhGaWxlU2l6ZTsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBsb25nIHN0b3JlU2l6ZSA9IDBMOworICBwcml2YXRlIGZpbmFsIE9iamVjdCBmbHVzaExvY2sgPSBuZXcgT2JqZWN0KCk7CisgIGZpbmFsIFJlZW50cmFudFJlYWRXcml0ZUxvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRSZWFkV3JpdGVMb2NrKCk7CisgIGZpbmFsIGJ5dGUgW10gc3RvcmVOYW1lOworICBwcml2YXRlIGZpbmFsIFN0cmluZyBzdG9yZU5hbWVTdHI7CisKKyAgLyoKKyAgICogU29ydGVkIE1hcCBvZiByZWFkZXJzIGtleWVkIGJ5IG1heGltdW0gZWRpdCBzZXF1ZW5jZSBpZCAoTW9zdCByZWNlbnQgc2hvdWxkCisgICAqIGJlIGxhc3QgaW4gaW4gbGlzdCkuICBDb25jdXJyZW50U2tpcExpc3RNYXAgaXMgbGF6aWx5IGNvbnNpc3RlbnQgc28gbm8KKyAgICogbmVlZCB0byBsb2NrIGl0IGRvd24gd2hlbiBpdGVyYXRpbmc7IGl0ZXJhdG9yIHZpZXcgaXMgdGhhdCBvZiB3aGVuIHRoZQorICAgKiBpdGVyYXRvciB3YXMgdGFrZW4gb3V0LgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBOYXZpZ2FibGVNYXA8TG9uZywgU3RvcmVGaWxlPiBzdG9yZWZpbGVzID0KKyAgICBuZXcgQ29uY3VycmVudFNraXBMaXN0TWFwPExvbmcsIFN0b3JlRmlsZT4oKTsKKworICAvLyBBbGwgYWNjZXNzIG11c3QgYmUgc3luY2hyb25pemVkLgorICBwcml2YXRlIGZpbmFsIENvcHlPbldyaXRlQXJyYXlTZXQ8Q2hhbmdlZFJlYWRlcnNPYnNlcnZlcj4gY2hhbmdlZFJlYWRlck9ic2VydmVycyA9CisgICAgbmV3IENvcHlPbldyaXRlQXJyYXlTZXQ8Q2hhbmdlZFJlYWRlcnNPYnNlcnZlcj4oKTsKKworICAvLyBUaGUgbW9zdC1yZWNlbnQgbG9nLXNlcS1JRC4gIFRoZSBtb3N0LXJlY2VudCBzdWNoIElEIG1lYW5zIHdlIGNhbiBpZ25vcmUKKyAgLy8gYWxsIGxvZyBtZXNzYWdlcyB1cCB0byBhbmQgaW5jbHVkaW5nIHRoYXQgSUQgKGJlY2F1c2UgdGhleSdyZSBhbHJlYWR5CisgIC8vIHJlZmxlY3RlZCBpbiB0aGUgVHJlZU1hcHMpLgorICBwcml2YXRlIHZvbGF0aWxlIGxvbmcgbWF4U2VxSWQgPSAtMTsKKworICBwcml2YXRlIGZpbmFsIFBhdGggY29tcGFjdGlvbkRpcjsKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgY29tcGFjdExvY2sgPSBuZXcgT2JqZWN0KCk7CisgIHByaXZhdGUgZmluYWwgaW50IGNvbXBhY3Rpb25UaHJlc2hvbGQ7CisgIHByaXZhdGUgZmluYWwgaW50IGJsb2Nrc2l6ZTsKKyAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGJsb29tZmlsdGVyOworICBwcml2YXRlIGZpbmFsIENvbXByZXNzaW9uLkFsZ29yaXRobSBjb21wcmVzc2lvbjsKKyAgCisgIC8vIENvbXBhcmluZyBLZXlWYWx1ZXMKKyAgZmluYWwgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGNvbXBhcmF0b3I7CisgIGZpbmFsIEtleVZhbHVlLktWQ29tcGFyYXRvciBjb21wYXJhdG9ySWdub3JpbmdUeXBlOworCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gYmFzZWRpciBxdWFsaWZpZWQgcGF0aCB1bmRlciB3aGljaCB0aGUgcmVnaW9uIGRpcmVjdG9yeSBsaXZlczsKKyAgICogZ2VuZXJhbGx5IHRoZSB0YWJsZSBzdWJkaXJlY3RvcnkKKyAgICogQHBhcmFtIGluZm8gSFJlZ2lvbkluZm8gZm9yIHRoaXMgcmVnaW9uCisgICAqIEBwYXJhbSBmYW1pbHkgSENvbHVtbkRlc2NyaXB0b3IgZm9yIHRoaXMgY29sdW1uCisgICAqIEBwYXJhbSBmcyBmaWxlIHN5c3RlbSBvYmplY3QKKyAgICogQHBhcmFtIHJlY29uc3RydWN0aW9uTG9nIGV4aXN0aW5nIGxvZyBmaWxlIHRvIGFwcGx5IGlmIGFueQorICAgKiBAcGFyYW0gY29uZiBjb25maWd1cmF0aW9uIG9iamVjdAorICAgKiBAcGFyYW0gcmVwb3J0ZXIgQ2FsbCBvbiBhIHBlcmlvZCBzbyBob3N0aW5nIHNlcnZlciBjYW4gcmVwb3J0IHdlJ3JlCisgICAqIG1ha2luZyBwcm9ncmVzcyB0byBtYXN0ZXIgLS0gb3RoZXJ3aXNlIG1hc3RlciBtaWdodCB0aGluayByZWdpb24gZGVwbG95CisgICAqIGZhaWxlZC4gIENhbiBiZSBudWxsLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcm90ZWN0ZWQgU3RvcmUoUGF0aCBiYXNlZGlyLCBIUmVnaW9uSW5mbyBpbmZvLCBIQ29sdW1uRGVzY3JpcHRvciBmYW1pbHksCisgICAgRmlsZVN5c3RlbSBmcywgUGF0aCByZWNvbnN0cnVjdGlvbkxvZywgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsCisgICAgZmluYWwgUHJvZ3Jlc3NhYmxlIHJlcG9ydGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geyAgCisgICAgdGhpcy5ob21lZGlyID0gZ2V0U3RvcmVIb21lZGlyKGJhc2VkaXIsIGluZm8uZ2V0RW5jb2RlZE5hbWUoKSwKKyAgICAgIGZhbWlseS5nZXROYW1lKCkpOworICAgIHRoaXMucmVnaW9uaW5mbyA9IGluZm87CisgICAgdGhpcy5mYW1pbHkgPSBmYW1pbHk7CisgICAgdGhpcy5mcyA9IGZzOworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgdGhpcy5ibG9vbWZpbHRlciA9IGZhbWlseS5pc0Jsb29tZmlsdGVyKCk7CisgICAgdGhpcy5ibG9ja3NpemUgPSBmYW1pbHkuZ2V0QmxvY2tzaXplKCk7CisgICAgdGhpcy5jb21wcmVzc2lvbiA9IGZhbWlseS5nZXRDb21wcmVzc2lvbigpOworICAgIHRoaXMuY29tcGFyYXRvciA9IGluZm8uZ2V0Q29tcGFyYXRvcigpOworICAgIHRoaXMuY29tcGFyYXRvcklnbm9yaW5nVHlwZSA9IHRoaXMuY29tcGFyYXRvci5nZXRDb21wYXJhdG9ySWdub3JpbmdUeXBlKCk7CisgICAgLy8gZ2V0VGltZVRvTGl2ZSByZXR1cm5zIHR0bCBpbiBzZWNvbmRzLiAgQ29udmVydCB0byBtaWxsaXNlY29uZHMuCisgICAgdGhpcy50dGwgPSBmYW1pbHkuZ2V0VGltZVRvTGl2ZSgpOworICAgIGlmICh0dGwgIT0gSENvbnN0YW50cy5GT1JFVkVSKSB7CisgICAgICB0aGlzLnR0bCAqPSAxMDAwOworICAgIH0KKyAgICB0aGlzLm1lbWNhY2hlID0gbmV3IE1lbWNhY2hlKHRoaXMudHRsLCB0aGlzLmNvbXBhcmF0b3IpOworICAgIHRoaXMuY29tcGFjdGlvbkRpciA9IEhSZWdpb24uZ2V0Q29tcGFjdGlvbkRpcihiYXNlZGlyKTsKKyAgICB0aGlzLnN0b3JlTmFtZSA9IHRoaXMuZmFtaWx5LmdldE5hbWUoKTsKKyAgICB0aGlzLnN0b3JlTmFtZVN0ciA9IEJ5dGVzLnRvU3RyaW5nKHRoaXMuc3RvcmVOYW1lKTsKKworICAgIC8vIEJ5IGRlZmF1bHQsIHdlIGNvbXBhY3QgaWYgYW4gSFN0b3JlIGhhcyBtb3JlIHRoYW4KKyAgICAvLyBNSU5fQ09NTUlUU19GT1JfQ09NUEFDVElPTiBtYXAgZmlsZXMKKyAgICB0aGlzLmNvbXBhY3Rpb25UaHJlc2hvbGQgPQorICAgICAgY29uZi5nZXRJbnQoImhiYXNlLmhzdG9yZS5jb21wYWN0aW9uVGhyZXNob2xkIiwgMyk7CisKKyAgICAvLyBCeSBkZWZhdWx0IHdlIHNwbGl0IHJlZ2lvbiBpZiBhIGZpbGUgPiBERUZBVUxUX01BWF9GSUxFX1NJWkUuCisgICAgbG9uZyBtYXhGaWxlU2l6ZSA9IGluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TWF4RmlsZVNpemUoKTsKKyAgICBpZiAobWF4RmlsZVNpemUgPT0gSENvbnN0YW50cy5ERUZBVUxUX01BWF9GSUxFX1NJWkUpIHsKKyAgICAgIG1heEZpbGVTaXplID0gY29uZi5nZXRMb25nKCJoYmFzZS5ocmVnaW9uLm1heC5maWxlc2l6ZSIsCisgICAgICAgIEhDb25zdGFudHMuREVGQVVMVF9NQVhfRklMRV9TSVpFKTsKKyAgICB9CisgICAgdGhpcy5kZXNpcmVkTWF4RmlsZVNpemUgPSBtYXhGaWxlU2l6ZTsKKworICAgIHRoaXMubWFqb3JDb21wYWN0aW9uVGltZSA9CisgICAgICBjb25mLmdldExvbmcoSENvbnN0YW50cy5NQUpPUl9DT01QQUNUSU9OX1BFUklPRCwgODY0MDAwMDApOworICAgIGlmIChmYW1pbHkuZ2V0VmFsdWUoSENvbnN0YW50cy5NQUpPUl9DT01QQUNUSU9OX1BFUklPRCkgIT0gbnVsbCkgeworICAgICAgU3RyaW5nIHN0ckNvbXBhY3Rpb25UaW1lID0KKyAgICAgICAgZmFtaWx5LmdldFZhbHVlKEhDb25zdGFudHMuTUFKT1JfQ09NUEFDVElPTl9QRVJJT0QpOworICAgICAgdGhpcy5tYWpvckNvbXBhY3Rpb25UaW1lID0gKG5ldyBMb25nKHN0ckNvbXBhY3Rpb25UaW1lKSkubG9uZ1ZhbHVlKCk7CisgICAgfQorCisgICAgdGhpcy5tYXhGaWxlc1RvQ29tcGFjdCA9IGNvbmYuZ2V0SW50KCJoYmFzZS5oc3RvcmUuY29tcGFjdGlvbi5tYXgiLCAxMCk7CisKKyAgICAvLyBsb2FkU3RvcmVGaWxlcyBjYWxjdWxhdGVzIHRoaXMubWF4U2VxSWQuIGFzIHNpZGUtZWZmZWN0LgorICAgIHRoaXMuc3RvcmVmaWxlcy5wdXRBbGwobG9hZFN0b3JlRmlsZXMoKSk7CisKKyAgICAvLyBEbyByZWNvbnN0cnVjdGlvbiBsb2cuCisgICAgcnVuUmVjb25zdHJ1Y3Rpb25Mb2cocmVjb25zdHJ1Y3Rpb25Mb2csIHRoaXMubWF4U2VxSWQsIHJlcG9ydGVyKTsKKyAgfQorCisgIEhDb2x1bW5EZXNjcmlwdG9yIGdldEZhbWlseSgpIHsKKyAgICByZXR1cm4gdGhpcy5mYW1pbHk7CisgIH0KKworICBsb25nIGdldE1heFNlcXVlbmNlSWQoKSB7CisgICAgcmV0dXJuIHRoaXMubWF4U2VxSWQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRhYmxlZGlyCisgICAqIEBwYXJhbSBlbmNvZGVkTmFtZSBFbmNvZGVkIHJlZ2lvbiBuYW1lLgorICAgKiBAcGFyYW0gZmFtaWx5CisgICAqIEByZXR1cm4gUGF0aCB0byBmYW1pbHkvU3RvcmUgaG9tZSBkaXJlY3RvcnkuCisgICAqLworICBwdWJsaWMgc3RhdGljIFBhdGggZ2V0U3RvcmVIb21lZGlyKGZpbmFsIFBhdGggdGFibGVkaXIsCisgICAgICBmaW5hbCBpbnQgZW5jb2RlZE5hbWUsIGZpbmFsIGJ5dGUgW10gZmFtaWx5KSB7CisgICAgcmV0dXJuIG5ldyBQYXRoKHRhYmxlZGlyLCBuZXcgUGF0aChJbnRlZ2VyLnRvU3RyaW5nKGVuY29kZWROYW1lKSwKKyAgICAgIG5ldyBQYXRoKEJ5dGVzLnRvU3RyaW5nKGZhbWlseSkpKSk7CisgIH0KKworICAvKgorICAgKiBSdW4gcmVjb25zdHJ1Y3Rpb24gbG9nCisgICAqIEBwYXJhbSByZWNvbnN0cnVjdGlvbkxvZworICAgKiBAcGFyYW0gbXNpZAorICAgKiBAcGFyYW0gcmVwb3J0ZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJ1blJlY29uc3RydWN0aW9uTG9nKGZpbmFsIFBhdGggcmVjb25zdHJ1Y3Rpb25Mb2csCisgICAgZmluYWwgbG9uZyBtc2lkLCBmaW5hbCBQcm9ncmVzc2FibGUgcmVwb3J0ZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGRvUmVjb25zdHJ1Y3Rpb25Mb2cocmVjb25zdHJ1Y3Rpb25Mb2csIG1zaWQsIHJlcG9ydGVyKTsKKyAgICB9IGNhdGNoIChFT0ZFeGNlcHRpb24gZSkgeworICAgICAgLy8gUHJlc3VtZSB3ZSBnb3QgaGVyZSBiZWNhdXNlIG9mIGxhY2sgb2YgSEFET09QLTE3MDA7IGZvciBub3cga2VlcCBnb2luZworICAgICAgLy8gYnV0IHRoaXMgaXMgcHJvYmFibHkgbm90IHdoYXQgd2Ugd2FudCBsb25nIHRlcm0uICBJZiB3ZSBnb3QgaGVyZSB0aGVyZQorICAgICAgLy8gaGFzIGJlZW4gZGF0YS1sb3NzCisgICAgICBMT0cud2FybigiRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVjb25zdHJ1Y3Rpb24gbG9nICIgKyByZWNvbnN0cnVjdGlvbkxvZyArCisgICAgICAgICIgb3BlbmluZyAiICsgQnl0ZXMudG9TdHJpbmcodGhpcy5zdG9yZU5hbWUpICsKKyAgICAgICAgIiAtLSBjb250aW51aW5nLiAgUHJvYmFibHkgbGFjay1vZi1IQURPT1AtMTcwMCBjYXVzaW5nIERBVEEgTE9TUyEiLCBlKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBQcmVzdW1lIHdlIGdvdCBoZXJlIGJlY2F1c2Ugb2Ygc29tZSBIREZTIGlzc3VlLiBEb24ndCBqdXN0IGtlZXAgZ29pbmcuCisgICAgICAvLyBGYWlsIHRvIG9wZW4gdGhlIEhTdG9yZS4gIFByb2JhYmx5IG1lYW5zIHdlJ2xsIGZhaWwgb3ZlciBhbmQgb3ZlcgorICAgICAgLy8gYWdhaW4gdW50aWwgaHVtYW4gaW50ZXJ2ZW50aW9uIGJ1dCBhbHRlcm5hdGl2ZSBoYXMgdXMgc2tpcHBpbmcgbG9ncworICAgICAgLy8gYW5kIGxvc2luZyBlZGl0czogSEJBU0UtNjQyLgorICAgICAgTE9HLndhcm4oIkV4Y2VwdGlvbiBwcm9jZXNzaW5nIHJlY29uc3RydWN0aW9uIGxvZyAiICsgcmVjb25zdHJ1Y3Rpb25Mb2cgKworICAgICAgICAiIG9wZW5pbmcgIiArIEJ5dGVzLnRvU3RyaW5nKHRoaXMuc3RvcmVOYW1lKSwgZSk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIFJlYWQgdGhlIHJlY29uc3RydWN0aW9uTG9nIHRvIHNlZSB3aGV0aGVyIHdlIG5lZWQgdG8gYnVpbGQgYSBicmFuZC1uZXcgCisgICAqIGZpbGUgb3V0IG9mIG5vbi1mbHVzaGVkIGxvZyBlbnRyaWVzLiAgCisgICAqCisgICAqIFdlIGNhbiBpZ25vcmUgYW55IGxvZyBtZXNzYWdlIHRoYXQgaGFzIGEgc2VxdWVuY2UgSUQgdGhhdCdzIGVxdWFsIHRvIG9yIAorICAgKiBsb3dlciB0aGFuIG1heFNlcUlELiAgKEJlY2F1c2Ugd2Uga25vdyBzdWNoIGxvZyBtZXNzYWdlcyBhcmUgYWxyZWFkeSAKKyAgICogcmVmbGVjdGVkIGluIHRoZSBNYXBGaWxlcy4pCisgICAqLworICBwcml2YXRlIHZvaWQgZG9SZWNvbnN0cnVjdGlvbkxvZyhmaW5hbCBQYXRoIHJlY29uc3RydWN0aW9uTG9nLAorICAgIGZpbmFsIGxvbmcgbWF4U2VxSUQsIGZpbmFsIFByb2dyZXNzYWJsZSByZXBvcnRlcikKKyAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICBpZiAocmVjb25zdHJ1Y3Rpb25Mb2cgPT0gbnVsbCB8fCAhdGhpcy5mcy5leGlzdHMocmVjb25zdHJ1Y3Rpb25Mb2cpKSB7CisgICAgICAvLyBOb3RoaW5nIHRvIGRvLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvLyBDaGVjayBpdHMgbm90IGVtcHR5LgorICAgIEZpbGVTdGF0dXMgW10gc3RhdHMgPSB0aGlzLmZzLmxpc3RTdGF0dXMocmVjb25zdHJ1Y3Rpb25Mb2cpOworICAgIGlmIChzdGF0cyA9PSBudWxsIHx8IHN0YXRzLmxlbmd0aCA9PSAwKSB7CisgICAgICBMT0cud2FybigiUGFzc2VkIHJlY29uc3RydWN0aW9uIGxvZyAiICsgcmVjb25zdHJ1Y3Rpb25Mb2cgKworICAgICAgICAiIGlzIHplcm8tbGVuZ3RoIik7CisgICAgICByZXR1cm47CisgICAgfQorICAgIC8vIFRPRE86IFRoaXMgY291bGQgZ3JvdyBsYXJnZSBhbmQgYmxvdyBoZWFwIG91dC4gIE5lZWQgdG8gZ2V0IGl0IGludG8KKyAgICAvLyBnZW5lcmFsIG1lbW9yeSB1c2FnZSBhY2NvdW50aW5nLgorICAgIGxvbmcgbWF4U2VxSWRJbkxvZyA9IC0xOworICAgIENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gcmVjb25zdHJ1Y3RlZENhY2hlID0KKyAgICAgIE1lbWNhY2hlLmNyZWF0ZVNldCh0aGlzLmNvbXBhcmF0b3IpOworICAgIFNlcXVlbmNlRmlsZS5SZWFkZXIgbG9nUmVhZGVyID0gbmV3IFNlcXVlbmNlRmlsZS5SZWFkZXIodGhpcy5mcywKKyAgICAgIHJlY29uc3RydWN0aW9uTG9nLCB0aGlzLmNvbmYpOworICAgIHRyeSB7CisgICAgICBITG9nS2V5IGtleSA9IG5ldyBITG9nS2V5KCk7CisgICAgICBLZXlWYWx1ZSB2YWwgPSBuZXcgS2V5VmFsdWUoKTsKKyAgICAgIGxvbmcgc2tpcHBlZEVkaXRzID0gMDsKKyAgICAgIGxvbmcgZWRpdHNDb3VudCA9IDA7CisgICAgICAvLyBIb3cgbWFueSBlZGl0cyB0byBhcHBseSBiZWZvcmUgd2Ugc2VuZCBhIHByb2dyZXNzIHJlcG9ydC4KKyAgICAgIGludCByZXBvcnRJbnRlcnZhbCA9CisgICAgICAgIHRoaXMuY29uZi5nZXRJbnQoImhiYXNlLmhzdG9yZS5yZXBvcnQuaW50ZXJ2YWwuZWRpdHMiLCAyMDAwKTsKKyAgICAgIHdoaWxlIChsb2dSZWFkZXIubmV4dChrZXksIHZhbCkpIHsKKyAgICAgICAgbWF4U2VxSWRJbkxvZyA9IE1hdGgubWF4KG1heFNlcUlkSW5Mb2csIGtleS5nZXRMb2dTZXFOdW0oKSk7CisgICAgICAgIGlmIChrZXkuZ2V0TG9nU2VxTnVtKCkgPD0gbWF4U2VxSUQpIHsKKyAgICAgICAgICBza2lwcGVkRWRpdHMrKzsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBDaGVjayB0aGlzIGVkaXQgaXMgZm9yIG1lLiBBbHNvLCBndWFyZCBhZ2FpbnN0IHdyaXRpbmcgdGhlIHNwZWNpYWwKKyAgICAgICAgLy8gTUVUQUNPTFVNTiBpbmZvIHN1Y2ggYXMgSEJBU0U6OkNBQ0hFRkxVU0ggZW50cmllcworICAgICAgICBpZiAoLyogQ29tbWVudGVkIG91dCBmb3Igbm93IC0tIFN0LkFjayB2YWwuaXNUcmFuc2FjdGlvbkVudHJ5KCkgfHwqLworICAgICAgICAgICAgdmFsLm1hdGNoaW5nQ29sdW1uTm9EZWxpbWl0ZXIoSExvZy5NRVRBQ09MVU1OLAorICAgICAgICAgICAgICBITG9nLk1FVEFDT0xVTU4ubGVuZ3RoIC0gMSkgfHwKKyAgICAgICAgICAhQnl0ZXMuZXF1YWxzKGtleS5nZXRSZWdpb25OYW1lKCksIHJlZ2lvbmluZm8uZ2V0UmVnaW9uTmFtZSgpKSB8fAorICAgICAgICAgICF2YWwubWF0Y2hpbmdGYW1pbHkoZmFtaWx5LmdldE5hbWUoKSkpIHsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICByZWNvbnN0cnVjdGVkQ2FjaGUuYWRkKHZhbCk7CisgICAgICAgIGVkaXRzQ291bnQrKzsKKyAgICAgICAgLy8gRXZlcnkgMmsgZWRpdHMsIHRlbGwgdGhlIHJlcG9ydGVyIHdlJ3JlIG1ha2luZyBwcm9ncmVzcy4KKyAgICAgICAgLy8gSGF2ZSBzZWVuIDYwayBlZGl0cyB0YWtpbmcgM21pbnV0ZXMgdG8gY29tcGxldGUuCisgICAgICAgIGlmIChyZXBvcnRlciAhPSBudWxsICYmIChlZGl0c0NvdW50ICUgcmVwb3J0SW50ZXJ2YWwpID09IDApIHsKKyAgICAgICAgICByZXBvcnRlci5wcm9ncmVzcygpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJBcHBsaWVkICIgKyBlZGl0c0NvdW50ICsgIiwgc2tpcHBlZCAiICsgc2tpcHBlZEVkaXRzICsKKyAgICAgICAgICAiIGJlY2F1c2Ugc2VxdWVuY2UgaWQgPD0gIiArIG1heFNlcUlEKTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgbG9nUmVhZGVyLmNsb3NlKCk7CisgICAgfQorICAgIAorICAgIGlmIChyZWNvbnN0cnVjdGVkQ2FjaGUuc2l6ZSgpID4gMCkgeworICAgICAgLy8gV2UgY3JlYXRlIGEgInZpcnR1YWwgZmx1c2giIGF0IG1heFNlcUlkSW5Mb2crMS4KKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoImZsdXNoaW5nIHJlY29uc3RydWN0aW9uQ2FjaGUiKTsKKyAgICAgIH0KKyAgICAgIGludGVybmFsRmx1c2hDYWNoZShyZWNvbnN0cnVjdGVkQ2FjaGUsIG1heFNlcUlkSW5Mb2cgKyAxKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBDcmVhdGVzIGEgc2VyaWVzIG9mIFN0b3JlRmlsZSBsb2FkZWQgZnJvbSB0aGUgZ2l2ZW4gZGlyZWN0b3J5LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIE1hcDxMb25nLCBTdG9yZUZpbGU+IGxvYWRTdG9yZUZpbGVzKCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBNYXA8TG9uZywgU3RvcmVGaWxlPiByZXN1bHRzID0gbmV3IEhhc2hNYXA8TG9uZywgU3RvcmVGaWxlPigpOworICAgIEZpbGVTdGF0dXMgZmlsZXNbXSA9IHRoaXMuZnMubGlzdFN0YXR1cyh0aGlzLmhvbWVkaXIpOworICAgIGZvciAoaW50IGkgPSAwOyBmaWxlcyAhPSBudWxsICYmIGkgPCBmaWxlcy5sZW5ndGg7IGkrKykgeworICAgICAgLy8gU2tpcCBkaXJlY3Rvcmllcy4KKyAgICAgIGlmIChmaWxlc1tpXS5pc0RpcigpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgUGF0aCBwID0gZmlsZXNbaV0uZ2V0UGF0aCgpOworICAgICAgLy8gQ2hlY2sgZm9yIGVtcHR5IGZpbGUuICBTaG91bGQgbmV2ZXIgYmUgdGhlIGNhc2UgYnV0IGNhbiBoYXBwZW4KKyAgICAgIC8vIGFmdGVyIGRhdGEgbG9zcyBpbiBoZGZzIGZvciB3aGF0ZXZlciByZWFzb24gKHVwZ3JhZGUsIGV0Yy4pOiBIQkFTRS02NDYKKyAgICAgIGlmICh0aGlzLmZzLmdldEZpbGVTdGF0dXMocCkuZ2V0TGVuKCkgPD0gMCkgeworICAgICAgICBMT0cud2FybigiU2tpcHBpbmcgIiArIHAgKyAiIGJlY2F1c2UgaXRzIGVtcHR5LiBIQkFTRS02NDYgREFUQSBMT1NTPyIpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIFN0b3JlRmlsZSBjdXJmaWxlID0gbmV3IFN0b3JlRmlsZShmcywgcCk7CisgICAgICBsb25nIHN0b3JlU2VxSWQgPSBjdXJmaWxlLmdldE1heFNlcXVlbmNlSWQoKTsKKyAgICAgIGlmIChzdG9yZVNlcUlkID4gdGhpcy5tYXhTZXFJZCkgeworICAgICAgICB0aGlzLm1heFNlcUlkID0gc3RvcmVTZXFJZDsKKyAgICAgIH0KKyAgICAgIGxvbmcgbGVuZ3RoID0gY3VyZmlsZS5nZXRSZWFkZXIoKS5sZW5ndGgoKTsKKyAgICAgIHRoaXMuc3RvcmVTaXplICs9IGxlbmd0aDsKKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoImxvYWRlZCAiICsgRlNVdGlscy5nZXRQYXRoKHApICsgIiwgaXNSZWZlcmVuY2U9IiArCisgICAgICAgICAgY3VyZmlsZS5pc1JlZmVyZW5jZSgpICsgIiwgc2VxdWVuY2UgaWQ9IiArIHN0b3JlU2VxSWQgKworICAgICAgICAgICIsIGxlbmd0aD0iICsgbGVuZ3RoICsgIiwgbWFqb3JDb21wYWN0aW9uPSIgKworICAgICAgICAgIGN1cmZpbGUuaXNNYWpvckNvbXBhY3Rpb24oKSk7CisgICAgICB9CisgICAgICByZXN1bHRzLnB1dChMb25nLnZhbHVlT2Yoc3RvcmVTZXFJZCksIGN1cmZpbGUpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0czsKKyAgfQorCisgIC8qKgorICAgKiBBZGRzIGEgdmFsdWUgdG8gdGhlIG1lbWNhY2hlCisgICAqIAorICAgKiBAcGFyYW0ga3YKKyAgICogQHJldHVybiBtZW1jYWNoZSBzaXplIGRlbHRhCisgICAqLworICBwcm90ZWN0ZWQgbG9uZyBhZGQoZmluYWwgS2V5VmFsdWUga3YpIHsKKyAgICBsb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICByZXR1cm4gdGhpcy5tZW1jYWNoZS5hZGQoa3YpOworICAgIH0gZmluYWxseSB7CisgICAgICBsb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gQWxsIHN0b3JlIGZpbGVzLgorICAgKi8KKyAgTmF2aWdhYmxlTWFwPExvbmcsIFN0b3JlRmlsZT4gZ2V0U3RvcmVmaWxlcygpIHsKKyAgICByZXR1cm4gdGhpcy5zdG9yZWZpbGVzOworICB9CisKKyAgLyoqCisgICAqIENsb3NlIGFsbCB0aGUgcmVhZGVycworICAgKiAKKyAgICogV2UgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCBzdWJzZXF1ZW50IHJlcXVlc3RzIGJlY2F1c2UgdGhlIEhSZWdpb24gaG9sZHMKKyAgICogYSB3cml0ZSBsb2NrIHRoYXQgd2lsbCBwcmV2ZW50IGFueSBtb3JlIHJlYWRzIG9yIHdyaXRlcy4KKyAgICogCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIExpc3Q8U3RvcmVGaWxlPiBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgQXJyYXlMaXN0PFN0b3JlRmlsZT4gcmVzdWx0ID0KKyAgICAgICAgbmV3IEFycmF5TGlzdDxTdG9yZUZpbGU+KHN0b3JlZmlsZXMudmFsdWVzKCkpOworICAgICAgLy8gQ2xlYXIgc28gbWV0cmljcyBkb2Vzbid0IGZpbmQgdGhlbS4KKyAgICAgIHRoaXMuc3RvcmVmaWxlcy5jbGVhcigpOworICAgICAgZm9yIChTdG9yZUZpbGUgZjogcmVzdWx0KSB7CisgICAgICAgIGYuY2xvc2UoKTsKKyAgICAgIH0KKyAgICAgIExPRy5kZWJ1ZygiY2xvc2VkICIgKyB0aGlzLnN0b3JlTmFtZVN0cik7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFNuYXBzaG90IHRoaXMgc3RvcmVzIG1lbWNhY2hlLiAgQ2FsbCBiZWZvcmUgcnVubmluZworICAgKiB7QGxpbmsgI2ZsdXNoQ2FjaGUobG9uZyl9IHNvIGl0IGhhcyBzb21lIHdvcmsgdG8gZG8uCisgICAqLworICB2b2lkIHNuYXBzaG90KCkgeworICAgIHRoaXMubWVtY2FjaGUuc25hcHNob3QoKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBvdXQgY3VycmVudCBzbmFwc2hvdC4gIFByZXN1bWVzIHtAbGluayAjc25hcHNob3QoKX0gaGFzIGJlZW4gY2FsbGVkCisgICAqIHByZXZpb3VzbHkuCisgICAqIEBwYXJhbSBsb2dDYWNoZUZsdXNoSWQgZmx1c2ggc2VxdWVuY2UgbnVtYmVyCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBhIGNvbXBhY3Rpb24gaXMgbmVlZGVkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIGJvb2xlYW4gZmx1c2hDYWNoZShmaW5hbCBsb25nIGxvZ0NhY2hlRmx1c2hJZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBHZXQgdGhlIHNuYXBzaG90IHRvIGZsdXNoLiAgUHJlc3VtZXMgdGhhdCBhIGNhbGwgdG8KKyAgICAvLyB0aGlzLm1lbWNhY2hlLnNuYXBzaG90KCkgaGFzIGhhcHBlbmVkIGVhcmxpZXIgdXAgaW4gdGhlIGNoYWluLgorICAgIENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gY2FjaGUgPSB0aGlzLm1lbWNhY2hlLmdldFNuYXBzaG90KCk7CisgICAgLy8gSWYgYW4gZXhjZXB0aW9uIGhhcHBlbnMgZmx1c2hpbmcsIHdlIGxldCBpdCBvdXQgd2l0aG91dCBjbGVhcmluZworICAgIC8vIHRoZSBtZW1jYWNoZSBzbmFwc2hvdC4gIFRoZSBvbGQgc25hcHNob3Qgd2lsbCBiZSByZXR1cm5lZCB3aGVuIHdlIHNheQorICAgIC8vICdzbmFwc2hvdCcsIHRoZSBuZXh0IHRpbWUgZmx1c2ggY29tZXMgYXJvdW5kLgorICAgIFN0b3JlRmlsZSBzZiA9IGludGVybmFsRmx1c2hDYWNoZShjYWNoZSwgbG9nQ2FjaGVGbHVzaElkKTsKKyAgICBpZiAoc2YgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAvLyBBZGQgbmV3IGZpbGUgdG8gc3RvcmUgZmlsZXMuICBDbGVhciBzbmFwc2hvdCB0b28gd2hpbGUgd2UgaGF2ZSB0aGUKKyAgICAvLyBTdG9yZSB3cml0ZSBsb2NrLgorICAgIGludCBzaXplID0gdXBkYXRlU3RvcmVmaWxlcyhsb2dDYWNoZUZsdXNoSWQsIHNmLCBjYWNoZSk7CisgICAgcmV0dXJuIHNpemUgPj0gdGhpcy5jb21wYWN0aW9uVGhyZXNob2xkOworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIGNhY2hlCisgICAqIEBwYXJhbSBsb2dDYWNoZUZsdXNoSWQKKyAgICogQHJldHVybiBTdG9yZUZpbGUgY3JlYXRlZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBTdG9yZUZpbGUgaW50ZXJuYWxGbHVzaENhY2hlKGZpbmFsIENvbmN1cnJlbnRTa2lwTGlzdFNldDxLZXlWYWx1ZT4gY2FjaGUsCisgICAgZmluYWwgbG9uZyBsb2dDYWNoZUZsdXNoSWQpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSEZpbGUuV3JpdGVyIHdyaXRlciA9IG51bGw7CisgICAgbG9uZyBmbHVzaGVkID0gMDsKKyAgICAvLyBEb24ndCBmbHVzaCBpZiB0aGVyZSBhcmUgbm8gZW50cmllcy4KKyAgICBpZiAoY2FjaGUuc2l6ZSgpID09IDApIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIC8vIFRPRE86ICBXZSBjYW4gZmFpbCBpbiB0aGUgYmVsb3cgYmxvY2sgYmVmb3JlIHdlIGNvbXBsZXRlIGFkZGluZyB0aGlzCisgICAgLy8gZmx1c2ggdG8gbGlzdCBvZiBzdG9yZSBmaWxlcy4gIEFkZCBjbGVhbnVwIG9mIGFueXRoaW5nIHB1dCBvbiBmaWxlc3lzdGVtCisgICAgLy8gaWYgd2UgZmFpbC4KKyAgICBzeW5jaHJvbml6ZWQgKGZsdXNoTG9jaykgeworICAgICAgLy8gQS4gV3JpdGUgdGhlIG1hcCBvdXQgdG8gdGhlIGRpc2sKKyAgICAgIHdyaXRlciA9IGdldFdyaXRlcigpOworICAgICAgaW50IGVudHJpZXMgPSAwOworICAgICAgdHJ5IHsKKyAgICAgICAgZm9yIChLZXlWYWx1ZSBrdjogY2FjaGUpIHsKKyAgICAgICAgICBpZiAoIWlzRXhwaXJlZChrdiwgdHRsLCBub3cpKSB7CisgICAgICAgICAgICB3cml0ZXIuYXBwZW5kKGt2KTsKKyAgICAgICAgICAgIGVudHJpZXMrKzsKKyAgICAgICAgICAgIGZsdXNoZWQgKz0gdGhpcy5tZW1jYWNoZS5oZWFwU2l6ZShrdiwgdHJ1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIEIuIFdyaXRlIG91dCB0aGUgbG9nIHNlcXVlbmNlIG51bWJlciB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoaXMgb3V0cHV0CisgICAgICAgIC8vIE1hcEZpbGUuICBUaGUgTWFwRmlsZSBpcyBjdXJyZW50IHVwIHRvIGFuZCBpbmNsdWRpbmcgbG9nQ2FjaGVGbHVzaElkLgorICAgICAgICBTdG9yZUZpbGUuYXBwZW5kTWV0YWRhdGEod3JpdGVyLCBsb2dDYWNoZUZsdXNoSWQpOworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgICB9CisgICAgfQorICAgIFN0b3JlRmlsZSBzZiA9IG5ldyBTdG9yZUZpbGUodGhpcy5mcywgd3JpdGVyLmdldFBhdGgoKSk7CisgICAgdGhpcy5zdG9yZVNpemUgKz0gc2YuZ2V0UmVhZGVyKCkubGVuZ3RoKCk7CisgICAgaWYoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiQWRkZWQgIiArIHNmICsgIiwgZW50cmllcz0iICsgc2YuZ2V0UmVhZGVyKCkuZ2V0RW50cmllcygpICsKKyAgICAgICAgIiwgc2VxdWVuY2VpZD0iICsgbG9nQ2FjaGVGbHVzaElkICsKKyAgICAgICAgIiwgbWVtc2l6ZT0iICsgU3RyaW5nVXRpbHMuaHVtYW5SZWFkYWJsZUludChmbHVzaGVkKSArCisgICAgICAgICIsIGZpbGVzaXplPSIgKyBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHNmLmdldFJlYWRlcigpLmxlbmd0aCgpKSArCisgICAgICAgICIgdG8gIiArIHRoaXMucmVnaW9uaW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgfQorICAgIHJldHVybiBzZjsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFdyaXRlciBmb3IgdGhpcyBzdG9yZS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgSEZpbGUuV3JpdGVyIGdldFdyaXRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFdyaXRlcih0aGlzLmhvbWVkaXIpOworICB9CisKKyAgLyoKKyAgICogQHJldHVybiBXcml0ZXIgZm9yIHRoaXMgc3RvcmUuCisgICAqIEBwYXJhbSBiYXNlZGlyIERpcmVjdG9yeSB0byBwdXQgd3JpdGVyIGluLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIEhGaWxlLldyaXRlciBnZXRXcml0ZXIoZmluYWwgUGF0aCBiYXNlZGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBTdG9yZUZpbGUuZ2V0V3JpdGVyKHRoaXMuZnMsIGJhc2VkaXIsIHRoaXMuYmxvY2tzaXplLAorICAgICAgICB0aGlzLmNvbXByZXNzaW9uLCB0aGlzLmNvbXBhcmF0b3IuZ2V0UmF3Q29tcGFyYXRvcigpLCB0aGlzLmJsb29tZmlsdGVyKTsKKyAgfQorCisgIC8qCisgICAqIENoYW5nZSBzdG9yZWZpbGVzIGFkZGluZyBpbnRvIHBsYWNlIHRoZSBSZWFkZXIgcHJvZHVjZWQgYnkgdGhpcyBuZXcgZmx1c2guCisgICAqIEBwYXJhbSBsb2dDYWNoZUZsdXNoSWQKKyAgICogQHBhcmFtIHNmCisgICAqIEBwYXJhbSBjYWNoZSBUaGF0IHdhcyB1c2VkIHRvIG1ha2UgdGhlIHBhc3NlZCBmaWxlIDxjb2RlPnA8L2NvZGU+LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEByZXR1cm4gQ291bnQgb2Ygc3RvcmUgZmlsZXMuCisgICAqLworICBwcml2YXRlIGludCB1cGRhdGVTdG9yZWZpbGVzKGZpbmFsIGxvbmcgbG9nQ2FjaGVGbHVzaElkLAorICAgIGZpbmFsIFN0b3JlRmlsZSBzZiwgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBjYWNoZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgY291bnQgPSAwOworICAgIHRoaXMubG9jay53cml0ZUxvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMuc3RvcmVmaWxlcy5wdXQoTG9uZy52YWx1ZU9mKGxvZ0NhY2hlRmx1c2hJZCksIHNmKTsKKyAgICAgIGNvdW50ID0gdGhpcy5zdG9yZWZpbGVzLnNpemUoKTsKKyAgICAgIC8vIFRlbGwgbGlzdGVuZXJzIG9mIHRoZSBjaGFuZ2UgaW4gcmVhZGVycy4KKyAgICAgIG5vdGlmeUNoYW5nZWRSZWFkZXJzT2JzZXJ2ZXJzKCk7CisgICAgICB0aGlzLm1lbWNhY2hlLmNsZWFyU25hcHNob3QoY2FjaGUpOworICAgICAgcmV0dXJuIGNvdW50OworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogTm90aWZ5IGFsbCBvYnNlcnZlcnMgdGhhdCBzZXQgb2YgUmVhZGVycyBoYXMgY2hhbmdlZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIG5vdGlmeUNoYW5nZWRSZWFkZXJzT2JzZXJ2ZXJzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKENoYW5nZWRSZWFkZXJzT2JzZXJ2ZXIgbzogdGhpcy5jaGFuZ2VkUmVhZGVyT2JzZXJ2ZXJzKSB7CisgICAgICBvLnVwZGF0ZVJlYWRlcnMoKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gbyBPYnNlcnZlciB3aG8gd2FudHMgdG8ga25vdyBhYm91dCBjaGFuZ2VzIGluIHNldCBvZiBSZWFkZXJzCisgICAqLworICB2b2lkIGFkZENoYW5nZWRSZWFkZXJPYnNlcnZlcihDaGFuZ2VkUmVhZGVyc09ic2VydmVyIG8pIHsKKyAgICB0aGlzLmNoYW5nZWRSZWFkZXJPYnNlcnZlcnMuYWRkKG8pOworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIG8gT2JzZXJ2ZXIgbm8gbG9uZ2VyIGludGVyZXN0ZWQgaW4gY2hhbmdlcyBpbiBzZXQgb2YgUmVhZGVycy4KKyAgICovCisgIHZvaWQgZGVsZXRlQ2hhbmdlZFJlYWRlck9ic2VydmVyKENoYW5nZWRSZWFkZXJzT2JzZXJ2ZXIgbykgeworICAgIGlmICghdGhpcy5jaGFuZ2VkUmVhZGVyT2JzZXJ2ZXJzLnJlbW92ZShvKSkgeworICAgICAgTE9HLndhcm4oIk5vdCBpbiBzZXQiICsgbyk7CisgICAgfQorICB9CisKKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIENvbXBhY3Rpb24KKyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKyAgLyoqCisgICAqIENvbXBhY3QgdGhlIFN0b3JlRmlsZXMuICBUaGlzIG1ldGhvZCBtYXkgdGFrZSBzb21lIHRpbWUsIHNvIHRoZSBjYWxsaW5nIAorICAgKiB0aHJlYWQgbXVzdCBiZSBhYmxlIHRvIGJsb2NrIGZvciBsb25nIHBlcmlvZHMuCisgICAqIAorICAgKiA8cD5EdXJpbmcgdGhpcyB0aW1lLCB0aGUgU3RvcmUgY2FuIHdvcmsgYXMgdXN1YWwsIGdldHRpbmcgdmFsdWVzIGZyb20KKyAgICogTWFwRmlsZXMgYW5kIHdyaXRpbmcgbmV3IE1hcEZpbGVzIGZyb20gdGhlIE1lbWNhY2hlLgorICAgKiAKKyAgICogRXhpc3RpbmcgTWFwRmlsZXMgYXJlIG5vdCBkZXN0cm95ZWQgdW50aWwgdGhlIG5ldyBjb21wYWN0ZWQgVHJlZU1hcCBpcyAKKyAgICogY29tcGxldGVseSB3cml0dGVuLW91dCB0byBkaXNrLgorICAgKgorICAgKiBUaGUgY29tcGFjdExvY2sgcHJldmVudHMgbXVsdGlwbGUgc2ltdWx0YW5lb3VzIGNvbXBhY3Rpb25zLgorICAgKiBUaGUgc3RydWN0dXJlTG9jayBwcmV2ZW50cyB1cyBmcm9tIGludGVyZmVyaW5nIHdpdGggb3RoZXIgd3JpdGUgb3BlcmF0aW9ucy4KKyAgICogCisgICAqIFdlIGRvbid0IHdhbnQgdG8gaG9sZCB0aGUgc3RydWN0dXJlTG9jayBmb3IgdGhlIHdob2xlIHRpbWUsIGFzIGEgY29tcGFjdCgpIAorICAgKiBjYW4gYmUgbGVuZ3RoeSBhbmQgd2Ugd2FudCB0byBhbGxvdyBjYWNoZS1mbHVzaGVzIGR1cmluZyB0aGlzIHBlcmlvZC4KKyAgICogCisgICAqIEBwYXJhbSBtYyBUcnVlIHRvIGZvcmNlIGEgbWFqb3IgY29tcGFjdGlvbiByZWdhcmRsZXNzIG9mCisgICAqIHRocmVzaG9sZHMKKyAgICogQHJldHVybiByb3cgdG8gc3BsaXQgYXJvdW5kIGlmIGEgc3BsaXQgaXMgbmVlZGVkLCBudWxsIG90aGVyd2lzZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBTdG9yZVNpemUgY29tcGFjdChmaW5hbCBib29sZWFuIG1jKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJvb2xlYW4gZm9yY2VTcGxpdCA9IHRoaXMucmVnaW9uaW5mby5zaG91bGRTcGxpdChmYWxzZSk7CisgICAgYm9vbGVhbiBtYWpvcmNvbXBhY3Rpb24gPSBtYzsKKyAgICBzeW5jaHJvbml6ZWQgKGNvbXBhY3RMb2NrKSB7CisgICAgICBsb25nIG1heElkID0gLTE7CisgICAgICAvLyBmaWxlc1RvQ29tcGFjdCBhcmUgc29ydGVkIG9sZGVzdCB0byBuZXdlc3QuCisgICAgICBMaXN0PFN0b3JlRmlsZT4gZmlsZXNUb0NvbXBhY3QgPSBudWxsOworICAgICAgZmlsZXNUb0NvbXBhY3QgPSBuZXcgQXJyYXlMaXN0PFN0b3JlRmlsZT4odGhpcy5zdG9yZWZpbGVzLnZhbHVlcygpKTsKKyAgICAgIGlmIChmaWxlc1RvQ29tcGFjdC5zaXplKCkgPD0gMCkgeworICAgICAgICBMT0cuZGVidWcodGhpcy5zdG9yZU5hbWVTdHIgKyAiOiBubyBzdG9yZSBmaWxlcyB0byBjb21wYWN0Iik7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgLy8gVGhlIG1heC1zZXF1ZW5jZUlEIGluIGFueSBvZiB0aGUgdG8tYmUtY29tcGFjdGVkIFRyZWVNYXBzIGlzIHRoZSAKKyAgICAgIC8vIGxhc3Qga2V5IG9mIHN0b3JlZmlsZXMuCisgICAgICBtYXhJZCA9IHRoaXMuc3RvcmVmaWxlcy5sYXN0S2V5KCkubG9uZ1ZhbHVlKCk7CisgICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgbmVlZCB0byBkbyBhIG1ham9yIGNvbXBhY3Rpb24gb24gdGhpcyByZWdpb24uCisgICAgICAvLyBJZiBzbywgY2hhbmdlIGRvTWFqb3JDb21wYWN0aW9uIHRvIHRydWUgdG8gc2tpcCB0aGUgaW5jcmVtZW50YWwKKyAgICAgIC8vIGNvbXBhY3RpbmcgYmVsb3cuIE9ubHkgY2hlY2sgaWYgZG9NYWpvckNvbXBhY3Rpb24gaXMgbm90IHRydWUuCisgICAgICBpZiAoIW1ham9yY29tcGFjdGlvbikgeworICAgICAgICBtYWpvcmNvbXBhY3Rpb24gPSBpc01ham9yQ29tcGFjdGlvbihmaWxlc1RvQ29tcGFjdCk7CisgICAgICB9CisgICAgICBib29sZWFuIHJlZmVyZW5jZXMgPSBoYXNSZWZlcmVuY2VzKGZpbGVzVG9Db21wYWN0KTsKKyAgICAgIGlmICghbWFqb3Jjb21wYWN0aW9uICYmICFyZWZlcmVuY2VzICYmIAorICAgICAgICAgIChmb3JjZVNwbGl0IHx8IChmaWxlc1RvQ29tcGFjdC5zaXplKCkgPCBjb21wYWN0aW9uVGhyZXNob2xkKSkpIHsKKyAgICAgICAgcmV0dXJuIGNoZWNrU3BsaXQoZm9yY2VTcGxpdCk7CisgICAgICB9CisgICAgICBpZiAoIWZzLmV4aXN0cyh0aGlzLmNvbXBhY3Rpb25EaXIpICYmICFmcy5ta2RpcnModGhpcy5jb21wYWN0aW9uRGlyKSkgeworICAgICAgICBMT0cud2FybigiTWtkaXIgb24gIiArIHRoaXMuY29tcGFjdGlvbkRpci50b1N0cmluZygpICsgIiBmYWlsZWQiKTsKKyAgICAgICAgcmV0dXJuIGNoZWNrU3BsaXQoZm9yY2VTcGxpdCk7CisgICAgICB9CisKKyAgICAgIC8vIEhCQVNFLTc0NSwgcHJlcGFyaW5nIGFsbCBzdG9yZSBmaWxlIHNpemVzIGZvciBpbmNyZW1lbnRhbCBjb21wYWN0aW5nCisgICAgICAvLyBzZWxlY3Rpb24uCisgICAgICBpbnQgY291bnRPZkZpbGVzID0gZmlsZXNUb0NvbXBhY3Quc2l6ZSgpOworICAgICAgbG9uZyB0b3RhbFNpemUgPSAwOworICAgICAgbG9uZ1tdIGZpbGVTaXplcyA9IG5ldyBsb25nW2NvdW50T2ZGaWxlc107CisgICAgICBsb25nIHNraXBwZWQgPSAwOworICAgICAgaW50IHBvaW50ID0gMDsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnRPZkZpbGVzOyBpKyspIHsKKyAgICAgICAgU3RvcmVGaWxlIGZpbGUgPSBmaWxlc1RvQ29tcGFjdC5nZXQoaSk7CisgICAgICAgIFBhdGggcGF0aCA9IGZpbGUuZ2V0UGF0aCgpOworICAgICAgICBpZiAocGF0aCA9PSBudWxsKSB7CisgICAgICAgICAgTE9HLndhcm4oIlBhdGggaXMgbnVsbCBmb3IgIiArIGZpbGUpOworICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIGxvbmcgbGVuID0gZmlsZS5nZXRSZWFkZXIoKS5sZW5ndGgoKTsKKyAgICAgICAgZmlsZVNpemVzW2ldID0gbGVuOworICAgICAgICB0b3RhbFNpemUgKz0gbGVuOworICAgICAgfQorICAgICAgaWYgKCFtYWpvcmNvbXBhY3Rpb24gJiYgIXJlZmVyZW5jZXMpIHsKKyAgICAgICAgLy8gSGVyZSB3ZSBzZWxlY3QgZmlsZXMgZm9yIGluY3JlbWVudGFsIGNvbXBhY3Rpb24uICAKKyAgICAgICAgLy8gVGhlIHJ1bGUgaXM6IGlmIHRoZSBsYXJnZXN0KG9sZGVzdCkgb25lIGlzIG1vcmUgdGhhbiB0d2ljZSB0aGUgCisgICAgICAgIC8vIHNpemUgb2YgdGhlIHNlY29uZCwgc2tpcCB0aGUgbGFyZ2VzdCwgYW5kIGNvbnRpbnVlIHRvIG5leHQuLi4sCisgICAgICAgIC8vIHVudGlsIHdlIG1lZXQgdGhlIGNvbXBhY3Rpb25UaHJlc2hvbGQgbGltaXQuCisgICAgICAgIGZvciAocG9pbnQgPSAwOyBwb2ludCA8IGNvdW50T2ZGaWxlcyAtIDE7IHBvaW50KyspIHsKKyAgICAgICAgICBpZiAoKGZpbGVTaXplc1twb2ludF0gPCBmaWxlU2l6ZXNbcG9pbnQgKyAxXSAqIDIpICYmIAorICAgICAgICAgICAgICAgKGNvdW50T2ZGaWxlcyAtIHBvaW50KSA8PSBtYXhGaWxlc1RvQ29tcGFjdCkgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIHNraXBwZWQgKz0gZmlsZVNpemVzW3BvaW50XTsKKyAgICAgICAgfQorICAgICAgICBmaWxlc1RvQ29tcGFjdCA9IG5ldyBBcnJheUxpc3Q8U3RvcmVGaWxlPihmaWxlc1RvQ29tcGFjdC5zdWJMaXN0KHBvaW50LAorICAgICAgICAgIGNvdW50T2ZGaWxlcykpOworICAgICAgICBpZiAoZmlsZXNUb0NvbXBhY3Quc2l6ZSgpIDw9IDEpIHsKKyAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgIExPRy5kZWJ1ZygiU2tpcHBlZCBjb21wYWN0aW9uIG9mIDEgZmlsZTsgY29tcGFjdGlvbiBzaXplIG9mICIgKworICAgICAgICAgICAgICB0aGlzLnN0b3JlTmFtZVN0ciArICI6ICIgKworICAgICAgICAgICAgICBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHRvdGFsU2l6ZSkgKyAiOyBTa2lwcGVkICIgKyBwb2ludCArCisgICAgICAgICAgICAgICIgZmlsZXMsIHNpemU6ICIgKyBza2lwcGVkKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGNoZWNrU3BsaXQoZm9yY2VTcGxpdCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgTE9HLmRlYnVnKCJDb21wYWN0aW9uIHNpemUgb2YgIiArIHRoaXMuc3RvcmVOYW1lU3RyICsgIjogIiArCisgICAgICAgICAgICBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHRvdGFsU2l6ZSkgKyAiOyBTa2lwcGVkICIgKyBwb2ludCArCisgICAgICAgICAgICAiIGZpbGUocyksIHNpemU6ICIgKyBza2lwcGVkKTsKKyAgICAgICAgfQorICAgICAgfQorIAorICAgICAgLy8gU3RlcCB0aHJvdWdoIHRoZW0sIHdyaXRpbmcgdG8gdGhlIGJyYW5kLW5ldyBmaWxlCisgICAgICBIRmlsZS5Xcml0ZXIgd3JpdGVyID0gZ2V0V3JpdGVyKHRoaXMuY29tcGFjdGlvbkRpcik7CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJTdGFydGVkIGNvbXBhY3Rpb24gb2YgIiArIGZpbGVzVG9Db21wYWN0LnNpemUoKSArICIgZmlsZShzKSIgKworICAgICAgICAgIChyZWZlcmVuY2VzPyAiLCBoYXNSZWZlcmVuY2VzPXRydWUsIjogIiAiKSArICIgaW50byAiICsKKyAgICAgICAgICBGU1V0aWxzLmdldFBhdGgod3JpdGVyLmdldFBhdGgoKSkpOworICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgY29tcGFjdCh3cml0ZXIsIGZpbGVzVG9Db21wYWN0LCBtYWpvcmNvbXBhY3Rpb24pOworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgLy8gTm93LCB3cml0ZSBvdXQgYW4gSFNUT1JFX0xPR0lORk9GSUxFIGZvciB0aGUgYnJhbmQtbmV3IFRyZWVNYXAuCisgICAgICAgIFN0b3JlRmlsZS5hcHBlbmRNZXRhZGF0YSh3cml0ZXIsIG1heElkLCBtYWpvcmNvbXBhY3Rpb24pOworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICAgIH0KKworICAgICAgLy8gTW92ZSB0aGUgY29tcGFjdGlvbiBpbnRvIHBsYWNlLgorICAgICAgY29tcGxldGVDb21wYWN0aW9uKGZpbGVzVG9Db21wYWN0LCB3cml0ZXIpOworICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiQ29tcGxldGVkIiArIChtYWpvcmNvbXBhY3Rpb24/ICIgbWFqb3IgIjogIiAiKSArCisgICAgICAgICAgImNvbXBhY3Rpb24gb2YgIiArIHRoaXMuc3RvcmVOYW1lU3RyICsKKyAgICAgICAgICAiOyBzdG9yZSBzaXplIGlzICIgKyBTdHJpbmdVdGlscy5odW1hblJlYWRhYmxlSW50KHN0b3JlU2l6ZSkpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY2hlY2tTcGxpdChmb3JjZVNwbGl0KTsKKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSBmaWxlcworICAgKiBAcmV0dXJuIFRydWUgaWYgYW55IG9mIHRoZSBmaWxlcyBpbiA8Y29kZT5maWxlczwvY29kZT4gYXJlIFJlZmVyZW5jZXMuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gaGFzUmVmZXJlbmNlcyhDb2xsZWN0aW9uPFN0b3JlRmlsZT4gZmlsZXMpIHsKKyAgICBpZiAoZmlsZXMgIT0gbnVsbCAmJiBmaWxlcy5zaXplKCkgPiAwKSB7CisgICAgICBmb3IgKFN0b3JlRmlsZSBoc2Y6IGZpbGVzKSB7CisgICAgICAgIGlmIChoc2YuaXNSZWZlcmVuY2UoKSkgeworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qCisgICAqIEdldHMgbG93ZXN0IHRpbWVzdGFtcCBmcm9tIGZpbGVzIGluIGEgZGlyCisgICAqIAorICAgKiBAcGFyYW0gZnMKKyAgICogQHBhcmFtIGRpcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHN0YXRpYyBsb25nIGdldExvd2VzdFRpbWVzdGFtcChGaWxlU3lzdGVtIGZzLCBQYXRoIGRpcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlU3RhdHVzW10gc3RhdHMgPSBmcy5saXN0U3RhdHVzKGRpcik7CisgICAgaWYgKHN0YXRzID09IG51bGwgfHwgc3RhdHMubGVuZ3RoID09IDApIHsKKyAgICAgIHJldHVybiAwbDsKKyAgICB9CisgICAgbG9uZyBsb3dUaW1lc3RhbXAgPSBMb25nLk1BWF9WQUxVRTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBsb25nIHRpbWVzdGFtcCA9IHN0YXRzW2ldLmdldE1vZGlmaWNhdGlvblRpbWUoKTsKKyAgICAgIGlmICh0aW1lc3RhbXAgPCBsb3dUaW1lc3RhbXApeworICAgICAgICBsb3dUaW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBsb3dUaW1lc3RhbXA7CisgIH0KKworICAvKgorICAgKiBAcmV0dXJuIFRydWUgaWYgd2Ugc2hvdWxkIHJ1biBhIG1ham9yIGNvbXBhY3Rpb24uCisgICAqLworICBib29sZWFuIGlzTWFqb3JDb21wYWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PFN0b3JlRmlsZT4gZmlsZXNUb0NvbXBhY3QgPSBudWxsOworICAgIC8vIGZpbGVzVG9Db21wYWN0IGFyZSBzb3J0ZWQgb2xkZXN0IHRvIG5ld2VzdC4KKyAgICBmaWxlc1RvQ29tcGFjdCA9IG5ldyBBcnJheUxpc3Q8U3RvcmVGaWxlPih0aGlzLnN0b3JlZmlsZXMudmFsdWVzKCkpOworICAgIHJldHVybiBpc01ham9yQ29tcGFjdGlvbihmaWxlc1RvQ29tcGFjdCk7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gZmlsZXNUb0NvbXBhY3QgRmlsZXMgdG8gY29tcGFjdC4gQ2FuIGJlIG51bGwuCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB3ZSBzaG91bGQgcnVuIGEgbWFqb3IgY29tcGFjdGlvbi4KKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiBpc01ham9yQ29tcGFjdGlvbihmaW5hbCBMaXN0PFN0b3JlRmlsZT4gZmlsZXNUb0NvbXBhY3QpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICBpZiAoZmlsZXNUb0NvbXBhY3QgPT0gbnVsbCB8fCBmaWxlc1RvQ29tcGFjdC5zaXplKCkgPD0gMCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgbG9uZyBsb3dUaW1lc3RhbXAgPSBnZXRMb3dlc3RUaW1lc3RhbXAoZnMsCisgICAgICBmaWxlc1RvQ29tcGFjdC5nZXQoMCkuZ2V0UGF0aCgpLmdldFBhcmVudCgpKTsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGlmIChsb3dUaW1lc3RhbXAgPiAwbCAmJiBsb3dUaW1lc3RhbXAgPCAobm93IC0gdGhpcy5tYWpvckNvbXBhY3Rpb25UaW1lKSkgeworICAgICAgLy8gTWFqb3IgY29tcGFjdGlvbiB0aW1lIGhhcyBlbGFwc2VkLgorICAgICAgbG9uZyBlbGFwc2VkVGltZSA9IG5vdyAtIGxvd1RpbWVzdGFtcDsKKyAgICAgIGlmIChmaWxlc1RvQ29tcGFjdC5zaXplKCkgPT0gMSAmJgorICAgICAgICAgIGZpbGVzVG9Db21wYWN0LmdldCgwKS5pc01ham9yQ29tcGFjdGlvbigpICYmCisgICAgICAgICAgKHRoaXMudHRsID09IEhDb25zdGFudHMuRk9SRVZFUiB8fCBlbGFwc2VkVGltZSA8IHRoaXMudHRsKSkgeworICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIlNraXBwaW5nIG1ham9yIGNvbXBhY3Rpb24gb2YgIiArIHRoaXMuc3RvcmVOYW1lU3RyICsKKyAgICAgICAgICAgICIgYmVjYXVzZSBvbmUgKG1ham9yKSBjb21wYWN0ZWQgZmlsZSBvbmx5IGFuZCBlbGFwc2VkVGltZSAiICsKKyAgICAgICAgICAgIGVsYXBzZWRUaW1lICsgIm1zIGlzIDwgdHRsPSIgKyB0aGlzLnR0bCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygiTWFqb3IgY29tcGFjdGlvbiB0cmlnZ2VyZWQgb24gc3RvcmUgIiArIHRoaXMuc3RvcmVOYW1lU3RyICsKKyAgICAgICAgICAgICI7IHRpbWUgc2luY2UgbGFzdCBtYWpvciBjb21wYWN0aW9uICIgKyAobm93IC0gbG93VGltZXN0YW1wKSArICJtcyIpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gciBTdG9yZUZpbGUgbGlzdCB0byByZXZlcnNlCisgICAqIEByZXR1cm4gQSBuZXcgYXJyYXkgb2YgY29udGVudCBvZiA8Y29kZT5yZWFkZXJzPC9jb2RlPiwgcmV2ZXJzZWQuCisgICAqLworICBwcml2YXRlIFN0b3JlRmlsZSBbXSByZXZlcnNlKGZpbmFsIExpc3Q8U3RvcmVGaWxlPiByKSB7CisgICAgTGlzdDxTdG9yZUZpbGU+IGNvcHkgPSBuZXcgQXJyYXlMaXN0PFN0b3JlRmlsZT4ocik7CisgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShjb3B5KTsKKyAgICAvLyBNYXBGaWxlLlJlYWRlciBpcyBpbnN0YW5jZSBvZiBTdG9yZUZpbGVSZWFkZXIgc28gdGhpcyBzaG91bGQgYmUgb2suCisgICAgcmV0dXJuIGNvcHkudG9BcnJheShuZXcgU3RvcmVGaWxlWzBdKTsKKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSByZHJzIExpc3Qgb2YgU3RvcmVGaWxlcworICAgKiBAcGFyYW0ga2V5cyBDdXJyZW50IGtleXMKKyAgICogQHBhcmFtIGRvbmUgV2hpY2ggcmVhZGVycyBhcmUgZG9uZQorICAgKiBAcmV0dXJuIFRoZSBsb3dlc3QgY3VycmVudCBrZXkgaW4gcGFzc2VkIDxjb2RlPnJkcnM8L2NvZGU+CisgICAqLworICBwcml2YXRlIGludCBnZXRMb3dlc3RLZXkoZmluYWwgSEZpbGVTY2FubmVyIFtdIHJkcnMsIGZpbmFsIEtleVZhbHVlIFtdIGtleXMsCisgICAgICBmaW5hbCBib29sZWFuIFtdIGRvbmUpIHsKKyAgICBpbnQgbG93ZXN0S2V5ID0gLTE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZHJzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoZG9uZVtpXSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGlmIChsb3dlc3RLZXkgPCAwKSB7CisgICAgICAgIGxvd2VzdEtleSA9IGk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAodGhpcy5jb21wYXJhdG9yLmNvbXBhcmUoa2V5c1tpXSwga2V5c1tsb3dlc3RLZXldKSA8IDApIHsKKyAgICAgICAgICBsb3dlc3RLZXkgPSBpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBsb3dlc3RLZXk7CisgIH0KKworICAvKgorICAgKiBDb21wYWN0IGEgbGlzdCBvZiBTdG9yZUZpbGVzLgorICAgKiAKKyAgICogV2Ugd29yayBieSBpdGVyYXRpbmcgdGhyb3VnaCB0aGUgcmVhZGVycyBpbiBwYXJhbGxlbCBsb29raW5nIGF0IG5ld2VzdAorICAgKiBzdG9yZSBmaWxlIGZpcnN0LiBXZSBhbHdheXMgaW5jcmVtZW50IHRoZSBsb3dlc3QtcmFua2VkIG9uZS4gVXBkYXRlcyB0byBhCisgICAqIHNpbmdsZSByb3cvY29sdW1uIHdpbGwgYXBwZWFyIHJhbmtlZCBieSB0aW1lc3RhbXAuCisgICAqIEBwYXJhbSBjb21wYWN0ZWRPdXQgV2hlcmUgdG8gd3JpdGUgY29tcGFjdGlvbi4KKyAgICogQHBhcmFtIHBSZWFkZXJzIExpc3Qgb2YgcmVhZGVycyBzb3J0ZWQgb2xkZXN0IHRvIG5ld2VzdC4KKyAgICogQHBhcmFtIG1ham9yQ29tcGFjdGlvbiBUcnVlIHRvIGZvcmNlIGEgbWFqb3IgY29tcGFjdGlvbiByZWdhcmRsZXNzIG9mCisgICAqIHRocmVzaG9sZHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNvbXBhY3QoZmluYWwgSEZpbGUuV3JpdGVyIGNvbXBhY3RlZE91dCwKKyAgICAgIGZpbmFsIExpc3Q8U3RvcmVGaWxlPiBwUmVhZGVycywgZmluYWwgYm9vbGVhbiBtYWpvckNvbXBhY3Rpb24pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gUmV2ZXJzZSBvcmRlciBzbyBuZXdlc3Qgc3RvcmUgZmlsZSBpcyBmaXJzdC4KKyAgICBTdG9yZUZpbGVbXSBmaWxlcyA9IHJldmVyc2UocFJlYWRlcnMpOworICAgIEhGaWxlU2Nhbm5lciBbXSByZHJzID0gbmV3IEhGaWxlU2Nhbm5lcltmaWxlcy5sZW5ndGhdOworICAgIEtleVZhbHVlIFtdIGt2cyA9IG5ldyBLZXlWYWx1ZVtyZHJzLmxlbmd0aF07CisgICAgYm9vbGVhbltdIGRvbmUgPSBuZXcgYm9vbGVhbltyZHJzLmxlbmd0aF07CisgICAgLy8gTm93LCBhZHZhbmNlIHRocm91Z2ggdGhlIHJlYWRlcnMgaW4gb3JkZXIuIFRoaXMgd2lsbCBoYXZlIHRoZQorICAgIC8vIGVmZmVjdCBvZiBhIHJ1bi10aW1lIHNvcnQgb2YgdGhlIGVudGlyZSBkYXRhc2V0LgorICAgIGludCBudW1Eb25lID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJkcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHJkcnNbaV0gPSBmaWxlc1tpXS5nZXRSZWFkZXIoKS5nZXRTY2FubmVyKCk7CisgICAgICBkb25lW2ldID0gIXJkcnNbaV0uc2Vla1RvKCk7CisgICAgICBpZiAoZG9uZVtpXSkgeworICAgICAgICBudW1Eb25lKys7CisgICAgICB9IGVsc2UgeworICAgICAgICBrdnNbaV0gPSByZHJzW2ldLmdldEtleVZhbHVlKCk7CisgICAgICB9CisgICAgfQorCisgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBpbnQgdGltZXNTZWVuID0gMDsKKyAgICBLZXlWYWx1ZSBsYXN0U2VlbiA9IEtleVZhbHVlLkxPV0VTVEtFWTsKKyAgICBLZXlWYWx1ZSBsYXN0RGVsZXRlID0gbnVsbDsKKyAgICBpbnQgbWF4VmVyc2lvbnMgPSBmYW1pbHkuZ2V0TWF4VmVyc2lvbnMoKTsKKyAgICB3aGlsZSAobnVtRG9uZSA8IGRvbmUubGVuZ3RoKSB7CisgICAgICAvLyBHZXQgbG93ZXN0IGtleSBpbiBhbGwgc3RvcmUgZmlsZXMuCisgICAgICBpbnQgbG93ZXN0S2V5ID0gZ2V0TG93ZXN0S2V5KHJkcnMsIGt2cywgZG9uZSk7CisgICAgICBLZXlWYWx1ZSBrdiA9IGt2c1tsb3dlc3RLZXldOworICAgICAgLy8gSWYgaXRzIHNhbWUgcm93IGFuZCBjb2x1bW4gYXMgbGFzdCBrZXksIGluY3JlbWVudCB0aW1lcyBzZWVuLgorICAgICAgaWYgKHRoaXMuY29tcGFyYXRvci5tYXRjaGluZ1Jvd0NvbHVtbihsYXN0U2Vlbiwga3YpKSB7CisgICAgICAgIHRpbWVzU2VlbisrOworICAgICAgICAvLyBSZXNldCBsYXN0IGRlbGV0ZSBpZiBub3QgZXhhY3QgdGltZXN0YW1wIC0tIGxhc3REZWxldGUgb25seSBzdG9wcworICAgICAgICAvLyBleGFjdGx5IHRoZSBzYW1lIGtleSBtYWtpbmcgaXQgb3V0IHRvIHRoZSBjb21wYWN0ZWQgc3RvcmUgZmlsZS4KKyAgICAgICAgaWYgKGxhc3REZWxldGUgIT0gbnVsbCAmJgorICAgICAgICAgICAgbGFzdERlbGV0ZS5nZXRUaW1lc3RhbXAoKSAhPSBrdi5nZXRUaW1lc3RhbXAoKSkgeworICAgICAgICAgIGxhc3REZWxldGUgPSBudWxsOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICB0aW1lc1NlZW4gPSAxOworICAgICAgICBsYXN0RGVsZXRlID0gbnVsbDsKKyAgICAgIH0KKworICAgICAgLy8gRG9uJ3Qgd3JpdGUgZW1wdHkgcm93cyBvciBjb2x1bW5zLiBPbmx5IHJlbW92ZSBjZWxscyBvbiBtYWpvcgorICAgICAgLy8gY29tcGFjdGlvbi4gUmVtb3ZlIGlmIGV4cGlyZWQgb3IgPiBWRVJTSU9OUworICAgICAgaWYgKGt2Lm5vbk51bGxSb3dBbmRDb2x1bW4oKSkgeworICAgICAgICBpZiAoIW1ham9yQ29tcGFjdGlvbikgeworICAgICAgICAgIC8vIFdyaXRlIG91dCBhbGwgdmFsdWVzIGlmIG5vdCBhIG1ham9yIGNvbXBhY3Rpb24uCisgICAgICAgICAgY29tcGFjdGVkT3V0LmFwcGVuZChrdik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYm9vbGVhbiBleHBpcmVkID0gZmFsc2U7CisgICAgICAgICAgYm9vbGVhbiBkZWxldGVkID0gZmFsc2U7CisgICAgICAgICAgaWYgKHRpbWVzU2VlbiA8PSBtYXhWZXJzaW9ucyAmJiAhKGV4cGlyZWQgPSBpc0V4cGlyZWQoa3YsIHR0bCwgbm93KSkpIHsKKyAgICAgICAgICAgIC8vIElmIHRoaXMgdmFsdWUga2V5IGlzIHNhbWUgYXMgYSBkZWxldGVkIGtleSwgc2tpcAorICAgICAgICAgICAgaWYgKGxhc3REZWxldGUgIT0gbnVsbCAmJgorICAgICAgICAgICAgICAgIHRoaXMuY29tcGFyYXRvcklnbm9yaW5nVHlwZS5jb21wYXJlKGt2LCBsYXN0RGVsZXRlKSA9PSAwKSB7CisgICAgICAgICAgICAgIGRlbGV0ZWQgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIGlmIChrdi5pc0RlbGV0ZVR5cGUoKSkgeworICAgICAgICAgICAgICAvLyBJZiBhIGRlbGV0ZWQgdmFsdWUsIHNraXAKKyAgICAgICAgICAgICAgZGVsZXRlZCA9IHRydWU7CisgICAgICAgICAgICAgIGxhc3REZWxldGUgPSBrdjsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIGNvbXBhY3RlZE91dC5hcHBlbmQoa3YpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoZXhwaXJlZCB8fCBkZWxldGVkKSB7CisgICAgICAgICAgICAvLyBIQkFTRS04NTUgcmVtb3ZlIG9uZSBmcm9tIHRpbWVzU2VlbiBiZWNhdXNlIGl0IGRpZCBub3QgbWFrZSBpdAorICAgICAgICAgICAgLy8gcGFzdCBleHBpcmVkIGNoZWNrIC0tIGRvbid0IGNvdW50IGFnYWluc3QgbWF4IHZlcnNpb25zLgorICAgICAgICAgICAgdGltZXNTZWVuLS07CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIFVwZGF0ZSBsYXN0LXNlZW4gaXRlbXMKKyAgICAgIGxhc3RTZWVuID0ga3Y7CisKKyAgICAgIC8vIEFkdmFuY2UgdGhlIHNtYWxsZXN0IGtleS4gSWYgdGhhdCByZWFkZXIncyBhbGwgZmluaXNoZWQsIHRoZW4KKyAgICAgIC8vIG1hcmsgaXQgYXMgZG9uZS4KKyAgICAgIGlmICghcmRyc1tsb3dlc3RLZXldLm5leHQoKSkgeworICAgICAgICBkb25lW2xvd2VzdEtleV0gPSB0cnVlOworICAgICAgICByZHJzW2xvd2VzdEtleV0gPSBudWxsOworICAgICAgICBudW1Eb25lKys7CisgICAgICB9IGVsc2UgeworICAgICAgICBrdnNbbG93ZXN0S2V5XSA9IHJkcnNbbG93ZXN0S2V5XS5nZXRLZXlWYWx1ZSgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qCisgICAqIEl0J3MgYXNzdW1lZCB0aGF0IHRoZSBjb21wYWN0TG9jayAgd2lsbCBiZSBhY3F1aXJlZCBwcmlvciB0byBjYWxsaW5nIHRoaXMgCisgICAqIG1ldGhvZCEgIE90aGVyd2lzZSwgaXQgaXMgbm90IHRocmVhZC1zYWZlIQorICAgKgorICAgKiBJdCB3b3JrcyBieSBwcm9jZXNzaW5nIGEgY29tcGFjdGlvbiB0aGF0J3MgYmVlbiB3cml0dGVuIHRvIGRpc2suCisgICAqIAorICAgKiA8cD5JdCBpcyB1c3VhbGx5IGludm9rZWQgYXQgdGhlIGVuZCBvZiBhIGNvbXBhY3Rpb24sIGJ1dCBtaWdodCBhbHNvIGJlCisgICAqIGludm9rZWQgYXQgSFN0b3JlIHN0YXJ0dXAsIGlmIHRoZSBwcmlvciBleGVjdXRpb24gZGllZCBtaWR3YXkgdGhyb3VnaC4KKyAgICogCisgICAqIDxwPk1vdmluZyB0aGUgY29tcGFjdGVkIFRyZWVNYXAgaW50byBwbGFjZSBtZWFuczoKKyAgICogPHByZT4KKyAgICogMSkgTW92aW5nIHRoZSBuZXcgY29tcGFjdGVkIE1hcEZpbGUgaW50byBwbGFjZQorICAgKiAyKSBVbmxvYWQgYWxsIHJlcGxhY2VkIE1hcEZpbGVzLCBjbG9zZSBhbmQgY29sbGVjdCBsaXN0IHRvIGRlbGV0ZS4KKyAgICogMykgTG9hZGluZyB0aGUgbmV3IFRyZWVNYXAuCisgICAqIDQpIENvbXB1dGUgbmV3IHN0b3JlIHNpemUKKyAgICogPC9wcmU+CisgICAqIAorICAgKiBAcGFyYW0gY29tcGFjdGVkRmlsZXMgbGlzdCBvZiBmaWxlcyB0aGF0IHdlcmUgY29tcGFjdGVkCisgICAqIEBwYXJhbSBjb21wYWN0ZWRGaWxlIEhTdG9yZUZpbGUgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIHRoZSBjb21wYWN0aW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgdm9pZCBjb21wbGV0ZUNvbXBhY3Rpb24oZmluYWwgTGlzdDxTdG9yZUZpbGU+IGNvbXBhY3RlZEZpbGVzLAorICAgIGZpbmFsIEhGaWxlLldyaXRlciBjb21wYWN0ZWRGaWxlKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIDEuIE1vdmluZyB0aGUgbmV3IGZpbGVzIGludG8gcGxhY2UuCisgICAgUGF0aCBwID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgcCA9IFN0b3JlRmlsZS5yZW5hbWUodGhpcy5mcywgY29tcGFjdGVkRmlsZS5nZXRQYXRoKCksCisgICAgICAgIFN0b3JlRmlsZS5nZXRSYW5kb21GaWxlbmFtZShmcywgdGhpcy5ob21lZGlyKSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJGYWlsZWQgbW92ZSBvZiBjb21wYWN0ZWQgZmlsZSAiICsgY29tcGFjdGVkRmlsZS5nZXRQYXRoKCksIGUpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBTdG9yZUZpbGUgZmluYWxDb21wYWN0ZWRGaWxlID0gbmV3IFN0b3JlRmlsZSh0aGlzLmZzLCBwKTsKKyAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICB0cnkgeworICAgICAgICAvLyAzLiBMb2FkaW5nIHRoZSBuZXcgVHJlZU1hcC4KKyAgICAgICAgLy8gQ2hhbmdlIHRoaXMuc3RvcmVmaWxlcyBzbyBpdCByZWZsZWN0cyBuZXcgc3RhdGUgYnV0IGRvIG5vdAorICAgICAgICAvLyBkZWxldGUgb2xkIHN0b3JlIGZpbGVzIHVudGlsIHdlIGhhdmUgc2VudCBvdXQgbm90aWZpY2F0aW9uIG9mCisgICAgICAgIC8vIGNoYW5nZSBpbiBjYXNlIG9sZCBmaWxlcyBhcmUgc3RpbGwgYmVpbmcgYWNjZXNzZWQgYnkgb3V0c3RhbmRpbmcKKyAgICAgICAgLy8gc2Nhbm5lcnMuCisgICAgICAgIGZvciAoTWFwLkVudHJ5PExvbmcsIFN0b3JlRmlsZT4gZTogdGhpcy5zdG9yZWZpbGVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICBpZiAoY29tcGFjdGVkRmlsZXMuY29udGFpbnMoZS5nZXRWYWx1ZSgpKSkgeworICAgICAgICAgICAgdGhpcy5zdG9yZWZpbGVzLnJlbW92ZShlLmdldEtleSgpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gQWRkIG5ldyBjb21wYWN0ZWQgUmVhZGVyIGFuZCBzdG9yZSBmaWxlLgorICAgICAgICBMb25nIG9yZGVyVmFsID0gTG9uZy52YWx1ZU9mKGZpbmFsQ29tcGFjdGVkRmlsZS5nZXRNYXhTZXF1ZW5jZUlkKCkpOworICAgICAgICB0aGlzLnN0b3JlZmlsZXMucHV0KG9yZGVyVmFsLCBmaW5hbENvbXBhY3RlZEZpbGUpOworICAgICAgICAvLyBUZWxsIG9ic2VydmVycyB0aGF0IGxpc3Qgb2YgUmVhZGVycyBoYXMgY2hhbmdlZC4KKyAgICAgICAgbm90aWZ5Q2hhbmdlZFJlYWRlcnNPYnNlcnZlcnMoKTsKKyAgICAgICAgLy8gRmluYWxseSwgZGVsZXRlIG9sZCBzdG9yZSBmaWxlcy4KKyAgICAgICAgZm9yIChTdG9yZUZpbGUgaHNmOiBjb21wYWN0ZWRGaWxlcykgeworICAgICAgICAgIGhzZi5kZWxldGUoKTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBlID0gUmVtb3RlRXhjZXB0aW9uSGFuZGxlci5jaGVja0lPRXhjZXB0aW9uKGUpOworICAgICAgICBMT0cuZXJyb3IoIkZhaWxlZCByZXBsYWNpbmcgY29tcGFjdGVkIGZpbGVzIGZvciAiICsKKyAgICAgICAgICAgIHRoaXMuc3RvcmVOYW1lU3RyICsKKyAgICAgICAgICAgICIuIENvbXBhY3RlZCBmaWxlIGlzICIgKyBmaW5hbENvbXBhY3RlZEZpbGUudG9TdHJpbmcoKSArCisgICAgICAgICAgICAiLiAgRmlsZXMgcmVwbGFjZWQgYXJlICIgKyBjb21wYWN0ZWRGaWxlcy50b1N0cmluZygpICsKKyAgICAgICAgICAgICIgc29tZSBvZiB3aGljaCBtYXkgaGF2ZSBiZWVuIGFscmVhZHkgcmVtb3ZlZCIsIGUpOworICAgICAgfQorICAgICAgLy8gNC4gQ29tcHV0ZSBuZXcgc3RvcmUgc2l6ZQorICAgICAgdGhpcy5zdG9yZVNpemUgPSAwTDsKKyAgICAgIGZvciAoU3RvcmVGaWxlIGhzZiA6IHRoaXMuc3RvcmVmaWxlcy52YWx1ZXMoKSkgeworICAgICAgICB0aGlzLnN0b3JlU2l6ZSArPSBoc2YuZ2V0UmVhZGVyKCkubGVuZ3RoKCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay53cml0ZUxvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIEFjY2Vzc29ycy4KKyAgLy8gKFRoaXMgaXMgdGhlIG9ubHkgc2VjdGlvbiB0aGF0IGlzIGRpcmVjdGx5IHVzZWZ1bCEpCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAKKyAgLyoqCisgICAqIFJldHVybiBhbGwgdGhlIGF2YWlsYWJsZSBjb2x1bW5zIGZvciB0aGUgZ2l2ZW4ga2V5LiAgVGhlIGtleSBpbmRpY2F0ZXMgYSAKKyAgICogcm93IGFuZCB0aW1lc3RhbXAsIGJ1dCBub3QgYSBjb2x1bW4gbmFtZS4KKyAgICoKKyAgICogVGhlIHJldHVybmVkIG9iamVjdCBzaG91bGQgbWFwIGNvbHVtbiBuYW1lcyB0byBDZWxscy4KKyAgICogQHBhcmFtIGtleSAtICBXaGVyZSB0byBzdGFydCBzZWFyY2hpbmcuICBTcGVjaWZpZXMgYSByb3cuCisgICAqIENvbHVtbnMgYXJlIHNwZWNpZmllZCBpbiBmb2xsb3dpbmcgYXJndW1lbnRzLgorICAgKiBAcGFyYW0gY29sdW1ucyBDYW4gYmUgbnVsbCB3aGljaCBtZWFucyBnZXQgYWxsCisgICAqIEBwYXJhbSBjb2x1bW5QYXR0ZXJuIENhbiBiZSBudWxsLgorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMKKyAgICogQHBhcmFtIHZlcnNpb25zQ291bnRlciBDYW4gYmUgbnVsbC4KKyAgICogQHBhcmFtIGtleXZhbHVlcworICAgKiBAcGFyYW0gbm93IC0gIFdoZXJlIHRvIHN0YXJ0IHNlYXJjaGluZy4gIFNwZWNpZmllcyBhIHRpbWVzdGFtcC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZ2V0RnVsbChLZXlWYWx1ZSBrZXksIGZpbmFsIE5hdmlnYWJsZVNldDxieXRlIFtdPiBjb2x1bW5zLAorICAgICAgZmluYWwgUGF0dGVybiBjb2x1bW5QYXR0ZXJuLAorICAgICAgZmluYWwgaW50IG51bVZlcnNpb25zLCBNYXA8S2V5VmFsdWUsIEhSZWdpb24uQ291bnRlcj4gdmVyc2lvbnNDb3VudGVyLAorICAgICAgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzLCBmaW5hbCBsb25nIG5vdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBpZiB0aGUga2V5IGlzIG51bGwsIHdlJ3JlIG5vdCBldmVuIGxvb2tpbmcgZm9yIGFueXRoaW5nLiByZXR1cm4uCisgICAgaWYgKGtleSA9PSBudWxsKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGludCB2ZXJzaW9ucyA9IHZlcnNpb25zVG9SZXR1cm4obnVtVmVyc2lvbnMpOworICAgIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcyA9CisgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4odGhpcy5jb21wYXJhdG9ySWdub3JpbmdUeXBlKTsKKyAgICAvLyBDcmVhdGUgYSBNYXAgdGhhdCBoYXMgcmVzdWx0cyBieSBjb2x1bW4gc28gd2UgY2FuIGtlZXAgY291bnQgb2YgdmVyc2lvbnMuCisgICAgLy8gSXQgZHVwbGljYXRlcyBjb2x1bW5zIGJ1dCBkb2luZyBjaGVjayBvZiBjb2x1bW5zLCB3ZSBkb24ndCB3YW50IHRvIG1ha2UKKyAgICAvLyBjb2x1bW4gc2V0IGVhY2ggdGltZS4KKyAgICB0aGlzLmxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIGdldCBmcm9tIHRoZSBtZW1jYWNoZSBmaXJzdC4KKyAgICAgIGlmICh0aGlzLm1lbWNhY2hlLmdldEZ1bGwoa2V5LCBjb2x1bW5zLCBjb2x1bW5QYXR0ZXJuLCB2ZXJzaW9ucywKKyAgICAgICAgICB2ZXJzaW9uc0NvdW50ZXIsIGRlbGV0ZXMsIGtleXZhbHVlcywgbm93KSkgeworICAgICAgICAvLyBNYXkgaGF2ZSBnb3R0ZW4gZW5vdWdoIHJlc3VsdHMsIGVub3VnaCB0byByZXR1cm4uCisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIE1hcDxMb25nLCBTdG9yZUZpbGU+IG0gPSB0aGlzLnN0b3JlZmlsZXMuZGVzY2VuZGluZ01hcCgpOworICAgICAgZm9yIChJdGVyYXRvcjxNYXAuRW50cnk8TG9uZywgU3RvcmVGaWxlPj4gaSA9IG0uZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgIGkuaGFzTmV4dCgpOykgeworICAgICAgICBpZiAoZ2V0RnVsbEZyb21TdG9yZUZpbGUoaS5uZXh0KCkuZ2V0VmFsdWUoKSwga2V5LCBjb2x1bW5zLAorICAgICAgICAgICAgY29sdW1uUGF0dGVybiwgdmVyc2lvbnMsIHZlcnNpb25zQ291bnRlciwgZGVsZXRlcywga2V5dmFsdWVzKSkgeworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBAcGFyYW0gZgorICAgKiBAcGFyYW0ga2V5IFdoZXJlIHRvIHN0YXJ0IHNlYXJjaGluZy4gIFNwZWNpZmllcyBhIHJvdyBhbmQgdGltZXN0YW1wLgorICAgKiBDb2x1bW5zIGFyZSBzcGVjaWZpZWQgaW4gZm9sbG93aW5nIGFyZ3VtZW50cy4KKyAgICogQHBhcmFtIGNvbHVtbnMKKyAgICogQHBhcmFtIHZlcnNpb25zCisgICAqIEBwYXJhbSB2ZXJzaW9uQ291bnRlcgorICAgKiBAcGFyYW0gZGVsZXRlcworICAgKiBAcGFyYW0ga2V5dmFsdWVzCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB3ZSBmb3VuZCBlbm91Z2ggcmVzdWx0cyB0byBzYXRpc2Z5IHRoZSA8Y29kZT52ZXJzaW9uczwvY29kZT4KKyAgICogYW5kIDxjb2RlPmNvbHVtbnM8L2NvZGU+IHBhc3NlZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGdldEZ1bGxGcm9tU3RvcmVGaWxlKFN0b3JlRmlsZSBmLCBLZXlWYWx1ZSB0YXJnZXQsIAorICAgIFNldDxieXRlIFtdPiBjb2x1bW5zLCBmaW5hbCBQYXR0ZXJuIGNvbHVtblBhdHRlcm4sIGludCB2ZXJzaW9ucywgCisgICAgTWFwPEtleVZhbHVlLCBIUmVnaW9uLkNvdW50ZXI+IHZlcnNpb25Db3VudGVyLAorICAgIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywKKyAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSBmLmdldFJlYWRlcigpLmdldFNjYW5uZXIoKTsKKyAgICBpZiAoIWdldENsb3Nlc3Qoc2Nhbm5lciwgdGFyZ2V0KSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBib29sZWFuIGhhc0Vub3VnaCA9IGZhbHNlOworICAgIGRvIHsKKyAgICAgIEtleVZhbHVlIGt2ID0gc2Nhbm5lci5nZXRLZXlWYWx1ZSgpOworICAgICAgLy8gTWFrZSBzdXJlIHdlIGhhdmUgbm90IHBhc3NlZCBvdXQgdGhlIHJvdy4gIElmIHRhcmdldCBrZXkgaGFzIGEKKyAgICAgIC8vIGNvbHVtbiBvbiBpdCwgdGhlbiB3ZSBhcmUgbG9va2luZyBleHBsaWNpdCBrZXkrY29sdW1uIGNvbWJpbmF0aW9uLiAgSWYKKyAgICAgIC8vIHdlJ3ZlIHBhc3NlZCBpdCBvdXQsIGFsc28gYnJlYWsuCisgICAgICBpZiAodGFyZ2V0LmlzRW1wdHlDb2x1bW4oKT8gIXRoaXMuY29tcGFyYXRvci5tYXRjaGluZ1Jvd3ModGFyZ2V0LCBrdik6CisgICAgICAgICAgIXRoaXMuY29tcGFyYXRvci5tYXRjaGluZ1Jvd0NvbHVtbih0YXJnZXQsIGt2KSkgeworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmICghU3RvcmUuZ2V0RnVsbENoZWNrKHRoaXMuY29tcGFyYXRvciwgdGFyZ2V0LCBrdiwgY29sdW1ucywgY29sdW1uUGF0dGVybikpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBpZiAoU3RvcmUuZG9LZXlWYWx1ZShrdiwgdmVyc2lvbnMsIHZlcnNpb25Db3VudGVyLCBjb2x1bW5zLCBkZWxldGVzLCBub3csCisgICAgICAgICAgdGhpcy50dGwsIGtleXZhbHVlcywgbnVsbCkpIHsKKyAgICAgICAgaGFzRW5vdWdoID0gdHJ1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfSB3aGlsZSAoc2Nhbm5lci5uZXh0KCkpOworICAgIHJldHVybiBoYXNFbm91Z2g7CisgIH0KKworICAvKioKKyAgICogQ29kZSBzaGFyZWQgYnkge0BsaW5rIE1lbWNhY2hlI2dldEZ1bGwoS2V5VmFsdWUsIE5hdmlnYWJsZVNldCwgUGF0dGVybiwgaW50LCBNYXAsIE5hdmlnYWJsZVNldCwgTGlzdCwgbG9uZyl9CisgICAqIGFuZCB7QGxpbmsgI2dldEZ1bGxGcm9tU3RvcmVGaWxlKFN0b3JlRmlsZSwgS2V5VmFsdWUsIFNldCwgUGF0dGVybiwgaW50LCBNYXAsIE5hdmlnYWJsZVNldCwgTGlzdCl9CisgICAqIEBwYXJhbSBjCisgICAqIEBwYXJhbSB0YXJnZXQKKyAgICogQHBhcmFtIGNhbmRpZGF0ZQorICAgKiBAcGFyYW0gY29sdW1ucworICAgKiBAcGFyYW0gY29sdW1uUGF0dGVybgorICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+Y2FuZGlkYXRlPC9jb2RlPiBtYXRjaGVzIGNvbHVtbiBhbmQgdGltZXN0YW1wLgorICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gZ2V0RnVsbENoZWNrKGZpbmFsIEtleVZhbHVlLktWQ29tcGFyYXRvciBjLAorICAgICAgZmluYWwgS2V5VmFsdWUgdGFyZ2V0LCBmaW5hbCBLZXlWYWx1ZSBjYW5kaWRhdGUsCisgICAgICBmaW5hbCBTZXQ8Ynl0ZSBbXT4gY29sdW1ucywgZmluYWwgUGF0dGVybiBjb2x1bW5QYXR0ZXJuKSB7CisgICAgLy8gRG9lcyBjb2x1bW4gbWF0Y2g/CisgICAgaWYgKCFTdG9yZS5tYXRjaGluZ0NvbHVtbnMoY2FuZGlkYXRlLCBjb2x1bW5zKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAvLyBpZiB0aGUgY29sdW1uIHBhdHRlcm4gaXMgbm90IG51bGwsIHdlIHVzZSBpdCBmb3IgY29sdW1uIG1hdGNoaW5nLgorICAgIC8vIHdlIHdpbGwgc2tpcCB0aGUga2V5cyB3aG9zZSBjb2x1bW4gZG9lc24ndCBtYXRjaCB0aGUgcGF0dGVybi4KKyAgICBpZiAoY29sdW1uUGF0dGVybiAhPSBudWxsKSB7CisgICAgICBpZiAoIShjb2x1bW5QYXR0ZXJuLm1hdGNoZXIoY2FuZGlkYXRlLmdldENvbHVtblN0cmluZygpKS5tYXRjaGVzKCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKGMuY29tcGFyZVRpbWVzdGFtcHModGFyZ2V0LCBjYW5kaWRhdGUpID4gMCkgIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7IAorICB9CisKKyAgLyoKKyAgICogQHBhcmFtIHdhbnRlZFZlcnNpb25zIEhvdyBtYW55IHZlcnNpb25zIHdlcmUgYXNrZWQgZm9yLgorICAgKiBAcmV0dXJuIHdhbnRlZFZlcnNpb25zIG9yIHRoaXMgZmFtaWxpZXMnIFZFUlNJT05TLgorICAgKi8KKyAgcHJpdmF0ZSBpbnQgdmVyc2lvbnNUb1JldHVybihmaW5hbCBpbnQgd2FudGVkVmVyc2lvbnMpIHsKKyAgICBpZiAod2FudGVkVmVyc2lvbnMgPD0gMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTnVtYmVyIG9mIHZlcnNpb25zIG11c3QgYmUgPiAwIik7CisgICAgfQorICAgIC8vIE1ha2Ugc3VyZSB3ZSBkbyBub3QgcmV0dXJuIG1vcmUgdGhhbiBtYXhpbXVtIHZlcnNpb25zIGZvciB0aGlzIHN0b3JlLgorICAgIGludCBtYXhWZXJzaW9ucyA9IHRoaXMuZmFtaWx5LmdldE1heFZlcnNpb25zKCk7CisgICAgcmV0dXJuIHdhbnRlZFZlcnNpb25zID4gbWF4VmVyc2lvbnMgJiYKKyAgICAgIHdhbnRlZFZlcnNpb25zICE9IEhDb25zdGFudHMuQUxMX1ZFUlNJT05TPyBtYXhWZXJzaW9uczogd2FudGVkVmVyc2lvbnM7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHZhbHVlIGZvciB0aGUgaW5kaWNhdGVkIEhTdG9yZUtleS4gIEdyYWIgdGhlIHRhcmdldCB2YWx1ZSBhbmQgdGhlIAorICAgKiBwcmV2aW91cyA8Y29kZT5udW1WZXJzaW9ucyAtIDE8L2NvZGU+IHZhbHVlcywgYXMgd2VsbC4KKyAgICoKKyAgICogVXNlIHtAbGluayBIQ29uc3RhbnRzLkFMTF9WRVJTSU9OU30gdG8gcmV0cmlldmUgYWxsIHZlcnNpb25zLgorICAgKiBAcGFyYW0ga2V5CisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBOdW1iZXIgb2YgdmVyc2lvbnMgdG8gZmV0Y2guICBNdXN0IGJlID4gMC4KKyAgICogQHJldHVybiB2YWx1ZXMgZm9yIHRoZSBzcGVjaWZpZWQgdmVyc2lvbnMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgTGlzdDxLZXlWYWx1ZT4gZ2V0KGZpbmFsIEtleVZhbHVlIGtleSwgZmluYWwgaW50IG51bVZlcnNpb25zKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFRoaXMgY29kZSBiZWxvdyBpcyB2ZXJ5IGNsb3NlIHRvIHRoZSBib2R5IG9mIHRoZSBnZXRLZXlzIG1ldGhvZC4gIEFueSAKKyAgICAvLyBjaGFuZ2VzIGluIHRoZSBmbG93IGJlbG93IHNob3VsZCBhbHNvIHByb2JhYmx5IGJlIGRvbmUgaW4gZ2V0S2V5cy4KKyAgICAvLyBUT0RPOiBSZWZhY3RvciBzbyBzYW1lIGNvZGUgdXNlZC4KKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGludCB2ZXJzaW9ucyA9IHZlcnNpb25zVG9SZXR1cm4obnVtVmVyc2lvbnMpOworICAgIC8vIEtlZXAgYSBsaXN0IG9mIGRlbGV0ZWQgY2VsbCBrZXlzLiAgV2UgbmVlZCB0aGlzIGJlY2F1c2UgYXMgd2UgZ28gdGhyb3VnaAorICAgIC8vIHRoZSBtZW1jYWNoZSBhbmQgc3RvcmUgZmlsZXMsIHRoZSBjZWxsIHdpdGggdGhlIGRlbGV0ZSBtYXJrZXIgbWF5IGJlCisgICAgLy8gaW4gb25lIHN0b3JlIGFuZCB0aGUgb2xkIG5vbi1kZWxldGUgY2VsbCB2YWx1ZSBpbiBhIGxhdGVyIHN0b3JlLgorICAgIC8vIElmIHdlIGRvbid0IGtlZXAgYXJvdW5kIHRoZSBmYWN0IHRoYXQgdGhlIGNlbGwgd2FzIGRlbGV0ZWQgaW4gYSBuZXdlcgorICAgIC8vIHJlY29yZCwgd2UgZW5kIHVwIHJldHVybmluZyB0aGUgb2xkIHZhbHVlIGlmIHVzZXIgaXMgYXNraW5nIGZvciBtb3JlCisgICAgLy8gdGhhbiBvbmUgdmVyc2lvbi4gVGhpcyBMaXN0IG9mIGRlbGV0ZXMgc2hvdWxkIG5vdCBiZSBsYXJnZSBzaW5jZSB3ZQorICAgIC8vIGFyZSBvbmx5IGtlZXBpbmcgcm93cyBhbmQgY29sdW1ucyB0aGF0IG1hdGNoIHRob3NlIHNldCBvbiB0aGUgZ2V0IGFuZAorICAgIC8vIHdoaWNoIGhhdmUgZGVsZXRlIHZhbHVlcy4gIElmIG1lbW9yeSB1c2FnZSBiZWNvbWVzIGFuIGlzc3VlLCBjb3VsZAorICAgIC8vIHJlZG8gYXMgYmxvb20gZmlsdGVyLiAgVXNlIHNvcnRlZCBzZXQgYmVjYXVzZSB0ZXN0IGZvciBtZW1iZXJzaGlwIHNob3VsZAorICAgIC8vIGJlIGZhc3RlciB0aGFuIGNhbGN1bGF0aW5nIGEgaGFzaC4gIFVzZSBhIGNvbXBhcmF0b3IgdGhhdCBpZ25vcmVzIHRzLgorICAgIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcyA9CisgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4odGhpcy5jb21wYXJhdG9ySWdub3JpbmdUeXBlKTsKKyAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgIHRoaXMubG9jay5yZWFkTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgLy8gQ2hlY2sgdGhlIG1lbWNhY2hlCisgICAgICBpZiAodGhpcy5tZW1jYWNoZS5nZXQoa2V5LCB2ZXJzaW9ucywga2V5dmFsdWVzLCBkZWxldGVzLCBub3cpKSB7CisgICAgICAgIHJldHVybiBrZXl2YWx1ZXM7CisgICAgICB9CisgICAgICBNYXA8TG9uZywgU3RvcmVGaWxlPiBtID0gdGhpcy5zdG9yZWZpbGVzLmRlc2NlbmRpbmdNYXAoKTsKKyAgICAgIGJvb2xlYW4gaGFzRW5vdWdoID0gZmFsc2U7CisgICAgICBmb3IgKE1hcC5FbnRyeTxMb25nLCBTdG9yZUZpbGU+IGU6IG0uZW50cnlTZXQoKSkgeworICAgICAgICBTdG9yZUZpbGUgZiA9IGUuZ2V0VmFsdWUoKTsKKyAgICAgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSBmLmdldFJlYWRlcigpLmdldFNjYW5uZXIoKTsKKyAgICAgICAgaWYgKCFnZXRDbG9zZXN0KHNjYW5uZXIsIGtleSkpIHsKKyAgICAgICAgICAvLyBNb3ZlIHRvIG5leHQgZmlsZS4KKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBkbyB7CisgICAgICAgICAgS2V5VmFsdWUga3YgPSBzY2FubmVyLmdldEtleVZhbHVlKCk7CisgICAgICAgICAgLy8gTWFrZSBzdXJlIGJlbG93IG1hdGNoZXMgd2hhdCBoYXBwZW5zIHVwIGluIE1lbWNhY2hlI2dldC4KKyAgICAgICAgICBpZiAodGhpcy5jb21wYXJhdG9yLm1hdGNoaW5nUm93Q29sdW1uKGt2LCBrZXkpKSB7CisgICAgICAgICAgICBpZiAoZG9LZXlWYWx1ZShrdiwgdmVyc2lvbnMsIGRlbGV0ZXMsIG5vdywgdGhpcy50dGwsIGtleXZhbHVlcywgbnVsbCkpIHsKKyAgICAgICAgICAgICAgaGFzRW5vdWdoID0gdHJ1ZTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIFJvdyBhbmQgY29sdW1uIGRvbid0IG1hdGNoLiBNdXN0IGhhdmUgZ29uZSBwYXN0LiBNb3ZlIHRvIG5leHQgZmlsZS4KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAoc2Nhbm5lci5uZXh0KCkpOworICAgICAgICBpZiAoaGFzRW5vdWdoKSB7CisgICAgICAgICAgYnJlYWs7IC8vIEJyZWFrIG91dCBvZiBmaWxlcyBsb29wLgorICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4ga2V5dmFsdWVzLmlzRW1wdHkoKT8gbnVsbDoga2V5dmFsdWVzOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBTbWFsbCBtZXRob2QgdG8gY2hlY2sgaWYgd2UgYXJlIG92ZXIgdGhlIG1heCBudW1iZXIgb2YgdmVyc2lvbnMKKyAgICogb3Igd2UgYWNoZWl2ZWQgdGhpcyBmYW1pbHkgbWF4IHZlcnNpb25zLiAKKyAgICogVGhlIGxhdGVyIGhhcHBlbnMgd2hlbiB3ZSBoYXZlIHRoZSBzaXR1YXRpb24gZGVzY3JpYmVkIGluIEhCQVNFLTYyMS4KKyAgICogQHBhcmFtIHZlcnNpb25zCisgICAqIEBwYXJhbSBjCisgICAqIEByZXR1cm4gCisgICAqLworICBzdGF0aWMgYm9vbGVhbiBoYXNFbm91Z2hWZXJzaW9ucyhmaW5hbCBpbnQgdmVyc2lvbnMsIGZpbmFsIExpc3Q8S2V5VmFsdWU+IGMpIHsKKyAgICByZXR1cm4gdmVyc2lvbnMgPiAwICYmICFjLmlzRW1wdHkoKSAmJiBjLnNpemUoKSA+PSB2ZXJzaW9uczsKKyAgfQorCisgIC8qCisgICAqIFVzZWQgd2hlbiBkb2luZyBnZXRGdWxscy4KKyAgICogQHBhcmFtIGt2CisgICAqIEBwYXJhbSB2ZXJzaW9ucworICAgKiBAcGFyYW0gdmVyc2lvbkNvdW50ZXIKKyAgICogQHBhcmFtIGNvbHVtbnMKKyAgICogQHBhcmFtIGRlbGV0ZXMKKyAgICogQHBhcmFtIG5vdworICAgKiBAcGFyYW0gdHRsCisgICAqIEBwYXJhbSBrZXl2YWx1ZXMKKyAgICogQHBhcmFtIHNldAorICAgKiBAcmV0dXJuIFRydWUgaWYgZW5vdWdoIHZlcnNpb25zLgorICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gZG9LZXlWYWx1ZShmaW5hbCBLZXlWYWx1ZSBrdiwKKyAgICAgIGZpbmFsIGludCB2ZXJzaW9ucywKKyAgICAgIGZpbmFsIE1hcDxLZXlWYWx1ZSwgQ291bnRlcj4gdmVyc2lvbkNvdW50ZXIsCisgICAgICBmaW5hbCBTZXQ8Ynl0ZSBbXT4gY29sdW1ucywKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywKKyAgICAgIGZpbmFsIGxvbmcgbm93LCAKKyAgICAgIGZpbmFsIGxvbmcgdHRsLAorICAgICAgZmluYWwgTGlzdDxLZXlWYWx1ZT4ga2V5dmFsdWVzLAorICAgICAgZmluYWwgU29ydGVkU2V0PEtleVZhbHVlPiBzZXQpIHsKKyAgICBib29sZWFuIGhhc0Vub3VnaCA9IGZhbHNlOworICAgIGlmIChrdi5pc0RlbGV0ZVR5cGUoKSkgeworICAgICAgaWYgKCFkZWxldGVzLmNvbnRhaW5zKGt2KSkgeworICAgICAgICBkZWxldGVzLmFkZChrdik7CisgICAgICB9CisgICAgfSBlbHNlIGlmICghZGVsZXRlcy5jb250YWlucyhrdikpIHsKKyAgICAgIC8vIFNraXAgZXhwaXJlZCBjZWxscworICAgICAgaWYgKCFpc0V4cGlyZWQoa3YsIHR0bCwgbm93KSkgeworICAgICAgICBpZiAoSFJlZ2lvbi5va1RvQWRkUmVzdWx0KGt2LCB2ZXJzaW9ucywgdmVyc2lvbkNvdW50ZXIpKSB7CisgICAgICAgICAgSFJlZ2lvbi5hZGRSZXN1bHQoa3YsIHZlcnNpb25Db3VudGVyLCBrZXl2YWx1ZXMpOworICAgICAgICAgIGlmIChIUmVnaW9uLmhhc0Vub3VnaFZlcnNpb25zKHZlcnNpb25zLCB2ZXJzaW9uQ291bnRlciwgY29sdW1ucykpIHsKKyAgICAgICAgICAgIGhhc0Vub3VnaCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBSZW1vdmUgdGhlIGV4cGlyZWQuCisgICAgICAgIFN0b3JlLmV4cGlyZWRPckRlbGV0ZWQoc2V0LCBrdik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBoYXNFbm91Z2g7CisgIH0KKworICAvKgorICAgKiBVc2VkIHdoZW4gZG9pbmcgZ2V0LgorICAgKiBAcGFyYW0ga3YKKyAgICogQHBhcmFtIHZlcnNpb25zCisgICAqIEBwYXJhbSBkZWxldGVzCisgICAqIEBwYXJhbSBub3cKKyAgICogQHBhcmFtIHR0bAorICAgKiBAcGFyYW0ga2V5dmFsdWVzCisgICAqIEBwYXJhbSBzZXQKKyAgICogQHJldHVybiBUcnVlIGlmIGVub3VnaCB2ZXJzaW9ucy4KKyAgICovCisgIHN0YXRpYyBib29sZWFuIGRvS2V5VmFsdWUoZmluYWwgS2V5VmFsdWUga3YsIGZpbmFsIGludCB2ZXJzaW9ucywKKyAgICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywKKyAgICAgIGZpbmFsIGxvbmcgbm93LCAgZmluYWwgbG9uZyB0dGwsCisgICAgICBmaW5hbCBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMsIGZpbmFsIFNvcnRlZFNldDxLZXlWYWx1ZT4gc2V0KSB7CisgICAgYm9vbGVhbiBoYXNFbm91Z2ggPSBmYWxzZTsKKyAgICBpZiAoIWt2LmlzRGVsZXRlVHlwZSgpKSB7CisgICAgICAvLyBGaWx0ZXIgb3V0IGV4cGlyZWQgcmVzdWx0cworICAgICAgaWYgKG5vdEV4cGlyZWRBbmROb3RJbkRlbGV0ZXModHRsLCBrdiwgbm93LCBkZWxldGVzKSkgeworICAgICAgICBpZiAoIWtleXZhbHVlcy5jb250YWlucyhrdikpIHsKKyAgICAgICAgICBrZXl2YWx1ZXMuYWRkKGt2KTsKKyAgICAgICAgICBpZiAoaGFzRW5vdWdoVmVyc2lvbnModmVyc2lvbnMsIGtleXZhbHVlcykpIHsKKyAgICAgICAgICAgIGhhc0Vub3VnaCA9IHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoc2V0ICE9IG51bGwpIHsKKyAgICAgICAgICBleHBpcmVkT3JEZWxldGVkKHNldCwga3YpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIENlbGwgaG9sZHMgYSBkZWxldGUgdmFsdWUuCisgICAgICBkZWxldGVzLmFkZChrdik7CisgICAgfQorICAgIHJldHVybiBoYXNFbm91Z2g7CisgIH0KKworICAvKgorICAgKiBUZXN0IHRoYXQgdGhlIDxpPnRhcmdldDwvaT4gbWF0Y2hlcyB0aGUgPGk+b3JpZ2luPC9pPi4gSWYgdGhlIDxpPm9yaWdpbjwvaT4KKyAgICogaGFzIGFuIGVtcHR5IGNvbHVtbiwgdGhlbiBpdCBqdXN0IHRlc3RzIHJvdyBlcXVpdmFsZW5jZS4gT3RoZXJ3aXNlLCBpdCB1c2VzCisgICAqIEhTdG9yZUtleS5tYXRjaGVzUm93Q29sKCkuCisgICAqIEBwYXJhbSBjIENvbXBhcmF0b3IgdG8gdXNlLgorICAgKiBAcGFyYW0gb3JpZ2luIEtleSB3ZSdyZSB0ZXN0aW5nIGFnYWluc3QKKyAgICogQHBhcmFtIHRhcmdldCBLZXkgd2UncmUgdGVzdGluZworICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gbWF0Y2hpbmdSb3dDb2x1bW4oZmluYWwgS2V5VmFsdWUuS1ZDb21wYXJhdG9yIGMsCisgICAgICBmaW5hbCBLZXlWYWx1ZSBvcmlnaW4sIGZpbmFsIEtleVZhbHVlIHRhcmdldCkgeworICAgIHJldHVybiBvcmlnaW4uaXNFbXB0eUNvbHVtbigpPyBjLm1hdGNoaW5nUm93cyh0YXJnZXQsIG9yaWdpbik6CisgICAgICBjLm1hdGNoaW5nUm93Q29sdW1uKHRhcmdldCwgb3JpZ2luKTsKKyAgfQorCisgIHN0YXRpYyB2b2lkIGV4cGlyZWRPckRlbGV0ZWQoZmluYWwgU2V0PEtleVZhbHVlPiBzZXQsIGZpbmFsIEtleVZhbHVlIGt2KSB7CisgICAgYm9vbGVhbiBiID0gc2V0LnJlbW92ZShrdik7CisgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICBMT0cuZGVidWcoa3YudG9TdHJpbmcoKSArICIgZXhwaXJlZDogIiArIGIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBGaW5kIHRoZSBrZXkgdGhhdCBtYXRjaGVzIDxpPnJvdzwvaT4gZXhhY3RseSwgb3IgdGhlIG9uZSB0aGF0IGltbWVkaWF0ZWx5CisgICAqIHByZWNlZWRzIGl0LiBXQVJOSU5HOiBPbmx5IHVzZSB0aGlzIG1ldGhvZCBvbiBhIHRhYmxlIHdoZXJlIHdyaXRlcyBvY2N1ciAKKyAgICogd2l0aCBzdHJpY2x5IGluY3JlYXNpbmcgdGltZXN0YW1wcy4gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGlzIHBhdHRlcm4gb2YgCisgICAqIHdyaXRlcyBpbiBvcmRlciB0byBtYWtlIGl0IHJlYXNvbmFibHkgcGVyZm9ybWFudC4KKyAgICogQHBhcmFtIHRhcmdldGtleQorICAgKiBAcmV0dXJuIEZvdW5kIGtleXZhbHVlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIEtleVZhbHVlIGdldFJvd0tleUF0T3JCZWZvcmUoZmluYWwgS2V5VmFsdWUgdGFyZ2V0a2V5KQorICB0aHJvd3MgSU9FeGNlcHRpb257CisgICAgLy8gTWFwIG9mIGtleXMgdGhhdCBhcmUgY2FuZGlkYXRlcyBmb3IgaG9sZGluZyB0aGUgcm93IGtleSB0aGF0CisgICAgLy8gbW9zdCBjbG9zZWx5IG1hdGNoZXMgd2hhdCB3ZSdyZSBsb29raW5nIGZvci4gV2UnbGwgaGF2ZSB0byB1cGRhdGUgaXQgYXMKKyAgICAvLyBkZWxldGVzIGFyZSBmb3VuZCBhbGwgb3ZlciB0aGUgcGxhY2UgYXMgd2UgZ28gYWxvbmcgYmVmb3JlIGZpbmFsbHkKKyAgICAvLyByZWFkaW5nIHRoZSBiZXN0IGtleSBvdXQgb2YgaXQgYXQgdGhlIGVuZC4gICBVc2UgYSBjb21wYXJhdG9yIHRoYXQKKyAgICAvLyBpZ25vcmVzIGtleSB0eXBlcy4gIE90aGVyd2lzZSwgd2UgY2FuJ3QgcmVtb3ZlIGRlbGV0ZWQgaXRlbXMgZG9pbmcKKyAgICAvLyBzZXQucmVtb3ZlIGJlY2F1c2Ugb2YgdGhlIGRpZmZlcmluZyB0eXBlIGJldHdlZW4gaW5zZXJ0IGFuZCBkZWxldGUuCisgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBjYW5kaWRhdGVzID0KKyAgICAgIG5ldyBUcmVlU2V0PEtleVZhbHVlPih0aGlzLmNvbXBhcmF0b3IuZ2V0Q29tcGFyYXRvcklnbm9yaW5nVHlwZSgpKTsKKworICAgIC8vIEtlZXAgYSBsaXN0IG9mIGRlbGV0ZWQgY2VsbCBrZXlzLiAgV2UgbmVlZCB0aGlzIGJlY2F1c2UgYXMgd2UgZ28gdGhyb3VnaAorICAgIC8vIHRoZSBzdG9yZSBmaWxlcywgdGhlIGNlbGwgd2l0aCB0aGUgZGVsZXRlIG1hcmtlciBtYXkgYmUgaW4gb25lIGZpbGUgYW5kCisgICAgLy8gdGhlIG9sZCBub24tZGVsZXRlIGNlbGwgdmFsdWUgaW4gYSBsYXRlciBzdG9yZSBmaWxlLiBJZiB3ZSBkb24ndCBrZWVwCisgICAgLy8gYXJvdW5kIHRoZSBmYWN0IHRoYXQgdGhlIGNlbGwgd2FzIGRlbGV0ZWQgaW4gYSBuZXdlciByZWNvcmQsIHdlIGVuZCB1cAorICAgIC8vIHJldHVybmluZyB0aGUgb2xkIHZhbHVlIGlmIHVzZXIgaXMgYXNraW5nIGZvciBtb3JlIHRoYW4gb25lIHZlcnNpb24uCisgICAgLy8gVGhpcyBMaXN0IG9mIGRlbGV0ZXMgc2hvdWxkIG5vdCBiZSBsYXJnZSBzaW5jZSB3ZSBhcmUgb25seSBrZWVwaW5nIHJvd3MKKyAgICAvLyBhbmQgY29sdW1ucyB0aGF0IG1hdGNoIHRob3NlIHNldCBvbiB0aGUgc2Nhbm5lciBhbmQgd2hpY2ggaGF2ZSBkZWxldGUKKyAgICAvLyB2YWx1ZXMuICBJZiBtZW1vcnkgdXNhZ2UgYmVjb21lcyBhbiBpc3N1ZSwgY291bGQgcmVkbyBhcyBibG9vbSBmaWx0ZXIuCisgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBkZWxldGVzID0KKyAgICAgIG5ldyBUcmVlU2V0PEtleVZhbHVlPih0aGlzLmNvbXBhcmF0b3JJZ25vcmluZ1R5cGUpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICAvLyBGaXJzdCBnbyB0byB0aGUgbWVtY2FjaGUuICBQaWNrIHVwIGRlbGV0ZXMgYW5kIGNhbmRpZGF0ZXMuCisgICAgICB0aGlzLm1lbWNhY2hlLmdldFJvd0tleUF0T3JCZWZvcmUodGFyZ2V0a2V5LCBjYW5kaWRhdGVzLCBkZWxldGVzLCBub3cpOworICAgICAgLy8gUHJvY2VzcyBlYWNoIHN0b3JlIGZpbGUuICBSdW4gdGhyb3VnaCBmcm9tIG5ld2VzdCB0byBvbGRlc3QuCisgICAgICBNYXA8TG9uZywgU3RvcmVGaWxlPiBtID0gdGhpcy5zdG9yZWZpbGVzLmRlc2NlbmRpbmdNYXAoKTsKKyAgICAgIGZvciAoTWFwLkVudHJ5PExvbmcsIFN0b3JlRmlsZT4gZTogbS5lbnRyeVNldCgpKSB7CisgICAgICAgIC8vIFVwZGF0ZSB0aGUgY2FuZGlkYXRlIGtleXMgZnJvbSB0aGUgY3VycmVudCBtYXAgZmlsZQorICAgICAgICByb3dBdE9yQmVmb3JlRnJvbVN0b3JlRmlsZShlLmdldFZhbHVlKCksIHRhcmdldGtleSwgY2FuZGlkYXRlcywKKyAgICAgICAgICBkZWxldGVzLCBub3cpOworICAgICAgfQorICAgICAgLy8gUmV0dXJuIHRoZSBiZXN0IGtleSBmcm9tIGNhbmRpZGF0ZUtleXMKKyAgICAgIHJldHVybiBjYW5kaWRhdGVzLmlzRW1wdHkoKT8gbnVsbDogY2FuZGlkYXRlcy5sYXN0KCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIENoZWNrIGFuIGluZGl2aWR1YWwgTWFwRmlsZSBmb3IgdGhlIHJvdyBhdCBvciBiZWZvcmUgYSBnaXZlbiBrZXkgCisgICAqIGFuZCB0aW1lc3RhbXAKKyAgICogQHBhcmFtIGYKKyAgICogQHBhcmFtIHRhcmdldGtleQorICAgKiBAcGFyYW0gY2FuZGlkYXRlcyBQYXNzIGEgU2V0IHdpdGggYSBDb21wYXJhdG9yIHRoYXQKKyAgICogaWdub3JlcyBrZXkgVHlwZSBzbyB3ZSBjYW4gZG8gU2V0LnJlbW92ZSB1c2luZyBhIGRlbGV0ZSwgaS5lLiBhIEtleVZhbHVlCisgICAqIHdpdGggYSBkaWZmZXJlbnQgVHlwZSB0byB0aGUgY2FuZGlkYXRlIGtleS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJvd0F0T3JCZWZvcmVGcm9tU3RvcmVGaWxlKGZpbmFsIFN0b3JlRmlsZSBmLAorICAgIGZpbmFsIEtleVZhbHVlIHRhcmdldGtleSwgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBjYW5kaWRhdGVzLAorICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywgZmluYWwgbG9uZyBub3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gaWYgdGhlcmUgYXJlbid0IGFueSBjYW5kaWRhdGUga2V5cyB5ZXQsIHdlJ2xsIGRvIHNvbWUgdGhpbmdzIGRpZmZlcmVudCAKKyAgICBpZiAoY2FuZGlkYXRlcy5pc0VtcHR5KCkpIHsKKyAgICAgIHJvd0F0T3JCZWZvcmVDYW5kaWRhdGUoZiwgdGFyZ2V0a2V5LCBjYW5kaWRhdGVzLCBkZWxldGVzLCBub3cpOworICAgIH0gZWxzZSB7CisgICAgICByb3dBdE9yQmVmb3JlV2l0aENhbmRpZGF0ZXMoZiwgdGFyZ2V0a2V5LCBjYW5kaWRhdGVzLCBkZWxldGVzLCBub3cpOworICAgIH0KKyAgfQorCisgIC8qIAorICAgKiBAcGFyYW0gdHRsU2V0dGluZworICAgKiBAcGFyYW0gaHNrCisgICAqIEBwYXJhbSBub3cKKyAgICogQHBhcmFtIGRlbGV0ZXMgQSBTZXQgd2hvc2UgQ29tcGFyYXRvciBpZ25vcmVzIFR5cGUuCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBrZXkgaGFzIG5vdCBleHBpcmVkIGFuZCBpcyBub3QgaW4gcGFzc2VkIHNldCBvZiBkZWxldGVzLgorICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gbm90RXhwaXJlZEFuZE5vdEluRGVsZXRlcyhmaW5hbCBsb25nIHR0bCwKKyAgICAgIGZpbmFsIEtleVZhbHVlIGtleSwgZmluYWwgbG9uZyBub3csIGZpbmFsIFNldDxLZXlWYWx1ZT4gZGVsZXRlcykgeworICAgIHJldHVybiAhaXNFeHBpcmVkKGtleSwgdHRsLCBub3cpICYmIChkZWxldGVzID09IG51bGwgfHwgZGVsZXRlcy5pc0VtcHR5KCkgfHwKKyAgICAgICAgIWRlbGV0ZXMuY29udGFpbnMoa2V5KSk7CisgIH0KKworICBzdGF0aWMgYm9vbGVhbiBpc0V4cGlyZWQoZmluYWwgS2V5VmFsdWUga2V5LCBmaW5hbCBsb25nIHR0bCwKKyAgICAgIGZpbmFsIGxvbmcgbm93KSB7CisgICAgcmV0dXJuIHR0bCAhPSBIQ29uc3RhbnRzLkZPUkVWRVIgJiYgbm93ID4ga2V5LmdldFRpbWVzdGFtcCgpICsgdHRsOworICB9CisKKyAgLyogRmluZCBhIGNhbmRpZGF0ZSBmb3Igcm93IHRoYXQgaXMgYXQgb3IgYmVmb3JlIHBhc3NlZCBrZXksIHNlYXJjaGtleSwgaW4gaGZpbGUuCisgICAqIEBwYXJhbSBmCisgICAqIEBwYXJhbSB0YXJnZXRrZXkgS2V5IHRvIGdvIHNlYXJjaCB0aGUgaGZpbGUgd2l0aC4KKyAgICogQHBhcmFtIGNhbmRpZGF0ZXMKKyAgICogQHBhcmFtIG5vdworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEBzZWUge0BsaW5rICNyb3dBdE9yQmVmb3JlQ2FuZGlkYXRlKEhTdG9yZUtleSwgb3JnLmFwYWNoZS5oYWRvb3AuaW8uTWFwRmlsZS5SZWFkZXIsIGJ5dGVbXSwgU29ydGVkTWFwLCBsb25nKX0KKyAgICovCisgIHByaXZhdGUgdm9pZCByb3dBdE9yQmVmb3JlQ2FuZGlkYXRlKGZpbmFsIFN0b3JlRmlsZSBmLAorICAgIGZpbmFsIEtleVZhbHVlIHRhcmdldGtleSwgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBjYW5kaWRhdGVzLAorICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gZGVsZXRlcywgZmluYWwgbG9uZyBub3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgS2V5VmFsdWUgc2VhcmNoID0gdGFyZ2V0a2V5OworICAgIC8vIElmIHRoZSByb3cgd2UncmUgbG9va2luZyBmb3IgaXMgcGFzdCB0aGUgZW5kIG9mIHRoaXMgbWFwZmlsZSwgc2V0IHRoZQorICAgIC8vIHNlYXJjaCBrZXkgdG8gYmUgdGhlIGxhc3Qga2V5LiAgSWYgaXRzIGEgZGVsZXRlZCBrZXksIHRoZW4gd2UnbGwgYmFjaworICAgIC8vIHVwIHRvIHRoZSByb3cgYmVmb3JlIGFuZCByZXR1cm4gdGhhdC4KKyAgICAvLyBUT0RPOiBDYWNoZSBsYXN0IGtleSBhcyBLViBvdmVyIGluIHRoZSBmaWxlLgorICAgIGJ5dGUgW10gbGFzdGtleSA9IGYuZ2V0UmVhZGVyKCkuZ2V0TGFzdEtleSgpOworICAgIEtleVZhbHVlIGxhc3RLZXlWYWx1ZSA9CisgICAgICBLZXlWYWx1ZS5jcmVhdGVLZXlWYWx1ZUZyb21LZXkobGFzdGtleSwgMCwgbGFzdGtleS5sZW5ndGgpOworICAgIGlmICh0aGlzLmNvbXBhcmF0b3IuY29tcGFyZVJvd3MobGFzdEtleVZhbHVlLCB0YXJnZXRrZXkpIDwgMCkgeworICAgICAgc2VhcmNoID0gbGFzdEtleVZhbHVlOworICAgIH0KKyAgICBLZXlWYWx1ZSBrbm93bk5vR29vZEtleSA9IG51bGw7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSBmLmdldFJlYWRlcigpLmdldFNjYW5uZXIoKTsKKyAgICBmb3IgKGJvb2xlYW4gZm91bmRDYW5kaWRhdGUgPSBmYWxzZTsgIWZvdW5kQ2FuZGlkYXRlOykgeworICAgICAgLy8gU2VlayB0byB0aGUgZXhhY3Qgcm93LCBvciB0aGUgb25lIHRoYXQgd291bGQgYmUgaW1tZWRpYXRlbHkgYmVmb3JlIGl0CisgICAgICBpbnQgcmVzdWx0ID0gc2Nhbm5lci5zZWVrVG8oc2VhcmNoLmdldEJ1ZmZlcigpLCBzZWFyY2guZ2V0S2V5T2Zmc2V0KCksCisgICAgICAgIHNlYXJjaC5nZXRLZXlMZW5ndGgoKSk7CisgICAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgICAvLyBOb3QgaW4gZmlsZS4KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBLZXlWYWx1ZSBkZWxldGVkT3JFeHBpcmVkUm93ID0gbnVsbDsKKyAgICAgIEtleVZhbHVlIGt2ID0gbnVsbDsKKyAgICAgIGRvIHsKKyAgICAgICAga3YgPSBzY2FubmVyLmdldEtleVZhbHVlKCk7CisgICAgICAgIGlmICh0aGlzLmNvbXBhcmF0b3IuY29tcGFyZVJvd3Moa3YsIHNlYXJjaCkgPD0gMCkgeworICAgICAgICAgIGlmICgha3YuaXNEZWxldGVUeXBlKCkpIHsKKyAgICAgICAgICAgIGlmIChoYW5kbGVOb25EZWxldGUoa3YsIG5vdywgZGVsZXRlcywgY2FuZGlkYXRlcykpIHsKKyAgICAgICAgICAgICAgZm91bmRDYW5kaWRhdGUgPSB0cnVlOworICAgICAgICAgICAgICAvLyBOT1RFISBDb250aW51ZS4KKyAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGRlbGV0ZXMuYWRkKGt2KTsKKyAgICAgICAgICBpZiAoZGVsZXRlZE9yRXhwaXJlZFJvdyA9PSBudWxsKSB7CisgICAgICAgICAgICBkZWxldGVkT3JFeHBpcmVkUm93ID0ga3Y7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY29tcGFyYXRvci5jb21wYXJlUm93cyhrdiwgc2VhcmNoKSA+IDApIHsKKyAgICAgICAgICAvLyBpZiB0aGUgcm93IGtleSB3ZSBqdXN0IHJlYWQgaXMgYmV5b25kIHRoZSBrZXkgd2UncmUgc2VhcmNoaW5nIGZvciwKKyAgICAgICAgICAvLyB0aGVuIHdlJ3JlIGRvbmUuCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgLy8gU28sIHRoZSByb3cga2V5IGRvZXNuJ3QgbWF0Y2gsIGJ1dCB3ZSBoYXZlbid0IGdvbmUgcGFzdCB0aGUgcm93CisgICAgICAgICAgLy8gd2UncmUgc2Vla2luZyB5ZXQsIHNvIHRoaXMgcm93IGlzIGEgY2FuZGlkYXRlIGZvciBjbG9zZXN0CisgICAgICAgICAgLy8gKGFzc3VtaW5nIHRoYXQgaXQgaXNuJ3QgYSBkZWxldGUpLgorICAgICAgICAgIGlmICgha3YuaXNEZWxldGVUeXBlKCkpIHsKKyAgICAgICAgICAgIGlmIChoYW5kbGVOb25EZWxldGUoa3YsIG5vdywgZGVsZXRlcywgY2FuZGlkYXRlcykpIHsKKyAgICAgICAgICAgICAgZm91bmRDYW5kaWRhdGUgPSB0cnVlOworICAgICAgICAgICAgICAvLyBOT1RFOiBDb250aW51ZQorICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZGVsZXRlcy5hZGQoa3YpOworICAgICAgICAgIGlmIChkZWxldGVkT3JFeHBpcmVkUm93ID09IG51bGwpIHsKKyAgICAgICAgICAgIGRlbGV0ZWRPckV4cGlyZWRSb3cgPSBrdjsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gd2hpbGUoc2Nhbm5lci5uZXh0KCkgJiYgKGtub3duTm9Hb29kS2V5ID09IG51bGwgfHwKKyAgICAgICAgICB0aGlzLmNvbXBhcmF0b3IuY29tcGFyZShrdiwga25vd25Ob0dvb2RLZXkpIDwgMCkpOworCisgICAgICAvLyBJZiB3ZSBnZXQgaGVyZSBhbmQgaGF2ZSBubyBjYW5kaWRhdGVzIGJ1dCB3ZSBkaWQgZmluZCBhIGRlbGV0ZWQgb3IKKyAgICAgIC8vIGV4cGlyZWQgY2FuZGlkYXRlLCB3ZSBuZWVkIHRvIGxvb2sgYXQgdGhlIGtleSBiZWZvcmUgdGhhdAorICAgICAgaWYgKCFmb3VuZENhbmRpZGF0ZSAmJiBkZWxldGVkT3JFeHBpcmVkUm93ICE9IG51bGwpIHsKKyAgICAgICAga25vd25Ob0dvb2RLZXkgPSBkZWxldGVkT3JFeHBpcmVkUm93OworICAgICAgICBpZiAoIXNjYW5uZXIuc2Vla0JlZm9yZShkZWxldGVkT3JFeHBpcmVkUm93LmdldEJ1ZmZlcigpLAorICAgICAgICAgICAgZGVsZXRlZE9yRXhwaXJlZFJvdy5nZXRLZXlPZmZzZXQoKSwKKyAgICAgICAgICAgIGRlbGV0ZWRPckV4cGlyZWRSb3cuZ2V0S2V5TGVuZ3RoKCkpKSB7CisgICAgICAgICAgLy8gTm90IGluIGZpbGUgLS0gd2hhdCBjYW4gSSBkbyBub3cgYnV0IGJyZWFrPworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHNlYXJjaCA9IHNjYW5uZXIuZ2V0S2V5VmFsdWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE5vIGNhbmRpZGF0ZXMgYW5kIG5vIGRlbGV0ZWQgb3IgZXhwaXJlZCBjYW5kaWRhdGVzLiBHaXZlIHVwLgorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLy8gQXJyaXZpbmcgaGVyZSBqdXN0IG1lYW5zIHRoYXQgd2UgY29uc3VtZWQgdGhlIHdob2xlIHJlc3Qgb2YgdGhlIG1hcAorICAgIC8vIHdpdGhvdXQgZ29pbmcgInBhc3QiIHRoZSBrZXkgd2UncmUgc2VhcmNoaW5nIGZvci4gd2UgY2FuIGp1c3QgZmFsbAorICAgIC8vIHRocm91Z2ggaGVyZS4KKyAgfQorCisgIHByaXZhdGUgdm9pZCByb3dBdE9yQmVmb3JlV2l0aENhbmRpZGF0ZXMoZmluYWwgU3RvcmVGaWxlIGYsCisgICAgZmluYWwgS2V5VmFsdWUgdGFyZ2V0a2V5LAorICAgIGZpbmFsIE5hdmlnYWJsZVNldDxLZXlWYWx1ZT4gY2FuZGlkYXRlcywKKyAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsIGZpbmFsIGxvbmcgbm93KSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBpZiB0aGVyZSBhcmUgYWxyZWFkeSBjYW5kaWRhdGUga2V5cywgd2UgbmVlZCB0byBzdGFydCBvdXIgc2VhcmNoIAorICAgIC8vIGF0IHRoZSBlYXJsaWVzdCBwb3NzaWJsZSBrZXkgc28gdGhhdCB3ZSBjYW4gZGlzY292ZXIgYW55IHBvc3NpYmxlCisgICAgLy8gZGVsZXRlcyBmb3Iga2V5cyBiZXR3ZWVuIHRoZSBzdGFydCBhbmQgdGhlIHNlYXJjaCBrZXkuICBCYWNrIHVwIHRvIHN0YXJ0CisgICAgLy8gb2YgdGhlIHJvdyBpbiBjYXNlIHRoZXJlIGFyZSBkZWxldGVzIGZvciB0aGlzIGNhbmRpZGF0ZSBpbiB0aGlzIG1hcGZpbGUKKyAgICAvLyBCVVQgZG8gbm90IGJhY2t1cCBiZWZvcmUgdGhlIGZpcnN0IGtleSBpbiB0aGUgc3RvcmUgZmlsZS4KKyAgICBLZXlWYWx1ZSBmaXJzdENhbmRpZGF0ZUtleSA9IGNhbmRpZGF0ZXMuZmlyc3QoKTsKKyAgICBLZXlWYWx1ZSBzZWFyY2ggPSBudWxsOworICAgIGlmICh0aGlzLmNvbXBhcmF0b3IuY29tcGFyZVJvd3MoZmlyc3RDYW5kaWRhdGVLZXksIHRhcmdldGtleSkgPCAwKSB7CisgICAgICBzZWFyY2ggPSB0YXJnZXRrZXk7CisgICAgfSBlbHNlIHsKKyAgICAgIHNlYXJjaCA9IGZpcnN0Q2FuZGlkYXRlS2V5OworICAgIH0KKworICAgIC8vIFNlZWsgdG8gdGhlIGV4YWN0IHJvdywgb3IgdGhlIG9uZSB0aGF0IHdvdWxkIGJlIGltbWVkaWF0ZWx5IGJlZm9yZSBpdAorICAgIEhGaWxlU2Nhbm5lciBzY2FubmVyID0gZi5nZXRSZWFkZXIoKS5nZXRTY2FubmVyKCk7CisgICAgaW50IHJlc3VsdCA9IHNjYW5uZXIuc2Vla1RvKHNlYXJjaC5nZXRCdWZmZXIoKSwgc2VhcmNoLmdldEtleU9mZnNldCgpLAorICAgICAgc2VhcmNoLmdldEtleUxlbmd0aCgpKTsKKyAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgLy8gS2V5IGlzIGJlZm9yZSBzdGFydCBvZiB0aGlzIGZpbGUuICBSZXR1cm4uCisgICAgICByZXR1cm47CisgICAgfQorICAgIGRvIHsKKyAgICAgIEtleVZhbHVlIGt2ID0gc2Nhbm5lci5nZXRLZXlWYWx1ZSgpOworICAgICAgLy8gaWYgd2UgaGF2ZSBhbiBleGFjdCBtYXRjaCBvbiByb3csIGFuZCBpdCdzIG5vdCBhIGRlbGV0ZSwgc2F2ZSB0aGlzCisgICAgICAvLyBhcyBhIGNhbmRpZGF0ZSBrZXkKKyAgICAgIGlmICh0aGlzLmNvbXBhcmF0b3IubWF0Y2hpbmdSb3dzKGt2LCB0YXJnZXRrZXkpKSB7CisgICAgICAgIGhhbmRsZUtleShrdiwgbm93LCBkZWxldGVzLCBjYW5kaWRhdGVzKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKGt2LCB0YXJnZXRrZXkpID4gMCApIHsKKyAgICAgICAgLy8gaWYgdGhlIHJvdyBrZXkgd2UganVzdCByZWFkIGlzIGJleW9uZCB0aGUga2V5IHdlJ3JlIHNlYXJjaGluZyBmb3IsCisgICAgICAgIC8vIHRoZW4gd2UncmUgZG9uZS4KKyAgICAgICAgYnJlYWs7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBTbywgdGhlIHJvdyBrZXkgZG9lc24ndCBtYXRjaCwgYnV0IHdlIGhhdmVuJ3QgZ29uZSBwYXN0IHRoZSByb3cKKyAgICAgICAgLy8gd2UncmUgc2Vla2luZyB5ZXQsIHNvIHRoaXMgcm93IGlzIGEgY2FuZGlkYXRlIGZvciBjbG9zZXN0IAorICAgICAgICAvLyAoYXNzdW1pbmcgdGhhdCBpdCBpc24ndCBhIGRlbGV0ZSkuCisgICAgICAgIGhhbmRsZUtleShrdiwgbm93LCBkZWxldGVzLCBjYW5kaWRhdGVzKTsKKyAgICAgIH0KKyAgICB9IHdoaWxlKHNjYW5uZXIubmV4dCgpKTsKKyAgfQorCisgIC8qCisgICAqIFVzZWQgY2FsY3VsYXRpbmcga2V5cyBhdCBvciBqdXN0IGJlZm9yZSBhIHBhc3NlZCBrZXkuCisgICAqIEBwYXJhbSByZWFka2V5CisgICAqIEBwYXJhbSBub3cKKyAgICogQHBhcmFtIGRlbGV0ZXMgU2V0IHdpdGggQ29tcGFyYXRvciB0aGF0IGlnbm9yZXMga2V5IHR5cGUuCisgICAqIEBwYXJhbSBjYW5kaWRhdGUgU2V0IHdpdGggQ29tcHJhdG9yIHRoYXQgaWdub3JlcyBrZXkgdHlwZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBoYW5kbGVLZXkoZmluYWwgS2V5VmFsdWUgcmVhZGtleSwgZmluYWwgbG9uZyBub3csCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMsCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGNhbmRpZGF0ZXMpIHsKKyAgICBpZiAoIXJlYWRrZXkuaXNEZWxldGVUeXBlKCkpIHsKKyAgICAgIGhhbmRsZU5vbkRlbGV0ZShyZWFka2V5LCBub3csIGRlbGV0ZXMsIGNhbmRpZGF0ZXMpOworICAgIH0gZWxzZSB7CisgICAgICBoYW5kbGVEZWxldGVzKHJlYWRrZXksIGNhbmRpZGF0ZXMsIGRlbGV0ZXMpOworICAgIH0KKyAgfQorCisgIC8qCisgICAqIFVzZWQgY2FsY3VsYXRpbmcga2V5cyBhdCBvciBqdXN0IGJlZm9yZSBhIHBhc3NlZCBrZXkuCisgICAqIEBwYXJhbSByZWFka2V5CisgICAqIEBwYXJhbSBub3cKKyAgICogQHBhcmFtIGRlbGV0ZXMgU2V0IHdpdGggQ29tcGFyYXRvciB0aGF0IGlnbm9yZXMga2V5IHR5cGUuCisgICAqIEBwYXJhbSBjYW5kaWRhdGVzIFNldCB3aXRoIENvbXBhcmF0b3IgdGhhdCBpZ25vcmVzIGtleSB0eXBlLgorICAgKiBAcmV0dXJuIFRydWUgaWYgd2UgYWRkZWQgYSBjYW5kaWRhdGUuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gaGFuZGxlTm9uRGVsZXRlKGZpbmFsIEtleVZhbHVlIHJlYWRrZXksIGZpbmFsIGxvbmcgbm93LAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBkZWxldGVzLAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBjYW5kaWRhdGVzKSB7CisgICAgaWYgKG5vdEV4cGlyZWRBbmROb3RJbkRlbGV0ZXModGhpcy50dGwsIHJlYWRrZXksIG5vdywgZGVsZXRlcykpIHsKKyAgICAgIGNhbmRpZGF0ZXMuYWRkKHJlYWRrZXkpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBIYW5kbGUga2V5cyB3aG9zZSB2YWx1ZXMgaG9sZCBkZWxldGVzLgorICAgKiBBZGQgdG8gdGhlIHNldCBvZiBkZWxldGVzIGFuZCB0aGVuIGlmIHRoZSBjYW5kaWRhdGUga2V5cyBjb250YWluIGFueSB0aGF0CisgICAqIG1pZ2h0IG1hdGNoLCB0aGVuIGNoZWNrIGZvciBhIG1hdGNoIGFuZCByZW1vdmUgaXQuICBJbXBsaWVzIGNhbmRpZGF0ZXMKKyAgICogaXMgbWFkZSB3aXRoIGEgQ29tcGFyYXRvciB0aGF0IGlnbm9yZXMga2V5IHR5cGUuCisgICAqIEBwYXJhbSBrCisgICAqIEBwYXJhbSBjYW5kaWRhdGVzCisgICAqIEBwYXJhbSBkZWxldGVzCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB3ZSByZW1vdmVkIDxjb2RlPms8L2NvZGU+IGZyb20gPGNvZGU+Y2FuZGlkYXRlczwvY29kZT4uCisgICAqLworICBzdGF0aWMgYm9vbGVhbiBoYW5kbGVEZWxldGVzKGZpbmFsIEtleVZhbHVlIGssCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGNhbmRpZGF0ZXMsCisgICAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMpIHsKKyAgICBkZWxldGVzLmFkZChrKTsKKyAgICByZXR1cm4gY2FuZGlkYXRlcy5yZW1vdmUoayk7CisgIH0KKworICAvKioKKyAgICogRGV0ZXJtaW5lcyBpZiBIU3RvcmUgY2FuIGJlIHNwbGl0CisgICAqIEBwYXJhbSBmb3JjZSBXaGV0aGVyIHRvIGZvcmNlIGEgc3BsaXQgb3Igbm90LgorICAgKiBAcmV0dXJuIGEgU3RvcmVTaXplIGlmIHN0b3JlIGNhbiBiZSBzcGxpdCwgbnVsbCBvdGhlcndpc2UuCisgICAqLworICBTdG9yZVNpemUgY2hlY2tTcGxpdChmaW5hbCBib29sZWFuIGZvcmNlKSB7CisgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIHN0b3JlIGZpbGVzCisgICAgICBpZiAodGhpcy5zdG9yZWZpbGVzLnNpemUoKSA8PSAwKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKCFmb3JjZSAmJiAoc3RvcmVTaXplIDwgdGhpcy5kZXNpcmVkTWF4RmlsZVNpemUpKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgLy8gTm90IHNwbGl0YWJsZSBpZiB3ZSBmaW5kIGEgcmVmZXJlbmNlIHN0b3JlIGZpbGUgcHJlc2VudCBpbiB0aGUgc3RvcmUuCisgICAgICBib29sZWFuIHNwbGl0YWJsZSA9IHRydWU7CisgICAgICBsb25nIG1heFNpemUgPSAwTDsKKyAgICAgIExvbmcgbWFwSW5kZXggPSBMb25nLnZhbHVlT2YoMEwpOworICAgICAgZm9yIChNYXAuRW50cnk8TG9uZywgU3RvcmVGaWxlPiBlOiBzdG9yZWZpbGVzLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgU3RvcmVGaWxlIHNmID0gZS5nZXRWYWx1ZSgpOworICAgICAgICBpZiAoc3BsaXRhYmxlKSB7CisgICAgICAgICAgc3BsaXRhYmxlID0gIXNmLmlzUmVmZXJlbmNlKCk7CisgICAgICAgICAgaWYgKCFzcGxpdGFibGUpIHsKKyAgICAgICAgICAgIC8vIFJFVFVSTiBJTiBNSURETEUgT0YgRlVOQ1RJT04hISEgSWYgbm90IHNwbGl0YWJsZSwganVzdCByZXR1cm4uCisgICAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgICAgTE9HLmRlYnVnKHNmICsgICIgaXMgbm90IHNwbGl0dGFibGUiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb25nIHNpemUgPSBzZi5nZXRSZWFkZXIoKS5sZW5ndGgoKTsKKyAgICAgICAgaWYgKHNpemUgPiBtYXhTaXplKSB7CisgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgbGFyZ2VzdCBvbmUgc28gZmFyCisgICAgICAgICAgbWF4U2l6ZSA9IHNpemU7CisgICAgICAgICAgbWFwSW5kZXggPSBlLmdldEtleSgpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIEhGaWxlLlJlYWRlciByID0gdGhpcy5zdG9yZWZpbGVzLmdldChtYXBJbmRleCkuZ2V0UmVhZGVyKCk7CisgICAgICAvLyBHZXQgZmlyc3QsIGxhc3QsIGFuZCBtaWQga2V5cy4gIE1pZGtleSBpcyB0aGUga2V5IHRoYXQgc3RhcnRzIGJsb2NrCisgICAgICAvLyBpbiBtaWRkbGUgb2YgaGZpbGUuICBIYXMgY29sdW1uIGFuZCB0aW1lc3RhbXAuICBOZWVkIHRvIHJldHVybiBqdXN0CisgICAgICAvLyB0aGUgcm93IHdlIHdhbnQgdG8gc3BsaXQgb24gYXMgbWlka2V5LgorICAgICAgYnl0ZSBbXSBtaWRrZXkgPSByLm1pZGtleSgpOworICAgICAgaWYgKG1pZGtleSAhPSBudWxsKSB7CisgICAgICAgIEtleVZhbHVlIG1rID0gS2V5VmFsdWUuY3JlYXRlS2V5VmFsdWVGcm9tS2V5KG1pZGtleSwgMCwgbWlka2V5Lmxlbmd0aCk7CisgICAgICAgIGJ5dGUgW10gZmsgPSByLmdldEZpcnN0S2V5KCk7CisgICAgICAgIEtleVZhbHVlIGZpcnN0S2V5ID0gS2V5VmFsdWUuY3JlYXRlS2V5VmFsdWVGcm9tS2V5KGZrLCAwLCBmay5sZW5ndGgpOworICAgICAgICBieXRlIFtdIGxrID0gci5nZXRMYXN0S2V5KCk7CisgICAgICAgIEtleVZhbHVlIGxhc3RLZXkgPSBLZXlWYWx1ZS5jcmVhdGVLZXlWYWx1ZUZyb21LZXkobGssIDAsIGxrLmxlbmd0aCk7CisgICAgICAgIC8vIGlmIHRoZSBtaWRrZXkgaXMgdGhlIHNhbWUgYXMgdGhlIGZpcnN0IGFuZCBsYXN0IGtleXMsIHRoZW4gd2UgY2Fubm90CisgICAgICAgIC8vIChldmVyKSBzcGxpdCB0aGlzIHJlZ2lvbi4gCisgICAgICAgIGlmICh0aGlzLmNvbXBhcmF0b3IuY29tcGFyZVJvd3MobWssIGZpcnN0S2V5KSA9PSAwICYmIAorICAgICAgICAgICAgdGhpcy5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKG1rLCBsYXN0S2V5KSA9PSAwKSB7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuZGVidWcoImNhbm5vdCBzcGxpdCBiZWNhdXNlIG1pZGtleSBpcyB0aGUgc2FtZSBhcyBmaXJzdCBvciAiICsKKyAgICAgICAgICAgICAgImxhc3Qgcm93Iik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBuZXcgU3RvcmVTaXplKG1heFNpemUsIG1rLmdldFJvdygpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgZ2V0dGluZyBzdG9yZSBzaXplIGZvciAiICsgdGhpcy5zdG9yZU5hbWVTdHIsIGUpOworICAgIH0gZmluYWxseSB7CisgICAgICB0aGlzLmxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgICAgcmV0dXJuIG51bGw7CisgIH0KKyAgCisgIC8qKiBAcmV0dXJuIGFnZ3JlZ2F0ZSBzaXplIG9mIEhTdG9yZSAqLworICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgIHJldHVybiBzdG9yZVNpemU7CisgIH0KKyAgCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAvLyBGaWxlIGFkbWluaXN0cmF0aW9uCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisgIC8qKgorICAgKiBSZXR1cm4gYSBzY2FubmVyIGZvciBib3RoIHRoZSBtZW1jYWNoZSBhbmQgdGhlIEhTdG9yZSBmaWxlcworICAgKi8KKyAgcHJvdGVjdGVkIEludGVybmFsU2Nhbm5lciBnZXRTY2FubmVyKGxvbmcgdGltZXN0YW1wLAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IHRhcmdldENvbHMsCisgICAgICBieXRlIFtdIGZpcnN0Um93LCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBuZXcgU3RvcmVTY2FubmVyKHRoaXMsIHRhcmdldENvbHMsIGZpcnN0Um93LCB0aW1lc3RhbXAsIGZpbHRlcik7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGxvY2sucmVhZExvY2soKS51bmxvY2soKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gdGhpcy5zdG9yZU5hbWVTdHI7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDb3VudCBvZiBzdG9yZSBmaWxlcworICAgKi8KKyAgaW50IGdldFN0b3JlZmlsZXNDb3VudCgpIHsKKyAgICByZXR1cm4gdGhpcy5zdG9yZWZpbGVzLnNpemUoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRoZSBzaXplIG9mIHRoZSBzdG9yZSBmaWxlIGluZGV4ZXMsIGluIGJ5dGVzLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIHdhcyBhIHByb2JsZW0gZ2V0dGluZyBmaWxlIHNpemVzIGZyb20gdGhlCisgICAqIGZpbGVzeXN0ZW0KKyAgICovCisgIGxvbmcgZ2V0U3RvcmVmaWxlc0luZGV4U2l6ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbG9uZyBzaXplID0gMDsKKyAgICBmb3IgKFN0b3JlRmlsZSBzOiBzdG9yZWZpbGVzLnZhbHVlcygpKQorICAgICAgc2l6ZSArPSBzLmdldFJlYWRlcigpLmluZGV4U2l6ZSgpOworICAgIHJldHVybiBzaXplOworICB9CisKKyAgLyoKKyAgICogRGF0YXN0cnVjdHVyZSB0aGF0IGhvbGRzIHNpemUgYW5kIHJvdyB0byBzcGxpdCBhIGZpbGUgYXJvdW5kLgorICAgKiBUT0RPOiBUYWtlIGEgS2V5VmFsdWUgcmF0aGVyIHRoYW4gcm93LgorICAgKi8KKyAgc3RhdGljIGNsYXNzIFN0b3JlU2l6ZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBsb25nIHNpemU7CisgICAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdIHJvdzsKKworICAgIFN0b3JlU2l6ZShsb25nIHNpemUsIGJ5dGUgW10gcm93KSB7CisgICAgICB0aGlzLnNpemUgPSBzaXplOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgfQorICAgIC8qIEByZXR1cm4gdGhlIHNpemUgKi8KKyAgICBsb25nIGdldFNpemUoKSB7CisgICAgICByZXR1cm4gc2l6ZTsKKyAgICB9CisKKyAgICBieXRlIFtdIGdldFNwbGl0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKyAgfQorCisgIEhSZWdpb25JbmZvIGdldEhSZWdpb25JbmZvKCkgeworICAgIHJldHVybiB0aGlzLnJlZ2lvbmluZm87CisgIH0KKworICAvKioKKyAgICogQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgaW1wbGVtZW50cyB0aGUgb2xkIE1hcEZpbGUuZ2V0Q2xvc2VzdCBvbiB0b3Agb2YKKyAgICogSEZpbGUgU2Nhbm5lcnMuICBnZXRDbG9zZXN0IHVzZWQgc2VlayB0byB0aGUgYXNrZWQtZm9yIGtleSBvciBqdXN0IGFmdGVyCisgICAqIChIRmlsZSBzZWVrcyB0byB0aGUga2V5IG9yIGp1c3QgYmVmb3JlKS4KKyAgICogQHBhcmFtIHMgU2Nhbm5lciB0byB1c2UKKyAgICogQHBhcmFtIGt2IEtleSB0byBmaW5kLgorICAgKiBAcmV0dXJuIFRydWUgaWYgd2Ugd2VyZSBhYmxlIHRvIHNlZWsgdGhlIHNjYW5uZXIgdG8gPGNvZGU+YjwvY29kZT4gb3IgdG8KKyAgICogdGhlIGtleSBqdXN0IGFmdGVyLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgc3RhdGljIGJvb2xlYW4gZ2V0Q2xvc2VzdChmaW5hbCBIRmlsZVNjYW5uZXIgcywgZmluYWwgS2V5VmFsdWUga3YpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gUGFzcyBvZmZzZXRzIHRvIGtleSBjb250ZW50IG9mIGEgS2V5VmFsdWU7IHRoYXRzIHdoYXRzIGluIHRoZSBoZmlsZSBpbmRleC4KKyAgICBpbnQgcmVzdWx0ID0gcy5zZWVrVG8oa3YuZ2V0QnVmZmVyKCksIGt2LmdldEtleU9mZnNldCgpLCBrdi5nZXRLZXlMZW5ndGgoKSk7CisgICAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICAgIC8vIE5vdCBpbiBmaWxlLiAgV2lsbCB0aGUgZmlyc3Qga2V5IGRvPworICAgICAgaWYgKCFzLnNlZWtUbygpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKHJlc3VsdCA+IDApIHsKKyAgICAgIC8vIExlc3MgdGhhbiB3aGF0IHdhcyBhc2tlZCBmb3IgYnV0IG1heWJlIDwgYmVjYXVzZSB3ZSdyZSBhc2tpbmcgZm9yCisgICAgICAvLyByL2MvTEFURVNUX1RJTUVTVEFNUCAtLSB3aGF0IHdhcyByZXR1cm5lZCB3YXMgci9jLTEvU09NRV9UUy4uLgorICAgICAgLy8gQSBuZXh0IHdpbGwgZ2V0IHVzIGEgci9jL1NPTUVfVFMuCisgICAgICBpZiAoIXMubmV4dCgpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGt2CisgICAqIEBwYXJhbSBjb2x1bW5zIENhbiBiZSBudWxsCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBjb2x1bW4gbWF0Y2hlcy4KKyAgICovCisgIHN0YXRpYyBib29sZWFuIG1hdGNoaW5nQ29sdW1ucyhmaW5hbCBLZXlWYWx1ZSBrdiwgZmluYWwgU2V0PGJ5dGUgW10+IGNvbHVtbnMpIHsKKyAgICBpZiAoY29sdW1ucyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgLy8gT25seSBpbnN0YW50aWF0ZSBjb2x1bW5zIGlmIGxvdHMgb2YgY29sdW1ucyB0byB0ZXN0LgorICAgIGlmIChjb2x1bW5zLnNpemUoKSA+IDEwMCkgeworICAgICAgcmV0dXJuIGNvbHVtbnMuY29udGFpbnMoa3YuZ2V0Q29sdW1uKCkpOworICAgIH0KKyAgICBmb3IgKGJ5dGUgW10gY29sdW1uOiBjb2x1bW5zKSB7CisgICAgICBpZiAoa3YubWF0Y2hpbmdDb2x1bW4oY29sdW1uKSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmVGaWxlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmVGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDM4YmI3ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9TdG9yZUZpbGUuamF2YQpAQCAtMCwwICsxLDQ5MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGFsZkhGaWxlUmVhZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJlZmVyZW5jZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5CbG9ja0NhY2hlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkNvbXByZXNzaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogQSBTdG9yZSBkYXRhIGZpbGUuICBTdG9yZXMgdXN1YWxseSBoYXZlIG9uZSBvciBtb3JlIG9mIHRoZXNlIGZpbGVzLiAgVGhleQorICogYXJlIHByb2R1Y2VkIGJ5IGZsdXNoaW5nIHRoZSBtZW1jYWNoZSB0byBkaXNrLiAgVG8KKyAqIGNyZWF0ZSwgY2FsbCB7QGxpbmsgI2dldFdyaXRlcihGaWxlU3lzdGVtLCBQYXRoKX0gYW5kIGFwcGVuZCBkYXRhLiAgQmUKKyAqIHN1cmUgdG8gYWRkIGFueSBtZXRhZGF0YSBiZWZvcmUgY2FsbGluZyBjbG9zZSBvbiB0aGUgV3JpdGVyCisgKiAoVXNlIHRoZSBhcHBlbmRNZXRhZGF0YSBjb252ZW5pZW5jZSBtZXRob2RzKS4gT24gY2xvc2UsIGEgU3RvcmVGaWxlIGlzCisgKiBzaXR0aW5nIGluIHRoZSBGaWxlc3lzdGVtLiAgVG8gcmVmZXIgdG8gaXQsIGNyZWF0ZSBhIFN0b3JlRmlsZSBpbnN0YW5jZQorICogcGFzc2luZyBmaWxlc3lzdGVtIGFuZCBwYXRoLiAgVG8gcmVhZCwgY2FsbCB7QGxpbmsgI2dldFJlYWRlcigpfS4KKyAqIDxwPlN0b3JlRmlsZXMgbWF5IGFsc28gcmVmZXJlbmNlIHN0b3JlIGZpbGVzIGluIGFub3RoZXIgU3RvcmUuCisgKi8KK3B1YmxpYyBjbGFzcyBTdG9yZUZpbGUgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhTdG9yZUZpbGUuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgCisgIC8vIE1ha2UgZGVmYXVsdCBibG9jayBzaXplIGZvciBTdG9yZUZpbGVzIDhrIHdoaWxlIHRlc3RpbmcuICBUT0RPOiBGSVghCisgIC8vIE5lZWQgdG8gbWFrZSBpdCA4ayBmb3IgdGVzdGluZy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfQkxPQ0tTSVpFX1NNQUxMID0gOCAqIDEwMjQ7CisKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlU3lzdGVtIGZzOworICAvLyBUaGlzIGZpbGUncyBwYXRoLgorICBwcml2YXRlIGZpbmFsIFBhdGggcGF0aDsKKyAgLy8gSWYgdGhpcyBzdG9yZWZpbGUgcmVmZXJlbmNlcyBhbm90aGVyLCB0aGlzIGlzIHRoZSByZWZlcmVuY2UgaW5zdGFuY2UuCisgIHByaXZhdGUgUmVmZXJlbmNlIHJlZmVyZW5jZTsKKyAgLy8gSWYgdGhpcyBTdG9yZUZpbGUgcmVmZXJlbmNlcyBhbm90aGVyLCB0aGlzIGlzIHRoZSBvdGhlciBmaWxlcyBwYXRoLgorICBwcml2YXRlIFBhdGggcmVmZXJlbmNlUGF0aDsKKworICAvLyBLZXlzIGZvciBtZXRhZGF0YSBzdG9yZWQgaW4gYmFja2luZyBIRmlsZS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBNQVhfU0VRX0lEX0tFWSA9IEJ5dGVzLnRvQnl0ZXMoIk1BWF9TRVFfSURfS0VZIik7CisgIC8vIFNldCB3aGVuIHdlIG9idGFpbiBhIFJlYWRlci4KKyAgcHJpdmF0ZSBsb25nIHNlcXVlbmNlaWQgPSAtMTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIE1BSk9SX0NPTVBBQ1RJT05fS0VZID0KKyAgICBCeXRlcy50b0J5dGVzKCJNQUpPUl9DT01QQUNUSU9OX0tFWSIpOworICAvLyBJZiB0cnVlLCB0aGlzIGZpbGUgd2FzIHByb2R1Y3Qgb2YgYSBtYWpvciBjb21wYWN0aW9uLiAgSXRzIHRoZW4gc2V0CisgIC8vIHdoZW5ldmVyIHlvdSBnZXQgYSBSZWFkZXIuCisgIHByaXZhdGUgQXRvbWljQm9vbGVhbiBtYWpvckNvbXBhY3Rpb24gPSBudWxsOworCisgIC8qCisgICAqIFJlZ2V4IHRoYXQgd2lsbCB3b3JrIGZvciBzdHJhaWdodCBmaWxlbmFtZXMgYW5kIGZvciByZWZlcmVuY2UgbmFtZXMuCisgICAqIElmIHJlZmVyZW5jZSwgdGhlbiB0aGUgcmVnZXggaGFzIG1vcmUgdGhhbiBqdXN0IG9uZSBncm91cC4gIEdyb3VwIDEgaXMKKyAgICogdGhpcyBmaWxlcyBpZC4gIEdyb3VwIDIgdGhlIHJlZmVyZW5jZWQgcmVnaW9uIG5hbWUsIGV0Yy4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gUkVGX05BTUVfUEFSU0VSID0KKyAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oXFxkKykoPzpcXC4oLispKT8kIik7CisKKyAgcHJpdmF0ZSB2b2xhdGlsZSBIRmlsZS5SZWFkZXIgcmVhZGVyOworCisgIC8vIFVzZWQgbWFraW5nIGZpbGUgaWRzLgorICBwcml2YXRlIGZpbmFsIHN0YXRpYyBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKKworICAvKioKKyAgICogQ29uc3RydWN0b3IuCisgICAqIExvYWRzIHVwIGEgUmVhZGVyIChhbmQgaXRzIGluZGljZXMsIGV0Yy4pLgorICAgKiBAcGFyYW0gZnMgRmlsZXN5c3RlbS4KKyAgICogQHBhcmFtIHAgcXVhbGlmaWVkIHBhdGgKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgU3RvcmVGaWxlKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLmZzID0gZnM7CisgICAgdGhpcy5wYXRoID0gcDsKKyAgICBpZiAoaXNSZWZlcmVuY2UocCkpIHsKKyAgICAgIHRoaXMucmVmZXJlbmNlID0gUmVmZXJlbmNlLnJlYWQoZnMsIHApOworICAgICAgdGhpcy5yZWZlcmVuY2VQYXRoID0gZ2V0UmVmZXJyZWRUb0ZpbGUodGhpcy5wYXRoKTsKKyAgICB9CisgICAgdGhpcy5yZWFkZXIgPSBvcGVuKCk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBQYXRoIG9yIG51bGwgaWYgdGhpcyBTdG9yZUZpbGUgd2FzIG1hZGUgd2l0aCBhIFN0cmVhbS4KKyAgICovCisgIFBhdGggZ2V0UGF0aCgpIHsKKyAgICByZXR1cm4gdGhpcy5wYXRoOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVGhlIFN0b3JlL0NvbHVtbkZhbWlseSB0aGlzIGZpbGUgYmVsb25ncyB0by4KKyAgICovCisgIGJ5dGUgW10gZ2V0RmFtaWx5KCkgeworICAgIHJldHVybiBCeXRlcy50b0J5dGVzKHRoaXMucGF0aC5nZXRQYXJlbnQoKS5nZXROYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIGlzIGEgU3RvcmVGaWxlIFJlZmVyZW5jZTsgY2FsbCBhZnRlciB7QGxpbmsgI29wZW4oKX0KKyAgICogZWxzZSBtYXkgZ2V0IHdyb25nIGFuc3dlci4KKyAgICovCisgIGJvb2xlYW4gaXNSZWZlcmVuY2UoKSB7CisgICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlICE9IG51bGw7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHAgUGF0aCB0byBjaGVjay4KKyAgICogQHJldHVybiBUcnVlIGlmIHRoZSBwYXRoIGhhcyBmb3JtYXQgb2YgYSBIU3RvcmVGaWxlIHJlZmVyZW5jZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1JlZmVyZW5jZShmaW5hbCBQYXRoIHApIHsKKyAgICByZXR1cm4gaXNSZWZlcmVuY2UocCwgUkVGX05BTUVfUEFSU0VSLm1hdGNoZXIocC5nZXROYW1lKCkpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gcCBQYXRoIHRvIGNoZWNrLgorICAgKiBAcGFyYW0gbSBNYXRjaGVyIHRvIHVzZS4KKyAgICogQHJldHVybiBUcnVlIGlmIHRoZSBwYXRoIGhhcyBmb3JtYXQgb2YgYSBIU3RvcmVGaWxlIHJlZmVyZW5jZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1JlZmVyZW5jZShmaW5hbCBQYXRoIHAsIGZpbmFsIE1hdGNoZXIgbSkgeworICAgIGlmIChtID09IG51bGwgfHwgIW0ubWF0Y2hlcygpKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIG1hdGNoIG9mIHN0b3JlIGZpbGUgbmFtZSAiICsgcC50b1N0cmluZygpKTsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJGYWlsZWQgbWF0Y2ggb2Ygc3RvcmUgZmlsZSBuYW1lICIgKworICAgICAgICAgIHAudG9TdHJpbmcoKSk7CisgICAgfQorICAgIHJldHVybiBtLmdyb3VwQ291bnQoKSA+IDEgJiYgbS5ncm91cCgyKSAhPSBudWxsOworICB9CisKKyAgLyoKKyAgICogUmV0dXJuIHBhdGggdG8gdGhlIGZpbGUgcmVmZXJyZWQgdG8gYnkgYSBSZWZlcmVuY2UuICBQcmVzdW1lcyBhIGRpcmVjdG9yeQorICAgKiBoaWVyYXJjaHkgb2YgPGNvZGU+JHtoYmFzZS5yb290ZGlyfS90YWJsZW5hbWUvcmVnaW9ubmFtZS9mYW1pbHluYW1lPC9jb2RlPi4KKyAgICogQHBhcmFtIHAgUGF0aCB0byBhIFJlZmVyZW5jZSBmaWxlLgorICAgKiBAcmV0dXJuIENhbGN1bGF0ZWQgcGF0aCB0byBwYXJlbnQgcmVnaW9uIGZpbGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHN0YXRpYyBQYXRoIGdldFJlZmVycmVkVG9GaWxlKGZpbmFsIFBhdGggcCkgeworICAgIE1hdGNoZXIgbSA9IFJFRl9OQU1FX1BBUlNFUi5tYXRjaGVyKHAuZ2V0TmFtZSgpKTsKKyAgICBpZiAobSA9PSBudWxsIHx8ICFtLm1hdGNoZXMoKSkgeworICAgICAgTE9HLndhcm4oIkZhaWxlZCBtYXRjaCBvZiBzdG9yZSBmaWxlIG5hbWUgIiArIHAudG9TdHJpbmcoKSk7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiRmFpbGVkIG1hdGNoIG9mIHN0b3JlIGZpbGUgbmFtZSAiICsKKyAgICAgICAgICBwLnRvU3RyaW5nKCkpOworICAgIH0KKyAgICAvLyBPdGhlciByZWdpb24gbmFtZSBpcyBzdWZmaXggb24gdGhlIHBhc3NlZCBSZWZlcmVuY2UgZmlsZSBuYW1lCisgICAgU3RyaW5nIG90aGVyUmVnaW9uID0gbS5ncm91cCgyKTsKKyAgICAvLyBUYWJsZWRpciBpcyB1cCB0d28gZGlyZWN0b3JpZXMgZnJvbSB3aGVyZSBSZWZlcmVuY2Ugd2FzIHdyaXR0ZW4uCisgICAgUGF0aCB0YWJsZURpciA9IHAuZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCk7CisgICAgU3RyaW5nIG5hbWVTdHJpcHBlZE9mU3VmZml4ID0gbS5ncm91cCgxKTsKKyAgICAvLyBCdWlsZCB1cCBuZXcgcGF0aCB3aXRoIHRoZSByZWZlcmVuY2VkIHJlZ2lvbiBpbiBwbGFjZSBvZiBvdXIgY3VycmVudAorICAgIC8vIHJlZ2lvbiBpbiB0aGUgcmVmZXJlbmNlIHBhdGguICBBbHNvIHN0cmlwIHJlZ2lvbm5hbWUgc3VmZml4IGZyb20gbmFtZS4KKyAgICByZXR1cm4gbmV3IFBhdGgobmV3IFBhdGgobmV3IFBhdGgodGFibGVEaXIsIG90aGVyUmVnaW9uKSwKKyAgICAgIHAuZ2V0UGFyZW50KCkuZ2V0TmFtZSgpKSwgbmFtZVN0cmlwcGVkT2ZTdWZmaXgpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGlzIGZpbGUgd2FzIG1hZGUgYnkgYSBtYWpvciBjb21wYWN0aW9uLgorICAgKi8KKyAgYm9vbGVhbiBpc01ham9yQ29tcGFjdGlvbigpIHsKKyAgICBpZiAodGhpcy5tYWpvckNvbXBhY3Rpb24gPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJUaGlzIGhhcyBub3QgYmVlbiBzZXQgeWV0Iik7CisgICAgfQorICAgIHJldHVybiB0aGlzLm1ham9yQ29tcGFjdGlvbi5nZXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFRoaXMgZmlsZXMgbWF4aW11bSBlZGl0IHNlcXVlbmNlIGlkLgorICAgKi8KKyAgcHVibGljIGxvbmcgZ2V0TWF4U2VxdWVuY2VJZCgpIHsKKyAgICBpZiAodGhpcy5zZXF1ZW5jZWlkID09IC0xKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFjY2Vzc0Vycm9yKCJIYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQiKTsKKyAgICB9CisgICAgcmV0dXJuIHRoaXMuc2VxdWVuY2VpZDsKKyAgfQorCisgIC8qKgorICAgKiBPcGVucyByZWFkZXIgb24gdGhpcyBzdG9yZSBmaWxlLiAgQ2FsbGVkIGJ5IENvbnN0cnVjdG9yLgorICAgKiBAcmV0dXJuIFJlYWRlciBmb3IgdGhlIHN0b3JlIGZpbGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHNlZSAjY2xvc2UoKQorICAgKi8KKyAgcHJvdGVjdGVkIEhGaWxlLlJlYWRlciBvcGVuKCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5yZWFkZXIgIT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBY2Nlc3NFcnJvcigiQWxyZWFkeSBvcGVuIik7CisgICAgfQorICAgIGlmIChpc1JlZmVyZW5jZSgpKSB7CisgICAgICB0aGlzLnJlYWRlciA9IG5ldyBIYWxmSEZpbGVSZWFkZXIodGhpcy5mcywgdGhpcy5yZWZlcmVuY2VQYXRoLCBudWxsLAorICAgICAgICB0aGlzLnJlZmVyZW5jZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHRoaXMucmVhZGVyID0gbmV3IFN0b3JlRmlsZVJlYWRlcih0aGlzLmZzLCB0aGlzLnBhdGgsIG51bGwpOworICAgIH0KKyAgICAvLyBMb2FkIHVwIGluZGljZXMgYW5kIGZpbGVpbmZvLgorICAgIE1hcDxieXRlIFtdLCBieXRlIFtdPiBtYXAgPSB0aGlzLnJlYWRlci5sb2FkRmlsZUluZm8oKTsKKyAgICAvLyBSZWFkIGluIG91ciBtZXRhZGF0YS4KKyAgICBieXRlIFtdIGIgPSBtYXAuZ2V0KE1BWF9TRVFfSURfS0VZKTsKKyAgICBpZiAoYiAhPSBudWxsKSB7CisgICAgICAvLyBCeSBjb252ZW50aW9uLCBpZiBoYWxmaGZpbGUsIHRvcCBoYWxmIGhhcyBhIHNlcXVlbmNlIG51bWJlciA+IGJvdHRvbQorICAgICAgLy8gaGFsZi4gVGhhdHMgd2h5IHdlIGFkZCBvbmUgaW4gYmVsb3cuIEl0cyBkb25lIGZvciBjYXNlIHRoZSB0d28gaGFsdmVzCisgICAgICAvLyBhcmUgZXZlciBtZXJnZWQgYmFjayB0b2dldGhlciAtLXJhcmUuICBXaXRob3V0IGl0LCBvbiBvcGVuIG9mIHN0b3JlLAorICAgICAgLy8gc2luY2Ugc3RvcmUgZmlsZXMgYXJlIGRpc3Rpbmd1c2hlZCBieSBzZXF1ZW5jZSBpZCwgdGhlIG9uZSBoYWxmIHdvdWxkCisgICAgICAvLyBzdWJzdW1lIHRoZSBvdGhlci4KKyAgICAgIHRoaXMuc2VxdWVuY2VpZCA9IEJ5dGVzLnRvTG9uZyhiKTsKKyAgICAgIGlmIChpc1JlZmVyZW5jZSgpKSB7CisgICAgICAgIGlmIChSZWZlcmVuY2UuaXNUb3BGaWxlUmVnaW9uKHRoaXMucmVmZXJlbmNlLmdldEZpbGVSZWdpb24oKSkpIHsKKyAgICAgICAgICB0aGlzLnNlcXVlbmNlaWQgKz0gMTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgCisgICAgfQorICAgIGIgPSBtYXAuZ2V0KE1BSk9SX0NPTVBBQ1RJT05fS0VZKTsKKyAgICBpZiAoYiAhPSBudWxsKSB7CisgICAgICBib29sZWFuIG1jID0gQnl0ZXMudG9Cb29sZWFuKGIpOworICAgICAgaWYgKHRoaXMubWFqb3JDb21wYWN0aW9uID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5tYWpvckNvbXBhY3Rpb24gPSBuZXcgQXRvbWljQm9vbGVhbihtYyk7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aGlzLm1ham9yQ29tcGFjdGlvbi5zZXQobWMpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdGhpcy5yZWFkZXI7CisgIH0KKyAgCisgIC8qKgorICAgKiBPdmVycmlkZSB0byBhZGQgc29tZSBjdXN0b21pemF0aW9uIG9uIEhGaWxlLlJlYWRlcgorICAgKi8KKyAgc3RhdGljIGNsYXNzIFN0b3JlRmlsZVJlYWRlciBleHRlbmRzIEhGaWxlLlJlYWRlciB7CisgICAgcHVibGljIFN0b3JlRmlsZVJlYWRlcihGaWxlU3lzdGVtIGZzLCBQYXRoIHBhdGgsIEJsb2NrQ2FjaGUgY2FjaGUpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmcywgcGF0aCwgY2FjaGUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBTdHJpbmcgdG9TdHJpbmdGaXJzdEtleSgpIHsKKyAgICAgIHJldHVybiBLZXlWYWx1ZS5rZXlUb1N0cmluZyhnZXRGaXJzdEtleSgpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvU3RyaW5nTGFzdEtleSgpIHsKKyAgICAgIHJldHVybiBLZXlWYWx1ZS5rZXlUb1N0cmluZyhnZXRMYXN0S2V5KCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBPdmVycmlkZSB0byBhZGQgc29tZSBjdXN0b21pemF0aW9uIG9uIEhhbGZIRmlsZVJlYWRlci4KKyAgICovCisgIHN0YXRpYyBjbGFzcyBIYWxmU3RvcmVGaWxlUmVhZGVyIGV4dGVuZHMgSGFsZkhGaWxlUmVhZGVyIHsKKyAgICBwdWJsaWMgSGFsZlN0b3JlRmlsZVJlYWRlcihGaWxlU3lzdGVtIGZzLCBQYXRoIHAsIEJsb2NrQ2FjaGUgYywgUmVmZXJlbmNlIHIpCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzdXBlcihmcywgcCwgYywgcik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgKGlzVG9wKCk/ICIsIGhhbGY9dG9wIjogIiwgaGFsZj1ib3R0b20iKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgU3RyaW5nIHRvU3RyaW5nRmlyc3RLZXkoKSB7CisgICAgICByZXR1cm4gS2V5VmFsdWUua2V5VG9TdHJpbmcoZ2V0Rmlyc3RLZXkoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIFN0cmluZyB0b1N0cmluZ0xhc3RLZXkoKSB7CisgICAgICByZXR1cm4gS2V5VmFsdWUua2V5VG9TdHJpbmcoZ2V0TGFzdEtleSgpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDdXJyZW50IHJlYWRlci4gIE11c3QgY2FsbCBvcGVuIGZpcnN0LgorICAgKi8KKyAgcHVibGljIEhGaWxlLlJlYWRlciBnZXRSZWFkZXIoKSB7CisgICAgaWYgKHRoaXMucmVhZGVyID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQWNjZXNzRXJyb3IoIkNhbGwgb3BlbiBmaXJzdCIpOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5yZWFkZXI7CisgIH0KKworICAvKioKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5yZWFkZXIgIT0gbnVsbCkgeworICAgICAgdGhpcy5yZWFkZXIuY2xvc2UoKTsKKyAgICAgIHRoaXMucmVhZGVyID0gbnVsbDsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICByZXR1cm4gdGhpcy5wYXRoLnRvU3RyaW5nKCkgKworICAgICAgKGlzUmVmZXJlbmNlKCk/ICItIiArIHRoaXMucmVmZXJlbmNlUGF0aCArICItIiArIHJlZmVyZW5jZS50b1N0cmluZygpOiAiIik7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlIHRoaXMgZmlsZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjbG9zZSgpOworICAgIHRoaXMuZnMuZGVsZXRlKGdldFBhdGgoKSwgdHJ1ZSk7CisgIH0KKworICAvKioKKyAgICogVXRpbGl0eSB0byBoZWxwIHdpdGggcmVuYW1lLgorICAgKiBAcGFyYW0gZnMKKyAgICogQHBhcmFtIHNyYworICAgKiBAcGFyYW0gdGd0CisgICAqIEByZXR1cm4gVHJ1ZSBpZiBzdWNjZWVkZWQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUGF0aCByZW5hbWUoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgUGF0aCBzcmMsCisgICAgICBmaW5hbCBQYXRoIHRndCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWZzLmV4aXN0cyhzcmMpKSB7CisgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKHNyYy50b1N0cmluZygpKTsKKyAgICB9CisgICAgaWYgKCFmcy5yZW5hbWUoc3JjLCB0Z3QpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCByZW5hbWUgb2YgIiArIHNyYyArICIgdG8gIiArIHRndCk7CisgICAgfQorICAgIHJldHVybiB0Z3Q7CisgIH0KKworICAvKioKKyAgICogR2V0IGEgc3RvcmUgZmlsZSB3cml0ZXIuIENsaWVudCBpcyByZXNwb25zaWJsZSBmb3IgY2xvc2luZyBmaWxlIHdoZW4gZG9uZS4KKyAgICogSWYgbWV0YWRhdGEsIGFkZCBCRUZPUkUgY2xvc2luZyB1c2luZworICAgKiB7QGxpbmsgI2FwcGVuZE1ldGFkYXRhKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlLldyaXRlciwgbG9uZyl9LgorICAgKiBAcGFyYW0gZnMKKyAgICogQHBhcmFtIGRpciBQYXRoIHRvIGZhbWlseSBkaXJlY3RvcnkuICBNYWtlcyB0aGUgZGlyZWN0b3J5IGlmIGRvZXNuJ3QgZXhpc3QuCisgICAqIENyZWF0ZXMgYSBmaWxlIHdpdGggYSB1bmlxdWUgbmFtZSBpbiB0aGlzIGRpcmVjdG9yeS4KKyAgICogQHJldHVybiBIRmlsZS5Xcml0ZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIRmlsZS5Xcml0ZXIgZ2V0V3JpdGVyKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggZGlyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRXcml0ZXIoZnMsIGRpciwgREVGQVVMVF9CTE9DS1NJWkVfU01BTEwsIG51bGwsIG51bGwsIGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgYSBzdG9yZSBmaWxlIHdyaXRlci4gQ2xpZW50IGlzIHJlc3BvbnNpYmxlIGZvciBjbG9zaW5nIGZpbGUgd2hlbiBkb25lLgorICAgKiBJZiBtZXRhZGF0YSwgYWRkIEJFRk9SRSBjbG9zaW5nIHVzaW5nCisgICAqIHtAbGluayAjYXBwZW5kTWV0YWRhdGEob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGUuV3JpdGVyLCBsb25nKX0uCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gZGlyIFBhdGggdG8gZmFtaWx5IGRpcmVjdG9yeS4gIE1ha2VzIHRoZSBkaXJlY3RvcnkgaWYgZG9lc24ndCBleGlzdC4KKyAgICogQ3JlYXRlcyBhIGZpbGUgd2l0aCBhIHVuaXF1ZSBuYW1lIGluIHRoaXMgZGlyZWN0b3J5LgorICAgKiBAcGFyYW0gYmxvY2tzaXplCisgICAqIEBwYXJhbSBhbGdvcml0aG0gUGFzcyBudWxsIHRvIGdldCBkZWZhdWx0LgorICAgKiBAcGFyYW0gYyBQYXNzIG51bGwgdG8gZ2V0IGRlZmF1bHQuCisgICAqIEBwYXJhbSBibG9vbWZpbHRlciAKKyAgICogQHJldHVybiBIRmlsZS5Xcml0ZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIRmlsZS5Xcml0ZXIgZ2V0V3JpdGVyKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggZGlyLAorICAgIGZpbmFsIGludCBibG9ja3NpemUsIGZpbmFsIENvbXByZXNzaW9uLkFsZ29yaXRobSBhbGdvcml0aG0sCisgICAgZmluYWwgS2V5VmFsdWUuS2V5Q29tcGFyYXRvciBjLCBmaW5hbCBib29sZWFuIGJsb29tZmlsdGVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghZnMuZXhpc3RzKGRpcikpIHsKKyAgICAgIGZzLm1rZGlycyhkaXIpOworICAgIH0KKyAgICBQYXRoIHBhdGggPSBnZXRVbmlxdWVGaWxlKGZzLCBkaXIpOworICAgIHJldHVybiBuZXcgSEZpbGUuV3JpdGVyKGZzLCBwYXRoLCBibG9ja3NpemUsCisgICAgICBhbGdvcml0aG0gPT0gbnVsbD8gSEZpbGUuREVGQVVMVF9DT01QUkVTU0lPTl9BTEdPUklUSE06IGFsZ29yaXRobSwKKyAgICAgIGMgPT0gbnVsbD8gS2V5VmFsdWUuS0VZX0NPTVBBUkFUT1I6IGMsIGJsb29tZmlsdGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gZnMKKyAgICogQHBhcmFtIHAKKyAgICogQHJldHVybiByYW5kb20gZmlsZW5hbWUgaW5zaWRlIHBhc3NlZCA8Y29kZT5kaXI8L2NvZGU+CisgICAqLworICBzdGF0aWMgUGF0aCBnZXRVbmlxdWVGaWxlKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggcCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWZzLmdldEZpbGVTdGF0dXMocCkuaXNEaXIoKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJFeHBlY3RpbmcgYSBkaXJlY3RvcnkiKTsKKyAgICB9CisgICAgcmV0dXJuIGZzLmdldEZpbGVTdGF0dXMocCkuaXNEaXIoKT8gZ2V0UmFuZG9tRmlsZW5hbWUoZnMsIHApOiBwOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gZGlyCisgICAqIEBwYXJhbSBlbmNvZGVkUmVnaW9uTmFtZQorICAgKiBAcGFyYW0gZmFtaWx5CisgICAqIEByZXR1cm4gUGF0aCB0byBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0IGF0IHRpbWUgb2YgdGhpcyBpbnZvY2F0aW9uLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBzdGF0aWMgUGF0aCBnZXRSYW5kb21GaWxlbmFtZShmaW5hbCBGaWxlU3lzdGVtIGZzLCBmaW5hbCBQYXRoIGRpcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0UmFuZG9tRmlsZW5hbWUoZnMsIGRpciwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBkaXIKKyAgICogQHBhcmFtIGVuY29kZWRSZWdpb25OYW1lCisgICAqIEBwYXJhbSBmYW1pbHkKKyAgICogQHBhcmFtIHN1ZmZpeAorICAgKiBAcmV0dXJuIFBhdGggdG8gYSBmaWxlIHRoYXQgZG9lc24ndCBleGlzdCBhdCB0aW1lIG9mIHRoaXMgaW52b2NhdGlvbi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgc3RhdGljIFBhdGggZ2V0UmFuZG9tRmlsZW5hbWUoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgUGF0aCBkaXIsCisgICAgICBmaW5hbCBTdHJpbmcgc3VmZml4KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgaWQgPSAtMTsKKyAgICBQYXRoIHAgPSBudWxsOworICAgIGRvIHsKKyAgICAgIGlkID0gTWF0aC5hYnMocmFuZC5uZXh0TG9uZygpKTsKKyAgICAgIHAgPSBuZXcgUGF0aChkaXIsIExvbmcudG9TdHJpbmcoaWQpICsKKyAgICAgICAgKChzdWZmaXggPT0gbnVsbCB8fCBzdWZmaXgubGVuZ3RoKCkgPD0gMCk/ICIiOiBzdWZmaXgpKTsKKyAgICB9IHdoaWxlKGZzLmV4aXN0cyhwKSk7CisgICAgcmV0dXJuIHA7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgZmlsZSBtZXRhZGF0YS4KKyAgICogQ2FsbCBiZWZvcmUgeW91IGNhbGwgY2xvc2Ugb24gdGhlIHBhc3NlZCA8Y29kZT53PC9jb2RlPiBzaW5jZSBpdHMgd3JpdHRlbgorICAgKiBhcyBtZXRhZGF0YSB0byB0aGF0IGZpbGUuCisgICAqIAorICAgKiBAcGFyYW0gZmlsZXN5c3RlbSBmaWxlIHN5c3RlbQorICAgKiBAcGFyYW0gbWF4U2VxdWVuY2VJZCBNYXhpbXVtIHNlcXVlbmNlIGlkLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBzdGF0aWMgdm9pZCBhcHBlbmRNZXRhZGF0YShmaW5hbCBIRmlsZS5Xcml0ZXIgdywgZmluYWwgbG9uZyBtYXhTZXF1ZW5jZUlkKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFwcGVuZE1ldGFkYXRhKHcsIG1heFNlcXVlbmNlSWQsIGZhbHNlKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZXMgbWV0YWRhdGEuCisgICAqIENhbGwgYmVmb3JlIHlvdSBjYWxsIGNsb3NlIG9uIHRoZSBwYXNzZWQgPGNvZGU+dzwvY29kZT4gc2luY2UgaXRzIHdyaXR0ZW4KKyAgICogYXMgbWV0YWRhdGEgdG8gdGhhdCBmaWxlLgorICAgKiBAcGFyYW0gbWF4U2VxdWVuY2VJZCBNYXhpbXVtIHNlcXVlbmNlIGlkLgorICAgKiBAcGFyYW0gbWMgVHJ1ZSBpZiB0aGlzIGZpbGUgaXMgcHJvZHVjdCBvZiBhIG1ham9yIGNvbXBhY3Rpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgc3RhdGljIHZvaWQgYXBwZW5kTWV0YWRhdGEoZmluYWwgSEZpbGUuV3JpdGVyIHcsIGZpbmFsIGxvbmcgbWF4U2VxdWVuY2VJZCwKKyAgICBmaW5hbCBib29sZWFuIG1jKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHcuYXBwZW5kRmlsZUluZm8oTUFYX1NFUV9JRF9LRVksIEJ5dGVzLnRvQnl0ZXMobWF4U2VxdWVuY2VJZCkpOworICAgIHcuYXBwZW5kRmlsZUluZm8oTUFKT1JfQ09NUEFDVElPTl9LRVksIEJ5dGVzLnRvQnl0ZXMobWMpKTsKKyAgfQorCisgIC8qCisgICAqIFdyaXRlIG91dCBhIHNwbGl0IHJlZmVyZW5jZS4KKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBzcGxpdERpciBQcmVzdW1lcyBwYXRoIGZvcm1hdCBpcyBhY3R1YWxseQorICAgKiA8Y29kZT5TT01FX0RJUkVDVE9SWS9SRUdJT05OQU1FL0ZBTUlMWTwvY29kZT4uCisgICAqIEBwYXJhbSBmIEZpbGUgdG8gc3BsaXQuCisgICAqIEBwYXJhbSBzcGxpdFJvdworICAgKiBAcGFyYW0gcmFuZ2UKKyAgICogQHJldHVybiBQYXRoIHRvIGNyZWF0ZWQgcmVmZXJlbmNlLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBzdGF0aWMgUGF0aCBzcGxpdChmaW5hbCBGaWxlU3lzdGVtIGZzLCBmaW5hbCBQYXRoIHNwbGl0RGlyLAorICAgIGZpbmFsIFN0b3JlRmlsZSBmLCBmaW5hbCBieXRlIFtdIHNwbGl0Um93LCBmaW5hbCBSZWZlcmVuY2UuUmFuZ2UgcmFuZ2UpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQSByZWZlcmVuY2UgdG8gdGhlIGJvdHRvbSBoYWxmIG9mIHRoZSBoc2Ygc3RvcmUgZmlsZS4KKyAgICBSZWZlcmVuY2UgciA9IG5ldyBSZWZlcmVuY2Uoc3BsaXRSb3csIHJhbmdlKTsKKyAgICAvLyBBZGQgdGhlIHJlZmVycmVkLXRvIHJlZ2lvbnMgbmFtZSBhcyBhIGRvdCBzZXBhcmF0ZWQgc3VmZml4LiAKKyAgICAvLyBTZWUgUkVGX05BTUVfUEFSU0VSIHJlZ2V4IGFib3ZlLiAgVGhlIHJlZmVycmVkLXRvIHJlZ2lvbnMgbmFtZSBpcworICAgIC8vIHVwIGluIHRoZSBwYXRoIG9mIHRoZSBwYXNzZWQgaW4gPGNvZGU+ZjwvY29kZT4gLS0gcGFyZW50ZGlyIGlzIGZhbWlseSwKKyAgICAvLyB0aGVuIHRoZSBkaXJlY3RvcnkgYWJvdmUgaXMgdGhlIHJlZ2lvbiBuYW1lLgorICAgIFN0cmluZyBwYXJlbnRSZWdpb25OYW1lID0gZi5nZXRQYXRoKCkuZ2V0UGFyZW50KCkuZ2V0UGFyZW50KCkuZ2V0TmFtZSgpOworICAgIC8vIFdyaXRlIHJlZmVyZW5jZSB3aXRoIHNhbWUgZmlsZSBpZCBvbmx5IHdpdGggdGhlIG90aGVyIHJlZ2lvbiBuYW1lIGFzCisgICAgLy8gc3VmZml4IGFuZCBpbnRvIHRoZSBuZXcgcmVnaW9uIGxvY2F0aW9uICh1bmRlciBzYW1lIGZhbWlseSkuCisgICAgUGF0aCBwID0gbmV3IFBhdGgoc3BsaXREaXIsIGYuZ2V0UGF0aCgpLmdldE5hbWUoKSArICIuIiArIHBhcmVudFJlZ2lvbk5hbWUpOworICAgIHJldHVybiByLndyaXRlKGZzLCBwKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9TdG9yZUZpbGVTY2FubmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmVGaWxlU2Nhbm5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmNDRmNzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvU3RvcmVGaWxlU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsMzI2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudFJlYWRXcml0ZUxvY2s7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlU2Nhbm5lcjsKKworLyoqCisgKiBBIHNjYW5uZXIgdGhhdCBpdGVyYXRlcyB0aHJvdWdoIEhTdG9yZSBmaWxlcworICovCitjbGFzcyBTdG9yZUZpbGVTY2FubmVyIGV4dGVuZHMgSEFic3RyYWN0U2Nhbm5lcgoraW1wbGVtZW50cyBDaGFuZ2VkUmVhZGVyc09ic2VydmVyIHsKKyAgICAvLyBLZXlzIHJldHJpZXZlZCBmcm9tIHRoZSBzb3VyY2VzCisgIHByaXZhdGUgdm9sYXRpbGUgS2V5VmFsdWUga2V5c1tdOworICAKKyAgLy8gUmVhZGVycyB3ZSBnbyBhZ2FpbnN0LgorICBwcml2YXRlIHZvbGF0aWxlIEhGaWxlU2Nhbm5lciBbXSBzY2FubmVyczsKKyAgCisgIC8vIFN0b3JlIHRoaXMgc2Nhbm5lciBjYW1lIG91dCBvZi4KKyAgcHJpdmF0ZSBmaW5hbCBTdG9yZSBzdG9yZTsKKyAgCisgIC8vIFVzZWQgYXJvdW5kIHJlcGxhY2VtZW50IG9mIFJlYWRlcnMgaWYgdGhleSBjaGFuZ2Ugd2hpbGUgd2UncmUgc2Nhbm5pbmcuCisgIHByaXZhdGUgZmluYWwgUmVlbnRyYW50UmVhZFdyaXRlTG9jayBsb2NrID0gbmV3IFJlZW50cmFudFJlYWRXcml0ZUxvY2soKTsKKworICBwcml2YXRlIGZpbmFsIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgLyoqCisgICAqIEBwYXJhbSBzdG9yZQorICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqIEBwYXJhbSBjb2x1bW5zCisgICAqIEBwYXJhbSBmaXJzdFJvdworICAgKiBAcGFyYW0gZGVsZXRlcyBTZXQgb2YgcnVubmluZyBkZWxldGVzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBTdG9yZUZpbGVTY2FubmVyKGZpbmFsIFN0b3JlIHN0b3JlLCBmaW5hbCBsb25nIHRpbWVzdGFtcCwKKyAgICBmaW5hbCBOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4gY29sdW1ucywgZmluYWwgYnl0ZSBbXSBmaXJzdFJvdykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcih0aW1lc3RhbXAsIGNvbHVtbnMpOworICAgIHRoaXMuc3RvcmUgPSBzdG9yZTsKKyAgICB0aGlzLnN0b3JlLmFkZENoYW5nZWRSZWFkZXJPYnNlcnZlcih0aGlzKTsKKyAgICB0cnkgeworICAgICAgb3BlblNjYW5uZXIoZmlyc3RSb3cpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgY2xvc2UoKTsKKyAgICAgIElPRXhjZXB0aW9uIGUgPSBuZXcgSU9FeGNlcHRpb24oIkhTdG9yZVNjYW5uZXIgZmFpbGVkIGNvbnN0cnVjdGlvbiIpOworICAgICAgZS5pbml0Q2F1c2UoZXgpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBHbyBvcGVuIG5ldyBzY2FubmVycyBhbmQgY3VlIHRoZW0gYXQgPGNvZGU+Zmlyc3RSb3c8L2NvZGU+LgorICAgKiBDbG9zZXMgZXhpc3RpbmcgUmVhZGVycyBpZiBhbnkuCisgICAqIEBwYXJhbSBmaXJzdFJvdworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgb3BlblNjYW5uZXIoZmluYWwgYnl0ZSBbXSBmaXJzdFJvdykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PEhGaWxlU2Nhbm5lcj4gcyA9CisgICAgICBuZXcgQXJyYXlMaXN0PEhGaWxlU2Nhbm5lcj4odGhpcy5zdG9yZS5nZXRTdG9yZWZpbGVzKCkuc2l6ZSgpKTsKKyAgICBNYXA8TG9uZywgU3RvcmVGaWxlPiBtYXAgPSB0aGlzLnN0b3JlLmdldFN0b3JlZmlsZXMoKS5kZXNjZW5kaW5nTWFwKCk7CisgICAgZm9yIChTdG9yZUZpbGUgZjogbWFwLnZhbHVlcygpKSB7CisgICAgICAgcy5hZGQoZi5nZXRSZWFkZXIoKS5nZXRTY2FubmVyKCkpOworICAgIH0KKyAgICB0aGlzLnNjYW5uZXJzID0gcy50b0FycmF5KG5ldyBIRmlsZVNjYW5uZXIgW10ge30pOworICAgIHRoaXMua2V5cyA9IG5ldyBLZXlWYWx1ZVt0aGlzLnNjYW5uZXJzLmxlbmd0aF07CisgICAgLy8gQWR2YW5jZSB0aGUgcmVhZGVycyB0byB0aGUgZmlyc3QgcG9zLgorICAgIEtleVZhbHVlIGZpcnN0S2V5ID0gKGZpcnN0Um93ICE9IG51bGwgJiYgZmlyc3RSb3cubGVuZ3RoID4gMCk/CisgICAgICBuZXcgS2V5VmFsdWUoZmlyc3RSb3csIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk6IG51bGw7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLnNjYW5uZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoZmlyc3RLZXkgIT0gbnVsbCkgeworICAgICAgICBpZiAoc2Vla1RvKGksIGZpcnN0S2V5KSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICB9CisgICAgICB3aGlsZSAoZ2V0TmV4dChpKSkgeworICAgICAgICBpZiAoY29sdW1uTWF0Y2goaSkpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBGb3IgYSBwYXJ0aWN1bGFyIGNvbHVtbiBpLCBmaW5kIGFsbCB0aGUgbWF0Y2hlcnMgZGVmaW5lZCBmb3IgdGhlIGNvbHVtbi4KKyAgICogQ29tcGFyZSB0aGUgY29sdW1uIGZhbWlseSBhbmQgY29sdW1uIGtleSB1c2luZyB0aGUgbWF0Y2hlcnMuIFRoZSBmaXJzdCBvbmUKKyAgICogdGhhdCBtYXRjaGVzIHJldHVybnMgdHJ1ZS4gSWYgbm8gbWF0Y2hlcnMgYXJlIHN1Y2Nlc3NmdWwsIHJldHVybiBmYWxzZS4KKyAgICogCisgICAqIEBwYXJhbSBpIGluZGV4IGludG8gdGhlIGtleXMgYXJyYXkKKyAgICogQHJldHVybiB0cnVlIGlmIGFueSBvZiB0aGUgbWF0Y2hlcnMgZm9yIHRoZSBjb2x1bW4gbWF0Y2ggdGhlIGNvbHVtbiBmYW1pbHkKKyAgICogYW5kIHRoZSBjb2x1bW4ga2V5LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBib29sZWFuIGNvbHVtbk1hdGNoKGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBjb2x1bW5NYXRjaChrZXlzW2ldKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIG5leHQgc2V0IG9mIHZhbHVlcyBmb3IgdGhpcyBzY2FubmVyLgorICAgKiAKKyAgICogQHBhcmFtIGtleSBUaGUga2V5IHRoYXQgbWF0Y2hlZAorICAgKiBAcGFyYW0gcmVzdWx0cyBBbGwgdGhlIHJlc3VsdHMgZm9yIDxjb2RlPmtleTwvY29kZT4KKyAgICogQHJldHVybiB0cnVlIGlmIGEgbWF0Y2ggd2FzIGZvdW5kCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogCisgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkludGVybmFsU2Nhbm5lciNuZXh0KG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTdG9yZUtleSwgamF2YS51dGlsLlNvcnRlZE1hcCkKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBuZXh0KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMuc2Nhbm5lckNsb3NlZCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB0aGlzLmxvY2sucmVhZExvY2soKS5sb2NrKCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIEZpbmQgdGhlIG5leHQgdmlhYmxlIHJvdyBsYWJlbCAoYW5kIHRpbWVzdGFtcCkuCisgICAgICBLZXlWYWx1ZSB2aWFibGUgPSBnZXROZXh0VmlhYmxlUm93KCk7CisgICAgICBpZiAodmlhYmxlID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICAvLyBHcmFiIGFsbCB0aGUgdmFsdWVzIHRoYXQgbWF0Y2ggdGhpcyByb3cvdGltZXN0YW1wCisgICAgICBib29sZWFuIGFkZGVkSXRlbSA9IGZhbHNlOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIC8vIEZldGNoIHRoZSBkYXRhCisgICAgICAgIHdoaWxlICgoa2V5c1tpXSAhPSBudWxsKSAmJgorICAgICAgICAgICAgKHRoaXMuc3RvcmUuY29tcGFyYXRvci5jb21wYXJlUm93cyh0aGlzLmtleXNbaV0sIHZpYWJsZSkgPT0gMCkpIHsKKyAgICAgICAgICAvLyBJZiB3ZSBhcmUgZG9pbmcgYSB3aWxkIGNhcmQgbWF0Y2ggb3IgdGhlcmUgYXJlIG11bHRpcGxlIG1hdGNoZXJzCisgICAgICAgICAgLy8gcGVyIGNvbHVtbiwgd2UgbmVlZCB0byBzY2FuIGFsbCB0aGUgb2xkZXIgdmVyc2lvbnMgb2YgdGhpcyByb3cKKyAgICAgICAgICAvLyB0byBwaWNrIHVwIHRoZSByZXN0IG9mIHRoZSBmYW1pbHkgbWVtYmVycworICAgICAgICAgIGlmKCFpc1dpbGRjYXJkU2Nhbm5lcigpCisgICAgICAgICAgICAgICYmICFpc011bHRpcGxlTWF0Y2hTY2FubmVyKCkKKyAgICAgICAgICAgICAgJiYgKGtleXNbaV0uZ2V0VGltZXN0YW1wKCkgIT0gdmlhYmxlLmdldFRpbWVzdGFtcCgpKSkgeworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChjb2x1bW5NYXRjaChpKSkgeworICAgICAgICAgICAgLy8gV2Ugb25seSB3YW50IHRoZSBmaXJzdCByZXN1bHQgZm9yIGFueSBzcGVjaWZpYyBmYW1pbHkgbWVtYmVyCisgICAgICAgICAgICAvLyBUT0RPOiBEbyB3ZSBoYXZlIHRvIGtlZXAgYSBydW5uaW5nIGxpc3Qgb2YgY29sdW1uIGVudHJpZXMgaW4KKyAgICAgICAgICAgIC8vIHRoZSByZXN1bHRzIGFjcm9zcyBhbGwgb2YgdGhlIFN0b3JlU2Nhbm5lcj8gIExpa2Ugd2UgZG8KKyAgICAgICAgICAgIC8vIGRvaW5nIGdldEZ1bGw/CisgICAgICAgICAgICBpZiAoIXJlc3VsdHMuY29udGFpbnMoa2V5c1tpXSkpIHsKKyAgICAgICAgICAgICAgcmVzdWx0cy5hZGQoa2V5c1tpXSk7CisgICAgICAgICAgICAgIGFkZGVkSXRlbSA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorCisgICAgICAgICAgaWYgKCFnZXROZXh0KGkpKSB7CisgICAgICAgICAgICBjbG9zZVN1YlNjYW5uZXIoaSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIEFkdmFuY2UgdGhlIGN1cnJlbnQgc2Nhbm5lciBiZXlvbmQgdGhlIGNob3NlbiByb3csIHRvCisgICAgICAgIC8vIGEgdmFsaWQgdGltZXN0YW1wLCBzbyB3ZSdyZSByZWFkeSBuZXh0IHRpbWUuCisgICAgICAgIHdoaWxlICgoa2V5c1tpXSAhPSBudWxsKSAmJgorICAgICAgICAgICAgKCh0aGlzLnN0b3JlLmNvbXBhcmF0b3IuY29tcGFyZVJvd3ModGhpcy5rZXlzW2ldLCB2aWFibGUpIDw9IDApIHx8CisgICAgICAgICAgICAgICAgKGtleXNbaV0uZ2V0VGltZXN0YW1wKCkgPiB0aGlzLnRpbWVzdGFtcCkgfHwKKyAgICAgICAgICAgICAgICAhY29sdW1uTWF0Y2goaSkpKSB7CisgICAgICAgICAgZ2V0TmV4dChpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIGFkZGVkSXRlbTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkudW5sb2NrKCk7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogQHJldHVybiBBbiBpbnN0YW5jZSBvZiA8Y29kZT5WaWFibGVSb3c8L2NvZGU+CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgS2V5VmFsdWUgZ2V0TmV4dFZpYWJsZVJvdygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gRmluZCB0aGUgbmV4dCB2aWFibGUgcm93IGxhYmVsIChhbmQgdGltZXN0YW1wKS4KKyAgICBLZXlWYWx1ZSB2aWFibGUgPSBudWxsOworICAgIGxvbmcgdmlhYmxlVGltZXN0YW1wID0gLTE7CisgICAgbG9uZyB0dGwgPSBzdG9yZS50dGw7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICAvLyBUaGUgZmlyc3Qga2V5IHRoYXQgd2UgZmluZCB0aGF0IG1hdGNoZXMgbWF5IGhhdmUgYSB0aW1lc3RhbXAgZ3JlYXRlcgorICAgICAgLy8gdGhhbiB0aGUgb25lIHdlJ3JlIGxvb2tpbmcgZm9yLiBXZSBoYXZlIHRvIGFkdmFuY2UgdG8gc2VlIGlmIHRoZXJlCisgICAgICAvLyBpcyBhbiBvbGRlciB2ZXJzaW9uIHByZXNlbnQsIHNpbmNlIHRpbWVzdGFtcHMgYXJlIHNvcnRlZCBkZXNjZW5kaW5nCisgICAgICB3aGlsZSAoa2V5c1tpXSAhPSBudWxsICYmCisgICAgICAgICAga2V5c1tpXS5nZXRUaW1lc3RhbXAoKSA+IHRoaXMudGltZXN0YW1wICYmCisgICAgICAgICAgY29sdW1uTWF0Y2goaSkgJiYKKyAgICAgICAgICBnZXROZXh0KGkpKSB7CisgICAgICAgIGlmIChjb2x1bW5NYXRjaChpKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZigoa2V5c1tpXSAhPSBudWxsKQorICAgICAgICAgIC8vIElmIHdlIGdldCBoZXJlIGFuZCBrZXlzW2ldIGlzIG5vdCBudWxsLCB3ZSBhbHJlYWR5IGtub3cgdGhhdCB0aGUKKyAgICAgICAgICAvLyBjb2x1bW4gbWF0Y2hlcyBhbmQgdGhlIHRpbWVzdGFtcCBvZiB0aGUgcm93IGlzIGxlc3MgdGhhbiBvciBlcXVhbAorICAgICAgICAgIC8vIHRvIHRoaXMudGltZXN0YW1wLCBzbyB3ZSBkbyBub3QgbmVlZCB0byB0ZXN0IHRoYXQgaGVyZQorICAgICAgICAgICYmICgodmlhYmxlID09IG51bGwpIHx8CisgICAgICAgICAgICAodGhpcy5zdG9yZS5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKHRoaXMua2V5c1tpXSwgdmlhYmxlKSA8IDApIHx8CisgICAgICAgICAgICAoKHRoaXMuc3RvcmUuY29tcGFyYXRvci5jb21wYXJlUm93cyh0aGlzLmtleXNbaV0sIHZpYWJsZSkgPT0gMCkgJiYKKyAgICAgICAgICAgICAgKGtleXNbaV0uZ2V0VGltZXN0YW1wKCkgPiB2aWFibGVUaW1lc3RhbXApKSkpIHsKKyAgICAgICAgaWYgKHR0bCA9PSBIQ29uc3RhbnRzLkZPUkVWRVIgfHwgbm93IDwga2V5c1tpXS5nZXRUaW1lc3RhbXAoKSArIHR0bCkgeworICAgICAgICAgIHZpYWJsZSA9IGtleXNbaV07CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgICBMT0cuZGVidWcoImdldE5leHRWaWFibGVSb3cgOiIgKyBrZXlzW2ldICsgIjogZXhwaXJlZCwgc2tpcHBlZCIpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdmlhYmxlOworICB9CisKKyAgLyoKKyAgICogVGhlIHVzZXIgZGlkbid0IHdhbnQgdG8gc3RhcnQgc2Nhbm5pbmcgYXQgdGhlIGZpcnN0IHJvdy4gVGhpcyBtZXRob2QKKyAgICogc2Vla3MgdG8gdGhlIHJlcXVlc3RlZCByb3cuCisgICAqCisgICAqIEBwYXJhbSBpIHdoaWNoIGl0ZXJhdG9yIHRvIGFkdmFuY2UKKyAgICogQHBhcmFtIGZpcnN0Um93IHNlZWsgdG8gdGhpcyByb3cKKyAgICogQHJldHVybiB0cnVlIGlmIHdlIGZvdW5kIHRoZSBmaXJzdCByb3cgYW5kIHNvIHRoZSBzY2FubmVyIGlzIHByb3Blcmx5CisgICAqIHByaW1lZCBvciB0cnVlIGlmIHRoZSByb3cgd2FzIG5vdCBmb3VuZCBhbmQgdGhpcyBzY2FubmVyIGlzIGV4aGF1c3RlZC4KKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiBzZWVrVG8oaW50IGksIGZpbmFsIEtleVZhbHVlIGZpcnN0S2V5KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmaXJzdEtleSA9PSBudWxsKSB7CisgICAgICBpZiAoIXRoaXMuc2Nhbm5lcnNbaV0uc2Vla1RvKCkpIHsKKyAgICAgICAgY2xvc2VTdWJTY2FubmVyKGkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gVE9ETzogc29ydCBjb2x1bW5zIGFuZCBwYXNzIGluIGNvbHVtbiBhcyBwYXJ0IG9mIGtleSBzbyB3ZSBnZXQgY2xvc2VyLgorICAgICAgaWYgKCFTdG9yZS5nZXRDbG9zZXN0KHRoaXMuc2Nhbm5lcnNbaV0sIGZpcnN0S2V5KSkgeworICAgICAgICBjbG9zZVN1YlNjYW5uZXIoaSk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICB0aGlzLmtleXNbaV0gPSB0aGlzLnNjYW5uZXJzW2ldLmdldEtleVZhbHVlKCk7CisgICAgcmV0dXJuIGlzR29vZEtleSh0aGlzLmtleXNbaV0pOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgbmV4dCB2YWx1ZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyLgorICAgKiAKKyAgICogQHBhcmFtIGkgd2hpY2ggcmVhZGVyIHRvIGZldGNoIG5leHQgdmFsdWUgZnJvbQorICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgaXMgbW9yZSBkYXRhIGF2YWlsYWJsZQorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGdldE5leHQoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgaWYgKCh0aGlzLnNjYW5uZXJzW2ldLmlzU2Vla2VkKCkgJiYgIXRoaXMuc2Nhbm5lcnNbaV0ubmV4dCgpKSB8fAorICAgICAgICAgICghdGhpcy5zY2FubmVyc1tpXS5pc1NlZWtlZCgpICYmICF0aGlzLnNjYW5uZXJzW2ldLnNlZWtUbygpKSkgeworICAgICAgICBjbG9zZVN1YlNjYW5uZXIoaSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgdGhpcy5rZXlzW2ldID0gdGhpcy5zY2FubmVyc1tpXS5nZXRLZXlWYWx1ZSgpOworICAgICAgaWYgKGlzR29vZEtleSh0aGlzLmtleXNbaV0pKSB7CisgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSBrdgorICAgKiBAcmV0dXJuIFRydWUgaWYgZ29vZCBrZXkgY2FuZGlkYXRlLgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGlzR29vZEtleShmaW5hbCBLZXlWYWx1ZSBrdikgeworICAgIHJldHVybiAhU3RvcmUuaXNFeHBpcmVkKGt2LCB0aGlzLnN0b3JlLnR0bCwgdGhpcy5ub3cpOworICB9CisKKyAgLyoqIENsb3NlIGRvd24gdGhlIGluZGljYXRlZCByZWFkZXIuICovCisgIHByaXZhdGUgdm9pZCBjbG9zZVN1YlNjYW5uZXIoaW50IGkpIHsKKyAgICB0aGlzLnNjYW5uZXJzW2ldID0gbnVsbDsKKyAgICB0aGlzLmtleXNbaV0gPSBudWxsOworICB9CisKKyAgLyoqIFNodXQgaXQgZG93biEgKi8KKyAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgaWYgKCF0aGlzLnNjYW5uZXJDbG9zZWQpIHsKKyAgICAgIHRoaXMuc3RvcmUuZGVsZXRlQ2hhbmdlZFJlYWRlck9ic2VydmVyKHRoaXMpOworICAgICAgdHJ5IHsKKyAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IHRoaXMuc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICBjbG9zZVN1YlNjYW5uZXIoaSk7CisgICAgICAgIH0KKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHRoaXMuc2Nhbm5lckNsb3NlZCA9IHRydWU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gSW1wbGVtZW50YXRpb24gb2YgQ2hhbmdlZFJlYWRlcnNPYnNlcnZlcgorICAKKyAgcHVibGljIHZvaWQgdXBkYXRlUmVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLmxvY2soKTsKKyAgICB0cnkgeworICAgICAgLy8gVGhlIGtleXMgYXJlIGN1cnJlbnRseSBsaW5lZCB1cCBhdCB0aGUgbmV4dCByb3cgdG8gZmV0Y2guICBQYXNzIGluCisgICAgICAvLyB0aGUgY3VycmVudCByb3cgYXMgJ2ZpcnN0JyByb3cgYW5kIHJlYWRlcnMgd2lsbCBiZSBvcGVuZWQgYW5kIGN1ZSdkCisgICAgICAvLyB1cCBzbyBmdXR1cmUgY2FsbCB0byBuZXh0IHdpbGwgc3RhcnQgaGVyZS4KKyAgICAgIEtleVZhbHVlIHZpYWJsZSA9IGdldE5leHRWaWFibGVSb3coKTsKKyAgICAgIG9wZW5TY2FubmVyKHZpYWJsZS5nZXRSb3coKSk7CisgICAgICBMT0cuZGVidWcoIlJlcGxhY2VkIFNjYW5uZXIgUmVhZGVycyBhdCByb3cgIiArCisgICAgICAgIHZpYWJsZS5nZXRSb3coKS50b1N0cmluZygpKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9TdG9yZVNjYW5uZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9TdG9yZVNjYW5uZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDBiZGM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1N0b3JlU2Nhbm5lci5qYXZhCkBAIC0wLDAgKzEsMzE0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLlJlZW50cmFudFJlYWRXcml0ZUxvY2s7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogU2Nhbm5lciBzY2FucyBib3RoIHRoZSBtZW1jYWNoZSBhbmQgdGhlIEhTdG9yZQorICovCitjbGFzcyBTdG9yZVNjYW5uZXIgaW1wbGVtZW50cyBJbnRlcm5hbFNjYW5uZXIsICBDaGFuZ2VkUmVhZGVyc09ic2VydmVyIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhTdG9yZVNjYW5uZXIuY2xhc3MpOworCisgIHByaXZhdGUgSW50ZXJuYWxTY2FubmVyIFtdIHNjYW5uZXJzOworICBwcml2YXRlIExpc3Q8S2V5VmFsdWU+IFtdIHJlc3VsdFNldHM7CisgIHByaXZhdGUgYm9vbGVhbiB3aWxkY2FyZE1hdGNoID0gZmFsc2U7CisgIHByaXZhdGUgYm9vbGVhbiBtdWx0aXBsZU1hdGNoZXJzID0gZmFsc2U7CisgIHByaXZhdGUgUm93RmlsdGVySW50ZXJmYWNlIGRhdGFGaWx0ZXI7CisgIHByaXZhdGUgU3RvcmUgc3RvcmU7CisgIHByaXZhdGUgZmluYWwgbG9uZyB0aW1lc3RhbXA7CisgIHByaXZhdGUgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IGNvbHVtbnM7CisgIAorICAvLyBJbmRpY2VzIGZvciBtZW1jYWNoZSBzY2FubmVyIGFuZCBoc3RvcmVmaWxlIHNjYW5uZXIuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNRU1TX0lOREVYID0gMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhTRlNfSU5ERVggPSBNRU1TX0lOREVYICsgMTsKKyAgCisgIC8vIFVzZWQgYXJvdW5kIHRyYW5zaXRpb24gZnJvbSBubyBzdG9yZWZpbGUgdG8gdGhlIGZpcnN0LgorICBwcml2YXRlIGZpbmFsIFJlZW50cmFudFJlYWRXcml0ZUxvY2sgbG9jayA9IG5ldyBSZWVudHJhbnRSZWFkV3JpdGVMb2NrKCk7CisKKyAgLy8gVXNlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZSBzY2FubmVyIGhhcyBjbG9zZWQgKHNlZSBIQkFTRS0xMTA3KQorICBwcml2YXRlIGZpbmFsIEF0b21pY0Jvb2xlYW4gY2xvc2luZyA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKworICAvKiogQ3JlYXRlIGFuIFNjYW5uZXIgd2l0aCBhIGhhbmRsZSBvbiB0aGUgbWVtY2FjaGUgYW5kIEhTdG9yZSBmaWxlcy4gKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgIFN0b3JlU2Nhbm5lcihTdG9yZSBzdG9yZSwgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IHRhcmdldENvbHMsCisgICAgYnl0ZSBbXSBmaXJzdFJvdywgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuc3RvcmUgPSBzdG9yZTsKKyAgICB0aGlzLmRhdGFGaWx0ZXIgPSBmaWx0ZXI7CisgICAgaWYgKG51bGwgIT0gZGF0YUZpbHRlcikgeworICAgICAgZGF0YUZpbHRlci5yZXNldCgpOworICAgIH0KKyAgICB0aGlzLnNjYW5uZXJzID0gbmV3IEludGVybmFsU2Nhbm5lclsyXTsKKyAgICB0aGlzLnJlc3VsdFNldHMgPSBuZXcgTGlzdFtzY2FubmVycy5sZW5ndGhdOworICAgIC8vIFNhdmUgdGhlc2UgYXJncyBpbiBjYXNlIHdlIG5lZWQgdGhlbSBsYXRlciBoYW5kbGluZyBjaGFuZ2UgaW4gcmVhZGVycworICAgIC8vIFNlZSB1cGRhdGVSZWFkZXJzIGJlbG93LgorICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgIHRoaXMuY29sdW1ucyA9IHRhcmdldENvbHM7CisgICAgdHJ5IHsKKyAgICAgIHNjYW5uZXJzW01FTVNfSU5ERVhdID0KKyAgICAgICAgc3RvcmUubWVtY2FjaGUuZ2V0U2Nhbm5lcih0aW1lc3RhbXAsIHRhcmdldENvbHMsIGZpcnN0Um93KTsKKyAgICAgIHNjYW5uZXJzW0hTRlNfSU5ERVhdID0KKyAgICAgICAgbmV3IFN0b3JlRmlsZVNjYW5uZXIoc3RvcmUsIHRpbWVzdGFtcCwgdGFyZ2V0Q29scywgZmlyc3RSb3cpOworICAgICAgZm9yIChpbnQgaSA9IE1FTVNfSU5ERVg7IGkgPCBzY2FubmVycy5sZW5ndGg7IGkrKykgeworICAgICAgICBjaGVja1NjYW5uZXJGbGFncyhpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBkb0Nsb3NlKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgICAKKyAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBrZXkgaW4gZWFjaCBzY2FubmVyLgorICAgIC8vIEFsbCByZXN1bHRzIHdpbGwgbWF0Y2ggdGhlIHJlcXVpcmVkIGNvbHVtbi1zZXQgYW5kIHNjYW5UaW1lLgorICAgIGZvciAoaW50IGkgPSBNRU1TX0lOREVYOyBpIDwgc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHNldHVwU2Nhbm5lcihpKTsKKyAgICB9CisgICAgdGhpcy5zdG9yZS5hZGRDaGFuZ2VkUmVhZGVyT2JzZXJ2ZXIodGhpcyk7CisgIH0KKyAgCisgIC8qCisgICAqIEBwYXJhbSBpIEluZGV4LgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGNoZWNrU2Nhbm5lckZsYWdzKGZpbmFsIGludCBpKSB7CisgICAgaWYgKHRoaXMuc2Nhbm5lcnNbaV0uaXNXaWxkY2FyZFNjYW5uZXIoKSkgeworICAgICAgdGhpcy53aWxkY2FyZE1hdGNoID0gdHJ1ZTsKKyAgICB9CisgICAgaWYgKHRoaXMuc2Nhbm5lcnNbaV0uaXNNdWx0aXBsZU1hdGNoU2Nhbm5lcigpKSB7CisgICAgICB0aGlzLm11bHRpcGxlTWF0Y2hlcnMgPSB0cnVlOworICAgIH0KKyAgfQorICAKKyAgLyoKKyAgICogRG8gc2Nhbm5lciBzZXR1cC4KKyAgICogQHBhcmFtIGkKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHNldHVwU2Nhbm5lcihmaW5hbCBpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLnJlc3VsdFNldHNbaV0gPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgIGlmICh0aGlzLnNjYW5uZXJzW2ldICE9IG51bGwgJiYgIXRoaXMuc2Nhbm5lcnNbaV0ubmV4dCh0aGlzLnJlc3VsdFNldHNbaV0pKSB7CisgICAgICBjbG9zZVNjYW5uZXIoaSk7CisgICAgfQorICB9CisKKyAgLyoqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc2Nhbm5lciBpcyBhIHdpbGQgY2FyZCBzY2FubmVyICovCisgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmRTY2FubmVyKCkgeworICAgIHJldHVybiB0aGlzLndpbGRjYXJkTWF0Y2g7CisgIH0KKworICAvKiogQHJldHVybiB0cnVlIGlmIHRoZSBzY2FubmVyIGlzIGEgbXVsdGlwbGUgbWF0Y2ggc2Nhbm5lciAqLworICBwdWJsaWMgYm9vbGVhbiBpc011bHRpcGxlTWF0Y2hTY2FubmVyKCkgeworICAgIHJldHVybiB0aGlzLm11bHRpcGxlTWF0Y2hlcnM7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBuZXh0KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5sb2NrLnJlYWRMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgLy8gRmlsdGVyZWQgZmxhZyBpcyBzZXQgYnkgZmlsdGVycy4gIElmIGEgY2VsbCBoYXMgYmVlbiAnZmlsdGVyZWQgb3V0JworICAgIC8vIC0tIGkuZS4gaXQgaXMgbm90IHRvIGJlIHJldHVybmVkIHRvIHRoZSBjYWxsZXIgLS0gdGhlIGZsYWcgaXMgJ3RydWUnLgorICAgIGJvb2xlYW4gZmlsdGVyZWQgPSB0cnVlOworICAgIGJvb2xlYW4gbW9yZVRvRm9sbG93ID0gdHJ1ZTsKKyAgICB3aGlsZSAoZmlsdGVyZWQgJiYgbW9yZVRvRm9sbG93KSB7CisgICAgICAvLyBGaW5kIHRoZSBsb3dlc3QtcG9zc2libGUga2V5LgorICAgICAgS2V5VmFsdWUgY2hvc2VuID0gbnVsbDsKKyAgICAgIGxvbmcgY2hvc2VuVGltZXN0YW1wID0gLTE7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuc2Nhbm5lcnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgS2V5VmFsdWUga3YgPSB0aGlzLnJlc3VsdFNldHNbaV0gPT0gbnVsbCB8fCB0aGlzLnJlc3VsdFNldHNbaV0uaXNFbXB0eSgpPworICAgICAgICAgIG51bGw6IHRoaXMucmVzdWx0U2V0c1tpXS5nZXQoMCk7CisgICAgICAgIGlmIChrdiA9PSBudWxsKSB7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNjYW5uZXJzW2ldICE9IG51bGwgJiYKKyAgICAgICAgICAgIChjaG9zZW4gPT0gbnVsbCB8fAorICAgICAgICAgICAgICAodGhpcy5zdG9yZS5jb21wYXJhdG9yLmNvbXBhcmVSb3dzKGt2LCBjaG9zZW4pIDwgMCkgfHwKKyAgICAgICAgICAgICAgKCh0aGlzLnN0b3JlLmNvbXBhcmF0b3IuY29tcGFyZVJvd3Moa3YsIGNob3NlbikgPT0gMCkgJiYKKyAgICAgICAgICAgICAgKGt2LmdldFRpbWVzdGFtcCgpID4gY2hvc2VuVGltZXN0YW1wKSkpKSB7CisgICAgICAgICAgY2hvc2VuID0ga3Y7CisgICAgICAgICAgY2hvc2VuVGltZXN0YW1wID0gY2hvc2VuLmdldFRpbWVzdGFtcCgpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIEZpbHRlciB3aG9sZSByb3cgYnkgcm93IGtleT8KKyAgICAgIGZpbHRlcmVkID0gZGF0YUZpbHRlciA9PSBudWxsIHx8IGNob3NlbiA9PSBudWxsPyBmYWxzZToKKyAgICAgICAgZGF0YUZpbHRlci5maWx0ZXJSb3dLZXkoY2hvc2VuLmdldEJ1ZmZlcigpLCBjaG9zZW4uZ2V0Um93T2Zmc2V0KCksCisgICAgICAgICAgY2hvc2VuLmdldFJvd0xlbmd0aCgpKTsKKworICAgICAgLy8gU3RvcmUgcmVzdWx0cyBmb3IgZWFjaCBzdWItc2Nhbm5lci4KKyAgICAgIGlmIChjaG9zZW5UaW1lc3RhbXAgPj0gMCAmJiAhZmlsdGVyZWQpIHsKKyAgICAgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiBkZWxldGVzID0KKyAgICAgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4odGhpcy5zdG9yZS5jb21wYXJhdG9ySWdub3JpbmdUeXBlKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzY2FubmVycy5sZW5ndGggJiYgIWZpbHRlcmVkOyBpKyspIHsKKyAgICAgICAgICBpZiAoKHNjYW5uZXJzW2ldICE9IG51bGwgJiYgIWZpbHRlcmVkICYmIG1vcmVUb0ZvbGxvdyAmJgorICAgICAgICAgICAgICB0aGlzLnJlc3VsdFNldHNbaV0gIT0gbnVsbCAmJiAhdGhpcy5yZXN1bHRTZXRzW2ldLmlzRW1wdHkoKSkpIHsKKyAgICAgICAgICAgIC8vIFRlc3QgdGhpcyByZXN1bHRzZXQgaXMgZm9yIHRoZSAnY2hvc2VuJyByb3cuCisgICAgICAgICAgICBLZXlWYWx1ZSBmaXJzdGt2ID0gcmVzdWx0U2V0c1tpXS5nZXQoMCk7CisgICAgICAgICAgICBpZiAoIXRoaXMuc3RvcmUuY29tcGFyYXRvci5tYXRjaGluZ1Jvd3MoZmlyc3RrdiwgY2hvc2VuKSkgeworICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEl0cyBmb3IgdGhlICdjaG9zZW4nIHJvdywgd29yayBpdC4KKyAgICAgICAgICAgIGZvciAoS2V5VmFsdWUga3Y6IHJlc3VsdFNldHNbaV0pIHsKKyAgICAgICAgICAgICAgaWYgKGt2LmlzRGVsZXRlVHlwZSgpKSB7CisgICAgICAgICAgICAgICAgZGVsZXRlcy5hZGQoa3YpOworICAgICAgICAgICAgICB9IGVsc2UgaWYgKChkZWxldGVzLmlzRW1wdHkoKSB8fCAhZGVsZXRlcy5jb250YWlucyhrdikpICYmCisgICAgICAgICAgICAgICAgICAhZmlsdGVyZWQgJiYgbW9yZVRvRm9sbG93ICYmICFyZXN1bHRzLmNvbnRhaW5zKGt2KSkgeworICAgICAgICAgICAgICAgIGlmICh0aGlzLmRhdGFGaWx0ZXIgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgLy8gRmlsdGVyIHdob2xlIHJvdyBieSBjb2x1bW4gZGF0YT8KKyAgICAgICAgICAgICAgICAgIGludCByb3dsZW5ndGggPSBrdi5nZXRSb3dMZW5ndGgoKTsKKyAgICAgICAgICAgICAgICAgIGludCBjb2x1bW5vZmZzZXQgPSBrdi5nZXRDb2x1bW5PZmZzZXQocm93bGVuZ3RoKTsKKyAgICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gZGF0YUZpbHRlci5maWx0ZXJDb2x1bW4oa3YuZ2V0QnVmZmVyKCksCisgICAgICAgICAgICAgICAgICAgICAga3YuZ2V0Um93T2Zmc2V0KCksIHJvd2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAga3YuZ2V0QnVmZmVyKCksIGNvbHVtbm9mZnNldCwga3YuZ2V0Q29sdW1uTGVuZ3RoKGNvbHVtbm9mZnNldCksCisgICAgICAgICAgICAgICAgICAgIGt2LmdldEJ1ZmZlcigpLCBrdi5nZXRWYWx1ZU9mZnNldCgpLCBrdi5nZXRWYWx1ZUxlbmd0aCgpKTsKKyAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZCkgeworICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmNsZWFyKCk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXN1bHRzLmFkZChrdik7CisgICAgICAgICAgICAgICAgLyogUkVNT1ZJTkcgQkVDQVVTRSBDT1VMRCBCRSBCVU5DSCBPRiBERUxFVEVTIElOIFJFU1VMVFMKKyAgICAgICAgICAgICAgICAgICBBTkQgV0UgV0FOVCBUTyBJTkNMVURFIFRIRU0gLS0gYmVsb3cgc2hvcnQtY2lyY3VpdCBpcworICAgICAgICAgICAgICAgICAgIHByb2JhYmx5IG5vdCB3YW50ZWQuCisgICAgICAgICAgICAgICAgLy8gSWYgd2UgYXJlIGRvaW5nIGEgd2lsZCBjYXJkIG1hdGNoIG9yIHRoZXJlIGFyZSBtdWx0aXBsZQorICAgICAgICAgICAgICAgIC8vIG1hdGNoZXJzIHBlciBjb2x1bW4sIHdlIG5lZWQgdG8gc2NhbiBhbGwgdGhlIG9sZGVyIHZlcnNpb25zIG9mIAorICAgICAgICAgICAgICAgIC8vIHRoaXMgcm93IHRvIHBpY2sgdXAgdGhlIHJlc3Qgb2YgdGhlIGZhbWlseSBtZW1iZXJzCisgICAgICAgICAgICAgICAgaWYgKCF3aWxkY2FyZE1hdGNoICYmICFtdWx0aXBsZU1hdGNoZXJzICYmCisgICAgICAgICAgICAgICAgICAgIChrdi5nZXRUaW1lc3RhbXAoKSAhPSBjaG9zZW5UaW1lc3RhbXApKSB7CisgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gTW92ZSBvbiB0byBuZXh0IHJvdy4KKyAgICAgICAgICAgIHJlc3VsdFNldHNbaV0uY2xlYXIoKTsKKyAgICAgICAgICAgIGlmICghc2Nhbm5lcnNbaV0ubmV4dChyZXN1bHRTZXRzW2ldKSkgeworICAgICAgICAgICAgICBjbG9zZVNjYW5uZXIoaSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIG1vcmVUb0ZvbGxvdyA9IGNob3NlblRpbWVzdGFtcCA+PSAwOworICAgICAgaWYgKGRhdGFGaWx0ZXIgIT0gbnVsbCkgeworICAgICAgICBpZiAoZGF0YUZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSkgeworICAgICAgICAgIG1vcmVUb0ZvbGxvdyA9IGZhbHNlOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChyZXN1bHRzLmlzRW1wdHkoKSAmJiAhZmlsdGVyZWQpIHsKKyAgICAgICAgLy8gVGhlcmUgd2VyZSBubyByZXN1bHRzIGZvdW5kIGZvciB0aGlzIHJvdy4gIE1hcmtlZCBpdCBhcyAKKyAgICAgICAgLy8gJ2ZpbHRlcmVkJy1vdXQgb3RoZXJ3aXNlIHdlIHdpbGwgbm90IG1vdmUgb24gdG8gdGhlIG5leHQgcm93LgorICAgICAgICBmaWx0ZXJlZCA9IHRydWU7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8vIElmIHdlIGdvdCBubyByZXN1bHRzLCB0aGVuIHRoZXJlIGlzIG5vIG1vcmUgdG8gZm9sbG93LgorICAgIGlmIChyZXN1bHRzID09IG51bGwgfHwgcmVzdWx0cy5pc0VtcHR5KCkpIHsKKyAgICAgIG1vcmVUb0ZvbGxvdyA9IGZhbHNlOworICAgIH0KKyAgICAKKyAgICAvLyBNYWtlIHN1cmUgc2Nhbm5lcnMgY2xvc2VkIGlmIG5vIG1vcmUgcmVzdWx0cworICAgIGlmICghbW9yZVRvRm9sbG93KSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNjYW5uZXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGlmIChudWxsICE9IHNjYW5uZXJzW2ldKSB7CisgICAgICAgICAgY2xvc2VTY2FubmVyKGkpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIAorICAgIHJldHVybiBtb3JlVG9Gb2xsb3c7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9jay5yZWFkTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorCisgIC8qKiBTaHV0IGRvd24gYSBzaW5nbGUgc2Nhbm5lciAqLworICB2b2lkIGNsb3NlU2Nhbm5lcihpbnQgaSkgeworICAgIHRyeSB7CisgICAgICB0cnkgeworICAgICAgICBzY2FubmVyc1tpXS5jbG9zZSgpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cud2FybihCeXRlcy50b1N0cmluZyhzdG9yZS5zdG9yZU5hbWUpICsgIiBmYWlsZWQgY2xvc2luZyBzY2FubmVyICIgKworICAgICAgICAgIGksIGUpOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzY2FubmVyc1tpXSA9IG51bGw7CisgICAgICByZXN1bHRTZXRzW2ldID0gbnVsbDsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICB0aGlzLmNsb3Npbmcuc2V0KHRydWUpOworICAgIHRoaXMuc3RvcmUuZGVsZXRlQ2hhbmdlZFJlYWRlck9ic2VydmVyKHRoaXMpOworICAgIGRvQ2xvc2UoKTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGRvQ2xvc2UoKSB7CisgICAgZm9yIChpbnQgaSA9IE1FTVNfSU5ERVg7IGkgPCBzY2FubmVycy5sZW5ndGg7IGkrKykgeworICAgICAgaWYgKHNjYW5uZXJzW2ldICE9IG51bGwpIHsKKyAgICAgICAgY2xvc2VTY2FubmVyKGkpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLy8gSW1wbGVtZW50YXRpb24gb2YgQ2hhbmdlZFJlYWRlcnNPYnNlcnZlcgorICAKKyAgcHVibGljIHZvaWQgdXBkYXRlUmVhZGVycygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMuY2xvc2luZy5nZXQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICB0aGlzLmxvY2sud3JpdGVMb2NrKCkubG9jaygpOworICAgIHRyeSB7CisgICAgICBNYXA8TG9uZywgU3RvcmVGaWxlPiBtYXAgPSB0aGlzLnN0b3JlLmdldFN0b3JlZmlsZXMoKTsKKyAgICAgIGlmICh0aGlzLnNjYW5uZXJzW0hTRlNfSU5ERVhdID09IG51bGwgJiYgbWFwICE9IG51bGwgJiYgbWFwLnNpemUoKSA+IDApIHsKKyAgICAgICAgLy8gUHJlc3VtZSB0aGF0IHdlIHdlbnQgZnJvbSBubyByZWFkZXJzIHRvIGF0IGxlYXN0IG9uZSAtLSBuZWVkIHRvIHB1dAorICAgICAgICAvLyBhIEhTdG9yZVNjYW5uZXIgaW4gcGxhY2UuCisgICAgICAgIHRyeSB7CisgICAgICAgICAgLy8gSSB0aGluayBpdHMgc2FmZSBnZXR0aW5nIGtleSBmcm9tIG1lbSBhdCB0aGlzIHN0YWdlIC0tIGl0IHNob3VsZG4ndCBoYXZlCisgICAgICAgICAgLy8gYmVlbiBmbHVzaGVkIHlldAorICAgICAgICAgIC8vIFRPRE86IE1BS0UgU1VSRSBXRSBVUERBVEUgRlJPTSBUUlVOTksuCisgICAgICAgICAgdGhpcy5zY2FubmVyc1tIU0ZTX0lOREVYXSA9IG5ldyBTdG9yZUZpbGVTY2FubmVyKHRoaXMuc3RvcmUsCisgICAgICAgICAgICAgIHRoaXMudGltZXN0YW1wLCB0aGlzLiBjb2x1bW5zLCB0aGlzLnJlc3VsdFNldHNbTUVNU19JTkRFWF0uZ2V0KDApLmdldFJvdygpKTsKKyAgICAgICAgICBjaGVja1NjYW5uZXJGbGFncyhIU0ZTX0lOREVYKTsKKyAgICAgICAgICBzZXR1cFNjYW5uZXIoSFNGU19JTkRFWCk7CisgICAgICAgICAgTE9HLmRlYnVnKCJBZGRlZCBhIFN0b3JlRmlsZVNjYW5uZXIgdG8gb3V0c3RhbmRpbmcgSFN0b3JlU2Nhbm5lciIpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZG9DbG9zZSgpOworICAgICAgICAgIHRocm93IGU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5sb2NrLndyaXRlTG9jaygpLnVubG9jaygpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Xcm9uZ1JlZ2lvbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1dyb25nUmVnaW9uRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNmZjlmZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9Xcm9uZ1JlZ2lvbkV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIFRocm93biB3aGVuIGEgcmVxdWVzdCBjb250YWlucyBhIGtleSB3aGljaCBpcyBub3QgcGFydCBvZiB0aGlzIHJlZ2lvbgorICovCitwdWJsaWMgY2xhc3MgV3JvbmdSZWdpb25FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDk5MzE3OTYyNzg1NjM5MjUyNkw7CisKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBXcm9uZ1JlZ2lvbkV4Y2VwdGlvbigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBzIG1lc3NhZ2UKKyAgICovCisgIHB1YmxpYyBXcm9uZ1JlZ2lvbkV4Y2VwdGlvbihTdHJpbmcgcykgeworICAgIHN1cGVyKHMpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL21ldHJpY3MvUmVnaW9uU2VydmVyTWV0cmljcy5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL21ldHJpY3MvUmVnaW9uU2VydmVyTWV0cmljcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhNzNmNTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvbWV0cmljcy9SZWdpb25TZXJ2ZXJNZXRyaWNzLmphdmEKQEAgLTAsMCArMSwxNjMgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIubWV0cmljczsKKworaW1wb3J0IGphdmEubGFuZy5tYW5hZ2VtZW50Lk1hbmFnZW1lbnRGYWN0b3J5OworaW1wb3J0IGphdmEubGFuZy5tYW5hZ2VtZW50Lk1lbW9yeVVzYWdlOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWV0cmljcy5NZXRyaWNzUmF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlN0cmluZ3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5NZXRyaWNzQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLk1ldHJpY3NSZWNvcmQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5NZXRyaWNzVXRpbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLlVwZGF0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWV0cmljcy5qdm0uSnZtTWV0cmljczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tZXRyaWNzLnV0aWwuTWV0cmljc0ludFZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1ldHJpY3MudXRpbC5NZXRyaWNzVGltZVZhcnlpbmdSYXRlOworCisvKiogCisgKiBUaGlzIGNsYXNzIGlzIGZvciBtYWludGFpbmluZyB0aGUgdmFyaW91cyByZWdpb25zZXJ2ZXIgc3RhdGlzdGljcworICogYW5kIHB1Ymxpc2hpbmcgdGhlbSB0aHJvdWdoIHRoZSBtZXRyaWNzIGludGVyZmFjZXMuCisgKiA8cD4KKyAqIFRoaXMgY2xhc3MgaGFzIGEgbnVtYmVyIG9mIG1ldHJpY3MgdmFyaWFibGVzIHRoYXQgYXJlIHB1YmxpY2x5IGFjY2Vzc2libGU7CisgKiB0aGVzZSB2YXJpYWJsZXMgKG9iamVjdHMpIGhhdmUgbWV0aG9kcyB0byB1cGRhdGUgdGhlaXIgdmFsdWVzLgorICovCitwdWJsaWMgY2xhc3MgUmVnaW9uU2VydmVyTWV0cmljcyBpbXBsZW1lbnRzIFVwZGF0ZXIgeworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkpOworICBwcml2YXRlIGZpbmFsIE1ldHJpY3NSZWNvcmQgbWV0cmljc1JlY29yZDsKKyAgcHJpdmF0ZSBsb25nIGxhc3RVcGRhdGUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1CID0gMTAyNCoxMDI0OworICAgIAorICBwdWJsaWMgZmluYWwgTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZSBhdG9taWNJbmNyZW1lbnRUaW1lID0KKyAgICBuZXcgTWV0cmljc1RpbWVWYXJ5aW5nUmF0ZSgiYXRvbWljSW5jcmVtZW50VGltZSIpOworICAKKyAgLyoqCisgICAqIENvdW50IG9mIHJlZ2lvbnMgY2FycmllZCBieSB0aGlzIHJlZ2lvbnNlcnZlcgorICAgKi8KKyAgcHVibGljIGZpbmFsIE1ldHJpY3NJbnRWYWx1ZSByZWdpb25zID0gbmV3IE1ldHJpY3NJbnRWYWx1ZSgicmVnaW9ucyIpOworCisgIC8qCisgICAqIENvdW50IG9mIHJlcXVlc3RzIHRvIHRoZSByZWdpb25zZXJ2ZXJzIHNpbmNlIGxhc3QgY2FsbCB0byBtZXRyaWNzIHVwZGF0ZQorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBNZXRyaWNzUmF0ZSByZXF1ZXN0cyA9IG5ldyBNZXRyaWNzUmF0ZSgicmVxdWVzdHMiKTsKKworICAvKioKKyAgICogQ291bnQgb2Ygc3RvcmVzIG9wZW4gb24gdGhlIHJlZ2lvbnNlcnZlci4KKyAgICovCisgIHB1YmxpYyBmaW5hbCBNZXRyaWNzSW50VmFsdWUgc3RvcmVzID0gbmV3IE1ldHJpY3NJbnRWYWx1ZSgic3RvcmVzIik7CisKKyAgLyoqCisgICAqIENvdW50IG9mIHN0b3JlZmlsZXMgb3BlbiBvbiB0aGUgcmVnaW9uc2VydmVyLgorICAgKi8KKyAgcHVibGljIGZpbmFsIE1ldHJpY3NJbnRWYWx1ZSBzdG9yZWZpbGVzID0gbmV3IE1ldHJpY3NJbnRWYWx1ZSgic3RvcmVmaWxlcyIpOworCisgIC8qKgorICAgKiBTdW0gb2YgYWxsIHRoZSBzdG9yZWZpbGUgaW5kZXggc2l6ZXMgaW4gdGhpcyByZWdpb25zZXJ2ZXIgaW4gTUIKKyAgICovCisgIHB1YmxpYyBmaW5hbCBNZXRyaWNzSW50VmFsdWUgc3RvcmVmaWxlSW5kZXhTaXplTUIgPQorICAgIG5ldyBNZXRyaWNzSW50VmFsdWUoInN0b3JlZmlsZUluZGV4U2l6ZU1CIik7CisKKyAgLyoqCisgICAqIFN1bSBvZiBhbGwgdGhlIG1lbWNhY2hlIHNpemVzIGluIHRoaXMgcmVnaW9uc2VydmVyIGluIE1CCisgICAqLworICBwdWJsaWMgZmluYWwgTWV0cmljc0ludFZhbHVlIG1lbWNhY2hlU2l6ZU1CID0KKyAgICBuZXcgTWV0cmljc0ludFZhbHVlKCJtZW1jYWNoZVNpemVNQiIpOworCisgIHB1YmxpYyBSZWdpb25TZXJ2ZXJNZXRyaWNzKCkgeworICAgIE1ldHJpY3NDb250ZXh0IGNvbnRleHQgPSBNZXRyaWNzVXRpbC5nZXRDb250ZXh0KCJoYmFzZSIpOworICAgIG1ldHJpY3NSZWNvcmQgPSBNZXRyaWNzVXRpbC5jcmVhdGVSZWNvcmQoY29udGV4dCwgInJlZ2lvbnNlcnZlciIpOworICAgIFN0cmluZyBuYW1lID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCk7CisgICAgbWV0cmljc1JlY29yZC5zZXRUYWcoIlJlZ2lvblNlcnZlciIsIG5hbWUpOworICAgIGNvbnRleHQucmVnaXN0ZXJVcGRhdGVyKHRoaXMpOworICAgIC8vIEFkZCBqdm1tZXRyaWNzLgorICAgIEp2bU1ldHJpY3MuaW5pdCgiUmVnaW9uU2VydmVyIiwgbmFtZSk7CisgICAgTE9HLmluZm8oIkluaXRpYWxpemVkIik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgeworICAgIC8vIG5vdWdodCB0byBkby4KKyAgfQorICAgIAorICAvKioKKyAgICogU2luY2UgdGhpcyBvYmplY3QgaXMgYSByZWdpc3RlcmVkIHVwZGF0ZXIsIHRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkCisgICAqIHBlcmlvZGljYWxseSwgZS5nLiBldmVyeSA1IHNlY29uZHMuCisgICAqIEBwYXJhbSB1bnVzZWQgCisgICAqLworICBwdWJsaWMgdm9pZCBkb1VwZGF0ZXMoTWV0cmljc0NvbnRleHQgdW51c2VkKSB7CisgICAgc3luY2hyb25pemVkICh0aGlzKSB7CisgICAgICB0aGlzLnN0b3Jlcy5wdXNoTWV0cmljKHRoaXMubWV0cmljc1JlY29yZCk7CisgICAgICB0aGlzLnN0b3JlZmlsZXMucHVzaE1ldHJpYyh0aGlzLm1ldHJpY3NSZWNvcmQpOworICAgICAgdGhpcy5zdG9yZWZpbGVJbmRleFNpemVNQi5wdXNoTWV0cmljKHRoaXMubWV0cmljc1JlY29yZCk7CisgICAgICB0aGlzLm1lbWNhY2hlU2l6ZU1CLnB1c2hNZXRyaWModGhpcy5tZXRyaWNzUmVjb3JkKTsKKyAgICAgIHRoaXMucmVnaW9ucy5wdXNoTWV0cmljKHRoaXMubWV0cmljc1JlY29yZCk7CisgICAgICB0aGlzLnJlcXVlc3RzLnB1c2hNZXRyaWModGhpcy5tZXRyaWNzUmVjb3JkKTsKKyAgICB9CisgICAgdGhpcy5tZXRyaWNzUmVjb3JkLnVwZGF0ZSgpOworICAgIHRoaXMubGFzdFVwZGF0ZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICB9CisgIAorICBwdWJsaWMgdm9pZCByZXNldEFsbE1pbk1heCgpIHsKKyAgICAvLyBOb3RoaW5nIHRvIGRvCisgIH0KKworICAvKioKKyAgICogQHJldHVybiBDb3VudCBvZiByZXF1ZXN0cy4KKyAgICovCisgIHB1YmxpYyBmbG9hdCBnZXRSZXF1ZXN0cygpIHsKKyAgICByZXR1cm4gdGhpcy5yZXF1ZXN0cy5nZXRQcmV2aW91c0ludGVydmFsVmFsdWUoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBpbmMgSG93IG11Y2ggdG8gYWRkIHRvIHJlcXVlc3RzLgorICAgKi8KKyAgcHVibGljIHZvaWQgaW5jcmVtZW50UmVxdWVzdHMoZmluYWwgaW50IGluYykgeworICAgIHRoaXMucmVxdWVzdHMuaW5jKGluYyk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgIGludCBzZWNvbmRzID0gKGludCkoKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gdGhpcy5sYXN0VXBkYXRlKS8xMDAwKTsKKyAgICBpZiAoc2Vjb25kcyA9PSAwKSB7CisgICAgICBzZWNvbmRzID0gMTsKKyAgICB9CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAicmVxdWVzdCIsCisgICAgICBGbG9hdC52YWx1ZU9mKHRoaXMucmVxdWVzdHMuZ2V0UHJldmlvdXNJbnRlcnZhbFZhbHVlKCkpKTsKKyAgICBzYiA9IFN0cmluZ3MuYXBwZW5kS2V5VmFsdWUoc2IsICJyZWdpb25zIiwKKyAgICAgIEludGVnZXIudmFsdWVPZih0aGlzLnJlZ2lvbnMuZ2V0KCkpKTsKKyAgICBzYiA9IFN0cmluZ3MuYXBwZW5kS2V5VmFsdWUoc2IsICJzdG9yZXMiLAorICAgICAgSW50ZWdlci52YWx1ZU9mKHRoaXMuc3RvcmVzLmdldCgpKSk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAic3RvcmVmaWxlcyIsCisgICAgICBJbnRlZ2VyLnZhbHVlT2YodGhpcy5zdG9yZWZpbGVzLmdldCgpKSk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAic3RvcmVmaWxlSW5kZXhTaXplIiwKKyAgICAgIEludGVnZXIudmFsdWVPZih0aGlzLnN0b3JlZmlsZUluZGV4U2l6ZU1CLmdldCgpKSk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAibWVtY2FjaGVTaXplIiwKKyAgICAgIEludGVnZXIudmFsdWVPZih0aGlzLm1lbWNhY2hlU2l6ZU1CLmdldCgpKSk7CisgICAgLy8gRHVwbGljYXRlIGZyb20ganZtbWV0cmljcyBiZWNhdXNlIG1ldHJpY3MgYXJlIHByaXZhdGUgdGhlcmUgc28KKyAgICAvLyBpbmFjY2Vzc2libGUuCisgICAgTWVtb3J5VXNhZ2UgbWVtb3J5ID0KKyAgICAgIE1hbmFnZW1lbnRGYWN0b3J5LmdldE1lbW9yeU1YQmVhbigpLmdldEhlYXBNZW1vcnlVc2FnZSgpOworICAgIHNiID0gU3RyaW5ncy5hcHBlbmRLZXlWYWx1ZShzYiwgInVzZWRIZWFwIiwKKyAgICAgIExvbmcudmFsdWVPZihtZW1vcnkuZ2V0VXNlZCgpL01CKSk7CisgICAgc2IgPSBTdHJpbmdzLmFwcGVuZEtleVZhbHVlKHNiLCAibWF4SGVhcCIsCisgICAgICBMb25nLnZhbHVlT2YobWVtb3J5LmdldE1heCgpL01CKSk7CisgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90YWJsZWluZGV4ZWQvSW5kZXhlZFJlZ2lvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL3RhYmxlaW5kZXhlZC9JbmRleGVkUmVnaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhlMjQ4MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90YWJsZWluZGV4ZWQvSW5kZXhlZFJlZ2lvbi5qYXZhCkBAIC0wLDAgKzEsMzQ2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5hdmlnYWJsZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CitpbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQuSW5kZXhTcGVjaWZpY2F0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQuSW5kZXhlZFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoT3BlcmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkZsdXNoUmVxdWVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5ITG9nOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsLlRyYW5zYWN0aW9uYWxSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworY2xhc3MgSW5kZXhlZFJlZ2lvbiBleHRlbmRzIFRyYW5zYWN0aW9uYWxSZWdpb24geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhJbmRleGVkUmVnaW9uLmNsYXNzKTsKKworICBwcml2YXRlIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICBwcml2YXRlIE1hcDxJbmRleFNwZWNpZmljYXRpb24sIEhUYWJsZT4gaW5kZXhTcGVjVG9UYWJsZSA9IG5ldyBIYXNoTWFwPEluZGV4U3BlY2lmaWNhdGlvbiwgSFRhYmxlPigpOworCisgIHB1YmxpYyBJbmRleGVkUmVnaW9uKGZpbmFsIFBhdGggYmFzZWRpciwgZmluYWwgSExvZyBsb2csIGZpbmFsIEZpbGVTeXN0ZW0gZnMsCisgICAgICBmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgZmluYWwgSFJlZ2lvbkluZm8gcmVnaW9uSW5mbywKKyAgICAgIGZpbmFsIEZsdXNoUmVxdWVzdGVyIGZsdXNoTGlzdGVuZXIpIHsKKyAgICBzdXBlcihiYXNlZGlyLCBsb2csIGZzLCBjb25mLCByZWdpb25JbmZvLCBmbHVzaExpc3RlbmVyKTsKKyAgICB0aGlzLmNvbmYgPSBjb25mOworICB9CisKKyAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgSFRhYmxlIGdldEluZGV4VGFibGUoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGUgaW5kZXhUYWJsZSA9IGluZGV4U3BlY1RvVGFibGUuZ2V0KGluZGV4KTsKKyAgICBpZiAoaW5kZXhUYWJsZSA9PSBudWxsKSB7CisgICAgICBpbmRleFRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBpbmRleC5nZXRJbmRleGVkVGFibGVOYW1lKHN1cGVyCisgICAgICAgICAgLmdldFJlZ2lvbkluZm8oKS5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCkpKTsKKyAgICAgIGluZGV4U3BlY1RvVGFibGUucHV0KGluZGV4LCBpbmRleFRhYmxlKTsKKyAgICB9CisgICAgcmV0dXJuIGluZGV4VGFibGU7CisgIH0KKworICBwcml2YXRlIENvbGxlY3Rpb248SW5kZXhTcGVjaWZpY2F0aW9uPiBnZXRJbmRleGVzKCkgeworICAgIHJldHVybiBzdXBlci5nZXRSZWdpb25JbmZvKCkuZ2V0VGFibGVEZXNjKCkuZ2V0SW5kZXhlcygpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiYXRjaFVwZGF0ZQorICAgKiBAcGFyYW0gbG9ja2lkCisgICAqIEBwYXJhbSB3cml0ZVRvV0FMIGlmIHRydWUsIHRoZW4gd2Ugd3JpdGUgdGhpcyB1cGRhdGUgdG8gdGhlIGxvZworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUsIEludGVnZXIgbG9ja2lkLCBib29sZWFuIHdyaXRlVG9XQUwpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHVwZGF0ZUluZGV4ZXMoYmF0Y2hVcGRhdGUpOyAvLyBEbyB0aGlzIGZpcnN0IGJlY2F1c2Ugd2lsbCB3YW50IHRvIHNlZSB0aGUgb2xkIHJvdworICAgIHN1cGVyLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBsb2NraWQsIHdyaXRlVG9XQUwpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHVwZGF0ZUluZGV4ZXMoQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTGlzdDxJbmRleFNwZWNpZmljYXRpb24+IGluZGV4ZXNUb1VwZGF0ZSA9IG5ldyBMaW5rZWRMaXN0PEluZGV4U3BlY2lmaWNhdGlvbj4oKTsKKworICAgIC8vIEZpbmQgdGhlIGluZGV4ZXMgd2UgbmVlZCB0byB1cGRhdGUKKyAgICBmb3IgKEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleCA6IGdldEluZGV4ZXMoKSkgeworICAgICAgaWYgKHBvc3NpYmx5QXBwbGllc1RvSW5kZXgoaW5kZXgsIGJhdGNoVXBkYXRlKSkgeworICAgICAgICBpbmRleGVzVG9VcGRhdGUuYWRkKGluZGV4KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoaW5kZXhlc1RvVXBkYXRlLnNpemUoKSA9PSAwKSB7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgTmF2aWdhYmxlU2V0PGJ5dGVbXT4gbmVlZGVkQ29sdW1ucyA9IGdldENvbHVtbnNGb3JJbmRleGVzKGluZGV4ZXNUb1VwZGF0ZSk7CisKKyAgICBOYXZpZ2FibGVNYXA8Ynl0ZVtdLCBieXRlW10+IG5ld0NvbHVtblZhbHVlcyA9CisgICAgICBnZXRDb2x1bW5zRnJvbUJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlKTsKKyAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBvbGRDb2x1bW5DZWxscyA9IHN1cGVyLmdldEZ1bGwoYmF0Y2hVcGRhdGUuZ2V0Um93KCksCisgICAgICAgIG5lZWRlZENvbHVtbnMsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgCisgICAgLy8gSGFuZGxlIGRlbGV0ZSBiYXRjaCB1cGRhdGVzLiBHbyBiYWNrIGFuZCBnZXQgdGhlIG5leHQgb2xkZXIgdmFsdWVzCisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBvcCA6IGJhdGNoVXBkYXRlKSB7CisgICAgICBpZiAoIW9wLmlzUHV0KCkpIHsKKyAgICAgICAgQ2VsbCBjdXJyZW50ID0gb2xkQ29sdW1uQ2VsbHMuZ2V0KG9wLmdldENvbHVtbigpKTsKKyAgICAgICAgaWYgKGN1cnJlbnQgIT0gbnVsbCkgeworICAgICAgICAgIC8vIFRPRE86IEZpeCB0aGlzIHByb2ZsaWdhY3khISEgU3QuQWNrCisgICAgICAgICAgQ2VsbCBbXSBvbGRlciA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHN1cGVyLmdldChiYXRjaFVwZGF0ZS5nZXRSb3coKSwKKyAgICAgICAgICAgICAgb3AuZ2V0Q29sdW1uKCksIGN1cnJlbnQuZ2V0VGltZXN0YW1wKCksIDEpKTsKKyAgICAgICAgICBpZiAob2xkZXIgIT0gbnVsbCAmJiBvbGRlci5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICBuZXdDb2x1bW5WYWx1ZXMucHV0KG9wLmdldENvbHVtbigpLCBvbGRlclswXS5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLy8gQWRkIHRoZSBvbGQgdmFsdWVzIHRvIHRoZSBuZXcgaWYgdGhleSBhcmUgbm90IHRoZXJlCisgICAgZm9yIChFbnRyeTxieXRlW10sIENlbGw+IG9sZEVudHJ5IDogb2xkQ29sdW1uQ2VsbHMuZW50cnlTZXQoKSkgeworICAgICAgaWYgKCFuZXdDb2x1bW5WYWx1ZXMuY29udGFpbnNLZXkob2xkRW50cnkuZ2V0S2V5KCkpKSB7CisgICAgICAgIG5ld0NvbHVtblZhbHVlcy5wdXQob2xkRW50cnkuZ2V0S2V5KCksIG9sZEVudHJ5LmdldFZhbHVlKCkuZ2V0VmFsdWUoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAKKyAgICAKKyAgICBJdGVyYXRvcjxJbmRleFNwZWNpZmljYXRpb24+IGluZGV4SXRlcmF0b3IgPSBpbmRleGVzVG9VcGRhdGUuaXRlcmF0b3IoKTsKKyAgICB3aGlsZSAoaW5kZXhJdGVyYXRvci5oYXNOZXh0KCkpIHsKKyAgICAgIEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMgPSBpbmRleEl0ZXJhdG9yLm5leHQoKTsKKyAgICAgIGlmICghZG9lc0FwcGx5VG9JbmRleChpbmRleFNwZWMsIG5ld0NvbHVtblZhbHVlcykpIHsKKyAgICAgICAgaW5kZXhJdGVyYXRvci5yZW1vdmUoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBTb3J0ZWRNYXA8Ynl0ZVtdLCBieXRlW10+IG9sZENvbHVtblZhbHVlcyA9IGNvbnZlcnRUb1ZhbHVlTWFwKG9sZENvbHVtbkNlbGxzKTsKKyAgICAKKyAgICBmb3IgKEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMgOiBpbmRleGVzVG9VcGRhdGUpIHsKKyAgICAgIHJlbW92ZU9sZEluZGV4RW50cnkoaW5kZXhTcGVjLCBiYXRjaFVwZGF0ZS5nZXRSb3coKSwgb2xkQ29sdW1uVmFsdWVzKTsKKyAgICAgIHVwZGF0ZUluZGV4KGluZGV4U3BlYywgYmF0Y2hVcGRhdGUuZ2V0Um93KCksIG5ld0NvbHVtblZhbHVlcyk7CisgICAgfQorICB9CisKKyAgLyoqIFJldHVybiB0aGUgY29sdW1ucyBuZWVkZWQgZm9yIHRoZSB1cGRhdGUuICovCisgIHByaXZhdGUgTmF2aWdhYmxlU2V0PGJ5dGVbXT4gZ2V0Q29sdW1uc0ZvckluZGV4ZXMoQ29sbGVjdGlvbjxJbmRleFNwZWNpZmljYXRpb24+IGluZGV4ZXMpIHsKKyAgICBOYXZpZ2FibGVTZXQ8Ynl0ZVtdPiBuZWVkZWRDb2x1bW5zID0gbmV3IFRyZWVTZXQ8Ynl0ZVtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICBmb3IgKEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMgOiBpbmRleGVzKSB7CisgICAgICBmb3IgKGJ5dGVbXSBjb2wgOiBpbmRleFNwZWMuZ2V0QWxsQ29sdW1ucygpKSB7CisgICAgICAgIG5lZWRlZENvbHVtbnMuYWRkKGNvbCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBuZWVkZWRDb2x1bW5zOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlbW92ZU9sZEluZGV4RW50cnkoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4U3BlYywgYnl0ZVtdIHJvdywKKyAgICAgIFNvcnRlZE1hcDxieXRlW10sIGJ5dGVbXT4gb2xkQ29sdW1uVmFsdWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoYnl0ZVtdIGluZGV4ZWRDb2wgOiBpbmRleFNwZWMuZ2V0SW5kZXhlZENvbHVtbnMoKSkgeworICAgICAgaWYgKCFvbGRDb2x1bW5WYWx1ZXMuY29udGFpbnNLZXkoaW5kZXhlZENvbCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJJbmRleCBbIiArIGluZGV4U3BlYy5nZXRJbmRleElkKCkKKyAgICAgICAgICAgICsgIl0gbm90IHRyeWluZyB0byByZW1vdmUgb2xkIGVudHJ5IGZvciByb3cgWyIKKyAgICAgICAgICAgICsgQnl0ZXMudG9TdHJpbmcocm93KSArICJdIGJlY2F1c2UgY29sIFsiCisgICAgICAgICAgICArIEJ5dGVzLnRvU3RyaW5nKGluZGV4ZWRDb2wpICsgIl0gaXMgbWlzc2luZyIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgfQorCisgICAgYnl0ZVtdIG9sZEluZGV4Um93ID0gaW5kZXhTcGVjLmdldEtleUdlbmVyYXRvcigpLmNyZWF0ZUluZGV4S2V5KHJvdywKKyAgICAgICAgb2xkQ29sdW1uVmFsdWVzKTsKKyAgICBMT0cuZGVidWcoIkluZGV4IFsiICsgaW5kZXhTcGVjLmdldEluZGV4SWQoKSArICJdIHJlbW92aW5nIG9sZCBlbnRyeSBbIgorICAgICAgICArIEJ5dGVzLnRvU3RyaW5nKG9sZEluZGV4Um93KSArICJdIik7CisgICAgZ2V0SW5kZXhUYWJsZShpbmRleFNwZWMpLmRlbGV0ZUFsbChvbGRJbmRleFJvdyk7CisgIH0KKyAgCisgIHByaXZhdGUgTmF2aWdhYmxlTWFwPGJ5dGVbXSwgYnl0ZVtdPiBnZXRDb2x1bW5zRnJvbUJhdGNoVXBkYXRlKEJhdGNoVXBkYXRlIGIpIHsKKyAgICBOYXZpZ2FibGVNYXA8Ynl0ZVtdLCBieXRlW10+IGNvbHVtblZhbHVlcyA9IG5ldyBUcmVlTWFwPGJ5dGVbXSwgYnl0ZVtdPigKKyAgICAgICAgQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBvcCA6IGIpIHsKKyAgICAgIGlmIChvcC5pc1B1dCgpKSB7CisgICAgICAgIGNvbHVtblZhbHVlcy5wdXQob3AuZ2V0Q29sdW1uKCksIG9wLmdldFZhbHVlKCkpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY29sdW1uVmFsdWVzOworICB9CisKKyAgLyoqIEFzayBpZiB0aGlzIHVwZGF0ZSAqY291bGQqIGFwcGx5IHRvIHRoZSBpbmRleC4gSXQgbWF5IGFjdHVhbGx5IGFwcGx5IGlmIHNvbWUgb2YgdGhlIGNvbHVtbnMgbmVlZGVkIGFyZSBtaXNzaW5nLgorICAgKiAKKyAgICogQHBhcmFtIGluZGV4U3BlYworICAgKiBAcGFyYW0gYgorICAgKiBAcmV0dXJuIHRydWUgaWYgcG9zc2libHkgYXBwbHkuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gcG9zc2libHlBcHBsaWVzVG9JbmRleChJbmRleFNwZWNpZmljYXRpb24gaW5kZXhTcGVjLCBCYXRjaFVwZGF0ZSBiKSB7CisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBvcCA6IGIpIHsKKyAgICAgIGlmIChpbmRleFNwZWMuY29udGFpbnNDb2x1bW4ob3AuZ2V0Q29sdW1uKCkpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgCisgIC8qKiBBc2sgaWYgdGhpcyB1cGRhdGUgZG9lcyBhcHBseSB0byB0aGUgaW5kZXguIAorICAgKiAKKyAgICogQHBhcmFtIGluZGV4U3BlYworICAgKiBAcGFyYW0gYgorICAgKiBAcmV0dXJuIHRydWUgaWYgcG9zc2libHkgYXBwbHkuCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gZG9lc0FwcGx5VG9JbmRleChJbmRleFNwZWNpZmljYXRpb24gaW5kZXhTcGVjLCAgU29ydGVkTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjb2x1bW5WYWx1ZXMpIHsKKyAgICAKKyAgICBmb3IgKGJ5dGUgW10gbmVlZGVkQ29sIDogaW5kZXhTcGVjLmdldEluZGV4ZWRDb2x1bW5zKCkpIHsKKyAgICAgIGlmICghIGNvbHVtblZhbHVlcy5jb250YWluc0tleShuZWVkZWRDb2wpKSAgeworICAgICAgICBMT0cuZGVidWcoIkluZGV4IFsiICsgaW5kZXhTcGVjLmdldEluZGV4SWQoKSArICJdIGNhbid0IGJlIHVwZGF0ZWQgYmVjYXVzZSBbIgorICAgICAgICAgICAgKyBCeXRlcy50b1N0cmluZyhuZWVkZWRDb2wpICsgIl0gaXMgbWlzc2luZyIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHVwZGF0ZUluZGV4KEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMsIGJ5dGVbXSByb3csCisgICAgICBTb3J0ZWRNYXA8Ynl0ZVtdLCBieXRlW10+IGNvbHVtblZhbHVlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCYXRjaFVwZGF0ZSBpbmRleFVwZGF0ZSA9IGNyZWF0ZUluZGV4VXBkYXRlKGluZGV4U3BlYywgcm93LCBjb2x1bW5WYWx1ZXMpOworICAgIGdldEluZGV4VGFibGUoaW5kZXhTcGVjKS5jb21taXQoaW5kZXhVcGRhdGUpOworICAgIExPRy5kZWJ1ZygiSW5kZXggWyIgKyBpbmRleFNwZWMuZ2V0SW5kZXhJZCgpICsgIl0gYWRkaW5nIG5ldyBlbnRyeSBbIgorICAgICAgICArIEJ5dGVzLnRvU3RyaW5nKGluZGV4VXBkYXRlLmdldFJvdygpKSArICJdIGZvciByb3cgWyIKKyAgICAgICAgKyBCeXRlcy50b1N0cmluZyhyb3cpICsgIl0iKTsKKworICB9CisKKyAgcHJpdmF0ZSBCYXRjaFVwZGF0ZSBjcmVhdGVJbmRleFVwZGF0ZShJbmRleFNwZWNpZmljYXRpb24gaW5kZXhTcGVjLAorICAgICAgYnl0ZVtdIHJvdywgU29ydGVkTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjb2x1bW5WYWx1ZXMpIHsKKyAgICBieXRlW10gaW5kZXhSb3cgPSBpbmRleFNwZWMuZ2V0S2V5R2VuZXJhdG9yKCkuY3JlYXRlSW5kZXhLZXkocm93LAorICAgICAgICBjb2x1bW5WYWx1ZXMpOworICAgIEJhdGNoVXBkYXRlIHVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShpbmRleFJvdyk7CisKKyAgICB1cGRhdGUucHV0KEluZGV4ZWRUYWJsZS5JTkRFWF9CQVNFX1JPV19DT0xVTU4sIHJvdyk7CisKKyAgICBmb3IgKGJ5dGVbXSBjb2wgOiBpbmRleFNwZWMuZ2V0SW5kZXhlZENvbHVtbnMoKSkgeworICAgICAgYnl0ZVtdIHZhbCA9IGNvbHVtblZhbHVlcy5nZXQoY29sKTsKKyAgICAgIGlmICh2YWwgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVW5leHBlY3RlZCBtaXNzaW5nIGNvbHVtbiB2YWx1ZS4gWyIrQnl0ZXMudG9TdHJpbmcoY29sKSsiXSIpOworICAgICAgfQorICAgICAgdXBkYXRlLnB1dChjb2wsIHZhbCk7CisgICAgfQorICAgIAorICAgIGZvciAoYnl0ZSBbXSBjb2wgOiBpbmRleFNwZWMuZ2V0QWRkaXRpb25hbENvbHVtbnMoKSkgeworICAgICAgYnl0ZVtdIHZhbCA9IGNvbHVtblZhbHVlcy5nZXQoY29sKTsKKyAgICAgIGlmICh2YWwgIT0gbnVsbCkgeworICAgICAgICB1cGRhdGUucHV0KGNvbCwgdmFsKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdXBkYXRlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBieXRlW10gcm93LCBmaW5hbCBsb25nIHRzLCBmaW5hbCBJbnRlZ2VyIGxvY2tpZCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICBpZiAoZ2V0SW5kZXhlcygpLnNpemUoKSAhPSAwKSB7CisKKyAgICAgIC8vIE5lZWQgYWxsIGNvbHVtbnMKKyAgICAgIE5hdmlnYWJsZVNldDxieXRlW10+IG5lZWRlZENvbHVtbnMgPSBnZXRDb2x1bW5zRm9ySW5kZXhlcyhnZXRJbmRleGVzKCkpOworCisgICAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBvbGRDb2x1bW5DZWxscyA9IHN1cGVyLmdldEZ1bGwocm93LAorICAgICAgICAgIG5lZWRlZENvbHVtbnMsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgICBTb3J0ZWRNYXA8Ynl0ZVtdLCBieXRlW10+IG9sZENvbHVtblZhbHVlcyA9IGNvbnZlcnRUb1ZhbHVlTWFwKG9sZENvbHVtbkNlbGxzKTsKKyAgICAgIAorICAgICAgCisgICAgICBmb3IgKEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMgOiBnZXRJbmRleGVzKCkpIHsKKyAgICAgICAgcmVtb3ZlT2xkSW5kZXhFbnRyeShpbmRleFNwZWMsIHJvdywgb2xkQ29sdW1uVmFsdWVzKTsKKyAgICAgIH0KKworICAgICAgLy8gSGFuZGxlIGlmIHRoZXJlIGlzIHN0aWxsIGEgdmVyc2lvbiB2aXNpYmxlLgorICAgICAgaWYgKHRzICE9IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkgeworICAgICAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBjdXJyZW50Q29sdW1uQ2VsbHMgPSBzdXBlci5nZXRGdWxsKHJvdywKKyAgICAgICAgICAgIG5lZWRlZENvbHVtbnMsIHRzLCAxLCBudWxsKTsKKyAgICAgICAgU29ydGVkTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjdXJyZW50Q29sdW1uVmFsdWVzID0gY29udmVydFRvVmFsdWVNYXAoY3VycmVudENvbHVtbkNlbGxzKTsKKyAgICAgICAgCisgICAgICAgIGZvciAoSW5kZXhTcGVjaWZpY2F0aW9uIGluZGV4U3BlYyA6IGdldEluZGV4ZXMoKSkgeworICAgICAgICAgIGlmIChkb2VzQXBwbHlUb0luZGV4KGluZGV4U3BlYywgY3VycmVudENvbHVtblZhbHVlcykpIHsKKyAgICAgICAgICAgIHVwZGF0ZUluZGV4KGluZGV4U3BlYywgcm93LCBjdXJyZW50Q29sdW1uVmFsdWVzKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgc3VwZXIuZGVsZXRlQWxsKHJvdywgdHMsIGxvY2tpZCk7CisgIH0KKworICBwcml2YXRlIFNvcnRlZE1hcDxieXRlW10sIGJ5dGVbXT4gY29udmVydFRvVmFsdWVNYXAoCisgICAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBjZWxsTWFwKSB7CisgICAgU29ydGVkTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjdXJyZW50Q29sdW1uVmFsdWVzID0gbmV3IFRyZWVNYXA8Ynl0ZVtdLCBieXRlW10+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgIGZvcihFbnRyeTxieXRlW10sIENlbGw+IGVudHJ5IDogY2VsbE1hcC5lbnRyeVNldCgpKSB7CisgICAgICBjdXJyZW50Q29sdW1uVmFsdWVzLnB1dChlbnRyeS5nZXRLZXkoKSwgZW50cnkuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIGN1cnJlbnRDb2x1bW5WYWx1ZXM7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsKGZpbmFsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdHMsCisgICAgICBmaW5hbCBJbnRlZ2VyIGxvY2tpZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PEluZGV4U3BlY2lmaWNhdGlvbj4gaW5kZXhlc1RvVXBkYXRlID0gbmV3IExpbmtlZExpc3Q8SW5kZXhTcGVjaWZpY2F0aW9uPigpOworICAgIAorICAgIGZvcihJbmRleFNwZWNpZmljYXRpb24gaW5kZXhTcGVjIDogZ2V0SW5kZXhlcygpKSB7CisgICAgICBpZiAoaW5kZXhTcGVjLmNvbnRhaW5zQ29sdW1uKGNvbHVtbikpIHsKKyAgICAgICAgaW5kZXhlc1RvVXBkYXRlLmFkZChpbmRleFNwZWMpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBOYXZpZ2FibGVTZXQ8Ynl0ZVtdPiBuZWVkZWRDb2x1bW5zID0gZ2V0Q29sdW1uc0ZvckluZGV4ZXMoaW5kZXhlc1RvVXBkYXRlKTsKKyAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBvbGRDb2x1bW5DZWxscyA9IHN1cGVyLmdldEZ1bGwocm93LAorICAgICAgICBuZWVkZWRDb2x1bW5zLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIDEsIG51bGwpOworICAgIFNvcnRlZE1hcDxieXRlIFtdLCBieXRlW10+IG9sZENvbHVtblZhbHVlcyA9IGNvbnZlcnRUb1ZhbHVlTWFwKG9sZENvbHVtbkNlbGxzKTsKKyAgICAKKyAgICBmb3IgKEluZGV4U3BlY2lmaWNhdGlvbiBpbmRleFNwZWMgOiBpbmRleGVzVG9VcGRhdGUpIHsKKyAgICAgIHJlbW92ZU9sZEluZGV4RW50cnkoaW5kZXhTcGVjLCByb3csIG9sZENvbHVtblZhbHVlcyk7CisgICAgfSAgICAKKyAgICAKKyAgICAvLyBIYW5kbGUgaWYgdGhlcmUgaXMgc3RpbGwgYSB2ZXJzaW9uIHZpc2libGUuCisgICAgaWYgKHRzICE9IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkgeworICAgICAgTWFwPGJ5dGVbXSwgQ2VsbD4gY3VycmVudENvbHVtbkNlbGxzID0gc3VwZXIuZ2V0RnVsbChyb3csCisgICAgICAgICAgbmVlZGVkQ29sdW1ucywgdHMsIDEsIG51bGwpOworICAgICAgU29ydGVkTWFwPGJ5dGVbXSwgYnl0ZVtdPiBjdXJyZW50Q29sdW1uVmFsdWVzID0gY29udmVydFRvVmFsdWVNYXAoY3VycmVudENvbHVtbkNlbGxzKTsKKyAgICAgIAorICAgICAgZm9yIChJbmRleFNwZWNpZmljYXRpb24gaW5kZXhTcGVjIDogZ2V0SW5kZXhlcygpKSB7CisgICAgICAgIGlmIChkb2VzQXBwbHlUb0luZGV4KGluZGV4U3BlYywgY3VycmVudENvbHVtblZhbHVlcykpIHsKKyAgICAgICAgICB1cGRhdGVJbmRleChpbmRleFNwZWMsIHJvdywgY3VycmVudENvbHVtblZhbHVlcyk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgc3VwZXIuZGVsZXRlQWxsKHJvdywgY29sdW1uLCB0cywgbG9ja2lkKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdGFibGVpbmRleGVkL0luZGV4ZWRSZWdpb25TZXJ2ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90YWJsZWluZGV4ZWQvSW5kZXhlZFJlZ2lvblNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxZmMxZGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdGFibGVpbmRleGVkL0luZGV4ZWRSZWdpb25TZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLnRhYmxlaW5kZXhlZDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSW5kZXhlZFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIudHJhbnNhY3Rpb25hbC5UcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuUHJvZ3Jlc3NhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5IQmFzZVJQQ1Byb3RvY29sVmVyc2lvbjsKKworLyoqCisgKiBSZWdpb25TZXJ2ZXIgd2hpY2ggbWFpbnRhaW5zIHNlY29uZGFyeSBpbmRleGVzLgorICogCisgKiovCitwdWJsaWMgY2xhc3MgSW5kZXhlZFJlZ2lvblNlcnZlciBleHRlbmRzIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIgaW1wbGVtZW50cworICAgIEluZGV4ZWRSZWdpb25JbnRlcmZhY2UgeworCisgIHB1YmxpYyBJbmRleGVkUmVnaW9uU2VydmVyKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMobmV3IEhTZXJ2ZXJBZGRyZXNzKGNvbmYuZ2V0KFJFR0lPTlNFUlZFUl9BRERSRVNTLAorICAgICAgICBERUZBVUxUX1JFR0lPTlNFUlZFUl9BRERSRVNTKSksIGNvbmYpOworICB9CisKKyAgcHVibGljIEluZGV4ZWRSZWdpb25TZXJ2ZXIoSFNlcnZlckFkZHJlc3Mgc2VydmVyQWRkcmVzcywKKyAgICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKHNlcnZlckFkZHJlc3MsIGNvbmYpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBsb25nIGdldFByb3RvY29sVmVyc2lvbihmaW5hbCBTdHJpbmcgcHJvdG9jb2wsIGZpbmFsIGxvbmcgY2xpZW50VmVyc2lvbikKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHByb3RvY29sLmVxdWFscyhJbmRleGVkUmVnaW9uSW50ZXJmYWNlLmNsYXNzLmdldE5hbWUoKSkpIHsKKyAgICAgIHJldHVybiBIQmFzZVJQQ1Byb3RvY29sVmVyc2lvbi52ZXJzaW9uSUQ7CisgICAgfQorICAgIHJldHVybiBzdXBlci5nZXRQcm90b2NvbFZlcnNpb24ocHJvdG9jb2wsIGNsaWVudFZlcnNpb24pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBIUmVnaW9uIGluc3RhbnRpYXRlUmVnaW9uKGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm8pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gciA9IG5ldyBJbmRleGVkUmVnaW9uKEhUYWJsZURlc2NyaXB0b3IuZ2V0VGFibGVEaXIoc3VwZXIKKyAgICAgICAgLmdldFJvb3REaXIoKSwgcmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCkpLCBzdXBlci5sb2csIHN1cGVyCisgICAgICAgIC5nZXRGaWxlU3lzdGVtKCksIHN1cGVyLmNvbmYsIHJlZ2lvbkluZm8sIHN1cGVyLmdldEZsdXNoUmVxdWVzdGVyKCkpOworICAgIHIuaW5pdGlhbGl6ZShudWxsLCBuZXcgUHJvZ3Jlc3NhYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcHJvZ3Jlc3MoKSB7CisgICAgICAgIGFkZFByb2Nlc3NpbmdNZXNzYWdlKHJlZ2lvbkluZm8pOworICAgICAgfQorICAgIH0pOworICAgIHJldHVybiByOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL0NsZWFuT2xkVHJhbnNhY3Rpb25zQ2hvcmUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL0NsZWFuT2xkVHJhbnNhY3Rpb25zQ2hvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMmE1MjJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL3RyYW5zYWN0aW9uYWwvQ2xlYW5PbGRUcmFuc2FjdGlvbnNDaG9yZS5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIudHJhbnNhY3Rpb25hbDsKKworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuQ2hvcmU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CisKKy8qKgorICogQ2xlYW5zIHVwIGNvbW1pdHRlZCB0cmFuc2FjdGlvbnMgd2hlbiB0aGV5IGFyZSBubyBsb25nZXIgbmVlZGVkIHRvIHZlcmlmeQorICogcGVuZGluZyB0cmFuc2FjdGlvbnMuCisgKi8KK2NsYXNzIENsZWFuT2xkVHJhbnNhY3Rpb25zQ2hvcmUgZXh0ZW5kcyBDaG9yZSB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNMRUVQX0NPTkYgPSAiaGJhc2UudHJhbnNhY3Rpb24uY2xlYW4uc2xlZXAiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TTEVFUCA9IDYwICogMTAwMDsKKworICBwcml2YXRlIGZpbmFsIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIgcmVnaW9uU2VydmVyOworCisgIC8qKgorICAgKiBAcGFyYW0gcmVnaW9uU2VydmVyCisgICAqIEBwYXJhbSBzdG9wUmVxdWVzdAorICAgKi8KKyAgcHVibGljIENsZWFuT2xkVHJhbnNhY3Rpb25zQ2hvcmUoCisgICAgICBmaW5hbCBUcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyIHJlZ2lvblNlcnZlciwKKyAgICAgIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcFJlcXVlc3QpIHsKKyAgICBzdXBlcihyZWdpb25TZXJ2ZXIuZ2V0Q29uZmlndXJhdGlvbigpLmdldEludChTTEVFUF9DT05GLCBERUZBVUxUX1NMRUVQKSwKKyAgICAgICAgc3RvcFJlcXVlc3QpOworICAgIHRoaXMucmVnaW9uU2VydmVyID0gcmVnaW9uU2VydmVyOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIGNob3JlKCkgeworICAgIGZvciAoSFJlZ2lvbiByZWdpb24gOiByZWdpb25TZXJ2ZXIuZ2V0T25saW5lUmVnaW9ucygpKSB7CisgICAgICAoKFRyYW5zYWN0aW9uYWxSZWdpb24pIHJlZ2lvbikucmVtb3ZlVW5OZWVkZWRDb21taXRlZFRyYW5zYWN0aW9ucygpOworICAgIH0KKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvblN0YXRlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvblN0YXRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhjMGE1NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uU3RhdGUuamF2YQpAQCAtMCwwICsxLDM2MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlclNldDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuU3RvcFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuV2hpbGVNYXRjaFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaE9wZXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogSG9sZHMgdGhlIHN0YXRlIG9mIGEgdHJhbnNhY3Rpb24uCisgKi8KK2NsYXNzIFRyYW5zYWN0aW9uU3RhdGUgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUcmFuc2FjdGlvblN0YXRlLmNsYXNzKTsKKworICAvKiogQ3VycmVudCBzdGF0dXMuICovCisgIHB1YmxpYyBlbnVtIFN0YXR1cyB7CisgICAgLyoqIEluaXRpYWwgc3RhdHVzLCBzdGlsbCBwZXJmb3JtaW5nIG9wZXJhdGlvbnMuICovCisgICAgUEVORElORywKKyAgICAvKioKKyAgICAgKiBDaGVja2VkIGlmIHdlIGNhbiBjb21taXQsIGFuZCBzYWlkIHllcy4gU3RpbGwgbmVlZCB0byBkZXRlcm1pbmUgdGhlCisgICAgICogZ2xvYmFsIGRlY2lzaW9uLgorICAgICAqLworICAgIENPTU1JVF9QRU5ESU5HLAorICAgIC8qKiBDb21taXR0ZWQuICovCisgICAgQ09NTUlURUQsCisgICAgLyoqIEFib3J0ZWQuICovCisgICAgQUJPUlRFRAorICB9CisKKyAgLyoqCisgICAqIFNpbXBsZSBjb250YWluZXIgb2YgdGhlIHJhbmdlIG9mIHRoZSBzY2FubmVycyB3ZSd2ZSBvcGVuZWQuIFVzZWQgdG8gY2hlY2sKKyAgICogZm9yIGNvbmZsaWN0aW5nIHdyaXRlcy4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFNjYW5SYW5nZSB7CisgICAgcHJvdGVjdGVkIGJ5dGVbXSBzdGFydFJvdzsKKyAgICBwcm90ZWN0ZWQgYnl0ZVtdIGVuZFJvdzsKKworICAgIHB1YmxpYyBTY2FuUmFuZ2UoYnl0ZVtdIHN0YXJ0Um93LCBieXRlW10gZW5kUm93KSB7CisgICAgICB0aGlzLnN0YXJ0Um93ID0gc3RhcnRSb3c7CisgICAgICB0aGlzLmVuZFJvdyA9IGVuZFJvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDaGVjayBpZiB0aGlzIHNjYW4gcmFuZ2UgY29udGFpbnMgdGhlIGdpdmVuIGtleS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcm93S2V5CisgICAgICogQHJldHVybiBib29sZWFuCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoYnl0ZVtdIHJvd0tleSkgeworICAgICAgaWYgKHN0YXJ0Um93ICE9IG51bGwgJiYgQnl0ZXMuY29tcGFyZVRvKHJvd0tleSwgc3RhcnRSb3cpIDwgMCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpZiAoZW5kUm93ICE9IG51bGwgJiYgQnl0ZXMuY29tcGFyZVRvKGVuZFJvdywgcm93S2V5KSA8IDApIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uSW5mbyByZWdpb25JbmZvOworICBwcml2YXRlIGZpbmFsIGxvbmcgaExvZ1N0YXJ0U2VxdWVuY2VJZDsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQ7CisgIHByaXZhdGUgU3RhdHVzIHN0YXR1czsKKyAgcHJpdmF0ZSBTb3J0ZWRTZXQ8Ynl0ZVtdPiByZWFkU2V0ID0gbmV3IFRyZWVTZXQ8Ynl0ZVtdPigKKyAgICAgIEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICBwcml2YXRlIExpc3Q8QmF0Y2hVcGRhdGU+IHdyaXRlU2V0ID0gbmV3IExpbmtlZExpc3Q8QmF0Y2hVcGRhdGU+KCk7CisgIHByaXZhdGUgTGlzdDxTY2FuUmFuZ2U+IHNjYW5TZXQgPSBuZXcgTGlua2VkTGlzdDxTY2FuUmFuZ2U+KCk7CisgIHByaXZhdGUgU2V0PFRyYW5zYWN0aW9uU3RhdGU+IHRyYW5zYWN0aW9uc1RvQ2hlY2sgPSBuZXcgSGFzaFNldDxUcmFuc2FjdGlvblN0YXRlPigpOworICBwcml2YXRlIGludCBzdGFydFNlcXVlbmNlTnVtYmVyOworICBwcml2YXRlIEludGVnZXIgc2VxdWVuY2VOdW1iZXI7CisKKyAgVHJhbnNhY3Rpb25TdGF0ZShmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGxvbmcgckxvZ1N0YXJ0U2VxdWVuY2VJZCwKKyAgICAgIEhSZWdpb25JbmZvIHJlZ2lvbkluZm8pIHsKKyAgICB0aGlzLnRyYW5zYWN0aW9uSWQgPSB0cmFuc2FjdGlvbklkOworICAgIHRoaXMuaExvZ1N0YXJ0U2VxdWVuY2VJZCA9IHJMb2dTdGFydFNlcXVlbmNlSWQ7CisgICAgdGhpcy5yZWdpb25JbmZvID0gcmVnaW9uSW5mbzsKKyAgICB0aGlzLnN0YXR1cyA9IFN0YXR1cy5QRU5ESU5HOworICB9CisKKyAgdm9pZCBhZGRSZWFkKGZpbmFsIGJ5dGVbXSByb3dLZXkpIHsKKyAgICByZWFkU2V0LmFkZChyb3dLZXkpOworICB9CisKKyAgU2V0PGJ5dGVbXT4gZ2V0UmVhZFNldCgpIHsKKyAgICByZXR1cm4gcmVhZFNldDsKKyAgfQorCisgIHZvaWQgYWRkV3JpdGUoZmluYWwgQmF0Y2hVcGRhdGUgd3JpdGUpIHsKKyAgICB3cml0ZVNldC5hZGQod3JpdGUpOworICB9CisKKyAgTGlzdDxCYXRjaFVwZGF0ZT4gZ2V0V3JpdGVTZXQoKSB7CisgICAgcmV0dXJuIHdyaXRlU2V0OworICB9CisKKyAgLyoqCisgICAqIEdldEZ1bGwgZnJvbSB0aGUgd3JpdGVTZXQuCisgICAqIAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW5zCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHJldHVybgorICAgKi8KKyAgTWFwPGJ5dGVbXSwgQ2VsbD4gbG9jYWxHZXRGdWxsKGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIFNldDxieXRlW10+IGNvbHVtbnMsCisgICAgICBmaW5hbCBsb25nIHRpbWVzdGFtcCkgeworICAgIE1hcDxieXRlW10sIENlbGw+IHJlc3VsdHMgPSBuZXcgVHJlZU1hcDxieXRlW10sIENlbGw+KAorICAgICAgICBCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsgLy8gTXVzdCB1c2UgdGhlIEJ5dGVzIENvbnBhcmF0b3IgYmVjYXVzZQorICAgIGZvciAoQmF0Y2hVcGRhdGUgYiA6IHdyaXRlU2V0KSB7CisgICAgICBpZiAoIUJ5dGVzLmVxdWFscyhyb3csIGIuZ2V0Um93KCkpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgaWYgKGIuZ2V0VGltZXN0YW1wKCkgPiB0aW1lc3RhbXApIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBmb3IgKEJhdGNoT3BlcmF0aW9uIG9wIDogYikgeworICAgICAgICBpZiAoIW9wLmlzUHV0KCkKKyAgICAgICAgICAgIHx8IChjb2x1bW5zICE9IG51bGwgJiYgIWNvbHVtbnMuY29udGFpbnMob3AuZ2V0Q29sdW1uKCkpKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHJlc3VsdHMucHV0KG9wLmdldENvbHVtbigpLCBuZXcgQ2VsbChvcC5nZXRWYWx1ZSgpLCBiLmdldFRpbWVzdGFtcCgpKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHRzLnNpemUoKSA9PSAwID8gbnVsbCA6IHJlc3VsdHM7CisgIH0KKworICAvKioKKyAgICogR2V0IGZyb20gdGhlIHdyaXRlU2V0LgorICAgKiAKKyAgICogQHBhcmFtIHJvdworICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHJldHVybgorICAgKi8KKyAgQ2VsbFtdIGxvY2FsR2V0KGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGJ5dGVbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdGltZXN0YW1wKSB7CisgICAgQXJyYXlMaXN0PENlbGw+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PENlbGw+KCk7CisKKyAgICAvLyBHbyBpbiByZXZlcnNlIG9yZGVyIHRvIHB1dCBuZXdlc3QgdXBkYXRlcyBmaXJzdCBpbiBsaXN0CisgICAgZm9yIChpbnQgaSA9IHdyaXRlU2V0LnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICBCYXRjaFVwZGF0ZSBiID0gd3JpdGVTZXQuZ2V0KGkpOworCisgICAgICBpZiAoIUJ5dGVzLmVxdWFscyhyb3csIGIuZ2V0Um93KCkpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgaWYgKGIuZ2V0VGltZXN0YW1wKCkgPiB0aW1lc3RhbXApIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBmb3IgKEJhdGNoT3BlcmF0aW9uIG9wIDogYikgeworICAgICAgICBpZiAoIW9wLmlzUHV0KCkgfHwgIUJ5dGVzLmVxdWFscyhjb2x1bW4sIG9wLmdldENvbHVtbigpKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHJlc3VsdHMuYWRkKG5ldyBDZWxsKG9wLmdldFZhbHVlKCksIGIuZ2V0VGltZXN0YW1wKCkpKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdHMuc2l6ZSgpID09IDAgPyBudWxsIDogcmVzdWx0cworICAgICAgICAudG9BcnJheShuZXcgQ2VsbFtyZXN1bHRzLnNpemUoKV0pOworICB9CisKKyAgdm9pZCBhZGRUcmFuc2FjdGlvblRvQ2hlY2soZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvbikgeworICAgIHRyYW5zYWN0aW9uc1RvQ2hlY2suYWRkKHRyYW5zYWN0aW9uKTsKKyAgfQorCisgIGJvb2xlYW4gaGFzQ29uZmxpY3QoKSB7CisgICAgZm9yIChUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgOiB0cmFuc2FjdGlvbnNUb0NoZWNrKSB7CisgICAgICBpZiAoaGFzQ29uZmxpY3QodHJhbnNhY3Rpb25TdGF0ZSkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiBoYXNDb25mbGljdChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIGNoZWNrQWdhaW5zdCkgeworICAgIGlmIChjaGVja0FnYWluc3QuZ2V0U3RhdHVzKCkuZXF1YWxzKFRyYW5zYWN0aW9uU3RhdGUuU3RhdHVzLkFCT1JURUQpKSB7CisgICAgICByZXR1cm4gZmFsc2U7IC8vIENhbm5vdCBjb25mbGljdCB3aXRoIGFib3J0ZWQgdHJhbnNhY3Rpb25zCisgICAgfQorCisgICAgZm9yIChCYXRjaFVwZGF0ZSBvdGhlclVwZGF0ZSA6IGNoZWNrQWdhaW5zdC5nZXRXcml0ZVNldCgpKSB7CisgICAgICBpZiAodGhpcy5nZXRSZWFkU2V0KCkuY29udGFpbnMob3RoZXJVcGRhdGUuZ2V0Um93KCkpKSB7CisgICAgICAgIExPRy5kZWJ1ZygiVHJhbnNhY3Rpb24gWyIgKyB0aGlzLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICsgIl0gaGFzIHJlYWQgd2hpY2ggY29uZmxpY3RzIHdpdGggWyIgKyBjaGVja0FnYWluc3QudG9TdHJpbmcoKQorICAgICAgICAgICAgKyAiXTogcmVnaW9uIFsiICsgcmVnaW9uSW5mby5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSArICJdLCByb3dbIgorICAgICAgICAgICAgKyBCeXRlcy50b1N0cmluZyhvdGhlclVwZGF0ZS5nZXRSb3coKSkgKyAiXSIpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGZvciAoU2NhblJhbmdlIHNjYW5SYW5nZSA6IHRoaXMuc2NhblNldCkgeworICAgICAgICBpZiAoc2NhblJhbmdlLmNvbnRhaW5zKG90aGVyVXBkYXRlLmdldFJvdygpKSkgeworICAgICAgICAgIExPRy5kZWJ1ZygiVHJhbnNhY3Rpb24gWyIgKyB0aGlzLnRvU3RyaW5nKCkKKyAgICAgICAgICAgICAgKyAiXSBoYXMgc2NhbiB3aGljaCBjb25mbGljdHMgd2l0aCBbIiArIGNoZWNrQWdhaW5zdC50b1N0cmluZygpCisgICAgICAgICAgICAgICsgIl06IHJlZ2lvbiBbIiArIHJlZ2lvbkluZm8uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkgKyAiXSwgcm93WyIKKyAgICAgICAgICAgICAgKyBCeXRlcy50b1N0cmluZyhvdGhlclVwZGF0ZS5nZXRSb3coKSkgKyAiXSIpOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIHN0YXR1cy4KKyAgICogCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSBzdGF0dXMuCisgICAqLworICBTdGF0dXMgZ2V0U3RhdHVzKCkgeworICAgIHJldHVybiBzdGF0dXM7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBzdGF0dXMuCisgICAqIAorICAgKiBAcGFyYW0gc3RhdHVzIFRoZSBzdGF0dXMgdG8gc2V0LgorICAgKi8KKyAgdm9pZCBzZXRTdGF0dXMoZmluYWwgU3RhdHVzIHN0YXR1cykgeworICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgc3RhcnRTZXF1ZW5jZU51bWJlci4KKyAgICogCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSBzdGFydFNlcXVlbmNlTnVtYmVyLgorICAgKi8KKyAgaW50IGdldFN0YXJ0U2VxdWVuY2VOdW1iZXIoKSB7CisgICAgcmV0dXJuIHN0YXJ0U2VxdWVuY2VOdW1iZXI7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBzdGFydFNlcXVlbmNlTnVtYmVyLgorICAgKiAKKyAgICogQHBhcmFtIHN0YXJ0U2VxdWVuY2VOdW1iZXIKKyAgICovCisgIHZvaWQgc2V0U3RhcnRTZXF1ZW5jZU51bWJlcihmaW5hbCBpbnQgc3RhcnRTZXF1ZW5jZU51bWJlcikgeworICAgIHRoaXMuc3RhcnRTZXF1ZW5jZU51bWJlciA9IHN0YXJ0U2VxdWVuY2VOdW1iZXI7CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBzZXF1ZW5jZU51bWJlci4KKyAgICogCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSBzZXF1ZW5jZU51bWJlci4KKyAgICovCisgIEludGVnZXIgZ2V0U2VxdWVuY2VOdW1iZXIoKSB7CisgICAgcmV0dXJuIHNlcXVlbmNlTnVtYmVyOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgc2VxdWVuY2VOdW1iZXIuCisgICAqIAorICAgKiBAcGFyYW0gc2VxdWVuY2VOdW1iZXIgVGhlIHNlcXVlbmNlTnVtYmVyIHRvIHNldC4KKyAgICovCisgIHZvaWQgc2V0U2VxdWVuY2VOdW1iZXIoZmluYWwgSW50ZWdlciBzZXF1ZW5jZU51bWJlcikgeworICAgIHRoaXMuc2VxdWVuY2VOdW1iZXIgPSBzZXF1ZW5jZU51bWJlcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICByZXN1bHQuYXBwZW5kKCJbdHJhbnNhY3Rpb25JZDogIik7CisgICAgcmVzdWx0LmFwcGVuZCh0cmFuc2FjdGlvbklkKTsKKyAgICByZXN1bHQuYXBwZW5kKCIgc3RhdHVzOiAiKTsKKyAgICByZXN1bHQuYXBwZW5kKHN0YXR1cy5uYW1lKCkpOworICAgIHJlc3VsdC5hcHBlbmQoIiByZWFkIFNpemU6ICIpOworICAgIHJlc3VsdC5hcHBlbmQocmVhZFNldC5zaXplKCkpOworICAgIHJlc3VsdC5hcHBlbmQoIiBzY2FuIFNpemU6ICIpOworICAgIHJlc3VsdC5hcHBlbmQoc2NhblNldC5zaXplKCkpOworICAgIHJlc3VsdC5hcHBlbmQoIiB3cml0ZSBTaXplOiAiKTsKKyAgICByZXN1bHQuYXBwZW5kKHdyaXRlU2V0LnNpemUoKSk7CisgICAgcmVzdWx0LmFwcGVuZCgiIHN0YXJ0U1E6ICIpOworICAgIHJlc3VsdC5hcHBlbmQoc3RhcnRTZXF1ZW5jZU51bWJlcik7CisgICAgaWYgKHNlcXVlbmNlTnVtYmVyICE9IG51bGwpIHsKKyAgICAgIHJlc3VsdC5hcHBlbmQoIiBjb21taXRlZFNROiIpOworICAgICAgcmVzdWx0LmFwcGVuZChzZXF1ZW5jZU51bWJlcik7CisgICAgfQorICAgIHJlc3VsdC5hcHBlbmQoIl0iKTsKKworICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIHRyYW5zYWN0aW9uSWQuCisgICAqIAorICAgKiBAcmV0dXJuIFJldHVybiB0aGUgdHJhbnNhY3Rpb25JZC4KKyAgICovCisgIGxvbmcgZ2V0VHJhbnNhY3Rpb25JZCgpIHsKKyAgICByZXR1cm4gdHJhbnNhY3Rpb25JZDsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIHN0YXJ0U2VxdWVuY2VJZC4KKyAgICogCisgICAqIEByZXR1cm4gUmV0dXJuIHRoZSBzdGFydFNlcXVlbmNlSWQuCisgICAqLworICBsb25nIGdldEhMb2dTdGFydFNlcXVlbmNlSWQoKSB7CisgICAgcmV0dXJuIGhMb2dTdGFydFNlcXVlbmNlSWQ7CisgIH0KKworICB2b2lkIGFkZFNjYW4oYnl0ZVtdIGZpcnN0Um93LCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB7CisgICAgU2NhblJhbmdlIHNjYW5SYW5nZSA9IG5ldyBTY2FuUmFuZ2UoZmlyc3RSb3csIGdldEVuZFJvdyhmaWx0ZXIpKTsKKyAgICBMT0cudHJhY2UoU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgIkFkZGluZyBzY2FuIGZvciB0cmFuc2NhY3Rpb24gWyVzXSwgZnJvbSBbJXNdIHRvIFslc10iLCB0cmFuc2FjdGlvbklkLAorICAgICAgICBzY2FuUmFuZ2Uuc3RhcnRSb3cgPT0gbnVsbCA/ICJudWxsIiA6IEJ5dGVzCisgICAgICAgICAgICAudG9TdHJpbmcoc2NhblJhbmdlLnN0YXJ0Um93KSwgc2NhblJhbmdlLmVuZFJvdyA9PSBudWxsID8gIm51bGwiCisgICAgICAgICAgICA6IEJ5dGVzLnRvU3RyaW5nKHNjYW5SYW5nZS5lbmRSb3cpKSk7CisgICAgc2NhblNldC5hZGQoc2NhblJhbmdlKTsKKyAgfQorCisgIHByaXZhdGUgYnl0ZVtdIGdldEVuZFJvdyhSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB7CisgICAgaWYgKGZpbHRlciBpbnN0YW5jZW9mIFdoaWxlTWF0Y2hSb3dGaWx0ZXIpIHsKKyAgICAgIFdoaWxlTWF0Y2hSb3dGaWx0ZXIgd21yRmlsdGVyID0gKFdoaWxlTWF0Y2hSb3dGaWx0ZXIpIGZpbHRlcjsKKyAgICAgIGlmICh3bXJGaWx0ZXIuZ2V0SW50ZXJuYWxGaWx0ZXIoKSBpbnN0YW5jZW9mIFN0b3BSb3dGaWx0ZXIpIHsKKyAgICAgICAgU3RvcFJvd0ZpbHRlciBzdG9wRmlsdGVyID0gKFN0b3BSb3dGaWx0ZXIpIHdtckZpbHRlcgorICAgICAgICAgICAgLmdldEludGVybmFsRmlsdGVyKCk7CisgICAgICAgIHJldHVybiBzdG9wRmlsdGVyLmdldFN0b3BSb3dLZXkoKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGZpbHRlciBpbnN0YW5jZW9mIFJvd0ZpbHRlclNldCkgeworICAgICAgUm93RmlsdGVyU2V0IHJvd0ZpbHRlclNldCA9IChSb3dGaWx0ZXJTZXQpIGZpbHRlcjsKKyAgICAgIGlmIChyb3dGaWx0ZXJTZXQuZ2V0T3BlcmF0b3IoKQorICAgICAgICAgIC5lcXVhbHMoUm93RmlsdGVyU2V0Lk9wZXJhdG9yLk1VU1RfUEFTU19BTEwpKSB7CisgICAgICAgIGZvciAoUm93RmlsdGVySW50ZXJmYWNlIHN1YkZpbHRlciA6IHJvd0ZpbHRlclNldC5nZXRGaWx0ZXJzKCkpIHsKKyAgICAgICAgICBieXRlW10gZW5kUm93ID0gZ2V0RW5kUm93KHN1YkZpbHRlcik7CisgICAgICAgICAgaWYgKGVuZFJvdyAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gZW5kUm93OworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uYWxITG9nTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiNjY2OGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIuamF2YQpAQCAtMCwwICsxLDMwNyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3RhdHVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaE9wZXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSExvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSExvZ0tleTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlNlcXVlbmNlRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyZXNzYWJsZTsKKworLyoqCisgKiBSZXNwb25zaWJsZSBmb3Igd3JpdGluZyBhbmQgcmVhZGluZyAocmVjb3ZlcmluZykgdHJhbnNhY3Rpb25hbCBpbmZvcm1hdGlvbgorICogdG8vZnJvbSB0aGUgSExvZy4KKyAqLworY2xhc3MgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyIHsKKyAgLyoqIElmIHRyYW5zYWN0aW9uYWwgbG9nIGVudHJ5LCB0aGVzZSBhcmUgdGhlIG9wIGNvZGVzICovCisgIC8vIFRPRE86IE1ha2UgdGhlc2UgaW50byB0eXBlcyBvbiB0aGUgS2V5VmFsdWUhISEgLS0gU3QuQWNrCisgIHB1YmxpYyBlbnVtIFRyYW5zYWN0aW9uYWxPcGVyYXRpb24geworICAgIC8qKiBzdGFydCB0cmFuc2FjdGlvbiAqLworICAgIFNUQVJULAorICAgIC8qKiBFcXVpdmFsZW50IHRvIGFwcGVuZCBpbiBub24tdHJhbnNhY3Rpb25hbCBlbnZpcm9ubWVudCAqLworICAgIFdSSVRFLAorICAgIC8qKiBUcmFuc2FjdGlvbiBjb21taXQgZW50cnkgKi8KKyAgICBDT01NSVQsCisgICAgLyoqIEFib3J0IHRyYW5zYWN0aW9uIGVudHJ5ICovCisgICAgQUJPUlQKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5CisgICAgICAuZ2V0TG9nKFRyYW5zYWN0aW9uYWxITG9nTWFuYWdlci5jbGFzcyk7CisKKyAgcHJpdmF0ZSBmaW5hbCBITG9nIGhsb2c7CisgIHByaXZhdGUgZmluYWwgRmlsZVN5c3RlbSBmaWxlU3lzdGVtOworICBwcml2YXRlIGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm87CisgIHByaXZhdGUgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisKKyAgLyoqCisgICAqIEBwYXJhbSByZWdpb24KKyAgICovCisgIHB1YmxpYyBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIoZmluYWwgVHJhbnNhY3Rpb25hbFJlZ2lvbiByZWdpb24pIHsKKyAgICB0aGlzLmhsb2cgPSByZWdpb24uZ2V0TG9nKCk7CisgICAgdGhpcy5maWxlU3lzdGVtID0gcmVnaW9uLmdldEZpbGVzeXN0ZW0oKTsKKyAgICB0aGlzLnJlZ2lvbkluZm8gPSByZWdpb24uZ2V0UmVnaW9uSW5mbygpOworICAgIHRoaXMuY29uZiA9IHJlZ2lvbi5nZXRDb25mKCk7CisgIH0KKworICAvLyBGb3IgVGVzdGluZworICBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIoZmluYWwgSExvZyBobG9nLCBmaW5hbCBGaWxlU3lzdGVtIGZpbGVTeXN0ZW0sCisgICAgICBmaW5hbCBIUmVnaW9uSW5mbyByZWdpb25JbmZvLCBmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgeworICAgIHRoaXMuaGxvZyA9IGhsb2c7CisgICAgdGhpcy5maWxlU3lzdGVtID0gZmlsZVN5c3RlbTsKKyAgICB0aGlzLnJlZ2lvbkluZm8gPSByZWdpb25JbmZvOworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVTdGFydFRvTG9nKGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvKgorICAgIEhMb2dFZGl0IGxvZ0VkaXQ7CisgICAgbG9nRWRpdCA9IG5ldyBITG9nRWRpdCh0cmFuc2FjdGlvbklkLCBUcmFuc2FjdGlvbmFsT3BlcmF0aW9uLlNUQVJUKTsKKyovCisgICAgaGxvZy5hcHBlbmQocmVnaW9uSW5mbywgbnVsbC8qbG9nRWRpdCovKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gdXBkYXRlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlVXBkYXRlVG9Mb2coZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLAorICAgICAgZmluYWwgQmF0Y2hVcGRhdGUgdXBkYXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgbG9uZyBjb21taXRUaW1lID0gdXBkYXRlLmdldFRpbWVzdGFtcCgpID09IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCA/IFN5c3RlbQorICAgICAgICAuY3VycmVudFRpbWVNaWxsaXMoKQorICAgICAgICA6IHVwZGF0ZS5nZXRUaW1lc3RhbXAoKTsKKworICAgIGZvciAoQmF0Y2hPcGVyYXRpb24gb3AgOiB1cGRhdGUpIHsKKyAgICAgIC8vIENPTU1FTlRFRCBPVVQgIEhMb2dFZGl0IGxvZ0VkaXQgPSBuZXcgSExvZ0VkaXQodHJhbnNhY3Rpb25JZCwgdXBkYXRlLmdldFJvdygpLCBvcCwgY29tbWl0VGltZSk7CisgICAgICBobG9nLmFwcGVuZChyZWdpb25JbmZvLCB1cGRhdGUuZ2V0Um93KCksIG51bGwgLypsb2dFZGl0Ki8pOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZUNvbW1pdFRvTG9nKGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvKkhMb2dFZGl0IGxvZ0VkaXQ7CisgICAgbG9nRWRpdCA9IG5ldyBITG9nRWRpdCh0cmFuc2FjdGlvbklkLAorICAgICAgICBITG9nRWRpdC5UcmFuc2FjdGlvbmFsT3BlcmF0aW9uLkNPTU1JVCk7CisqLworICAgIGhsb2cuYXBwZW5kKHJlZ2lvbkluZm8sIG51bGwgLypsb2dFZGl0Ki8pOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHdyaXRlQWJvcnRUb0xvZyhmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLypITG9nRWRpdCBsb2dFZGl0OworICAgIGxvZ0VkaXQgPSBuZXcgSExvZ0VkaXQodHJhbnNhY3Rpb25JZCwgSExvZ0VkaXQuVHJhbnNhY3Rpb25hbE9wZXJhdGlvbi5BQk9SVCk7CisqLworICAgIGhsb2cuYXBwZW5kKHJlZ2lvbkluZm8sIG51bGwgLypsb2dFZGl0Ki8pOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSByZWNvbnN0cnVjdGlvbkxvZworICAgKiBAcGFyYW0gbWF4U2VxSUQKKyAgICogQHBhcmFtIHJlcG9ydGVyCisgICAqIEByZXR1cm4gbWFwIG9mIGJhdGNoIHVwZGF0ZXMKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBNYXA8TG9uZywgTGlzdDxCYXRjaFVwZGF0ZT4+IGdldENvbW1pdHNGcm9tTG9nKAorICAgICAgZmluYWwgUGF0aCByZWNvbnN0cnVjdGlvbkxvZywgZmluYWwgbG9uZyBtYXhTZXFJRCwKKyAgICAgIGZpbmFsIFByb2dyZXNzYWJsZSByZXBvcnRlcikgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sCisgICAgICBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHJlY29uc3RydWN0aW9uTG9nID09IG51bGwgfHwgIWZpbGVTeXN0ZW0uZXhpc3RzKHJlY29uc3RydWN0aW9uTG9nKSkgeworICAgICAgLy8gTm90aGluZyB0byBkby4KKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICAvLyBDaGVjayBpdHMgbm90IGVtcHR5LgorICAgIEZpbGVTdGF0dXNbXSBzdGF0cyA9IGZpbGVTeXN0ZW0ubGlzdFN0YXR1cyhyZWNvbnN0cnVjdGlvbkxvZyk7CisgICAgaWYgKHN0YXRzID09IG51bGwgfHwgc3RhdHMubGVuZ3RoID09IDApIHsKKyAgICAgIExPRy53YXJuKCJQYXNzZWQgcmVjb25zdHJ1Y3Rpb24gbG9nICIgKyByZWNvbnN0cnVjdGlvbkxvZworICAgICAgICAgICsgIiBpcyB6ZXJvLWxlbmd0aCIpOworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgU29ydGVkTWFwPExvbmcsIExpc3Q8QmF0Y2hVcGRhdGU+PiBwZW5kaW5nVHJhbnNhY3Rpb25zQnlJZCA9IG5ldyBUcmVlTWFwPExvbmcsIExpc3Q8QmF0Y2hVcGRhdGU+PigpOworICAgIFNvcnRlZE1hcDxMb25nLCBMaXN0PEJhdGNoVXBkYXRlPj4gY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkID0gbmV3IFRyZWVNYXA8TG9uZywgTGlzdDxCYXRjaFVwZGF0ZT4+KCk7CisgICAgU2V0PExvbmc+IGFib3J0ZWRUcmFuc2FjdGlvbnMgPSBuZXcgSGFzaFNldDxMb25nPigpOworCisgICAgU2VxdWVuY2VGaWxlLlJlYWRlciBsb2dSZWFkZXIgPSBuZXcgU2VxdWVuY2VGaWxlLlJlYWRlcihmaWxlU3lzdGVtLAorICAgICAgICByZWNvbnN0cnVjdGlvbkxvZywgY29uZik7CisgICAgLyoKKyAgICB0cnkgeworICAgICAgSExvZ0tleSBrZXkgPSBuZXcgSExvZ0tleSgpOworICAgICAgS2V5VmFsdWUgdmFsID0gbmV3IEtleVZhbHVlKCk7CisgICAgICBsb25nIHNraXBwZWRFZGl0cyA9IDA7CisgICAgICBsb25nIHRvdGFsRWRpdHMgPSAwOworICAgICAgbG9uZyBzdGFydENvdW50ID0gMDsKKyAgICAgIGxvbmcgd3JpdGVDb3VudCA9IDA7CisgICAgICBsb25nIGFib3J0Q291bnQgPSAwOworICAgICAgbG9uZyBjb21taXRDb3VudCA9IDA7CisgICAgICAvLyBIb3cgbWFueSBlZGl0cyB0byBhcHBseSBiZWZvcmUgd2Ugc2VuZCBhIHByb2dyZXNzIHJlcG9ydC4KKyAgICAgIGludCByZXBvcnRJbnRlcnZhbCA9IGNvbmYuZ2V0SW50KCJoYmFzZS5oc3RvcmUucmVwb3J0LmludGVydmFsLmVkaXRzIiwKKyAgICAgICAgICAyMDAwKTsKKworICAgICAgd2hpbGUgKGxvZ1JlYWRlci5uZXh0KGtleSwgdmFsKSkgeworICAgICAgICBMT0cuZGVidWcoIlByb2Nlc3NpbmcgZWRpdDoga2V5OiAiICsga2V5LnRvU3RyaW5nKCkgKyAiIHZhbDogIgorICAgICAgICAgICAgKyB2YWwudG9TdHJpbmcoKSk7CisgICAgICAgIGlmIChrZXkuZ2V0TG9nU2VxTnVtKCkgPCBtYXhTZXFJRCkgeworICAgICAgICAgIHNraXBwZWRFZGl0cysrOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIC8vIFRPRE86IENoYW5nZSBhbGwgYmVsb3cgc28gd2UgYXJlIG5vdCBkb2luZyBhIGdldFJvdyBhbmQgZ2V0Q29sdW1uCisgICAgICAgIC8vIGFnYWluc3QgYSBLZXlWYWx1ZS4gIEVhY2ggaW52b2NhdGlvbiBjcmVhdGVzIGEgbmV3IGluc3RhbmNlLiAgU3QuQWNrLgorCisgICAgICAgIC8vIENoZWNrIHRoaXMgZWRpdCBpcyBmb3IgbWUuCisKKyAgICAgICAgYnl0ZVtdIGNvbHVtbiA9IHZhbC5nZXRLZXlWYWx1ZSgpLmdldENvbHVtbigpOworICAgICAgICBMb25nIHRyYW5zYWN0aW9uSWQgPSB2YWwuZ2V0VHJhbnNhY3Rpb25JZCgpOworICAgICAgICBpZiAoIXZhbC5pc1RyYW5zYWN0aW9uRW50cnkoKSB8fCBITG9nLmlzTWV0YUNvbHVtbihjb2x1bW4pCisgICAgICAgICAgICB8fCAhQnl0ZXMuZXF1YWxzKGtleS5nZXRSZWdpb25OYW1lKCksIHJlZ2lvbkluZm8uZ2V0UmVnaW9uTmFtZSgpKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgTGlzdDxCYXRjaFVwZGF0ZT4gdXBkYXRlcyA9IHBlbmRpbmdUcmFuc2FjdGlvbnNCeUlkLmdldCh0cmFuc2FjdGlvbklkKTsKKyAgICAgICAgc3dpdGNoICh2YWwuZ2V0T3BlcmF0aW9uKCkpIHsKKworICAgICAgICBjYXNlIFNUQVJUOgorICAgICAgICAgIGlmICh1cGRhdGVzICE9IG51bGwgfHwgYWJvcnRlZFRyYW5zYWN0aW9ucy5jb250YWlucyh0cmFuc2FjdGlvbklkKQorICAgICAgICAgICAgICB8fCBjb21taXRlZFRyYW5zYWN0aW9uc0J5SWQuY29udGFpbnNLZXkodHJhbnNhY3Rpb25JZCkpIHsKKyAgICAgICAgICAgIExPRy5lcnJvcigiUHJvY2Vzc2luZyBzdGFydCBmb3IgdHJhbnNhY3Rpb246ICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgICAgICAgKyAiLCBidXQgaGF2ZSBhbHJlYWR5IHNlZW4gc3RhcnQgbWVzc2FnZSIpOworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3JydXB0ZWQgdHJhbnNhY3Rpb24gbG9nIik7CisgICAgICAgICAgfQorICAgICAgICAgIHVwZGF0ZXMgPSBuZXcgTGlua2VkTGlzdDxCYXRjaFVwZGF0ZT4oKTsKKyAgICAgICAgICBwZW5kaW5nVHJhbnNhY3Rpb25zQnlJZC5wdXQodHJhbnNhY3Rpb25JZCwgdXBkYXRlcyk7CisgICAgICAgICAgc3RhcnRDb3VudCsrOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgV1JJVEU6CisgICAgICAgICAgaWYgKHVwZGF0ZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgTE9HLmVycm9yKCJQcm9jZXNzaW5nIGVkaXQgZm9yIHRyYW5zYWN0aW9uOiAiICsgdHJhbnNhY3Rpb25JZAorICAgICAgICAgICAgICAgICsgIiwgYnV0IGhhdmUgbm90IHNlZW4gc3RhcnQgbWVzc2FnZSIpOworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3JydXB0ZWQgdHJhbnNhY3Rpb24gbG9nIik7CisgICAgICAgICAgfQorCisgICAgICAgICAgQmF0Y2hVcGRhdGUgdHJhblVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSh2YWwuZ2V0S2V5VmFsdWUoKS5nZXRSb3coKSk7CisgICAgICAgICAgaWYgKHZhbC5nZXRLZXlWYWx1ZSgpLmdldFZhbHVlKCkgIT0gbnVsbCkgeworICAgICAgICAgICAgdHJhblVwZGF0ZS5wdXQodmFsLmdldEtleVZhbHVlKCkuZ2V0Q29sdW1uKCksCisgICAgICAgICAgICAgIHZhbC5nZXRLZXlWYWx1ZSgpLmdldFZhbHVlKCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB0cmFuVXBkYXRlLmRlbGV0ZSh2YWwuZ2V0S2V5VmFsdWUoKS5nZXRDb2x1bW4oKSk7CisgICAgICAgICAgfQorICAgICAgICAgIHVwZGF0ZXMuYWRkKHRyYW5VcGRhdGUpOworICAgICAgICAgIHdyaXRlQ291bnQrKzsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEFCT1JUOgorICAgICAgICAgIGlmICh1cGRhdGVzID09IG51bGwpIHsKKyAgICAgICAgICAgIExPRy5lcnJvcigiUHJvY2Vzc2luZyBhYm9ydCBmb3IgdHJhbnNhY3Rpb246ICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgICAgICAgKyAiLCBidXQgaGF2ZSBub3Qgc2VlbiBzdGFydCBtZXNzYWdlIik7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvcnJ1cHRlZCB0cmFuc2FjdGlvbiBsb2ciKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYWJvcnRlZFRyYW5zYWN0aW9ucy5hZGQodHJhbnNhY3Rpb25JZCk7CisgICAgICAgICAgcGVuZGluZ1RyYW5zYWN0aW9uc0J5SWQucmVtb3ZlKHRyYW5zYWN0aW9uSWQpOworICAgICAgICAgIGFib3J0Q291bnQrKzsKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIENPTU1JVDoKKyAgICAgICAgICBpZiAodXBkYXRlcyA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0cuZXJyb3IoIlByb2Nlc3NpbmcgY29tbWl0IGZvciB0cmFuc2FjdGlvbjogIiArIHRyYW5zYWN0aW9uSWQKKyAgICAgICAgICAgICAgICArICIsIGJ1dCBoYXZlIG5vdCBzZWVuIHN0YXJ0IG1lc3NhZ2UiKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ29ycnVwdGVkIHRyYW5zYWN0aW9uIGxvZyIpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoYWJvcnRlZFRyYW5zYWN0aW9ucy5jb250YWlucyh0cmFuc2FjdGlvbklkKSkgeworICAgICAgICAgICAgTE9HLmVycm9yKCJQcm9jZXNzaW5nIGNvbW1pdCBmb3IgdHJhbnNhY3Rpb246ICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgICAgICAgKyAiLCBidXQgYWxzbyBoYXZlIGFib3J0IG1lc3NhZ2UiKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ29ycnVwdGVkIHRyYW5zYWN0aW9uIGxvZyIpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAodXBkYXRlcy5zaXplKCkgPT0gMCkgeworICAgICAgICAgICAgTE9HCisgICAgICAgICAgICAgICAgLndhcm4oIlRyYW5zYWNpdG9uICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgICAgICAgICAgICsgIiBoYXMgbm8gd3JpdGVzIGluIGxvZy4gIik7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChjb21taXRlZFRyYW5zYWN0aW9uc0J5SWQuY29udGFpbnNLZXkodHJhbnNhY3Rpb25JZCkpIHsKKyAgICAgICAgICAgIExPRy5lcnJvcigiUHJvY2Vzc2luZyBjb21taXQgZm9yIHRyYW5zYWN0aW9uOiAiICsgdHJhbnNhY3Rpb25JZAorICAgICAgICAgICAgICAgICsgIiwgYnV0IGhhdmUgYWxyZWFkeSBjb21taXRlZCB0cmFuc2FjdGlvbiB3aXRoIHRoYXQgaWQiKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ29ycnVwdGVkIHRyYW5zYWN0aW9uIGxvZyIpOworICAgICAgICAgIH0KKyAgICAgICAgICBwZW5kaW5nVHJhbnNhY3Rpb25zQnlJZC5yZW1vdmUodHJhbnNhY3Rpb25JZCk7CisgICAgICAgICAgY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkLnB1dCh0cmFuc2FjdGlvbklkLCB1cGRhdGVzKTsKKyAgICAgICAgICBjb21taXRDb3VudCsrOworCisgICAgICAgIH0KKyAgICAgICAgdG90YWxFZGl0cysrOworCisgICAgICAgIGlmIChyZXBvcnRlciAhPSBudWxsICYmICh0b3RhbEVkaXRzICUgcmVwb3J0SW50ZXJ2YWwpID09IDApIHsKKyAgICAgICAgICByZXBvcnRlci5wcm9ncmVzcygpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJSZWFkICIgKyB0b3RhbEVkaXRzICsgIiB0cmFuYXNjdGlvbmFsIG9wZXJhdGlvbnMgKHNraXBwZWQgIgorICAgICAgICAgICAgKyBza2lwcGVkRWRpdHMgKyAiIGJlY2F1c2Ugc2VxdWVuY2UgaWQgPD0gIiArIG1heFNlcUlEICsgIik6ICIKKyAgICAgICAgICAgICsgc3RhcnRDb3VudCArICIgc3RhcnRzLCAiICsgd3JpdGVDb3VudCArICIgd3JpdGVzLCAiICsgYWJvcnRDb3VudAorICAgICAgICAgICAgKyAiIGFib3J0cywgYW5kICIgKyBjb21taXRDb3VudCArICIgY29tbWl0cy4iKTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgbG9nUmVhZGVyLmNsb3NlKCk7CisgICAgfQorCisgICAgaWYgKHBlbmRpbmdUcmFuc2FjdGlvbnNCeUlkLnNpemUoKSA+IDApIHsKKyAgICAgIExPRworICAgICAgICAgIC5pbmZvKCJSZWdpb24gbG9nIGhhcyAiCisgICAgICAgICAgICAgICsgcGVuZGluZ1RyYW5zYWN0aW9uc0J5SWQuc2l6ZSgpCisgICAgICAgICAgICAgICsgIiB1bmZpbmlzaGVkIHRyYW5zYWN0aW9ucy4gR29pbmcgdG8gdGhlIHRyYW5zYWN0aW9uIGxvZyB0byByZXNvbHZlIik7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVHJhbnNhY3Rpb24gbG9nIG5vdCB5ZXQgaW1wbGVtZW50ZWQiKTsKKyAgICB9CisgICAgICAgICAgICAgICovCisKKyAgICByZXR1cm4gY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsUmVnaW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsUmVnaW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg5YTE1MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uYWxSZWdpb24uamF2YQpAQCAtMCwwICsxLDcxOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlNvcnRlZE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5MZWFzZUV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5MZWFzZUxpc3RlbmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkxlYXNlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5MZWFzZXMuTGVhc2VTdGlsbEhlbGRFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWwuVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuRmx1c2hSZXF1ZXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhMb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkludGVybmFsU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuU3RvcmU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLnRyYW5zYWN0aW9uYWwuVHJhbnNhY3Rpb25TdGF0ZS5TdGF0dXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyZXNzYWJsZTsKKworLyoqCisgKiBSZWdpb25zZXJ2ZXIgd2hpY2ggcHJvdmlkZXMgdHJhbnNhY3Rpb25hbCBzdXBwb3J0IGZvciBhdG9taWMgdHJhbnNhY3Rpb25zLgorICogVGhpcyBpcyBhY2hpZXZlZCB3aXRoIG9wdGltaXN0aWMgY29uY3VycmVuY3kgY29udHJvbCAoc2VlCisgKiBodHRwOi8vd3d3LnNlYXMudXBlbm4uZWR1L356aXZlcy9jaXM2NTAvcGFwZXJzL29wdC1jYy5wZGYpLiBXZSBrZWVwIHRyYWNrCisgKiByZWFkIGFuZCB3cml0ZSBzZXRzIGZvciBlYWNoIHRyYW5zYWN0aW9uLCBhbmQgaG9sZCBvZmYgb24gcHJvY2Vzc2luZyB0aGUKKyAqIHdyaXRlcy4gVG8gZGVjaWRlIHRvIGNvbW1pdCBhIHRyYW5zYWN0aW9uIHdlIGNoZWNrIGl0cyByZWFkIHNldHMgd2l0aCBhbGwKKyAqIHRyYW5zYWN0aW9ucyB0aGF0IGhhdmUgY29tbWl0dGVkIHdoaWxlIGl0IHdhcyBydW5uaW5nIGZvciBvdmVybGFwcy4KKyAqIDxwPgorICogQmVjYXVzZSB0cmFuc2FjdGlvbnMgY2FuIHNwYW4gbXVsdGlwbGUgcmVnaW9ucywgYWxsIHJlZ2lvbnMgbXVzdCBhZ3JlZSB0bworICogY29tbWl0IGEgdHJhbnNhY3Rpb25zLiBUaGUgY2xpZW50IHNpZGUgb2YgdGhpcyBjb21taXQgcHJvdG9jb2wgaXMgZW5jb2RlZCBpbgorICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWwuVHJhbnNhY3Rpb25NYW5nZXIKKyAqIDxwPgorICogSW4gdGhlIGV2ZW50IG9mIGFuIGZhaWx1cmUgb2YgdGhlIGNsaWVudCBtaWQtY29tbWl0LCAoYWZ0ZXIgd2Ugdm90ZWQgeWVzKSwgd2UKKyAqIHdpbGwgaGF2ZSB0byBjb25zdWx0IHRoZSB0cmFuc2FjdGlvbiBsb2cgdG8gZGV0ZXJtaW5lIHRoZSBmaW5hbCBkZWNpc2lvbiBvZgorICogdGhlIHRyYW5zYWN0aW9uLiBUaGlzIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBUcmFuc2FjdGlvbmFsUmVnaW9uIGV4dGVuZHMgSFJlZ2lvbiB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExFQVNFX1RJTUUgPSAiaGJhc2UudHJhbnNhY3Rpb24ubGVhc2VUaW1lIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfTEVBU0VfVElNRSA9IDYwICogMTAwMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQVNFX0NIRUNLX0ZSRVFVRU5DWSA9IDEwMDA7CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT0xEX1RSQU5TQUNUSU9OX0ZMVVNIID0gImhiYXNlLnRyYW5zYWN0aW9uLmZsdXNoIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfT0xEX1RSQU5TQUNUSU9OX0ZMVVNIID0gMTAwOyAvLyBEbyBhIGZsdXNoIGlmIHdlIGhhdmUgdGhpcyBtYW55IG9sZCB0cmFuc2FjdGlvbnMuLgorICAKKworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRyYW5zYWN0aW9uYWxSZWdpb24uY2xhc3MpOworCisgIC8vIENvbGxlY3Rpb24gb2YgYWN0aXZlIHRyYW5zYWN0aW9ucyAoUEVORElORykga2V5ZWQgYnkgaWQuCisgIHByb3RlY3RlZCBNYXA8U3RyaW5nLCBUcmFuc2FjdGlvblN0YXRlPiB0cmFuc2FjdGlvbnNCeUlkID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBUcmFuc2FjdGlvblN0YXRlPigpOworCisgIC8vIE1hcCBvZiByZWNlbnQgdHJhbnNhY3Rpb25zIHRoYXQgYXJlIENPTU1JVF9QRU5ESU5HIG9yIENPTU1JVEVEIGtleWVkIGJ5CisgIC8vIHRoZWlyIHNlcXVlbmNlIG51bWJlcgorICBwcml2YXRlIFNvcnRlZE1hcDxJbnRlZ2VyLCBUcmFuc2FjdGlvblN0YXRlPiBjb21taXRlZFRyYW5zYWN0aW9uc0J5U2VxdWVuY2VOdW1iZXIgPSBDb2xsZWN0aW9ucworICAgICAgLnN5bmNocm9uaXplZFNvcnRlZE1hcChuZXcgVHJlZU1hcDxJbnRlZ2VyLCBUcmFuc2FjdGlvblN0YXRlPigpKTsKKworICAvLyBDb2xsZWN0aW9uIG9mIHRyYW5zYWN0aW9ucyB0aGF0IGFyZSBDT01NSVRfUEVORElORworICBwcml2YXRlIFNldDxUcmFuc2FjdGlvblN0YXRlPiBjb21taXRQZW5kaW5nVHJhbnNhY3Rpb25zID0gQ29sbGVjdGlvbnMKKyAgICAgIC5zeW5jaHJvbml6ZWRTZXQobmV3IEhhc2hTZXQ8VHJhbnNhY3Rpb25TdGF0ZT4oKSk7CisKKyAgcHJpdmF0ZSBmaW5hbCBMZWFzZXMgdHJhbnNhY3Rpb25MZWFzZXM7CisgIHByaXZhdGUgQXRvbWljSW50ZWdlciBuZXh0U2VxdWVuY2VJZCA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworICBwcml2YXRlIE9iamVjdCBjb21taXRDaGVja0xvY2sgPSBuZXcgT2JqZWN0KCk7CisgIHByaXZhdGUgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyIGxvZ01hbmFnZXI7CisgIHByaXZhdGUgZmluYWwgaW50IG9sZFRyYW5zYWN0aW9uRmx1c2hUcmlnZ2VyOworCisgIC8qKgorICAgKiBAcGFyYW0gYmFzZWRpcgorICAgKiBAcGFyYW0gbG9nCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gY29uZgorICAgKiBAcGFyYW0gcmVnaW9uSW5mbworICAgKiBAcGFyYW0gZmx1c2hMaXN0ZW5lcgorICAgKi8KKyAgcHVibGljIFRyYW5zYWN0aW9uYWxSZWdpb24oZmluYWwgUGF0aCBiYXNlZGlyLCBmaW5hbCBITG9nIGxvZywKKyAgICAgIGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgZmluYWwgSFJlZ2lvbkluZm8gcmVnaW9uSW5mbywgZmluYWwgRmx1c2hSZXF1ZXN0ZXIgZmx1c2hMaXN0ZW5lcikgeworICAgIHN1cGVyKGJhc2VkaXIsIGxvZywgZnMsIGNvbmYsIHJlZ2lvbkluZm8sIGZsdXNoTGlzdGVuZXIpOworICAgIHRyYW5zYWN0aW9uTGVhc2VzID0gbmV3IExlYXNlcyhjb25mLmdldEludChMRUFTRV9USU1FLCBERUZBVUxUX0xFQVNFX1RJTUUpLAorICAgICAgICBMRUFTRV9DSEVDS19GUkVRVUVOQ1kpOworICAgIGxvZ01hbmFnZXIgPSBuZXcgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyKHRoaXMpOworICAgIG9sZFRyYW5zYWN0aW9uRmx1c2hUcmlnZ2VyID0gY29uZi5nZXRJbnQoT0xEX1RSQU5TQUNUSU9OX0ZMVVNILCBERUZBVUxUX09MRF9UUkFOU0FDVElPTl9GTFVTSCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgZG9SZWNvbnN0cnVjdGlvbkxvZyhmaW5hbCBQYXRoIG9sZExvZ0ZpbGUsCisgICAgICBmaW5hbCBsb25nIG1pblNlcUlkLCBmaW5hbCBsb25nIG1heFNlcUlkLCBmaW5hbCBQcm9ncmVzc2FibGUgcmVwb3J0ZXIpCisgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgIHN1cGVyLmRvUmVjb25zdHJ1Y3Rpb25Mb2cob2xkTG9nRmlsZSwgbWluU2VxSWQsIG1heFNlcUlkLCByZXBvcnRlcik7CisKKyAgICBNYXA8TG9uZywgTGlzdDxCYXRjaFVwZGF0ZT4+IGNvbW1pdGVkVHJhbnNhY3Rpb25zQnlJZCA9IGxvZ01hbmFnZXIKKyAgICAgICAgLmdldENvbW1pdHNGcm9tTG9nKG9sZExvZ0ZpbGUsIG1pblNlcUlkLCByZXBvcnRlcik7CisKKyAgICBpZiAoY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkICE9IG51bGwgJiYgY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkLnNpemUoKSA+IDApIHsKKyAgICAgIExPRy5kZWJ1ZygiZm91bmQgIiArIGNvbW1pdGVkVHJhbnNhY3Rpb25zQnlJZC5zaXplKCkKKyAgICAgICAgICArICIgQ09NTUlURUQgdHJhbnNhY3Rpb25zIik7CisKKyAgICAgIGZvciAoRW50cnk8TG9uZywgTGlzdDxCYXRjaFVwZGF0ZT4+IGVudHJ5IDogY29tbWl0ZWRUcmFuc2FjdGlvbnNCeUlkCisgICAgICAgICAgLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgTE9HLmRlYnVnKCJXcml0aW5nICIgKyBlbnRyeS5nZXRWYWx1ZSgpLnNpemUoKQorICAgICAgICAgICAgKyAiIHVwZGF0ZXMgZm9yIHRyYW5zYWN0aW9uICIgKyBlbnRyeS5nZXRLZXkoKSk7CisgICAgICAgIGZvciAoQmF0Y2hVcGRhdGUgYiA6IGVudHJ5LmdldFZhbHVlKCkpIHsKKyAgICAgICAgICBzdXBlci5iYXRjaFVwZGF0ZShiLCB0cnVlKTsgLy8gVGhlc2UgYXJlIHdhbGxlZCBzbyB0aGV5IGxpdmUgZm9yZXZlcgorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIExPRy5kZWJ1ZygiRmx1c2hpbmcgY2FjaGUiKTsgLy8gV2UgbXVzdCB0cmlnZ2VyIGEgY2FjaGUgZmx1c2gsCisgICAgICAvLyBvdGhlcndpc2UKKyAgICAgIC8vIHdlIHdpbGwgd291bGQgaWdub3JlIHRoZSBsb2cgb24gc3Vic2VxdWVudCBmYWlsdXJlCisgICAgICAvLyBpZiAoIXN1cGVyLmZsdXNoY2FjaGUoKSkgeworICAgICAgLy8gTE9HLndhcm4oIkRpZCBub3QgZmx1c2ggY2FjaGUiKTsKKyAgICAgIC8vIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogV2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB3ZSBkb24ndCBjb21wbGV0ZSBhIGNhY2hlIGZsdXNoIGJldHdlZW4gcnVubmluZworICAgKiB0cmFuc2FjdGlvbnMuIElmIHdlIGRpZCwgdGhlbiB3ZSB3b3VsZCBub3QgZmluZCBhbGwgbG9nIG1lc3NhZ2VzIG5lZWRlZCB0bworICAgKiByZXN0b3JlIHRoZSB0cmFuc2FjdGlvbiwgYXMgc29tZSBvZiB0aGVtIHdvdWxkIGJlIGJlZm9yZSB0aGUgbGFzdAorICAgKiAiY29tcGxldGUiIGZsdXNoIGlkLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBsb25nIGdldENvbXBsZXRlQ2FjaGVGbHVzaFNlcXVlbmNlSWQoZmluYWwgbG9uZyBjdXJyZW50U2VxdWVuY2VJZCkgeworICAgIGxvbmcgbWluUGVuZGluZ1N0YXJ0U2VxdWVuY2VJZCA9IGN1cnJlbnRTZXF1ZW5jZUlkOworICAgIGZvciAoVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlIDogdHJhbnNhY3Rpb25zQnlJZC52YWx1ZXMoKSkgeworICAgICAgbWluUGVuZGluZ1N0YXJ0U2VxdWVuY2VJZCA9IE1hdGgubWluKG1pblBlbmRpbmdTdGFydFNlcXVlbmNlSWQsCisgICAgICAgICAgdHJhbnNhY3Rpb25TdGF0ZS5nZXRITG9nU3RhcnRTZXF1ZW5jZUlkKCkpOworICAgIH0KKyAgICByZXR1cm4gbWluUGVuZGluZ1N0YXJ0U2VxdWVuY2VJZDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBiZWdpblRyYW5zYWN0aW9uKGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcga2V5ID0gU3RyaW5nLnZhbHVlT2YodHJhbnNhY3Rpb25JZCk7CisgICAgaWYgKHRyYW5zYWN0aW9uc0J5SWQuZ2V0KGtleSkgIT0gbnVsbCkgeworICAgICAgVHJhbnNhY3Rpb25TdGF0ZSBhbGlhcyA9IGdldFRyYW5zYWN0aW9uU3RhdGUodHJhbnNhY3Rpb25JZCk7CisgICAgICBpZiAoYWxpYXMgIT0gbnVsbCkgeworICAgICAgICBhbGlhcy5zZXRTdGF0dXMoU3RhdHVzLkFCT1JURUQpOworICAgICAgICByZXRpcmVUcmFuc2FjdGlvbihhbGlhcyk7CisgICAgICB9CisgICAgICBMT0cuZXJyb3IoIkV4aXN0aW5nIHRyYXNhY3Rpb24gd2l0aCBpZCBbIitrZXkrIl0gaW4gcmVnaW9uIFsiK3N1cGVyLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSsiXSIpOworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJBbHJlYWR5IGV4aXRpbmcgdHJhbnNhY3Rpb24gaWQ6ICIgKyBrZXkpOworICAgIH0KKworICAgIFRyYW5zYWN0aW9uU3RhdGUgc3RhdGUgPSBuZXcgVHJhbnNhY3Rpb25TdGF0ZSh0cmFuc2FjdGlvbklkLCBzdXBlci5nZXRMb2coKQorICAgICAgICAuZ2V0U2VxdWVuY2VOdW1iZXIoKSwgc3VwZXIuZ2V0UmVnaW9uSW5mbygpKTsKKworICAgIC8vIE9yZGVyIGlzIGltcG9ydGFudCBoZXJlIC4uLgorICAgIExpc3Q8VHJhbnNhY3Rpb25TdGF0ZT4gY29tbWl0UGVuZGluZ0NvcHkgPSBuZXcgTGlua2VkTGlzdDxUcmFuc2FjdGlvblN0YXRlPihjb21taXRQZW5kaW5nVHJhbnNhY3Rpb25zKTsKKyAgICBmb3IgKFRyYW5zYWN0aW9uU3RhdGUgY29tbWl0UGVuZGluZyA6IGNvbW1pdFBlbmRpbmdDb3B5KSB7CisgICAgICBzdGF0ZS5hZGRUcmFuc2FjdGlvblRvQ2hlY2soY29tbWl0UGVuZGluZyk7CisgICAgfQorICAgIHN0YXRlLnNldFN0YXJ0U2VxdWVuY2VOdW1iZXIobmV4dFNlcXVlbmNlSWQuZ2V0KCkpOworCisgICAgdHJhbnNhY3Rpb25zQnlJZC5wdXQoU3RyaW5nLnZhbHVlT2Yoa2V5KSwgc3RhdGUpOworICAgIHRyeSB7CisgICAgICB0cmFuc2FjdGlvbkxlYXNlcy5jcmVhdGVMZWFzZShrZXksIG5ldyBUcmFuc2FjdGlvbkxlYXNlTGlzdGVuZXIoa2V5KSk7CisgICAgfSBjYXRjaCAoTGVhc2VTdGlsbEhlbGRFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJMZWFzZSBzdGlsbCBoZWxkIGZvciBbIitrZXkrIl0gaW4gcmVnaW9uIFsiK3N1cGVyLmdldFJlZ2lvbkluZm8oKS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSsiXSIpOyAgICAgIAorICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgfQorICAgIExPRy5kZWJ1ZygiQmVnaW5pbmcgdHJhbnNhY3Rpb24gIiArIGtleSArICIgaW4gcmVnaW9uICIKKyAgICAgICAgKyBzdXBlci5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgIGxvZ01hbmFnZXIud3JpdGVTdGFydFRvTG9nKHRyYW5zYWN0aW9uSWQpOworICAgIAorICAgIG1heWJlVHJpZ2dlck9sZFRyYW5zYWN0aW9uRmx1c2goKTsKKyAgfQorCisgIC8qKgorICAgKiBGZXRjaCBhIHNpbmdsZSBkYXRhIGl0ZW0uCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHJldHVybiBjb2x1bW4gdmFsdWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGwgZ2V0KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJvdywKKyAgICAgIGZpbmFsIGJ5dGVbXSBjb2x1bW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQ2VsbFtdIHJlc3VsdHMgPSBnZXQodHJhbnNhY3Rpb25JZCwgcm93LCBjb2x1bW4sIDEpOworICAgIHJldHVybiAocmVzdWx0cyA9PSBudWxsIHx8IHJlc3VsdHMubGVuZ3RoID09IDApID8gbnVsbCA6IHJlc3VsdHNbMF07CisgIH0KKworICAvKioKKyAgICogRmV0Y2ggbXVsdGlwbGUgdmVyc2lvbnMgb2YgYSBzaW5nbGUgZGF0YSBpdGVtCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIG51bVZlcnNpb25zCisgICAqIEByZXR1cm4gYXJyYXkgb2YgdmFsdWVzIG9uZSBlbGVtZW50IHBlciB2ZXJzaW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBDZWxsW10gZ2V0KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJvdywKKyAgICAgIGZpbmFsIGJ5dGVbXSBjb2x1bW4sIGZpbmFsIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0KHRyYW5zYWN0aW9uSWQsIHJvdywgY29sdW1uLCBMb25nLk1BWF9WQUxVRSwgbnVtVmVyc2lvbnMpOworICB9CisKKyAgLyoqCisgICAqIEZldGNoIG11bHRpcGxlIHZlcnNpb25zIG9mIGEgc2luZ2xlIGRhdGEgaXRlbSwgd2l0aCB0aW1lc3RhbXAuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMKKyAgICogQHJldHVybiBhcnJheSBvZiB2YWx1ZXMgb25lIGVsZW1lbnQgcGVyIHZlcnNpb24gdGhhdCBtYXRjaGVzIHRoZSB0aW1lc3RhbXAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIENlbGxbXSBnZXQoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBieXRlW10gcm93LAorICAgICAgZmluYWwgYnl0ZVtdIGNvbHVtbiwgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIGludCBudW1WZXJzaW9ucykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVHJhbnNhY3Rpb25TdGF0ZSBzdGF0ZSA9IGdldFRyYW5zYWN0aW9uU3RhdGUodHJhbnNhY3Rpb25JZCk7CisKKyAgICBzdGF0ZS5hZGRSZWFkKHJvdyk7CisKKyAgICBDZWxsW10gbG9jYWxDZWxscyA9IHN0YXRlLmxvY2FsR2V0KHJvdywgY29sdW1uLCB0aW1lc3RhbXApOworCisgICAgaWYgKGxvY2FsQ2VsbHMgIT0gbnVsbCAmJiBsb2NhbENlbGxzLmxlbmd0aCA+IDApIHsKKyAgICAgIExPRworICAgICAgICAgIC50cmFjZSgiVHJhbnNhY3Rpb25hbCBnZXQgb2Ygc29tZXRoaW5nIHdlJ3ZlIHdyaXR0ZW4gaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24gIgorICAgICAgICAgICAgICArIHRyYW5zYWN0aW9uSWQpOworICAgICAgTE9HLnRyYWNlKCJyb3c6ICIgKyBCeXRlcy50b1N0cmluZyhyb3cpKTsKKyAgICAgIExPRy50cmFjZSgiY29sOiAiICsgQnl0ZXMudG9TdHJpbmcoY29sdW1uKSk7CisgICAgICBMT0cudHJhY2UoIm51bVZlcnNpb25zOiAiICsgbnVtVmVyc2lvbnMpOworICAgICAgZm9yIChDZWxsIGNlbGwgOiBsb2NhbENlbGxzKSB7CisgICAgICAgIExPRy50cmFjZSgiY2VsbDogIiArIEJ5dGVzLnRvU3RyaW5nKGNlbGwuZ2V0VmFsdWUoKSkpOworICAgICAgfQorCisgICAgICBpZiAobnVtVmVyc2lvbnMgPiAxKSB7CisgICAgICAgIC8vIEZJWCBUSElTIFBST0ZMSUdBQ1kgQ09OVkVSVElORyBSRVNVTFQgT0YgZ2V0LgorICAgICAgICBDZWxsW10gZ2xvYmFsQ2VsbHMgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShnZXQocm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMgLSAxKSk7CisgICAgICAgIENlbGxbXSByZXN1bHQgPSBuZXcgQ2VsbFtnbG9iYWxDZWxscy5sZW5ndGggKyBsb2NhbENlbGxzLmxlbmd0aF07CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobG9jYWxDZWxscywgMCwgcmVzdWx0LCAwLCBsb2NhbENlbGxzLmxlbmd0aCk7CisgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoZ2xvYmFsQ2VsbHMsIDAsIHJlc3VsdCwgbG9jYWxDZWxscy5sZW5ndGgsCisgICAgICAgICAgICBnbG9iYWxDZWxscy5sZW5ndGgpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgICAgcmV0dXJuIGxvY2FsQ2VsbHM7CisgICAgfQorCisgICAgcmV0dXJuIENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KGdldChyb3csIGNvbHVtbiwgdGltZXN0YW1wLCBudW1WZXJzaW9ucykpOworICB9CisKKyAgLyoqCisgICAqIEZldGNoIGFsbCB0aGUgY29sdW1ucyBmb3IgdGhlIGluZGljYXRlZCByb3cgYXQgYSBzcGVjaWZpZWQgdGltZXN0YW1wLgorICAgKiBSZXR1cm5zIGEgVHJlZU1hcCB0aGF0IG1hcHMgY29sdW1uIG5hbWVzIHRvIHZhbHVlcy4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkCisgICAqIEBwYXJhbSByb3cKKyAgICogQHBhcmFtIGNvbHVtbnMgQXJyYXkgb2YgY29sdW1ucyB5b3UnZCBsaWtlIHRvIHJldHJpZXZlLiBXaGVuIG51bGwsIGdldCBhbGwuCisgICAqIEBwYXJhbSB0cworICAgKiBAcmV0dXJuIE1hcDxjb2x1bW5OYW1lLCBDZWxsPiB2YWx1ZXMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIE1hcDxieXRlW10sIENlbGw+IGdldEZ1bGwoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBieXRlW10gcm93LAorICAgICAgZmluYWwgTmF2aWdhYmxlU2V0PGJ5dGVbXT4gY29sdW1ucywgZmluYWwgbG9uZyB0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlID0gZ2V0VHJhbnNhY3Rpb25TdGF0ZSh0cmFuc2FjdGlvbklkKTsKKworICAgIHN0YXRlLmFkZFJlYWQocm93KTsKKworICAgIE1hcDxieXRlW10sIENlbGw+IGxvY2FsQ2VsbHMgPSBzdGF0ZS5sb2NhbEdldEZ1bGwocm93LCBjb2x1bW5zLCB0cyk7CisKKyAgICBpZiAobG9jYWxDZWxscyAhPSBudWxsICYmIGxvY2FsQ2VsbHMuc2l6ZSgpID4gMCkgeworICAgICAgTE9HCisgICAgICAgICAgLnRyYWNlKCJUcmFuc2FjdGlvbmFsIGdldCBvZiBzb21ldGhpbmcgd2UndmUgd3JpdHRlbiBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiAiCisgICAgICAgICAgICAgICsgdHJhbnNhY3Rpb25JZCk7CisgICAgICBMT0cudHJhY2UoInJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKHJvdykpOworICAgICAgZm9yIChFbnRyeTxieXRlW10sIENlbGw+IGVudHJ5IDogbG9jYWxDZWxscy5lbnRyeVNldCgpKSB7CisgICAgICAgIExPRy50cmFjZSgiY29sOiAiICsgQnl0ZXMudG9TdHJpbmcoZW50cnkuZ2V0S2V5KCkpKTsKKyAgICAgICAgTE9HLnRyYWNlKCJjZWxsOiAiICsgQnl0ZXMudG9TdHJpbmcoZW50cnkuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpKSk7CisgICAgICB9CisKKyAgICAgIE1hcDxieXRlW10sIENlbGw+IGludGVybmFsUmVzdWx0cyA9IGdldEZ1bGwocm93LCBjb2x1bW5zLCB0cywgMSwgbnVsbCk7CisgICAgICBpbnRlcm5hbFJlc3VsdHMucHV0QWxsKGxvY2FsQ2VsbHMpOworICAgICAgcmV0dXJuIGludGVybmFsUmVzdWx0czsKKyAgICB9CisKKyAgICByZXR1cm4gZ2V0RnVsbChyb3csIGNvbHVtbnMsIHRzLCAxLCBudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gYW4gaXRlcmF0b3IgdGhhdCBzY2FucyBvdmVyIHRoZSBIUmVnaW9uLCByZXR1cm5pbmcgdGhlIGluZGljYXRlZAorICAgKiBjb2x1bW5zIGZvciBvbmx5IHRoZSByb3dzIHRoYXQgbWF0Y2ggdGhlIGRhdGEgZmlsdGVyLiBUaGlzIEl0ZXJhdG9yIG11c3QgYmUKKyAgICogY2xvc2VkIGJ5IHRoZSBjYWxsZXIuCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gY29scyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsIGNvbHVtbnMKKyAgICogb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gSXRzIGFsc28gcG9zc2libGUgdG8gcGFzcyBhCisgICAqIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLiBBIGNvbHVtbiBxdWFsaWZpZXIgaXMganVkZ2VkIHRvIGJlIGEgcmVnZXgKKyAgICogaWYgaXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczoKKyAgICogPGNvZGU+XCt8XiYqJFtdXX17KSg8L2NvZGU+LgorICAgKiBAcGFyYW0gZmlyc3RSb3cgcm93IHdoaWNoIGlzIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgc2NhbgorICAgKiBAcGFyYW0gdGltZXN0YW1wIG9ubHkgcmV0dXJuIHJvd3Mgd2hvc2UgdGltZXN0YW1wIGlzIDw9IHRoaXMgdmFsdWUKKyAgICogQHBhcmFtIGZpbHRlciByb3cgZmlsdGVyCisgICAqIEByZXR1cm4gSW50ZXJuYWxTY2FubmVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBJbnRlcm5hbFNjYW5uZXIgZ2V0U2Nhbm5lcihmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsCisgICAgICBmaW5hbCBieXRlW11bXSBjb2xzLCBmaW5hbCBieXRlW10gZmlyc3RSb3csIGZpbmFsIGxvbmcgdGltZXN0YW1wLAorICAgICAgZmluYWwgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlID0gZ2V0VHJhbnNhY3Rpb25TdGF0ZSh0cmFuc2FjdGlvbklkKTsKKyAgICBzdGF0ZS5hZGRTY2FuKGZpcnN0Um93LCBmaWx0ZXIpOworICAgIHJldHVybiBuZXcgU2Nhbm5lcldyYXBwZXIodHJhbnNhY3Rpb25JZCwgc3VwZXIuZ2V0U2Nhbm5lcihjb2xzLCBmaXJzdFJvdywKKyAgICAgICAgdGltZXN0YW1wLCBmaWx0ZXIpKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGQgYSB3cml0ZSB0byB0aGUgdHJhbnNhY3Rpb24uIERvZXMgbm90IGdldCBhcHBsaWVkIHVudGlsIGNvbW1pdCBwcm9jZXNzLgorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHBhcmFtIGIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgYmF0Y2hVcGRhdGUoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBCYXRjaFVwZGF0ZSBiKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlID0gZ2V0VHJhbnNhY3Rpb25TdGF0ZSh0cmFuc2FjdGlvbklkKTsKKyAgICBzdGF0ZS5hZGRXcml0ZShiKTsKKyAgICBsb2dNYW5hZ2VyLndyaXRlVXBkYXRlVG9Mb2codHJhbnNhY3Rpb25JZCwgYik7CisgIH0KKworICAvKioKKyAgICogQWRkIGEgZGVsZXRlIHRvIHRoZSB0cmFuc2FjdGlvbi4gRG9lcyBub3QgZ2V0IGFwcGxpZWQgdW50aWwgY29tbWl0IHByb2Nlc3MuCisgICAqIEZJWE1FLCBub3Qgc3VyZSBhYm91dCB0aGlzIGFwcHJvYWNoCisgICAqIAorICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgKiBAcGFyYW0gcm93CisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQWxsKGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJvdywKKyAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFRyYW5zYWN0aW9uU3RhdGUgc3RhdGUgPSBnZXRUcmFuc2FjdGlvblN0YXRlKHRyYW5zYWN0aW9uSWQpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICBmb3IgKFN0b3JlIHN0b3JlIDogc3VwZXIuc3RvcmVzLnZhbHVlcygpKSB7CisgICAgICBMaXN0PEtleVZhbHVlPiBrZXl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgc3RvcmUuZ2V0RnVsbChuZXcgS2V5VmFsdWUocm93LCB0aW1lc3RhbXApLAorICAgICAgICBudWxsLCBudWxsLCBBTExfVkVSU0lPTlMsIG51bGwsIGtleXZhbHVlcywgbm93KTsKKyAgICAgIEJhdGNoVXBkYXRlIGRlbGV0ZVVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3csIHRpbWVzdGFtcCk7CisKKyAgICAgIGZvciAoS2V5VmFsdWUga2V5IDoga2V5dmFsdWVzKSB7CisgICAgICAgIGRlbGV0ZVVwZGF0ZS5kZWxldGUoa2V5LmdldENvbHVtbigpKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgc3RhdGUuYWRkV3JpdGUoZGVsZXRlVXBkYXRlKTsKKyAgICAgIGxvZ01hbmFnZXIud3JpdGVVcGRhdGVUb0xvZyh0cmFuc2FjdGlvbklkLCBkZWxldGVVcGRhdGUpOworCisgICAgfQorCisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHJldHVybiB0cnVlIGlmIGNvbW1pdCBpcyBzdWNjZXNzZnVsCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGNvbW1pdFJlcXVlc3QoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN5bmNocm9uaXplZCAoY29tbWl0Q2hlY2tMb2NrKSB7CisgICAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlID0gZ2V0VHJhbnNhY3Rpb25TdGF0ZSh0cmFuc2FjdGlvbklkKTsKKyAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgaWYgKGhhc0NvbmZsaWN0KHN0YXRlKSkgeworICAgICAgICBzdGF0ZS5zZXRTdGF0dXMoU3RhdHVzLkFCT1JURUQpOworICAgICAgICByZXRpcmVUcmFuc2FjdGlvbihzdGF0ZSk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgLy8gTm8gY29uZmxpY3RzLCB3ZSBjYW4gY29tbWl0LgorICAgICAgTE9HLnRyYWNlKCJObyBjb25mbGljdHMgZm9yIHRyYW5zYWN0aW9uICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgKyAiIGZvdW5kIGluIHJlZ2lvbiAiICsgc3VwZXIuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpCisgICAgICAgICAgKyAiLiBWb3RpbmcgZm9yIGNvbW1pdCIpOworICAgICAgc3RhdGUuc2V0U3RhdHVzKFN0YXR1cy5DT01NSVRfUEVORElORyk7CisKKyAgICAgIC8vIElmIHRoZXJlIGFyZSB3cml0ZXMgd2UgbXVzdCBrZWVwIHJlY29yZCBvZmYgdGhlIHRyYW5zYWN0aW9uCisgICAgICBpZiAoc3RhdGUuZ2V0V3JpdGVTZXQoKS5zaXplKCkgPiAwKSB7CisgICAgICAgIC8vIE9yZGVyIGlzIGltcG9ydGFudAorICAgICAgICBjb21taXRQZW5kaW5nVHJhbnNhY3Rpb25zLmFkZChzdGF0ZSk7CisgICAgICAgIHN0YXRlLnNldFNlcXVlbmNlTnVtYmVyKG5leHRTZXF1ZW5jZUlkLmdldEFuZEluY3JlbWVudCgpKTsKKyAgICAgICAgY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLnB1dChzdGF0ZS5nZXRTZXF1ZW5jZU51bWJlcigpLAorICAgICAgICAgICAgc3RhdGUpOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gaGFzQ29uZmxpY3QoZmluYWwgVHJhbnNhY3Rpb25TdGF0ZSBzdGF0ZSkgeworICAgIC8vIENoZWNrIHRyYW5zYWN0aW9ucyB0aGF0IHdlcmUgY29tbWl0dGVkIHdoaWxlIHdlIHdlcmUgcnVubmluZworICAgIGZvciAoaW50IGkgPSBzdGF0ZS5nZXRTdGFydFNlcXVlbmNlTnVtYmVyKCk7IGkgPCBuZXh0U2VxdWVuY2VJZC5nZXQoKTsgaSsrKSB7CisgICAgICBUcmFuc2FjdGlvblN0YXRlIG90aGVyID0gY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLmdldChpKTsKKyAgICAgIGlmIChvdGhlciA9PSBudWxsKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgc3RhdGUuYWRkVHJhbnNhY3Rpb25Ub0NoZWNrKG90aGVyKTsKKyAgICB9CisKKyAgICByZXR1cm4gc3RhdGUuaGFzQ29uZmxpY3QoKTsKKyAgfQorCisgIC8qKgorICAgKiBDb21taXQgdGhlIHRyYW5zYWN0aW9uLgorICAgKiAKKyAgICogQHBhcmFtIHRyYW5zYWN0aW9uSWQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgY29tbWl0KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlOworICAgIHRyeSB7CisgICAgICBzdGF0ZSA9IGdldFRyYW5zYWN0aW9uU3RhdGUodHJhbnNhY3Rpb25JZCk7CisgICAgfSBjYXRjaCAoVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiQXNrZWQgdG8gY29tbWl0IHVua25vd24gdHJhbnNhY3Rpb246ICIgKyB0cmFuc2FjdGlvbklkCisgICAgICAgICAgKyAiIGluIHJlZ2lvbiAiICsgc3VwZXIuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgICAgIC8vIEZJWE1FIFdyaXRlIHRvIHRoZSB0cmFuc2FjdGlvbiBsb2cgdGhhdCB0aGlzIHRyYW5zYWN0aW9uIHdhcyBjb3JydXB0ZWQKKyAgICAgIHRocm93IGU7CisgICAgfQorCisgICAgaWYgKCFzdGF0ZS5nZXRTdGF0dXMoKS5lcXVhbHMoU3RhdHVzLkNPTU1JVF9QRU5ESU5HKSkgeworICAgICAgTE9HLmZhdGFsKCJBc2tlZCB0byBjb21taXQgYSBub24gcGVuZGluZyB0cmFuc2FjdGlvbiIpOworICAgICAgLy8gRklYTUUgV3JpdGUgdG8gdGhlIHRyYW5zYWN0aW9uIGxvZyB0aGF0IHRoaXMgdHJhbnNhY3Rpb24gd2FzIGNvcnJ1cHRlZAorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjb21taXQgZmFpbHVyZSIpOworICAgIH0KKworICAgIGNvbW1pdChzdGF0ZSk7CisgIH0KKworICAvKioKKyAgICogQ29tbWl0IHRoZSB0cmFuc2FjdGlvbi4KKyAgICogCisgICAqIEBwYXJhbSB0cmFuc2FjdGlvbklkCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGFib3J0KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHN0YXRlOworICAgIHRyeSB7CisgICAgICBzdGF0ZSA9IGdldFRyYW5zYWN0aW9uU3RhdGUodHJhbnNhY3Rpb25JZCk7CisgICAgfSBjYXRjaCAoVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiQXNrZWQgdG8gYWJvcnQgdW5rbm93biB0cmFuc2FjdGlvbjogIiArIHRyYW5zYWN0aW9uSWQpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHN0YXRlLnNldFN0YXR1cyhTdGF0dXMuQUJPUlRFRCk7CisKKyAgICBpZiAoc3RhdGUuZ2V0V3JpdGVTZXQoKS5zaXplKCkgPiAwKSB7CisgICAgICBsb2dNYW5hZ2VyLndyaXRlQWJvcnRUb0xvZyhzdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCkpOworICAgIH0KKworICAgIC8vIEZvbGxvd2luZyByZW1vdmVzIG5lZWRlZCBpZiB3ZSBoYXZlIHZvdGVkCisgICAgaWYgKHN0YXRlLmdldFNlcXVlbmNlTnVtYmVyKCkgIT0gbnVsbCkgeworICAgICAgY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLnJlbW92ZShzdGF0ZS5nZXRTZXF1ZW5jZU51bWJlcigpKTsKKyAgICB9CisgICAgY29tbWl0UGVuZGluZ1RyYW5zYWN0aW9ucy5yZW1vdmUoc3RhdGUpOworCisgICAgcmV0aXJlVHJhbnNhY3Rpb24oc3RhdGUpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNvbW1pdChmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHN0YXRlKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgTE9HLmRlYnVnKCJDb21taXRpbmcgdHJhbnNhY3Rpb246ICIgKyBzdGF0ZS50b1N0cmluZygpICsgIiB0byAiCisgICAgICAgICsgc3VwZXIuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKworICAgIGlmIChzdGF0ZS5nZXRXcml0ZVNldCgpLnNpemUoKSA+IDApIHsKKyAgICAgIGxvZ01hbmFnZXIud3JpdGVDb21taXRUb0xvZyhzdGF0ZS5nZXRUcmFuc2FjdGlvbklkKCkpOworICAgIH0KKworICAgIGZvciAoQmF0Y2hVcGRhdGUgdXBkYXRlIDogc3RhdGUuZ2V0V3JpdGVTZXQoKSkgeworICAgICAgdGhpcy5iYXRjaFVwZGF0ZSh1cGRhdGUsIGZhbHNlKTsgLy8gRG9uJ3QgbmVlZCB0byBXQUwgdGhlc2UKKyAgICAgIC8vIEZJTUUsIG1heWJlIHNob3VsZCBiZSB3YWxsZWQgc28gd2UgZG9uJ3QgbmVlZCB0byBsb29rIHNvIGZhciBiYWNrLgorICAgIH0KKworICAgIHN0YXRlLnNldFN0YXR1cyhTdGF0dXMuQ09NTUlURUQpOworICAgIGlmIChzdGF0ZS5nZXRXcml0ZVNldCgpLnNpemUoKSA+IDAKKyAgICAgICAgJiYgIWNvbW1pdFBlbmRpbmdUcmFuc2FjdGlvbnMucmVtb3ZlKHN0YXRlKSkgeworICAgICAgTE9HCisgICAgICAgICAgLmZhdGFsKCJDb21taXRpbmcgYSBub24tcXVlcnkgdHJhbnNhY3Rpb24gdGhhdCBpcyBub3QgaW4gY29tbWl0UGVuZGluZ1RyYW5zYWN0aW9ucyIpOworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjb21taXQgZmFpbHVyZSIpOyAvLyBGSVhNRSwgaG93IHRvIGhhbmRsZT8KKyAgICB9CisgICAgcmV0aXJlVHJhbnNhY3Rpb24oc3RhdGUpOworICB9CisKKyAgLy8gQ2FuY2VsIGxlYXNlcywgYW5kIHJlbW92ZWQgZnJvbSBsZWFzZSBsb29rdXAuIFRoaXMgdHJhbnNhY3Rpb24gbWF5IHN0aWxsCisgIC8vIGxpdmUgaW4gY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyIGFuZCBjb21taXRQZW5kaW5nVHJhbnNhY3Rpb25zCisgIHByaXZhdGUgdm9pZCByZXRpcmVUcmFuc2FjdGlvbihmaW5hbCBUcmFuc2FjdGlvblN0YXRlIHN0YXRlKSB7CisgICAgU3RyaW5nIGtleSA9IFN0cmluZy52YWx1ZU9mKHN0YXRlLmdldFRyYW5zYWN0aW9uSWQoKSk7CisgICAgdHJ5IHsKKyAgICAgIHRyYW5zYWN0aW9uTGVhc2VzLmNhbmNlbExlYXNlKGtleSk7CisgICAgfSBjYXRjaCAoTGVhc2VFeGNlcHRpb24gZSkgeworICAgICAgLy8gSWdub3JlCisgICAgfQorCisgICAgdHJhbnNhY3Rpb25zQnlJZC5yZW1vdmUoa2V5KTsKKyAgfQorCisgIHByb3RlY3RlZCBUcmFuc2FjdGlvblN0YXRlIGdldFRyYW5zYWN0aW9uU3RhdGUoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkKQorICAgICAgdGhyb3dzIFVua25vd25UcmFuc2FjdGlvbkV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIGtleSA9IFN0cmluZy52YWx1ZU9mKHRyYW5zYWN0aW9uSWQpOworICAgIFRyYW5zYWN0aW9uU3RhdGUgc3RhdGUgPSBudWxsOworCisgICAgc3RhdGUgPSB0cmFuc2FjdGlvbnNCeUlkLmdldChrZXkpOworCisgICAgaWYgKHN0YXRlID09IG51bGwpIHsKKyAgICAgIExPRy50cmFjZSgiVW5rbm93biB0cmFuc2FjdGlvbjogIiArIGtleSk7CisgICAgICB0aHJvdyBuZXcgVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uKGtleSk7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIHRyYW5zYWN0aW9uTGVhc2VzLnJlbmV3TGVhc2Uoa2V5KTsKKyAgICB9IGNhdGNoIChMZWFzZUV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICB9CisKKyAgICByZXR1cm4gc3RhdGU7CisgIH0KKworICBwcml2YXRlIHZvaWQgbWF5YmVUcmlnZ2VyT2xkVHJhbnNhY3Rpb25GbHVzaCgpIHsKKyAgICAgIGlmIChjb21taXRlZFRyYW5zYWN0aW9uc0J5U2VxdWVuY2VOdW1iZXIuc2l6ZSgpID4gb2xkVHJhbnNhY3Rpb25GbHVzaFRyaWdnZXIpIHsKKyAgICAgICAgcmVtb3ZlVW5OZWVkZWRDb21taXRlZFRyYW5zYWN0aW9ucygpOworICAgICAgfQorICB9CisgIAorICAvKioKKyAgICogQ2xlYW51cCByZWZlcmVuY2VzIHRvIGNvbW1pdHRlZCB0cmFuc2FjdGlvbnMgdGhhdCBhcmUgbm8gbG9uZ2VyIG5lZWRlZC4KKyAgICogCisgICAqLworICBzeW5jaHJvbml6ZWQgdm9pZCByZW1vdmVVbk5lZWRlZENvbW1pdGVkVHJhbnNhY3Rpb25zKCkgeworICAgIEludGVnZXIgbWluU3RhcnRTZXFOdW1iZXIgPSBnZXRNaW5TdGFydFNlcXVlbmNlTnVtYmVyKCk7CisgICAgaWYgKG1pblN0YXJ0U2VxTnVtYmVyID09IG51bGwpIHsKKyAgICAgIG1pblN0YXJ0U2VxTnVtYmVyID0gSW50ZWdlci5NQVhfVkFMVUU7IC8vIFJlbW92ZSBhbGwKKyAgICB9CisKKyAgICBpbnQgbnVtUmVtb3ZlZCA9IDA7CisgICAgLy8gQ29weSBsaXN0IHRvIGF2b2lkIGNvbmMgdXBkYXRlIGV4Y2VwdGlvbgorICAgIGZvciAoRW50cnk8SW50ZWdlciwgVHJhbnNhY3Rpb25TdGF0ZT4gZW50cnkgOiBuZXcgTGlua2VkTGlzdDxFbnRyeTxJbnRlZ2VyLCBUcmFuc2FjdGlvblN0YXRlPj4oCisgICAgICAgIGNvbW1pdGVkVHJhbnNhY3Rpb25zQnlTZXF1ZW5jZU51bWJlci5lbnRyeVNldCgpKSkgeworICAgICAgaWYgKGVudHJ5LmdldEtleSgpID49IG1pblN0YXJ0U2VxTnVtYmVyKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgbnVtUmVtb3ZlZCA9IG51bVJlbW92ZWQKKyAgICAgICAgICArIChjb21taXRlZFRyYW5zYWN0aW9uc0J5U2VxdWVuY2VOdW1iZXIucmVtb3ZlKGVudHJ5LmdldEtleSgpKSA9PSBudWxsID8gMAorICAgICAgICAgICAgICA6IDEpOworICAgICAgbnVtUmVtb3ZlZCsrOworICAgIH0KKworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgU3RyaW5nQnVpbGRlciBkZWJ1Z01lc3NhZ2UgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgaWYgKG51bVJlbW92ZWQgPiAwKSB7CisgICAgICAgIGRlYnVnTWVzc2FnZS5hcHBlbmQoIlJlbW92ZWQgIikuYXBwZW5kKG51bVJlbW92ZWQpLmFwcGVuZCgKKyAgICAgICAgICAgICIgY29tbWl0ZWQgdHJhbnNhY3Rpb25zIik7CisKKyAgICAgICAgaWYgKG1pblN0YXJ0U2VxTnVtYmVyID09IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgICAgZGVidWdNZXNzYWdlLmFwcGVuZCgid2l0aCBhbnkgc2VxdWVuY2UgbnVtYmVyIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZGVidWdNZXNzYWdlLmFwcGVuZCgid2l0aCBzZXF1ZW5jZSBsb3dlciB0aGFuICIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgbWluU3RhcnRTZXFOdW1iZXIpLmFwcGVuZCgiLiIpOworICAgICAgICB9CisgICAgICAgIGlmICghY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLmlzRW1wdHkoKSkgeworICAgICAgICAgIGRlYnVnTWVzc2FnZS5hcHBlbmQoIiBTdGlsbCBoYXZlICIpLmFwcGVuZCgKKyAgICAgICAgICAgICAgY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLnNpemUoKSkuYXBwZW5kKCIgbGVmdC4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBkZWJ1Z01lc3NhZ2UuYXBwZW5kKCJOb25lIGxlZnQuIik7CisgICAgICAgIH0KKyAgICAgICAgTE9HLmRlYnVnKGRlYnVnTWVzc2FnZS50b1N0cmluZygpKTsKKyAgICAgIH0gZWxzZSBpZiAoY29tbWl0ZWRUcmFuc2FjdGlvbnNCeVNlcXVlbmNlTnVtYmVyLnNpemUoKSA+IDApIHsKKyAgICAgICAgZGVidWdNZXNzYWdlLmFwcGVuZCgKKyAgICAgICAgICAgICJDb3VsZCBub3QgcmVtb3ZlIGFueSB0cmFuc2FjdGlvbnMsIGFuZCBzdGlsbCBoYXZlICIpLmFwcGVuZCgKKyAgICAgICAgICAgIGNvbW1pdGVkVHJhbnNhY3Rpb25zQnlTZXF1ZW5jZU51bWJlci5zaXplKCkpLmFwcGVuZCgiIGxlZnQiKTsKKyAgICAgICAgTE9HLmRlYnVnKGRlYnVnTWVzc2FnZS50b1N0cmluZygpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcml2YXRlIEludGVnZXIgZ2V0TWluU3RhcnRTZXF1ZW5jZU51bWJlcigpIHsKKyAgICBJbnRlZ2VyIG1pbiA9IG51bGw7CisgICAgZm9yIChUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgOiB0cmFuc2FjdGlvbnNCeUlkLnZhbHVlcygpKSB7CisgICAgICBpZiAobWluID09IG51bGwgfHwgdHJhbnNhY3Rpb25TdGF0ZS5nZXRTdGFydFNlcXVlbmNlTnVtYmVyKCkgPCBtaW4pIHsKKyAgICAgICAgbWluID0gdHJhbnNhY3Rpb25TdGF0ZS5nZXRTdGFydFNlcXVlbmNlTnVtYmVyKCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBtaW47CisgIH0KKworICAvLyBUT0RPLCByZXNvbHZlIGZyb20gdGhlIGdsb2JhbCB0cmFuc2FjdGlvbiBsb2cKKyAgcHJvdGVjdGVkIHZvaWQgcmVzb2x2ZVRyYW5zYWN0aW9uRnJvbUxvZygpIHsKKyAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiR2xvYmFxbCB0cmFuc2FjdGlvbiBsb2cgaXMgbm90IEltcGxlbWVudGVkIik7CisgIH0KKworICBwcml2YXRlIGNsYXNzIFRyYW5zYWN0aW9uTGVhc2VMaXN0ZW5lciBpbXBsZW1lbnRzIExlYXNlTGlzdGVuZXIgeworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHRyYW5zYWN0aW9uTmFtZTsKKworICAgIFRyYW5zYWN0aW9uTGVhc2VMaXN0ZW5lcihmaW5hbCBTdHJpbmcgbikgeworICAgICAgdGhpcy50cmFuc2FjdGlvbk5hbWUgPSBuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGxlYXNlRXhwaXJlZCgpIHsKKyAgICAgIExPRy5pbmZvKCJUcmFuc2FjdGlvbiAiICsgdGhpcy50cmFuc2FjdGlvbk5hbWUgKyAiIGxlYXNlIGV4cGlyZWQiKTsKKyAgICAgIFRyYW5zYWN0aW9uU3RhdGUgcyA9IG51bGw7CisgICAgICBzeW5jaHJvbml6ZWQgKHRyYW5zYWN0aW9uc0J5SWQpIHsKKyAgICAgICAgcyA9IHRyYW5zYWN0aW9uc0J5SWQucmVtb3ZlKHRyYW5zYWN0aW9uTmFtZSk7CisgICAgICB9CisgICAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICAgIExPRy53YXJuKCJVbmtub3duIHRyYW5zYWN0aW9uIGV4cGlyZWQgIiArIHRoaXMudHJhbnNhY3Rpb25OYW1lKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICBzd2l0Y2ggKHMuZ2V0U3RhdHVzKCkpIHsKKyAgICAgIGNhc2UgUEVORElORzoKKyAgICAgICAgcy5zZXRTdGF0dXMoU3RhdHVzLkFCT1JURUQpOyAvLyBPdGhlciB0cmFuc2FjdGlvbnMgbWF5IGhhdmUgYSByZWYKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIENPTU1JVF9QRU5ESU5HOgorICAgICAgICBMT0cuaW5mbygiVHJhbnNhY3Rpb24gIiArIHMuZ2V0VHJhbnNhY3Rpb25JZCgpCisgICAgICAgICAgICArICIgZXhwaXJlZCBpbiBDT01NSVRfUEVORElORyBzdGF0ZSIpOworICAgICAgICBMT0cuaW5mbygiQ2hlY2tpbmcgdHJhbnNhY3Rpb24gc3RhdHVzIGluIHRyYW5zYWN0aW9uIGxvZyIpOworICAgICAgICByZXNvbHZlVHJhbnNhY3Rpb25Gcm9tTG9nKCk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgTE9HLndhcm4oIlVuZXhwZWN0ZWQgc3RhdHVzIG9uIGV4cGlyZWQgbGVhc2UiKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKiogV3JhcHBlciB3aGljaCBrZWVwcyB0cmFjayBvZiByb3dzIHJldHVybmVkIGJ5IHNjYW5uZXIuICovCisgIHByaXZhdGUgY2xhc3MgU2Nhbm5lcldyYXBwZXIgaW1wbGVtZW50cyBJbnRlcm5hbFNjYW5uZXIgeworICAgIHByaXZhdGUgbG9uZyB0cmFuc2FjdGlvbklkOworICAgIHByaXZhdGUgSW50ZXJuYWxTY2FubmVyIHNjYW5uZXI7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JZAorICAgICAqIEBwYXJhbSBzY2FubmVyCisgICAgICogQHRocm93cyBVbmtub3duVHJhbnNhY3Rpb25FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgU2Nhbm5lcldyYXBwZXIoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLAorICAgICAgICBmaW5hbCBJbnRlcm5hbFNjYW5uZXIgc2Nhbm5lcikgdGhyb3dzIFVua25vd25UcmFuc2FjdGlvbkV4Y2VwdGlvbiB7CisKKyAgICAgIHRoaXMudHJhbnNhY3Rpb25JZCA9IHRyYW5zYWN0aW9uSWQ7CisgICAgICB0aGlzLnNjYW5uZXIgPSBzY2FubmVyOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBpc011bHRpcGxlTWF0Y2hTY2FubmVyKCkgeworICAgICAgcmV0dXJuIHNjYW5uZXIuaXNNdWx0aXBsZU1hdGNoU2Nhbm5lcigpOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzV2lsZGNhcmRTY2FubmVyKCkgeworICAgICAgcmV0dXJuIHNjYW5uZXIuaXNXaWxkY2FyZFNjYW5uZXIoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KExpc3Q8S2V5VmFsdWU+IHJlc3VsdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBib29sZWFuIHJlc3VsdCA9IHNjYW5uZXIubmV4dChyZXN1bHRzKTsKKyAgICAgIFRyYW5zYWN0aW9uU3RhdGUgc3RhdGUgPSBnZXRUcmFuc2FjdGlvblN0YXRlKHRyYW5zYWN0aW9uSWQpOworCisgICAgICBpZiAocmVzdWx0KSB7CisgICAgICAgIC8vIFRPRE86IElzIHRoaXMgcmlnaHQ/Pz8/IFN0LkFjaworICAgICAgICBieXRlIFtdIHJvdyA9IHJlc3VsdHMuZ2V0KDApLmdldFJvdygpOworICAgICAgICBNYXA8Ynl0ZVtdLCBDZWxsPiBsb2NhbFdyaXRlcyA9IHN0YXRlLmxvY2FsR2V0RnVsbChyb3csIG51bGwsCisgICAgICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSk7CisgICAgICAgIGlmIChsb2NhbFdyaXRlcyAhPSBudWxsKSB7CisgICAgICAgICAgTE9HLmluZm8oIlNjYW5uaW5nIG92ZXIgcm93IHRoYXQgaGFzIGJlZW4gd3JpdGVuIHRvICIgKyB0cmFuc2FjdGlvbklkKTsKKyAgICAgICAgICBmb3IgKEVudHJ5PGJ5dGVbXSwgQ2VsbD4gZW50cnkgOiBsb2NhbFdyaXRlcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgICAvLyBUT0RPOiBJcyB0aGlzIHJpZ2h0Pz8/CisgICAgICAgICAgICByZXN1bHRzLmFkZChuZXcgS2V5VmFsdWUocm93LCBlbnRyeS5nZXRLZXkoKSwKKyAgICAgICAgICAgICAgZW50cnkuZ2V0VmFsdWUoKS5nZXRUaW1lc3RhbXAoKSwgZW50cnkuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFjNWEzZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL1RyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDMwNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmxhbmcuVGhyZWFkLlVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLk5hdmlnYWJsZVNldDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJBZGRyZXNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTm90U2VydmluZ1JlZ2lvbkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZW1vdGVFeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5IYmFzZU1hcFdyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuSEJhc2VSUENQcm90b2NvbFZlcnNpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaXBjLlRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb25TZXJ2ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkludGVybmFsU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuVGhyZWFkczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5NYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlByb2dyZXNzYWJsZTsKKworLyoqCisgKiBSZWdpb25TZXJ2ZXIgd2l0aCBzdXBwb3J0IGZvciB0cmFuc2FjdGlvbnMuIFRyYW5zYWN0aW9uYWwgbG9naWMgaXMgYXQgdGhlCisgKiByZWdpb24gbGV2ZWwsIHNvIHdlIG1vc3RseSBqdXN0IGRlbGVnYXRlIHRvIHRoZSBhcHByb3ByaWF0ZQorICogVHJhbnNhY3Rpb25hbFJlZ2lvbi4KKyAqLworcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIgZXh0ZW5kcyBIUmVnaW9uU2VydmVyIGltcGxlbWVudHMKKyAgICBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyLmNsYXNzKTsKKworICBwcml2YXRlIGZpbmFsIENsZWFuT2xkVHJhbnNhY3Rpb25zQ2hvcmUgY2xlYW5PbGRUcmFuc2FjdGlvbnNUaHJlYWQ7CisKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBUcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzKG5ldyBIU2VydmVyQWRkcmVzcyhjb25mLmdldChSRUdJT05TRVJWRVJfQUREUkVTUywKKyAgICAgICAgREVGQVVMVF9SRUdJT05TRVJWRVJfQUREUkVTUykpLCBjb25mKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYWRkcmVzcworICAgKiBAcGFyYW0gY29uZgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgVHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlcihmaW5hbCBIU2VydmVyQWRkcmVzcyBhZGRyZXNzLAorICAgICAgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIoYWRkcmVzcywgY29uZik7CisgICAgY2xlYW5PbGRUcmFuc2FjdGlvbnNUaHJlYWQgPSBuZXcgQ2xlYW5PbGRUcmFuc2FjdGlvbnNDaG9yZSh0aGlzLAorICAgICAgICBzdXBlci5zdG9wUmVxdWVzdGVkKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyBnZXRQcm90b2NvbFZlcnNpb24oZmluYWwgU3RyaW5nIHByb3RvY29sLCBmaW5hbCBsb25nIGNsaWVudFZlcnNpb24pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChwcm90b2NvbC5lcXVhbHMoVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZS5jbGFzcy5nZXROYW1lKCkpKSB7CisgICAgICByZXR1cm4gSEJhc2VSUENQcm90b2NvbFZlcnNpb24udmVyc2lvbklEOworICAgIH0KKyAgICByZXR1cm4gc3VwZXIuZ2V0UHJvdG9jb2xWZXJzaW9uKHByb3RvY29sLCBjbGllbnRWZXJzaW9uKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBpbml0KGZpbmFsIE1hcFdyaXRhYmxlIGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIuaW5pdChjKTsKKyAgICBTdHJpbmcgbiA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCkuZ2V0TmFtZSgpOworICAgIFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlciBoYW5kbGVyID0gbmV3IFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcigpIHsKKyAgICAgIHB1YmxpYyB2b2lkIHVuY2F1Z2h0RXhjZXB0aW9uKGZpbmFsIFRocmVhZCB0LCBmaW5hbCBUaHJvd2FibGUgZSkgeworICAgICAgICBhYm9ydCgpOworICAgICAgICBMT0cuZmF0YWwoIlNldCBzdG9wIGZsYWcgaW4gIiArIHQuZ2V0TmFtZSgpLCBlKTsKKyAgICAgIH0KKyAgICB9OworICAgIFRocmVhZHMuc2V0RGFlbW9uVGhyZWFkUnVubmluZyh0aGlzLmNsZWFuT2xkVHJhbnNhY3Rpb25zVGhyZWFkLCBuCisgICAgICAgICsgIi5vbGRUcmFuc2FjdGlvbkNsZWFuZXIiLCBoYW5kbGVyKTsKKworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBIUmVnaW9uIGluc3RhbnRpYXRlUmVnaW9uKGZpbmFsIEhSZWdpb25JbmZvIHJlZ2lvbkluZm8pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gciA9IG5ldyBUcmFuc2FjdGlvbmFsUmVnaW9uKEhUYWJsZURlc2NyaXB0b3IuZ2V0VGFibGVEaXIoc3VwZXIKKyAgICAgICAgLmdldFJvb3REaXIoKSwgcmVnaW9uSW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCkpLCBzdXBlci5sb2csIHN1cGVyCisgICAgICAgIC5nZXRGaWxlU3lzdGVtKCksIHN1cGVyLmNvbmYsIHJlZ2lvbkluZm8sIHN1cGVyLmdldEZsdXNoUmVxdWVzdGVyKCkpOworICAgIHIuaW5pdGlhbGl6ZShudWxsLCBuZXcgUHJvZ3Jlc3NhYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcHJvZ3Jlc3MoKSB7CisgICAgICAgIGFkZFByb2Nlc3NpbmdNZXNzYWdlKHJlZ2lvbkluZm8pOworICAgICAgfQorICAgIH0pOworICAgIHJldHVybiByOworICB9CisKKyAgcHJvdGVjdGVkIFRyYW5zYWN0aW9uYWxSZWdpb24gZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihmaW5hbCBieXRlW10gcmVnaW9uTmFtZSkKKyAgICAgIHRocm93cyBOb3RTZXJ2aW5nUmVnaW9uRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gKFRyYW5zYWN0aW9uYWxSZWdpb24pIHN1cGVyLmdldFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFib3J0KGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLCBmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIHN1cGVyLmdldFJlcXVlc3RDb3VudCgpLmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICBnZXRUcmFuc2FjdGlvbmFsUmVnaW9uKHJlZ2lvbk5hbWUpLmFib3J0KHRyYW5zYWN0aW9uSWQpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBiYXRjaFVwZGF0ZShmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLAorICAgICAgZmluYWwgQmF0Y2hVcGRhdGUgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBzdXBlci5nZXRSZXF1ZXN0Q291bnQoKS5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKS5iYXRjaFVwZGF0ZSh0cmFuc2FjdGlvbklkLCBiKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgY29tbWl0KGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLCBmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIHN1cGVyLmdldFJlcXVlc3RDb3VudCgpLmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICBnZXRUcmFuc2FjdGlvbmFsUmVnaW9uKHJlZ2lvbk5hbWUpLmNvbW1pdCh0cmFuc2FjdGlvbklkKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gY29tbWl0UmVxdWVzdChmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwgZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBzdXBlci5nZXRSZXF1ZXN0Q291bnQoKS5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIGdldFRyYW5zYWN0aW9uYWxSZWdpb24ocmVnaW9uTmFtZSkuY29tbWl0UmVxdWVzdCh0cmFuc2FjdGlvbklkKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgcHVibGljIENlbGwgZ2V0KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW10gY29sdW1uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIHN1cGVyLmdldFJlcXVlc3RDb3VudCgpLmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICByZXR1cm4gZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKS5nZXQodHJhbnNhY3Rpb25JZCwgcm93LCBjb2x1bW4pOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgQ2VsbFtdIGdldChmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgYnl0ZVtdIGNvbHVtbiwgZmluYWwgaW50IG51bVZlcnNpb25zKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBzdXBlci5nZXRSZXF1ZXN0Q291bnQoKS5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIGdldFRyYW5zYWN0aW9uYWxSZWdpb24ocmVnaW9uTmFtZSkuZ2V0KHRyYW5zYWN0aW9uSWQsIHJvdywgY29sdW1uLAorICAgICAgICAgIG51bVZlcnNpb25zKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBjaGVja0ZpbGVTeXN0ZW0oKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgcHVibGljIENlbGxbXSBnZXQoZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBieXRlW10gcmVnaW9uTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGVbXSByb3csIGZpbmFsIGJ5dGVbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdGltZXN0YW1wLAorICAgICAgZmluYWwgaW50IG51bVZlcnNpb25zKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGNoZWNrT3BlbigpOworICAgIHN1cGVyLmdldFJlcXVlc3RDb3VudCgpLmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICByZXR1cm4gZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKS5nZXQodHJhbnNhY3Rpb25JZCwgcm93LCBjb2x1bW4sCisgICAgICAgICAgdGltZXN0YW1wLCBudW1WZXJzaW9ucyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgY2hlY2tGaWxlU3lzdGVtKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBsb25nIHRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRSb3codHJhbnNhY3Rpb25JZCwgcmVnaW9uTmFtZSwgcm93LCBudWxsLCB0cyk7CisgIH0KKworICBwdWJsaWMgUm93UmVzdWx0IGdldFJvdyhmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgYnl0ZVtdW10gY29sdW1ucykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0Um93KHRyYW5zYWN0aW9uSWQsIHJlZ2lvbk5hbWUsIHJvdywgY29sdW1ucywKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0Um93KGZpbmFsIGxvbmcgdHJhbnNhY3Rpb25JZCwgZmluYWwgYnl0ZVtdIHJlZ2lvbk5hbWUsCisgICAgICBmaW5hbCBieXRlW10gcm93LCBmaW5hbCBieXRlW11bXSBjb2x1bW5zLCBmaW5hbCBsb25nIHRzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja09wZW4oKTsKKyAgICBzdXBlci5nZXRSZXF1ZXN0Q291bnQoKS5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICB0cnkgeworICAgICAgLy8gY29udmVydCB0aGUgY29sdW1ucyBhcnJheSBpbnRvIGEgc2V0IHNvIGl0J3MgZWFzeSB0byBjaGVjayBsYXRlci4KKyAgICAgIE5hdmlnYWJsZVNldDxieXRlW10+IGNvbHVtblNldCA9IG51bGw7CisgICAgICBpZiAoY29sdW1ucyAhPSBudWxsKSB7CisgICAgICAgIGNvbHVtblNldCA9IG5ldyBUcmVlU2V0PGJ5dGVbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgICAgIGNvbHVtblNldC5hZGRBbGwoQXJyYXlzLmFzTGlzdChjb2x1bW5zKSk7CisgICAgICB9CisKKyAgICAgIFRyYW5zYWN0aW9uYWxSZWdpb24gcmVnaW9uID0gZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgICAgIE1hcDxieXRlW10sIENlbGw+IG1hcCA9IHJlZ2lvbi5nZXRGdWxsKHRyYW5zYWN0aW9uSWQsIHJvdywgY29sdW1uU2V0LCB0cyk7CisgICAgICBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSwgQ2VsbD4gcmVzdWx0ID0gbmV3IEhiYXNlTWFwV3JpdGFibGU8Ynl0ZVtdLCBDZWxsPigpOworICAgICAgcmVzdWx0LnB1dEFsbChtYXApOworICAgICAgcmV0dXJuIG5ldyBSb3dSZXN1bHQocm93LCByZXN1bHQpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLAorICAgICAgZmluYWwgYnl0ZVtdIHJvdywgZmluYWwgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tPcGVuKCk7CisgICAgc3VwZXIuZ2V0UmVxdWVzdENvdW50KCkuaW5jcmVtZW50QW5kR2V0KCk7CisgICAgdHJ5IHsKKyAgICAgIFRyYW5zYWN0aW9uYWxSZWdpb24gcmVnaW9uID0gZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKTsKKyAgICAgIHJlZ2lvbi5kZWxldGVBbGwodHJhbnNhY3Rpb25JZCwgcm93LCB0aW1lc3RhbXApOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGNoZWNrRmlsZVN5c3RlbSgpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgbG9uZyBvcGVuU2Nhbm5lcihmaW5hbCBsb25nIHRyYW5zYWN0aW9uSWQsIGZpbmFsIGJ5dGVbXSByZWdpb25OYW1lLAorICAgICAgZmluYWwgYnl0ZVtdW10gY29scywgZmluYWwgYnl0ZVtdIGZpcnN0Um93LCBmaW5hbCBsb25nIHRpbWVzdGFtcCwKKyAgICAgIGZpbmFsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY2hlY2tPcGVuKCk7CisgICAgTnVsbFBvaW50ZXJFeGNlcHRpb24gbnBlID0gbnVsbDsKKyAgICBpZiAocmVnaW9uTmFtZSA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oInJlZ2lvbk5hbWUgaXMgbnVsbCIpOworICAgIH0gZWxzZSBpZiAoY29scyA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImNvbHVtbnMgdG8gc2NhbiBpcyBudWxsIik7CisgICAgfSBlbHNlIGlmIChmaXJzdFJvdyA9PSBudWxsKSB7CisgICAgICBucGUgPSBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImZpcnN0Um93IGZvciBzY2FubmVyIGlzIG51bGwiKTsKKyAgICB9CisgICAgaWYgKG5wZSAhPSBudWxsKSB7CisgICAgICBJT0V4Y2VwdGlvbiBpbyA9IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBhcmd1bWVudHMgdG8gb3BlblNjYW5uZXIiKTsKKyAgICAgIGlvLmluaXRDYXVzZShucGUpOworICAgICAgdGhyb3cgaW87CisgICAgfQorICAgIHN1cGVyLmdldFJlcXVlc3RDb3VudCgpLmluY3JlbWVudEFuZEdldCgpOworICAgIHRyeSB7CisgICAgICBUcmFuc2FjdGlvbmFsUmVnaW9uIHIgPSBnZXRUcmFuc2FjdGlvbmFsUmVnaW9uKHJlZ2lvbk5hbWUpOworICAgICAgbG9uZyBzY2FubmVySWQgPSAtMUw7CisgICAgICBJbnRlcm5hbFNjYW5uZXIgcyA9IHIuZ2V0U2Nhbm5lcih0cmFuc2FjdGlvbklkLCBjb2xzLCBmaXJzdFJvdywKKyAgICAgICAgICB0aW1lc3RhbXAsIGZpbHRlcik7CisgICAgICBzY2FubmVySWQgPSBzdXBlci5hZGRTY2FubmVyKHMpOworICAgICAgcmV0dXJuIHNjYW5uZXJJZDsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoIkVycm9yIG9wZW5pbmcgc2Nhbm5lciAoZnNPazogIiArIHRoaXMuZnNPayArICIpIiwKKyAgICAgICAgICBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZSkpOworICAgICAgY2hlY2tGaWxlU3lzdGVtKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIGJlZ2luVHJhbnNhY3Rpb24oZmluYWwgbG9uZyB0cmFuc2FjdGlvbklkLCBmaW5hbCBieXRlW10gcmVnaW9uTmFtZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZ2V0VHJhbnNhY3Rpb25hbFJlZ2lvbihyZWdpb25OYW1lKS5iZWdpblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uSWQpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvQWJzdHJhY3RDb250cm9sbGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0Fic3RyYWN0Q29udHJvbGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4OWYyODQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0Fic3RyYWN0Q29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsNjggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0OworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QucGFyc2VyLklIQmFzZVJlc3RQYXJzZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0Q29udHJvbGxlciBpbXBsZW1lbnRzIFJFU1RDb25zdGFudHMgeworICBwcm90ZWN0ZWQgQ29uZmlndXJhdGlvbiBjb25mOworICBwcm90ZWN0ZWQgQWJzdHJhY3RNb2RlbCBtb2RlbDsKKworICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBIQmFzZUFkbWluIGFkbWluKSB7CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB0aGlzLm1vZGVsID0gZ2VuZXJhdGVNb2RlbChjb25mLCBhZG1pbik7CisgIH0KKworICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBnZXQoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwb3N0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAsIGJ5dGVbXSBpbnB1dCwgSUhCYXNlUmVzdFBhcnNlciBwYXJzZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uOworCisgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHB1dChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwLCBieXRlW10gaW5wdXQsIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkZWxldGUoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICBwcm90ZWN0ZWQgYWJzdHJhY3QgQWJzdHJhY3RNb2RlbCBnZW5lcmF0ZU1vZGVsKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgSEJhc2VBZG1pbiBhKTsKKyAgCisgIHByb3RlY3RlZCBieXRlW11bXSBnZXRDb2x1bW5zRnJvbVF1ZXJ5TWFwKE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCkgeworICAgIGJ5dGVbXVtdIGNvbHVtbnMgPSBudWxsOworICAgIFN0cmluZ1tdIGNvbHVtbkFycmF5ID0gcXVlcnlNYXAuZ2V0KFJFU1RDb25zdGFudHMuQ09MVU1OKTsKKyAgICBpZiAoY29sdW1uQXJyYXkgIT0gbnVsbCkgeworICAgICAgY29sdW1ucyA9IG5ldyBieXRlW2NvbHVtbkFycmF5Lmxlbmd0aF1bXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29sdW1uQXJyYXkubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgY29sdW1uc1tpXSA9IEJ5dGVzLnRvQnl0ZXMoY29sdW1uQXJyYXlbaV0pOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY29sdW1uczsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9BYnN0cmFjdE1vZGVsLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0Fic3RyYWN0TW9kZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zM2FjNzM2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9BYnN0cmFjdE1vZGVsLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQmFzZTY0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE1vZGVsIHsKKworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coQWJzdHJhY3RNb2RlbC5jbGFzcyk7CisgIHByb3RlY3RlZCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJvdGVjdGVkIEhCYXNlQWRtaW4gYWRtaW47CisKKyAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBFbmNvZGluZ3MgeworCisgICAgcHJvdGVjdGVkIGludGVyZmFjZSBFbmNvZGluZyB7CisKKyAgICAgIFN0cmluZyBlbmNvZGUoYnl0ZVtdIGIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBFbmNvZGluZyBFQmFzZTY0ID0gbmV3IEVuY29kaW5nKCkgeworCisgICAgICBwdWJsaWMgU3RyaW5nIGVuY29kZShieXRlW10gYikgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBCYXNlNjQuZW5jb2RlQnl0ZXMoYik7CisgICAgICB9CisgICAgfTsKKyAgICBwdWJsaWMgc3RhdGljIEVuY29kaW5nIEVVVEY4ID0gbmV3IEVuY29kaW5nKCkgeworCisgICAgICBwdWJsaWMgU3RyaW5nIGVuY29kZShieXRlW10gYikgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGIpOworICAgICAgfQorICAgIH07CisgIH0KKworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIEVuY29kaW5ncy5FbmNvZGluZyBlbmNvZGluZyA9IEVuY29kaW5ncy5FVVRGODsKKworICBwdWJsaWMgdm9pZCBpbml0aWFsaXplKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBIQmFzZUFkbWluIGFkbWluKSB7CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB0aGlzLmFkbWluID0gYWRtaW47CisgIH0KKworICBwcm90ZWN0ZWQgYnl0ZVtdW10gZ2V0Q29sdW1ucyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIGggPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICBDb2xsZWN0aW9uPEhDb2x1bW5EZXNjcmlwdG9yPiBjb2x1bW5zID0gaC5nZXRUYWJsZURlc2NyaXB0b3IoKQorICAgICAgICAgIC5nZXRGYW1pbGllcygpOworICAgICAgYnl0ZVtdW10gcmVzdWx0YW50ID0gbmV3IGJ5dGVbY29sdW1ucy5zaXplKCldW107CisgICAgICBpbnQgY291bnQgPSAwOworCisgICAgICBmb3IgKEhDb2x1bW5EZXNjcmlwdG9yIGMgOiBjb2x1bW5zKSB7CisgICAgICAgIHJlc3VsdGFudFtjb3VudCsrXSA9IGMuZ2V0TmFtZVdpdGhDb2xvbigpOworICAgICAgfQorCisgICAgICByZXR1cm4gcmVzdWx0YW50OworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIENPTE9OID0gQnl0ZXMudG9CeXRlcygiOiIpWzBdOworCisgIHByb3RlY3RlZCBib29sZWFuIGlzQ29sdW1uRmFtaWx5KGJ5dGVbXSBjb2x1bW5OYW1lKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5OYW1lLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoY29sdW1uTmFtZVtpXSA9PSBDT0xPTikgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvRGF0YWJhc2VDb250cm9sbGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0RhdGFiYXNlQ29udHJvbGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ZWEwMmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0RhdGFiYXNlQ29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0OworCitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlcjsKKworcHVibGljIGNsYXNzIERhdGFiYXNlQ29udHJvbGxlciBleHRlbmRzIEFic3RyYWN0Q29udHJvbGxlciB7CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByaXZhdGUgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKERhdGFiYXNlQ29udHJvbGxlci5jbGFzcyk7CisKKyAgcHJvdGVjdGVkIERhdGFiYXNlTW9kZWwgZ2V0TW9kZWwoKSB7CisgICAgcmV0dXJuIChEYXRhYmFzZU1vZGVsKSBtb2RlbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgQWJzdHJhY3RNb2RlbCBnZW5lcmF0ZU1vZGVsKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHJldHVybiBuZXcgRGF0YWJhc2VNb2RlbChjb25mLCBhZG1pbik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZ2V0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHMuc2V0Tm9RdWVyeVJlc3VsdHMoKTsKKyAgICBEYXRhYmFzZU1vZGVsIGlubmVyTW9kZWwgPSBnZXRNb2RlbCgpOworCisgICAgaWYgKHF1ZXJ5TWFwLnNpemUoKSA9PSAwKSB7CisgICAgICBzLnNldE9LKGlubmVyTW9kZWwuZ2V0RGF0YWJhc2VNZXRhZGF0YSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgcy5zZXRCYWRSZXF1ZXN0KCJVbmtub3duIHF1ZXJ5LiIpOworICAgIH0KKyAgICBzLnJlc3BvbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBwb3N0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAsIGJ5dGVbXSBpbnB1dCwgSUhCYXNlUmVzdFBhcnNlciBwYXJzZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzLnNldE1ldGhvZE5vdEltcGxlbWVudGVkKCk7CisgICAgcy5yZXNwb25kKCk7CisKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBwdXQoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCwgYnl0ZVtdIGlucHV0LCBJSEJhc2VSZXN0UGFyc2VyIHBhcnNlcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHMuc2V0TWV0aG9kTm90SW1wbGVtZW50ZWQoKTsKKyAgICBzLnJlc3BvbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGUoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcy5zZXRNZXRob2ROb3RJbXBsZW1lbnRlZCgpOworICAgIHMucmVzcG9uZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0RhdGFiYXNlTW9kZWwuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvRGF0YWJhc2VNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjN2E0ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0RhdGFiYXNlTW9kZWwuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVNlcmlhbGl6YWJsZTsKKworaW1wb3J0IGFnaWxlanNvbi5UT0pTT047CisKK3B1YmxpYyBjbGFzcyBEYXRhYmFzZU1vZGVsIGV4dGVuZHMgQWJzdHJhY3RNb2RlbCB7CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByaXZhdGUgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKERhdGFiYXNlTW9kZWwuY2xhc3MpOworCisgIHB1YmxpYyBEYXRhYmFzZU1vZGVsKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBIQmFzZUFkbWluIGFkbWluKSB7CisgICAgc3VwZXIuaW5pdGlhbGl6ZShjb25mLCBhZG1pbik7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIERhdGFiYXNlTWV0YWRhdGEgaW1wbGVtZW50cyBJU2VyaWFsaXphYmxlIHsKKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtYXN0ZXJfcnVubmluZzsKKyAgICBwcm90ZWN0ZWQgSFRhYmxlRGVzY3JpcHRvcltdIHRhYmxlczsKKworICAgIHB1YmxpYyBEYXRhYmFzZU1ldGFkYXRhKEhCYXNlQWRtaW4gYSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIG1hc3Rlcl9ydW5uaW5nID0gYS5pc01hc3RlclJ1bm5pbmcoKTsKKyAgICAgIHRhYmxlcyA9IGEubGlzdFRhYmxlcygpOworICAgIH0KKworICAgIEBUT0pTT04ocHJlZml4TGVuZ3RoID0gMikKKyAgICBwdWJsaWMgYm9vbGVhbiBpc01hc3RlclJ1bm5pbmcoKSB7CisgICAgICByZXR1cm4gbWFzdGVyX3J1bm5pbmc7CisgICAgfQorCisgICAgQFRPSlNPTgorICAgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yW10gZ2V0VGFibGVzKCkgeworICAgICAgcmV0dXJuIHRhYmxlczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXN0U2VyaWFsaXplKElSZXN0U2VyaWFsaXplciBzZXJpYWxpemVyKQorICAgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAgIHNlcmlhbGl6ZXIuc2VyaWFsaXplRGF0YWJhc2VNZXRhZGF0YSh0aGlzKTsKKyAgICB9CisgIH0KKworICAvLyBTZXJpYWxpemUgYWRtaW4gb3Vyc2VsdmVzIHRvIGpzb24gb2JqZWN0CisgIC8vIHJhdGhlciB0aGFuIHJldHVybmluZyB0aGUgYWRtaW4gb2JqZWN0IGZvciBvYnZpb3VzIHJlYXNvbnMKKyAgcHVibGljIERhdGFiYXNlTWV0YWRhdGEgZ2V0TWV0YWRhdGEoKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZ2V0RGF0YWJhc2VNZXRhZGF0YSgpOworICB9CisKKyAgcHJvdGVjdGVkIERhdGFiYXNlTWV0YWRhdGEgZ2V0RGF0YWJhc2VNZXRhZGF0YSgpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIERhdGFiYXNlTWV0YWRhdGEgZGF0YWJhc2VNZXRhZGF0YSA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIGRhdGFiYXNlTWV0YWRhdGEgPSBuZXcgRGF0YWJhc2VNZXRhZGF0YSh0aGlzLmFkbWluKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKworICAgIHJldHVybiBkYXRhYmFzZU1ldGFkYXRhOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0Rpc3BhdGNoZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvRGlzcGF0Y2hlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0OTYwN2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L0Rpc3BhdGNoZXIuamF2YQpAQCAtMCwwICsxLDQ5NSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QucGFyc2VyLkhCYXNlUmVzdFBhcnNlckZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuUmVzdFNlcmlhbGl6ZXJGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5JbmZvU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5TdGF0dXNIdHRwU2VydmVyOworaW1wb3J0IG9yZy5tb3J0YmF5Lmh0dHAuTkNTQVJlcXVlc3RMb2c7CitpbXBvcnQgb3JnLm1vcnRiYXkuaHR0cC5Tb2NrZXRMaXN0ZW5lcjsKK2ltcG9ydCBvcmcubW9ydGJheS5qZXR0eS5zZXJ2bGV0LldlYkFwcGxpY2F0aW9uQ29udGV4dDsKKworaW1wb3J0IGphdmF4LnNlcnZsZXQuU2VydmxldEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXF1ZXN0OworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKKy8qKgorICogU2VydmxldCBpbXBsZW1lbnRhdGlvbiBjbGFzcyBmb3IgaGJhc2UgUkVTVCBpbnRlcmZhY2UuIFByZXN1bWVzIGNvbnRhaW5lcgorICogZW5zdXJlcyBzaW5nbGUgdGhyZWFkIHRocm91Z2ggaGVyZSBhdCBhbnkgb25lIHRpbWUgKFVzdWFsbHkgdGhlIGRlZmF1bHQKKyAqIGNvbmZpZ3VyYXRpb24pLiBJbiBvdGhlciB3b3JkcywgY29kZSBpcyBub3Qgd3JpdHRlbiB0aHJlYWQtc2FmZS4KKyAqIDxwPgorICogVGhpcyBzZXJ2bGV0IGhhcyBleHBsaWNpdCBkZXBlbmRlbmN5IG9uIEpldHR5IHNlcnZlcjsgaXQgdXNlcyB0aGUgamV0dHkKKyAqIGltcGxlbWVudGF0aW9uIG9mIE11bHRpcGFydFJlc3BvbnNlLgorICogCisgKiA8cD4KKyAqIFRPRE86CisgKiA8dWw+CisgKiA8bGk+bXVsdGlwYXJ0L3JlbGF0ZWQgcmVzcG9uc2UgaXMgbm90IGNvcnJlY3Q7IHRoZSBzZXJ2bGV0IHNldENvbnRlbnRUeXBlIGlzCisgKiBicm9rZW4uIEkgYW0gdW5hYmxlIHRvIGFkZCBwYXJhbWV0ZXJzIHN1Y2ggYXMgYm91bmRhcnkgb3Igc3RhcnQgdG8KKyAqIG11bHRpcGFydC9yZWxhdGVkLiBUaGV5IGdldCBzdHJpcHBlZC48L2xpPgorICogPGxpPkN1cnJlbnRseSBjcmVhdGluZyBhIHNjYW5uZXIsIG5lZWQgdG8gc3BlY2lmeSBhIGNvbHVtbi4gTmVlZCB0byBtYWtlIGl0CisgKiBzbyB0aGUgSFRhYmxlIGluc3RhbmNlIGhhcyBjdXJyZW50IHRhYmxlJ3MgbWV0YWRhdGEgdG8taGFuZCBzbyBlYXN5IHRvIGZpbmQKKyAqIHRoZSBsaXN0IG9mIGFsbCBjb2x1bW4gZmFtaWxpZXMgc28gY2FuIG1ha2UgdXAgbGlzdCBvZiBjb2x1bW5zIGlmIG5vbmUKKyAqIHNwZWNpZmllZC48L2xpPgorICogPGxpPk1pbm9yIGl0ZW1zIGFyZSB3ZSBhcmUgZGVjb2RpbmcgVVJMcyBpbiBwbGFjZXMgd2hlcmUgcHJvYmFibHkgYWxyZWFkeQorICogZG9uZSBhbmQgaG93IHRvIHRpbWVvdXQgc2Nhbm5lcnMgdGhhdCBhcmUgaW4gdGhlIHNjYW5uZXIgbGlzdC48L2xpPgorICogPC91bD4KKyAqIAorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2x1Y2VuZS1oYWRvb3AvSGJhc2UvSGJhc2VSZXN0Ij5IYmFzZQorICogICAgICBSRVNUIFNwZWNpZmljYXRpb248L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBEaXNwYXRjaGVyIGV4dGVuZHMgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0IHsKKworICAvKioKKyAgICogCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODA3NTMzNTQzNTc5NzA3MTU2OUw7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhEaXNwYXRjaGVyLmNsYXNzKTsKKyAgcHJvdGVjdGVkIERhdGFiYXNlQ29udHJvbGxlciBkYkNvbnRyb2xsZXI7CisgIHByb3RlY3RlZCBUYWJsZUNvbnRyb2xsZXIgdGFibGVDb250cm9sbGVyOworICBwcm90ZWN0ZWQgUm93Q29udHJvbGxlciByb3dDb250cm9sbGVyOworICBwcm90ZWN0ZWQgU2Nhbm5lckNvbnRyb2xsZXIgc2Nhbm5lcmNvbnRyb2xsZXI7CisgIHByb3RlY3RlZCBUaW1lc3RhbXBDb250cm9sbGVyIHRzQ29udHJvbGxlcjsKKworICBwdWJsaWMgZW51bSBDb250ZW50VHlwZSB7CisgICAgWE1MKCJ0ZXh0L3htbCIpLCBKU09OKCJhcHBsaWNhdGlvbi9qc29uIiksIFBMQUlOKCJ0ZXh0L3BsYWluIiksIE1JTUUoCisgICAgICAgICJtdWx0aXBhcnQvcmVsYXRlZCIpLCBOT1RfQUNDRVBUQUJMRSgiIik7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0eXBlOworCisgICAgcHJpdmF0ZSBDb250ZW50VHlwZShmaW5hbCBTdHJpbmcgdCkgeworICAgICAgdGhpcy50eXBlID0gdDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgcmV0dXJuIHRoaXMudHlwZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IG1ldGhvZCB1c2VkIGxvb2tpbmcgYXQgQWNjZXB0IGhlYWRlciBjb250ZW50LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0CisgICAgICogICAgICAgICAgVGhlIGNvbnRlbnQgdHlwZSB0byBleGFtaW5lLgorICAgICAqIEByZXR1cm4gVGhlIGVudW0gdGhhdCBtYXRjaGVzIHRoZSBwcmVmaXggb2YgPGNvZGU+dDwvY29kZT4gb3IgdGhlIGRlZmF1bHQKKyAgICAgKiAgICAgICAgIGVudW0gaWYgPGNvZGU+dDwvY29kZT4gaXMgZW1wdHkuIElmIHVuc3VwcG9ydGVkIHR5cGUsIHdlIHJldHVybgorICAgICAqICAgICAgICAgTk9UX0FDQ0VQVEFCTEUuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBDb250ZW50VHlwZSBnZXRDb250ZW50VHlwZShmaW5hbCBTdHJpbmcgdCkgeworICAgICAgLy8gRGVmYXVsdCB0byB0ZXh0L3BsYWluLiBDdXJsIHNlbmRzICovKi4KKyAgICAgIGlmICh0ID09IG51bGwgfHwgdC5lcXVhbHMoIiovKiIpKSB7CisgICAgICAgIHJldHVybiBDb250ZW50VHlwZS5YTUw7CisgICAgICB9CisgICAgICBTdHJpbmcgbG93ZXJDYXNlZCA9IHQudG9Mb3dlckNhc2UoKTsKKyAgICAgIENvbnRlbnRUeXBlW10gdmFsdWVzID0gQ29udGVudFR5cGUudmFsdWVzKCk7CisgICAgICBDb250ZW50VHlwZSByZXN1bHQgPSBudWxsOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgaWYgKGxvd2VyQ2FzZWQuc3RhcnRzV2l0aCh2YWx1ZXNbaV0udHlwZSkpIHsKKyAgICAgICAgICByZXN1bHQgPSB2YWx1ZXNbaV07CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IE5PVF9BQ0NFUFRBQkxFIDogcmVzdWx0OworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCisgICAqLworICBwdWJsaWMgRGlzcGF0Y2hlcigpIHsKKyAgICBzdXBlcigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGluaXQoKSB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuaW5pdCgpOworCisgICAgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG51bGw7CisKKyAgICB0cnkgeworICAgICAgYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICAgIGNyZWF0ZUNvbnRyb2xsZXJzKCk7CisKKyAgICAgIGRiQ29udHJvbGxlci5pbml0aWFsaXplKGNvbmYsIGFkbWluKTsKKyAgICAgIHRhYmxlQ29udHJvbGxlci5pbml0aWFsaXplKGNvbmYsIGFkbWluKTsKKyAgICAgIHJvd0NvbnRyb2xsZXIuaW5pdGlhbGl6ZShjb25mLCBhZG1pbik7CisgICAgICB0c0NvbnRyb2xsZXIuaW5pdGlhbGl6ZShjb25mLCBhZG1pbik7CisgICAgICBzY2FubmVyY29udHJvbGxlci5pbml0aWFsaXplKGNvbmYsIGFkbWluKTsKKworICAgICAgTE9HLmRlYnVnKCJubyBlcnJvcnMgaW4gaW5pdC4iKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKGUudG9TdHJpbmcoKSk7CisgICAgICB0aHJvdyBuZXcgU2VydmxldEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDb250cm9sbGVycygpIHsKKyAgICBkYkNvbnRyb2xsZXIgPSBuZXcgRGF0YWJhc2VDb250cm9sbGVyKCk7CisgICAgdGFibGVDb250cm9sbGVyID0gbmV3IFRhYmxlQ29udHJvbGxlcigpOworICAgIHJvd0NvbnRyb2xsZXIgPSBuZXcgUm93Q29udHJvbGxlcigpOworICAgIHRzQ29udHJvbGxlciA9IG5ldyBUaW1lc3RhbXBDb250cm9sbGVyKCk7CisgICAgc2Nhbm5lcmNvbnRyb2xsZXIgPSBuZXcgU2Nhbm5lckNvbnRyb2xsZXIoKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgZG9HZXQoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBTdGF0dXMgcyA9IHRoaXMuY3JlYXRlU3RhdHVzKHJlcXVlc3QsIHJlc3BvbnNlKTsKKyAgICAgIGJ5dGVbXVtdIHBhdGhTZWdtZW50cyA9IGdldFBhdGhTZWdtZW50cyhyZXF1ZXN0KTsKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCA9IHJlcXVlc3QuZ2V0UGFyYW1ldGVyTWFwKCk7CisKKyAgICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID09IDAgfHwgcGF0aFNlZ21lbnRzWzBdLmxlbmd0aCA8PSAwKSB7CisgICAgICAgIC8vIGlmIGl0IHdhcyBhIHJvb3QgcmVxdWVzdCwgdGhlbiBnZXQgc29tZSBtZXRhZGF0YSBhYm91dAorICAgICAgICAvLyB0aGUgZW50aXJlIGluc3RhbmNlLgorICAgICAgICBkYkNvbnRyb2xsZXIuZ2V0KHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXApOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKHBhdGhTZWdtZW50cy5sZW5ndGggPj0gMgorICAgICAgICAgICAgJiYgcGF0aFNlZ21lbnRzLmxlbmd0aCA8PSAzCisgICAgICAgICAgICAmJiBwYXRoU2VnbWVudHNbMF0ubGVuZ3RoID4gMAorICAgICAgICAgICAgJiYgQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzFdKS50b0xvd2VyQ2FzZSgpLmVxdWFscygKKyAgICAgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlJPVykpIHsKKyAgICAgICAgICAvLyBpZiBpdCBoYXMgdGFibGUgbmFtZSBhbmQgcm93IHBhdGggc2VnbWVudHMKKyAgICAgICAgICByb3dDb250cm9sbGVyLmdldChzLCBwYXRoU2VnbWVudHMsIHF1ZXJ5TWFwKTsKKyAgICAgICAgfSBlbHNlIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID09IDQKKyAgICAgICAgICAgICYmIEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgICAgICAgICAgUkVTVENvbnN0YW50cy5ST1cpKSB7CisgICAgICAgICAgdHNDb250cm9sbGVyLmdldChzLCBwYXRoU2VnbWVudHMsIHF1ZXJ5TWFwKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBvdGhlcndpc2UsIGl0IG11c3QgYmUgYSBHRVQgcmVxdWVzdCBzdWl0YWJsZSBmb3IgdGhlCisgICAgICAgICAgLy8gdGFibGUgaGFuZGxlci4KKyAgICAgICAgICB0YWJsZUNvbnRyb2xsZXIuZ2V0KHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXApOworICAgICAgICB9CisgICAgICB9CisgICAgICBMT0cuZGVidWcoIkdFVCAtIE5vIEVycm9yIik7CisgICAgfSBjYXRjaCAoSEJhc2VSZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5kZWJ1ZygiR0VUIC0gRXJyb3I6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgdHJ5IHsKKyAgICAgICAgU3RhdHVzIHNFcnJvciA9IGNyZWF0ZVN0YXR1cyhyZXF1ZXN0LCByZXNwb25zZSk7CisgICAgICAgIHNFcnJvci5zZXRJbnRlcm5hbEVycm9yKGUpOworICAgICAgICBzRXJyb3IucmVzcG9uZCgpOworICAgICAgfSBjYXRjaCAoSEJhc2VSZXN0RXhjZXB0aW9uIGYpIHsKKyAgICAgICAgcmVzcG9uc2Uuc2VuZEVycm9yKEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfSU5URVJOQUxfU0VSVkVSX0VSUk9SKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIGRvUG9zdChIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgU2VydmxldEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKworICAgICAgU3RhdHVzIHMgPSBjcmVhdGVTdGF0dXMocmVxdWVzdCwgcmVzcG9uc2UpOworICAgICAgYnl0ZVtdW10gcGF0aFNlZ21lbnRzID0gZ2V0UGF0aFNlZ21lbnRzKHJlcXVlc3QpOworICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXJNYXAoKTsKKyAgICAgIGJ5dGVbXSBpbnB1dCA9IHJlYWRJbnB1dEJ1ZmZlcihyZXF1ZXN0KTsKKyAgICAgIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyID0gdGhpcy5nZXRQYXJzZXIocmVxdWVzdCk7CisKKyAgICAgIGlmICgocGF0aFNlZ21lbnRzLmxlbmd0aCA+PSAwICYmIHBhdGhTZWdtZW50cy5sZW5ndGggPD0gMSkKKyAgICAgICAgICB8fCBCeXRlcy50b1N0cmluZyhwYXRoU2VnbWVudHNbMV0pLnRvTG93ZXJDYXNlKCkuZXF1YWxzKAorICAgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLkVOQUJMRSkKKyAgICAgICAgICB8fCBCeXRlcy50b1N0cmluZyhwYXRoU2VnbWVudHNbMV0pLnRvTG93ZXJDYXNlKCkuZXF1YWxzKAorICAgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLkRJU0FCTEUpKSB7CisgICAgICAgIC8vIHRoaXMgaXMgYSB0YWJsZSByZXF1ZXN0CisgICAgICAgIHRhYmxlQ29udHJvbGxlci5wb3N0KHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXAsIGlucHV0LCBwYXJzZXIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gdGhlcmUgc2hvdWxkIGJlIGF0IGxlYXN0IHR3byBwYXRoIHNlZ21lbnRzICh0YWJsZSBuYW1lIGFuZCByb3cgb3IKKyAgICAgICAgLy8gc2Nhbm5lcikKKyAgICAgICAgaWYgKHBhdGhTZWdtZW50cy5sZW5ndGggPj0gMiAmJiBwYXRoU2VnbWVudHNbMF0ubGVuZ3RoID4gMCkgeworICAgICAgICAgIGlmIChCeXRlcy50b1N0cmluZyhwYXRoU2VnbWVudHNbMV0pLnRvTG93ZXJDYXNlKCkuZXF1YWxzKAorICAgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlNDQU5ORVIpKSB7CisgICAgICAgICAgICBzY2FubmVyY29udHJvbGxlci5wb3N0KHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXAsIGlucHV0LCBwYXJzZXIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgIH0gZWxzZSBpZiAoQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzFdKS50b0xvd2VyQ2FzZSgpLmVxdWFscygKKyAgICAgICAgICAgICAgUkVTVENvbnN0YW50cy5ST1cpCisgICAgICAgICAgICAgICYmIHBhdGhTZWdtZW50cy5sZW5ndGggPj0gMykgeworICAgICAgICAgICAgcm93Q29udHJvbGxlci5wb3N0KHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXAsIGlucHV0LCBwYXJzZXIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0gY2F0Y2ggKEhCYXNlUmVzdEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZGVidWcoIlBPU1QgLSBFcnJvcjogIiArIGUudG9TdHJpbmcoKSk7CisgICAgICB0cnkgeworICAgICAgICBTdGF0dXMgc19lcnJvciA9IGNyZWF0ZVN0YXR1cyhyZXF1ZXN0LCByZXNwb25zZSk7CisgICAgICAgIHNfZXJyb3Iuc2V0SW50ZXJuYWxFcnJvcihlKTsKKyAgICAgICAgc19lcnJvci5yZXNwb25kKCk7CisgICAgICB9IGNhdGNoIChIQmFzZVJlc3RFeGNlcHRpb24gZikgeworICAgICAgICByZXNwb25zZS5zZW5kRXJyb3IoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19JTlRFUk5BTF9TRVJWRVJfRVJST1IpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgZG9QdXQoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBieXRlW11bXSBwYXRoU2VnbWVudHMgPSBnZXRQYXRoU2VnbWVudHMocmVxdWVzdCk7CisgICAgICBpZihwYXRoU2VnbWVudHMubGVuZ3RoID09IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigibWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnRzLmxlbmd0aCA9PSAxICYmIHBhdGhTZWdtZW50c1swXS5sZW5ndGggPiAwKSB7CisgICAgICAgIC8vIGlmIGl0IGhhcyBvbmx5IHRhYmxlIG5hbWUKKyAgICAgICAgU3RhdHVzIHMgPSBjcmVhdGVTdGF0dXMocmVxdWVzdCwgcmVzcG9uc2UpOworICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAgPSByZXF1ZXN0LmdldFBhcmFtZXRlck1hcCgpOworICAgICAgICBJSEJhc2VSZXN0UGFyc2VyIHBhcnNlciA9IHRoaXMuZ2V0UGFyc2VyKHJlcXVlc3QpOworICAgICAgICBieXRlW10gaW5wdXQgPSByZWFkSW5wdXRCdWZmZXIocmVxdWVzdCk7CisgICAgICAgIHRhYmxlQ29udHJvbGxlci5wdXQocywgcGF0aFNlZ21lbnRzLCBxdWVyeU1hcCwgaW5wdXQsIHBhcnNlcik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBFcXVhdGUgUFVUIHdpdGggYSBQT1NULgorICAgICAgICBkb1Bvc3QocmVxdWVzdCwgcmVzcG9uc2UpOworICAgICAgfQorICAgIH0gY2F0Y2ggKEhCYXNlUmVzdEV4Y2VwdGlvbiBlKSB7CisgICAgICB0cnkgeworICAgICAgICBTdGF0dXMgc19lcnJvciA9IGNyZWF0ZVN0YXR1cyhyZXF1ZXN0LCByZXNwb25zZSk7CisgICAgICAgIHNfZXJyb3Iuc2V0SW50ZXJuYWxFcnJvcihlKTsKKyAgICAgICAgc19lcnJvci5yZXNwb25kKCk7CisgICAgICB9IGNhdGNoIChIQmFzZVJlc3RFeGNlcHRpb24gZikgeworICAgICAgICByZXNwb25zZS5zZW5kRXJyb3IoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19JTlRFUk5BTF9TRVJWRVJfRVJST1IpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgZG9EZWxldGUoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsCisgICAgICBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKSB0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBTdGF0dXMgcyA9IGNyZWF0ZVN0YXR1cyhyZXF1ZXN0LCByZXNwb25zZSk7CisgICAgICBieXRlW11bXSBwYXRoU2VnbWVudHMgPSBnZXRQYXRoU2VnbWVudHMocmVxdWVzdCk7CisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAgPSByZXF1ZXN0LmdldFBhcmFtZXRlck1hcCgpOworICAgICAgCisgICAgICBpZihwYXRoU2VnbWVudHMubGVuZ3RoID09IDApIHsKKyAgICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigibWV0aG9kIG5vdCBzdXBwb3J0ZWQiKTsKKyAgICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnRzLmxlbmd0aCA9PSAxICYmIHBhdGhTZWdtZW50c1swXS5sZW5ndGggPiAwKSB7CisgICAgICAgIC8vIGlmIGl0IG9ubHkgaGFzIG9ubHkgdGFibGUgbmFtZQorICAgICAgICB0YWJsZUNvbnRyb2xsZXIuZGVsZXRlKHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXApOworICAgICAgICByZXR1cm47CisgICAgICB9IGVsc2UgaWYgKHBhdGhTZWdtZW50cy5sZW5ndGggPj0gMyAmJiBwYXRoU2VnbWVudHNbMF0ubGVuZ3RoID4gMCkgeworICAgICAgICAvLyBtdXN0IGJlIGF0IGxlYXN0IHR3byBwYXRoIHNlZ21lbnRzICh0YWJsZSBuYW1lIGFuZCByb3cgb3Igc2Nhbm5lcikKKyAgICAgICAgaWYgKEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlNDQU5ORVIpCisgICAgICAgICAgICAmJiBwYXRoU2VnbWVudHMubGVuZ3RoID09IDMgJiYgcGF0aFNlZ21lbnRzWzJdLmxlbmd0aCA+IDApIHsKKyAgICAgICAgICAvLyBERUxFVEUgdG8gYSBzY2FubmVyIHJlcXVpcmVzIGF0IGxlYXN0IHRocmVlIHBhdGggc2VnbWVudHMKKyAgICAgICAgICBzY2FubmVyY29udHJvbGxlci5kZWxldGUocywgcGF0aFNlZ21lbnRzLCBxdWVyeU1hcCk7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9IGVsc2UgaWYgKEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlJPVykKKyAgICAgICAgICAgICYmIHBhdGhTZWdtZW50cy5sZW5ndGggPj0gMykgeworICAgICAgICAgIHJvd0NvbnRyb2xsZXIuZGVsZXRlKHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXApOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfSBlbHNlIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID09IDQpIHsKKyAgICAgICAgICB0c0NvbnRyb2xsZXIuZGVsZXRlKHMsIHBhdGhTZWdtZW50cywgcXVlcnlNYXApOworICAgICAgICB9CisgICAgICB9CisgICAgfSBjYXRjaCAoSEJhc2VSZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5kZWJ1ZygiUE9TVCAtIEVycm9yOiAiICsgZS50b1N0cmluZygpKTsKKyAgICAgIHRyeSB7CisgICAgICAgIFN0YXR1cyBzX2Vycm9yID0gY3JlYXRlU3RhdHVzKHJlcXVlc3QsIHJlc3BvbnNlKTsKKyAgICAgICAgc19lcnJvci5zZXRJbnRlcm5hbEVycm9yKGUpOworICAgICAgICBzX2Vycm9yLnJlc3BvbmQoKTsKKyAgICAgIH0gY2F0Y2ggKEhCYXNlUmVzdEV4Y2VwdGlvbiBmKSB7CisgICAgICAgIHJlc3BvbnNlLnNlbmRFcnJvcihIdHRwU2VydmxldFJlc3BvbnNlLlNDX0lOVEVSTkFMX1NFUlZFUl9FUlJPUik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFRoaXMgbWV0aG9kIHdpbGwgZ2V0IHRoZSBwYXRoIHNlZ21lbnRzIGZyb20gdGhlIEh0dHBTZXJ2bGV0UmVxdWVzdC4gIFBsZWFzZQorICAgKiBub3RlIHRoYXQgaWYgdGhlIGZpcnN0IHNlZ21lbnQgb2YgdGhlIHBhdGggaXMgL2FwaSB0aGlzIGlzIHJlbW92ZWQgZnJvbSB0aGUgCisgICAqIHJldHVybmluZyBieXRlIGFycmF5LgorICAgKiAKKyAgICogQHBhcmFtIHJlcXVlc3QKKyAgICogCisgICAqIEByZXR1cm4gcmVxdWVzdCBwYXRoaW5mbyBzcGxpdCBvbiB0aGUgJy8nIGlnbm9yaW5nIHRoZSBmaXJzdCAnLycgc28gZmlyc3QKKyAgICogZWxlbWVudCBpbiBwYXRoU2VnbWVudCBpcyBub3QgdGhlIGVtcHR5IHN0cmluZy4KKyAgICovCisgIHByb3RlY3RlZCBieXRlW11bXSBnZXRQYXRoU2VnbWVudHMoZmluYWwgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QpIHsKKyAgICBpbnQgY29udGV4dF9sZW4gPSByZXF1ZXN0LmdldENvbnRleHRQYXRoKCkubGVuZ3RoKCkgKyAxOworICAgIAorICAgIGJ5dGVbXVtdIHBhdGhTZWdtZW50cyA9IEJ5dGVzLnRvQnl0ZUFycmF5cyhyZXF1ZXN0LmdldFJlcXVlc3RVUkkoKS5zdWJzdHJpbmcoY29udGV4dF9sZW4pCisgICAgICAgIC5zcGxpdCgiLyIpKTsKKyAgICBieXRlW10gYXBpQXNCeXRlcyA9ICJhcGkiLmdldEJ5dGVzKCk7CisgICAgaWYgKEFycmF5cy5lcXVhbHMoYXBpQXNCeXRlcywgcGF0aFNlZ21lbnRzWzBdKSkgeworICAgICAgYnl0ZVtdW10gbmV3UGF0aFNlZ21lbnRzID0gbmV3IGJ5dGVbcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDFdW107CisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbmV3UGF0aFNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIG5ld1BhdGhTZWdtZW50c1tpXSA9IHBhdGhTZWdtZW50c1tpICsgMV07CisgICAgICB9CisgICAgICBwYXRoU2VnbWVudHMgPSBuZXdQYXRoU2VnbWVudHM7CisgICAgfQorICAgIHJldHVybiBwYXRoU2VnbWVudHM7CisgIH0KKworICBwcm90ZWN0ZWQgYnl0ZVtdIHJlYWRJbnB1dEJ1ZmZlcihIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBTdHJpbmcgcmVzdWx0YW50ID0gIiI7CisgICAgICBCdWZmZXJlZFJlYWRlciByID0gcmVxdWVzdC5nZXRSZWFkZXIoKTsKKworICAgICAgaW50IG1heExlbmd0aCA9IDUwMDA7IC8vIHRpZSB0byBjb25mCisgICAgICBpbnQgYnVmZmVyTGVuZ3RoID0gNjQwOworCisgICAgICAvLyBUT0RPIG1ha2UgcyBtYXhMZW5ndGggYW5kIGMgc2l6ZSB2YWx1ZXMgaW4gY29uZmlndXJhdGlvbgorICAgICAgaWYgKCFyLnJlYWR5KCkpIHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOyAvLyBJZiByIGlzIG5vdCByZWFkeSB3YWl0IDEgc2Vjb25kCisgICAgICAgIGlmICghci5yZWFkeSgpKSB7IC8vIElmIHIgc3RpbGwgaXMgbm90IHJlYWR5IHNvbWV0aGluZyBpcyB3cm9uZywgcmV0dXJuCisgICAgICAgICAgLy8gYmxhbmsuCisgICAgICAgICAgcmV0dXJuIG5ldyBieXRlWzBdOworICAgICAgICB9CisgICAgICB9CisgICAgICBjaGFyW10gYzsvLyA0MCBjaGFyYWN0ZXJzICogc2l6ZW9mKFVURjE2KQorICAgICAgd2hpbGUgKHIucmVhZHkoKSkgeworICAgIAljID0gbmV3IGNoYXJbYnVmZmVyTGVuZ3RoXTsgCisgICAgICAgIGludCBuID0gci5yZWFkKGMsIDAsIGJ1ZmZlckxlbmd0aCk7CisgICAgICAgIHJlc3VsdGFudCArPSBuZXcgU3RyaW5nKGMpOworICAgICAgICBpZiAobiAhPSBidWZmZXJMZW5ndGgpIHsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSBlbHNlIGlmIChyZXN1bHRhbnQubGVuZ3RoKCkgPiBtYXhMZW5ndGgpIHsKKyAgICAgICAgICByZXN1bHRhbnQgPSByZXN1bHRhbnQuc3Vic3RyaW5nKDAsIG1heExlbmd0aCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBCeXRlcy50b0J5dGVzKHJlc3VsdGFudC50cmltKCkpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHByb3RlY3RlZCBJSEJhc2VSZXN0UGFyc2VyIGdldFBhcnNlcihIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCkgeworICAgIHJldHVybiBIQmFzZVJlc3RQYXJzZXJGYWN0b3J5LmdldFBhcnNlcihDb250ZW50VHlwZS5nZXRDb250ZW50VHlwZShyZXF1ZXN0CisgICAgICAgIC5nZXRIZWFkZXIoImNvbnRlbnQtdHlwZSIpKSk7CisgIH0KKworICBwcm90ZWN0ZWQgU3RhdHVzIGNyZWF0ZVN0YXR1cyhIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwKKyAgICAgIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgU3RhdHVzKHJlc3BvbnNlLCBSZXN0U2VyaWFsaXplckZhY3RvcnkuZ2V0U2VyaWFsaXplcihyZXF1ZXN0LAorICAgICAgICByZXNwb25zZSksIHRoaXMuZ2V0UGF0aFNlZ21lbnRzKHJlcXVlc3QpKTsKKyAgfQorCisgIC8vCisgIC8vIE1haW4gcHJvZ3JhbSBhbmQgc3VwcG9ydCByb3V0aW5lcworICAvLworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgcHJpbnRVc2FnZUFuZEV4aXQoKSB7CisgICAgcHJpbnRVc2FnZUFuZEV4aXQobnVsbCk7CisgIH0KKworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgcHJpbnRVc2FnZUFuZEV4aXQoZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBpZiAobWVzc2FnZSAhPSBudWxsKSB7CisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obWVzc2FnZSk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigiVXNhZ2U6IGphdmEgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5EaXNwYXRjaGVyICIKKyAgICAgICAgKyAiLS1oZWxwIHwgWy0tcG9ydD1QT1JUXSBbLS1iaW5kPUFERFJdIHN0YXJ0Iik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJBcmd1bWVudHM6Iik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIgc3RhcnQgU3RhcnQgUkVTVCBzZXJ2ZXIiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiBzdG9wICBTdG9wIFJFU1Qgc2VydmVyIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJPcHRpb25zOiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIHBvcnQgIFBvcnQgdG8gbGlzdGVuIG9uLiBEZWZhdWx0OiA2MDA1MC4iKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiBiaW5kICBBZGRyZXNzIHRvIGJpbmQgb24uIERlZmF1bHQ6IDAuMC4wLjAuIik7CisgICAgU3lzdGVtLm91dAorICAgICAgICAucHJpbnRsbigiIG1heC1udW0tdGhyZWFkcyAgVGhlIG1heGltdW0gbnVtYmVyIG9mIHRocmVhZHMgZm9yIEpldHR5IHRvIHJ1bi4gRGVmYXVsdHMgdG8gMjU2LiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIGhlbHAgIFByaW50IHRoaXMgbWVzc2FnZSBhbmQgZXhpdC4iKTsKKworICAgIFN5c3RlbS5leGl0KDApOworICB9CisKKyAgLyoKKyAgICogU3RhcnQgdXAgdGhlIFJFU1Qgc2VydmxldCBpbiBzdGFuZGFsb25lIG1vZGUuCisgICAqIAorICAgKiBAcGFyYW0gYXJncworICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGRvTWFpbihmaW5hbCBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpZiAoYXJncy5sZW5ndGggPCAxKSB7CisgICAgICBwcmludFVzYWdlQW5kRXhpdCgpOworICAgIH0KKworICAgIGludCBwb3J0ID0gNjAwNTA7CisgICAgU3RyaW5nIGJpbmRBZGRyZXNzID0gIjAuMC4wLjAiOworICAgIGludCBudW1UaHJlYWRzID0gMjU2OworCisgICAgLy8gUHJvY2VzcyBjb21tYW5kLWxpbmUgYXJncy4gVE9ETzogQmV0dGVyIGNtZC1saW5lIHByb2Nlc3NpbmcKKyAgICAvLyAoYnV0IGhvcGVmdWxseSBzb21ldGhpbmcgbm90IGFzIHBhaW5mdWwgYXMgY2xpIG9wdGlvbnMpLgorICAgIGZpbmFsIFN0cmluZyBhZGRyZXNzQXJnS2V5ID0gIi0tYmluZD0iOworICAgIGZpbmFsIFN0cmluZyBwb3J0QXJnS2V5ID0gIi0tcG9ydD0iOworICAgIGZpbmFsIFN0cmluZyBudW1UaHJlYWRzS2V5ID0gIi0tbWF4LW51bS10aHJlYWRzPSI7CisgICAgZm9yIChTdHJpbmcgY21kIDogYXJncykgeworICAgICAgaWYgKGNtZC5zdGFydHNXaXRoKGFkZHJlc3NBcmdLZXkpKSB7CisgICAgICAgIGJpbmRBZGRyZXNzID0gY21kLnN1YnN0cmluZyhhZGRyZXNzQXJnS2V5Lmxlbmd0aCgpKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9IGVsc2UgaWYgKGNtZC5zdGFydHNXaXRoKHBvcnRBcmdLZXkpKSB7CisgICAgICAgIHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGNtZC5zdWJzdHJpbmcocG9ydEFyZ0tleS5sZW5ndGgoKSkpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0gZWxzZSBpZiAoY21kLmVxdWFscygiLS1oZWxwIikgfHwgY21kLmVxdWFscygiLWgiKSkgeworICAgICAgICBwcmludFVzYWdlQW5kRXhpdCgpOworICAgICAgfSBlbHNlIGlmIChjbWQuZXF1YWxzKCJzdGFydCIpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfSBlbHNlIGlmIChjbWQuZXF1YWxzKCJzdG9wIikpIHsKKyAgICAgICAgcHJpbnRVc2FnZUFuZEV4aXQoIlRvIHNodXRkb3duIHRoZSBSRVNUIHNlcnZlciBydW4gIgorICAgICAgICAgICAgKyAiYmluL2hiYXNlLWRhZW1vbi5zaCBzdG9wIHJlc3Qgb3Igc2VuZCBhIGtpbGwgc2lnbmFsIHRvICIKKyAgICAgICAgICAgICsgInRoZSBSRVNUIHNlcnZlciBwaWQiKTsKKyAgICAgIH0gZWxzZSBpZiAoY21kLnN0YXJ0c1dpdGgobnVtVGhyZWFkc0tleSkpIHsKKyAgICAgICAgbnVtVGhyZWFkcyA9IEludGVnZXIucGFyc2VJbnQoY21kLnN1YnN0cmluZyhudW1UaHJlYWRzS2V5Lmxlbmd0aCgpKSk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICAvLyBQcmludCBvdXQgdXNhZ2UgaWYgd2UgZ2V0IHRvIGhlcmUuCisgICAgICBwcmludFVzYWdlQW5kRXhpdCgpOworICAgIH0KKyAgICBvcmcubW9ydGJheS5qZXR0eS5TZXJ2ZXIgd2ViU2VydmVyID0gbmV3IG9yZy5tb3J0YmF5LmpldHR5LlNlcnZlcigpOworICAgIFNvY2tldExpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFNvY2tldExpc3RlbmVyKCk7CisgICAgbGlzdGVuZXIuc2V0UG9ydChwb3J0KTsKKyAgICBsaXN0ZW5lci5zZXRIb3N0KGJpbmRBZGRyZXNzKTsKKyAgICBsaXN0ZW5lci5zZXRNYXhUaHJlYWRzKG51bVRocmVhZHMpOworICAgIHdlYlNlcnZlci5hZGRMaXN0ZW5lcihsaXN0ZW5lcik7CisgICAgTkNTQVJlcXVlc3RMb2cgbmNzYSA9IG5ldyBOQ1NBUmVxdWVzdExvZygpOworICAgIG5jc2Euc2V0TG9nTGF0ZW5jeSh0cnVlKTsKKyAgICB3ZWJTZXJ2ZXIuc2V0UmVxdWVzdExvZyhuY3NhKTsKKyAgICBXZWJBcHBsaWNhdGlvbkNvbnRleHQgY29udGV4dCA9CisgICAgICB3ZWJTZXJ2ZXIuYWRkV2ViQXBwbGljYXRpb24oIi9hcGkiLCBJbmZvU2VydmVyLmdldFdlYkFwcERpcigicmVzdCIpKTsKKyAgICBjb250ZXh0LmFkZFNlcnZsZXQoInN0YWNrcyIsICIvc3RhY2tzIiwKKyAgICAgIFN0YXR1c0h0dHBTZXJ2ZXIuU3RhY2tTZXJ2bGV0LmNsYXNzLmdldE5hbWUoKSk7CisgICAgY29udGV4dC5hZGRTZXJ2bGV0KCJsb2dMZXZlbCIsICIvbG9nTGV2ZWwiLAorICAgICAgb3JnLmFwYWNoZS5oYWRvb3AubG9nLkxvZ0xldmVsLlNlcnZsZXQuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICB3ZWJTZXJ2ZXIuc3RhcnQoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYXJncworICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJTdGFydGluZyByZXN0U2VydmVyIik7CisgICAgZG9NYWluKGFyZ3MpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1JFU1RDb25zdGFudHMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvUkVTVENvbnN0YW50cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyYjBkMTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1JFU1RDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmZpbHRlci5Sb3dGaWx0ZXJTZXRGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLlN0b3BSb3dGaWx0ZXJGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLldoaWxlTWF0Y2hSb3dGaWx0ZXJGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLlBhZ2VSb3dGaWx0ZXJGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLkNvbHVtblZhbHVlRmlsdGVyRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmZpbHRlci5SZWdFeHBSb3dGaWx0ZXJGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLkluY2x1c2l2ZVN0b3BSb3dGaWx0ZXJGYWN0b3J5OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLkZpbHRlckZhY3Rvcnk7CisKK3B1YmxpYyBpbnRlcmZhY2UgUkVTVENvbnN0YW50cyB7CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgVFJVRSA9ICJ0cnVlIjsKKyAgZmluYWwgc3RhdGljIFN0cmluZyBGQUxTRSA9ICJmYWxzZSI7CisgIC8vIFVzZWQgZm9yIGdldHRpbmcgYWxsIGRhdGEgZnJvbSBhIGNvbHVtbiBzcGVjaWZpZWQgaW4gdGhhdCBvcmRlci4KKyAgZmluYWwgc3RhdGljIFN0cmluZyBDT0xVTU5TID0gImNvbHVtbnMiOworICBmaW5hbCBzdGF0aWMgU3RyaW5nIENPTFVNTiA9ICJjb2x1bW4iOworICAvLyBVc2VkIHdpdGggVGFibGVFeGlzdHMKKyAgZmluYWwgc3RhdGljIFN0cmluZyBFWElTVFMgPSAiZXhpc3RzIjsKKyAgLy8gTWFwcyB0byBUcmFuc2FjdGlvbiBJRAorICBmaW5hbCBzdGF0aWMgU3RyaW5nIFRSQU5TQUNUSU9OID0gInRyYW5zYWN0aW9uIjsKKyAgLy8gVHJhbnNhY3Rpb24gT3BlcmF0aW9uIEtleS4KKyAgZmluYWwgc3RhdGljIFN0cmluZyBUUkFOU0FDVElPTl9PUEVSQVRJT04gPSAidHJhbnNhY3Rpb25fb3AiOworICAvLyBUcmFuc2FjdGlvbiBPcGVyYXRpb24gVmFsdWVzCisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgVFJBTlNBQ1RJT05fT1BFUkFUSU9OX0NPTU1JVCA9ICJjb21taXQiOworICBmaW5hbCBzdGF0aWMgU3RyaW5nIFRSQU5TQUNUSU9OX09QRVJBVElPTl9DUkVBVEUgPSAiY3JlYXRlIjsKKyAgZmluYWwgc3RhdGljIFN0cmluZyBUUkFOU0FDVElPTl9PUEVSQVRJT05fQUJPUlQgPSAiYWJvcnQiOworICAvLyBGaWx0ZXIgS2V5CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgRklMVEVSID0gImZpbHRlciI7CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgRklMVEVSX1RZUEUgPSAidHlwZSI7CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgRklMVEVSX1ZBTFVFID0gInZhbHVlIjsKKyAgZmluYWwgc3RhdGljIFN0cmluZyBGSUxURVJfUkFOSyA9ICJyYW5rIjsKKyAgLy8gU2Nhbm5lciBLZXkKKyAgZmluYWwgc3RhdGljIFN0cmluZyBTQ0FOTkVSID0gInNjYW5uZXIiOworICAvLyBUaGUgYW1vdW50IG9mIHJvd3MgdG8gcmV0dXJuIGF0IG9uZSB0aW1lLgorICBmaW5hbCBzdGF0aWMgU3RyaW5nIFNDQU5ORVJfUkVTVUxUX1NJWkUgPSAicmVzdWx0X3NpemUiOworICBmaW5hbCBzdGF0aWMgU3RyaW5nIFNDQU5ORVJfU1RBUlRfUk9XID0gInN0YXJ0X3JvdyI7CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgU0NBTk5FUl9TVE9QX1JPVyA9ICJzdG9wX3JvdyI7CisgIGZpbmFsIHN0YXRpYyBTdHJpbmcgU0NBTk5FUl9GSUxURVIgPSAiZmlsdGVyIjsKKyAgZmluYWwgc3RhdGljIFN0cmluZyBTQ0FOTkVSX1RJTUVTVEFNUCA9ICJ0aW1lc3RhbXAiOworICBmaW5hbCBzdGF0aWMgU3RyaW5nIE5VTV9WRVJTSU9OUyA9ICJudW1fdmVyc2lvbnMiOworICBmaW5hbCBzdGF0aWMgU3RyaW5nIFNDQU5ORVJfQ09MVU1OID0gImNvbHVtbiI7CisgIC8vIHN0YXRpYyBpdGVtcyB1c2VkIG9uIHRoZSBwYXRoCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRElTQUJMRSA9ICJkaXNhYmxlIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBFTkFCTEUgPSAiZW5hYmxlIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBSRUdJT05TID0gInJlZ2lvbnMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIFJPVyA9ICJyb3ciOworICBzdGF0aWMgZmluYWwgU3RyaW5nIFRJTUVfU1RBTVBTID0gInRpbWVzdGFtcHMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIE1FVEFEQVRBID0gIm1ldGFkYXRhIjsKKworICBzdGF0aWMgZmluYWwgU3RyaW5nIE5BTUUgPSAibmFtZSI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMVUUgPSAidmFsdWUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIFJPV1MgPSAicm93cyI7CisKKyAgc3RhdGljIGZpbmFsIEZhY3RvcnlNYXAgZmlsdGVyRmFjdG9yaWVzID0gRmFjdG9yeU1hcC5nZXRGYWN0b3J5TWFwKCk7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTElNSVQgPSAibGltaXQiOworCisgIHN0YXRpYyBjbGFzcyBGYWN0b3J5TWFwIHsKKworICAgIHN0YXRpYyBib29sZWFuIGNyZWF0ZWQgPSBmYWxzZTsKKyAgICBwcm90ZWN0ZWQgSGFzaE1hcDxTdHJpbmcsIEZpbHRlckZhY3Rvcnk+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgRmlsdGVyRmFjdG9yeT4oKTsKKworICAgIHByb3RlY3RlZCBGYWN0b3J5TWFwKCkgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgRmFjdG9yeU1hcCBnZXRGYWN0b3J5TWFwKCkgeworICAgICAgaWYgKCFjcmVhdGVkKSB7CisgICAgICAgIGNyZWF0ZWQgPSB0cnVlOworICAgICAgICBGYWN0b3J5TWFwIGYgPSBuZXcgRmFjdG9yeU1hcCgpOworICAgICAgICBmLmluaXRpYWxpemUoKTsKKyAgICAgICAgcmV0dXJuIGY7CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgRmlsdGVyRmFjdG9yeSBnZXQoU3RyaW5nIGMpIHsKKyAgICAgIHJldHVybiBtYXAuZ2V0KGMpOworICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGluaXRpYWxpemUoKSB7CisgICAgICBtYXAucHV0KCJDb2x1bW5WYWx1ZUZpbHRlciIsIG5ldyBDb2x1bW5WYWx1ZUZpbHRlckZhY3RvcnkoKSk7CisgICAgICBtYXAucHV0KCJJbmNsdXNpdmVTdG9wUm93RmlsdGVyIiwgbmV3IEluY2x1c2l2ZVN0b3BSb3dGaWx0ZXJGYWN0b3J5KCkpOworICAgICAgbWFwLnB1dCgiUGFnZVJvd0ZpbHRlciIsIG5ldyBQYWdlUm93RmlsdGVyRmFjdG9yeSgpKTsKKyAgICAgIG1hcC5wdXQoIlJlZ0V4cFJvd0ZpbHRlciIsIG5ldyBSZWdFeHBSb3dGaWx0ZXJGYWN0b3J5KCkpOworICAgICAgbWFwLnB1dCgiUm93RmlsdGVyU2V0IiwgbmV3IFJvd0ZpbHRlclNldEZhY3RvcnkoKSk7CisgICAgICBtYXAucHV0KCJTdG9wUm93RmlsdGVyIiwgbmV3IFN0b3BSb3dGaWx0ZXJGYWN0b3J5KCkpOworICAgICAgbWFwLnB1dCgiV2hpbGVNYXRjaFJvd0ZpbHRlciIsIG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyRmFjdG9yeSgpKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvUm93Q29udHJvbGxlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9Sb3dDb250cm9sbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzVkM2M5YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvUm93Q29udHJvbGxlci5qYXZhCkBAIC0wLDAgKzEsMTM1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdDsKKworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuUm93VXBkYXRlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgUm93Q29udHJvbGxlciBleHRlbmRzIEFic3RyYWN0Q29udHJvbGxlciB7CisKKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByaXZhdGUgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFJvd0NvbnRyb2xsZXIuY2xhc3MpOworCisgIHByb3RlY3RlZCBSb3dNb2RlbCBnZXRNb2RlbCgpIHsKKyAgICByZXR1cm4gKFJvd01vZGVsKSBtb2RlbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgQWJzdHJhY3RNb2RlbCBnZW5lcmF0ZU1vZGVsKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLAorICAgICAgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHJldHVybiBuZXcgUm93TW9kZWwoY29uZiwgYWRtaW4pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGdldChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBSb3dNb2RlbCBpbm5lck1vZGVsID0gZ2V0TW9kZWwoKTsKKyAgICBzLnNldE5vUXVlcnlSZXN1bHRzKCk7CisKKyAgICBieXRlW10gdGFibGVOYW1lOworICAgIGJ5dGVbXSByb3dOYW1lOworCisgICAgdGFibGVOYW1lID0gcGF0aFNlZ21lbnRzWzBdOworICAgIHJvd05hbWUgPSBwYXRoU2VnbWVudHNbMl07CisgICAgUm93UmVzdWx0IHJvdyA9IG51bGw7CisgICAgCisgICAgaWYgKHF1ZXJ5TWFwLnNpemUoKSA9PSAwICYmIHBhdGhTZWdtZW50cy5sZW5ndGggPD0gMykgeworICAgICAgcm93ID0gaW5uZXJNb2RlbC5nZXQodGFibGVOYW1lLCByb3dOYW1lKTsKKyAgICB9IGVsc2UgaWYgKHBhdGhTZWdtZW50cy5sZW5ndGggPT0gNAorICAgICAgICAmJiBCeXRlcy50b1N0cmluZyhwYXRoU2VnbWVudHNbM10pLnRvTG93ZXJDYXNlKCkuZXF1YWxzKAorICAgICAgICAgICAgUkVTVENvbnN0YW50cy5USU1FX1NUQU1QUykpIHsKKyAgICAgIGlubmVyTW9kZWwuZ2V0VGltZXN0YW1wcyh0YWJsZU5hbWUsIHJvd05hbWUpOworICAgIH0gZWxzZSB7CisgICAgICByb3cgPSBpbm5lck1vZGVsLmdldCh0YWJsZU5hbWUsIHJvd05hbWUsIHRoaXMuZ2V0Q29sdW1uc0Zyb21RdWVyeU1hcChxdWVyeU1hcCkpOworICAgIH0KKyAgICBpZihyb3cgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigicm93IG5vdCBmb3VuZCIpOworICAgIH0KKyAgICBzLnNldE9LKHJvdyk7CisgICAgcy5yZXNwb25kKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcG9zdChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwLCBieXRlW10gaW5wdXQsIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgUm93TW9kZWwgaW5uZXJNb2RlbCA9IGdldE1vZGVsKCk7CisKKyAgICBCYXRjaFVwZGF0ZSBiOworICAgIFJvd1VwZGF0ZURlc2NyaXB0b3IgcnVkID0gcGFyc2VyCisgICAgICAgIC5nZXRSb3dVcGRhdGVEZXNjcmlwdG9yKGlucHV0LCBwYXRoU2VnbWVudHMpOworCisgICAgaWYgKGlucHV0Lmxlbmd0aCA9PSAwKSB7CisgICAgICBzLnNldFVuc3VwcG9ydGVkTWVkaWFUeXBlKCJubyBkYXRhIHNlbmQgd2l0aCBwb3N0IHJlcXVlc3QiKTsKKyAgICAgIHMucmVzcG9uZCgpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGIgPSBuZXcgQmF0Y2hVcGRhdGUocnVkLmdldFJvd05hbWUoKSk7CisKKyAgICBmb3IgKGJ5dGVbXSBrZXkgOiBydWQuZ2V0Q29sVmFscygpLmtleVNldCgpKSB7CisgICAgICBiLnB1dChrZXksIHJ1ZC5nZXRDb2xWYWxzKCkuZ2V0KGtleSkpOworICAgIH0KKworICAgIHRyeSB7CisgICAgICBpbm5lck1vZGVsLnBvc3QocnVkLmdldFRhYmxlTmFtZSgpLmdldEJ5dGVzKCksIGIpOworICAgICAgcy5zZXRPSygpOworICAgIH0gY2F0Y2ggKEhCYXNlUmVzdEV4Y2VwdGlvbiBlKSB7CisgICAgICBzLnNldFVuc3VwcG9ydGVkTWVkaWFUeXBlKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgICAgcy5yZXNwb25kKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcHV0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAsIGJ5dGVbXSBpbnB1dCwgSUhCYXNlUmVzdFBhcnNlciBwYXJzZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzLnNldE1ldGhvZE5vdEltcGxlbWVudGVkKCk7CisgICAgcy5yZXNwb25kKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZGVsZXRlKFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFJvd01vZGVsIGlubmVyTW9kZWwgPSBnZXRNb2RlbCgpOworICAgIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgYnl0ZVtdIHJvd05hbWU7CisKKyAgICB0YWJsZU5hbWUgPSBwYXRoU2VnbWVudHNbMF07CisgICAgcm93TmFtZSA9IHBhdGhTZWdtZW50c1syXTsKKyAgICBpZihxdWVyeU1hcC5zaXplKCkgPT0gMCkgeworICAgICAgaW5uZXJNb2RlbC5kZWxldGUodGFibGVOYW1lLCByb3dOYW1lKTsKKyAgICB9IGVsc2UgeworICAgICAgaW5uZXJNb2RlbC5kZWxldGUodGFibGVOYW1lLCByb3dOYW1lLCB0aGlzLmdldENvbHVtbnNGcm9tUXVlcnlNYXAocXVlcnlNYXApKTsKKyAgICB9CisgICAgcy5zZXRPSygpOworICAgIHMucmVzcG9uZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1Jvd01vZGVsLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1Jvd01vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWI4Y2U4YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvUm93TW9kZWwuamF2YQpAQCAtMCwwICsxLDE0MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuVGltZXN0YW1wc0Rlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgUm93TW9kZWwgZXh0ZW5kcyBBYnN0cmFjdE1vZGVsIHsKKworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coUm93TW9kZWwuY2xhc3MpOworCisgIHB1YmxpYyBSb3dNb2RlbChIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHN1cGVyLmluaXRpYWxpemUoY29uZiwgYWRtaW4pOworICB9CisKKyAgcHVibGljIFJvd1Jlc3VsdCBnZXQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgcmV0dXJuIHRhYmxlLmdldFJvdyhyb3dOYW1lKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBSb3dSZXN1bHQgZ2V0KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3dOYW1lLCBieXRlW11bXSBjb2x1bW5zKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiB0YWJsZS5nZXRSb3cocm93TmFtZSwgY29sdW1ucyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgUm93UmVzdWx0IGdldChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93TmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgcmV0dXJuIHRhYmxlLmdldFJvdyhyb3dOYW1lLCBjb2x1bW5zLCB0aW1lc3RhbXApOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIFJvd1Jlc3VsdCBnZXQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUsIGxvbmcgdGltZXN0YW1wKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiB0YWJsZS5nZXRSb3cocm93TmFtZSwgdGltZXN0YW1wKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBUaW1lc3RhbXBzRGVzY3JpcHRvciBnZXRUaW1lc3RhbXBzKAorICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikgYnl0ZVtdIHJvd05hbWUpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIHRyeSB7CisgICAgLy8gVGltZXN0YW1wc0Rlc2NyaXB0b3IgdHNkID0gbmV3IFRpbWVzdGFtcHNEZXNjcmlwdG9yKCk7CisgICAgLy8gSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgIC8vIFJvd1Jlc3VsdCByb3cgPSB0YWJsZS5nZXRSb3cocm93TmFtZSk7CisKKyAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKCJvcGVyYXRpb24gY3VycmVudGx5IHVuc3VwcG9ydGVkIik7CisKKyAgICAvLyB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgLy8gdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigiRXJyb3IgZmluZGluZyB0aW1lc3RhbXBzIGZvciByb3c6ICIKKyAgICAvLyArIEJ5dGVzLnRvU3RyaW5nKHJvd05hbWUpLCBlKTsKKyAgICAvLyB9CisKKyAgfQorCisgIHB1YmxpYyB2b2lkIHBvc3QoYnl0ZVtdIHRhYmxlTmFtZSwgQmF0Y2hVcGRhdGUgYikgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHRhYmxlLmNvbW1pdChiKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHBvc3QoYnl0ZVtdIHRhYmxlTmFtZSwgTGlzdDxCYXRjaFVwZGF0ZT4gYikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBkZWxldGUoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgdGFibGUuZGVsZXRlQWxsKHJvd05hbWUpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgZGVsZXRlKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3dOYW1lLCBieXRlW11bXSBjb2x1bW5zKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgZm9yIChieXRlW10gY29sdW1uIDogY29sdW1ucykgeworICAgICAgICB0YWJsZS5kZWxldGVBbGwocm93TmFtZSwgY29sdW1uKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9TY2FubmVyQ29udHJvbGxlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9TY2FubmVyQ29udHJvbGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4ZjE3ZmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1NjYW5uZXJDb250cm9sbGVyLmphdmEKQEAgLTAsMCArMSwzNTggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlclNldDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuU3RvcFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuV2hpbGVNYXRjaFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlNjYW5uZXJEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuU2Nhbm5lcklkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyLkZpbHRlckZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgU2Nhbm5lckNvbnRyb2xsZXIgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2xsZXIgeworCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5BYnN0cmFjdENvbnRyb2xsZXIjZGVsZXRlKG9yZy5hcGFjaGUuaGFkb29wCisgICAqIC5oYmFzZS5yZXN0LlN0YXR1cywgYnl0ZVtdW10sIGphdmEudXRpbC5NYXApCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZGVsZXRlKFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFNjYW5uZXJNb2RlbCBpbm5lck1vZGVsID0gdGhpcy5nZXRNb2RlbCgpOworICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID09IDMKKyAgICAgICAgJiYgQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzFdKS50b0xvd2VyQ2FzZSgpLmVxdWFscygKKyAgICAgICAgICAgIFJFU1RDb25zdGFudHMuU0NBTk5FUikpIHsKKyAgICAgIC8vIGdldCB0aGUgc2Nhbm5lcklkCisgICAgICBJbnRlZ2VyIHNjYW5uZXJJZCA9IG51bGw7CisgICAgICBTdHJpbmcgc2Nhbm5lcklkU3RyaW5nID0gbmV3IFN0cmluZyhwYXRoU2VnbWVudHNbMl0pOworICAgICAgaWYgKCFQYXR0ZXJuLm1hdGNoZXMoIl5cXGQrJCIsIHNjYW5uZXJJZFN0cmluZykpIHsKKyAgICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJ0aGUgc2Nhbm5lcmlkIGluIHRoZSBwYXRoIGFuZCBtdXN0IGJlIGFuIGludGVnZXIiKTsKKyAgICAgIH0KKyAgICAgIHNjYW5uZXJJZCA9IEludGVnZXIucGFyc2VJbnQoc2Nhbm5lcklkU3RyaW5nKTsKKworICAgICAgdHJ5IHsKKyAgICAgICAgaW5uZXJNb2RlbC5zY2FubmVyQ2xvc2Uoc2Nhbm5lcklkKTsKKyAgICAgICAgcy5zZXRPSygpOworICAgICAgfSBjYXRjaCAoSEJhc2VSZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcy5zZXROb3RGb3VuZCgpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBzLnNldEJhZFJlcXVlc3QoImludmFsaWQgcXVlcnkiKTsKKyAgICB9CisgICAgcy5yZXNwb25kKCk7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuQWJzdHJhY3RDb250cm9sbGVyI2dlbmVyYXRlTW9kZWwob3JnLmFwYWNoZQorICAgKiAuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbiwKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW4pCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIEFic3RyYWN0TW9kZWwgZ2VuZXJhdGVNb2RlbChIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgSEJhc2VBZG1pbiBhKSB7CisgICAgcmV0dXJuIG5ldyBTY2FubmVyTW9kZWwoY29uZiwgYSk7CisgIH0KKworICBwcm90ZWN0ZWQgU2Nhbm5lck1vZGVsIGdldE1vZGVsKCkgeworICAgIHJldHVybiAoU2Nhbm5lck1vZGVsKSBtb2RlbDsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5BYnN0cmFjdENvbnRyb2xsZXIjZ2V0KG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlCisgICAqIC5yZXN0LlN0YXR1cywgYnl0ZVtdW10sIGphdmEudXRpbC5NYXApCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZ2V0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworCisgICAgcy5zZXRCYWRSZXF1ZXN0KCJpbnZhbGlkIHF1ZXJ5Iik7CisgICAgcy5yZXNwb25kKCk7CisKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5BYnN0cmFjdENvbnRyb2xsZXIjcG9zdChvcmcuYXBhY2hlLmhhZG9vcC4KKyAgICogaGJhc2UucmVzdC5TdGF0dXMsIGJ5dGVbXVtdLCBqYXZhLnV0aWwuTWFwLCBieXRlW10sCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QucGFyc2VyLklIQmFzZVJlc3RQYXJzZXIpCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcG9zdChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwLCBieXRlW10gaW5wdXQsIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgU2Nhbm5lck1vZGVsIGlubmVyTW9kZWwgPSB0aGlzLmdldE1vZGVsKCk7CisgICAgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICB0YWJsZU5hbWUgPSBwYXRoU2VnbWVudHNbMF07CisKKyAgICAvLyBPdGhlcndpc2Ugd2UgaW50ZXJwcmV0IHRoaXMgcmVxdWVzdCBhcyBhIHNjYW5uZXIgcmVxdWVzdC4KKyAgICBpZiAocGF0aFNlZ21lbnRzLmxlbmd0aCA9PSAyCisgICAgICAgICYmIEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlNDQU5ORVIpKSB7IC8vIG5ldyBzY2FubmVyIHJlcXVlc3QKKyAgICAgIFNjYW5uZXJEZXNjcmlwdG9yIHNkID0gdGhpcy5nZXRTY2FubmVyRGVzY3JpcHRvcihxdWVyeU1hcCk7CisgICAgICBzLnNldFNjYW5uZXJDcmVhdGVkKGNyZWF0ZVNjYW5uZXIoaW5uZXJNb2RlbCwgdGFibGVOYW1lLCBzZCkpOworICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnRzLmxlbmd0aCA9PSAzCisgICAgICAgICYmIEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgICAgICBSRVNUQ29uc3RhbnRzLlNDQU5ORVIpKSB7IC8vIG9wZW4gc2Nhbm5lciByZXF1ZXN0CisgICAgICAvLyBmaXJzdCBzZWUgaWYgdGhlIGxpbWl0IHZhcmlhYmxlIGlzIHByZXNlbnQKKyAgICAgIExvbmcgbnVtUm93cyA9IDFMOworICAgICAgU3RyaW5nW10gbnVtUm93c1N0cmluZyA9IHF1ZXJ5TWFwLmdldChSRVNUQ29uc3RhbnRzLkxJTUlUKTsKKyAgICAgIGlmIChudW1Sb3dzU3RyaW5nICE9IG51bGwgJiYgUGF0dGVybi5tYXRjaGVzKCJeXFxkKyQiLCBudW1Sb3dzU3RyaW5nWzBdKSkgeworICAgICAgICBudW1Sb3dzID0gTG9uZy5wYXJzZUxvbmcobnVtUm93c1N0cmluZ1swXSk7CisgICAgICB9CisgICAgICAvLyBnZXQgdGhlIHNjYW5uZXJJZAorICAgICAgSW50ZWdlciBzY2FubmVySWQgPSBudWxsOworICAgICAgU3RyaW5nIHNjYW5uZXJJZFN0cmluZyA9IG5ldyBTdHJpbmcocGF0aFNlZ21lbnRzWzJdKTsKKyAgICAgIGlmICghUGF0dGVybi5tYXRjaGVzKCJeXFxkKyQiLCBzY2FubmVySWRTdHJpbmcpKSB7CisgICAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oCisgICAgICAgICAgICAidGhlIHNjYW5uZXJpZCBpbiB0aGUgcGF0aCBhbmQgbXVzdCBiZSBhbiBpbnRlZ2VyIik7CisgICAgICB9CisgICAgICBzY2FubmVySWQgPSBJbnRlZ2VyLnBhcnNlSW50KHNjYW5uZXJJZFN0cmluZyk7CisKKyAgICAgIHRyeSB7CisgICAgICAgIHMuc2V0T0soaW5uZXJNb2RlbC5zY2FubmVyR2V0KHNjYW5uZXJJZCwgbnVtUm93cykpOworICAgICAgfSBjYXRjaCAoSEJhc2VSZXN0RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcy5zZXROb3RGb3VuZCgpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBzLnNldEJhZFJlcXVlc3QoIlVua25vd24gUXVlcnkuIik7CisgICAgfQorICAgIHMucmVzcG9uZCgpOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LkFic3RyYWN0Q29udHJvbGxlciNwdXQob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UKKyAgICogLnJlc3QuU3RhdHVzLCBieXRlW11bXSwgamF2YS51dGlsLk1hcCwgYnl0ZVtdLAorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlci5JSEJhc2VSZXN0UGFyc2VyKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHB1dChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwLCBieXRlW10gaW5wdXQsIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBzLnNldEJhZFJlcXVlc3QoImludmFsaWQgcXVlcnkiKTsKKyAgICBzLnJlc3BvbmQoKTsKKworICB9CisKKyAgcHJpdmF0ZSBTY2FubmVyRGVzY3JpcHRvciBnZXRTY2FubmVyRGVzY3JpcHRvcihNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHsKKyAgICBsb25nIHRpbWVzdGFtcCA9IDBMOworICAgIGJ5dGVbXSBzdGFydFJvdyA9IG51bGw7CisgICAgYnl0ZVtdIHN0b3BSb3cgPSBudWxsOworICAgIFN0cmluZyBmaWx0ZXJzID0gbnVsbDsKKworICAgIFN0cmluZ1tdIHRpbWVTdGFtcFN0cmluZyA9IHF1ZXJ5TWFwLmdldChSRVNUQ29uc3RhbnRzLlNDQU5ORVJfVElNRVNUQU1QKTsKKyAgICBpZiAodGltZVN0YW1wU3RyaW5nICE9IG51bGwgJiYgdGltZVN0YW1wU3RyaW5nLmxlbmd0aCA9PSAxKSB7CisgICAgICB0aW1lc3RhbXAgPSBMb25nLnBhcnNlTG9uZyh0aW1lU3RhbXBTdHJpbmdbMF0pOworICAgIH0KKworICAgIFN0cmluZ1tdIHN0YXJ0Um93U3RyaW5nID0gcXVlcnlNYXAuZ2V0KFJFU1RDb25zdGFudHMuU0NBTk5FUl9TVEFSVF9ST1cpOworICAgIGlmIChzdGFydFJvd1N0cmluZyAhPSBudWxsICYmIHN0YXJ0Um93U3RyaW5nLmxlbmd0aCA9PSAxKSB7CisgICAgICBzdGFydFJvdyA9IEJ5dGVzLnRvQnl0ZXMoc3RhcnRSb3dTdHJpbmdbMF0pOworICAgIH0KKworICAgIFN0cmluZ1tdIHN0b3BSb3dTdHJpbmcgPSBxdWVyeU1hcC5nZXQoUkVTVENvbnN0YW50cy5TQ0FOTkVSX1NUT1BfUk9XKTsKKyAgICBpZiAoc3RvcFJvd1N0cmluZyAhPSBudWxsICYmIHN0b3BSb3dTdHJpbmcubGVuZ3RoID09IDEpIHsKKyAgICAgIHN0b3BSb3cgPSBCeXRlcy50b0J5dGVzKHN0b3BSb3dTdHJpbmdbMF0pOworICAgIH0KKworICAgIFN0cmluZ1tdIGZpbHRlcnNTdHJpbmdzID0gcXVlcnlNYXAuZ2V0KFJFU1RDb25zdGFudHMuU0NBTk5FUl9GSUxURVIpOworICAgIGlmIChmaWx0ZXJzU3RyaW5ncyAhPSBudWxsICYmIGZpbHRlcnNTdHJpbmdzLmxlbmd0aCA+IDApIHsKKyAgICAgIGZpbHRlcnMgPSAiIjsKKyAgICAgIGZvciAoQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICBTdHJpbmcgZmlsdGVyIDogZmlsdGVyc1N0cmluZ3MpIHsKKyAgICAgICAgLy8gVE9ETyBmaWx0ZXJzIGFyZSBub3QgaG9va2VkIHVwIHlldC4uLiBBbmQgdGhlIFN0cmluZyBzaG91bGQgcHJvYmFibHkKKyAgICAgICAgLy8gYmUgY2hhbmdlZCB0byBhIHNldAorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbmV3IFNjYW5uZXJEZXNjcmlwdG9yKHRoaXMuZ2V0Q29sdW1uc0Zyb21RdWVyeU1hcChxdWVyeU1hcCksCisgICAgICAgIHRpbWVzdGFtcCwgc3RhcnRSb3csIHN0b3BSb3csIGZpbHRlcnMpOworICB9CisKKyAgcHJvdGVjdGVkIFNjYW5uZXJJZGVudGlmaWVyIGNyZWF0ZVNjYW5uZXIoU2Nhbm5lck1vZGVsIGlubmVyTW9kZWwsCisgICAgICBieXRlW10gdGFibGVOYW1lLCBTY2FubmVyRGVzY3JpcHRvciBzY2FubmVyRGVzY3JpcHRvcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworCisgICAgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlclNldCA9IG51bGw7CisKKyAgICAvLyBNaWdodCB3YW50IHRvIGNoYW5nZSB0aGlzLiBJIGFtIGRvaW5nIHRoaXMgc28gdGhhdCBJIGNhbiB1c2UKKyAgICAvLyBhIHN3aXRjaCBzdGF0ZW1lbnQgdGhhdCBpcyBtb3JlIGVmZmljaWVudC4KKyAgICBpbnQgc3dpdGNoSW50ID0gMDsKKyAgICBpZiAoc2Nhbm5lckRlc2NyaXB0b3IuZ2V0Q29sdW1ucygpICE9IG51bGwKKyAgICAgICAgJiYgc2Nhbm5lckRlc2NyaXB0b3IuZ2V0Q29sdW1ucygpLmxlbmd0aCA+IDApIHsKKyAgICAgIHN3aXRjaEludCArPSAxOworICAgIH0KKyAgICBzd2l0Y2hJbnQgKz0gKHNjYW5uZXJEZXNjcmlwdG9yLmdldFRpbWVzdGFtcCgpICE9IDBMKSA/ICgxIDw8IDEpIDogMDsKKyAgICBzd2l0Y2hJbnQgKz0gKHNjYW5uZXJEZXNjcmlwdG9yLmdldFN0YXJ0Um93KCkubGVuZ3RoID4gMCkgPyAoMSA8PCAyKSA6IDA7CisgICAgc3dpdGNoSW50ICs9IChzY2FubmVyRGVzY3JpcHRvci5nZXRTdG9wUm93KCkubGVuZ3RoID4gMCkgPyAoMSA8PCAzKSA6IDA7CisgICAgaWYgKHNjYW5uZXJEZXNjcmlwdG9yLmdldEZpbHRlcnMoKSAhPSBudWxsCisgICAgICAgICYmICFzY2FubmVyRGVzY3JpcHRvci5nZXRGaWx0ZXJzKCkuZXF1YWxzKCIiKSkgeworICAgICAgc3dpdGNoSW50ICs9IChzY2FubmVyRGVzY3JpcHRvci5nZXRGaWx0ZXJzKCkgIT0gbnVsbCkgPyAoMSA8PCA0KSA6IDA7CisgICAgICBmaWx0ZXJTZXQgPSB1bmlvbkZpbHRlcnMoc2Nhbm5lckRlc2NyaXB0b3IuZ2V0RmlsdGVycygpKTsKKyAgICB9CisKKyAgICByZXR1cm4gc2Nhbm5lclN3aXRjaChzd2l0Y2hJbnQsIGlubmVyTW9kZWwsIHRhYmxlTmFtZSwgc2Nhbm5lckRlc2NyaXB0b3IKKyAgICAgICAgLmdldENvbHVtbnMoKSwgc2Nhbm5lckRlc2NyaXB0b3IuZ2V0VGltZXN0YW1wKCksIHNjYW5uZXJEZXNjcmlwdG9yCisgICAgICAgIC5nZXRTdGFydFJvdygpLCBzY2FubmVyRGVzY3JpcHRvci5nZXRTdG9wUm93KCksIGZpbHRlclNldCk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lclN3aXRjaChpbnQgc3dpdGNoSW50LAorICAgICAgU2Nhbm5lck1vZGVsIGlubmVyTW9kZWwsIGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXVtdIGNvbHVtbnMsCisgICAgICBsb25nIHRpbWVzdGFtcCwgYnl0ZVtdIHN0YXJ0Um93LCBieXRlW10gc3RvcFJvdywKKyAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXJTZXQpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHN3aXRjaCAoc3dpdGNoSW50KSB7CisgICAgY2FzZSAwOgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lKTsKKyAgICBjYXNlIDE6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMpOworICAgIGNhc2UgMjoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgdGltZXN0YW1wKTsKKyAgICBjYXNlIDM6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIHRpbWVzdGFtcCk7CisgICAgY2FzZSA0OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBzdGFydFJvdyk7CisgICAgY2FzZSA1OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBzdGFydFJvdyk7CisgICAgY2FzZSA2OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBzdGFydFJvdywgdGltZXN0YW1wKTsKKyAgICBjYXNlIDc6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIHN0YXJ0Um93LCB0aW1lc3RhbXApOworICAgIGNhc2UgODoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgZ2V0U3RvcFJvdyhzdG9wUm93KSk7CisgICAgY2FzZSA5OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBnZXRTdG9wUm93KHN0b3BSb3cpKTsKKyAgICBjYXNlIDEwOgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCB0aW1lc3RhbXAsIGdldFN0b3BSb3coc3RvcFJvdykpOworICAgIGNhc2UgMTE6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIHRpbWVzdGFtcCwKKyAgICAgICAgICBnZXRTdG9wUm93KHN0b3BSb3cpKTsKKyAgICBjYXNlIDEyOgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBzdGFydFJvdywgZ2V0U3RvcFJvdyhzdG9wUm93KSk7CisgICAgY2FzZSAxMzoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgY29sdW1ucywgc3RhcnRSb3csCisgICAgICAgICAgZ2V0U3RvcFJvdyhzdG9wUm93KSk7CisgICAgY2FzZSAxNDoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgc3RhcnRSb3csIHRpbWVzdGFtcCwKKyAgICAgICAgICBnZXRTdG9wUm93KHN0b3BSb3cpKTsKKyAgICBjYXNlIDE1OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBzdGFydFJvdywgdGltZXN0YW1wLAorICAgICAgICAgIGdldFN0b3BSb3coc3RvcFJvdykpOworICAgIGNhc2UgMTY6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGZpbHRlclNldCk7CisgICAgY2FzZSAxNzoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgY29sdW1ucywgZmlsdGVyU2V0KTsKKyAgICBjYXNlIDE4OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCB0aW1lc3RhbXAsIGZpbHRlclNldCk7CisgICAgY2FzZSAxOToKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgY29sdW1ucywgdGltZXN0YW1wLCBmaWx0ZXJTZXQpOworICAgIGNhc2UgMjA6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIHN0YXJ0Um93LCBmaWx0ZXJTZXQpOworICAgIGNhc2UgMjE6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIHN0YXJ0Um93LCBmaWx0ZXJTZXQpOworICAgIGNhc2UgMjI6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIHN0YXJ0Um93LCB0aW1lc3RhbXAsIGZpbHRlclNldCk7CisgICAgY2FzZSAyMzoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgY29sdW1ucywgc3RhcnRSb3csIHRpbWVzdGFtcCwKKyAgICAgICAgICBmaWx0ZXJTZXQpOworICAgIGNhc2UgMjQ6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldFN0b3BSb3dVbmlvbkZpbHRlcihzdG9wUm93LAorICAgICAgICAgIGZpbHRlclNldCkpOworICAgIGNhc2UgMjU6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIGdldFN0b3BSb3dVbmlvbkZpbHRlcigKKyAgICAgICAgICBzdG9wUm93LCBmaWx0ZXJTZXQpKTsKKyAgICBjYXNlIDI2OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCB0aW1lc3RhbXAsCisgICAgICAgICAgZ2V0U3RvcFJvd1VuaW9uRmlsdGVyKHN0b3BSb3csIGZpbHRlclNldCkpOworICAgIGNhc2UgMjc6CisgICAgICByZXR1cm4gaW5uZXJNb2RlbC5zY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIHRpbWVzdGFtcCwKKyAgICAgICAgICBnZXRTdG9wUm93VW5pb25GaWx0ZXIoc3RvcFJvdywgZmlsdGVyU2V0KSk7CisgICAgY2FzZSAyODoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgc3RhcnRSb3csIGdldFN0b3BSb3dVbmlvbkZpbHRlcigKKyAgICAgICAgICBzdG9wUm93LCBmaWx0ZXJTZXQpKTsKKyAgICBjYXNlIDI5OgorICAgICAgcmV0dXJuIGlubmVyTW9kZWwuc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgICBnZXRTdG9wUm93VW5pb25GaWx0ZXIoc3RvcFJvdywgZmlsdGVyU2V0KSk7CisgICAgY2FzZSAzMDoKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgc3RhcnRSb3csIHRpbWVzdGFtcCwKKyAgICAgICAgICBnZXRTdG9wUm93VW5pb25GaWx0ZXIoc3RvcFJvdywgZmlsdGVyU2V0KSk7CisgICAgY2FzZSAzMToKKyAgICAgIHJldHVybiBpbm5lck1vZGVsLnNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgY29sdW1ucywgc3RhcnRSb3csIHRpbWVzdGFtcCwKKyAgICAgICAgICBnZXRTdG9wUm93VW5pb25GaWx0ZXIoc3RvcFJvdywgZmlsdGVyU2V0KSk7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgfQorCisgIHByb3RlY3RlZCBSb3dGaWx0ZXJJbnRlcmZhY2UgZ2V0U3RvcFJvdyhieXRlW10gc3RvcFJvdykgeworICAgIHJldHVybiBuZXcgV2hpbGVNYXRjaFJvd0ZpbHRlcihuZXcgU3RvcFJvd0ZpbHRlcihzdG9wUm93KSk7CisgIH0KKworICBwcm90ZWN0ZWQgUm93RmlsdGVySW50ZXJmYWNlIGdldFN0b3BSb3dVbmlvbkZpbHRlcihieXRlW10gc3RvcFJvdywKKyAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHsKKyAgICBTZXQ8Um93RmlsdGVySW50ZXJmYWNlPiBmaWx0ZXJTZXQgPSBuZXcgSGFzaFNldDxSb3dGaWx0ZXJJbnRlcmZhY2U+KCk7CisgICAgZmlsdGVyU2V0LmFkZChnZXRTdG9wUm93KHN0b3BSb3cpKTsKKyAgICBmaWx0ZXJTZXQuYWRkKGZpbHRlcik7CisgICAgcmV0dXJuIG5ldyBSb3dGaWx0ZXJTZXQoZmlsdGVyU2V0KTsKKyAgfQorCisgIC8qKgorICAgKiBHaXZlbiBhIGxpc3Qgb2YgZmlsdGVycyBpbiBKU09OIHN0cmluZyBmb3JtLCByZXR1cm5zIGEgUm93U2V0RmlsdGVyIHRoYXQKKyAgICogcmV0dXJucyB0cnVlIGlmIGFsbCBpbnB1dCBmaWx0ZXJzIHJldHVybiB0cnVlIG9uIGEgUm93IChha2EgYW4gQU5ECisgICAqIHN0YXRlbWVudCkuCisgICAqIAorICAgKiBAcGFyYW0gZmlsdGVycworICAgKiAgICAgICAgICBhcnJheSBvZiBpbnB1dCBmaWx0ZXJzIGluIGEgSlNPTiBTdHJpbmcKKyAgICogQHJldHVybiBSb3dTZXRGaWx0ZXIgd2l0aCBhbGwgaW5wdXQgZmlsdGVycyBpbiBhbiBBTkQgU3RhdGVtZW50CisgICAqIEB0aHJvd3Mgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwcm90ZWN0ZWQgUm93RmlsdGVySW50ZXJmYWNlIHVuaW9uRmlsdGVycyhTdHJpbmcgZmlsdGVycykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIEZpbHRlckZhY3RvcnkgZiA9IFJFU1RDb25zdGFudHMuZmlsdGVyRmFjdG9yaWVzLmdldCgiUm93RmlsdGVyU2V0Iik7CisgICAgcmV0dXJuIGYuZ2V0RmlsdGVyRnJvbUpTT04oZmlsdGVycyk7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9TY2FubmVyTW9kZWwuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvU2Nhbm5lck1vZGVsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzk1MTQzMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvU2Nhbm5lck1vZGVsLmphdmEKQEAgLTAsMCArMSwyNzcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuU2Nhbm5lcklkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgU2Nhbm5lck1vZGVsIGV4dGVuZHMgQWJzdHJhY3RNb2RlbCB7CisKKyAgcHVibGljIFNjYW5uZXJNb2RlbChIQmFzZUNvbmZpZ3VyYXRpb24gY29uZmlnLCBIQmFzZUFkbWluIGFkbWluKSB7CisgICAgc3VwZXIuaW5pdGlhbGl6ZShjb25maWcsIGFkbWluKTsKKyAgfQorICAKKyAgLy8KKyAgLy8gTm9ybWFsIFNjYW5uZXIKKyAgLy8KKyAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBTY2FubmVyTWFzdGVyIHsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIFNjYW5uZXI+IHNjYW5uZXJNYXAgPSBuZXcgQ29uY3VycmVudEhhc2hNYXA8SW50ZWdlciwgU2Nhbm5lcj4oKTsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIEF0b21pY0ludGVnZXIgbmV4dFNjYW5uZXJJZCA9IG5ldyBBdG9taWNJbnRlZ2VyKDEpOworCisgICAgcHVibGljIEludGVnZXIgYWRkU2Nhbm5lcihTY2FubmVyIHNjYW5uZXIpIHsKKyAgICAgIEludGVnZXIgaSA9IEludGVnZXIudmFsdWVPZihuZXh0U2Nhbm5lcklkLmdldEFuZEluY3JlbWVudCgpKTsKKyAgICAgIHNjYW5uZXJNYXAucHV0KGksIHNjYW5uZXIpOworICAgICAgcmV0dXJuIGk7CisgICAgfQorCisgICAgcHVibGljIFNjYW5uZXIgZ2V0U2Nhbm5lcihJbnRlZ2VyIGlkKSB7CisgICAgICByZXR1cm4gc2Nhbm5lck1hcC5nZXQoaWQpOworICAgIH0KKworICAgIHB1YmxpYyBTY2FubmVyIHJlbW92ZVNjYW5uZXIoSW50ZWdlciBpZCkgeworICAgICAgcmV0dXJuIHNjYW5uZXJNYXAucmVtb3ZlKGlkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gaWQKKyAgICAgKiAgICAgICAgICBpZCBvZiBzY2FubmVyIHRvIGNsb3NlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2Nhbm5lckNsb3NlKEludGVnZXIgaWQpIHsKKyAgICAgIFNjYW5uZXIgcyA9IHNjYW5uZXJNYXAucmVtb3ZlKGlkKTsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgIH0KKworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFNjYW5uZXJNYXN0ZXIgc2Nhbm5lck1hc3RlciA9IG5ldyBTY2FubmVyTWFzdGVyKCk7CisKKyAgLyoqCisgICAqIHJldHVybnMgdGhlIG5leHQgbnVtUmVzdWx0cyBSb3dSZXN1bHRzIGZyb20gdGhlIFNjYW5lciBtYXBwZWQgdG8gSW50ZWdlcgorICAgKiBpZC4gSWYgdGhlIGVuZCBvZiB0aGUgdGFibGUgaXMgcmVhY2hlZCwgdGhlIHNjYW5uZXIgaXMgY2xvc2VkIGFuZCBhbGwKKyAgICogc3VjY2VzZnVsbHkgcmV0cmlldmVkIHJvd3MgYXJlIHJldHVybmVkLgorICAgKiAKKyAgICogQHBhcmFtIGlkCisgICAqICAgICAgICAgIGlkIHRhcmdldCBzY2FubmVyIGlzIG1hcHBlZCB0by4KKyAgICogQHBhcmFtIG51bVJvd3MKKyAgICogICAgICAgICAgbnVtYmVyIG9mIHJlc3VsdHMgdG8gcmV0dXJuLgorICAgKiBAcmV0dXJuIGFsbCBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIHJvd3MuCisgICAqIEB0aHJvd3Mgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgUm93UmVzdWx0W10gc2Nhbm5lckdldChJbnRlZ2VyIGlkLCBMb25nIG51bVJvd3MpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgQXJyYXlMaXN0PFJvd1Jlc3VsdD4gYTsKKyAgICAgIFNjYW5uZXIgczsKKyAgICAgIFJvd1Jlc3VsdCByOworCisgICAgICBhID0gbmV3IEFycmF5TGlzdDxSb3dSZXN1bHQ+KCk7CisgICAgICBzID0gc2Nhbm5lck1hc3Rlci5nZXRTY2FubmVyKGlkKTsKKworICAgICAgaWYgKHMgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKCJTY2FubmVySWQ6ICIgKyBpZAorICAgICAgICAgICAgKyAiIGlzIHVuYXZhaWxhYmxlLiAgUGxlYXNlIGNyZWF0ZSBhIG5ldyBzY2FubmVyIik7CisgICAgICB9CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtUm93czsgaSsrKSB7CisgICAgICAgIGlmICgociA9IHMubmV4dCgpKSAhPSBudWxsKSB7CisgICAgICAgICAgYS5hZGQocik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2Nhbm5lck1hc3Rlci5zY2FubmVyQ2xvc2UoaWQpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHJldHVybiBhLnRvQXJyYXkobmV3IFJvd1Jlc3VsdFswXSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhbGwgcm93cyBpbmJldHdlZW4gdGhlIHNjYW5uZXJzIGN1cnJlbnQgcG9zaXRpb24gYW5kIHRoZSBlbmQgb2YgdGhlCisgICAqIHRhYmxlLgorICAgKiAKKyAgICogQHBhcmFtIGlkCisgICAqICAgICAgICAgIGlkIG9mIHNjYW5uZXIgdG8gdXNlCisgICAqIEByZXR1cm4gYWxsIHJvd3MgdGlsbCBlbmQgb2YgdGFibGUKKyAgICogQHRocm93cyBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBSb3dSZXN1bHRbXSBzY2FubmVyR2V0KEludGVnZXIgaWQpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBBcnJheUxpc3Q8Um93UmVzdWx0PiBhOworICAgICAgU2Nhbm5lciBzOworICAgICAgUm93UmVzdWx0IHI7CisKKyAgICAgIGEgPSBuZXcgQXJyYXlMaXN0PFJvd1Jlc3VsdD4oKTsKKyAgICAgIHMgPSBzY2FubmVyTWFzdGVyLmdldFNjYW5uZXIoaWQpOworCisgICAgICB3aGlsZSAoKHIgPSBzLm5leHQoKSkgIT0gbnVsbCkgeworICAgICAgICBhLmFkZChyKTsKKyAgICAgIH0KKworICAgICAgc2Nhbm5lck1hc3Rlci5zY2FubmVyQ2xvc2UoaWQpOworCisgICAgICByZXR1cm4gYS50b0FycmF5KG5ldyBSb3dSZXN1bHRbMF0pOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gc2Nhbm5lckNsb3NlKEludGVnZXIgaWQpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFNjYW5uZXIgcyA9IHNjYW5uZXJNYXN0ZXIucmVtb3ZlU2Nhbm5lcihpZCk7CisKKyAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKCJTY2FubmVyIGlkOiAiICsgaWQgKyAiIGRvZXMgbm90IGV4aXN0Iik7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gU2Nhbm5lciBPcGVuIE1ldGhvZHMKKyAgLy8gTm8gQ29sdW1ucworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgbG9uZyB0aW1lc3RhbXApCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gc2Nhbm5lck9wZW4odGFibGVOYW1lLCBnZXRDb2x1bW5zKHRhYmxlTmFtZSksIHRpbWVzdGFtcCk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93KQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHNjYW5uZXJPcGVuKHRhYmxlTmFtZSwgZ2V0Q29sdW1ucyh0YWJsZU5hbWUpLCBzdGFydFJvdyk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LAorICAgICAgbG9uZyB0aW1lc3RhbXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSwgc3RhcnRSb3csIHRpbWVzdGFtcCk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSwgZmlsdGVyKTsKKyAgfQorCisgIHB1YmxpYyBTY2FubmVySWRlbnRpZmllciBzY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBsb25nIHRpbWVzdGFtcCwKKyAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSwgdGltZXN0YW1wLCBmaWx0ZXIpOworICB9CisKKyAgcHVibGljIFNjYW5uZXJJZGVudGlmaWVyIHNjYW5uZXJPcGVuKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywKKyAgICAgIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSwgc3RhcnRSb3csIGZpbHRlcik7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LAorICAgICAgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGdldENvbHVtbnModGFibGVOYW1lKSwgc3RhcnRSb3csIHRpbWVzdGFtcCwKKyAgICAgICAgZmlsdGVyKTsKKyAgfQorCisgIC8vIFdpdGggQ29sdW1ucworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlOworICAgICAgdGFibGUgPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICByZXR1cm4gbmV3IFNjYW5uZXJJZGVudGlmaWVyKHNjYW5uZXJNYXN0ZXIuYWRkU2Nhbm5lcih0YWJsZS5nZXRTY2FubmVyKAorICAgICAgICAgIGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLCB0aW1lc3RhbXApKSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdW10gY29sdW1ucykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBzY2FubmVyT3Blbih0YWJsZU5hbWUsIGNvbHVtbnMsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGJ5dGVbXSBzdGFydFJvdywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBIVGFibGUgdGFibGU7CisgICAgICB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiBuZXcgU2Nhbm5lcklkZW50aWZpZXIoc2Nhbm5lck1hc3Rlci5hZGRTY2FubmVyKHRhYmxlLmdldFNjYW5uZXIoCisgICAgICAgICAgY29sdW1ucywgc3RhcnRSb3csIHRpbWVzdGFtcCkpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBTY2FubmVySWRlbnRpZmllciBzY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBieXRlW11bXSBjb2x1bW5zLAorICAgICAgYnl0ZVtdIHN0YXJ0Um93KSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgfQorCisgIHB1YmxpYyBTY2FubmVySWRlbnRpZmllciBzY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBieXRlW11bXSBjb2x1bW5zLAorICAgICAgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBIVGFibGUgdGFibGU7CisgICAgICB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiBuZXcgU2Nhbm5lcklkZW50aWZpZXIoc2Nhbm5lck1hc3Rlci5hZGRTY2FubmVyKHRhYmxlLmdldFNjYW5uZXIoCisgICAgICAgICAgY29sdW1ucywgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csIHRpbWVzdGFtcCwgZmlsdGVyKSkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIFNjYW5uZXJJZGVudGlmaWVyIHNjYW5uZXJPcGVuKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXVtdIGNvbHVtbnMsCisgICAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIGZpbHRlcik7CisgIH0KKworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lck9wZW4oYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGJ5dGVbXSBzdGFydFJvdywgbG9uZyB0aW1lc3RhbXAsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlOworICAgICAgdGFibGUgPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICByZXR1cm4gbmV3IFNjYW5uZXJJZGVudGlmaWVyKHNjYW5uZXJNYXN0ZXIuYWRkU2Nhbm5lcih0YWJsZS5nZXRTY2FubmVyKAorICAgICAgICAgIGNvbHVtbnMsIHN0YXJ0Um93LCB0aW1lc3RhbXAsIGZpbHRlcikpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBTY2FubmVySWRlbnRpZmllciBzY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBieXRlW11bXSBjb2x1bW5zLAorICAgICAgYnl0ZVtdIHN0YXJ0Um93LCBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXR1cm4gc2Nhbm5lck9wZW4odGFibGVOYW1lLCBjb2x1bW5zLCBzdGFydFJvdywKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBmaWx0ZXIpOworICB9CisgIAorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9TdGF0dXMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvU3RhdHVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWNjNWU4NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvU3RhdHVzLmphdmEKQEAgLTAsMCArMSwyNTYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0OworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CisKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuU2Nhbm5lcklkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklTZXJpYWxpemFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworaW1wb3J0IGFnaWxlanNvbi5UT0pTT047CisKK3B1YmxpYyBjbGFzcyBTdGF0dXMgeworCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICBwcml2YXRlIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhTdGF0dXMuY2xhc3MpOworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgSGFzaE1hcDxJbnRlZ2VyLCBTdHJpbmc+IHN0YXROYW1lcyA9IG5ldyBIYXNoTWFwPEludGVnZXIsIFN0cmluZz4oKTsKKworICBzdGF0aWMgeworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19DT05USU5VRSwgImNvbnRpbnVlIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1NXSVRDSElOR19QUk9UT0NPTFMsCisgICAgICAgICJzd2l0Y2hpbmcgcHJvdG9jb2xzIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX09LLCAib2siKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfQ1JFQVRFRCwgImNyZWF0ZWQiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfQUNDRVBURUQsICJhY2NlcHRlZCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19OT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTiwKKyAgICAgICAgIm5vbi1hdXRob3JpdGF0aXZlIGluZm9ybWF0aW9uIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX05PX0NPTlRFTlQsICJubyBjb250ZW50Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1JFU0VUX0NPTlRFTlQsICJyZXNldCBjb250ZW50Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1BBUlRJQUxfQ09OVEVOVCwgInBhcnRpYWwgY29udGVudCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19NVUxUSVBMRV9DSE9JQ0VTLCAibXVsdGlwbGUgY2hvaWNlcyIpOworICAgIHN0YXROYW1lcworICAgICAgICAucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTU9WRURfUEVSTUFORU5UTFksICJtb3ZlZCBwZXJtYW5lbnRseSIpOworICAgIHN0YXROYW1lcworICAgICAgICAucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTU9WRURfVEVNUE9SQVJJTFksICJtb3ZlZCB0ZW1wb3JhcmlseSIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19GT1VORCwgImZvdW5kIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1NFRV9PVEhFUiwgInNlZSBvdGhlciIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19OT1RfTU9ESUZJRUQsICJub3QgbW9kaWZpZWQiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfVVNFX1BST1hZLCAidXNlIHByb3h5Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1RFTVBPUkFSWV9SRURJUkVDVCwKKyAgICAgICAgInRlbXBvcmFyeSByZWRpcmVjdCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19CQURfUkVRVUVTVCwgImJhZCByZXF1ZXN0Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1VOQVVUSE9SSVpFRCwgInVuYXV0aG9yaXplZCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19GT1JCSURERU4sICJmb3JiaWRkZW4iKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTk9UX0ZPVU5ELCAibm90IGZvdW5kIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX01FVEhPRF9OT1RfQUxMT1dFRCwKKyAgICAgICAgIm1ldGhvZCBub3QgYWxsb3dlZCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19OT1RfQUNDRVBUQUJMRSwgIm5vdCBhY2NlcHRhYmxlIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1BST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVELAorICAgICAgICAicHJveHkgYXV0aGVudGljYXRpb24gcmVxdWlyZWQiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfUkVRVUVTVF9USU1FT1VULCAicmVxdWVzdCB0aW1lb3V0Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX0NPTkZMSUNULCAiY29uZmxpY3QiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfR09ORSwgImdvbmUiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTEVOR1RIX1JFUVVJUkVELCAibGVuZ3RoIHJlcXVpcmVkIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1BSRUNPTkRJVElPTl9GQUlMRUQsCisgICAgICAgICJwcmVjb25kaXRpb24gZmFpbGVkIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1JFUVVFU1RfRU5USVRZX1RPT19MQVJHRSwKKyAgICAgICAgInJlcXVlc3QgZW50aXR5IHRvbyBsYXJnZSIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19SRVFVRVNUX1VSSV9UT09fTE9ORywKKyAgICAgICAgInJlcXVlc3QgdXJpIHRvbyBsb25nIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1VOU1VQUE9SVEVEX01FRElBX1RZUEUsCisgICAgICAgICJ1bnN1cHBvcnRlZCBtZWRpYSB0eXBlIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX1JFUVVFU1RFRF9SQU5HRV9OT1RfU0FUSVNGSUFCTEUsCisgICAgICAgICJyZXF1ZXN0ZWQgcmFuZ2Ugbm90IHNhdGlzZmlhYmxlIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX0VYUEVDVEFUSU9OX0ZBSUxFRCwKKyAgICAgICAgImV4cGVjdGF0aW9uIGZhaWxlZCIpOworICAgIHN0YXROYW1lcy5wdXQoSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19JTlRFUk5BTF9TRVJWRVJfRVJST1IsCisgICAgICAgICJpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTk9UX0lNUExFTUVOVEVELCAibm90IGltcGxlbWVudGVkIik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX0JBRF9HQVRFV0FZLCAiYmFkIGdhdGV3YXkiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfU0VSVklDRV9VTkFWQUlMQUJMRSwKKyAgICAgICAgInNlcnZpY2UgdW5hdmFpbGFibGUiKTsKKyAgICBzdGF0TmFtZXMucHV0KEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfR0FURVdBWV9USU1FT1VULCAiZ2F0ZXdheSB0aW1lb3V0Iik7CisgICAgc3RhdE5hbWVzLnB1dChIdHRwU2VydmxldFJlc3BvbnNlLlNDX0hUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVELAorICAgICAgICAiaHR0cCB2ZXJzaW9uIG5vdCBzdXBwb3J0ZWQiKTsKKyAgfQorICBwcm90ZWN0ZWQgaW50IHN0YXR1c0NvZGU7CisgIHByb3RlY3RlZCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlOworICBwcm90ZWN0ZWQgT2JqZWN0IG1lc3NhZ2U7CisgIHByb3RlY3RlZCBJUmVzdFNlcmlhbGl6ZXIgc2VyaWFsaXplcjsKKyAgcHJvdGVjdGVkIGJ5dGVbXVtdIHBhdGhTZWdtZW50czsgCisKKyAgcHVibGljIGludCBnZXRTdGF0dXNDb2RlKCkgeworICAgIHJldHVybiBzdGF0dXNDb2RlOworICB9CisKKyAgQFRPSlNPTgorICBwdWJsaWMgT2JqZWN0IGdldE1lc3NhZ2UoKSB7CisgICAgcmV0dXJuIG1lc3NhZ2U7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIFN0YXR1c01lc3NhZ2UgaW1wbGVtZW50cyBJU2VyaWFsaXphYmxlIHsKKyAgICBpbnQgc3RhdHVzQ29kZTsKKyAgICBib29sZWFuIGVycm9yOworICAgIE9iamVjdCByZWFzb247CisKKyAgICBwdWJsaWMgU3RhdHVzTWVzc2FnZShpbnQgc3RhdHVzQ29kZSwgYm9vbGVhbiBlcnJvciwgT2JqZWN0IG8pIHsKKyAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7CisgICAgICB0aGlzLmVycm9yID0gZXJyb3I7CisgICAgICByZWFzb24gPSBvOworICAgIH0KKworICAgIEBUT0pTT04KKyAgICBwdWJsaWMgaW50IGdldFN0YXR1c0NvZGUoKSB7CisgICAgICByZXR1cm4gc3RhdHVzQ29kZTsKKyAgICB9CisKKyAgICBAVE9KU09OCisgICAgcHVibGljIGJvb2xlYW4gZ2V0RXJyb3IoKSB7CisgICAgICByZXR1cm4gZXJyb3I7CisgICAgfQorCisgICAgQFRPSlNPTgorICAgIHB1YmxpYyBPYmplY3QgZ2V0TWVzc2FnZSgpIHsKKyAgICAgIHJldHVybiByZWFzb247CisgICAgfQorCisgICAgLyoKKyAgICAgKiAobm9uLUphdmFkb2MpCisgICAgICogCisgICAgICogQHNlZQorICAgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QueG1sLklPdXRwdXRYTUwjdG9YTUwob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UKKyAgICAgKiAucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCByZXN0U2VyaWFsaXplKElSZXN0U2VyaWFsaXplciBzZXJpYWxpemVyKQorICAgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAgIHNlcmlhbGl6ZXIuc2VyaWFsaXplU3RhdHVzTWVzc2FnZSh0aGlzKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgU3RhdHVzKEh0dHBTZXJ2bGV0UmVzcG9uc2UgciwgSVJlc3RTZXJpYWxpemVyIHNlcmlhbGl6ZXIsIGJ5dGVbXVtdIGJzKSB7CisgICAgdGhpcy5zZXRPSygpOworICAgIHRoaXMucmVzcG9uc2UgPSByOworICAgIHRoaXMuc2VyaWFsaXplciA9IHNlcmlhbGl6ZXI7CisgICAgdGhpcy5wYXRoU2VnbWVudHMgPSBiczsKKyAgfQorCisgIC8vIEdvb2QgTWVzc2FnZXMKKyAgcHVibGljIHZvaWQgc2V0T0soKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19PSzsKKyAgICB0aGlzLm1lc3NhZ2UgPSBuZXcgU3RhdHVzTWVzc2FnZShIdHRwU2VydmxldFJlc3BvbnNlLlNDX09LLCBmYWxzZSwgInN1Y2Nlc3MiKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE9LKE9iamVjdCBtZXNzYWdlKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19PSzsKKyAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOworICB9CisgIAorICBwdWJsaWMgdm9pZCBzZXRBY2NlcHRlZCgpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX0FDQ0VQVEVEOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfQUNDRVBURUQsIGZhbHNlLCAic3VjY2VzcyIpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0RXhpc3RzKGJvb2xlYW4gZXJyb3IpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX0NPTkZMSUNUOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKHN0YXR1c0NvZGUsIGVycm9yLCAidGFibGUgYWxyZWFkeSBleGlzdHMiKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldENyZWF0ZWQoKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19DUkVBVEVEOworICAgIHRoaXMuc2V0T0soKTsKKyAgfSAgCisKKyAgcHVibGljIHZvaWQgc2V0U2Nhbm5lckNyZWF0ZWQoU2Nhbm5lcklkZW50aWZpZXIgc2Nhbm5lcklkZW50aWZpZXIpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX09LOworICAgIHRoaXMubWVzc2FnZSA9IHNjYW5uZXJJZGVudGlmaWVyOworICAgIHJlc3BvbnNlLmFkZEhlYWRlcigiTG9jYXRpb24iLCAiLyIgKyBCeXRlcy50b1N0cmluZyhwYXRoU2VnbWVudHNbMF0pCisgICAgICAgICsgIi9zY2FubmVyLyIgKyBzY2FubmVySWRlbnRpZmllci5nZXRJZCgpKTsKKyAgfQorICAvLyBCYWQgTWVzc2FnZXMKKworICBwdWJsaWMgdm9pZCBzZXRJbnRlcm5hbEVycm9yKEV4Y2VwdGlvbiBlKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19JTlRFUk5BTF9TRVJWRVJfRVJST1I7CisgICAgdGhpcy5tZXNzYWdlID0gbmV3IFN0YXR1c01lc3NhZ2Uoc3RhdHVzQ29kZSwgdHJ1ZSwgZSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXROb1F1ZXJ5UmVzdWx0cygpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX05PVF9GT1VORDsKKyAgICB0aGlzLm1lc3NhZ2UgPSBuZXcgU3RhdHVzTWVzc2FnZShzdGF0dXNDb2RlLCB0cnVlLCAibm8gcXVlcnkgcmVzdWx0cyIpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Q29uZmxpY3QoT2JqZWN0IG1lc3NhZ2UpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX0NPTkZMSUNUOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKHN0YXR1c0NvZGUsIHRydWUsIG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Tm90Rm91bmQoT2JqZWN0IG1lc3NhZ2UpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX05PVF9GT1VORDsKKyAgICB0aGlzLm1lc3NhZ2UgPSBuZXcgU3RhdHVzTWVzc2FnZShzdGF0dXNDb2RlLCB0cnVlLCBtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEJhZFJlcXVlc3QoT2JqZWN0IG1lc3NhZ2UpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX0JBRF9SRVFVRVNUOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKHN0YXR1c0NvZGUsIHRydWUsIG1lc3NhZ2UpOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Tm90Rm91bmQoKSB7CisgICAgc2V0Tm90Rm91bmQoIlVuYWJsZSB0byBmaW5kIHJlcXVlc3RlZCBVUkkiKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1ldGhvZE5vdEltcGxlbWVudGVkKCkgeworICAgIHRoaXMuc3RhdHVzQ29kZSA9IEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTUVUSE9EX05PVF9BTExPV0VEOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKHN0YXR1c0NvZGUsIHRydWUsICJtZXRob2Qgbm90IGltcGxlbWVudGVkIik7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRJbnZhbGlkVVJJKCkgeworICAgIHNldEludmFsaWRVUkkoIkludmFsaWQgVVJJIik7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRJbnZhbGlkVVJJKE9iamVjdCBtZXNzYWdlKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19CQURfUkVRVUVTVDsKKyAgICB0aGlzLm1lc3NhZ2UgPSBuZXcgU3RhdHVzTWVzc2FnZShzdGF0dXNDb2RlLCB0cnVlLCBtZXNzYWdlKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgc2V0VW5zdXBwb3J0ZWRNZWRpYVR5cGUoT2JqZWN0IG1lc3NhZ2UpIHsKKyAgICB0aGlzLnN0YXR1c0NvZGUgPSBIdHRwU2VydmxldFJlc3BvbnNlLlNDX1VOU1VQUE9SVEVEX01FRElBX1RZUEU7CisgICAgdGhpcy5tZXNzYWdlID0gbmV3IFN0YXR1c01lc3NhZ2Uoc3RhdHVzQ29kZSwgdHJ1ZSwgbWVzc2FnZSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHNldEdvbmUoKSB7CisgICAgdGhpcy5zdGF0dXNDb2RlID0gSHR0cFNlcnZsZXRSZXNwb25zZS5TQ19HT05FOworICAgIHRoaXMubWVzc2FnZSA9IG5ldyBTdGF0dXNNZXNzYWdlKHN0YXR1c0NvZGUsIHRydWUsICJpdGVtIG5vIGxvbmdlciBhdmFpbGFibGUiKTsKKyAgfQorICAKKworICAvLyBVdGlsaXR5CisgIHB1YmxpYyB2b2lkIHJlc3BvbmQoKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICByZXNwb25zZS5zZXRTdGF0dXModGhpcy5zdGF0dXNDb2RlKTsKKyAgICB0aGlzLnNlcmlhbGl6ZXIud3JpdGVPdXRwdXQodGhpcy5tZXNzYWdlKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1RhYmxlQ29udHJvbGxlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9UYWJsZUNvbnRyb2xsZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDIyMDQxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9UYWJsZUNvbnRyb2xsZXIuamF2YQpAQCAtMCwwICsxLDE3MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgVGFibGVDb250cm9sbGVyIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sbGVyIHsKKworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGFibGVDb250cm9sbGVyLmNsYXNzKTsKKworICBwcm90ZWN0ZWQgVGFibGVNb2RlbCBnZXRNb2RlbCgpIHsKKyAgICByZXR1cm4gKFRhYmxlTW9kZWwpIG1vZGVsOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBBYnN0cmFjdE1vZGVsIGdlbmVyYXRlTW9kZWwoCisgICAgICBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHJldHVybiBuZXcgVGFibGVNb2RlbChjb25mLCBhZG1pbik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZ2V0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFRhYmxlTW9kZWwgaW5uZXJNb2RlbCA9IGdldE1vZGVsKCk7CisKKyAgICBieXRlW10gdGFibGVOYW1lOworCisgICAgdGFibGVOYW1lID0gcGF0aFNlZ21lbnRzWzBdOworICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoIDwgMikgeworICAgICAgcy5zZXRPSyhpbm5lck1vZGVsLmdldFRhYmxlTWV0YWRhdGEoQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSkpOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzFdKS50b0xvd2VyQ2FzZSgpLmVxdWFscyhSRUdJT05TKSkgeworICAgICAgICBzLnNldE9LKGlubmVyTW9kZWwuZ2V0VGFibGVSZWdpb25zKEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHMuc2V0QmFkUmVxdWVzdCgidW5rbm93biBxdWVyeS4iKTsKKyAgICAgIH0KKyAgICB9CisgICAgcy5yZXNwb25kKCk7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAcGFyYW0gaW5wdXQgY29sdW1uIGRlc2NyaXB0b3IgSlNPTi4gU2hvdWxkIGJlIG9mIHRoZSBmb3JtOiA8cHJlPgorICAgKiB7ImNvbHVtbl9mYW1pbGllcyI6WyB7ICJuYW1lIjpTVFJJTkcsICJibG9vbWZpbHRlciI6Qk9PTEVBTiwKKyAgICogIm1heF92ZXJzaW9ucyI6SU5URUdFUiwgImNvbXByZXNzaW9uX3R5cGUiOlNUUklORywgImluX21lbW9yeSI6Qk9PTEVBTiwKKyAgICogImJsb2NrX2NhY2hlX2VuYWJsZWQiOkJPT0xFQU4sICJtYXhfdmFsdWVfbGVuZ3RoIjpJTlRFR0VSLAorICAgKiAidGltZV90b19saXZlIjpJTlRFR0VSIF19IDwvcHJlPiBJZiBhbnkgb2YgdGhlIGpzb24gb2JqZWN0IGZpZWxkcyAoZXhjZXB0CisgICAqIG5hbWUpIGFyZSBub3QgaW5jbHVkZWQgdGhlIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgaW5jbHVkZWQgaW5zdGVhZC4gVGhlCisgICAqIGRlZmF1bHQgdmFsdWVzIGFyZTogPHByZT4gYmxvb21maWx0ZXIgPT4gZmFsc2UgbWF4X3ZlcnNpb25zID0+IDMKKyAgICogY29tcHJlc3Npb25fdHlwZSA9PiBOT05FIGluX21lbW9yeSA9PiBmYWxzZSBibG9ja19jYWNoZV9lbmFibGVkID0+IGZhbHNlCisgICAqIG1heF92YWx1ZV9sZW5ndGggPT4gMjE0NzQ4MzY0NyB0aW1lX3RvX2xpdmUgPT4gSW50ZWdlci5NQVhfVkFMVUUgPC9wcmU+CisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuQWJzdHJhY3RDb250cm9sbGVyI3Bvc3Qob3JnLmFwYWNoZS5oYWRvb3AuCisgICAqIGhiYXNlLnJlc3QuU3RhdHVzLCBieXRlW11bXSwgamF2YS51dGlsLk1hcCwgYnl0ZVtdLAorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlci5JSEJhc2VSZXN0UGFyc2VyKQorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHBvc3QoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCwgYnl0ZVtdIGlucHV0LCBJSEJhc2VSZXN0UGFyc2VyIHBhcnNlcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFRhYmxlTW9kZWwgaW5uZXJNb2RlbCA9IGdldE1vZGVsKCk7CisKKyAgICBieXRlW10gdGFibGVOYW1lOworCisgICAgaWYgKHBhdGhTZWdtZW50cy5sZW5ndGggPT0gMCkgeworICAgICAgLy8gSWYgbm8gaW5wdXQsIHdlIGRvbid0IGtub3cgY29sdW1uZmFtaWx5IHNjaGVtYSwgc28gc2VuZAorICAgICAgLy8gbm8gZGF0YQorICAgICAgaWYgKGlucHV0Lmxlbmd0aCA9PSAwKSB7CisgICAgICAgIHMuc2V0QmFkUmVxdWVzdCgibm8gZGF0YSBzZW5kIHdpdGggcG9zdCByZXF1ZXN0Iik7CisgICAgICB9IGVsc2UgeworICAgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IHBhcnNlci5nZXRUYWJsZURlc2NyaXB0b3IoaW5wdXQpOworICAgICAgICAvLyBTZW5kIHRvIGlubmVyTW9kZWwuIElmIGlNIHJldHVybnMgZmFsc2UsIG1lYW5zIHRoZQorICAgICAgICAvLyB0YWJsZSBhbHJlYWR5IGV4aXN0cyBzbyByZXR1cm4gY29uZmxpY3QuCisgICAgICAgIGlmICghaW5uZXJNb2RlbC5wb3N0KGh0ZC5nZXROYW1lKCksIGh0ZCkpIHsKKyAgICAgICAgICBzLnNldENvbmZsaWN0KCJ0YWJsZSBhbHJlYWR5IGV4aXN0cyIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIE90aGVyd2lzZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCB0YWJsZS4gUmV0dXJuICJjcmVhdGVkIjp0cnVlCisgICAgICAgICAgcy5zZXRDcmVhdGVkKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1sxXSkudG9Mb3dlckNhc2UoKS5lcXVhbHMoCisgICAgICAgIFJFU1RDb25zdGFudHMuRU5BQkxFKSkgeworICAgICAgdGFibGVOYW1lID0gcGF0aFNlZ21lbnRzWzBdOworICAgICAgaW5uZXJNb2RlbC5lbmFibGVUYWJsZSh0YWJsZU5hbWUpOworICAgICAgcy5zZXRBY2NlcHRlZCgpOworICAgIH0gZWxzZSBpZiAoQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzFdKS50b0xvd2VyQ2FzZSgpLmVxdWFscygKKyAgICAgICAgUkVTVENvbnN0YW50cy5ESVNBQkxFKSkgeworICAgICAgdGFibGVOYW1lID0gcGF0aFNlZ21lbnRzWzBdOworICAgICAgaW5uZXJNb2RlbC5kaXNhYmxlVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHMuc2V0QWNjZXB0ZWQoKTsKKyAgICB9IGVsc2UgeworICAgICAgcy5zZXRCYWRSZXF1ZXN0KCJVbmtub3duIFF1ZXJ5LiIpOworICAgIH0KKyAgICBzLnJlc3BvbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBwdXQoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCwgYnl0ZVtdIGlucHV0LCBJSEJhc2VSZXN0UGFyc2VyIHBhcnNlcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoICE9IDEpIHsKKyAgICAgIHMuc2V0QmFkUmVxdWVzdCgibXVzdCBzcGVjaWZpZnkgdGhlIG5hbWUgb2YgdGhlIHRhYmxlIik7CisgICAgICBzLnJlc3BvbmQoKTsKKyAgICB9IGVsc2UgaWYgKHF1ZXJ5TWFwLnNpemUoKSA+IDApIHsKKyAgICAgIHMKKyAgICAgICAgICAuc2V0QmFkUmVxdWVzdCgibm8gcXVlcnkgc3RyaW5nIHNob3VsZCBiZSBzcGVjaWZpZWQgd2hlbiB1cGRhdGluZyBhIHRhYmxlIik7CisgICAgICBzLnJlc3BvbmQoKTsKKyAgICB9IGVsc2UgeworICAgICAgQXJyYXlMaXN0PEhDb2x1bW5EZXNjcmlwdG9yPiBuZXdDb2x1bW5zID0gcGFyc2VyCisgICAgICAgICAgLmdldENvbHVtbkRlc2NyaXB0b3JzKGlucHV0KTsKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUgPSBwYXRoU2VnbWVudHNbMF07CisgICAgICBnZXRNb2RlbCgpLnVwZGF0ZVRhYmxlKEJ5dGVzLnRvU3RyaW5nKHRhYmxlTmFtZSksIG5ld0NvbHVtbnMpOworICAgICAgcy5zZXRPSygpOworICAgICAgcy5yZXNwb25kKCk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGRlbGV0ZShTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBUYWJsZU1vZGVsIGlubmVyTW9kZWwgPSBnZXRNb2RlbCgpOworCisgICAgYnl0ZVtdIHRhYmxlTmFtZTsKKworICAgIHRhYmxlTmFtZSA9IHBhdGhTZWdtZW50c1swXTsKKworICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID09IDEpIHsKKyAgICAgIGlmICghaW5uZXJNb2RlbC5kZWxldGUodGFibGVOYW1lKSkgeworICAgICAgICBzLnNldEJhZFJlcXVlc3QoInRhYmxlIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzLnNldEFjY2VwdGVkKCk7CisgICAgICB9CisgICAgICBzLnJlc3BvbmQoKTsKKyAgICB9IGVsc2UgeworCisgICAgfQorICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1RhYmxlTW9kZWwuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvVGFibGVNb2RlbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllMTUyNGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1RhYmxlTW9kZWwuamF2YQpAQCAtMCwwICsxLDI3OSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVNlcmlhbGl6YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitpbXBvcnQgYWdpbGVqc29uLlRPSlNPTjsKKworcHVibGljIGNsYXNzIFRhYmxlTW9kZWwgZXh0ZW5kcyBBYnN0cmFjdE1vZGVsIHsKKworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGFibGVNb2RlbC5jbGFzcyk7CisKKyAgcHVibGljIFRhYmxlTW9kZWwoSEJhc2VDb25maWd1cmF0aW9uIGNvbmZpZywgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHN1cGVyLmluaXRpYWxpemUoY29uZmlnLCBhZG1pbik7CisgIH0KKworICAvLyBHZXQgTWV0aG9kcworICBwdWJsaWMgUm93UmVzdWx0W10gZ2V0KGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJldHVybiBnZXQodGFibGVOYW1lLCBnZXRDb2x1bW5zKHRhYmxlTmFtZSkpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYWxsIGNlbGxzIGZyb20gYWxsIHJvd3MgZnJvbSB0aGUgZ2l2ZW4gdGFibGUgaW4gdGhlIGdpdmVuIGNvbHVtbnMuCisgICAqIFRoZSBvdXRwdXQgaXMgaW4gdGhlIG9yZGVyIHRoYXQgdGhlIGNvbHVtbnMgYXJlIGdpdmVuLgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiAgICAgICAgICB0YWJsZSBuYW1lCisgICAqIEBwYXJhbSBjb2x1bW5OYW1lcworICAgKiAgICAgICAgICBjb2x1bW4gbmFtZXMKKyAgICogQHJldHVybiByZXN1bHRhbnQgcm93cworICAgKiBAdGhyb3dzIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdFtdIGdldChieXRlW10gdGFibGVOYW1lLCBieXRlW11bXSBjb2x1bW5OYW1lcykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBBcnJheUxpc3Q8Um93UmVzdWx0PiBhID0gbmV3IEFycmF5TGlzdDxSb3dSZXN1bHQ+KCk7CisgICAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisKKyAgICAgIFNjYW5uZXIgcyA9IHRhYmxlLmdldFNjYW5uZXIoY29sdW1uTmFtZXMpOworICAgICAgUm93UmVzdWx0IHI7CisKKyAgICAgIHdoaWxlICgociA9IHMubmV4dCgpKSAhPSBudWxsKSB7CisgICAgICAgIGEuYWRkKHIpOworICAgICAgfQorCisgICAgICByZXR1cm4gYS50b0FycmF5KG5ldyBSb3dSZXN1bHRbMF0pOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHByb3RlY3RlZCBib29sZWFuIGRvZXNUYWJsZUV4aXN0KGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICByZXR1cm4gdGhpcy5hZG1pbi50YWJsZUV4aXN0cyh0YWJsZU5hbWUpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisgIAorICBwcm90ZWN0ZWQgdm9pZCBkaXNhYmxlVGFibGUoYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMuYWRtaW4uZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigiSU9FeGNlcHRpb24gZGlzYWJsaW5nIHRhYmxlIiwgZSk7CisgICAgfQorICB9CisgIAorICBwcm90ZWN0ZWQgdm9pZCBlbmFibGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgdGhpcy5hZG1pbi5lbmFibGVUYWJsZSh0YWJsZU5hbWUpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oIklPRXhjZXB0aW9uIGVuYWJpbGluZyB0YWJsZSIsIGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBib29sZWFuIHVwZGF0ZVRhYmxlKFN0cmluZyB0YWJsZU5hbWUsCisgICAgICBBcnJheUxpc3Q8SENvbHVtbkRlc2NyaXB0b3I+IGNvbHVtbnMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIEhUYWJsZURlc2NyaXB0b3IgaHRjID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgaHRjID0gdGhpcy5hZG1pbi5nZXRUYWJsZURlc2NyaXB0b3IodGFibGVOYW1lKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKCJUYWJsZSBkb2VzIG5vdCBleGlzdCIpOworICAgIH0KKworICAgIGZvciAoSENvbHVtbkRlc2NyaXB0b3IgY29sdW1uIDogY29sdW1ucykgeworICAgICAgaWYgKGh0Yy5oYXNGYW1pbHkoQnl0ZXMudG9CeXRlcyhjb2x1bW4uZ2V0TmFtZUFzU3RyaW5nKCkpKSkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHRoaXMuYWRtaW4uZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgICAgdGhpcy5hZG1pbi5tb2RpZnlDb2x1bW4odGFibGVOYW1lLCBjb2x1bW4uZ2V0TmFtZUFzU3RyaW5nKCksIGNvbHVtbik7CisgICAgICAgICAgdGhpcy5hZG1pbi5lbmFibGVUYWJsZSh0YWJsZU5hbWUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigidW5hYmxlIHRvIG1vZGlmeSBjb2x1bW4gIgorICAgICAgICAgICAgICArIGNvbHVtbi5nZXROYW1lQXNTdHJpbmcoKSwgZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgdGhpcy5hZG1pbi5kaXNhYmxlVGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgICB0aGlzLmFkbWluLmFkZENvbHVtbih0YWJsZU5hbWUsIGNvbHVtbik7CisgICAgICAgICAgdGhpcy5hZG1pbi5lbmFibGVUYWJsZSh0YWJsZU5hbWUpOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigidW5hYmxlIHRvIGFkZCBjb2x1bW4gIgorICAgICAgICAgICAgICArIGNvbHVtbi5nZXROYW1lQXNTdHJpbmcoKSwgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKworICB9CisKKyAgLyoqCisgICAqIEdldCB0YWJsZSBtZXRhZGF0YS4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgKiBAcmV0dXJuIEhUYWJsZURlc2NyaXB0b3IKKyAgICogQHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlTWV0YWRhdGEoZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzY3JpcHRvciA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3JbXSB0YWJsZXMgPSB0aGlzLmFkbWluLmxpc3RUYWJsZXMoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGlmIChCeXRlcy50b1N0cmluZyh0YWJsZXNbaV0uZ2V0TmFtZSgpKS5lcXVhbHModGFibGVOYW1lKSkgeworICAgICAgICAgIGRlc2NyaXB0b3IgPSB0YWJsZXNbaV07CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlmIChkZXNjcmlwdG9yID09IG51bGwpIHsKKworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigiZXJyb3IgcHJvY2Vzc2luZyByZXF1ZXN0LiIpOworICAgIH0KKyAgICByZXR1cm4gZGVzY3JpcHRvcjsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gcmVnaW9uIG9mZnNldHMuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgCisgICAqIEByZXR1cm4gUmVnaW9ucworICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBSZWdpb25zIGdldFRhYmxlUmVnaW9ucyhmaW5hbCBTdHJpbmcgdGFibGVOYW1lKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGhpcy5jb25mLCB0YWJsZU5hbWUpOworICAgICAgLy8gUHJlc3VtcHRpb24gaXMgdGhhdCB0aGlzLnRhYmxlIGhhcyBhbHJlYWR5IGJlZW4gZm9jdXNlZCBvbiB0YXJnZXQKKyAgICAgIC8vIHRhYmxlLgorICAgICAgUmVnaW9ucyByZWdpb25zID0gbmV3IFJlZ2lvbnModGFibGUuZ2V0U3RhcnRLZXlzKCkpOworICAgICAgLy8gUHJlc3VtcHRpb24gaXMgdGhhdCB0aGlzLnRhYmxlIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGFnYWluc3QgdGFyZ2V0CisgICAgICAvLyB0YWJsZQorICAgICAgcmV0dXJuIHJlZ2lvbnM7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigiVW5hYmxlIHRvIGdldCByZWdpb25zIGZyb20gdGFibGUiKTsKKyAgICB9CisgIH0KKworICAvLyBQb3N0IE1ldGhvZHMKKyAgLyoqCisgICAqIENyZWF0ZXMgdGFibGUgdGFibGVOYW1lIGRlc2NyaWJlZCBieSB0aGUganNvbiBpbiBpbnB1dC4KKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogICAgICAgICAgdGFibGUgbmFtZQorICAgKiBAcGFyYW0gaHRkCisgICAqICAgICAgICAgIEhCYXNlVGFibGVEZXNjcmlwdG9yIGZvciB0aGUgdGFibGUgdG8gYmUgY3JlYXRlZAorICAgKiAKKyAgICogQHJldHVybiB0cnVlIGlmIG9wZXJhdGlvbiBkb2VzIG5vdCBmYWlsIGR1ZSB0byBhIHRhYmxlIHdpdGggdGhlIGdpdmVuCisgICAqICAgICAgICAgdGFibGVOYW1lIG5vdCBleGlzdGluZy4KKyAgICogQHRocm93cyBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHBvc3QoYnl0ZVtdIHRhYmxlTmFtZSwgSFRhYmxlRGVzY3JpcHRvciBodGQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgaWYgKCF0aGlzLmFkbWluLnRhYmxlRXhpc3RzKHRhYmxlTmFtZSkpIHsKKyAgICAgICAgdGhpcy5hZG1pbi5jcmVhdGVUYWJsZShodGQpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlcyB0YWJsZSB0YWJsZU5hbWUKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogICAgICAgICAgbmFtZSBvZiB0aGUgdGFibGUuCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0YWJsZSBleGlzdHMgYW5kIGRlbGV0ZWQsIGZhbHNlIGlmIHRhYmxlIGRvZXMgbm90IGV4aXN0LgorICAgKiBAdGhyb3dzIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gZGVsZXRlKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBpZiAodGhpcy5hZG1pbi50YWJsZUV4aXN0cyh0YWJsZU5hbWUpKSB7CisgICAgICAgIHRoaXMuYWRtaW4uZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIHRoaXMuYWRtaW4uZGVsZXRlVGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBSZWdpb25zIGltcGxlbWVudHMgSVNlcmlhbGl6YWJsZSB7CisgICAgYnl0ZVtdW10gcmVnaW9uS2V5OworCisgICAgcHVibGljIFJlZ2lvbnMoYnl0ZVtdW10gYnMpIHsKKyAgICAgIHN1cGVyKCk7CisgICAgICB0aGlzLnJlZ2lvbktleSA9IGJzOworICAgIH0KKworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICAgIHByaXZhdGUgUmVnaW9ucygpIHsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuIHRoZSByZWdpb25LZXkKKyAgICAgKi8KKyAgICBAVE9KU09OKGZpZWxkTmFtZSA9ICJyZWdpb24iKQorICAgIHB1YmxpYyBieXRlW11bXSBnZXRSZWdpb25LZXkoKSB7CisgICAgICByZXR1cm4gcmVnaW9uS2V5OworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSByZWdpb25LZXkKKyAgICAgKiAgICAgICAgICB0aGUgcmVnaW9uS2V5IHRvIHNldAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJlZ2lvbktleShieXRlW11bXSByZWdpb25LZXkpIHsKKyAgICAgIHRoaXMucmVnaW9uS2V5ID0gcmVnaW9uS2V5OworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqIAorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC54bWwuSU91dHB1dFhNTCN0b1hNTCgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzdFNlcmlhbGl6ZShJUmVzdFNlcmlhbGl6ZXIgc2VyaWFsaXplcikKKyAgICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgICBzZXJpYWxpemVyLnNlcmlhbGl6ZVJlZ2lvbkRhdGEodGhpcyk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1RpbWVzdGFtcENvbnRyb2xsZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvVGltZXN0YW1wQ29udHJvbGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhNmUyNmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L1RpbWVzdGFtcENvbnRyb2xsZXIuamF2YQpAQCAtMCwwICsxLDEzOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Q7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QucGFyc2VyLklIQmFzZVJlc3RQYXJzZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworcHVibGljIGNsYXNzIFRpbWVzdGFtcENvbnRyb2xsZXIgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2xsZXIgeworCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICBwcml2YXRlIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUaW1lc3RhbXBDb250cm9sbGVyLmNsYXNzKTsKKworICBwcm90ZWN0ZWQgVGltZXN0YW1wTW9kZWwgZ2V0TW9kZWwoKSB7CisgICAgcmV0dXJuIChUaW1lc3RhbXBNb2RlbCkgbW9kZWw7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIEFic3RyYWN0TW9kZWwgZ2VuZXJhdGVNb2RlbCgKKyAgICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBIQmFzZUFkbWluIGFkbWluKSB7CisgICAgcmV0dXJuIG5ldyBUaW1lc3RhbXBNb2RlbChjb25mLCBhZG1pbik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZ2V0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXApIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFRpbWVzdGFtcE1vZGVsIGlubmVyTW9kZWwgPSBnZXRNb2RlbCgpOworCisgICAgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBieXRlW10gcm93TmFtZTsKKyAgICBsb25nIHRpbWVzdGFtcDsKKworICAgIHRhYmxlTmFtZSA9IHBhdGhTZWdtZW50c1swXTsKKyAgICByb3dOYW1lID0gcGF0aFNlZ21lbnRzWzJdOworICAgIHRpbWVzdGFtcCA9IEJ5dGVzLnRvTG9uZyhwYXRoU2VnbWVudHNbM10pOworCisgICAgaWYgKHF1ZXJ5TWFwLnNpemUoKSA9PSAwKSB7CisgICAgICBzLnNldE9LKGlubmVyTW9kZWwuZ2V0KHRhYmxlTmFtZSwgcm93TmFtZSwgdGltZXN0YW1wKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIGdldCB0aGUgY29sdW1uIG5hbWVzIGlmIGFueSB3ZXJlIHBhc3NlZCBpbgorICAgICAgU3RyaW5nW10gY29sdW1uX3BhcmFtcyA9IHF1ZXJ5TWFwLmdldChSRVNUQ29uc3RhbnRzLkNPTFVNTik7CisgICAgICBieXRlW11bXSBjb2x1bW5zID0gbnVsbDsKKworICAgICAgaWYgKGNvbHVtbl9wYXJhbXMgIT0gbnVsbCAmJiBjb2x1bW5fcGFyYW1zLmxlbmd0aCA+IDApIHsKKyAgICAgICAgTGlzdDxTdHJpbmc+IGF2YWlsYWJsZV9jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgICAgIGZvciAoU3RyaW5nIGNvbHVtbl9wYXJhbSA6IGNvbHVtbl9wYXJhbXMpIHsKKyAgICAgICAgICBhdmFpbGFibGVfY29sdW1ucy5hZGQoY29sdW1uX3BhcmFtKTsKKyAgICAgICAgfQorICAgICAgICBjb2x1bW5zID0gQnl0ZXMudG9CeXRlQXJyYXlzKGF2YWlsYWJsZV9jb2x1bW5zLnRvQXJyYXkobmV3IFN0cmluZ1swXSkpOworICAgICAgfQorICAgICAgcy5zZXRPSyhpbm5lck1vZGVsLmdldCh0YWJsZU5hbWUsIHJvd05hbWUsIGNvbHVtbnMsIHRpbWVzdGFtcCkpOworICAgIH0KKyAgICBzLnJlc3BvbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBwb3N0KFN0YXR1cyBzLCBieXRlW11bXSBwYXRoU2VnbWVudHMsCisgICAgICBNYXA8U3RyaW5nLCBTdHJpbmdbXT4gcXVlcnlNYXAsIGJ5dGVbXSBpbnB1dCwgSUhCYXNlUmVzdFBhcnNlciBwYXJzZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBUaW1lc3RhbXBNb2RlbCBpbm5lck1vZGVsID0gZ2V0TW9kZWwoKTsKKworICAgIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgYnl0ZVtdIHJvd05hbWU7CisgICAgYnl0ZVtdIGNvbHVtbk5hbWU7CisgICAgbG9uZyB0aW1lc3RhbXA7CisKKyAgICB0YWJsZU5hbWUgPSBwYXRoU2VnbWVudHNbMF07CisgICAgcm93TmFtZSA9IHBhdGhTZWdtZW50c1sxXTsKKyAgICBjb2x1bW5OYW1lID0gcGF0aFNlZ21lbnRzWzJdOworICAgIHRpbWVzdGFtcCA9IEJ5dGVzLnRvTG9uZyhwYXRoU2VnbWVudHNbM10pOworCisgICAgdHJ5IHsKKyAgICAgIGlmIChxdWVyeU1hcC5zaXplKCkgPT0gMCkgeworICAgICAgICBpbm5lck1vZGVsLnBvc3QodGFibGVOYW1lLCByb3dOYW1lLCBjb2x1bW5OYW1lLCB0aW1lc3RhbXAsIGlucHV0KTsKKyAgICAgICAgcy5zZXRPSygpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcy5zZXRVbnN1cHBvcnRlZE1lZGlhVHlwZSgiVW5rbm93biBRdWVyeS4iKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChIQmFzZVJlc3RFeGNlcHRpb24gZSkgeworICAgICAgcy5zZXRVbnN1cHBvcnRlZE1lZGlhVHlwZShlLmdldE1lc3NhZ2UoKSk7CisgICAgfQorICAgIHMucmVzcG9uZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHB1dChTdGF0dXMgcywgYnl0ZVtdW10gcGF0aFNlZ21lbnRzLAorICAgICAgTWFwPFN0cmluZywgU3RyaW5nW10+IHF1ZXJ5TWFwLCBieXRlW10gaW5wdXQsIElIQmFzZVJlc3RQYXJzZXIgcGFyc2VyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJOb3Qgc3VwcG9ydGVkIHlldC4iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGUoU3RhdHVzIHMsIGJ5dGVbXVtdIHBhdGhTZWdtZW50cywKKyAgICAgIE1hcDxTdHJpbmcsIFN0cmluZ1tdPiBxdWVyeU1hcCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgVGltZXN0YW1wTW9kZWwgaW5uZXJNb2RlbCA9IGdldE1vZGVsKCk7CisKKyAgICBieXRlW10gdGFibGVOYW1lOworICAgIGJ5dGVbXSByb3dOYW1lOworICAgIGxvbmcgdGltZXN0YW1wOworCisgICAgdGFibGVOYW1lID0gcGF0aFNlZ21lbnRzWzBdOworICAgIHJvd05hbWUgPSBwYXRoU2VnbWVudHNbMl07CisgICAgdGltZXN0YW1wID0gQnl0ZXMudG9Mb25nKHBhdGhTZWdtZW50c1szXSk7CisKKyAgICBpZiAocXVlcnlNYXAuc2l6ZSgpID09IDApIHsKKyAgICAgIGlubmVyTW9kZWwuZGVsZXRlKHRhYmxlTmFtZSwgcm93TmFtZSwgdGltZXN0YW1wKTsKKyAgICB9IGVsc2UgeworICAgICAgaW5uZXJNb2RlbC5kZWxldGUodGFibGVOYW1lLCByb3dOYW1lLCB0aGlzCisgICAgICAgICAgLmdldENvbHVtbnNGcm9tUXVlcnlNYXAocXVlcnlNYXApLCB0aW1lc3RhbXApOworICAgIH0KKyAgICBzLnNldEFjY2VwdGVkKCk7CisgICAgcy5yZXNwb25kKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvVGltZXN0YW1wTW9kZWwuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvVGltZXN0YW1wTW9kZWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTg3NmM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9UaW1lc3RhbXBNb2RlbC5qYXZhCkBAIC0wLDAgKzEsMTI2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworCitwdWJsaWMgY2xhc3MgVGltZXN0YW1wTW9kZWwgZXh0ZW5kcyBBYnN0cmFjdE1vZGVsIHsKKworICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgcHJpdmF0ZSBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGltZXN0YW1wTW9kZWwuY2xhc3MpOworCisgIHB1YmxpYyBUaW1lc3RhbXBNb2RlbChIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgSEJhc2VBZG1pbiBhZG1pbikgeworICAgIHN1cGVyLmluaXRpYWxpemUoY29uZiwgYWRtaW4pOworICB9CisKKyAgcHVibGljIHZvaWQgZGVsZXRlKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3dOYW1lLCBsb25nIHRpbWVzdGFtcCkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICB0YWJsZS5kZWxldGVBbGwocm93TmFtZSwgdGltZXN0YW1wKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIGRlbGV0ZShieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93TmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgZm9yIChieXRlW10gY29sdW1uIDogY29sdW1ucykgeworICAgICAgICB0YWJsZS5kZWxldGVBbGwocm93TmFtZSwgY29sdW1uLCB0aW1lc3RhbXApOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIENlbGwgZ2V0KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3dOYW1lLCBieXRlW10gY29sdW1uTmFtZSwKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgcmV0dXJuIHRhYmxlLmdldChyb3dOYW1lLCBjb2x1bW5OYW1lLCB0aW1lc3RhbXAsIDEpWzBdOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHVibGljIENlbGxbXSBnZXQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUsIGJ5dGVbXSBjb2x1bW5OYW1lLAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGludCBudW1WZXJzaW9ucykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiB0YWJsZS5nZXQocm93TmFtZSwgY29sdW1uTmFtZSwgdGltZXN0YW1wLCBudW1WZXJzaW9ucyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgUm93UmVzdWx0IGdldChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93TmFtZSwgYnl0ZVtdW10gY29sdW1ucywKKyAgICAgIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgcmV0dXJuIHRhYmxlLmdldFJvdyhyb3dOYW1lLCBjb2x1bW5zLCB0aW1lc3RhbXApOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIHJvd05hbWUKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKiBAcmV0dXJuIFJvd1Jlc3VsdAorICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFJvd1Jlc3VsdCBnZXQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUsIGxvbmcgdGltZXN0YW1wKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJldHVybiB0YWJsZS5nZXRSb3cocm93TmFtZSwgdGltZXN0YW1wKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHBvc3QoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUsIGJ5dGVbXSBjb2x1bW5OYW1lLAorICAgICAgbG9uZyB0aW1lc3RhbXAsIGJ5dGVbXSB2YWx1ZSkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZTsKKyAgICAgIEJhdGNoVXBkYXRlIGI7CisKKyAgICAgIHRhYmxlID0gbmV3IEhUYWJsZSh0YWJsZU5hbWUpOworICAgICAgYiA9IG5ldyBCYXRjaFVwZGF0ZShyb3dOYW1lLCB0aW1lc3RhbXApOworCisgICAgICBiLnB1dChjb2x1bW5OYW1lLCB2YWx1ZSk7CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvUmVzdENlbGwuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvUmVzdENlbGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNDgwY2UxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9kZXNjcmlwdG9ycy9SZXN0Q2VsbC5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9yczsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CisKK2ltcG9ydCBhZ2lsZWpzb24uVE9KU09OOworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgUmVzdENlbGwgZXh0ZW5kcyBDZWxsIHsKKworICBieXRlW10gbmFtZTsKKyAgCisgIAorCisgIC8qKgorICAgKiAKKyAgICovCisgIHB1YmxpYyBSZXN0Q2VsbCgpIHsKKyAgICBzdXBlcigpOworICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY29uc3RydWN0b3Igc3R1YgorICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIG5hbWUgCisgICAqIEBwYXJhbSBjZWxsCisgICAqLworICBwdWJsaWMgUmVzdENlbGwoYnl0ZVtdIG5hbWUsIENlbGwgY2VsbCkgeworICAgIHN1cGVyKGNlbGwuZ2V0VmFsdWUoKSwgY2VsbC5nZXRUaW1lc3RhbXAoKSk7CisgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdmFsdWUKKyAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgKi8KKyAgcHVibGljIFJlc3RDZWxsKGJ5dGVbXSB2YWx1ZSwgbG9uZyB0aW1lc3RhbXApIHsKKyAgICBzdXBlcih2YWx1ZSwgdGltZXN0YW1wKTsKKyAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNvbnN0cnVjdG9yIHN0dWIKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdmFscworICAgKiBAcGFyYW0gdHMKKyAgICovCisgIHB1YmxpYyBSZXN0Q2VsbChieXRlW11bXSB2YWxzLCBsb25nW10gdHMpIHsKKyAgICBzdXBlcih2YWxzLCB0cyk7CisgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjb25zdHJ1Y3RvciBzdHViCisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHZhbHVlCisgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICovCisgIHB1YmxpYyBSZXN0Q2VsbChTdHJpbmcgdmFsdWUsIGxvbmcgdGltZXN0YW1wKSB7CisgICAgc3VwZXIodmFsdWUsIHRpbWVzdGFtcCk7CisgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjb25zdHJ1Y3RvciBzdHViCisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHZhbHMKKyAgICogQHBhcmFtIHRzCisgICAqLworICBwdWJsaWMgUmVzdENlbGwoU3RyaW5nW10gdmFscywgbG9uZ1tdIHRzKSB7CisgICAgc3VwZXIodmFscywgdHMpOworICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY29uc3RydWN0b3Igc3R1YgorICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIG5hbWUKKyAgICovCisgIEBUT0pTT04oYmFzZTY0PXRydWUpCisgIHB1YmxpYyBieXRlW10gZ2V0TmFtZSgpIHsKKyAgICByZXR1cm4gbmFtZTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSB0byBzZXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldE5hbWUoYnl0ZVtdIG5hbWUpIHsKKyAgICB0aGlzLm5hbWUgPSBuYW1lOworICB9CisgIAorICAKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvUm93VXBkYXRlRGVzY3JpcHRvci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9kZXNjcmlwdG9ycy9Sb3dVcGRhdGVEZXNjcmlwdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQwMTA1NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvUm93VXBkYXRlRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKgorICovCitwdWJsaWMgY2xhc3MgUm93VXBkYXRlRGVzY3JpcHRvciB7CisgIHByaXZhdGUgU3RyaW5nIHRhYmxlTmFtZTsKKyAgcHJpdmF0ZSBTdHJpbmcgcm93TmFtZTsKKyAgcHJpdmF0ZSBNYXA8Ynl0ZVtdLCBieXRlW10+IGNvbHZhbHMgPSBuZXcgSGFzaE1hcDxieXRlW10sIGJ5dGVbXT4oKTsKKyAgCisgIHB1YmxpYyBSb3dVcGRhdGVEZXNjcmlwdG9yKFN0cmluZyB0YWJsZU5hbWUsIFN0cmluZyByb3dOYW1lKSB7CisgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgdGhpcy5yb3dOYW1lID0gcm93TmFtZTsKKyAgfQorICAKKyAgcHVibGljIFJvd1VwZGF0ZURlc2NyaXB0b3IoKSB7fQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSB0YWJsZU5hbWUKKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZ2V0VGFibGVOYW1lKCkgeworICAgIHJldHVybiB0YWJsZU5hbWU7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHRhYmxlTmFtZSB0aGUgdGFibGVOYW1lIHRvIHNldAorICAgKi8KKyAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKFN0cmluZyB0YWJsZU5hbWUpIHsKKyAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSByb3dOYW1lCisgICAqLworICBwdWJsaWMgU3RyaW5nIGdldFJvd05hbWUoKSB7CisgICAgcmV0dXJuIHJvd05hbWU7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHJvd05hbWUgdGhlIHJvd05hbWUgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRSb3dOYW1lKFN0cmluZyByb3dOYW1lKSB7CisgICAgdGhpcy5yb3dOYW1lID0gcm93TmFtZTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSB0ZXN0CisgICAqLworICBwdWJsaWMgTWFwPGJ5dGVbXSwgYnl0ZVtdPiBnZXRDb2xWYWxzKCkgeworICAgIHJldHVybiBjb2x2YWxzOworICB9ICAKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvU2Nhbm5lckRlc2NyaXB0b3IuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvU2Nhbm5lckRlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2RkYWJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9kZXNjcmlwdG9ycy9TY2FubmVyRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsMTMwIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9yczsKKworLyoqCisgKiAKKyAqLworcHVibGljIGNsYXNzIFNjYW5uZXJEZXNjcmlwdG9yIHsKKyAgYnl0ZVtdW10gY29sdW1uczsKKyAgbG9uZyB0aW1lc3RhbXA7CisgIGJ5dGVbXSBzdGFydFJvdzsKKyAgYnl0ZVtdIHN0b3BSb3c7CisgIFN0cmluZyBmaWx0ZXJzOworCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1ucworICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqIEBwYXJhbSBzdGFydFJvdworICAgKiBAcGFyYW0gc3RvcFJvdworICAgKiBAcGFyYW0gZmlsdGVycworICAgKi8KKyAgcHVibGljIFNjYW5uZXJEZXNjcmlwdG9yKGJ5dGVbXVtdIGNvbHVtbnMsIGxvbmcgdGltZXN0YW1wLCBieXRlW10gc3RhcnRSb3csCisgICAgICBieXRlW10gc3RvcFJvdywgU3RyaW5nIGZpbHRlcnMpIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgdGhpcy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgIHRoaXMuc3RvcFJvdyA9IHN0b3BSb3c7CisgICAgdGhpcy5maWx0ZXJzID0gZmlsdGVyczsKKyAgICAKKyAgICBpZih0aGlzLnN0YXJ0Um93ID09IG51bGwpIHsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBuZXcgYnl0ZVswXTsKKyAgICB9CisgICAgaWYodGhpcy5zdG9wUm93ID09IG51bGwpIHsKKyAgICAgIHRoaXMuc3RvcFJvdyA9IG5ldyBieXRlWzBdOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBjb2x1bW5zCisgICAqLworICBwdWJsaWMgYnl0ZVtdW10gZ2V0Q29sdW1ucygpIHsKKyAgICByZXR1cm4gY29sdW1uczsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1ucworICAgKiAgICAgICAgICB0aGUgY29sdW1ucyB0byBzZXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldENvbHVtbnMoYnl0ZVtdW10gY29sdW1ucykgeworICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgdGltZXN0YW1wCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgcmV0dXJuIHRpbWVzdGFtcDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAqICAgICAgICAgIHRoZSB0aW1lc3RhbXAgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBzdGFydFJvdworICAgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRTdGFydFJvdygpIHsKKyAgICByZXR1cm4gc3RhcnRSb3c7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHN0YXJ0Um93CisgICAqICAgICAgICAgIHRoZSBzdGFydFJvdyB0byBzZXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldFN0YXJ0Um93KGJ5dGVbXSBzdGFydFJvdykgeworICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBzdG9wUm93CisgICAqLworICBwdWJsaWMgYnl0ZVtdIGdldFN0b3BSb3coKSB7CisgICAgcmV0dXJuIHN0b3BSb3c7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIHN0b3BSb3cKKyAgICogICAgICAgICAgdGhlIHN0b3BSb3cgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRTdG9wUm93KGJ5dGVbXSBzdG9wUm93KSB7CisgICAgdGhpcy5zdG9wUm93ID0gc3RvcFJvdzsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBmaWx0ZXJzCisgICAqLworICBwdWJsaWMgU3RyaW5nIGdldEZpbHRlcnMoKSB7CisgICAgcmV0dXJuIGZpbHRlcnM7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGZpbHRlcnMKKyAgICogICAgICAgICAgdGhlIGZpbHRlcnMgdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRGaWx0ZXJzKFN0cmluZyBmaWx0ZXJzKSB7CisgICAgdGhpcy5maWx0ZXJzID0gZmlsdGVyczsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvU2Nhbm5lcklkZW50aWZpZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvU2Nhbm5lcklkZW50aWZpZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjg0NzJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9kZXNjcmlwdG9ycy9TY2FubmVySWRlbnRpZmllci5qYXZhCkBAIC0wLDAgKzEsOTYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklTZXJpYWxpemFibGU7CisKK2ltcG9ydCBhZ2lsZWpzb24uVE9KU09OOworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgU2Nhbm5lcklkZW50aWZpZXIgaW1wbGVtZW50cyBJU2VyaWFsaXphYmxlIHsKKyAgSW50ZWdlciBpZDsKKyAgTG9uZyBudW1Sb3dzOworCisgIC8qKgorICAgKiBAcGFyYW0gaWQKKyAgICovCisgIHB1YmxpYyBTY2FubmVySWRlbnRpZmllcihJbnRlZ2VyIGlkKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLmlkID0gaWQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGlkCisgICAqIEBwYXJhbSBudW1Sb3dzCisgICAqLworICBwdWJsaWMgU2Nhbm5lcklkZW50aWZpZXIoSW50ZWdlciBpZCwgTG9uZyBudW1Sb3dzKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLmlkID0gaWQ7CisgICAgdGhpcy5udW1Sb3dzID0gbnVtUm93czsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHRoZSBpZAorICAgKi8KKyAgQFRPSlNPTgorICBwdWJsaWMgSW50ZWdlciBnZXRJZCgpIHsKKyAgICByZXR1cm4gaWQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGlkCisgICAqICAgICAgICAgIHRoZSBpZCB0byBzZXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldElkKEludGVnZXIgaWQpIHsKKyAgICB0aGlzLmlkID0gaWQ7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgbnVtUm93cworICAgKi8KKyAgcHVibGljIExvbmcgZ2V0TnVtUm93cygpIHsKKyAgICByZXR1cm4gbnVtUm93czsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbnVtUm93cworICAgKiAgICAgICAgICB0aGUgbnVtUm93cyB0byBzZXQKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldE51bVJvd3MoTG9uZyBudW1Sb3dzKSB7CisgICAgdGhpcy5udW1Sb3dzID0gbnVtUm93czsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC54bWwuSU91dHB1dFhNTCN0b1hNTChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZQorICAgKiAucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplcikKKyAgICovCisgIHB1YmxpYyB2b2lkIHJlc3RTZXJpYWxpemUoSVJlc3RTZXJpYWxpemVyIHNlcmlhbGl6ZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzZXJpYWxpemVyLnNlcmlhbGl6ZVNjYW5uZXJJZGVudGlmaWVyKHRoaXMpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvVGltZXN0YW1wc0Rlc2NyaXB0b3IuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZGVzY3JpcHRvcnMvVGltZXN0YW1wc0Rlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MTI1YzgwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9kZXNjcmlwdG9ycy9UaW1lc3RhbXBzRGVzY3JpcHRvci5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JU2VyaWFsaXphYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBUaW1lc3RhbXBzRGVzY3JpcHRvciBpbXBsZW1lbnRzIElTZXJpYWxpemFibGUgeworICBNYXA8TG9uZywgU3RyaW5nPiB0aW1lc3RhbXBzID0gbmV3IEhhc2hNYXA8TG9uZywgU3RyaW5nPigpOworCisgIHB1YmxpYyB2b2lkIGFkZChsb25nIHRpbWVzdGFtcCwgYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvd05hbWUpIHsKKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICBzYi5hcHBlbmQoJy8nKTsKKyAgICBzYi5hcHBlbmQoQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisgICAgc2IuYXBwZW5kKCIvcm93LyIpOworICAgIHNiLmFwcGVuZChCeXRlcy50b1N0cmluZyhyb3dOYW1lKSk7CisgICAgc2IuYXBwZW5kKCcvJyk7CisgICAgc2IuYXBwZW5kKHRpbWVzdGFtcCk7CisKKyAgICB0aW1lc3RhbXBzLnB1dCh0aW1lc3RhbXAsIHNiLnRvU3RyaW5nKCkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIHRpbWVzdGFtcHMKKyAgICovCisgIHB1YmxpYyBNYXA8TG9uZywgU3RyaW5nPiBnZXRUaW1lc3RhbXBzKCkgeworICAgIHJldHVybiB0aW1lc3RhbXBzOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVNlcmlhbGl6YWJsZSNyZXN0U2VyaWFsaXplKG9yZworICAgKiAuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyKQorICAgKi8KKyAgcHVibGljIHZvaWQgcmVzdFNlcmlhbGl6ZShJUmVzdFNlcmlhbGl6ZXIgc2VyaWFsaXplcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHNlcmlhbGl6ZXIuc2VyaWFsaXplVGltZXN0YW1wcyh0aGlzKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2V4Y2VwdGlvbi9IQmFzZVJlc3RFeGNlcHRpb24uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZXhjZXB0aW9uL0hCYXNlUmVzdEV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5Mzg1MzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2V4Y2VwdGlvbi9IQmFzZVJlc3RFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDg2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb247CisKK2ltcG9ydCBhZ2lsZWpzb24uVE9KU09OOworCitwdWJsaWMgY2xhc3MgSEJhc2VSZXN0RXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKworICAvKioKKyAgICogCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA4NDgxNTg1NDM3MTI0Mjk4NjQ2TDsKKyAgcHJpdmF0ZSBFeGNlcHRpb24gaW5uZXJFeGNlcHRpb247CisgIHByaXZhdGUgU3RyaW5nIGlubmVyQ2xhc3M7CisgIHByaXZhdGUgU3RyaW5nIGlubmVyTWVzc2FnZTsKKworICBwdWJsaWMgSEJhc2VSZXN0RXhjZXB0aW9uKCkgeworCisgIH0KKworICBwdWJsaWMgSEJhc2VSZXN0RXhjZXB0aW9uKEV4Y2VwdGlvbiBlKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBpZiAoSEJhc2VSZXN0RXhjZXB0aW9uLmNsYXNzLmlzQXNzaWduYWJsZUZyb20oZS5nZXRDbGFzcygpKSkgeworICAgICAgdGhyb3cgKChIQmFzZVJlc3RFeGNlcHRpb24pIGUpOworICAgIH0KKyAgICBzZXRJbm5lckV4Y2VwdGlvbihlKTsKKyAgICBpbm5lckNsYXNzID0gZS5nZXRDbGFzcygpLnRvU3RyaW5nKCk7CisgICAgaW5uZXJNZXNzYWdlID0gZS5nZXRNZXNzYWdlKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICovCisgIHB1YmxpYyBIQmFzZVJlc3RFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgICBpbm5lck1lc3NhZ2UgPSBtZXNzYWdlOworICB9CisKKyAgcHVibGljIEhCYXNlUmVzdEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgRXhjZXB0aW9uIGV4Y2VwdGlvbikgeworICAgIHN1cGVyKG1lc3NhZ2UsIGV4Y2VwdGlvbik7CisgICAgc2V0SW5uZXJFeGNlcHRpb24oZXhjZXB0aW9uKTsKKyAgICBpbm5lckNsYXNzID0gZXhjZXB0aW9uLmdldENsYXNzKCkudG9TdHJpbmcoKTsKKyAgICBpbm5lck1lc3NhZ2UgPSBtZXNzYWdlOworICB9CisKKyAgQFRPSlNPTgorICBwdWJsaWMgU3RyaW5nIGdldElubmVyQ2xhc3MoKSB7CisgICAgcmV0dXJuIHRoaXMuaW5uZXJDbGFzczsKKyAgfQorCisgIEBUT0pTT04KKyAgcHVibGljIFN0cmluZyBnZXRJbm5lck1lc3NhZ2UoKSB7CisgICAgcmV0dXJuIHRoaXMuaW5uZXJNZXNzYWdlOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBpbm5lckV4Y2VwdGlvbgorICAgKiAgICAgICAgICB0aGUgaW5uZXJFeGNlcHRpb24gdG8gc2V0CisgICAqLworICBwdWJsaWMgdm9pZCBzZXRJbm5lckV4Y2VwdGlvbihFeGNlcHRpb24gaW5uZXJFeGNlcHRpb24pIHsKKyAgICB0aGlzLmlubmVyRXhjZXB0aW9uID0gaW5uZXJFeGNlcHRpb247CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgaW5uZXJFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBFeGNlcHRpb24gZ2V0SW5uZXJFeGNlcHRpb24oKSB7CisgICAgcmV0dXJuIGlubmVyRXhjZXB0aW9uOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9Db2x1bW5WYWx1ZUZpbHRlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL0NvbHVtblZhbHVlRmlsdGVyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhZjY1MmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9Db2x1bW5WYWx1ZUZpbHRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5maWx0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuQ29sdW1uVmFsdWVGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CitpbXBvcnQgb3JnLmpzb24uSlNPTkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanNvbi5KU09OT2JqZWN0OworCisvKioKKyAqIEZpbHRlckZhY3RvcnkgdGhhdCBjb25zdHJ1Y3RzIGEgQ29sdW1uVmFsdWVGaWx0ZXIgZnJvbSBhIEpTT04gYXJnIFN0cmluZy4KKyAqIEV4cGVjdHMgYSBTdHJpbmdpZmllZCBKU09OIGFyZ3VtZW50IHdpdGggdGhlIGZvbGxvd2luZyBmb3JtOgorICogCisgKiB7ICJjb2x1bW5fbmFtZSIgOiAiTVlfQ09MVU1OX05BTUUiLCAiY29tcGFyZV9vcCIgOiAiSU5TRVJUX0NPTVBBUkVfT1BfSEVSRSIsCisgKiAidmFsdWUiIDogIk1ZX0NPTVBBUkVfVkFMVUUiIH0KKyAqIAorICogVGhlIGN1cnJlbnQgdmFsaWQgY29tcGFyZSBvcHMgYXJlOiBlcXVhbCwgZ3JlYXRlciwgZ3JlYXRlcl9vcl9lcXVhbCwgbGVzcywKKyAqIGxlc3Nfb3JfZXF1YWwsIG5vdF9lcXVhbAorICovCitwdWJsaWMgY2xhc3MgQ29sdW1uVmFsdWVGaWx0ZXJGYWN0b3J5IGltcGxlbWVudHMgRmlsdGVyRmFjdG9yeSB7CisKKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXJGcm9tSlNPTihTdHJpbmcgYXJncykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIEpTT05PYmplY3QgaW5uZXJKU09OOworICAgIFN0cmluZyBjb2x1bW5OYW1lOworICAgIFN0cmluZyBjb21wYXJlT3A7CisgICAgU3RyaW5nIHZhbHVlOworCisgICAgdHJ5IHsKKyAgICAgIGlubmVySlNPTiA9IG5ldyBKU09OT2JqZWN0KGFyZ3MpOworICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisKKyAgICBpZiAoKGNvbHVtbk5hbWUgPSBpbm5lckpTT04ub3B0U3RyaW5nKENPTFVNTl9OQU1FKSkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbigpOworICAgIH0KKyAgICBpZiAoKGNvbXBhcmVPcCA9IGlubmVySlNPTi5vcHRTdHJpbmcoQ09NUEFSRV9PUCkpID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRGaWx0ZXJFeGNlcHRpb24oKTsKKyAgICB9CisgICAgaWYgKCh2YWx1ZSA9IGlubmVySlNPTi5vcHRTdHJpbmcoVkFMVUUpKSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkRmlsdGVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgcmV0dXJuIG5ldyBDb2x1bW5WYWx1ZUZpbHRlcihjb2x1bW5OYW1lLmdldEJ5dGVzKCksCisgICAgICAgIENvbHVtblZhbHVlRmlsdGVyLkNvbXBhcmVPcC52YWx1ZU9mKGNvbXBhcmVPcCksIHZhbHVlLmdldEJ5dGVzKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9GaWx0ZXJGYWN0b3J5LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9GaWx0ZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDA4MDNjMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL0ZpbHRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5maWx0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKKworLyoqCisgKiBDb25zdHJ1Y3RzIEZpbHRlcnMgZnJvbSBKU09OLiBGaWx0ZXJzIGFyZSBkZWZpbmVkCisgKiBhcyBKU09OIE9iamVjdHMgb2YgdGhlIGZvcm06CisgKiB7CisgKiAgInR5cGUiIDogIkZJTFRFUl9DTEFTU19OQU1FIiwKKyAqICJhcmdzIiA6ICJGSUxURVJfQVJHVU1FTlRTIgorICogfQorICogCisgKiBGb3IgRmlsdGVycyBsaWtlIFdoaWxlTWF0Y2hSb3dGaWx0ZXIsCisgKiBuZXN0ZWQgRmlsdGVycyBhcmUgc3VwcG9ydGVkLiBKdXN0IHNlcmlhbGl6ZSBhIGRpZmZlcmVudAorICogZmlsdGVyIGluIHRoZSBmb3JtIChmb3IgaW5zdGFuY2UgaWYgeW91IHdhbnRlZCB0byB1c2UgV2hpbGVNYXRjaFJvd0ZpbHRlcgorICogd2l0aCBhIFN0b3BSb3dGaWx0ZXI6CisgKiAKKyAqIHsKKyAqICAidHlwZSIgOiAiV2hpbGVNYXRjaFJvd0ZpbHRlciIsCisgKiAiYXJncyIgOiB7CisgKiAgICAgICAgICAgICAgInR5cGUiIDogIlN0b3BSb3dGaWx0ZXIiLAorICogICAgICAgICAgICAgICJhcmdzIiA6ICJST1dfS0VZX1RPX1NUT1BfT04iCisgKiAgICAgICAgICAgIH0KKyAqIH0KKyAqIAorICogRm9yIGZpbHRlcnMgbGlrZSBSb3dTZXRGaWx0ZXIsIG5lc3RlZCBGaWx0ZXJzIEFORCBGaWx0ZXIgYXJyYXlzCisgKiBhcmUgc3VwcG9ydGVkLiBTbyBmb3IgaW5zdGFuY2UgSWYgb25lIHdhbnRlZCB0byBkbyBhIFJlZ0V4cAorICogUm93RmlsdGVyIFVOSU9OZWQgd2l0aCBhIFdoaWxlTWF0Y2hSb3dGaWx0ZXIoU3RvcFJvd0ZpbHRlciksCisgKiB5b3Ugd291bGQgbG9vayBsaWtlIHRoaXM6CisgKiAKKyAqIHsKKyAqICAgInR5cGUiIDogIlJvd0ZpbHRlclNldCIsCisgKiAgICJhcmdzIiA6IFsKKyAqICAgICAgICAgICAgICAgIHsKKyAqICAgICAgICAgICAgICAgICAgInR5cGUiIDogIlJlZ0V4cFJvd0ZpbHRlciIsCisgKiAgICAgICAgICAgICAgICAgICJhcmdzIiA6ICJNWV9SRUdVTEFSX0VYUFJFU1NJT04iCisgKiAgICAgICAgICAgICAgICB9LAorICogICAgICAgICAgICAgICAgeworICogICAgICAgICAgICAgICAgICAidHlwZSIgOiAiV2hpbGVNYXRjaFJvd0ZpbHRlciIKKyAqICAgICAgICAgICAgICAgICAgImFyZ3MiIDogeworICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIiA6ICJTdG9wUm93RmlsdGVyIgorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhcmdzIiA6ICJNWV9TVE9QX1JPV19FWFBSRVNTSU9OIgorICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAqICAgICAgICAgICAgICAgIH0KKyAqICAgICAgICAgICAgICBdCisgKiB9CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRmlsdGVyRmFjdG9yeSBleHRlbmRzIEZpbHRlckZhY3RvcnlDb25zdGFudHMgeworICBwdWJsaWMgUm93RmlsdGVySW50ZXJmYWNlIGdldEZpbHRlckZyb21KU09OKFN0cmluZyBhcmdzKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL0ZpbHRlckZhY3RvcnlDb25zdGFudHMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL0ZpbHRlckZhY3RvcnlDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTJiZDQ4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvRmlsdGVyRmFjdG9yeUNvbnN0YW50cy5qYXZhCkBAIC0wLDAgKzEsNDIgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmZpbHRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKKworcHVibGljIGludGVyZmFjZSBGaWx0ZXJGYWN0b3J5Q29uc3RhbnRzIHsKKyAgc3RhdGljIFN0cmluZyBUWVBFID0gInR5cGUiOworICBzdGF0aWMgU3RyaW5nIEFSR1VNRU5UUyA9ICJhcmdzIjsKKyAgc3RhdGljIFN0cmluZyBDT0xVTU5fTkFNRSA9ICJjb2x1bW5fbmFtZSI7CisgIHN0YXRpYyBTdHJpbmcgQ09NUEFSRV9PUCA9ICJjb21wYXJlX29wIjsKKyAgc3RhdGljIFN0cmluZyBWQUxVRSA9ICJ2YWx1ZSI7CisKKyAgc3RhdGljIGNsYXNzIE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbiBleHRlbmRzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CisKKyAgICBwdWJsaWMgTWFsZm9ybWVkRmlsdGVyRXhjZXB0aW9uKCkgeworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICByZXR1cm4gIm1hbGZvcm1lZCBmaWx0ZXIgZXhwcmVzc2lvbiI7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9JbmNsdXNpdmVTdG9wUm93RmlsdGVyRmFjdG9yeS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvSW5jbHVzaXZlU3RvcFJvd0ZpbHRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTM5MjEzNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL0luY2x1c2l2ZVN0b3BSb3dGaWx0ZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLkluY2x1c2l2ZVN0b3BSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEZpbHRlckZhY3RvcnkgdGhhdCBjb25zdHJ1Y3QgYSBJbmNsdXNpdmVTdG9wUm93RmlsdGVyCisgKiBmcm9tIGEgSlNPTiBhcmd1bWVudCBTdHJpbmcuCisgKiAKKyAqIEl0IGV4cGVjdHMgdGhhdCB0aGUgd2hvbGUgaW5wdXQgc3RyaW5nIGNvbnNpc3RzIG9mIG9ubHkKKyAqIHRoZSByb3dLZXkgdGhhdCB5b3Ugd2lzaCB0byBzdG9wIG9uLgorICovCitwdWJsaWMgY2xhc3MgSW5jbHVzaXZlU3RvcFJvd0ZpbHRlckZhY3RvcnkgaW1wbGVtZW50cyBGaWx0ZXJGYWN0b3J5IHsKKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXJGcm9tSlNPTihTdHJpbmcgYXJncykgeworICAgIHJldHVybiBuZXcgSW5jbHVzaXZlU3RvcFJvd0ZpbHRlcihCeXRlcy50b0J5dGVzKGFyZ3MpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvUGFnZVJvd0ZpbHRlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1BhZ2VSb3dGaWx0ZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzViOGE0ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1BhZ2VSb3dGaWx0ZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwzNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlBhZ2VSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKKworLyoqCisgKiBDb25zdHJ1Y3RzIGEgUGFnZVJvd0ZpbHRlciBmcm9tIGEgSlNPTiBhcmd1bWVudCBTdHJpbmcuCisgKiBFeHBlY3RzIHRoZSBlbnRpcmUgSlNPTiBhcmd1bWVudCBzdHJpbmcgdG8gY29uc2lzdAorICogb2YgdGhlIGxvbmcgdGhhdCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBwYWdlcyB0aGF0IHlvdSB3YW50LgorICovCitwdWJsaWMgY2xhc3MgUGFnZVJvd0ZpbHRlckZhY3RvcnkgaW1wbGVtZW50cyBGaWx0ZXJGYWN0b3J5IHsKKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXJGcm9tSlNPTihTdHJpbmcgYXJncykgeworICAgIHJldHVybiBuZXcgUGFnZVJvd0ZpbHRlcihMb25nLnBhcnNlTG9uZyhhcmdzKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1JlZ0V4cFJvd0ZpbHRlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1JlZ0V4cFJvd0ZpbHRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjcyZjMwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvUmVnRXhwUm93RmlsdGVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmZpbHRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5SZWdFeHBSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKKworLyoqCisgKiBDb25zdHJ1Y3RzIGEgUmVnRXhwUm93RmlsdGVyIGZyb20gYSBKU09OIGFyZ3VtZW50IHN0cmluZy4KKyAqIEV4cGVjdHMgdGhlIGVudGlyZSBKU09OIGFyZyBzdHJpbmcgdG8gY29uc2lzdCBvZiB0aGUKKyAqIGVudGlyZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gYmUgdXNlZC4KKyAqLworcHVibGljIGNsYXNzIFJlZ0V4cFJvd0ZpbHRlckZhY3RvcnkgaW1wbGVtZW50cyBGaWx0ZXJGYWN0b3J5IHsKKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXJGcm9tSlNPTihTdHJpbmcgYXJncykgeworICAgIHJldHVybiBuZXcgUmVnRXhwUm93RmlsdGVyKGFyZ3MpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9Sb3dGaWx0ZXJTZXRGYWN0b3J5LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9Sb3dGaWx0ZXJTZXRGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWRjZjRiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1Jvd0ZpbHRlclNldEZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZmlsdGVyOworCitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJTZXQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5SRVNUQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanNvbi5KU09OQXJyYXk7CitpbXBvcnQgb3JnLmpzb24uSlNPTkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanNvbi5KU09OT2JqZWN0OworCisvKioKKyAqIENvbnN0cnVjdHMgYSBSb3dGaWx0ZXJTZXQgZnJvbSBhIEpTT04gYXJndW1lbnQgU3RyaW5nLgorICogCisgKiBBc3N1bWVzIHRoYXQgdGhlIGlucHV0IGlzIGEgSlNPTkFycmF5IGNvbnNpc3Rpbmcgb2YgSlNPTiBPYmplY3QgdmVyc2lvbiBvZgorICogdGhlIGZpbHRlcnMgdGhhdCB5b3Ugd2lzaCB0byBtYXNoIHRvZ2V0aGVyIGluIGFuIEFORCBzdGF0ZW1lbnQuCisgKiAKKyAqIFRoZSBTeW50YXggZm9yIHRoZSBpbmRpdmlkdWFsIGlubmVyIGZpbHRlcnMgYXJlIGRlZmluZWQgYnkgdGhlaXIgcmVzcGVjdGl2ZQorICogRmlsdGVyRmFjdG9yeS4gSWYgYSBmaWx0ZXIgZmFjdG9yeSBmb3Igc2FpZCBGYWN0b3J5IGRvZXMgbm90IGV4aXN0LCBhCisgKiBNYWxmb3JtZWRGaWx0ZXJKU09ORXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgorICogCisgKiBDdXJyZW50bHkgT1IgU3RhdGVtZW50cyBhcmUgbm90IHN1cHBvcnRlZCBldmVuIHRob3VnaCBhdCBhIGxhdGVyIGl0ZXJhdGlvbgorICogdGhleSBjb3VsZCBiZSBzdXBwb3J0ZWQgZWFzaWx5LgorICovCitwdWJsaWMgY2xhc3MgUm93RmlsdGVyU2V0RmFjdG9yeSBpbXBsZW1lbnRzIEZpbHRlckZhY3RvcnkgeworCisgIHB1YmxpYyBSb3dGaWx0ZXJJbnRlcmZhY2UgZ2V0RmlsdGVyRnJvbUpTT04oU3RyaW5nIGFyZ3MpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBKU09OQXJyYXkgZmlsdGVyQXJyYXk7CisgICAgU2V0PFJvd0ZpbHRlckludGVyZmFjZT4gc2V0OworICAgIEpTT05PYmplY3QgZmlsdGVyOworCisgICAgdHJ5IHsKKyAgICAgIGZpbHRlckFycmF5ID0gbmV3IEpTT05BcnJheShhcmdzKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorCisgICAgLy8gSWYgb25seSAxIFJvdywganVzdCByZXR1cm4gdGhlIHJvdy4KKyAgICBpZiAoZmlsdGVyQXJyYXkubGVuZ3RoKCkgPT0gMSkgeworICAgICAgcmV0dXJuIGdldFJvd0ZpbHRlcihmaWx0ZXJBcnJheS5vcHRKU09OT2JqZWN0KDApKTsKKyAgICB9CisKKyAgICAvLyBPdGhlcndpc2UgY29udGludWUKKyAgICBzZXQgPSBuZXcgSGFzaFNldDxSb3dGaWx0ZXJJbnRlcmZhY2U+KCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbHRlckFycmF5Lmxlbmd0aCgpOyBpKyspIHsKKworICAgICAgLy8gR2V0IEZJbHRlciBPYmplY3QKKyAgICAgIGlmICgoZmlsdGVyID0gZmlsdGVyQXJyYXkub3B0SlNPTk9iamVjdChpKSkgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkRmlsdGVyRXhjZXB0aW9uKCk7CisgICAgICB9CisKKyAgICAgIC8vIEFkZCBuZXdseSBjb25zdHJ1Y3RlZCBmaWx0ZXIgdG8gdGhlIGZpbHRlciBzZXQ7CisgICAgICBzZXQuYWRkKGdldFJvd0ZpbHRlcihmaWx0ZXIpKTsKKyAgICB9CisKKyAgICAvLyBQdXQgc2V0IGludG8gYSBSb3dGaWx0ZXJTZXQgYW5kIHJldHVybi4KKyAgICByZXR1cm4gbmV3IFJvd0ZpbHRlclNldChzZXQpOworICB9CisKKyAgLyoqCisgICAqIEEgcmVmYWN0b3JlZCBtZXRob2QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGNyZWF0aW9uIG9mIGEgUm93RmlsdGVyIGdpdmVuIGEKKyAgICogSlNPTk9iamVjdCB3aXRoIGEgY29ycmVjdCBmb3JtIG9mOiB7ICJ0eXBlIiA6ICJNWV9UWVBFIiwgImFyZ3MiIDogTVlfQVJHUywKKyAgICogfQorICAgKiAKKyAgICogQHBhcmFtIGZpbHRlcgorICAgKiBAcmV0dXJuIFJvd0ZpbHRlcgorICAgKiBAdGhyb3dzIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHJvdGVjdGVkIFJvd0ZpbHRlckludGVyZmFjZSBnZXRSb3dGaWx0ZXIoSlNPTk9iamVjdCBmaWx0ZXIpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBGaWx0ZXJGYWN0b3J5IGY7CisgICAgU3RyaW5nIGZpbHRlclR5cGU7CisgICAgU3RyaW5nIGZpbHRlckFyZ3M7CisKKyAgICAvLyBHZXQgRmlsdGVyJ3MgVHlwZQorICAgIGlmICgoZmlsdGVyVHlwZSA9IGZpbHRlci5vcHRTdHJpbmcoRmlsdGVyRmFjdG9yeUNvbnN0YW50cy5UWVBFKSkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIC8vIEdldCBGaWx0ZXIgQXJncworICAgIGlmICgoZmlsdGVyQXJncyA9IGZpbHRlci5vcHRTdHJpbmcoRmlsdGVyRmFjdG9yeUNvbnN0YW50cy5BUkdVTUVOVFMpKSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkRmlsdGVyRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgLy8gR2V0IEZpbHRlciBGYWN0b3J5IGZvciBnaXZlbiBGaWx0ZXIgVHlwZQorICAgIGlmICgoZiA9IFJFU1RDb25zdGFudHMuZmlsdGVyRmFjdG9yaWVzLmdldChmaWx0ZXJUeXBlKSkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbigpOworICAgIH0KKworICAgIHJldHVybiBmLmdldEZpbHRlckZyb21KU09OKGZpbHRlckFyZ3MpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9TdG9wUm93RmlsdGVyRmFjdG9yeS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvU3RvcFJvd0ZpbHRlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGNhYWY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9maWx0ZXIvU3RvcFJvd0ZpbHRlckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDM3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5maWx0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuUm93RmlsdGVySW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5TdG9wUm93RmlsdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogRmlsdGVyRmFjdG9yeSB0aGF0IGNvbnN0cnVjdCBhIFN0b3BSb3dGaWx0ZXIKKyAqIGZyb20gYW4gQXJndW1lbnQgU3RyaW5nLgorICogCisgKiBJdCBleHBlY3RzIHRoYXQgdGhlIHdob2xlIGlucHV0IHN0cmluZyBjb25zaXN0cyBvZiBvbmx5CisgKiB0aGUgcm93S2V5IHRoYXQgeW91IHdpc2ggdG8gc3RvcCBvbi4KKyAqLworcHVibGljIGNsYXNzIFN0b3BSb3dGaWx0ZXJGYWN0b3J5IGltcGxlbWVudHMgRmlsdGVyRmFjdG9yeSB7CisgIHB1YmxpYyBSb3dGaWx0ZXJJbnRlcmZhY2UgZ2V0RmlsdGVyRnJvbUpTT04oU3RyaW5nIGFyZ3MpIHsKKyAgICByZXR1cm4gbmV3IFN0b3BSb3dGaWx0ZXIoQnl0ZXMudG9CeXRlcyhhcmdzKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvZmlsdGVyL1doaWxlTWF0Y2hSb3dGaWx0ZXJGYWN0b3J5LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9XaGlsZU1hdGNoUm93RmlsdGVyRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkYjJhMjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L2ZpbHRlci9XaGlsZU1hdGNoUm93RmlsdGVyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmZpbHRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5Sb3dGaWx0ZXJJbnRlcmZhY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLldoaWxlTWF0Y2hSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5SRVNUQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanNvbi5KU09ORXhjZXB0aW9uOworaW1wb3J0IG9yZy5qc29uLkpTT05PYmplY3Q7CisKKy8qKgorICogRmFjdG9yeSB0byBwcm9kdWNlIFdoaWxlTWF0Y2hSb3dGaWx0ZXJzIGZyb20gSlNPTgorICogRXhwZWN0cyBhcyBhbiBhcmd1ZW1lbnQgYSB2YWxpZCBKU09OIE9iamVjdCBpbiAKKyAqIFN0cmluZyBmb3JtIG9mIGFub3RoZXIgUm93RmlsdGVySW50ZXJmYWNlLgorICovCitwdWJsaWMgY2xhc3MgV2hpbGVNYXRjaFJvd0ZpbHRlckZhY3RvcnkgaW1wbGVtZW50cyBGaWx0ZXJGYWN0b3J5IHsKKyAgcHVibGljIFJvd0ZpbHRlckludGVyZmFjZSBnZXRGaWx0ZXJGcm9tSlNPTihTdHJpbmcgYXJncykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIEpTT05PYmplY3QgaW5uZXJGaWx0ZXJKU09OOworICAgIEZpbHRlckZhY3RvcnkgZjsKKyAgICBTdHJpbmcgaW5uZXJGaWx0ZXJUeXBlOworICAgIFN0cmluZyBpbm5lckZpbHRlckFyZ3M7CisKKyAgICB0cnkgeworICAgICAgaW5uZXJGaWx0ZXJKU09OID0gbmV3IEpTT05PYmplY3QoYXJncyk7CisgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKworICAgIC8vIENoZWNrIGlmIGZpbHRlciBpcyBjb3JyZWN0CisgICAgaWYgKChpbm5lckZpbHRlclR5cGUgPSBpbm5lckZpbHRlckpTT04ub3B0U3RyaW5nKFRZUEUpKSA9PSBudWxsKQorICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbigpOworICAgIGlmICgoaW5uZXJGaWx0ZXJBcmdzID0gaW5uZXJGaWx0ZXJKU09OLm9wdFN0cmluZyhBUkdVTUVOVFMpKSA9PSBudWxsKQorICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZEZpbHRlckV4Y2VwdGlvbigpOworCisgICAgaWYgKChmID0gUkVTVENvbnN0YW50cy5maWx0ZXJGYWN0b3JpZXMuZ2V0KGlubmVyRmlsdGVyVHlwZSkpID09IG51bGwpCisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkRmlsdGVyRXhjZXB0aW9uKCk7CisKKyAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgaW5uZXJGaWx0ZXIgPSBmLmdldEZpbHRlckZyb21KU09OKGlubmVyRmlsdGVyQXJncyk7CisKKyAgICByZXR1cm4gbmV3IFdoaWxlTWF0Y2hSb3dGaWx0ZXIoaW5uZXJGaWx0ZXIpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhY2thZ2UuaHRtbCBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvcGFja2FnZS5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2M2E3YTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDExMiBAQAorPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9JRVRGLy9EVEQgSFRNTC8vRU4iPgorPGh0bWw+CisKKzwhLS0KKyAgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICAgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgICB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAgIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKworPGhlYWQvPgorCis8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+CitQcm92aWRlcyBhbiBIQmFzZQorPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SZXByZXNlbnRhdGlvbmFsX1N0YXRlX1RyYW5zZmVyIj4KK1JFU1Q8L2E+IHNlcnZpY2UuCisKK1RoaXMgZGlyZWN0b3J5IGNvbnRhaW5zIGEgUkVTVCBzZXJ2aWNlIGltcGxlbWVudGF0aW9uIGZvciBhbiBIYmFzZSBSUEMKK3NlcnZpY2UuCisKKzxoMj48YSBuYW1lPSJkZXNjcmlwdGlvbiI+RGVzY3JpcHRpb248L2E+PC9oMj4KKzxwPgorQnkgZGVmYXVsdCwgYW4gaW5zdGFuY2Ugb2YgdGhlIFJFU1Qgc2VydmxldCBydW5zIGluIHRoZSBtYXN0ZXIgVUk7IGp1c3QgYnJvd3NlCit0byBbV1dXXSBodHRwOi8vTUFTVEVSX0hPU1Q6TUFTVEVSX1BPUlQvYXBpLyAoUmVzdWx0cyBhcmUgcmV0dXJuZWQgYXMgeG1sIGJ5CitkZWZhdWx0IHNvIHlvdSBtYXkgaGF2ZSB0byBsb29rIGF0IHNvdXJjZSB0byBzZWUgcmVzdWx0cykuCisKK0lmIHlvdSBpbnRlbmQgdG8gdXNlIHRoZSBoYmFzZSBSRVNUIEFQSSBoZWF2aWx5LCB0byBydW4gYW4gaW5zdGFuY2Ugb2YgdGhlIFJFUworVCBzZXJ2ZXIgb3V0c2lkZSBvZiB0aGUgbWFzdGVyLCBkbyB0aGUgZm9sbG93aW5nOgorICA8cHJlPgorY2QgJEhCQVNFX0hPTUUKK2Jpbi9oYmFzZSByZXN0IHN0YXJ0CisgIDwvcHJlPgorVGhlIGRlZmF1bHQgcG9ydCBpcyA2MDA1MC4KKzwvcD4KKworPGgyPjxhIG5hbWU9InVyaSI+VVJJPC9hPjwvaDI+Cis8aDM+PGEgbmFtZT0idXJpI21ldGEiPlN5c3RlbSBPcGVyYXRpb248L2E+PC9oMz4KKzx1bD4KKyAgPGxpPkdFVCAvIDogUmV0cmlldmUgYSBsaXN0IG9mIGFsbCB0aGUgdGFibGVzIGluIEhCYXNlLjwvbGk+Cis8L3VsPgorCis8aDM+PGEgbmFtZT0idXJpI3RhYmxlIj5UYWJsZSBPcGVyYXRpb248L2E+PC9oMz4KKzx1bD4KKyAgPGxpPlBPU1QgLyA6IENyZWF0ZSBhIHRhYmxlPC9saT4KKworICA8bGk+R0VUIC9bdGFibGVfbmFtZV0gOiBSZXRyaWV2ZSBtZXRhZGF0YSBhYm91dCB0aGUgdGFibGU8L2xpPgorCisgIDxsaT5QVVQgL1t0YWJsZV9uYW1lXSA6IFVwZGF0ZSB0aGUgdGFibGUgc2NoZW1hPC9saT4KKworICA8bGk+REVMRVRFIC9bdGFibGVfbmFtZV0gOiBEZWxldGUgdGhlIHRhYmxlPC9saT4KKworICA8bGk+UE9TVCAvW3RhYmxlX25hbWVdL2Rpc2FibGUgOiBEaXNhYmxlIHRoZSB0YWJsZTwvbGk+CisKKyAgPGxpPlBPU1QgL1t0YWJsZV9uYW1lXS9lbmFibGUgOiBFbmFibGUgdGhlIHRhYmxlPC9saT4KKworICA8bGk+R0VUIC9bdGFibGVfbmFtZV0vcmVnaW9ucyA6IFJldHJpZXZlIGEgbGlzdCBvZiB0aGUgcmVnaW9ucyBmb3IgdGhpcyB0YWJsZQorICBzbyB0aGF0IHlvdSBjYW4gZWZmaWNpZW50bHkgc3BsaXQgdXAgdGhlIHdvcms8L2xpPgorPC91bD4KKworPGgzPjxhIG5hbWU9InVyaSNyb3ciPlJvdyBPcGVyYXRpb248L2E+PC9oMz4KKzx1bD4KKyAgPGxpPkdFVCAvW3RhYmxlX25hbWVdL3Jvdy9bcm93X2tleV0vdGltZXN0YW1wcyA6IFJldHJpZXZlIGEgbGlzdCBvZiBhbGwgdGhlCisgIHRpbWVzdGFtcHMgYXZhaWxhYmxlIGZvciB0aGlzIHJvdyBrZXkgKE5vdCBzdXBwb3J0ZWQgYnkgbmF0aXZlIGhiYXNlIHlldCk8L2xpPgorCisgIDxsaT5HRVQgL1t0YWJsZV9uYW1lXS9yb3cvW3Jvd19rZXldIDogUmV0cmlldmUgZGF0YSBmcm9tIGEKKyAgcm93LiBJZiBjb2x1bW4gbm90IHNwZWNpZmllZCwgcmV0dXJuIGFsbCBjb2x1bW5zPC9saT4KKworICA8bGk+R0VUIC9bdGFibGVfbmFtZV0vcm93L1tyb3dfa2V5XS9bdGltZXN0YW1wXSA6IFJldHJpZXZlCisgIGRhdGEgZnJvbSBhIHJvdywgY29uc3RyYWluZWQgYnkgdGhlIHRpbWVzdGFtcCB2YWx1ZS4gSWYgY29sdW1uIG5vdCBzcGVjaWZpZWQsCisgIHJldHVybiBhbGwgY29sdW1uczwvbGk+CisKKyAgPGxpPlBPU1QvUFVUIC9bdGFibGVfbmFtZV0vcm93L1tyb3dfa2V5XSA6IFNldCB0aGUgdmFsdWUgb2Ygb25lIG9yIG1vcmUKKyAgY29sdW1ucyBmb3IgYSBnaXZlbiByb3cga2V5PC9saT4KKworICA8bGk+UE9TVC9QVVQgL1t0YWJsZV9uYW1lXS9yb3cvW3Jvd19rZXldL1t0aW1lc3RhbXBdIDogU2V0IHRoZSB2YWx1ZSBvZiBvbmUKKyAgb3IgbW9yZSBjb2x1bW5zIGZvciBhIGdpdmVuIHJvdyBrZXkgd2l0aCBhbiBvcHRpb25hbCB0aW1lc3RhbXA8L2xpPgorCisgIDxsaT5ERUxFVEUgL1t0YWJsZV9uYW1lXS9yb3cvW3Jvd19rZXldLyA6IERlbGV0ZSB0aGUgc3BlY2lmaWVkIGNvbHVtbnMgZnJvbQorICB0aGUgcm93LiBJZiB0aGVyZSBhcmUgbm8gY29sdW1ucyBzcGVjaWZpZWQsIHRoZW4gaXQgd2lsbCBkZWxldGUgQUxMIGNvbHVtbnM8L2xpPgorCisgIDxsaT5ERUxFVEUgL1t0YWJsZV9uYW1lXS9yb3cvW3Jvd19rZXldL1t0aW1lc3RhbXBdIDogRGVsZXRlIHRoZSBzcGVjaWZpZWQKKyAgY29sdW1ucyBmcm9tIHRoZSByb3cgY29uc3RyYWluZWQgYnkgdGhlIHRpbWVzdGFtcC4gSWYgdGhlcmUgYXJlIG5vIGNvbHVtbnMKKyAgc3BlY2lmaWVkLCB0aGVuIGl0IHdpbGwgZGVsZXRlIEFMTCBjb2x1bW5zLiAgTm90IHN1cHBvcnRlZCB5ZXQuPC9saT4KKzwvdWw+CisKKzxoMz48YSBuYW1lPSJ1cmkjc2Nhbm5lciI+U2Nhbm5lciBPcGVyYXRpb248L2E+PC9oMz4KKzx1bD4KKyAgPGxpPlBPU1QvUFVUIC9bdGFibGVfbmFtZV0vc2Nhbm5lciA6IFJlcXVlc3QgdGhhdCBhIHNjYW5uZXIgYmUgY3JlYXRlZCB3aXRoCisgIHRoZSBzcGVjaWZpZWQgb3B0aW9ucy4gUmV0dXJucyBhIHNjYW5uZXIgSUQgdGhhdCBjYW4gYmUgdXNlZCB0byBpdGVyYXRlIG92ZXIKKyAgdGhlIHJlc3VsdHMgb2YgdGhlIHNjYW5uZXI8L2xpPgorCisgIDxsaT5QT1NUIC9bdGFibGVfbmFtZV0vc2Nhbm5lci9bc2Nhbm5lcl9pZF0gOiBSZXR1cm4gdGhlIGN1cnJlbnQgaXRlbSBpbiB0aGUKKyAgc2Nhbm5lciBhbmQgYWR2YW5jZSB0byB0aGUgbmV4dCBvbmUuIFRoaW5rIG9mIGl0IGFzIGEgcXVldWUgZGVxdWV1ZSBvcGVyYXRpb248L2xpPgorCisgIDxsaT5ERUxFVEUgL1t0YWJsZV9uYW1lXS9zY2FubmVyL1tzY2FubmVyX2lkXSA6IENsb3NlIGEgc2Nhbm5lcjwvbGk+Cis8L3VsPgorPHA+CitGb3IgZXhhbXBsZXMgYW5kIG1vcmUgZGV0YWlscywgIHBsZWFzZSB2aXNpdAorPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9oYWRvb3AvSGJhc2UvSGJhc2VSZXN0Ij5IQmFzZVJlc3QgV2lraTwvYT4gcGFnZS4KKzwvcD4KKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvcGFyc2VyL0hCYXNlUmVzdFBhcnNlckZhY3RvcnkuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvcGFyc2VyL0hCYXNlUmVzdFBhcnNlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjQ3MTI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9wYXJzZXIvSEJhc2VSZXN0UGFyc2VyRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlcjsKKworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LkRpc3BhdGNoZXIuQ29udGVudFR5cGU7CisKKy8qKgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBIQmFzZVJlc3RQYXJzZXJGYWN0b3J5IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8Q29udGVudFR5cGUsIENsYXNzPD8+PiBwYXJzZXJNYXAgPSAKKyAgICBuZXcgSGFzaE1hcDxDb250ZW50VHlwZSwgQ2xhc3M8Pz4+KCk7CisKKyAgc3RhdGljIHsKKyAgICBwYXJzZXJNYXAucHV0KENvbnRlbnRUeXBlLlhNTCwgWE1MUmVzdFBhcnNlci5jbGFzcyk7CisgICAgcGFyc2VyTWFwLnB1dChDb250ZW50VHlwZS5KU09OLCBKc29uUmVzdFBhcnNlci5jbGFzcyk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIElIQmFzZVJlc3RQYXJzZXIgZ2V0UGFyc2VyKENvbnRlbnRUeXBlIGN0KSB7CisgICAgSUhCYXNlUmVzdFBhcnNlciBwYXJzZXIgPSBudWxsOworCisgICAgQ2xhc3M8Pz4gY2xhenogPSBwYXJzZXJNYXAuZ2V0KGN0KTsKKyAgICB0cnkgeworICAgICAgcGFyc2VyID0gKElIQmFzZVJlc3RQYXJzZXIpIGNsYXp6Lm5ld0luc3RhbmNlKCk7CisgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCisgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgeworICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jaworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICB9CisKKyAgICByZXR1cm4gcGFyc2VyOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhcnNlci9JSEJhc2VSZXN0UGFyc2VyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhcnNlci9JSEJhc2VSZXN0UGFyc2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjg3MzEzYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3QvcGFyc2VyL0lIQmFzZVJlc3RQYXJzZXIuamF2YQpAQCAtMCwwICsxLDUyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXI7CisKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlJvd1VwZGF0ZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9ycy5TY2FubmVyRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CisKKy8qKgorICogCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSUhCYXNlUmVzdFBhcnNlciB7CisgIC8qKgorICAgKiBQYXJzZXMgYSBIVGFibGVEZXNjcmlwdG9yIGdpdmVuIHRoZSBpbnB1dCBhcnJheS4KKyAgICogCisgICAqIEBwYXJhbSBpbnB1dAorICAgKiBAcmV0dXJuIEhUYWJsZURlc2NyaXB0b3IKKyAgICogQHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlRGVzY3JpcHRvcihieXRlW10gaW5wdXQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uOworCisgIHB1YmxpYyBBcnJheUxpc3Q8SENvbHVtbkRlc2NyaXB0b3I+IGdldENvbHVtbkRlc2NyaXB0b3JzKGJ5dGVbXSBpbnB1dCkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgcHVibGljIFNjYW5uZXJEZXNjcmlwdG9yIGdldFNjYW5uZXJEZXNjcmlwdG9yKGJ5dGVbXSBpbnB1dCkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgcHVibGljIFJvd1VwZGF0ZURlc2NyaXB0b3IgZ2V0Um93VXBkYXRlRGVzY3JpcHRvcihieXRlW10gaW5wdXQsCisgICAgICBieXRlW11bXSBwYXRoU2VnbWVudHMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhcnNlci9Kc29uUmVzdFBhcnNlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9wYXJzZXIvSnNvblJlc3RQYXJzZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzE1NzI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9wYXJzZXIvSnNvblJlc3RQYXJzZXIuamF2YQpAQCAtMCwwICsxLDIzNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QucGFyc2VyOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5SRVNUQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuUm93VXBkYXRlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlNjYW5uZXJEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5qc29uLkpTT05BcnJheTsKK2ltcG9ydCBvcmcuanNvbi5KU09ORXhjZXB0aW9uOworaW1wb3J0IG9yZy5qc29uLkpTT05PYmplY3Q7CisKKy8qKgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBKc29uUmVzdFBhcnNlciBpbXBsZW1lbnRzIElIQmFzZVJlc3RQYXJzZXIgeworCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlciNnZXRUYWJsZURlc2NyaXB0b3IKKyAgICogKGJ5dGVbXSkKKyAgICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlRGVzY3JpcHRvcihieXRlW10gaW5wdXQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgSlNPTk9iamVjdCBvOworICAgICAgSFRhYmxlRGVzY3JpcHRvciBoOworICAgICAgSlNPTkFycmF5IGNvbHVtbkRlc2NyaXB0b3JBcnJheTsKKyAgICAgIG8gPSBuZXcgSlNPTk9iamVjdChuZXcgU3RyaW5nKGlucHV0KSk7CisgICAgICBjb2x1bW5EZXNjcmlwdG9yQXJyYXkgPSBvLmdldEpTT05BcnJheSgiY29sdW1uX2ZhbWlsaWVzIik7CisgICAgICBoID0gbmV3IEhUYWJsZURlc2NyaXB0b3Ioby5nZXRTdHJpbmcoIm5hbWUiKSk7CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29sdW1uRGVzY3JpcHRvckFycmF5Lmxlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgSlNPTk9iamVjdCBqc29uX2NvbHVtbkRlc2NyaXB0b3IgPSBjb2x1bW5EZXNjcmlwdG9yQXJyYXkKKyAgICAgICAgICAgIC5nZXRKU09OT2JqZWN0KGkpOworICAgICAgICBoLmFkZEZhbWlseSh0aGlzLmdldENvbHVtbkRlc2NyaXB0b3IoanNvbl9jb2x1bW5EZXNjcmlwdG9yKSk7CisgICAgICB9CisgICAgICByZXR1cm4gaDsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEhDb2x1bW5EZXNjcmlwdG9yIGdldENvbHVtbkRlc2NyaXB0b3IoSlNPTk9iamVjdCBqc29uT2JqZWN0KQorICAgICAgdGhyb3dzIEpTT05FeGNlcHRpb24geworICAgIFN0cmluZyBzdHJUZW1wOworICAgIHN0clRlbXAgPSBqc29uT2JqZWN0LmdldFN0cmluZygibmFtZSIpOworICAgIGlmIChzdHJUZW1wLmNoYXJBdChzdHJUZW1wLmxlbmd0aCgpIC0gMSkgIT0gJzonKSB7CisgICAgICBzdHJUZW1wICs9ICI6IjsKKyAgICB9CisKKyAgICBieXRlW10gbmFtZSA9IEJ5dGVzLnRvQnl0ZXMoc3RyVGVtcCk7CisKKyAgICBpbnQgbWF4VmVyc2lvbnM7CisgICAgU3RyaW5nIGNUeXBlOworICAgIGJvb2xlYW4gaW5NZW1vcnk7CisgICAgYm9vbGVhbiBibG9ja0NhY2hlRW5hYmxlZDsKKyAgICBpbnQgbWF4VmFsdWVMZW5ndGg7CisgICAgaW50IHRpbWVUb0xpdmU7CisgICAgYm9vbGVhbiBibG9vbWZpbHRlcjsKKworICAgIHRyeSB7CisgICAgICBibG9vbWZpbHRlciA9IGpzb25PYmplY3QuZ2V0Qm9vbGVhbigiYmxvb21maWx0ZXIiKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIGJsb29tZmlsdGVyID0gZmFsc2U7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIG1heFZlcnNpb25zID0ganNvbk9iamVjdC5nZXRJbnQoIm1heF92ZXJzaW9ucyIpOworICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgbWF4VmVyc2lvbnMgPSAzOworICAgIH0KKworICAgIHRyeSB7CisgICAgICBjVHlwZSA9IGpzb25PYmplY3QuZ2V0U3RyaW5nKCJjb21wcmVzc2lvbl90eXBlIikudG9VcHBlckNhc2UoKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIGNUeXBlID0gSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9DT01QUkVTU0lPTjsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgaW5NZW1vcnkgPSBqc29uT2JqZWN0LmdldEJvb2xlYW4oImluX21lbW9yeSIpOworICAgIH0gY2F0Y2ggKEpTT05FeGNlcHRpb24gZSkgeworICAgICAgaW5NZW1vcnkgPSBmYWxzZTsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgYmxvY2tDYWNoZUVuYWJsZWQgPSBqc29uT2JqZWN0LmdldEJvb2xlYW4oImJsb2NrX2NhY2hlX2VuYWJsZWQiKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIGJsb2NrQ2FjaGVFbmFibGVkID0gZmFsc2U7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIG1heFZhbHVlTGVuZ3RoID0ganNvbk9iamVjdC5nZXRJbnQoIm1heF92YWx1ZV9sZW5ndGgiKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIG1heFZhbHVlTGVuZ3RoID0gMjE0NzQ4MzY0NzsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgdGltZVRvTGl2ZSA9IGpzb25PYmplY3QuZ2V0SW50KCJ0aW1lX3RvX2xpdmUiKTsKKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIHRpbWVUb0xpdmUgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKKyAgICB9CisKKyAgICByZXR1cm4gbmV3IEhDb2x1bW5EZXNjcmlwdG9yKG5hbWUsIG1heFZlcnNpb25zLCBjVHlwZSwgaW5NZW1vcnksCisgICAgICAgIGJsb2NrQ2FjaGVFbmFibGVkLCBtYXhWYWx1ZUxlbmd0aCwgdGltZVRvTGl2ZSwgYmxvb21maWx0ZXIpOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlci5JSEJhc2VSZXN0UGFyc2VyI2dldENvbHVtbkRlc2NyaXB0b3JzCisgICAqIChieXRlW10pCisgICAqLworICBwdWJsaWMgQXJyYXlMaXN0PEhDb2x1bW5EZXNjcmlwdG9yPiBnZXRDb2x1bW5EZXNjcmlwdG9ycyhieXRlW10gaW5wdXQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBBcnJheUxpc3Q8SENvbHVtbkRlc2NyaXB0b3I+IGNvbHVtbnMgPSBuZXcgQXJyYXlMaXN0PEhDb2x1bW5EZXNjcmlwdG9yPigpOworICAgIHRyeSB7CisgICAgICBKU09OT2JqZWN0IG87CisgICAgICBKU09OQXJyYXkgY29sdW1uRGVzY3JpcHRvckFycmF5OworICAgICAgbyA9IG5ldyBKU09OT2JqZWN0KG5ldyBTdHJpbmcoaW5wdXQpKTsKKyAgICAgIGNvbHVtbkRlc2NyaXB0b3JBcnJheSA9IG8uZ2V0SlNPTkFycmF5KCJjb2x1bW5fZmFtaWxpZXMiKTsKKworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5EZXNjcmlwdG9yQXJyYXkubGVuZ3RoKCk7IGkrKykgeworICAgICAgICBKU09OT2JqZWN0IGpzb25fY29sdW1uRGVzY3JpcHRvciA9IGNvbHVtbkRlc2NyaXB0b3JBcnJheQorICAgICAgICAgICAgLmdldEpTT05PYmplY3QoaSk7CisgICAgICAgIGNvbHVtbnMuYWRkKHRoaXMuZ2V0Q29sdW1uRGVzY3JpcHRvcihqc29uX2NvbHVtbkRlc2NyaXB0b3IpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oIkVycm9yIFBhcnNpbmcganNvbiBpbnB1dCIsIGUpOworICAgIH0KKworICAgIHJldHVybiBjb2x1bW5zOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlci5JSEJhc2VSZXN0UGFyc2VyI2dldFNjYW5uZXJEZXNjcmlwdG9yCisgICAqIChieXRlW10pCisgICAqLworICBwdWJsaWMgU2Nhbm5lckRlc2NyaXB0b3IgZ2V0U2Nhbm5lckRlc2NyaXB0b3IoYnl0ZVtdIGlucHV0KQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgSlNPTk9iamVjdCBzY2FubmVyRGVzY3JpcHRvcjsKKyAgICBKU09OQXJyYXkgY29sdW1uQXJyYXk7CisKKyAgICBieXRlW11bXSBjb2x1bW5zID0gbnVsbDsKKyAgICBsb25nIHRpbWVzdGFtcDsKKyAgICBieXRlW10gc3RhcnRSb3c7CisgICAgYnl0ZVtdIHN0b3BSb3c7CisgICAgU3RyaW5nIGZpbHRlcnM7CisKKyAgICB0cnkgeworICAgICAgc2Nhbm5lckRlc2NyaXB0b3IgPSBuZXcgSlNPTk9iamVjdChuZXcgU3RyaW5nKGlucHV0KSk7CisKKyAgICAgIGNvbHVtbkFycmF5ID0gc2Nhbm5lckRlc2NyaXB0b3Iub3B0SlNPTkFycmF5KFJFU1RDb25zdGFudHMuQ09MVU1OUyk7CisgICAgICB0aW1lc3RhbXAgPSBzY2FubmVyRGVzY3JpcHRvci5vcHRMb25nKFJFU1RDb25zdGFudHMuU0NBTk5FUl9USU1FU1RBTVApOworICAgICAgc3RhcnRSb3cgPSBCeXRlcy50b0J5dGVzKHNjYW5uZXJEZXNjcmlwdG9yLm9wdFN0cmluZygKKyAgICAgICAgICBSRVNUQ29uc3RhbnRzLlNDQU5ORVJfU1RBUlRfUk9XLCAiIikpOworICAgICAgc3RvcFJvdyA9IEJ5dGVzLnRvQnl0ZXMoc2Nhbm5lckRlc2NyaXB0b3Iub3B0U3RyaW5nKAorICAgICAgICAgIFJFU1RDb25zdGFudHMuU0NBTk5FUl9TVE9QX1JPVywgIiIpKTsKKyAgICAgIGZpbHRlcnMgPSBzY2FubmVyRGVzY3JpcHRvci5vcHRTdHJpbmcoUkVTVENvbnN0YW50cy5TQ0FOTkVSX0ZJTFRFUik7CisKKyAgICAgIGlmIChjb2x1bW5BcnJheSAhPSBudWxsKSB7CisgICAgICAgIGNvbHVtbnMgPSBuZXcgYnl0ZVtjb2x1bW5BcnJheS5sZW5ndGgoKV1bXTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5BcnJheS5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgY29sdW1uc1tpXSA9IEJ5dGVzLnRvQnl0ZXMoY29sdW1uQXJyYXkub3B0U3RyaW5nKGkpKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICByZXR1cm4gbmV3IFNjYW5uZXJEZXNjcmlwdG9yKGNvbHVtbnMsIHRpbWVzdGFtcCwgc3RhcnRSb3csIHN0b3BSb3csCisgICAgICAgICAgZmlsdGVycyk7CisgICAgfSBjYXRjaCAoSlNPTkV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKCJlcnJvciBwYXJzaW5nIGpzb24gc3RyaW5nIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlci5JSEJhc2VSZXN0UGFyc2VyI2dldFJvd1VwZGF0ZURlc2NyaXB0b3IKKyAgICogKGJ5dGVbXSwgYnl0ZVtdW10pCisgICAqLworICBwdWJsaWMgUm93VXBkYXRlRGVzY3JpcHRvciBnZXRSb3dVcGRhdGVEZXNjcmlwdG9yKGJ5dGVbXSBpbnB1dCwKKyAgICAgIGJ5dGVbXVtdIHBhdGhTZWdtZW50cykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBSb3dVcGRhdGVEZXNjcmlwdG9yIHJ1ZCA9IG5ldyBSb3dVcGRhdGVEZXNjcmlwdG9yKCk7CisgICAgSlNPTkFycmF5IGE7CisKKyAgICBydWQuc2V0VGFibGVOYW1lKEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1swXSkpOworICAgIHJ1ZC5zZXRSb3dOYW1lKEJ5dGVzLnRvU3RyaW5nKHBhdGhTZWdtZW50c1syXSkpOworCisgICAgdHJ5IHsKKyAgICAgIEpTT05PYmplY3QgdXBkYXRlT2JqZWN0ID0gbmV3IEpTT05PYmplY3QobmV3IFN0cmluZyhpbnB1dCkpOworICAgICAgYSA9IHVwZGF0ZU9iamVjdC5nZXRKU09OQXJyYXkoUkVTVENvbnN0YW50cy5DT0xVTU5TKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYS5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgIHJ1ZC5nZXRDb2xWYWxzKCkucHV0KAorICAgICAgICAgICAgQnl0ZXMudG9CeXRlcyhhLmdldEpTT05PYmplY3QoaSkuZ2V0U3RyaW5nKFJFU1RDb25zdGFudHMuTkFNRSkpLAorICAgICAgICAgICAgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CYXNlNjQuZGVjb2RlKGEuZ2V0SlNPTk9iamVjdChpKQorICAgICAgICAgICAgICAgIC5nZXRTdHJpbmcoUkVTVENvbnN0YW50cy5WQUxVRSkpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChKU09ORXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oIkVycm9yIHBhcnNpbmcgcm93IHVwZGF0ZSBqc29uIiwgZSk7CisgICAgfQorICAgIHJldHVybiBydWQ7CisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9wYXJzZXIvWE1MUmVzdFBhcnNlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9wYXJzZXIvWE1MUmVzdFBhcnNlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiYWI2NDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3BhcnNlci9YTUxSZXN0UGFyc2VyLmphdmEKQEAgLTAsMCArMSwyODkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnBhcnNlcjsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKKworaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKK2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy5Eb2N1bWVudEJ1aWxkZXJGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlJFU1RDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9ycy5Sb3dVcGRhdGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuU2Nhbm5lckRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CitpbXBvcnQgb3JnLnczYy5kb20uRWxlbWVudDsKK2ltcG9ydCBvcmcudzNjLmRvbS5Ob2RlOworaW1wb3J0IG9yZy53M2MuZG9tLk5vZGVMaXN0OworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgWE1MUmVzdFBhcnNlciBpbXBsZW1lbnRzIElIQmFzZVJlc3RQYXJzZXIgeworCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlciNnZXRUYWJsZURlc2NyaXB0b3IKKyAgICogKGJ5dGVbXSkKKyAgICovCisgIHB1YmxpYyBIVGFibGVEZXNjcmlwdG9yIGdldFRhYmxlRGVzY3JpcHRvcihieXRlW10gaW5wdXQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRvY0J1aWxkZXJGYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAubmV3SW5zdGFuY2UoKTsKKyAgICBkb2NCdWlsZGVyRmFjdG9yeS5zZXRJZ25vcmluZ0NvbW1lbnRzKHRydWUpOworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXIgPSBudWxsOworICAgIERvY3VtZW50IGRvYyA9IG51bGw7CisgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBudWxsOworCisgICAgdHJ5IHsKKyAgICAgIGJ1aWxkZXIgPSBkb2NCdWlsZGVyRmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKKyAgICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGlzID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgIGRvYyA9IGJ1aWxkZXIucGFyc2UoaXMpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKworICAgIHRyeSB7CisgICAgICBOb2RlIG5hbWVfbm9kZSA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpLml0ZW0oMCk7CisgICAgICBTdHJpbmcgdGFibGVfbmFtZSA9IG5hbWVfbm9kZS5nZXRGaXJzdENoaWxkKCkuZ2V0Tm9kZVZhbHVlKCk7CisKKyAgICAgIGh0ZCA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlX25hbWUpOworICAgICAgTm9kZUxpc3QgY29sdW1uZmFtaWx5X25vZGVzID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJjb2x1bW5mYW1pbHkiKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29sdW1uZmFtaWx5X25vZGVzLmdldExlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgRWxlbWVudCBjb2x1bW5mYW1pbHkgPSAoRWxlbWVudCkgY29sdW1uZmFtaWx5X25vZGVzLml0ZW0oaSk7CisgICAgICAgIGh0ZC5hZGRGYW1pbHkodGhpcy5nZXRDb2x1bW5EZXNjcmlwdG9yKGNvbHVtbmZhbWlseSkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUpOworICAgIH0KKyAgICByZXR1cm4gaHRkOworICB9CisKKyAgcHVibGljIEhDb2x1bW5EZXNjcmlwdG9yIGdldENvbHVtbkRlc2NyaXB0b3IoRWxlbWVudCBjb2x1bW5mYW1pbHkpIHsKKyAgICByZXR1cm4gdGhpcy5nZXRDb2x1bW5EZXNjcmlwdG9yKGNvbHVtbmZhbWlseSwgbnVsbCk7CisgIH0KKworICBwcml2YXRlIEhDb2x1bW5EZXNjcmlwdG9yIGdldENvbHVtbkRlc2NyaXB0b3IoRWxlbWVudCBjb2x1bW5mYW1pbHksCisgICAgICBIVGFibGVEZXNjcmlwdG9yIGN1cnJlbnRURGVzcCkgeworICAgIE5vZGUgbmFtZV9ub2RlID0gY29sdW1uZmFtaWx5LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJuYW1lIikuaXRlbSgwKTsKKyAgICBTdHJpbmcgY29sbmFtZSA9IG1ha2VDb2x1bW5OYW1lKG5hbWVfbm9kZS5nZXRGaXJzdENoaWxkKCkuZ2V0Tm9kZVZhbHVlKCkpOworCisgICAgaW50IG1heF92ZXJzaW9ucyA9IEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfVkVSU0lPTlM7CisgICAgU3RyaW5nIGNvbXByZXNzaW9uID0gSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9DT01QUkVTU0lPTjsKKyAgICBib29sZWFuIGluX21lbW9yeSA9IEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfSU5fTUVNT1JZOworICAgIGJvb2xlYW4gYmxvY2tfY2FjaGUgPSBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0JMT0NLQ0FDSEU7CisgICAgaW50IG1heF9jZWxsX3NpemUgPSBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0xFTkdUSDsKKyAgICBpbnQgdHRsID0gSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9UVEw7CisgICAgYm9vbGVhbiBibG9vbWZpbHRlciA9IEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQkxPT01GSUxURVI7CisKKyAgICBpZiAoY3VycmVudFREZXNwICE9IG51bGwpIHsKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yIGN1cnJlbnRDRGVzcCA9IGN1cnJlbnRURGVzcC5nZXRGYW1pbHkoQnl0ZXMKKyAgICAgICAgICAudG9CeXRlcyhjb2xuYW1lKSk7CisgICAgICBpZiAoY3VycmVudENEZXNwICE9IG51bGwpIHsKKyAgICAgICAgbWF4X3ZlcnNpb25zID0gY3VycmVudENEZXNwLmdldE1heFZlcnNpb25zKCk7CisgICAgICAgIC8vIGNvbXByZXNzaW9uID0gY3VycmVudENEZXNwLmdldENvbXByZXNzaW9uKCk7CisgICAgICAgIGluX21lbW9yeSA9IGN1cnJlbnRDRGVzcC5pc0luTWVtb3J5KCk7CisgICAgICAgIGJsb2NrX2NhY2hlID0gY3VycmVudENEZXNwLmlzQmxvY2tDYWNoZUVuYWJsZWQoKTsKKyAgICAgICAgbWF4X2NlbGxfc2l6ZSA9IGN1cnJlbnRDRGVzcC5nZXRNYXhWYWx1ZUxlbmd0aCgpOworICAgICAgICB0dGwgPSBjdXJyZW50Q0Rlc3AuZ2V0VGltZVRvTGl2ZSgpOworICAgICAgICBibG9vbWZpbHRlciA9IGN1cnJlbnRDRGVzcC5pc0Jsb29tZmlsdGVyKCk7CisgICAgICB9CisgICAgfQorCisgICAgTm9kZUxpc3QgbWF4X3ZlcnNpb25zX2xpc3QgPSBjb2x1bW5mYW1pbHkKKyAgICAgICAgLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJtYXgtdmVyc2lvbnMiKTsKKyAgICBpZiAobWF4X3ZlcnNpb25zX2xpc3QuZ2V0TGVuZ3RoKCkgPiAwKSB7CisgICAgICBtYXhfdmVyc2lvbnMgPSBJbnRlZ2VyLnBhcnNlSW50KG1heF92ZXJzaW9uc19saXN0Lml0ZW0oMCkuZ2V0Rmlyc3RDaGlsZCgpCisgICAgICAgICAgLmdldE5vZGVWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBOb2RlTGlzdCBjb21wcmVzc2lvbl9saXN0ID0gY29sdW1uZmFtaWx5CisgICAgICAgIC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiY29tcHJlc3Npb24iKTsKKyAgICBpZiAoY29tcHJlc3Npb25fbGlzdC5nZXRMZW5ndGgoKSA+IDApIHsKKyAgICAgIGNvbXByZXNzaW9uID0gY29tcHJlc3Npb25fbGlzdC5pdGVtKDApCisgICAgICAgICAgLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKS50b1VwcGVyQ2FzZSgpOworICAgIH0KKworICAgIE5vZGVMaXN0IGluX21lbW9yeV9saXN0ID0gY29sdW1uZmFtaWx5LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJpbi1tZW1vcnkiKTsKKyAgICBpZiAoaW5fbWVtb3J5X2xpc3QuZ2V0TGVuZ3RoKCkgPiAwKSB7CisgICAgICBpbl9tZW1vcnkgPSBCb29sZWFuLnZhbHVlT2YoaW5fbWVtb3J5X2xpc3QuaXRlbSgwKS5nZXRGaXJzdENoaWxkKCkKKyAgICAgICAgICAuZ2V0Tm9kZVZhbHVlKCkpOworICAgIH0KKworICAgIE5vZGVMaXN0IGJsb2NrX2NhY2hlX2xpc3QgPSBjb2x1bW5mYW1pbHkKKyAgICAgICAgLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJibG9jay1jYWNoZSIpOworICAgIGlmIChibG9ja19jYWNoZV9saXN0LmdldExlbmd0aCgpID4gMCkgeworICAgICAgYmxvY2tfY2FjaGUgPSBCb29sZWFuLnZhbHVlT2YoYmxvY2tfY2FjaGVfbGlzdC5pdGVtKDApLmdldEZpcnN0Q2hpbGQoKQorICAgICAgICAgIC5nZXROb2RlVmFsdWUoKSk7CisgICAgfQorCisgICAgTm9kZUxpc3QgbWF4X2NlbGxfc2l6ZV9saXN0ID0gY29sdW1uZmFtaWx5CisgICAgICAgIC5nZXRFbGVtZW50c0J5VGFnTmFtZSgibWF4LWNlbGwtc2l6ZSIpOworICAgIGlmIChtYXhfY2VsbF9zaXplX2xpc3QuZ2V0TGVuZ3RoKCkgPiAwKSB7CisgICAgICBtYXhfY2VsbF9zaXplID0gSW50ZWdlci52YWx1ZU9mKG1heF9jZWxsX3NpemVfbGlzdC5pdGVtKDApCisgICAgICAgICAgLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKSk7CisgICAgfQorCisgICAgTm9kZUxpc3QgdHRsX2xpc3QgPSBjb2x1bW5mYW1pbHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInRpbWUtdG8tbGl2ZSIpOworICAgIGlmICh0dGxfbGlzdC5nZXRMZW5ndGgoKSA+IDApIHsKKyAgICAgIHR0bCA9IEludGVnZXIudmFsdWVPZih0dGxfbGlzdC5pdGVtKDApLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKSk7CisgICAgfQorCisgICAgTm9kZUxpc3QgYmxvb21maWx0ZXJfbGlzdCA9IGNvbHVtbmZhbWlseQorICAgICAgICAuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImJsb29tZmlsdGVyIik7CisgICAgaWYgKGJsb29tZmlsdGVyX2xpc3QuZ2V0TGVuZ3RoKCkgPiAwKSB7CisgICAgICBibG9vbWZpbHRlciA9IEJvb2xlYW4udmFsdWVPZihibG9vbWZpbHRlcl9saXN0Lml0ZW0oMCkuZ2V0Rmlyc3RDaGlsZCgpCisgICAgICAgICAgLmdldE5vZGVWYWx1ZSgpKTsKKyAgICB9CisKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBoY2QgPSBuZXcgSENvbHVtbkRlc2NyaXB0b3IoQnl0ZXMudG9CeXRlcyhjb2xuYW1lKSwKKyAgICAgICAgbWF4X3ZlcnNpb25zLCBjb21wcmVzc2lvbiwgaW5fbWVtb3J5LCBibG9ja19jYWNoZSwKKyAgICAgICAgbWF4X2NlbGxfc2l6ZSwgdHRsLCBibG9vbWZpbHRlcik7CisKKyAgICBOb2RlTGlzdCBtZXRhZGF0YUxpc3QgPSBjb2x1bW5mYW1pbHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIm1ldGFkYXRhIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRhZGF0YUxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgRWxlbWVudCBtZXRhZGF0YUNvbHVtbiA9IChFbGVtZW50KSBtZXRhZGF0YUxpc3QuaXRlbShpKTsKKyAgICAgIC8vIGV4dHJhY3QgdGhlIG5hbWUgYW5kIHZhbHVlIGNoaWxkcmVuCisgICAgICBOb2RlIG1uYW1lX25vZGUgPSBtZXRhZGF0YUNvbHVtbi5nZXRFbGVtZW50c0J5VGFnTmFtZSgibmFtZSIpLml0ZW0oMCk7CisgICAgICBTdHJpbmcgbW5hbWUgPSBtbmFtZV9ub2RlLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIE5vZGUgbXZhbHVlX25vZGUgPSBtZXRhZGF0YUNvbHVtbi5nZXRFbGVtZW50c0J5VGFnTmFtZSgidmFsdWUiKS5pdGVtKDApOworICAgICAgU3RyaW5nIG12YWx1ZSA9IG12YWx1ZV9ub2RlLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIGhjZC5zZXRWYWx1ZShtbmFtZSwgbXZhbHVlKTsKKyAgICB9CisKKyAgICByZXR1cm4gaGNkOworICB9CisKKyAgcHJvdGVjdGVkIFN0cmluZyBtYWtlQ29sdW1uTmFtZShTdHJpbmcgY29sdW1uKSB7CisgICAgU3RyaW5nIHJldHVybkNvbHVtbiA9IGNvbHVtbjsKKyAgICBpZiAoY29sdW1uLmluZGV4T2YoJzonKSA9PSAtMSkKKyAgICAgIHJldHVybkNvbHVtbiArPSAnOic7CisgICAgcmV0dXJuIHJldHVybkNvbHVtbjsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlciNnZXRDb2x1bW5EZXNjcmlwdG9ycworICAgKiAoYnl0ZVtdKQorICAgKi8KKyAgcHVibGljIEFycmF5TGlzdDxIQ29sdW1uRGVzY3JpcHRvcj4gZ2V0Q29sdW1uRGVzY3JpcHRvcnMoYnl0ZVtdIGlucHV0KQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgRG9jdW1lbnRCdWlsZGVyRmFjdG9yeSBkb2NCdWlsZGVyRmFjdG9yeSA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkKKyAgICAgICAgLm5ld0luc3RhbmNlKCk7CisgICAgZG9jQnVpbGRlckZhY3Rvcnkuc2V0SWdub3JpbmdDb21tZW50cyh0cnVlKTsKKworICAgIERvY3VtZW50QnVpbGRlciBidWlsZGVyID0gbnVsbDsKKyAgICBEb2N1bWVudCBkb2MgPSBudWxsOworICAgIEFycmF5TGlzdDxIQ29sdW1uRGVzY3JpcHRvcj4gY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8SENvbHVtbkRlc2NyaXB0b3I+KCk7CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlciA9IGRvY0J1aWxkZXJGYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgZG9jID0gYnVpbGRlci5wYXJzZShpcyk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZSk7CisgICAgfQorCisgICAgTm9kZUxpc3QgY29sdW1uZmFtaWx5X25vZGVzID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJjb2x1bW5mYW1pbHkiKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHVtbmZhbWlseV9ub2Rlcy5nZXRMZW5ndGgoKTsgaSsrKSB7CisgICAgICBFbGVtZW50IGNvbHVtbmZhbWlseSA9IChFbGVtZW50KSBjb2x1bW5mYW1pbHlfbm9kZXMuaXRlbShpKTsKKyAgICAgIGNvbHVtbnMuYWRkKHRoaXMuZ2V0Q29sdW1uRGVzY3JpcHRvcihjb2x1bW5mYW1pbHkpKTsKKyAgICB9CisKKyAgICByZXR1cm4gY29sdW1uczsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlciNnZXRTY2FubmVyRGVzY3JpcHRvcgorICAgKiAoYnl0ZVtdKQorICAgKi8KKyAgcHVibGljIFNjYW5uZXJEZXNjcmlwdG9yIGdldFNjYW5uZXJEZXNjcmlwdG9yKGJ5dGVbXSBpbnB1dCkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5wYXJzZXIuSUhCYXNlUmVzdFBhcnNlciNnZXRSb3dVcGRhdGVEZXNjcmlwdG9yCisgICAqIChieXRlW10sIGJ5dGVbXVtdKQorICAgKi8KKyAgcHVibGljIFJvd1VwZGF0ZURlc2NyaXB0b3IgZ2V0Um93VXBkYXRlRGVzY3JpcHRvcihieXRlW10gaW5wdXQsCisgICAgICBieXRlW11bXSBwYXRoU2VnbWVudHMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIFJvd1VwZGF0ZURlc2NyaXB0b3IgcnVkID0gbmV3IFJvd1VwZGF0ZURlc2NyaXB0b3IoKTsKKworICAgIHJ1ZC5zZXRUYWJsZU5hbWUoQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzBdKSk7CisgICAgcnVkLnNldFJvd05hbWUoQnl0ZXMudG9TdHJpbmcocGF0aFNlZ21lbnRzWzJdKSk7CisKKyAgICBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGRvY0J1aWxkZXJGYWN0b3J5ID0gRG9jdW1lbnRCdWlsZGVyRmFjdG9yeQorICAgICAgICAubmV3SW5zdGFuY2UoKTsKKyAgICBkb2NCdWlsZGVyRmFjdG9yeS5zZXRJZ25vcmluZ0NvbW1lbnRzKHRydWUpOworCisgICAgRG9jdW1lbnRCdWlsZGVyIGJ1aWxkZXIgPSBudWxsOworICAgIERvY3VtZW50IGRvYyA9IG51bGw7CisKKyAgICB0cnkgeworICAgICAgYnVpbGRlciA9IGRvY0J1aWxkZXJGYWN0b3J5Lm5ld0RvY3VtZW50QnVpbGRlcigpOworICAgICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgZG9jID0gYnVpbGRlci5wYXJzZShpcyk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBIQmFzZVJlc3RFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCksIGUpOworICAgIH0KKworICAgIE5vZGVMaXN0IGNlbGxfbm9kZXMgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoUkVTVENvbnN0YW50cy5DT0xVTU4pOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY2VsbF9ub2Rlcy5sZW5ndGg6ICIgKyBjZWxsX25vZGVzLmdldExlbmd0aCgpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNlbGxfbm9kZXMuZ2V0TGVuZ3RoKCk7IGkrKykgeworICAgICAgU3RyaW5nIGNvbHVtbk5hbWUgPSBudWxsOworICAgICAgYnl0ZVtdIHZhbHVlID0gbnVsbDsKKworICAgICAgRWxlbWVudCBjZWxsID0gKEVsZW1lbnQpIGNlbGxfbm9kZXMuaXRlbShpKTsKKworICAgICAgTm9kZUxpc3QgaXRlbSA9IGNlbGwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoUkVTVENvbnN0YW50cy5OQU1FKTsKKyAgICAgIGlmIChpdGVtLmdldExlbmd0aCgpID4gMCkgeworICAgICAgICBjb2x1bW5OYW1lID0gaXRlbS5pdGVtKDApLmdldEZpcnN0Q2hpbGQoKS5nZXROb2RlVmFsdWUoKTsKKyAgICAgIH0KKworICAgICAgTm9kZUxpc3QgaXRlbTEgPSBjZWxsLmdldEVsZW1lbnRzQnlUYWdOYW1lKFJFU1RDb25zdGFudHMuVkFMVUUpOworICAgICAgaWYgKGl0ZW0xLmdldExlbmd0aCgpID4gMCkgeworICAgICAgICB2YWx1ZSA9IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQmFzZTY0LmRlY29kZShpdGVtMQorICAgICAgICAgICAgLml0ZW0oMCkuZ2V0Rmlyc3RDaGlsZCgpLmdldE5vZGVWYWx1ZSgpKTsKKyAgICAgIH0KKworICAgICAgaWYgKGNvbHVtbk5hbWUgIT0gbnVsbCAmJiB2YWx1ZSAhPSBudWxsKSB7CisgICAgICAgIHJ1ZC5nZXRDb2xWYWxzKCkucHV0KGNvbHVtbk5hbWUuZ2V0Qnl0ZXMoKSwgdmFsdWUpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcnVkOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvQWJzdHJhY3RSZXN0U2VyaWFsaXplci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9zZXJpYWxpemVyL0Fic3RyYWN0UmVzdFNlcmlhbGl6ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2JlMWM3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9zZXJpYWxpemVyL0Fic3RyYWN0UmVzdFNlcmlhbGl6ZXIuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyOworCitpbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVzcG9uc2U7CisKKy8qKgorICogCisgKiAgICAgICAgIEFic3RyYWN0IG9iamVjdCB0aGF0IGlzIHVzZWQgYXMgdGhlIGJhc2Ugb2YgYWxsIHNlcmlhbGl6ZXJzIGluIHRoZQorICogICAgICAgICBSRVNUIGJhc2VkIGludGVyZmFjZS4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0UmVzdFNlcmlhbGl6ZXIgaW1wbGVtZW50cyBJUmVzdFNlcmlhbGl6ZXIgeworCisgIC8vIGtlZXAgdGhlIHJlc3BvbnNlIG9iamVjdCB0byB3cml0ZSBiYWNrIHRvIHRoZSBzdHJlYW0KKyAgcHJvdGVjdGVkIGZpbmFsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2U7CisgIC8vIFVzZWQgdG8gZGVub3RlIGlmIHByZXR0eSBwcmludGluZyBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSB1c2VkCisgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIHByZXR0eVByaW50OworCisgIC8qKgorICAgKiBtYXJraW5nIHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yIGFzIHByaXZhdGUgc28gaXQgd2lsbCBuZXZlciBiZSB1c2VkLgorICAgKi8KKyAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgIHByaXZhdGUgQWJzdHJhY3RSZXN0U2VyaWFsaXplcigpIHsKKyAgICByZXNwb25zZSA9IG51bGw7CisgICAgcHJldHR5UHJpbnQgPSBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBQdWJsaWMgY29uc3RydWN0b3IgZm9yIEFic3RyYWN0UmVzdFNlcmlhbGl6ZXIuIFRoaXMgaXMgdGhlIGNvbnN0cnVjdG9yIHRoYXQKKyAgICogc2hvdWxkIGJlIGNhbGxlZCB3aGVuZXZlciBjcmVhdGluZyBhIFJlc3RTZXJpYWxpemVyIG9iamVjdC4KKyAgICogCisgICAqIEBwYXJhbSByZXNwb25zZQorICAgKiBAcGFyYW0gcHJldHR5UHJpbnQgCisgICAqLworICBwdWJsaWMgQWJzdHJhY3RSZXN0U2VyaWFsaXplcihIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlLAorICAgICAgYm9vbGVhbiBwcmV0dHlQcmludCkgeworICAgIHN1cGVyKCk7CisgICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlOworICAgIHRoaXMucHJldHR5UHJpbnQgPSBwcmV0dHlQcmludDsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvSVJlc3RTZXJpYWxpemVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvSVJlc3RTZXJpYWxpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTkxZGIzNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9JUmVzdFNlcmlhbGl6ZXIuamF2YQpAQCAtMCwwICsxLDE3MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5EYXRhYmFzZU1vZGVsLkRhdGFiYXNlTWV0YWRhdGE7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5TdGF0dXMuU3RhdHVzTWVzc2FnZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlRhYmxlTW9kZWwuUmVnaW9uczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlNjYW5uZXJJZGVudGlmaWVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuVGltZXN0YW1wc0Rlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5leGNlcHRpb24uSEJhc2VSZXN0RXhjZXB0aW9uOworCisvKioKKyAqIAorICogICAgICAgICBJbnRlcmZhY2UgdGhhdCBpcyBpbXBsZW1lbnRlZCB0byByZXR1cm4gc2VyaWFsaXplZCBvYmplY3RzIGJhY2sgdG8KKyAqICAgICAgICAgdGhlIG91dHB1dCBzdHJlYW0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSVJlc3RTZXJpYWxpemVyIHsKKyAgLyoqCisgICAqIFNlcmlhbGl6ZXMgYW4gb2JqZWN0IGludG8gdGhlIGFwcHJvcHJpYXRlIGZvcm1hdCBhbmQgd3JpdGVzIGl0IHRvIHRoZQorICAgKiBvdXRwdXQgc3RyZWFtLgorICAgKiAKKyAgICogVGhpcyBpcyB0aGUgbWFpbiBwb2ludCBvZiBlbnRyeSB3aGVuIGZvciBhbiBvYmplY3QgdG8gYmUgc2VyaWFsaXplZCB0byB0aGUKKyAgICogb3V0cHV0IHN0cmVhbS4KKyAgICogCisgICAqIEBwYXJhbSBvCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZU91dHB1dChPYmplY3QgbykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICAvKioKKyAgICogc2VyaWFsaXplIHRoZSBkYXRhYmFzZSBtZXRhZGF0YQorICAgKiAKKyAgICogSW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgaXMgb3B0aW9uYWwsIElGIGFsbCB0aGUgd29yayBpcyBkb25lIGluIHRoZQorICAgKiB3cml0ZU91dHB1dChPYmplY3QgbykgbWV0aG9kCisgICAqIAorICAgKiBAcGFyYW0gZGF0YWJhc2VNZXRhZGF0YQorICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplRGF0YWJhc2VNZXRhZGF0YShEYXRhYmFzZU1ldGFkYXRhIGRhdGFiYXNlTWV0YWRhdGEpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uOworCisgIC8qKgorICAgKiBzZXJpYWxpemUgdGhlIEhUYWJsZURlc2NyaXB0b3Igb2JqZWN0CisgICAqIAorICAgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyBvcHRpb25hbCwgSUYgYWxsIHRoZSB3b3JrIGlzIGRvbmUgaW4gdGhlCisgICAqIHdyaXRlT3V0cHV0KE9iamVjdCBvKSBtZXRob2QKKyAgICogCisgICAqIEBwYXJhbSB0YWJsZURlc2NyaXB0b3IKKyAgICogQHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVRhYmxlRGVzY3JpcHRvcihIVGFibGVEZXNjcmlwdG9yIHRhYmxlRGVzY3JpcHRvcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgLyoqCisgICAqIHNlcmlhbGl6ZSBhbiBIQ29sdW1uRGVzY3JpcHRvciB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICogCisgICAqIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIG9wdGlvbmFsLCBJRiBhbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiB0aGUKKyAgICogd3JpdGVPdXRwdXQoT2JqZWN0IG8pIG1ldGhvZAorICAgKiAKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplQ29sdW1uRGVzY3JpcHRvcihIQ29sdW1uRGVzY3JpcHRvciBjb2x1bW4pCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uOworCisgIC8qKgorICAgKiBzZXJpYWxpemUgdGhlIHJlZ2lvbiBkYXRhIGZvciBhIHRhYmxlIHRvIHRoZSBvdXRwdXQgc3RyZWFtCisgICAqIAorICAgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyBvcHRpb25hbCwgSUYgYWxsIHRoZSB3b3JrIGlzIGRvbmUgaW4gdGhlCisgICAqIHdyaXRlT3V0cHV0KE9iamVjdCBvKSBtZXRob2QKKyAgICogCisgICAqIEBwYXJhbSByZWdpb25zCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVSZWdpb25EYXRhKFJlZ2lvbnMgcmVnaW9ucykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICAvKioKKyAgICogc2VyaWFsaXplIHRoZSBzdGF0dXMgbWVzc2FnZSBvYmplY3QgdG8gdGhlIG91dHB1dCBzdHJlYW0KKyAgICogCisgICAqIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIG9wdGlvbmFsLCBJRiBhbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiB0aGUKKyAgICogd3JpdGVPdXRwdXQoT2JqZWN0IG8pIG1ldGhvZAorICAgKiAKKyAgICogQHBhcmFtIG1lc3NhZ2UKKyAgICogQHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVN0YXR1c01lc3NhZ2UoU3RhdHVzTWVzc2FnZSBtZXNzYWdlKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKworICAvKioKKyAgICogc2VyaWFsaXplIHRoZSBTY2FubmVySWRlbnRpZmllciBvYmplY3QgdG8gdGhlIG91dHB1dCBzdHJlYW0KKyAgICogCisgICAqIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIG9wdGlvbmFsLCBJRiBhbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiB0aGUKKyAgICogd3JpdGVPdXRwdXQoT2JqZWN0IG8pIG1ldGhvZAorICAgKiAKKyAgICogQHBhcmFtIHNjYW5uZXJJZGVudGlmaWVyCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVTY2FubmVySWRlbnRpZmllcihTY2FubmVySWRlbnRpZmllciBzY2FubmVySWRlbnRpZmllcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgLyoqCisgICAqIHNlcmlhbGl6ZSBhIFJvd1Jlc3VsdCBvYmplY3QgdG8gdGhlIG91dHB1dCBzdHJlYW0KKyAgICogCisgICAqIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGlzIG9wdGlvbmFsLCBJRiBhbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiB0aGUKKyAgICogd3JpdGVPdXRwdXQoT2JqZWN0IG8pIG1ldGhvZAorICAgKiAKKyAgICogQHBhcmFtIHJvd1Jlc3VsdAorICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplUm93UmVzdWx0KFJvd1Jlc3VsdCByb3dSZXN1bHQpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgLyoqCisgICAqIHNlcmlhbGl6ZSBhIFJvd1Jlc3VsdCBhcnJheSB0byB0aGUgb3V0cHV0IHN0cmVhbQorICAgKiAKKyAgICogSW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgaXMgb3B0aW9uYWwsIElGIGFsbCB0aGUgd29yayBpcyBkb25lIGluIHRoZQorICAgKiB3cml0ZU91dHB1dChPYmplY3QgbykgbWV0aG9kCisgICAqIAorICAgKiBAcGFyYW0gcm93cworICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplUm93UmVzdWx0QXJyYXkoUm93UmVzdWx0W10gcm93cykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisKKyAgLyoqCisgICAqIHNlcmlhbGl6ZSBhIGNlbGwgb2JqZWN0IHRvIHRoZSBvdXRwdXQgc3RyZWFtCisgICAqIAorICAgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyBvcHRpb25hbCwgSUYgYWxsIHRoZSB3b3JrIGlzIGRvbmUgaW4gdGhlCisgICAqIHdyaXRlT3V0cHV0KE9iamVjdCBvKSBtZXRob2QKKyAgICogCisgICAqIEBwYXJhbSBjZWxsCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVDZWxsKENlbGwgY2VsbCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbjsKKyAgCisgIC8qKgorICAgKiBzZXJpYWxpemUgYSBDZWxsIGFycmF5IHRvIHRoZSBvdXRwdXQgc3RyZWFtCisgICAqIAorICAgKiBAcGFyYW0gY2VsbHMKKyAgICogQHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZUNlbGxBcnJheShDZWxsW10gY2VsbHMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247CisgIAorICAKKyAgLyoqCisgICAqIHNlcmlhbGl6ZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSB0aW1lc3RhbXBzIGF2YWlsYWJsZSBmb3IgYSByb3cgCisgICAqIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorICAgKiAKKyAgICogQHBhcmFtIHRpbWVzdGFtcHNEZXNjcmlwdG9yCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVUaW1lc3RhbXBzKFRpbWVzdGFtcHNEZXNjcmlwdG9yIHRpbWVzdGFtcHNEZXNjcmlwdG9yKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uOworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9zZXJpYWxpemVyL0lTZXJpYWxpemFibGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9JU2VyaWFsaXphYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQ4Mjg1NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9JU2VyaWFsaXphYmxlLmphdmEKQEAgLTAsMCArMSw0MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKKworLyoqCisgKiAKKyAqICAgICAgICAgSW50ZXJmYWNlIGZvciBvYmplY3RzIHRoYXQgd2lzaCB0byB3cml0ZSBiYWNrIHRvIHRoZSBSRVNUIGJhc2VkCisgKiAgICAgICAgIGludGVyZmFjZSBvdXRwdXQgc3RyZWFtLiBPYmplY3RzIHNob3VsZCBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UsCisgKiAgICAgICAgIHRoZW4gdXNlIHRoZSBJUmVzdFNlcmlhbGl6ZXIgcGFzc2VkIHRvIGl0IHRvIGNhbGwgdGhlIGFwcHJvcHJpYXRlCisgKiAgICAgICAgIHNlcmlhbGl6YXRpb24gbWV0aG9kLgorICovCitwdWJsaWMgaW50ZXJmYWNlIElTZXJpYWxpemFibGUgeworICAvKioKKyAgICogdmlzaXRvciBwYXR0ZXJuIG1ldGhvZCB3aGVyZSB0aGUgb2JqZWN0IGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSB3aWxsCisgICAqIGNhbGwgYmFjayBvbiB0aGUgSVJlc3RTZXJpYWxpemVyIHdpdGggdGhlIGNvcnJlY3QgbWV0aG9kIHRvIHJ1biB0bworICAgKiBzZXJpYWxpemUgdGhlIG91dHB1dCBvZiB0aGUgb2JqZWN0IHRvIHRoZSBzdHJlYW0uCisgICAqIAorICAgKiBAcGFyYW0gc2VyaWFsaXplcgorICAgKiBAdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgcmVzdFNlcmlhbGl6ZShJUmVzdFNlcmlhbGl6ZXIgc2VyaWFsaXplcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvSlNPTlNlcmlhbGl6ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9KU09OU2VyaWFsaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1NGRmOGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvSlNPTlNlcmlhbGl6ZXIuamF2YQpAQCAtMCwwICsxLDIxMyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplcjsKKworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LkRhdGFiYXNlTW9kZWwuRGF0YWJhc2VNZXRhZGF0YTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlN0YXR1cy5TdGF0dXNNZXNzYWdlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuVGFibGVNb2RlbC5SZWdpb25zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuU2Nhbm5lcklkZW50aWZpZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9ycy5UaW1lc3RhbXBzRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CisKK2ltcG9ydCBhZ2lsZWpzb24uSlNPTjsKKworLyoqCisgKiAKKyAqIFNlcmlhbGl6ZXMgb2JqZWN0cyBpbnRvIEpTT04gc3RyaW5ncyBhbmQgcHJpbnRzIHRoZW0gYmFjayBvdXQgb24gdGhlIG91dHB1dAorICogc3RyZWFtLiBJdCBzaG91bGQgYmUgbm90ZWQgdGhhdCB0aGlzIEpTT04gaW1wbGVtZW50YXRpb24gdXNlcyBhbm5vdGF0aW9ucyBvbgorICogdGhlIG9iamVjdHMgdG8gYmUgc2VyaWFsaXplZC4KKyAqIAorICogU2luY2UgdGhlc2UgYW5ub3RhdGlvbnMgYXJlIHVzZWQgdG8gZGVzY3JpYmUgdGhlIHNlcmlhbGl6YXRpb24gb2YgdGhlIG9iamVjdHMKKyAqIHRoZSBvbmx5IG1ldGhvZCB0aGF0IGlzIGltcGxlbWVudGVkIGlzIHdyaXRlT3V0cHV0KE9iamVjdCBvKS4gVGhlIG90aGVyCisgKiBtZXRob2RzIGluIHRoZSBpbnRlcmZhY2UgZG8gbm90IG5lZWQgdG8gYmUgaW1wbGVtZW50ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBKU09OU2VyaWFsaXplciBleHRlbmRzIEFic3RyYWN0UmVzdFNlcmlhbGl6ZXIgeworCisgIC8qKgorICAgKiBAcGFyYW0gcmVzcG9uc2UKKyAgICovCisgIHB1YmxpYyBKU09OU2VyaWFsaXplcihIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKSB7CisgICAgc3VwZXIocmVzcG9uc2UsIGZhbHNlKTsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciN3cml0ZU91dHB1dChqYXZhCisgICAqIC5sYW5nLk9iamVjdCwgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVzcG9uc2UpCisgICAqLworICBwdWJsaWMgdm9pZCB3cml0ZU91dHB1dChPYmplY3QgbykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoImFwcGxpY2F0aW9uL2pzb24iKTsKKworICAgIHRyeSB7CisgICAgICAvLyBMT0cuZGVidWcoIkF0IHRvcCBvZiBzZW5kIGRhdGEiKTsKKyAgICAgIFN0cmluZyBkYXRhID0gSlNPTi50b0pTT04obyk7CisgICAgICByZXNwb25zZS5zZXRDb250ZW50TGVuZ3RoKGRhdGEubGVuZ3RoKCkpOworICAgICAgcmVzcG9uc2UuZ2V0V3JpdGVyKCkucHJpbnRsbihkYXRhKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgLy8gTE9HLmRlYnVnKCJFcnJvciBzZW5kaW5nIGRhdGE6ICIgKyBlLnRvU3RyaW5nKCkpOworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbihlKTsKKyAgICB9CisKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWVvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyIworICAgKiBzZXJpYWxpemVDb2x1bW5EZXNjcmlwdG9yKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplQ29sdW1uRGVzY3JpcHRvcihIQ29sdW1uRGVzY3JpcHRvciBjb2x1bW4pCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZW9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjCisgICAqIHNlcmlhbGl6ZURhdGFiYXNlTWV0YWRhdGEKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuRGF0YWJhc2VNb2RlbC5EYXRhYmFzZU1ldGFkYXRhKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplRGF0YWJhc2VNZXRhZGF0YShEYXRhYmFzZU1ldGFkYXRhIGRhdGFiYXNlTWV0YWRhdGEpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyI3NlcmlhbGl6ZVJlZ2lvbkRhdGEKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuVGFibGVNb2RlbC5SZWdpb25zKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplUmVnaW9uRGF0YShSZWdpb25zIHJlZ2lvbnMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIE5vIGltcGxlbWVudGF0aW9uIG5lZWRlZCBmb3IgdGhlIEpTT04gc2VyaWFsaXplcgorCisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2Vlb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciMKKyAgICogc2VyaWFsaXplVGFibGVEZXNjcmlwdG9yKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3IpCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVUYWJsZURlc2NyaXB0b3IoSFRhYmxlRGVzY3JpcHRvciB0YWJsZURlc2NyaXB0b3IpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyI3NlcmlhbGl6ZVN0YXR1c01lc3NhZ2UKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuU3RhdHVzLlN0YXR1c01lc3NhZ2UpCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVTdGF0dXNNZXNzYWdlKFN0YXR1c01lc3NhZ2UgbWVzc2FnZSkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIE5vIGltcGxlbWVudGF0aW9uIG5lZWRlZCBmb3IgdGhlIEpTT04gc2VyaWFsaXplcgorCisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2Vlb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciMKKyAgICogc2VyaWFsaXplU2Nhbm5lcklkZW50aWZpZXIob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5TY2FubmVySWRlbnRpZmllcikKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVNjYW5uZXJJZGVudGlmaWVyKFNjYW5uZXJJZGVudGlmaWVyIHNjYW5uZXJJZGVudGlmaWVyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgLy8gTm8gaW1wbGVtZW50YXRpb24gbmVlZGVkIGZvciB0aGUgSlNPTiBzZXJpYWxpemVyCisKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciNzZXJpYWxpemVSb3dSZXN1bHQKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdCkKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVJvd1Jlc3VsdChSb3dSZXN1bHQgcm93UmVzdWx0KSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyI3NlcmlhbGl6ZVJvd1Jlc3VsdEFycmF5CisgICAqIChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHRbXSkKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVJvd1Jlc3VsdEFycmF5KFJvd1Jlc3VsdFtdIHJvd3MpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyI3NlcmlhbGl6ZUNlbGwob3JnCisgICAqIC5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGwpCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVDZWxsKENlbGwgY2VsbCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgLy8gTm8gaW1wbGVtZW50YXRpb24gbmVlZGVkIGZvciB0aGUgSlNPTiBzZXJpYWxpemVyCisKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciNzZXJpYWxpemVDZWxsQXJyYXkKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGxbXSkKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZUNlbGxBcnJheShDZWxsW10gY2VsbHMpIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIE5vIGltcGxlbWVudGF0aW9uIG5lZWRlZCBmb3IgdGhlIEpTT04gc2VyaWFsaXplcgorCisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjc2VyaWFsaXplVGltZXN0YW1wcworICAgKiAob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5Sb3dNb2RlbC5UaW1lc3RhbXBzRGVzY3JpcHRvcikKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVRpbWVzdGFtcHMoVGltZXN0YW1wc0Rlc2NyaXB0b3IgdGltZXN0YW1wc0Rlc2NyaXB0b3IpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAvLyBObyBpbXBsZW1lbnRhdGlvbiBuZWVkZWQgZm9yIHRoZSBKU09OIHNlcmlhbGl6ZXIKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvUmVzdFNlcmlhbGl6ZXJGYWN0b3J5LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZXN0L3NlcmlhbGl6ZXIvUmVzdFNlcmlhbGl6ZXJGYWN0b3J5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTI4NGRhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9SZXN0U2VyaWFsaXplckZhY3RvcnkuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyOworCitpbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVxdWVzdDsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuRGlzcGF0Y2hlci5Db250ZW50VHlwZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmV4Y2VwdGlvbi5IQmFzZVJlc3RFeGNlcHRpb247CisKKy8qKgorICogCisgKiAgICAgICAgIEZhY3RvcnkgdXNlZCB0byByZXR1cm4gYSBSZXN0IFNlcmlhbGl6ZXIgdGFpbG9yZWQgdG8gdGhlIEhUVFAKKyAqICAgICAgICAgUmVxdWVzdGVycyBhY2NlcHQgdHlwZSBpbiB0aGUgaGVhZGVyLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBSZXN0U2VyaWFsaXplckZhY3RvcnkgeworCisgIHB1YmxpYyBzdGF0aWMgQWJzdHJhY3RSZXN0U2VyaWFsaXplciBnZXRTZXJpYWxpemVyKAorICAgICAgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBDb250ZW50VHlwZSBjdCA9IENvbnRlbnRUeXBlLmdldENvbnRlbnRUeXBlKHJlcXVlc3QuZ2V0SGVhZGVyKCJhY2NlcHQiKSk7CisgICAgQWJzdHJhY3RSZXN0U2VyaWFsaXplciBzZXJpYWxpemVyID0gbnVsbDsKKworICAgIC8vIFRPRE8gcmVmYWN0b3IgdGhpcyBzbyBpdCB1c2VzIHJlZmxlY3Rpb24gdG8gY3JlYXRlIHRoZSBuZXcgb2JqZWN0cy4KKyAgICBzd2l0Y2ggKGN0KSB7CisgICAgY2FzZSBYTUw6CisgICAgICBzZXJpYWxpemVyID0gbmV3IFNpbXBsZVhNTFNlcmlhbGl6ZXIocmVzcG9uc2UpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKU09OOgorICAgICAgc2VyaWFsaXplciA9IG5ldyBKU09OU2VyaWFsaXplcihyZXNwb25zZSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgc2VyaWFsaXplciA9IG5ldyBTaW1wbGVYTUxTZXJpYWxpemVyKHJlc3BvbnNlKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICByZXR1cm4gc2VyaWFsaXplcjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVzdC9zZXJpYWxpemVyL1NpbXBsZVhNTFNlcmlhbGl6ZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9TaW1wbGVYTUxTZXJpYWxpemVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTJiMzBhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3Jlc3Qvc2VyaWFsaXplci9TaW1wbGVYTUxTZXJpYWxpemVyLmphdmEKQEAgLTAsMCArMSw0NjQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CisKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LkRhdGFiYXNlTW9kZWwuRGF0YWJhc2VNZXRhZGF0YTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlN0YXR1cy5TdGF0dXNNZXNzYWdlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuVGFibGVNb2RlbC5SZWdpb25zOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZGVzY3JpcHRvcnMuUmVzdENlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5kZXNjcmlwdG9ycy5TY2FubmVySWRlbnRpZmllcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LmRlc2NyaXB0b3JzLlRpbWVzdGFtcHNEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3QuZXhjZXB0aW9uLkhCYXNlUmVzdEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIAorICogQmFzaWMgZmlyc3QgcGFzcyBhdCBpbXBsZW1lbnRpbmcgYW4gWE1MIHNlcmlhbGl6ZXIgZm9yIHRoZSBSRVNUIGludGVyZmFjZS4KKyAqIFRoaXMgc2hvdWxkIHByb2JhYmx5IGJlIHJlZmFjdG9yZWQgaW50byBzb21ldGhpbmcgYmV0dGVyLgorICogCisgKi8KK3B1YmxpYyBjbGFzcyBTaW1wbGVYTUxTZXJpYWxpemVyIGV4dGVuZHMgQWJzdHJhY3RSZXN0U2VyaWFsaXplciB7CisKKyAgcHJpdmF0ZSBmaW5hbCBBYnN0cmFjdFByaW50ZXIgcHJpbnRlcjsKKworICAvKioKKyAgICogQHBhcmFtIHJlc3BvbnNlCisgICAqIEB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCisgIHB1YmxpYyBTaW1wbGVYTUxTZXJpYWxpemVyKEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzdXBlcihyZXNwb25zZSwgZmFsc2UpOworICAgIHByaW50ZXIgPSBuZXcgU2ltcGxlUHJpbnRlcihyZXNwb25zZSk7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCisgIHB1YmxpYyBTaW1wbGVYTUxTZXJpYWxpemVyKEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UsIGJvb2xlYW4gcHJldHR5UHJpbnQpCisgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBzdXBlcihyZXNwb25zZSwgcHJldHR5UHJpbnQpOworICAgIGlmIChwcmV0dHlQcmludCkgeworICAgICAgcHJpbnRlciA9IG5ldyBQcmV0dHlQcmludGVyKHJlc3BvbnNlKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlciA9IG5ldyBTaW1wbGVQcmludGVyKHJlc3BvbnNlKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjd3JpdGVPdXRwdXQoamF2YQorICAgKiAubGFuZy5PYmplY3QsIGphdmEuaW8uT3V0cHV0U3RyZWFtKQorICAgKi8KKyAgcHVibGljIHZvaWQgd3JpdGVPdXRwdXQoT2JqZWN0IG8pIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L3htbCIpOworICAgIHJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKEhDb25zdGFudHMuVVRGOF9FTkNPRElORyk7CisKKyAgICBpZiAobyBpbnN0YW5jZW9mIElTZXJpYWxpemFibGUpIHsKKyAgICAgICgoSVNlcmlhbGl6YWJsZSkgbykucmVzdFNlcmlhbGl6ZSh0aGlzKTsKKyAgICB9IGVsc2UgaWYgKG8uZ2V0Q2xhc3MoKS5pc0FycmF5KCkKKyAgICAgICAgJiYgby5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKSA9PSBSb3dSZXN1bHQuY2xhc3MpIHsKKyAgICAgIHRoaXMuc2VyaWFsaXplUm93UmVzdWx0QXJyYXkoKFJvd1Jlc3VsdFtdKSBvKTsKKyAgICB9IGVsc2UgaWYgKG8uZ2V0Q2xhc3MoKS5pc0FycmF5KCkKKyAgICAgICAgJiYgby5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKSA9PSBDZWxsLmNsYXNzKSB7CisgICAgICB0aGlzLnNlcmlhbGl6ZUNlbGxBcnJheSgoQ2VsbFtdKSBvKTsKKyAgICB9IGVsc2UgeworICAgICAgdGhyb3cgbmV3IEhCYXNlUmVzdEV4Y2VwdGlvbigKKyAgICAgICAgICAiT2JqZWN0IGRvZXMgbm90IGNvbmZvcm0gdG8gdGhlIElTZXJpYWxpemFibGUgIgorICAgICAgICAgICAgICArICJpbnRlcmZhY2UuICBVbmFibGUgdG8gZ2VuZXJhdGUgeG1sIG91dHB1dC4iKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2Vlb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciMKKyAgICogc2VyaWFsaXplRGF0YWJhc2VNZXRhZGF0YQorICAgKiAob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5EYXRhYmFzZU1vZGVsLkRhdGFiYXNlTWV0YWRhdGEpCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVEYXRhYmFzZU1ldGFkYXRhKERhdGFiYXNlTWV0YWRhdGEgZGF0YWJhc2VNZXRhZGF0YSkKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHByaW50ZXIucHJpbnQoIjx0YWJsZXM+Iik7CisgICAgZm9yIChIVGFibGVEZXNjcmlwdG9yIHRhYmxlIDogZGF0YWJhc2VNZXRhZGF0YS5nZXRUYWJsZXMoKSkgeworICAgICAgdGFibGUucmVzdFNlcmlhbGl6ZSh0aGlzKTsKKyAgICB9CisgICAgcHJpbnRlci5wcmludCgiPC90YWJsZXM+Iik7CisgICAgcHJpbnRlci5mbHVzaCgpOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZW9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjCisgICAqIHNlcmlhbGl6ZVRhYmxlRGVzY3JpcHRvcihvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplVGFibGVEZXNjcmlwdG9yKEhUYWJsZURlc2NyaXB0b3IgdGFibGVEZXNjcmlwdG9yKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcHJpbnRlci5wcmludCgiPHRhYmxlPiIpOworICAgIC8vIG5hbWUgZWxlbWVudAorICAgIHByaW50ZXIucHJpbnQoIjxuYW1lPiIpOworICAgIHByaW50ZXIucHJpbnQodGFibGVEZXNjcmlwdG9yLmdldE5hbWVBc1N0cmluZygpKTsKKyAgICBwcmludGVyLnByaW50KCI8L25hbWU+Iik7CisgICAgLy8gY29sdW1uIGZhbWlsaWVzCisgICAgcHJpbnRlci5wcmludCgiPGNvbHVtbmZhbWlsaWVzPiIpOworICAgIGZvciAoSENvbHVtbkRlc2NyaXB0b3IgY29sdW1uIDogdGFibGVEZXNjcmlwdG9yLmdldENvbHVtbkZhbWlsaWVzKCkpIHsKKyAgICAgIGNvbHVtbi5yZXN0U2VyaWFsaXplKHRoaXMpOworICAgIH0KKyAgICBwcmludGVyLnByaW50KCI8L2NvbHVtbmZhbWlsaWVzPiIpOworICAgIHByaW50ZXIucHJpbnQoIjwvdGFibGU+Iik7CisgICAgcHJpbnRlci5mbHVzaCgpOworCisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2Vlb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciMKKyAgICogc2VyaWFsaXplQ29sdW1uRGVzY3JpcHRvcihvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcikKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZUNvbHVtbkRlc2NyaXB0b3IoSENvbHVtbkRlc2NyaXB0b3IgY29sdW1uKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBwcmludGVyLnByaW50KCI8Y29sdW1uZmFtaWx5PiIpOworICAgIC8vIG5hbWUKKyAgICBwcmludGVyLnByaW50KCI8bmFtZT4iKTsKKyAgICBwcmludGVyLnByaW50KG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQmFzZTY0LmVuY29kZUJ5dGVzKGNvbHVtbi5nZXROYW1lKCkpKTsKKyAgICBwcmludGVyLnByaW50KCI8L25hbWU+Iik7CisgICAgLy8gY29tcHJlc3Npb24KKyAgICBwcmludGVyLnByaW50KCI8Y29tcHJlc3Npb24+Iik7CisgICAgcHJpbnRlci5wcmludChjb2x1bW4uZ2V0Q29tcHJlc3Npb24oKS50b1N0cmluZygpKTsKKyAgICBwcmludGVyLnByaW50KCI8L2NvbXByZXNzaW9uPiIpOworICAgIC8vIGJsb29tZmlsdGVyCisgICAgcHJpbnRlci5wcmludCgiPGJsb29tZmlsdGVyPiIpOworICAgIHByaW50ZXIucHJpbnQoY29sdW1uLmdldENvbXByZXNzaW9uVHlwZSgpLnRvU3RyaW5nKCkpOworICAgIHByaW50ZXIucHJpbnQoIjwvYmxvb21maWx0ZXI+Iik7CisgICAgLy8gbWF4LXZlcnNpb25zCisgICAgcHJpbnRlci5wcmludCgiPG1heC12ZXJzaW9ucz4iKTsKKyAgICBwcmludGVyLnByaW50KGNvbHVtbi5nZXRNYXhWZXJzaW9ucygpKTsKKyAgICBwcmludGVyLnByaW50KCI8L21heC12ZXJzaW9ucz4iKTsKKyAgICAvLyBtYXgtbGVuZ3RoCisgICAgcHJpbnRlci5wcmludCgiPG1heC1sZW5ndGg+Iik7CisgICAgcHJpbnRlci5wcmludChjb2x1bW4uZ2V0TWF4VmFsdWVMZW5ndGgoKSk7CisgICAgcHJpbnRlci5wcmludCgiPC9tYXgtbGVuZ3RoPiIpOworICAgIHByaW50ZXIucHJpbnQoIjwvY29sdW1uZmFtaWx5PiIpOworICAgIHByaW50ZXIuZmx1c2goKTsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciNzZXJpYWxpemVSZWdpb25EYXRhCisgICAqIChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlRhYmxlTW9kZWwuUmVnaW9ucykKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVJlZ2lvbkRhdGEoUmVnaW9ucyByZWdpb25zKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKworICAgIHByaW50ZXIucHJpbnQoIjxyZWdpb25zPiIpOworICAgIGZvciAoYnl0ZVtdIHJlZ2lvbiA6IHJlZ2lvbnMuZ2V0UmVnaW9uS2V5KCkpIHsKKyAgICAgIHByaW50ZXIucHJpbnQoIjxyZWdpb24+Iik7CisgICAgICBwcmludGVyLnByaW50KEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbikpOworICAgICAgcHJpbnRlci5wcmludCgiPC9yZWdpb24+Iik7CisgICAgfQorICAgIHByaW50ZXIucHJpbnQoIjwvcmVnaW9ucz4iKTsKKyAgICBwcmludGVyLmZsdXNoKCk7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjc2VyaWFsaXplU3RhdHVzTWVzc2FnZQorICAgKiAob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5TdGF0dXMuU3RhdHVzTWVzc2FnZSkKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVN0YXR1c01lc3NhZ2UoU3RhdHVzTWVzc2FnZSBtZXNzYWdlKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBwcmludGVyLnByaW50KCI8c3RhdHVzPiIpOworICAgIHByaW50ZXIucHJpbnQoIjxjb2RlPiIpOworICAgIHByaW50ZXIucHJpbnQobWVzc2FnZS5nZXRTdGF0dXNDb2RlKCkpOworICAgIHByaW50ZXIucHJpbnQoIjwvY29kZT4iKTsKKyAgICBwcmludGVyLnByaW50KCI8bWVzc2FnZT4iKTsKKyAgICBwcmludGVyLnByaW50KG1lc3NhZ2UuZ2V0TWVzc2FnZSgpLnRvU3RyaW5nKCkpOworICAgIHByaW50ZXIucHJpbnQoIjwvbWVzc2FnZT4iKTsKKyAgICBwcmludGVyLnByaW50KCI8ZXJyb3I+Iik7CisgICAgcHJpbnRlci5wcmludChtZXNzYWdlLmdldEVycm9yKCkpOworICAgIHByaW50ZXIucHJpbnQoIjwvZXJyb3I+Iik7CisgICAgcHJpbnRlci5wcmludCgiPC9zdGF0dXM+Iik7CisgICAgcHJpbnRlci5mbHVzaCgpOworCisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2Vlb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciMKKyAgICogc2VyaWFsaXplU2Nhbm5lcklkZW50aWZpZXIob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5TY2FubmVySWRlbnRpZmllcikKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZVNjYW5uZXJJZGVudGlmaWVyKFNjYW5uZXJJZGVudGlmaWVyIHNjYW5uZXJJZGVudGlmaWVyKQorICAgICAgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBwcmludGVyLnByaW50KCI8c2Nhbm5lcj4iKTsKKyAgICBwcmludGVyLnByaW50KCI8aWQ+Iik7CisgICAgcHJpbnRlci5wcmludChzY2FubmVySWRlbnRpZmllci5nZXRJZCgpKTsKKyAgICBwcmludGVyLnByaW50KCI8L2lkPiIpOworICAgIHByaW50ZXIucHJpbnQoIjwvc2Nhbm5lcj4iKTsKKyAgICBwcmludGVyLmZsdXNoKCk7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjc2VyaWFsaXplUm93UmVzdWx0CisgICAqIChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQpCisgICAqLworICBwdWJsaWMgdm9pZCBzZXJpYWxpemVSb3dSZXN1bHQoUm93UmVzdWx0IHJvd1Jlc3VsdCkgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisKKyAgICBwcmludGVyLnByaW50KCI8cm93PiIpOworICAgIHByaW50ZXIucHJpbnQoIjxuYW1lPiIpOworICAgIHByaW50ZXIucHJpbnQob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CYXNlNjQuZW5jb2RlQnl0ZXMocm93UmVzdWx0CisgICAgICAgIC5nZXRSb3coKSkpOworICAgIHByaW50ZXIucHJpbnQoIjwvbmFtZT4iKTsKKyAgICBwcmludGVyLnByaW50KCI8Y29sdW1ucz4iKTsKKyAgICBmb3IgKFJlc3RDZWxsIGNlbGwgOiByb3dSZXN1bHQuZ2V0Q2VsbHMoKSkgeworICAgICAgcHJpbnRlci5wcmludCgiPGNvbHVtbj4iKTsKKyAgICAgIHByaW50ZXIucHJpbnQoIjxuYW1lPiIpOworICAgICAgcHJpbnRlci5wcmludChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJhc2U2NC5lbmNvZGVCeXRlcyhjZWxsCisgICAgICAgICAgLmdldE5hbWUoKSkpOworICAgICAgcHJpbnRlci5wcmludCgiPC9uYW1lPiIpOworICAgICAgcHJpbnRlci5wcmludCgiPHRpbWVzdGFtcD4iKTsKKyAgICAgIHByaW50ZXIucHJpbnQoY2VsbC5nZXRUaW1lc3RhbXAoKSk7CisgICAgICBwcmludGVyLnByaW50KCI8L3RpbWVzdGFtcD4iKTsKKyAgICAgIHByaW50ZXIucHJpbnQoIjx2YWx1ZT4iKTsKKyAgICAgIHByaW50ZXIucHJpbnQob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CYXNlNjQuZW5jb2RlQnl0ZXMoY2VsbAorICAgICAgICAgIC5nZXRWYWx1ZSgpKSk7CisgICAgICBwcmludGVyLnByaW50KCI8L3ZhbHVlPiIpOworICAgICAgcHJpbnRlci5wcmludCgiPC9jb2x1bW4+Iik7CisgICAgICBwcmludGVyLmZsdXNoKCk7CisgICAgfQorICAgIHByaW50ZXIucHJpbnQoIjwvY29sdW1ucz4iKTsKKyAgICBwcmludGVyLnByaW50KCI8L3Jvdz4iKTsKKyAgICBwcmludGVyLmZsdXNoKCk7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjc2VyaWFsaXplUm93UmVzdWx0QXJyYXkKKyAgICogKG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdFtdKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplUm93UmVzdWx0QXJyYXkoUm93UmVzdWx0W10gcm93cykKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIHByaW50ZXIucHJpbnQoIjxyb3dzPiIpOworICAgIGZvciAoUm93UmVzdWx0IHJvdyA6IHJvd3MpIHsKKyAgICAgIHJvdy5yZXN0U2VyaWFsaXplKHRoaXMpOworICAgIH0KKyAgICBwcmludGVyLnByaW50KCI8L3Jvd3M+Iik7CisgIH0KKworICAvKgorICAgKiAobm9uLUphdmFkb2MpCisgICAqIAorICAgKiBAc2VlCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5JUmVzdFNlcmlhbGl6ZXIjc2VyaWFsaXplQ2VsbChvcmcKKyAgICogLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbCkKKyAgICovCisgIHB1YmxpYyB2b2lkIHNlcmlhbGl6ZUNlbGwoQ2VsbCBjZWxsKSB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICBwcmludGVyLnByaW50KCI8Y2VsbD4iKTsKKyAgICBwcmludGVyLnByaW50KCI8dmFsdWU+Iik7CisgICAgcHJpbnRlci5wcmludChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJhc2U2NC5lbmNvZGVCeXRlcyhjZWxsCisgICAgICAgIC5nZXRWYWx1ZSgpKSk7CisgICAgcHJpbnRlci5wcmludCgiPC92YWx1ZT4iKTsKKyAgICBwcmludGVyLnByaW50KCI8dGltZXN0YW1wPiIpOworICAgIHByaW50ZXIucHJpbnQoY2VsbC5nZXRUaW1lc3RhbXAoKSk7CisgICAgcHJpbnRlci5wcmludCgiPC90aW1lc3RhbXA+Iik7CisgICAgcHJpbnRlci5wcmludCgiPC9jZWxsPiIpOworICB9CisKKyAgLyoKKyAgICogKG5vbi1KYXZhZG9jKQorICAgKiAKKyAgICogQHNlZQorICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuSVJlc3RTZXJpYWxpemVyI3NlcmlhbGl6ZUNlbGxBcnJheQorICAgKiAob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbFtdKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplQ2VsbEFycmF5KENlbGxbXSBjZWxscykgdGhyb3dzIEhCYXNlUmVzdEV4Y2VwdGlvbiB7CisgICAgcHJpbnRlci5wcmludCgiPGNlbGxzPiIpOworICAgIGZvciAoQ2VsbCBjZWxsIDogY2VsbHMpIHsKKyAgICAgIGNlbGwucmVzdFNlcmlhbGl6ZSh0aGlzKTsKKyAgICB9CisgICAgcHJpbnRlci5wcmludCgiPC9jZWxscz4iKTsKKyAgfQorCisgIC8qCisgICAqIChub24tSmF2YWRvYykKKyAgICogCisgICAqIEBzZWUKKyAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLklSZXN0U2VyaWFsaXplciNzZXJpYWxpemVUaW1lc3RhbXBzCisgICAqIChvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LlJvd01vZGVsLlRpbWVzdGFtcHNEZXNjcmlwdG9yKQorICAgKi8KKyAgcHVibGljIHZvaWQgc2VyaWFsaXplVGltZXN0YW1wcyhUaW1lc3RhbXBzRGVzY3JpcHRvciB0aW1lc3RhbXBzRGVzY3JpcHRvcikKKyAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICB9CisKKyAgLy8gUHJpdmF0ZSBjbGFzc2VzIHVzZWQgZm9yIHByaW50aW5nIHRoZSBvdXRwdXQKKworICBwcml2YXRlIGludGVyZmFjZSBJUHJpbnRlciB7CisgICAgcHVibGljIHZvaWQgcHJpbnQoU3RyaW5nIG91dHB1dCk7CisKKyAgICBwdWJsaWMgdm9pZCBwcmludChpbnQgb3V0cHV0KTsKKworICAgIHB1YmxpYyB2b2lkIHByaW50KGxvbmcgb3V0cHV0KTsKKyAgICAKKyAgICBwdWJsaWMgdm9pZCBwcmludChib29sZWFuIG91dHB1dCk7IAorCisgICAgcHVibGljIHZvaWQgZmx1c2goKTsKKyAgfQorCisgIHByaXZhdGUgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RQcmludGVyIGltcGxlbWVudHMgSVByaW50ZXIgeworICAgIHByb3RlY3RlZCBmaW5hbCBQcmludFdyaXRlciB3cml0ZXI7CisKKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBwcml2YXRlIEFic3RyYWN0UHJpbnRlcigpIHsKKyAgICAgIHdyaXRlciA9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIEFic3RyYWN0UHJpbnRlcihIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQorICAgICAgICB0aHJvd3MgSEJhc2VSZXN0RXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHdyaXRlciA9IHJlc3BvbnNlLmdldFdyaXRlcigpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSEJhc2VSZXN0RXhjZXB0aW9uKGUuZ2V0TWVzc2FnZSgpLCBlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHsKKyAgICAgIHdyaXRlci5mbHVzaCgpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgY2xhc3MgU2ltcGxlUHJpbnRlciBleHRlbmRzIEFic3RyYWN0UHJpbnRlciB7CisgICAgcHJpdmF0ZSBTaW1wbGVQcmludGVyKEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgICAgc3VwZXIocmVzcG9uc2UpOworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqIAorICAgICAqIEBzZWUKKyAgICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuU2ltcGxlWE1MU2VyaWFsaXplci5QcmludGVyI3ByaW50CisgICAgICogKGphdmEuaW8uUHJpbnRXcml0ZXIsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoZmluYWwgU3RyaW5nIG91dHB1dCkgeworICAgICAgd3JpdGVyLnByaW50KG91dHB1dCk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiAobm9uLUphdmFkb2MpCisgICAgICogCisgICAgICogQHNlZQorICAgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlc3Quc2VyaWFsaXplci5TaW1wbGVYTUxTZXJpYWxpemVyLklQcmludGVyIworICAgICAqIHByaW50KGludCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChpbnQgb3V0cHV0KSB7CisgICAgICB3cml0ZXIucHJpbnQob3V0cHV0KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIChub24tSmF2YWRvYykKKyAgICAgKiAKKyAgICAgKiBAc2VlCisgICAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLlNpbXBsZVhNTFNlcmlhbGl6ZXIuSVByaW50ZXIjCisgICAgICogcHJpbnQobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChsb25nIG91dHB1dCkgeworICAgICAgd3JpdGVyLnByaW50KG91dHB1dCk7CisgICAgfQorCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLlNpbXBsZVhNTFNlcmlhbGl6ZXIuSVByaW50ZXIjcHJpbnQoYm9vbGVhbikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChib29sZWFuIG91dHB1dCkgeworICAgICAgd3JpdGVyLnByaW50KG91dHB1dCk7IAorICAgIH0KKyAgfQorCisgIHByaXZhdGUgY2xhc3MgUHJldHR5UHJpbnRlciBleHRlbmRzIEFic3RyYWN0UHJpbnRlciB7CisgICAgcHJpdmF0ZSBQcmV0dHlQcmludGVyKEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCisgICAgICAgIHRocm93cyBIQmFzZVJlc3RFeGNlcHRpb24geworICAgICAgc3VwZXIocmVzcG9uc2UpOworICAgIH0KKworICAgIC8qCisgICAgICogKG5vbi1KYXZhZG9jKQorICAgICAqIAorICAgICAqIEBzZWUKKyAgICAgKiBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuU2ltcGxlWE1MU2VyaWFsaXplci5QcmludGVyI3ByaW50CisgICAgICogKGphdmEuaW8uUHJpbnRXcml0ZXIsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcHJpbnQoU3RyaW5nIG91dHB1dCkgeworICAgICAgd3JpdGVyLnByaW50bG4ob3V0cHV0KTsKKyAgICB9CisKKyAgICAvKgorICAgICAqIChub24tSmF2YWRvYykKKyAgICAgKiAKKyAgICAgKiBAc2VlCisgICAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLlNpbXBsZVhNTFNlcmlhbGl6ZXIuSVByaW50ZXIjCisgICAgICogcHJpbnQoaW50KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGludCBvdXRwdXQpIHsKKyAgICAgIHdyaXRlci5wcmludGxuKG91dHB1dCk7CisKKyAgICB9CisKKyAgICAvKgorICAgICAqIChub24tSmF2YWRvYykKKyAgICAgKiAKKyAgICAgKiBAc2VlCisgICAgICogb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVzdC5zZXJpYWxpemVyLlNpbXBsZVhNTFNlcmlhbGl6ZXIuSVByaW50ZXIjCisgICAgICogcHJpbnQobG9uZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBwcmludChsb25nIG91dHB1dCkgeworICAgICAgd3JpdGVyLnByaW50bG4ob3V0cHV0KTsKKyAgICB9CisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LnNlcmlhbGl6ZXIuU2ltcGxlWE1MU2VyaWFsaXplci5JUHJpbnRlciNwcmludChib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHByaW50KGJvb2xlYW4gb3V0cHV0KSB7CisgICAgICB3cml0ZXIucHJpbnRsbihvdXRwdXQpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L0hiYXNlLnRocmlmdCBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9IYmFzZS50aHJpZnQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGE3ZmM5MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9IYmFzZS50aHJpZnQKQEAgLTAsMCArMSw1NDkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEhCYXNlLnRocmlmdCAtCisvLworLy8gVGhpcyBpcyBhIFRocmlmdCBpbnRlcmZhY2UgZGVmaW5pdGlvbiBmaWxlIGZvciB0aGUgSGJhc2Ugc2VydmljZS4KKy8vIFRhcmdldCBsYW5ndWFnZSBsaWJyYXJpZXMgZm9yIEMrKywgSmF2YSwgUnVieSwgUEhQLCAoYW5kIG1vcmUpIGFyZQorLy8gZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgdGhpcyBmaWxlIHRocm91Z2ggdGhlIFRocmlmdCBjb21waWxlciB3aXRoIHRoZQorLy8gYXBwcm9wcmlhdGUgZmxhZ3MuICBUaGUgVGhyaWZ0IGNvbXBpbGVyIGJpbmFyeSBhbmQgcnVudGltZQorLy8gbGlicmFyaWVzIGZvciB2YXJpb3VzIGxhbmd1YWdlcyBpcyBjdXJyZW50bHkgYXZhaWxhYmxlIGZyb20KKy8vIEZhY2Vib29rIChodHRwOi8vZGV2ZWxvcGVycy5mYWNlYm9vay5jb20vdGhyaWZ0LykuICBUaGUgaW50ZW50IGlzCisvLyBmb3IgdGhlIFRocmlmdCBwcm9qZWN0IHRvIG1pZ3JhdGUgdG8gQXBhY2hlIEluY3ViYXRvci4KKy8vCisvLyBTZWUgdGhlIHBhY2thZ2UuaHRtbCBmaWxlIGZvciBpbmZvcm1hdGlvbiBvbiB0aGUgdmVyc2lvbiBvZiBUaHJpZnQKKy8vIHVzZWQgdG8gZ2VuZXJhdGUgdGhlICouamF2YSBmaWxlcyBjaGVja2VkIGludG8gdGhlIEhiYXNlIHByb2plY3QuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK25hbWVzcGFjZSBqYXZhIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQKK25hbWVzcGFjZSBjcHAgIGFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0CituYW1lc3BhY2UgcmIgQXBhY2hlLkhhZG9vcC5IYmFzZS5UaHJpZnQKK25hbWVzcGFjZSBweSBoYmFzZQorbmFtZXNwYWNlIHBlcmwgSGJhc2UKKworLy8gbm90ZTogb3RoZXIgbGFuZ3VhZ2UgbmFtZXNwYWNlcyB0YmQuLi4KKworLy8KKy8vIFR5cGVzCisvLworCisvLyBOT1RFOiBhbGwgdmFyaWFibGVzIHdpdGggdGhlIFRleHQgdHlwZSBhcmUgYXNzdW1lZCB0byBiZSBjb3JyZWN0bHkKKy8vIGZvcm1hdHRlZCBVVEYtOCBzdHJpbmdzLiAgVGhpcyBpcyBhIHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZCBsb2NhbGUKKy8vIGRlcGVuZGVudCBwcm9wZXJ0eSB0aGF0IHRoZSBjbGllbnQgYXBwbGljYXRpb24gaXMgcmVwc29uc2libGUgZm9yCisvLyBtYWludGFpbmluZy4gIElmIHN0cmluZ3Mgd2l0aCBhbiBpbnZhbGlkIGVuY29kaW5nIGFyZSBzZW50LCBhbgorLy8gSU9FcnJvciB3aWxsIGJlIHRocm93bi4KKwordHlwZWRlZiBiaW5hcnkgVGV4dAordHlwZWRlZiBiaW5hcnkgQnl0ZXMKK3R5cGVkZWYgaTMyICAgIFNjYW5uZXJJRAorCisvKioKKyAqIFRDZWxsIC0gVXNlZCB0byB0cmFuc3BvcnQgYSBjZWxsIHZhbHVlIChieXRlW10pIGFuZCB0aGUgdGltZXN0YW1wIGl0IHdhcyAKKyAqIHN0b3JlZCB3aXRoIHRvZ2V0aGVyIGFzIGEgcmVzdWx0IGZvciBnZXQgYW5kIGdldFJvdyBtZXRob2RzLiBUaGlzIHByb21vdGVzCisgKiB0aGUgdGltZXN0YW1wIG9mIGEgY2VsbCB0byBhIGZpcnN0LWNsYXNzIHZhbHVlLCBtYWtpbmcgaXQgZWFzeSB0byB0YWtlIAorICogbm90ZSBvZiB0ZW1wb3JhbCBkYXRhLiBDZWxsIGlzIHVzZWQgYWxsIHRoZSB3YXkgZnJvbSBIU3RvcmUgdXAgdG8gSFRhYmxlLgorICovCitzdHJ1Y3QgVENlbGx7CisgIDE6Qnl0ZXMgdmFsdWUsCisgIDI6aTY0IHRpbWVzdGFtcAorfQorCisvKioKKyAqIEFuIEhDb2x1bW5EZXNjcmlwdG9yIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgY29sdW1uIGZhbWlseQorICogc3VjaCBhcyB0aGUgbnVtYmVyIG9mIHZlcnNpb25zLCBjb21wcmVzc2lvbiBzZXR0aW5ncywgZXRjLiBJdCBpcworICogdXNlZCBhcyBpbnB1dCB3aGVuIGNyZWF0aW5nIGEgdGFibGUgb3IgYWRkaW5nIGEgY29sdW1uLgorICovCitzdHJ1Y3QgQ29sdW1uRGVzY3JpcHRvciB7CisgIDE6VGV4dCBuYW1lLAorICAyOmkzMiBtYXhWZXJzaW9ucyA9IDMsCisgIDM6c3RyaW5nIGNvbXByZXNzaW9uID0gIk5PTkUiLAorICA0OmJvb2wgaW5NZW1vcnkgPSAwLAorICA1OmkzMiBtYXhWYWx1ZUxlbmd0aCA9IDIxNDc0ODM2NDcsCisgIDY6c3RyaW5nIGJsb29tRmlsdGVyVHlwZSA9ICJOT05FIiwKKyAgNzppMzIgYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gMCwKKyAgODppMzIgYmxvb21GaWx0ZXJOYkhhc2hlcyA9IDAsCisgIDk6Ym9vbCBibG9ja0NhY2hlRW5hYmxlZCA9IDAsCisgIDEwOmkzMiB0aW1lVG9MaXZlID0gLTEKK30KKworLyoqCisgKiBBIFRSZWdpb25JbmZvIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFuIEhUYWJsZSByZWdpb24uCisgKi8KK3N0cnVjdCBUUmVnaW9uSW5mbyB7CisgIDE6VGV4dCBzdGFydEtleSwKKyAgMjpUZXh0IGVuZEtleSwKKyAgMzppNjQgaWQsCisgIDQ6VGV4dCBuYW1lLAorICA1OmJ5dGUgdmVyc2lvbiAKK30KKworLyoqCisgKiBBIE11dGF0aW9uIG9iamVjdCBpcyB1c2VkIHRvIGVpdGhlciB1cGRhdGUgb3IgZGVsZXRlIGEgY29sdW1uLXZhbHVlLgorICovCitzdHJ1Y3QgTXV0YXRpb24geworICAxOmJvb2wgaXNEZWxldGUgPSAwLAorICAyOlRleHQgY29sdW1uLAorICAzOlRleHQgdmFsdWUKK30KKworCisvKioKKyAqIEEgQmF0Y2hNdXRhdGlvbiBvYmplY3QgaXMgdXNlZCB0byBhcHBseSBhIG51bWJlciBvZiBNdXRhdGlvbnMgdG8gYSBzaW5nbGUgcm93LgorICovCitzdHJ1Y3QgQmF0Y2hNdXRhdGlvbiB7CisgIDE6VGV4dCByb3csCisgIDI6bGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zCit9CisKKworLyoqCisgKiBIb2xkcyByb3cgbmFtZSBhbmQgdGhlbiBhIG1hcCBvZiBjb2x1bW5zIHRvIGNlbGxzLiAKKyAqLworc3RydWN0IFRSb3dSZXN1bHQgeworICAxOlRleHQgcm93LAorICAyOm1hcDxUZXh0LCBUQ2VsbD4gY29sdW1ucworfQorCisvLworLy8gRXhjZXB0aW9ucworLy8KKy8qKgorICogQW4gSU9FcnJvciBleGNlcHRpb24gc2lnbmFscyB0aGF0IGFuIGVycm9yIG9jY3VycmVkIGNvbW11bmljYXRpbmcKKyAqIHRvIHRoZSBIYmFzZSBtYXN0ZXIgb3IgYW4gSGJhc2UgcmVnaW9uIHNlcnZlci4gIEFsc28gdXNlZCB0byByZXR1cm4KKyAqIG1vcmUgZ2VuZXJhbCBIYmFzZSBlcnJvciBjb25kaXRpb25zLgorICovCitleGNlcHRpb24gSU9FcnJvciB7CisgIDE6c3RyaW5nIG1lc3NhZ2UKK30KKworLyoqCisgKiBBbiBJbGxlZ2FsQXJndW1lbnQgZXhjZXB0aW9uIGluZGljYXRlcyBhbiBpbGxlZ2FsIG9yIGludmFsaWQKKyAqIGFyZ3VtZW50IHdhcyBwYXNzZWQgaW50byBhIHByb2NlZHVyZS4KKyAqLworZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudCB7CisgIDE6c3RyaW5nIG1lc3NhZ2UKK30KKworLyoqCisgKiBBbiBBbHJlYWR5RXhpc3RzIGV4Y2VwdGlvbnMgc2lnbmFscyB0aGF0IGEgdGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkCisgKiBuYW1lIGFscmVhZHkgZXhpc3RzCisgKi8KK2V4Y2VwdGlvbiBBbHJlYWR5RXhpc3RzIHsKKyAgMTpzdHJpbmcgbWVzc2FnZQorfQorCisvLworLy8gU2VydmljZSAKKy8vCisKK3NlcnZpY2UgSGJhc2UgeworICAvKioKKyAgICogQnJpbmdzIGEgdGFibGUgb24tbGluZSAoZW5hYmxlcyBpdCkKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRoZSB0YWJsZQorICAgKi8KKyAgdm9pZCBlbmFibGVUYWJsZSgxOkJ5dGVzIHRhYmxlTmFtZSkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKyAgICAKKyAgLyoqCisgICAqIERpc2FibGVzIGEgdGFibGUgKHRha2VzIGl0IG9mZi1saW5lKSBJZiBpdCBpcyBiZWluZyBzZXJ2ZWQsIHRoZSBtYXN0ZXIKKyAgICogd2lsbCB0ZWxsIHRoZSBzZXJ2ZXJzIHRvIHN0b3Agc2VydmluZyBpdC4KKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRoZSB0YWJsZQorICAgKi8KKyAgdm9pZCBkaXNhYmxlVGFibGUoMTpCeXRlcyB0YWJsZU5hbWUpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisKKyAgLyoqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBjaGVjaworICAgKiBAcmV0dXJuIHRydWUgaWYgdGFibGUgaXMgb24tbGluZQorICAgKi8KKyAgYm9vbCBpc1RhYmxlRW5hYmxlZCgxOkJ5dGVzIHRhYmxlTmFtZSkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKyAgICAKKyAgdm9pZCBjb21wYWN0KDE6Qnl0ZXMgdGFibGVOYW1lT3JSZWdpb25OYW1lKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorICAKKyAgdm9pZCBtYWpvckNvbXBhY3QoMTpCeXRlcyB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisgICAgCisgIC8qKgorICAgKiBMaXN0IGFsbCB0aGUgdXNlcnNwYWNlIHRhYmxlcy4KKyAgICogQHJldHVybiAtIHJldHVybnMgYSBsaXN0IG9mIG5hbWVzCisgICAqLworICBsaXN0PFRleHQ+IGdldFRhYmxlTmFtZXMoKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorCisgIC8qKgorICAgKiBMaXN0IGFsbCB0aGUgY29sdW1uIGZhbWlsaWVzIGFzc29pY2F0ZWQgd2l0aCBhIHRhYmxlLgorICAgKiBAcGFyYW0gdGFibGVOYW1lIHRhYmxlIG5hbWUKKyAgICogQHJldHVybiBsaXN0IG9mIGNvbHVtbiBmYW1pbHkgZGVzY3JpcHRvcnMKKyAgICovCisgIG1hcDxUZXh0LENvbHVtbkRlc2NyaXB0b3I+IGdldENvbHVtbkRlc2NyaXB0b3JzICgxOlRleHQgdGFibGVOYW1lKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorCisgIC8qKgorICAgKiBMaXN0IHRoZSByZWdpb25zIGFzc29jaWF0ZWQgd2l0aCBhIHRhYmxlLgorICAgKiBAcGFyYW0gdGFibGVOYW1lIHRhYmxlIG5hbWUKKyAgICogQHJldHVybiBsaXN0IG9mIHJlZ2lvbiBkZXNjcmlwdG9ycworICAgKi8KKyAgbGlzdDxUUmVnaW9uSW5mbz4gZ2V0VGFibGVSZWdpb25zKDE6VGV4dCB0YWJsZU5hbWUpIAorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorCisgIC8qKgorICAgKiBDcmVhdGUgYSB0YWJsZSB3aXRoIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlsaWVzLiAgVGhlIG5hbWUKKyAgICogZmllbGQgZm9yIGVhY2ggQ29sdW1uRGVzY3JpcHRvciBtdXN0IGJlIHNldCBhbmQgbXVzdCBlbmQgaW4gYQorICAgKiBjb2xvbiAoOikuICBBbGwgb3RoZXIgZmllbGRzIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBnZXQgZGVmYXVsdAorICAgKiB2YWx1ZXMgaWYgbm90IGV4cGxpY2l0bHkgc3BlY2lmaWVkLgorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gY3JlYXRlCisgICAqIEBwYXJhbSBjb2x1bW5GYW1pbGllcyBsaXN0IG9mIGNvbHVtbiBmYW1pbHkgZGVzY3JpcHRvcnMKKyAgICoKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnQgaWYgYW4gaW5wdXQgcGFyYW1ldGVyIGlzIGludmFsaWQKKyAgICogQHRocm93cyBBbHJlYWR5RXhpc3RzIGlmIHRoZSB0YWJsZSBuYW1lIGFscmVhZHkgZXhpc3RzCisgICAqLyAKKyAgdm9pZCBjcmVhdGVUYWJsZSgxOlRleHQgdGFibGVOYW1lLCAyOmxpc3Q8Q29sdW1uRGVzY3JpcHRvcj4gY29sdW1uRmFtaWxpZXMpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8sIDI6SWxsZWdhbEFyZ3VtZW50IGlhLCAzOkFscmVhZHlFeGlzdHMgZXhpc3QpCisKKyAgLyoqCisgICAqIERlbGV0ZXMgYSB0YWJsZQorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gZGVsZXRlCisgICAqIEB0aHJvd3MgSU9FcnJvciBpZiB0YWJsZSBkb2Vzbid0IGV4aXN0IG9uIHNlcnZlciBvciB0aGVyZSB3YXMgc29tZSBvdGhlcgorICAgKiBwcm9ibGVtCisgICAqLworICB2b2lkIGRlbGV0ZVRhYmxlKDE6VGV4dCB0YWJsZU5hbWUpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisKKyAgLyoqIAorICAgKiBHZXQgYSBzaW5nbGUgVENlbGwgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUsIHJvdywgYW5kIGNvbHVtbiBhdCB0aGUKKyAgICogbGF0ZXN0IHRpbWVzdGFtcC4gUmV0dXJucyBhbiBlbXB0eSBsaXN0IGlmIG5vIHN1Y2ggdmFsdWUgZXhpc3RzLgorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICogQHJldHVybiB2YWx1ZSBmb3Igc3BlY2lmaWVkIHJvdy9jb2x1bW4KKyAgICovCisgIGxpc3Q8VENlbGw+IGdldCgxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LCAzOlRleHQgY29sdW1uKSAKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBmb3IgdGhlIHNwZWNpZmllZCB0YWJsZSwKKyAgICogcm93LCBhbmQgY29sdW1uLgorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXRyaWV2ZQorICAgKiBAcmV0dXJuIGxpc3Qgb2YgY2VsbHMgZm9yIHNwZWNpZmllZCByb3cvY29sdW1uCisgICAqLworICBsaXN0PFRDZWxsPiBnZXRWZXIoMTpUZXh0IHRhYmxlTmFtZSwgMjpUZXh0IHJvdywgMzpUZXh0IGNvbHVtbiwKKyAgICAgIDQ6aTMyIG51bVZlcnNpb25zKSAKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB2ZXJzaW9ucyBmb3IgdGhlIHNwZWNpZmllZCB0YWJsZSwKKyAgICogcm93LCBhbmQgY29sdW1uLiAgT25seSB2ZXJzaW9ucyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNwZWNpZmllZAorICAgKiB0aW1lc3RhbXAgd2lsbCBiZSByZXR1cm5lZC4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0cmlldmUKKyAgICogQHJldHVybiBsaXN0IG9mIGNlbGxzIGZvciBzcGVjaWZpZWQgcm93L2NvbHVtbgorICAgKi8KKyAgbGlzdDxUQ2VsbD4gZ2V0VmVyVHMoMTpUZXh0IHRhYmxlTmFtZSwgMjpUZXh0IHJvdywgMzpUZXh0IGNvbHVtbiwgCisgICAgICA0Omk2NCB0aW1lc3RhbXAsICA1OmkzMiBudW1WZXJzaW9ucykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCBhbGwgdGhlIGRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUgYW5kIHJvdyBhdCB0aGUgbGF0ZXN0CisgICAqIHRpbWVzdGFtcC4gUmV0dXJucyBhbiBlbXB0eSBsaXN0IGlmIHRoZSByb3cgZG9lcyBub3QgZXhpc3QuCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEByZXR1cm4gVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSByb3cgYW5kIG1hcCBvZiBjb2x1bW5zIHRvIFRDZWxscworICAgKi8KKyAgbGlzdDxUUm93UmVzdWx0PiBnZXRSb3coMTpUZXh0IHRhYmxlTmFtZSwgMjpUZXh0IHJvdykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCB0aGUgc3BlY2lmaWVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUgYW5kIHJvdyBhdCB0aGUgbGF0ZXN0CisgICAqIHRpbWVzdGFtcC4gUmV0dXJucyBhbiBlbXB0eSBsaXN0IGlmIHRoZSByb3cgZG9lcyBub3QgZXhpc3QuCisgICAqIAorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAqIEBwYXJhbSBjb2x1bW5zIExpc3Qgb2YgY29sdW1ucyB0byByZXR1cm4sIG51bGwgZm9yIGFsbCBjb2x1bW5zCisgICAqIEByZXR1cm4gVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSByb3cgYW5kIG1hcCBvZiBjb2x1bW5zIHRvIFRDZWxscworICAgKi8KKyAgbGlzdDxUUm93UmVzdWx0PiBnZXRSb3dXaXRoQ29sdW1ucygxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LAorICAgICAgMzpsaXN0PFRleHQ+IGNvbHVtbnMpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisKKyAgLyoqIAorICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHRhYmxlIGFuZCByb3cgYXQgdGhlIHNwZWNpZmllZAorICAgKiB0aW1lc3RhbXAuIFJldHVybnMgYW4gZW1wdHkgbGlzdCBpZiB0aGUgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICogQHJldHVybiBUUm93UmVzdWx0IGNvbnRhaW5pbmcgdGhlIHJvdyBhbmQgbWFwIG9mIGNvbHVtbnMgdG8gVENlbGxzCisgICAqLworICBsaXN0PFRSb3dSZXN1bHQ+IGdldFJvd1RzKDE6VGV4dCB0YWJsZU5hbWUsIDI6VGV4dCByb3csIDM6aTY0IHRpbWVzdGFtcCkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKyAgICAKKyAgLyoqIAorICAgKiBHZXQgdGhlIHNwZWNpZmllZCBjb2x1bW5zIGZvciB0aGUgc3BlY2lmaWVkIHRhYmxlIGFuZCByb3cgYXQgdGhlIHNwZWNpZmllZAorICAgKiB0aW1lc3RhbXAuIFJldHVybnMgYW4gZW1wdHkgbGlzdCBpZiB0aGUgcm93IGRvZXMgbm90IGV4aXN0LgorICAgKiAKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gY29sdW1ucyBMaXN0IG9mIGNvbHVtbnMgdG8gcmV0dXJuLCBudWxsIGZvciBhbGwgY29sdW1ucworICAgKiBAcmV0dXJuIFRSb3dSZXN1bHQgY29udGFpbmluZyB0aGUgcm93IGFuZCBtYXAgb2YgY29sdW1ucyB0byBUQ2VsbHMKKyAgICovCisgIGxpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93V2l0aENvbHVtbnNUcygxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LAorICAgICAgMzpsaXN0PFRleHQ+IGNvbHVtbnMsIDQ6aTY0IHRpbWVzdGFtcCkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEFwcGx5IGEgc2VyaWVzIG9mIG11dGF0aW9ucyAodXBkYXRlcy9kZWxldGVzKSB0byBhIHJvdyBpbiBhCisgICAqIHNpbmdsZSB0cmFuc2FjdGlvbi4gIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24sIHRoZW4gdGhlCisgICAqIHRyYW5zYWN0aW9uIGlzIGFib3J0ZWQuICBEZWZhdWx0IGN1cnJlbnQgdGltZXN0YW1wIGlzIHVzZWQsIGFuZAorICAgKiBhbGwgZW50cmllcyB3aWxsIGhhdmUgYW4gaWRlbnRpY2FsIHRpbWVzdGFtcC4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgKiBAcGFyYW0gbXV0YXRpb25zIGxpc3Qgb2YgbXV0YXRpb24gY29tbWFuZHMKKyAgICovCisgIHZvaWQgbXV0YXRlUm93KDE6VGV4dCB0YWJsZU5hbWUsIDI6VGV4dCByb3csIDM6bGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvLCAyOklsbGVnYWxBcmd1bWVudCBpYSkKKworICAvKiogCisgICAqIEFwcGx5IGEgc2VyaWVzIG9mIG11dGF0aW9ucyAodXBkYXRlcy9kZWxldGVzKSB0byBhIHJvdyBpbiBhCisgICAqIHNpbmdsZSB0cmFuc2FjdGlvbi4gIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24sIHRoZW4gdGhlCisgICAqIHRyYW5zYWN0aW9uIGlzIGFib3J0ZWQuICBUaGUgc3BlY2lmaWVkIHRpbWVzdGFtcCBpcyB1c2VkLCBhbmQKKyAgICogYWxsIGVudHJpZXMgd2lsbCBoYXZlIGFuIGlkZW50aWNhbCB0aW1lc3RhbXAuCisgICAqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICogQHBhcmFtIG11dGF0aW9ucyBsaXN0IG9mIG11dGF0aW9uIGNvbW1hbmRzCisgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAqLworICB2b2lkIG11dGF0ZVJvd1RzKDE6VGV4dCB0YWJsZU5hbWUsIDI6VGV4dCByb3csIDM6bGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zLCA0Omk2NCB0aW1lc3RhbXApCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8sIDI6SWxsZWdhbEFyZ3VtZW50IGlhKQorCisgIC8qKiAKKyAgICogQXBwbHkgYSBzZXJpZXMgb2YgYmF0Y2hlcyAoZWFjaCBhIHNlcmllcyBvZiBtdXRhdGlvbnMgb24gYSBzaW5nbGUgcm93KQorICAgKiBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbi4gIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24sIHRoZW4gdGhlCisgICAqIHRyYW5zYWN0aW9uIGlzIGFib3J0ZWQuICBEZWZhdWx0IGN1cnJlbnQgdGltZXN0YW1wIGlzIHVzZWQsIGFuZAorICAgKiBhbGwgZW50cmllcyB3aWxsIGhhdmUgYW4gaWRlbnRpY2FsIHRpbWVzdGFtcC4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3dCYXRjaGVzIGxpc3Qgb2Ygcm93IGJhdGNoZXMKKyAgICovCisgIHZvaWQgbXV0YXRlUm93cygxOlRleHQgdGFibGVOYW1lLCAyOmxpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbywgMjpJbGxlZ2FsQXJndW1lbnQgaWEpCisKKyAgLyoqIAorICAgKiBBcHBseSBhIHNlcmllcyBvZiBiYXRjaGVzIChlYWNoIGEgc2VyaWVzIG9mIG11dGF0aW9ucyBvbiBhIHNpbmdsZSByb3cpCisgICAqIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiAgSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biwgdGhlbiB0aGUKKyAgICogdHJhbnNhY3Rpb24gaXMgYWJvcnRlZC4gIFRoZSBzcGVjaWZpZWQgdGltZXN0YW1wIGlzIHVzZWQsIGFuZAorICAgKiBhbGwgZW50cmllcyB3aWxsIGhhdmUgYW4gaWRlbnRpY2FsIHRpbWVzdGFtcC4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3dCYXRjaGVzIGxpc3Qgb2Ygcm93IGJhdGNoZXMKKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICovCisgIHZvaWQgbXV0YXRlUm93c1RzKDE6VGV4dCB0YWJsZU5hbWUsIDI6bGlzdDxCYXRjaE11dGF0aW9uPiByb3dCYXRjaGVzLCAzOmk2NCB0aW1lc3RhbXApCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8sIDI6SWxsZWdhbEFyZ3VtZW50IGlhKQorCisgIC8qKgorICAgKiBBdG9taWNhbGx5IGluY3JlbWVudCB0aGUgY29sdW1uIHZhbHVlIHNwZWNpZmllZC4gIFJldHVybnMgdGhlIG5leHQgdmFsdWUgcG9zdCBpbmNyZW1lbnQuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gcm93IHJvdyB0byBpbmNyZW1lbnQKKyAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbgorICAgKiBAcGFyYW0gdmFsdWUgYW1vdW50IHRvIGluY3JlbWVudCBieQorICAgKi8KKyAgaTY0IGF0b21pY0luY3JlbWVudCgxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LCAzOlRleHQgY29sdW1uLCA0Omk2NCB2YWx1ZSkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbywgMjpJbGxlZ2FsQXJndW1lbnQgaWEpCisgICAgCisgIC8qKiAKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4uCisgICAqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gcm93IFJvdyB0byB1cGRhdGUKKyAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBkZWxldGVkCisgICAqLworICB2b2lkIGRlbGV0ZUFsbCgxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LCAzOlRleHQgY29sdW1uKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorCisgIC8qKiAKKyAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4gYW5kIHdob3NlCisgICAqIHRpbWVzdGFtcCBpcyBlcXVhbC10byBvciBvbGRlciB0aGFuIHRoZSBwYXNzZWQgdGltZXN0YW1wLgorICAgKgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAqIEBwYXJhbSBjb2x1bW4gbmFtZSBvZiBjb2x1bW4gd2hvc2UgdmFsdWUgaXMgdG8gYmUgZGVsZXRlZAorICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcAorICAgKi8KKyAgdm9pZCBkZWxldGVBbGxUcygxOlRleHQgdGFibGVOYW1lLCAyOlRleHQgcm93LCAzOlRleHQgY29sdW1uLCA0Omk2NCB0aW1lc3RhbXApCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisKKyAgLyoqCisgICAqIENvbXBsZXRlbHkgZGVsZXRlIHRoZSByb3cncyBjZWxscy4KKyAgICoKKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSByb3cga2V5IG9mIHRoZSByb3cgdG8gYmUgY29tcGxldGVseSBkZWxldGVkLgorICAgKi8KKyAgdm9pZCBkZWxldGVBbGxSb3coMTpUZXh0IHRhYmxlTmFtZSwgMjpUZXh0IHJvdykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKioKKyAgICogQ29tcGxldGVseSBkZWxldGUgdGhlIHJvdydzIGNlbGxzIG1hcmtlZCB3aXRoIGEgdGltZXN0YW1wCisgICAqIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAqCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gcm93IGtleSBvZiB0aGUgcm93IHRvIGJlIGNvbXBsZXRlbHkgZGVsZXRlZC4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICovCisgIHZvaWQgZGVsZXRlQWxsUm93VHMoMTpUZXh0IHRhYmxlTmFtZSwgMjpUZXh0IHJvdywgMzppNjQgdGltZXN0YW1wKQorICAgIHRocm93cyAoMTpJT0Vycm9yIGlvKQorCisgIC8qKiAKKyAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhdCB0aGUgc3BlY2lmaWVkIHJvdyBhbmQKKyAgICogZW5kaW5nIGF0IHRoZSBsYXN0IHJvdyBpbiB0aGUgdGFibGUuICBSZXR1cm4gdGhlIHNwZWNpZmllZCBjb2x1bW5zLgorICAgKgorICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gIEl0cyBhbHNvIHBvc3NpYmxlCisgICAqIHRvIHBhc3MgYSByZWdleCBpbiB0aGUgY29sdW1uIHF1YWxpZmllci4KKyAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2Nhbi4gIHNlbmQgIiIgKGVtcHR5IHN0cmluZykgdG8KKyAgICogICAgICAgICAgICAgICAgIHN0YXJ0IGF0IHRoZSBmaXJzdCByb3cuCisgICAqCisgICAqIEByZXR1cm4gc2Nhbm5lciBpZCB0byBiZSB1c2VkIHdpdGggb3RoZXIgc2Nhbm5lciBwcm9jZWR1cmVzCisgICAqLworICBTY2FubmVySUQgc2Nhbm5lck9wZW4oMTpUZXh0IHRhYmxlTmFtZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAyOlRleHQgc3RhcnRSb3csCisgICAgICAgICAgICAgICAgICAgICAgICAzOmxpc3Q8VGV4dD4gY29sdW1ucykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYW5kIHN0b3BwaW5nIGF0IHRoZQorICAgKiBzcGVjaWZpZWQgcm93cy4gIGVuZGluZyBhdCB0aGUgbGFzdCByb3cgaW4gdGhlIHRhYmxlLiAgUmV0dXJuIHRoZQorICAgKiBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4uICBzZW5kICIiIChlbXB0eSBzdHJpbmcpIHRvCisgICAqICAgICAgICAgICAgICAgICBzdGFydCBhdCB0aGUgZmlyc3Qgcm93LgorICAgKiBAcGFyYW0gc3RvcFJvdyByb3cgdG8gc3RvcCBzY2FubmluZyBvbi4gIFRoaXMgcm93IGlzICpub3QqIGluY2x1ZGVkIGluIHRoZQorICAgKiAgICAgICAgICAgICAgICBzY2FubmVyJ3MgcmVzdWx0cworICAgKgorICAgKiBAcmV0dXJuIHNjYW5uZXIgaWQgdG8gYmUgdXNlZCB3aXRoIG90aGVyIHNjYW5uZXIgcHJvY2VkdXJlcworICAgKi8KKyAgU2Nhbm5lcklEIHNjYW5uZXJPcGVuV2l0aFN0b3AoMTpUZXh0IHRhYmxlTmFtZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDI6VGV4dCBzdGFydFJvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzpUZXh0IHN0b3BSb3csIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0Omxpc3Q8VGV4dD4gY29sdW1ucykKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKiogCisgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cgYW5kCisgICAqIGVuZGluZyBhdCB0aGUgbGFzdCByb3cgaW4gdGhlIHRhYmxlLiAgUmV0dXJuIHRoZSBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICogT25seSB2YWx1ZXMgd2l0aCB0aGUgc3BlY2lmaWVkIHRpbWVzdGFtcCBhcmUgcmV0dXJuZWQuCisgICAqCisgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLgorICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICogQHBhcmFtIHN0YXJ0Um93IHN0YXJ0aW5nIHJvdyBpbiB0YWJsZSB0byBzY2FuLiAgc2VuZCAiIiAoZW1wdHkgc3RyaW5nKSB0bworICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgYXQgdGhlIGZpcnN0IHJvdy4KKyAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICoKKyAgICogQHJldHVybiBzY2FubmVyIGlkIHRvIGJlIHVzZWQgd2l0aCBvdGhlciBzY2FubmVyIHByb2NlZHVyZXMKKyAgICovCisgIFNjYW5uZXJJRCBzY2FubmVyT3BlblRzKDE6VGV4dCB0YWJsZU5hbWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAyOlRleHQgc3RhcnRSb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgIDM6bGlzdDxUZXh0PiBjb2x1bW5zLAorICAgICAgICAgICAgICAgICAgICAgICAgICA0Omk2NCB0aW1lc3RhbXApCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8pCisKKyAgLyoqIAorICAgKiBHZXQgYSBzY2FubmVyIG9uIHRoZSBjdXJyZW50IHRhYmxlIHN0YXJ0aW5nIGFuZCBzdG9wcGluZyBhdCB0aGUKKyAgICogc3BlY2lmaWVkIHJvd3MuICBlbmRpbmcgYXQgdGhlIGxhc3Qgcm93IGluIHRoZSB0YWJsZS4gIFJldHVybiB0aGUKKyAgICogc3BlY2lmaWVkIGNvbHVtbnMuICBPbmx5IHZhbHVlcyB3aXRoIHRoZSBzcGVjaWZpZWQgdGltZXN0YW1wIGFyZQorICAgKiByZXR1cm5lZC4KKyAgICoKKyAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4uICBzZW5kICIiIChlbXB0eSBzdHJpbmcpIHRvCisgICAqICAgICAgICAgICAgICAgICBzdGFydCBhdCB0aGUgZmlyc3Qgcm93LgorICAgKiBAcGFyYW0gc3RvcFJvdyByb3cgdG8gc3RvcCBzY2FubmluZyBvbi4gIFRoaXMgcm93IGlzICpub3QqIGluY2x1ZGVkCisgICAqICAgICAgICAgICAgICAgIGluIHRoZSBzY2FubmVyJ3MgcmVzdWx0cworICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcAorICAgKgorICAgKiBAcmV0dXJuIHNjYW5uZXIgaWQgdG8gYmUgdXNlZCB3aXRoIG90aGVyIHNjYW5uZXIgcHJvY2VkdXJlcworICAgKi8KKyAgU2Nhbm5lcklEIHNjYW5uZXJPcGVuV2l0aFN0b3BUcygxOlRleHQgdGFibGVOYW1lLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyOlRleHQgc3RhcnRSb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMzpUZXh0IHN0b3BSb3csIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQ6bGlzdDxUZXh0PiBjb2x1bW5zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDU6aTY0IHRpbWVzdGFtcCkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbykKKworICAvKioKKyAgICogUmV0dXJucyB0aGUgc2Nhbm5lcidzIGN1cnJlbnQgcm93IHZhbHVlIGFuZCBhZHZhbmNlcyB0byB0aGUgbmV4dAorICAgKiByb3cgaW4gdGhlIHRhYmxlLiAgV2hlbiB0aGVyZSBhcmUgbm8gbW9yZSByb3dzIGluIHRoZSB0YWJsZSwgb3IgYSBrZXkKKyAgICogZ3JlYXRlci10aGFuLW9yLWVxdWFsLXRvIHRoZSBzY2FubmVyJ3Mgc3BlY2lmaWVkIHN0b3BSb3cgaXMgcmVhY2hlZCwKKyAgICogYW4gZW1wdHkgbGlzdCBpcyByZXR1cm5lZC4KKyAgICoKKyAgICogQHBhcmFtIGlkIGlkIG9mIGEgc2Nhbm5lciByZXR1cm5lZCBieSBzY2FubmVyT3BlbgorICAgKiBAcmV0dXJuIGEgVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSBjdXJyZW50IHJvdyBhbmQgYSBtYXAgb2YgdGhlIGNvbHVtbnMgdG8gVENlbGxzLgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudCBpZiBTY2FubmVySUQgaXMgaW52YWxpZAorICAgKiBAdGhyb3dzIE5vdEZvdW5kIHdoZW4gdGhlIHNjYW5uZXIgcmVhY2hlcyB0aGUgZW5kCisgICAqLworICBsaXN0PFRSb3dSZXN1bHQ+IHNjYW5uZXJHZXQoMTpTY2FubmVySUQgaWQpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8sIDI6SWxsZWdhbEFyZ3VtZW50IGlhKQorCisgIC8qKgorICAgKiBSZXR1cm5zLCBzdGFydGluZyBhdCB0aGUgc2Nhbm5lcidzIGN1cnJlbnQgcm93IHZhbHVlIG5iUm93cyB3b3J0aCBvZgorICAgKiByb3dzIGFuZCBhZHZhbmNlcyB0byB0aGUgbmV4dCByb3cgaW4gdGhlIHRhYmxlLiAgV2hlbiB0aGVyZSBhcmUgbm8gbW9yZSAKKyAgICogcm93cyBpbiB0aGUgdGFibGUsIG9yIGEga2V5IGdyZWF0ZXItdGhhbi1vci1lcXVhbC10byB0aGUgc2Nhbm5lcidzIAorICAgKiBzcGVjaWZpZWQgc3RvcFJvdyBpcyByZWFjaGVkLCAgYW4gZW1wdHkgbGlzdCBpcyByZXR1cm5lZC4KKyAgICoKKyAgICogQHBhcmFtIGlkIGlkIG9mIGEgc2Nhbm5lciByZXR1cm5lZCBieSBzY2FubmVyT3BlbgorICAgKiBAcGFyYW0gbmJSb3dzIG51bWJlciBvZiByZXN1bHRzIHRvIHJlZ3R1cm4KKyAgICogQHJldHVybiBhIFRSb3dSZXN1bHQgY29udGFpbmluZyB0aGUgY3VycmVudCByb3cgYW5kIGEgbWFwIG9mIHRoZSBjb2x1bW5zIHRvIFRDZWxscy4KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnQgaWYgU2Nhbm5lcklEIGlzIGludmFsaWQKKyAgICogQHRocm93cyBOb3RGb3VuZCB3aGVuIHRoZSBzY2FubmVyIHJlYWNoZXMgdGhlIGVuZAorICAgKi8KKyAgbGlzdDxUUm93UmVzdWx0PiBzY2FubmVyR2V0TGlzdCgxOlNjYW5uZXJJRCBpZCwyOmkzMiBuYlJvd3MpCisgICAgdGhyb3dzICgxOklPRXJyb3IgaW8sIDI6SWxsZWdhbEFyZ3VtZW50IGlhKQorCisgIC8qKgorICAgKiBDbG9zZXMgdGhlIHNlcnZlci1zdGF0ZSBhc3NvY2lhdGVkIHdpdGggYW4gb3BlbiBzY2FubmVyLgorICAgKgorICAgKiBAcGFyYW0gaWQgaWQgb2YgYSBzY2FubmVyIHJldHVybmVkIGJ5IHNjYW5uZXJPcGVuCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50IGlmIFNjYW5uZXJJRCBpcyBpbnZhbGlkCisgICAqLworICB2b2lkIHNjYW5uZXJDbG9zZSgxOlNjYW5uZXJJRCBpZCkKKyAgICB0aHJvd3MgKDE6SU9FcnJvciBpbywgMjpJbGxlZ2FsQXJndW1lbnQgaWEpCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvVGhyaWZ0U2VydmVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvVGhyaWZ0U2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjA3NGU1MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9UaHJpZnRTZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDYyOSBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLkFscmVhZHlFeGlzdHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5CYXRjaE11dGF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLkhiYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuSU9FcnJvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLklsbGVnYWxBcmd1bWVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLk11dGF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuVFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5UQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLlRSb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5URXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnByb3RvY29sLlRCaW5hcnlQcm90b2NvbDsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC5UUHJvdG9jb2xGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnNlcnZlci5UU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnNlcnZlci5UVGhyZWFkUG9vbFNlcnZlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC50cmFuc3BvcnQuVFNlcnZlclNvY2tldDsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC50cmFuc3BvcnQuVFNlcnZlclRyYW5zcG9ydDsKKworLyoqCisgKiBUaHJpZnRTZXJ2ZXIgLSB0aGlzIGNsYXNzIHN0YXJ0cyB1cCBhIFRocmlmdCBzZXJ2ZXIgd2hpY2ggaW1wbGVtZW50cyB0aGUKKyAqIEhiYXNlIEFQSSBzcGVjaWZpZWQgaW4gdGhlIEhiYXNlLnRocmlmdCBJREwgZmlsZS4KKyAqLworcHVibGljIGNsYXNzIFRocmlmdFNlcnZlciB7CisgIAorICAvKioKKyAgICogVGhlIEhCYXNlSGFuZGxlciBpcyBhIGdsdWUgb2JqZWN0IHRoYXQgY29ubmVjdHMgVGhyaWZ0IFJQQyBjYWxscyB0byB0aGUKKyAgICogSEJhc2UgY2xpZW50IEFQSSBwcmltYXJpbHkgZGVmaW5lZCBpbiB0aGUgSEJhc2VBZG1pbiBhbmQgSFRhYmxlIG9iamVjdHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEhCYXNlSGFuZGxlciBpbXBsZW1lbnRzIEhiYXNlLklmYWNlIHsKKyAgICBwcm90ZWN0ZWQgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgcHJvdGVjdGVkIEhCYXNlQWRtaW4gYWRtaW4gPSBudWxsOworICAgIHByb3RlY3RlZCBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisKKyAgICAvLyBuZXh0U2Nhbm5lcklkIGFuZCBzY2FubmVyTWFwIGFyZSB1c2VkIHRvIG1hbmFnZSBzY2FubmVyIHN0YXRlCisgICAgcHJvdGVjdGVkIGludCBuZXh0U2Nhbm5lcklkID0gMDsKKyAgICBwcm90ZWN0ZWQgSGFzaE1hcDxJbnRlZ2VyLCBTY2FubmVyPiBzY2FubmVyTWFwID0gbnVsbDsKKyAgICAKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgdGhlIGNvbHVtbiBmYW1pbGllcyBmb3IgYSBnaXZlbiBodGFibGUuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBieXRlW11bXSBnZXRBbGxDb2x1bW5zKEhUYWJsZSB0YWJsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yW10gY2RzID0gdGFibGUuZ2V0VGFibGVEZXNjcmlwdG9yKCkuZ2V0Q29sdW1uRmFtaWxpZXMoKTsKKyAgICAgIGJ5dGVbXVtdIGNvbHVtbnMgPSBuZXcgYnl0ZVtjZHMubGVuZ3RoXVtdOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZHMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgY29sdW1uc1tpXSA9IGNkc1tpXS5nZXROYW1lV2l0aENvbG9uKCk7CisgICAgICB9CisgICAgICByZXR1cm4gY29sdW1uczsKKyAgICB9CisgICAgICAgICAgCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhbmQgcmV0dXJucyBhbiBIVGFibGUgaW5zdGFuY2UgZnJvbSBhIGdpdmVuIHRhYmxlIG5hbWUuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqICAgICAgICAgIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcmV0dXJuIEhUYWJsZSBvYmplY3QKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHRocm93cyBJT0Vycm9yCisgICAgICovCisgICAgcHJvdGVjdGVkIEhUYWJsZSBnZXRUYWJsZShmaW5hbCBieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwKKyAgICAgICAgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIG5ldyBIVGFibGUodGhpcy5jb25mLCB0YWJsZU5hbWUpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBBc3NpZ25zIGEgdW5pcXVlIElEIHRvIHRoZSBzY2FubmVyIGFuZCBhZGRzIHRoZSBtYXBwaW5nIHRvIGFuIGludGVybmFsCisgICAgICogaGFzaC1tYXAuCisgICAgICogCisgICAgICogQHBhcmFtIHNjYW5uZXIKKyAgICAgKiBAcmV0dXJuIGludGVnZXIgc2Nhbm5lciBpZAorICAgICAqLworICAgIHByb3RlY3RlZCBzeW5jaHJvbml6ZWQgaW50IGFkZFNjYW5uZXIoU2Nhbm5lciBzY2FubmVyKSB7CisgICAgICBpbnQgaWQgPSBuZXh0U2Nhbm5lcklkKys7CisgICAgICBzY2FubmVyTWFwLnB1dChpZCwgc2Nhbm5lcik7CisgICAgICByZXR1cm4gaWQ7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIHNjYW5uZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuCisgICAgICogCisgICAgICogQHBhcmFtIGlkCisgICAgICogQHJldHVybiBhIFNjYW5uZXIsIG9yIG51bGwgaWYgSUQgd2FzIGludmFsaWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBTY2FubmVyIGdldFNjYW5uZXIoaW50IGlkKSB7CisgICAgICByZXR1cm4gc2Nhbm5lck1hcC5nZXQoaWQpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSZW1vdmVzIHRoZSBzY2FubmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIElEIGZyb20gdGhlIGludGVybmFsCisgICAgICogaWQtPnNjYW5uZXIgaGFzaC1tYXAuCisgICAgICogCisgICAgICogQHBhcmFtIGlkCisgICAgICogQHJldHVybiBhIFNjYW5uZXIsIG9yIG51bGwgaWYgSUQgd2FzIGludmFsaWQuCisgICAgICovCisgICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBTY2FubmVyIHJlbW92ZVNjYW5uZXIoaW50IGlkKSB7CisgICAgICByZXR1cm4gc2Nhbm5lck1hcC5yZW1vdmUoaWQpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGFuIEhCYXNlSGFuZGxlciBvYmplY3QuCisgICAgICogCisgICAgICogQHRocm93cyBNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgSEJhc2VIYW5kbGVyKCkgdGhyb3dzIE1hc3Rlck5vdFJ1bm5pbmdFeGNlcHRpb24geworICAgICAgY29uZiA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKyAgICAgIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgICBzY2FubmVyTWFwID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgU2Nhbm5lcj4oKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgZW5hYmxlVGFibGUoZmluYWwgYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5eworICAgICAgICBhZG1pbi5lbmFibGVUYWJsZSh0YWJsZU5hbWUpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGRpc2FibGVUYWJsZShmaW5hbCBieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvcnsKKyAgICAgIHRyeXsKKyAgICAgICAgYWRtaW4uZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIGJvb2xlYW4gaXNUYWJsZUVuYWJsZWQoZmluYWwgYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5IHsKKyAgICAgICAgcmV0dXJuIEhUYWJsZS5pc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGNvbXBhY3QoYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5eworICAgICAgICBhZG1pbi5jb21wYWN0KHRhYmxlTmFtZU9yUmVnaW9uTmFtZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtYWpvckNvbXBhY3QoYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5eworICAgICAgICBhZG1pbi5tYWpvckNvbXBhY3QodGFibGVOYW1lT3JSZWdpb25OYW1lKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfSAgICAKKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8Ynl0ZVtdPiBnZXRUYWJsZU5hbWVzKCkgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5IHsKKyAgICAgICAgSFRhYmxlRGVzY3JpcHRvcltdIHRhYmxlcyA9IHRoaXMuYWRtaW4ubGlzdFRhYmxlcygpOworICAgICAgICBBcnJheUxpc3Q8Ynl0ZVtdPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxieXRlW10+KHRhYmxlcy5sZW5ndGgpOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRhYmxlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgIGxpc3QuYWRkKHRhYmxlc1tpXS5nZXROYW1lKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBsaXN0OworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyBMaXN0PFRSZWdpb25JbmZvPiBnZXRUYWJsZVJlZ2lvbnMoYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICB0aHJvd3MgSU9FcnJvciB7CisgICAgICB0cnl7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIE1hcDxIUmVnaW9uSW5mbywgSFNlcnZlckFkZHJlc3M+IHJlZ2lvbnNJbmZvID0gdGFibGUuZ2V0UmVnaW9uc0luZm8oKTsKKyAgICAgICAgTGlzdDxUUmVnaW9uSW5mbz4gcmVnaW9ucyA9IG5ldyBBcnJheUxpc3Q8VFJlZ2lvbkluZm8+KCk7CisKKyAgICAgICAgZm9yIChIUmVnaW9uSW5mbyByZWdpb25JbmZvIDogcmVnaW9uc0luZm8ua2V5U2V0KCkpeworICAgICAgICAgIFRSZWdpb25JbmZvIHJlZ2lvbiA9IG5ldyBUUmVnaW9uSW5mbygpOworICAgICAgICAgIHJlZ2lvbi5zdGFydEtleSA9IHJlZ2lvbkluZm8uZ2V0U3RhcnRLZXkoKTsKKyAgICAgICAgICByZWdpb24uZW5kS2V5ID0gcmVnaW9uSW5mby5nZXRFbmRLZXkoKTsKKyAgICAgICAgICByZWdpb24uaWQgPSByZWdpb25JbmZvLmdldFJlZ2lvbklkKCk7CisgICAgICAgICAgcmVnaW9uLm5hbWUgPSByZWdpb25JbmZvLmdldFJlZ2lvbk5hbWUoKTsKKyAgICAgICAgICByZWdpb24udmVyc2lvbiA9IHJlZ2lvbkluZm8uZ2V0VmVyc2lvbigpOworICAgICAgICAgIHJlZ2lvbnMuYWRkKHJlZ2lvbik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlZ2lvbnM7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKXsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4pCisgICAgICAgIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIENlbGwgY2VsbCA9IHRhYmxlLmdldChyb3csIGNvbHVtbik7CisgICAgICAgIHJldHVybiBUaHJpZnRVdGlsaXRpZXMuY2VsbEZyb21IQmFzZShjZWxsKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0VmVyKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csCisgICAgICAgIGJ5dGVbXSBjb2x1bW4sIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXJyb3IgeworICAgICAgdHJ5IHsKKyAgICAgICAgSFRhYmxlIHRhYmxlID0gZ2V0VGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgQ2VsbFtdIGNlbGxzID0gCisgICAgICAgICAgdGFibGUuZ2V0KHJvdywgY29sdW1uLCBudW1WZXJzaW9ucyk7CisgICAgICAgIHJldHVybiBUaHJpZnRVdGlsaXRpZXMuY2VsbEZyb21IQmFzZShjZWxscyk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VENlbGw+IGdldFZlclRzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csCisgICAgICAgIGJ5dGVbXSBjb2x1bW4sIGxvbmcgdGltZXN0YW1wLCBpbnQgbnVtVmVyc2lvbnMpIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIENlbGxbXSBjZWxscyA9IHRhYmxlLmdldChyb3csIGNvbHVtbiwgdGltZXN0YW1wLCBudW1WZXJzaW9ucyk7CisgICAgICAgIHJldHVybiBUaHJpZnRVdGlsaXRpZXMuY2VsbEZyb21IQmFzZShjZWxscyk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3cpCisgICAgICAgIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHJldHVybiBnZXRSb3dXaXRoQ29sdW1uc1RzKHRhYmxlTmFtZSwgcm93LCBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93V2l0aENvbHVtbnMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywKKyAgICAgICAgTGlzdDxieXRlW10+IGNvbHVtbnMpIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHJldHVybiBnZXRSb3dXaXRoQ29sdW1uc1RzKHRhYmxlTmFtZSwgcm93LCBjb2x1bW5zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93VHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywKKyAgICAgICAgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHJldHVybiBnZXRSb3dXaXRoQ29sdW1uc1RzKHRhYmxlTmFtZSwgcm93LCBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93V2l0aENvbHVtbnNUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LAorICAgICAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIGlmIChjb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgICByZXR1cm4gVGhyaWZ0VXRpbGl0aWVzLnJvd1Jlc3VsdEZyb21IQmFzZSh0YWJsZS5nZXRSb3cocm93LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXApKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW11bXSBjb2x1bW5BcnIgPSBjb2x1bW5zLnRvQXJyYXkobmV3IGJ5dGVbY29sdW1ucy5zaXplKCldW10pOworICAgICAgICByZXR1cm4gVGhyaWZ0VXRpbGl0aWVzLnJvd1Jlc3VsdEZyb21IQmFzZSh0YWJsZS5nZXRSb3cocm93LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uQXJyLCB0aW1lc3RhbXApKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbikKKyAgICAgICAgdGhyb3dzIElPRXJyb3IgeworICAgICAgZGVsZXRlQWxsVHModGFibGVOYW1lLCByb3csIGNvbHVtbiwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgZGVsZXRlQWxsVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwKKyAgICAgICAgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIHRhYmxlLmRlbGV0ZUFsbChyb3csIGNvbHVtbiwgdGltZXN0YW1wKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVBbGxSb3coYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdykgdGhyb3dzIElPRXJyb3IgeworICAgICAgZGVsZXRlQWxsUm93VHModGFibGVOYW1lLCByb3csIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbFJvd1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGxvbmcgdGltZXN0YW1wKQorICAgICAgICB0aHJvd3MgSU9FcnJvciB7CisgICAgICB0cnkgeworICAgICAgICBIVGFibGUgdGFibGUgPSBnZXRUYWJsZSh0YWJsZU5hbWUpOworICAgICAgICB0YWJsZS5kZWxldGVBbGwocm93LCB0aW1lc3RhbXApOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGNyZWF0ZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICAgIExpc3Q8Q29sdW1uRGVzY3JpcHRvcj4gY29sdW1uRmFtaWxpZXMpIHRocm93cyBJT0Vycm9yLAorICAgICAgICBJbGxlZ2FsQXJndW1lbnQsIEFscmVhZHlFeGlzdHMgeworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKGFkbWluLnRhYmxlRXhpc3RzKHRhYmxlTmFtZSkpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgQWxyZWFkeUV4aXN0cygidGFibGUgbmFtZSBhbHJlYWR5IGluIHVzZSIpOworICAgICAgICB9CisgICAgICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlTmFtZSk7CisgICAgICAgIGZvciAoQ29sdW1uRGVzY3JpcHRvciBjb2wgOiBjb2x1bW5GYW1pbGllcykgeworICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yIGNvbERlc2MgPSBUaHJpZnRVdGlsaXRpZXMuY29sRGVzY0Zyb21UaHJpZnQoY29sKTsKKyAgICAgICAgICBkZXNjLmFkZEZhbWlseShjb2xEZXNjKTsKKyAgICAgICAgfQorICAgICAgICBhZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudChlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGRlbGV0ZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0Vycm9yIHsKKyAgICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgICBMT0cuZGVidWcoImRlbGV0ZVRhYmxlOiB0YWJsZT0iICsgbmV3IFN0cmluZyh0YWJsZU5hbWUpKTsKKyAgICAgIH0KKyAgICAgIHRyeSB7CisgICAgICAgIGlmICghYWRtaW4udGFibGVFeGlzdHModGFibGVOYW1lKSkgeworICAgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKCJ0YWJsZSBkb2VzIG5vdCBleGlzdCIpOworICAgICAgICB9CisgICAgICAgIGFkbWluLmRlbGV0ZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgbXV0YXRlUm93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csCisgICAgICAgIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucykgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCB7CisgICAgICBtdXRhdGVSb3dUcyh0YWJsZU5hbWUsIHJvdywgbXV0YXRpb25zLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBtdXRhdGVSb3dUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LAorICAgICAgICBMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG51bGw7CisgICAgICB0cnkgeworICAgICAgICB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdGltZXN0YW1wKTsKKyAgICAgICAgZm9yIChNdXRhdGlvbiBtIDogbXV0YXRpb25zKSB7CisgICAgICAgICAgaWYgKG0uaXNEZWxldGUpIHsKKyAgICAgICAgICAgIGJhdGNoVXBkYXRlLmRlbGV0ZShtLmNvbHVtbik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGJhdGNoVXBkYXRlLnB1dChtLmNvbHVtbiwgbS52YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRhYmxlLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnQoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBtdXRhdGVSb3dzKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykgCisgICAgICAgIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24geworICAgICAgbXV0YXRlUm93c1RzKHRhYmxlTmFtZSwgcm93QmF0Y2hlcywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICB9CisgCisgICAgcHVibGljIHZvaWQgbXV0YXRlUm93c1RzKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcywgbG9uZyB0aW1lc3RhbXApCisgICAgICAgIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24geworICAgICAgTGlzdDxCYXRjaFVwZGF0ZT4gYmF0Y2hVcGRhdGVzID0gbmV3IEFycmF5TGlzdDxCYXRjaFVwZGF0ZT4oKTsKKyAgICAgICAKKyAgICAgIGZvciAoQmF0Y2hNdXRhdGlvbiBiYXRjaCA6IHJvd0JhdGNoZXMpIHsKKyAgICAgICAgYnl0ZVtdIHJvdyA9IGJhdGNoLnJvdzsKKyAgICAgICAgTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zID0gYmF0Y2gubXV0YXRpb25zOworICAgICAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3csIHRpbWVzdGFtcCk7CisgICAgICAgIGZvciAoTXV0YXRpb24gbSA6IG11dGF0aW9ucykgeworICAgICAgICAgIGlmIChtLmlzRGVsZXRlKSB7CisgICAgICAgICAgICBiYXRjaFVwZGF0ZS5kZWxldGUobS5jb2x1bW4pOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBiYXRjaFVwZGF0ZS5wdXQobS5jb2x1bW4sIG0udmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBiYXRjaFVwZGF0ZXMuYWRkKGJhdGNoVXBkYXRlKTsKKyAgICAgIH0KKworICAgICAgSFRhYmxlIHRhYmxlID0gbnVsbDsKKyAgICAgIHRyeSB7CisgICAgICAgIHRhYmxlID0gZ2V0VGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgdGFibGUuY29tbWl0KGJhdGNoVXBkYXRlcyk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnQoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGF0b21pY0luY3JlbWVudChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uLCBsb25nIGFtb3VudCkgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbiB7CisgICAgICBIVGFibGUgdGFibGU7CisgICAgICB0cnkgeworICAgICAgICB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIHJldHVybiB0YWJsZS5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgYW1vdW50KTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNjYW5uZXJDbG9zZShpbnQgaWQpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQgeworICAgICAgTE9HLmRlYnVnKCJzY2FubmVyQ2xvc2U6IGlkPSIgKyBpZCk7CisgICAgICBTY2FubmVyIHNjYW5uZXIgPSBnZXRTY2FubmVyKGlkKTsKKyAgICAgIGlmIChzY2FubmVyID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudCgic2Nhbm5lciBJRCBpcyBpbnZhbGlkIik7CisgICAgICB9CisgICAgICBzY2FubmVyLmNsb3NlKCk7CisgICAgICByZW1vdmVTY2FubmVyKGlkKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gc2Nhbm5lckdldExpc3QoaW50IGlkLGludCBuYlJvd3MpIHRocm93cyBJbGxlZ2FsQXJndW1lbnQsIElPRXJyb3IgeworICAgICAgICBMT0cuZGVidWcoInNjYW5uZXJHZXRMaXN0OiBpZD0iICsgaWQpOworICAgICAgICBTY2FubmVyIHNjYW5uZXIgPSBnZXRTY2FubmVyKGlkKTsKKyAgICAgICAgaWYgKG51bGwgPT0gc2Nhbm5lcikgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudCgic2Nhbm5lciBJRCBpcyBpbnZhbGlkIik7CisgICAgICAgIH0KKworICAgICAgICBSb3dSZXN1bHQgW10gcmVzdWx0cyA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICByZXN1bHRzID0gc2Nhbm5lci5uZXh0KG5iUm93cyk7CisgICAgICAgICAgICBpZiAobnVsbCA9PSByZXN1bHRzKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheUxpc3Q8VFJvd1Jlc3VsdD4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgICB9CisgICAgICAgIHJldHVybiBUaHJpZnRVdGlsaXRpZXMucm93UmVzdWx0RnJvbUhCYXNlKHJlc3VsdHMpOworICAgIH0KKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBzY2FubmVyR2V0KGludCBpZCkgdGhyb3dzIElsbGVnYWxBcmd1bWVudCwgSU9FcnJvciB7CisgICAgICAgIHJldHVybiBzY2FubmVyR2V0TGlzdChpZCwxKTsKKyAgICB9CisgICAgcHVibGljIGludCBzY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBieXRlW10gc3RhcnRSb3csCisgICAgICAgICAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucykgdGhyb3dzIElPRXJyb3IgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgSFRhYmxlIHRhYmxlID0gZ2V0VGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgICAgIGJ5dGVbXVtdIGNvbHVtbnNBcnJheSA9IG51bGw7CisgICAgICAgICAgICBpZiAoKGNvbHVtbnMgPT0gbnVsbCkgfHwgKGNvbHVtbnMuc2l6ZSgpID09IDApKSB7CisgICAgICAgICAgICAgICAgY29sdW1uc0FycmF5ID0gZ2V0QWxsQ29sdW1ucyh0YWJsZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY29sdW1uc0FycmF5ID0gY29sdW1ucy50b0FycmF5KG5ldyBieXRlWzBdW10pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBhZGRTY2FubmVyKHRhYmxlLmdldFNjYW5uZXIoY29sdW1uc0FycmF5LCBzdGFydFJvdykpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FcnJvcihlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHB1YmxpYyBpbnQgc2Nhbm5lck9wZW5XaXRoU3RvcChieXRlW10gdGFibGVOYW1lLCBieXRlW10gc3RhcnRSb3csCisgICAgICAgIGJ5dGVbXSBzdG9wUm93LCBMaXN0PGJ5dGVbXT4gY29sdW1ucykgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24geworICAgICAgdHJ5IHsKKyAgICAgICAgSFRhYmxlIHRhYmxlID0gZ2V0VGFibGUodGFibGVOYW1lKTsKKyAgICAgICAgYnl0ZVtdW10gY29sdW1uc0FycmF5ID0gbnVsbDsKKyAgICAgICAgaWYgKChjb2x1bW5zID09IG51bGwpIHx8IChjb2x1bW5zLnNpemUoKSA9PSAwKSkgeworICAgICAgICAgIGNvbHVtbnNBcnJheSA9IGdldEFsbENvbHVtbnModGFibGUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGNvbHVtbnNBcnJheSA9IGNvbHVtbnMudG9BcnJheShuZXcgYnl0ZVswXVtdKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYWRkU2Nhbm5lcih0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnNBcnJheSwgc3RhcnRSb3csIHN0b3BSb3cpKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LAorICAgICAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIGJ5dGVbXVtdIGNvbHVtbnNBcnJheSA9IG51bGw7CisgICAgICAgIGlmICgoY29sdW1ucyA9PSBudWxsKSB8fCAoY29sdW1ucy5zaXplKCkgPT0gMCkpIHsKKyAgICAgICAgICBjb2x1bW5zQXJyYXkgPSBnZXRBbGxDb2x1bW5zKHRhYmxlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBjb2x1bW5zQXJyYXkgPSBjb2x1bW5zLnRvQXJyYXkobmV3IGJ5dGVbMF1bXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFkZFNjYW5uZXIodGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zQXJyYXksIHN0YXJ0Um93LCB0aW1lc3RhbXApKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuV2l0aFN0b3BUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gc3RhcnRSb3csCisgICAgICAgIGJ5dGVbXSBzdG9wUm93LCBMaXN0PGJ5dGVbXT4gY29sdW1ucywgbG9uZyB0aW1lc3RhbXApCisgICAgICAgIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIGJ5dGVbXVtdIGNvbHVtbnNBcnJheSA9IG51bGw7CisgICAgICAgIGlmICgoY29sdW1ucyA9PSBudWxsKSB8fCAoY29sdW1ucy5zaXplKCkgPT0gMCkpIHsKKyAgICAgICAgICBjb2x1bW5zQXJyYXkgPSBnZXRBbGxDb2x1bW5zKHRhYmxlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBjb2x1bW5zQXJyYXkgPSBjb2x1bW5zLnRvQXJyYXkobmV3IGJ5dGVbMF1bXSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGFkZFNjYW5uZXIodGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zQXJyYXksIHN0YXJ0Um93LCBzdG9wUm93LAorICAgICAgICAgICAgdGltZXN0YW1wKSk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0Vycm9yKGUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgcHVibGljIE1hcDxieXRlW10sIENvbHVtbkRlc2NyaXB0b3I+IGdldENvbHVtbkRlc2NyaXB0b3JzKAorICAgICAgICBieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbiB7CisgICAgICB0cnkgeworICAgICAgICBUcmVlTWFwPGJ5dGVbXSwgQ29sdW1uRGVzY3JpcHRvcj4gY29sdW1ucyA9CisgICAgICAgICAgbmV3IFRyZWVNYXA8Ynl0ZVtdLCBDb2x1bW5EZXNjcmlwdG9yPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICAgICAgCisgICAgICAgIEhUYWJsZSB0YWJsZSA9IGdldFRhYmxlKHRhYmxlTmFtZSk7CisgICAgICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IHRhYmxlLmdldFRhYmxlRGVzY3JpcHRvcigpOworICAgICAgICAKKyAgICAgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBlIDogZGVzYy5nZXRGYW1pbGllcygpKSB7CisgICAgICAgICAgQ29sdW1uRGVzY3JpcHRvciBjb2wgPSBUaHJpZnRVdGlsaXRpZXMuY29sRGVzY0Zyb21IYmFzZShlKTsKKyAgICAgICAgICBjb2x1bW5zLnB1dChjb2wubmFtZSwgY29sKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gY29sdW1uczsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXJyb3IoZS5nZXRNZXNzYWdlKCkpOworICAgICAgfQorICAgIH0gICAgCisgIH0KKyAgCisgIC8vCisgIC8vIE1haW4gcHJvZ3JhbSBhbmQgc3VwcG9ydCByb3V0aW5lcworICAvLworICAKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFVzYWdlQW5kRXhpdCgpIHsKKyAgICBwcmludFVzYWdlQW5kRXhpdChudWxsKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFVzYWdlQW5kRXhpdChmaW5hbCBTdHJpbmcgbWVzc2FnZSkgeworICAgIGlmIChtZXNzYWdlICE9IG51bGwpIHsKKyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtZXNzYWdlKTsKKyAgICB9CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJVc2FnZTogamF2YSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuVGhyaWZ0U2VydmVyICIgKworICAgICAgIi0taGVscCB8IFstLXBvcnQ9UE9SVF0gc3RhcnQiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkFyZ3VtZW50czoiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiBzdGFydCBTdGFydCB0aHJpZnQgc2VydmVyIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIgc3RvcCAgU3RvcCB0aHJpZnQgc2VydmVyIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJPcHRpb25zOiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIHBvcnQgIFBvcnQgdG8gbGlzdGVuIG9uLiBEZWZhdWx0OiA5MDkwIik7CisgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCIgYmluZCAgQWRkcmVzcyB0byBiaW5kIG9uLiBEZWZhdWx0OiAwLjAuMC4wLiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIGhlbHAgIFByaW50IHRoaXMgbWVzc2FnZSBhbmQgZXhpdCIpOworICAgIFN5c3RlbS5leGl0KDApOworICB9CisKKyAgLyoKKyAgICogU3RhcnQgdXAgdGhlIFRocmlmdCBzZXJ2ZXIuCisgICAqIEBwYXJhbSBhcmdzCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZG9NYWluKGZpbmFsIFN0cmluZyBbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpZiAoYXJncy5sZW5ndGggPCAxKSB7CisgICAgICBwcmludFVzYWdlQW5kRXhpdCgpOworICAgIH0KKworICAgIGludCBwb3J0ID0gOTA5MDsKKyAgICAvLyBTdHJpbmcgYmluZEFkZHJlc3MgPSAiMC4wLjAuMCI7CisKKyAgICAvLyBQcm9jZXNzIGNvbW1hbmQtbGluZSBhcmdzLiBUT0RPOiBCZXR0ZXIgY21kLWxpbmUgcHJvY2Vzc2luZworICAgIC8vIChidXQgaG9wZWZ1bGx5IHNvbWV0aGluZyBub3QgYXMgcGFpbmZ1bCBhcyBjbGkgb3B0aW9ucykuCisvLyAgICBmaW5hbCBTdHJpbmcgYWRkcmVzc0FyZ0tleSA9ICItLWJpbmQ9IjsKKyAgICBmaW5hbCBTdHJpbmcgcG9ydEFyZ0tleSA9ICItLXBvcnQ9IjsKKyAgICBmb3IgKFN0cmluZyBjbWQ6IGFyZ3MpIHsKKy8vICAgICAgaWYgKGNtZC5zdGFydHNXaXRoKGFkZHJlc3NBcmdLZXkpKSB7CisvLyAgICAgICAgYmluZEFkZHJlc3MgPSBjbWQuc3Vic3RyaW5nKGFkZHJlc3NBcmdLZXkubGVuZ3RoKCkpOworLy8gICAgICAgIGNvbnRpbnVlOworLy8gICAgICB9IGVsc2UgCisgICAgICBpZiAoY21kLnN0YXJ0c1dpdGgocG9ydEFyZ0tleSkpIHsKKyAgICAgICAgcG9ydCA9IEludGVnZXIucGFyc2VJbnQoY21kLnN1YnN0cmluZyhwb3J0QXJnS2V5Lmxlbmd0aCgpKSk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfSBlbHNlIGlmIChjbWQuZXF1YWxzKCItLWhlbHAiKSB8fCBjbWQuZXF1YWxzKCItaCIpKSB7CisgICAgICAgIHByaW50VXNhZ2VBbmRFeGl0KCk7CisgICAgICB9IGVsc2UgaWYgKGNtZC5lcXVhbHMoInN0YXJ0IikpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9IGVsc2UgaWYgKGNtZC5lcXVhbHMoInN0b3AiKSkgeworICAgICAgICBwcmludFVzYWdlQW5kRXhpdCgiVG8gc2h1dGRvd24gdGhlIHRocmlmdCBzZXJ2ZXIgcnVuICIgKworICAgICAgICAgICJiaW4vaGJhc2UtZGFlbW9uLnNoIHN0b3AgdGhyaWZ0IG9yIHNlbmQgYSBraWxsIHNpZ25hbCB0byAiICsKKyAgICAgICAgICAidGhlIHRocmlmdCBzZXJ2ZXIgcGlkIik7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIFByaW50IG91dCB1c2FnZSBpZiB3ZSBnZXQgdG8gaGVyZS4KKyAgICAgIHByaW50VXNhZ2VBbmRFeGl0KCk7CisgICAgfQorICAgIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZygiVGhyaWZ0U2VydmVyIik7CisgICAgTE9HLmluZm8oInN0YXJ0aW5nIEhCYXNlIFRocmlmdCBzZXJ2ZXIgb24gcG9ydCAiICsKKyAgICAgIEludGVnZXIudG9TdHJpbmcocG9ydCkpOworICAgIEhCYXNlSGFuZGxlciBoYW5kbGVyID0gbmV3IEhCYXNlSGFuZGxlcigpOworICAgIEhiYXNlLlByb2Nlc3NvciBwcm9jZXNzb3IgPSBuZXcgSGJhc2UuUHJvY2Vzc29yKGhhbmRsZXIpOworICAgIFRTZXJ2ZXJUcmFuc3BvcnQgc2VydmVyVHJhbnNwb3J0ID0gbmV3IFRTZXJ2ZXJTb2NrZXQocG9ydCk7CisgICAgVFByb3RvY29sRmFjdG9yeSBwcm90RmFjdG9yeSA9IG5ldyBUQmluYXJ5UHJvdG9jb2wuRmFjdG9yeSh0cnVlLCB0cnVlKTsKKyAgICBUU2VydmVyIHNlcnZlciA9IG5ldyBUVGhyZWFkUG9vbFNlcnZlcihwcm9jZXNzb3IsIHNlcnZlclRyYW5zcG9ydCwKKyAgICAgIHByb3RGYWN0b3J5KTsKKyAgICBzZXJ2ZXIuc2VydmUoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIFtdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIGRvTWFpbihhcmdzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L1RocmlmdFV0aWxpdGllcy5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L1RocmlmdFV0aWxpdGllcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwNmU4NjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvVGhyaWZ0VXRpbGl0aWVzLmphdmEKQEAgLTAsMCArMSwxNTQgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkNvbXByZXNzaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLklsbGVnYWxBcmd1bWVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLlRDZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuVFJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgVGhyaWZ0VXRpbGl0aWVzIHsKKyAgCisgIC8qKgorICAgKiBUaGlzIHV0aWxpdHkgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgSGJhc2UgSENvbHVtbkRlc2NyaXB0b3Igb2JqZWN0IGJhc2VkIG9uIGEKKyAgICogVGhyaWZ0IENvbHVtbkRlc2NyaXB0b3IgInN0cnVjdCIuCisgICAqIAorICAgKiBAcGFyYW0gaW4KKyAgICogICAgICAgICAgVGhyaWZ0IENvbHVtbkRlc2NyaXB0b3Igb2JqZWN0CisgICAqIEByZXR1cm4gSENvbHVtbkRlc2NyaXB0b3IKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnQKKyAgICovCisgIHN0YXRpYyBwdWJsaWMgSENvbHVtbkRlc2NyaXB0b3IgY29sRGVzY0Zyb21UaHJpZnQoQ29sdW1uRGVzY3JpcHRvciBpbikKKyAgICAgIHRocm93cyBJbGxlZ2FsQXJndW1lbnQgeworICAgIENvbXByZXNzaW9uLkFsZ29yaXRobSBjb21wID0KKyAgICAgIENvbXByZXNzaW9uLmdldENvbXByZXNzaW9uQWxnb3JpdGhtQnlOYW1lKGluLmNvbXByZXNzaW9uLnRvTG93ZXJDYXNlKCkpOworICAgIGJvb2xlYW4gYmxvb20gPSBmYWxzZTsKKyAgICBpZiAoaW4uYmxvb21GaWx0ZXJUeXBlLmNvbXBhcmVUbygiTk9ORSIpICE9IDApIHsKKyAgICAgIGJsb29tID0gdHJ1ZTsKKyAgICB9CisgICAgCisgICAgaWYgKGluLm5hbWUgPT0gbnVsbCB8fCBpbi5uYW1lLmxlbmd0aCA8PSAwKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50KCJjb2x1bW4gbmFtZSBpcyBlbXB0eSIpOworICAgIH0KKyAgICBIQ29sdW1uRGVzY3JpcHRvciBjb2wgPSBuZXcgSENvbHVtbkRlc2NyaXB0b3IoaW4ubmFtZSwKKyAgICAgICAgaW4ubWF4VmVyc2lvbnMsIGNvbXAuZ2V0TmFtZSgpLCBpbi5pbk1lbW9yeSwgaW4uYmxvY2tDYWNoZUVuYWJsZWQsCisgICAgICAgIGluLm1heFZhbHVlTGVuZ3RoLCBpbi50aW1lVG9MaXZlLCBibG9vbSk7CisgICAgcmV0dXJuIGNvbDsKKyAgfQorICAKKyAgLyoqCisgICAqIFRoaXMgdXRpbGl0eSBtZXRob2QgY3JlYXRlcyBhIG5ldyBUaHJpZnQgQ29sdW1uRGVzY3JpcHRvciAic3RydWN0IiBiYXNlZCBvbgorICAgKiBhbiBIYmFzZSBIQ29sdW1uRGVzY3JpcHRvciBvYmplY3QuCisgICAqIAorICAgKiBAcGFyYW0gaW4KKyAgICogICAgICAgICAgSGJhc2UgSENvbHVtbkRlc2NyaXB0b3Igb2JqZWN0CisgICAqIEByZXR1cm4gVGhyaWZ0IENvbHVtbkRlc2NyaXB0b3IKKyAgICovCisgIHN0YXRpYyBwdWJsaWMgQ29sdW1uRGVzY3JpcHRvciBjb2xEZXNjRnJvbUhiYXNlKEhDb2x1bW5EZXNjcmlwdG9yIGluKSB7CisgICAgQ29sdW1uRGVzY3JpcHRvciBjb2wgPSBuZXcgQ29sdW1uRGVzY3JpcHRvcigpOworICAgIGNvbC5uYW1lID0gaW4uZ2V0TmFtZSgpOworICAgIGNvbC5tYXhWZXJzaW9ucyA9IGluLmdldE1heFZlcnNpb25zKCk7CisgICAgY29sLmNvbXByZXNzaW9uID0gaW4uZ2V0Q29tcHJlc3Npb24oKS50b1N0cmluZygpOworICAgIGNvbC5pbk1lbW9yeSA9IGluLmlzSW5NZW1vcnkoKTsKKyAgICBjb2wuYmxvY2tDYWNoZUVuYWJsZWQgPSBpbi5pc0Jsb2NrQ2FjaGVFbmFibGVkKCk7CisgICAgY29sLm1heFZhbHVlTGVuZ3RoID0gaW4uZ2V0TWF4VmFsdWVMZW5ndGgoKTsKKyAgICBjb2wuYmxvb21GaWx0ZXJUeXBlID0gQm9vbGVhbi50b1N0cmluZyhpbi5pc0Jsb29tZmlsdGVyKCkpOworICAgIHJldHVybiBjb2w7CisgIH0KKyAgCisgIC8qKgorICAgKiBUaGlzIHV0aWxpdHkgbWV0aG9kIGNyZWF0ZXMgYSBsaXN0IG9mIFRocmlmdCBUQ2VsbCAic3RydWN0IiBiYXNlZCBvbgorICAgKiBhbiBIYmFzZSBDZWxsIG9iamVjdC4gVGhlIGVtcHR5IGxpc3QgaXMgcmV0dXJuZWQgaWYgdGhlIGlucHV0IGlzIG51bGwuCisgICAqIAorICAgKiBAcGFyYW0gaW4KKyAgICogICAgICAgICAgSGJhc2UgQ2VsbCBvYmplY3QKKyAgICogQHJldHVybiBUaHJpZnQgVENlbGwgYXJyYXkKKyAgICovCisgIHN0YXRpYyBwdWJsaWMgTGlzdDxUQ2VsbD4gY2VsbEZyb21IQmFzZShDZWxsIGluKSB7CisgICAgTGlzdDxUQ2VsbD4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KDEpOworICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICBsaXN0LmFkZChuZXcgVENlbGwoaW4uZ2V0VmFsdWUoKSwgaW4uZ2V0VGltZXN0YW1wKCkpKTsKKyAgICB9CisgICAgcmV0dXJuIGxpc3Q7CisgIH0KKworICAvKioKKyAgICogVGhpcyB1dGlsaXR5IG1ldGhvZCBjcmVhdGVzIGEgbGlzdCBvZiBUaHJpZnQgVENlbGwgInN0cnVjdCIgYmFzZWQgb24KKyAgICogYW4gSGJhc2UgQ2VsbCBhcnJheS4gVGhlIGVtcHR5IGxpc3QgaXMgcmV0dXJuZWQgaWYgdGhlIGlucHV0IGlzIG51bGwuCisgICAqIEBwYXJhbSBpbiBIYmFzZSBDZWxsIGFycmF5CisgICAqIEByZXR1cm4gVGhyaWZ0IFRDZWxsIGFycmF5CisgICAqLworICBzdGF0aWMgcHVibGljIExpc3Q8VENlbGw+IGNlbGxGcm9tSEJhc2UoQ2VsbFtdIGluKSB7CisgICAgTGlzdDxUQ2VsbD4gbGlzdCA9IG51bGw7CisgICAgaWYgKGluICE9IG51bGwpIHsKKyAgICAgIGxpc3QgPSBuZXcgQXJyYXlMaXN0PFRDZWxsPihpbi5sZW5ndGgpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbi5sZW5ndGg7IGkrKykgeworICAgICAgICBsaXN0LmFkZChuZXcgVENlbGwoaW5baV0uZ2V0VmFsdWUoKSwgaW5baV0uZ2V0VGltZXN0YW1wKCkpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgbGlzdCA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KDApOworICAgIH0KKyAgICByZXR1cm4gbGlzdDsKKyAgfQorCisgIC8qKgorICAgKiBUaGlzIHV0aWxpdHkgbWV0aG9kIGNyZWF0ZXMgYSBsaXN0IG9mIFRocmlmdCBUUm93UmVzdWx0ICJzdHJ1Y3QiIGJhc2VkIG9uCisgICAqIGFuIEhiYXNlIFJvd1Jlc3VsdCBvYmplY3QuIFRoZSBlbXB0eSBsaXN0IGlzIHJldHVybmVkIGlmIHRoZSBpbnB1dCBpcworICAgKiBudWxsLgorICAgKiAKKyAgICogQHBhcmFtIGluCisgICAqICAgICAgICAgIEhiYXNlIFJvd1Jlc3VsdCBvYmplY3QKKyAgICogQHJldHVybiBUaHJpZnQgVFJvd1Jlc3VsdCBhcnJheQorICAgKi8KKyAgc3RhdGljIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IHJvd1Jlc3VsdEZyb21IQmFzZShSb3dSZXN1bHRbXSBpbikgeworICAgIExpc3Q8VFJvd1Jlc3VsdD4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8VFJvd1Jlc3VsdD4oKTsKKyAgICBmb3IgKCBSb3dSZXN1bHQgcmVzdWx0XyA6IGluKSB7CisgICAgICAgIGlmKG51bGwgPT0gcmVzdWx0XykgeworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgVFJvd1Jlc3VsdCByZXN1bHQgPSBuZXcgVFJvd1Jlc3VsdCgpOworICAgICAgICByZXN1bHQucm93ID0gcmVzdWx0Xy5nZXRSb3coKTsKKyAgICAgICAgcmVzdWx0LmNvbHVtbnMgPSBuZXcgVHJlZU1hcDxieXRlW10sIFRDZWxsPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZVtdLCBDZWxsPiBlbnRyeSA6IHJlc3VsdF8uZW50cnlTZXQoKSl7CisgICAgICAgICAgICBDZWxsIGNlbGwgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgcmVzdWx0LmNvbHVtbnMucHV0KGVudHJ5LmdldEtleSgpLAorICAgICAgICAgICAgICAgIG5ldyBUQ2VsbChjZWxsLmdldFZhbHVlKCksIGNlbGwuZ2V0VGltZXN0YW1wKCkpKTsKKworICAgICAgICB9CisgICAgICAgIHJlc3VsdHMuYWRkKHJlc3VsdCk7CisgICAgfQorICAgIHJldHVybiByZXN1bHRzOworICB9CisgIHN0YXRpYyBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiByb3dSZXN1bHRGcm9tSEJhc2UoUm93UmVzdWx0IGluKSB7CisgICAgUm93UmVzdWx0IFtdIHJlc3VsdCA9IHsgaW4gfTsKKyAgICByZXR1cm4gcm93UmVzdWx0RnJvbUhCYXNlKHJlc3VsdCk7CisgIH0KKworfQorCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0FscmVhZHlFeGlzdHMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9nZW5lcmF0ZWQvQWxyZWFkeUV4aXN0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiMmY2NDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0FscmVhZHlFeGlzdHMuamF2YQpAQCAtMCwwICsxLDIzOSBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEF1dG9nZW5lcmF0ZWQgYnkgVGhyaWZ0CisgKgorICogRE8gTk9UIEVESVQgVU5MRVNTIFlPVSBBUkUgU1VSRSBUSEFUIFlPVSBLTk9XIFdIQVQgWU9VIEFSRSBET0lORworICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC4qOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0Lm1ldGFfZGF0YS4qOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnByb3RvY29sLio7CisKKy8qKgorICogQW4gQWxyZWFkeUV4aXN0cyBleGNlcHRpb25zIHNpZ25hbHMgdGhhdCBhIHRhYmxlIHdpdGggdGhlIHNwZWNpZmllZAorICogbmFtZSBhbHJlYWR5IGV4aXN0cworICovCitwdWJsaWMgY2xhc3MgQWxyZWFkeUV4aXN0cyBleHRlbmRzIEV4Y2VwdGlvbiBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJBbHJlYWR5RXhpc3RzIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBNRVNTQUdFX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJtZXNzYWdlIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisKKyAgcHVibGljIFN0cmluZyBtZXNzYWdlOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFID0gMTsKKworICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgcHV0KE1FU1NBR0UsIG5ldyBGaWVsZE1ldGFEYXRhKCJtZXNzYWdlIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgfX0pOworCisgIHN0YXRpYyB7CisgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChBbHJlYWR5RXhpc3RzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgIH0KKworICBwdWJsaWMgQWxyZWFkeUV4aXN0cygpIHsKKyAgfQorCisgIHB1YmxpYyBBbHJlYWR5RXhpc3RzKAorICAgIFN0cmluZyBtZXNzYWdlKQorICB7CisgICAgdGhpcygpOworICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisgIH0KKworICAvKioKKyAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgKi8KKyAgcHVibGljIEFscmVhZHlFeGlzdHMoQWxyZWFkeUV4aXN0cyBvdGhlcikgeworICAgIGlmIChvdGhlci5pc1NldE1lc3NhZ2UoKSkgeworICAgICAgdGhpcy5tZXNzYWdlID0gb3RoZXIubWVzc2FnZTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEFscmVhZHlFeGlzdHMgY2xvbmUoKSB7CisgICAgcmV0dXJuIG5ldyBBbHJlYWR5RXhpc3RzKHRoaXMpOworICB9CisKKyAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgeworICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNZXNzYWdlKFN0cmluZyBtZXNzYWdlKSB7CisgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0TWVzc2FnZSgpIHsKKyAgICB0aGlzLm1lc3NhZ2UgPSBudWxsOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIG1lc3NhZ2UgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRNZXNzYWdlKCkgeworICAgIHJldHVybiB0aGlzLm1lc3NhZ2UgIT0gbnVsbDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2VJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5tZXNzYWdlID0gbnVsbDsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIE1FU1NBR0U6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldE1lc3NhZ2UoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldE1lc3NhZ2UoKFN0cmluZyl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIE1FU1NBR0U6CisgICAgICByZXR1cm4gZ2V0TWVzc2FnZSgpOworCisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIE1FU1NBR0U6CisgICAgICByZXR1cm4gaXNTZXRNZXNzYWdlKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmICh0aGF0IGluc3RhbmNlb2YgQWxyZWFkeUV4aXN0cykKKyAgICAgIHJldHVybiB0aGlzLmVxdWFscygoQWxyZWFkeUV4aXN0cyl0aGF0KTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQWxyZWFkeUV4aXN0cyB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X21lc3NhZ2UgPSB0cnVlICYmIHRoaXMuaXNTZXRNZXNzYWdlKCk7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfbWVzc2FnZSA9IHRydWUgJiYgdGhhdC5pc1NldE1lc3NhZ2UoKTsKKyAgICBpZiAodGhpc19wcmVzZW50X21lc3NhZ2UgfHwgdGhhdF9wcmVzZW50X21lc3NhZ2UpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tZXNzYWdlICYmIHRoYXRfcHJlc2VudF9tZXNzYWdlKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCF0aGlzLm1lc3NhZ2UuZXF1YWxzKHRoYXQubWVzc2FnZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICBURmllbGQgZmllbGQ7CisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgd2hpbGUgKHRydWUpCisgICAgeworICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgeworICAgICAgICBjYXNlIE1FU1NBR0U6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBpcHJvdC5yZWFkU3RyaW5nKCk7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgfQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgdmFsaWRhdGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIHZhbGlkYXRlKCk7CisKKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICBpZiAodGhpcy5tZXNzYWdlICE9IG51bGwpIHsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihNRVNTQUdFX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVTdHJpbmcodGhpcy5tZXNzYWdlKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJBbHJlYWR5RXhpc3RzKCIpOworICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgc2IuYXBwZW5kKCJtZXNzYWdlOiIpOworICAgIGlmICh0aGlzLm1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLm1lc3NhZ2UpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9CYXRjaE11dGF0aW9uLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0JhdGNoTXV0YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODk3NDFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9CYXRjaE11dGF0aW9uLmphdmEKQEAgLTAsMCArMSwzNTAgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIEEgQmF0Y2hNdXRhdGlvbiBvYmplY3QgaXMgdXNlZCB0byBhcHBseSBhIG51bWJlciBvZiBNdXRhdGlvbnMgdG8gYSBzaW5nbGUgcm93LgorICovCitwdWJsaWMgY2xhc3MgQmF0Y2hNdXRhdGlvbiBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJCYXRjaE11dGF0aW9uIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTVVUQVRJT05TX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJtdXRhdGlvbnMiLCBUVHlwZS5MSVNULCAoc2hvcnQpMik7CisKKyAgcHVibGljIGJ5dGVbXSByb3c7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPVyA9IDE7CisgIHB1YmxpYyBMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnM7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1VVEFUSU9OUyA9IDI7CisKKyAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgIHB1dChST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJyb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChNVVRBVElPTlMsIG5ldyBGaWVsZE1ldGFEYXRhKCJtdXRhdGlvbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBMaXN0TWV0YURhdGEoVFR5cGUuTElTVCwgCisgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBNdXRhdGlvbi5jbGFzcykpKSk7CisgIH19KTsKKworICBzdGF0aWMgeworICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoQmF0Y2hNdXRhdGlvbi5jbGFzcywgbWV0YURhdGFNYXApOworICB9CisKKyAgcHVibGljIEJhdGNoTXV0YXRpb24oKSB7CisgIH0KKworICBwdWJsaWMgQmF0Y2hNdXRhdGlvbigKKyAgICBieXRlW10gcm93LAorICAgIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucykKKyAgeworICAgIHRoaXMoKTsKKyAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgfQorCisgIC8qKgorICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAqLworICBwdWJsaWMgQmF0Y2hNdXRhdGlvbihCYXRjaE11dGF0aW9uIG90aGVyKSB7CisgICAgaWYgKG90aGVyLmlzU2V0Um93KCkpIHsKKyAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgIH0KKyAgICBpZiAob3RoZXIuaXNTZXRNdXRhdGlvbnMoKSkgeworICAgICAgTGlzdDxNdXRhdGlvbj4gX190aGlzX19tdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgICAgZm9yIChNdXRhdGlvbiBvdGhlcl9lbGVtZW50IDogb3RoZXIubXV0YXRpb25zKSB7CisgICAgICAgIF9fdGhpc19fbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24ob3RoZXJfZWxlbWVudCkpOworICAgICAgfQorICAgICAgdGhpcy5tdXRhdGlvbnMgPSBfX3RoaXNfX211dGF0aW9uczsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEJhdGNoTXV0YXRpb24gY2xvbmUoKSB7CisgICAgcmV0dXJuIG5ldyBCYXRjaE11dGF0aW9uKHRoaXMpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgcmV0dXJuIHRoaXMucm93OworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICB0aGlzLnJvdyA9IHJvdzsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgIHRoaXMucm93ID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0TXV0YXRpb25zU2l6ZSgpIHsKKyAgICByZXR1cm4gKHRoaXMubXV0YXRpb25zID09IG51bGwpID8gMCA6IHRoaXMubXV0YXRpb25zLnNpemUoKTsKKyAgfQorCisgIHB1YmxpYyBqYXZhLnV0aWwuSXRlcmF0b3I8TXV0YXRpb24+IGdldE11dGF0aW9uc0l0ZXJhdG9yKCkgeworICAgIHJldHVybiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5tdXRhdGlvbnMuaXRlcmF0b3IoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIGFkZFRvTXV0YXRpb25zKE11dGF0aW9uIGVsZW0pIHsKKyAgICBpZiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgeworICAgICAgdGhpcy5tdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgIH0KKyAgICB0aGlzLm11dGF0aW9ucy5hZGQoZWxlbSk7CisgIH0KKworICBwdWJsaWMgTGlzdDxNdXRhdGlvbj4gZ2V0TXV0YXRpb25zKCkgeworICAgIHJldHVybiB0aGlzLm11dGF0aW9uczsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE11dGF0aW9ucyhMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnMpIHsKKyAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0TXV0YXRpb25zKCkgeworICAgIHRoaXMubXV0YXRpb25zID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBtdXRhdGlvbnMgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRNdXRhdGlvbnMoKSB7CisgICAgcmV0dXJuIHRoaXMubXV0YXRpb25zICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNdXRhdGlvbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5tdXRhdGlvbnMgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgUk9XOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRSb3coKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBNVVRBVElPTlM6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldE11dGF0aW9ucygpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0TXV0YXRpb25zKChMaXN0PE11dGF0aW9uPil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFJPVzoKKyAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgIGNhc2UgTVVUQVRJT05TOgorICAgICAgcmV0dXJuIGdldE11dGF0aW9ucygpOworCisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFJPVzoKKyAgICAgIHJldHVybiBpc1NldFJvdygpOworICAgIGNhc2UgTVVUQVRJT05TOgorICAgICAgcmV0dXJuIGlzU2V0TXV0YXRpb25zKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmICh0aGF0IGluc3RhbmNlb2YgQmF0Y2hNdXRhdGlvbikKKyAgICAgIHJldHVybiB0aGlzLmVxdWFscygoQmF0Y2hNdXRhdGlvbil0aGF0KTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQmF0Y2hNdXRhdGlvbiB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhpcy5pc1NldFJvdygpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhhdC5pc1NldFJvdygpOworICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9yb3cgJiYgdGhhdF9wcmVzZW50X3JvdykpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X211dGF0aW9ucyA9IHRydWUgJiYgdGhpcy5pc1NldE11dGF0aW9ucygpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X211dGF0aW9ucyA9IHRydWUgJiYgdGhhdC5pc1NldE11dGF0aW9ucygpOworICAgIGlmICh0aGlzX3ByZXNlbnRfbXV0YXRpb25zIHx8IHRoYXRfcHJlc2VudF9tdXRhdGlvbnMpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tdXRhdGlvbnMgJiYgdGhhdF9wcmVzZW50X211dGF0aW9ucykpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghdGhpcy5tdXRhdGlvbnMuZXF1YWxzKHRoYXQubXV0YXRpb25zKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIFRGaWVsZCBmaWVsZDsKKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICB3aGlsZSAodHJ1ZSkKKyAgICB7CisgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICB7CisgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBNVVRBVElPTlM6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgeworICAgICAgICAgICAgICBUTGlzdCBfbGlzdDAgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zID0gbmV3IEFycmF5TGlzdDxNdXRhdGlvbj4oX2xpc3QwLnNpemUpOworICAgICAgICAgICAgICBmb3IgKGludCBfaTEgPSAwOyBfaTEgPCBfbGlzdDAuc2l6ZTsgKytfaTEpCisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBNdXRhdGlvbiBfZWxlbTI7CisgICAgICAgICAgICAgICAgX2VsZW0yID0gbmV3IE11dGF0aW9uKCk7CisgICAgICAgICAgICAgICAgX2VsZW0yLnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zLmFkZChfZWxlbTIpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgfQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgdmFsaWRhdGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIHZhbGlkYXRlKCk7CisKKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFJPV19GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgaWYgKHRoaXMubXV0YXRpb25zICE9IG51bGwpIHsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihNVVRBVElPTlNfRklFTERfREVTQyk7CisgICAgICB7CisgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMubXV0YXRpb25zLnNpemUoKSkpOworICAgICAgICBmb3IgKE11dGF0aW9uIF9pdGVyMyA6IHRoaXMubXV0YXRpb25zKSAgICAgICAgeworICAgICAgICAgIF9pdGVyMy53cml0ZShvcHJvdCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgfQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiQmF0Y2hNdXRhdGlvbigiKTsKKyAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgIGlmICh0aGlzLnJvdyA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMucm93KTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJtdXRhdGlvbnM6Iik7CisgICAgaWYgKHRoaXMubXV0YXRpb25zID09IG51bGwpIHsKKyAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgIH0gZWxzZSB7CisgICAgICBzYi5hcHBlbmQodGhpcy5tdXRhdGlvbnMpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9Db2x1bW5EZXNjcmlwdG9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0NvbHVtbkRlc2NyaXB0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzBiYTdiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9Db2x1bW5EZXNjcmlwdG9yLmphdmEKQEAgLTAsMCArMSw4OTggQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIEFuIEhDb2x1bW5EZXNjcmlwdG9yIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgY29sdW1uIGZhbWlseQorICogc3VjaCBhcyB0aGUgbnVtYmVyIG9mIHZlcnNpb25zLCBjb21wcmVzc2lvbiBzZXR0aW5ncywgZXRjLiBJdCBpcworICogdXNlZCBhcyBpbnB1dCB3aGVuIGNyZWF0aW5nIGEgdGFibGUgb3IgYWRkaW5nIGEgY29sdW1uLgorICovCitwdWJsaWMgY2xhc3MgQ29sdW1uRGVzY3JpcHRvciBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJDb2x1bW5EZXNjcmlwdG9yIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBOQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJuYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBNQVhfVkVSU0lPTlNfRklFTERfREVTQyA9IG5ldyBURmllbGQoIm1heFZlcnNpb25zIiwgVFR5cGUuSTMyLCAoc2hvcnQpMik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT01QUkVTU0lPTl9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29tcHJlc3Npb24iLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkzKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElOX01FTU9SWV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW5NZW1vcnkiLCBUVHlwZS5CT09MLCAoc2hvcnQpNCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBNQVhfVkFMVUVfTEVOR1RIX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJtYXhWYWx1ZUxlbmd0aCIsIFRUeXBlLkkzMiwgKHNob3J0KTUpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQkxPT01fRklMVEVSX1RZUEVfRklFTERfREVTQyA9IG5ldyBURmllbGQoImJsb29tRmlsdGVyVHlwZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTYpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQkxPT01fRklMVEVSX1ZFQ1RPUl9TSVpFX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJibG9vbUZpbHRlclZlY3RvclNpemUiLCBUVHlwZS5JMzIsIChzaG9ydCk3KTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIEJMT09NX0ZJTFRFUl9OQl9IQVNIRVNfRklFTERfREVTQyA9IG5ldyBURmllbGQoImJsb29tRmlsdGVyTmJIYXNoZXMiLCBUVHlwZS5JMzIsIChzaG9ydCk4KTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIEJMT0NLX0NBQ0hFX0VOQUJMRURfRklFTERfREVTQyA9IG5ldyBURmllbGQoImJsb2NrQ2FjaGVFbmFibGVkIiwgVFR5cGUuQk9PTCwgKHNob3J0KTkpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVElNRV9UT19MSVZFX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0aW1lVG9MaXZlIiwgVFR5cGUuSTMyLCAoc2hvcnQpMTApOworCisgIHB1YmxpYyBieXRlW10gbmFtZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRSA9IDE7CisgIHB1YmxpYyBpbnQgbWF4VmVyc2lvbnM7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWFZFUlNJT05TID0gMjsKKyAgcHVibGljIFN0cmluZyBjb21wcmVzc2lvbjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUFJFU1NJT04gPSAzOworICBwdWJsaWMgYm9vbGVhbiBpbk1lbW9yeTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5NRU1PUlkgPSA0OworICBwdWJsaWMgaW50IG1heFZhbHVlTGVuZ3RoOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVhWQUxVRUxFTkdUSCA9IDU7CisgIHB1YmxpYyBTdHJpbmcgYmxvb21GaWx0ZXJUeXBlOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCTE9PTUZJTFRFUlRZUEUgPSA2OworICBwdWJsaWMgaW50IGJsb29tRmlsdGVyVmVjdG9yU2l6ZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkxPT01GSUxURVJWRUNUT1JTSVpFID0gNzsKKyAgcHVibGljIGludCBibG9vbUZpbHRlck5iSGFzaGVzOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCTE9PTUZJTFRFUk5CSEFTSEVTID0gODsKKyAgcHVibGljIGJvb2xlYW4gYmxvY2tDYWNoZUVuYWJsZWQ7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJMT0NLQ0FDSEVFTkFCTEVEID0gOTsKKyAgcHVibGljIGludCB0aW1lVG9MaXZlOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FVE9MSVZFID0gMTA7CisKKyAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHB1YmxpYyBib29sZWFuIG1heFZlcnNpb25zID0gZmFsc2U7CisgICAgcHVibGljIGJvb2xlYW4gaW5NZW1vcnkgPSBmYWxzZTsKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXhWYWx1ZUxlbmd0aCA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIGJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIGJsb29tRmlsdGVyTmJIYXNoZXMgPSBmYWxzZTsKKyAgICBwdWJsaWMgYm9vbGVhbiBibG9ja0NhY2hlRW5hYmxlZCA9IGZhbHNlOworICAgIHB1YmxpYyBib29sZWFuIHRpbWVUb0xpdmUgPSBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICBwdXQoTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoIm5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChNQVhWRVJTSU9OUywgbmV3IEZpZWxkTWV0YURhdGEoIm1heFZlcnNpb25zIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkkzMikpKTsKKyAgICBwdXQoQ09NUFJFU1NJT04sIG5ldyBGaWVsZE1ldGFEYXRhKCJjb21wcmVzc2lvbiIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgcHV0KElOTUVNT1JZLCBuZXcgRmllbGRNZXRhRGF0YSgiaW5NZW1vcnkiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuQk9PTCkpKTsKKyAgICBwdXQoTUFYVkFMVUVMRU5HVEgsIG5ldyBGaWVsZE1ldGFEYXRhKCJtYXhWYWx1ZUxlbmd0aCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgcHV0KEJMT09NRklMVEVSVFlQRSwgbmV3IEZpZWxkTWV0YURhdGEoImJsb29tRmlsdGVyVHlwZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgcHV0KEJMT09NRklMVEVSVkVDVE9SU0laRSwgbmV3IEZpZWxkTWV0YURhdGEoImJsb29tRmlsdGVyVmVjdG9yU2l6ZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgcHV0KEJMT09NRklMVEVSTkJIQVNIRVMsIG5ldyBGaWVsZE1ldGFEYXRhKCJibG9vbUZpbHRlck5iSGFzaGVzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkkzMikpKTsKKyAgICBwdXQoQkxPQ0tDQUNIRUVOQUJMRUQsIG5ldyBGaWVsZE1ldGFEYXRhKCJibG9ja0NhY2hlRW5hYmxlZCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5CT09MKSkpOworICAgIHB1dChUSU1FVE9MSVZFLCBuZXcgRmllbGRNZXRhRGF0YSgidGltZVRvTGl2ZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgIH19KTsKKworICBzdGF0aWMgeworICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoQ29sdW1uRGVzY3JpcHRvci5jbGFzcywgbWV0YURhdGFNYXApOworICB9CisKKyAgcHVibGljIENvbHVtbkRlc2NyaXB0b3IoKSB7CisgICAgdGhpcy5tYXhWZXJzaW9ucyA9IDM7CisKKyAgICB0aGlzLmNvbXByZXNzaW9uID0gIk5PTkUiOworCisgICAgdGhpcy5pbk1lbW9yeSA9IGZhbHNlOworCisgICAgdGhpcy5tYXhWYWx1ZUxlbmd0aCA9IDIxNDc0ODM2NDc7CisKKyAgICB0aGlzLmJsb29tRmlsdGVyVHlwZSA9ICJOT05FIjsKKworICAgIHRoaXMuYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gMDsKKworICAgIHRoaXMuYmxvb21GaWx0ZXJOYkhhc2hlcyA9IDA7CisKKyAgICB0aGlzLmJsb2NrQ2FjaGVFbmFibGVkID0gZmFsc2U7CisKKyAgICB0aGlzLnRpbWVUb0xpdmUgPSAtMTsKKworICB9CisKKyAgcHVibGljIENvbHVtbkRlc2NyaXB0b3IoCisgICAgYnl0ZVtdIG5hbWUsCisgICAgaW50IG1heFZlcnNpb25zLAorICAgIFN0cmluZyBjb21wcmVzc2lvbiwKKyAgICBib29sZWFuIGluTWVtb3J5LAorICAgIGludCBtYXhWYWx1ZUxlbmd0aCwKKyAgICBTdHJpbmcgYmxvb21GaWx0ZXJUeXBlLAorICAgIGludCBibG9vbUZpbHRlclZlY3RvclNpemUsCisgICAgaW50IGJsb29tRmlsdGVyTmJIYXNoZXMsCisgICAgYm9vbGVhbiBibG9ja0NhY2hlRW5hYmxlZCwKKyAgICBpbnQgdGltZVRvTGl2ZSkKKyAgeworICAgIHRoaXMoKTsKKyAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgIHRoaXMubWF4VmVyc2lvbnMgPSBtYXhWZXJzaW9uczsKKyAgICB0aGlzLl9faXNzZXQubWF4VmVyc2lvbnMgPSB0cnVlOworICAgIHRoaXMuY29tcHJlc3Npb24gPSBjb21wcmVzc2lvbjsKKyAgICB0aGlzLmluTWVtb3J5ID0gaW5NZW1vcnk7CisgICAgdGhpcy5fX2lzc2V0LmluTWVtb3J5ID0gdHJ1ZTsKKyAgICB0aGlzLm1heFZhbHVlTGVuZ3RoID0gbWF4VmFsdWVMZW5ndGg7CisgICAgdGhpcy5fX2lzc2V0Lm1heFZhbHVlTGVuZ3RoID0gdHJ1ZTsKKyAgICB0aGlzLmJsb29tRmlsdGVyVHlwZSA9IGJsb29tRmlsdGVyVHlwZTsKKyAgICB0aGlzLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IGJsb29tRmlsdGVyVmVjdG9yU2l6ZTsKKyAgICB0aGlzLl9faXNzZXQuYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gdHJ1ZTsKKyAgICB0aGlzLmJsb29tRmlsdGVyTmJIYXNoZXMgPSBibG9vbUZpbHRlck5iSGFzaGVzOworICAgIHRoaXMuX19pc3NldC5ibG9vbUZpbHRlck5iSGFzaGVzID0gdHJ1ZTsKKyAgICB0aGlzLmJsb2NrQ2FjaGVFbmFibGVkID0gYmxvY2tDYWNoZUVuYWJsZWQ7CisgICAgdGhpcy5fX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkID0gdHJ1ZTsKKyAgICB0aGlzLnRpbWVUb0xpdmUgPSB0aW1lVG9MaXZlOworICAgIHRoaXMuX19pc3NldC50aW1lVG9MaXZlID0gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAqLworICBwdWJsaWMgQ29sdW1uRGVzY3JpcHRvcihDb2x1bW5EZXNjcmlwdG9yIG90aGVyKSB7CisgICAgaWYgKG90aGVyLmlzU2V0TmFtZSgpKSB7CisgICAgICB0aGlzLm5hbWUgPSBvdGhlci5uYW1lOworICAgIH0KKyAgICBfX2lzc2V0Lm1heFZlcnNpb25zID0gb3RoZXIuX19pc3NldC5tYXhWZXJzaW9uczsKKyAgICB0aGlzLm1heFZlcnNpb25zID0gb3RoZXIubWF4VmVyc2lvbnM7CisgICAgaWYgKG90aGVyLmlzU2V0Q29tcHJlc3Npb24oKSkgeworICAgICAgdGhpcy5jb21wcmVzc2lvbiA9IG90aGVyLmNvbXByZXNzaW9uOworICAgIH0KKyAgICBfX2lzc2V0LmluTWVtb3J5ID0gb3RoZXIuX19pc3NldC5pbk1lbW9yeTsKKyAgICB0aGlzLmluTWVtb3J5ID0gb3RoZXIuaW5NZW1vcnk7CisgICAgX19pc3NldC5tYXhWYWx1ZUxlbmd0aCA9IG90aGVyLl9faXNzZXQubWF4VmFsdWVMZW5ndGg7CisgICAgdGhpcy5tYXhWYWx1ZUxlbmd0aCA9IG90aGVyLm1heFZhbHVlTGVuZ3RoOworICAgIGlmIChvdGhlci5pc1NldEJsb29tRmlsdGVyVHlwZSgpKSB7CisgICAgICB0aGlzLmJsb29tRmlsdGVyVHlwZSA9IG90aGVyLmJsb29tRmlsdGVyVHlwZTsKKyAgICB9CisgICAgX19pc3NldC5ibG9vbUZpbHRlclZlY3RvclNpemUgPSBvdGhlci5fX2lzc2V0LmJsb29tRmlsdGVyVmVjdG9yU2l6ZTsKKyAgICB0aGlzLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IG90aGVyLmJsb29tRmlsdGVyVmVjdG9yU2l6ZTsKKyAgICBfX2lzc2V0LmJsb29tRmlsdGVyTmJIYXNoZXMgPSBvdGhlci5fX2lzc2V0LmJsb29tRmlsdGVyTmJIYXNoZXM7CisgICAgdGhpcy5ibG9vbUZpbHRlck5iSGFzaGVzID0gb3RoZXIuYmxvb21GaWx0ZXJOYkhhc2hlczsKKyAgICBfX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkID0gb3RoZXIuX19pc3NldC5ibG9ja0NhY2hlRW5hYmxlZDsKKyAgICB0aGlzLmJsb2NrQ2FjaGVFbmFibGVkID0gb3RoZXIuYmxvY2tDYWNoZUVuYWJsZWQ7CisgICAgX19pc3NldC50aW1lVG9MaXZlID0gb3RoZXIuX19pc3NldC50aW1lVG9MaXZlOworICAgIHRoaXMudGltZVRvTGl2ZSA9IG90aGVyLnRpbWVUb0xpdmU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIENvbHVtbkRlc2NyaXB0b3IgY2xvbmUoKSB7CisgICAgcmV0dXJuIG5ldyBDb2x1bW5EZXNjcmlwdG9yKHRoaXMpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXROYW1lKCkgeworICAgIHJldHVybiB0aGlzLm5hbWU7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXROYW1lKGJ5dGVbXSBuYW1lKSB7CisgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0TmFtZSgpIHsKKyAgICB0aGlzLm5hbWUgPSBudWxsOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIG5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXROYW1lKCkgeworICAgIHJldHVybiB0aGlzLm5hbWUgIT0gbnVsbDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5uYW1lID0gbnVsbDsKKyAgICB9CisgIH0KKworICBwdWJsaWMgaW50IGdldE1heFZlcnNpb25zKCkgeworICAgIHJldHVybiB0aGlzLm1heFZlcnNpb25zOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0TWF4VmVyc2lvbnMoaW50IG1heFZlcnNpb25zKSB7CisgICAgdGhpcy5tYXhWZXJzaW9ucyA9IG1heFZlcnNpb25zOworICAgIHRoaXMuX19pc3NldC5tYXhWZXJzaW9ucyA9IHRydWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldE1heFZlcnNpb25zKCkgeworICAgIHRoaXMuX19pc3NldC5tYXhWZXJzaW9ucyA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIG1heFZlcnNpb25zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0TWF4VmVyc2lvbnMoKSB7CisgICAgcmV0dXJuIHRoaXMuX19pc3NldC5tYXhWZXJzaW9uczsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1heFZlcnNpb25zSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIHRoaXMuX19pc3NldC5tYXhWZXJzaW9ucyA9IHZhbHVlOworICB9CisKKyAgcHVibGljIFN0cmluZyBnZXRDb21wcmVzc2lvbigpIHsKKyAgICByZXR1cm4gdGhpcy5jb21wcmVzc2lvbjsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldENvbXByZXNzaW9uKFN0cmluZyBjb21wcmVzc2lvbikgeworICAgIHRoaXMuY29tcHJlc3Npb24gPSBjb21wcmVzc2lvbjsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Q29tcHJlc3Npb24oKSB7CisgICAgdGhpcy5jb21wcmVzc2lvbiA9IG51bGw7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29tcHJlc3Npb24gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRDb21wcmVzc2lvbigpIHsKKyAgICByZXR1cm4gdGhpcy5jb21wcmVzc2lvbiAhPSBudWxsOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Q29tcHJlc3Npb25Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5jb21wcmVzc2lvbiA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNJbk1lbW9yeSgpIHsKKyAgICByZXR1cm4gdGhpcy5pbk1lbW9yeTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEluTWVtb3J5KGJvb2xlYW4gaW5NZW1vcnkpIHsKKyAgICB0aGlzLmluTWVtb3J5ID0gaW5NZW1vcnk7CisgICAgdGhpcy5fX2lzc2V0LmluTWVtb3J5ID0gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0SW5NZW1vcnkoKSB7CisgICAgdGhpcy5fX2lzc2V0LmluTWVtb3J5ID0gZmFsc2U7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW5NZW1vcnkgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRJbk1lbW9yeSgpIHsKKyAgICByZXR1cm4gdGhpcy5fX2lzc2V0LmluTWVtb3J5OworICB9CisKKyAgcHVibGljIHZvaWQgc2V0SW5NZW1vcnlJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgdGhpcy5fX2lzc2V0LmluTWVtb3J5ID0gdmFsdWU7CisgIH0KKworICBwdWJsaWMgaW50IGdldE1heFZhbHVlTGVuZ3RoKCkgeworICAgIHJldHVybiB0aGlzLm1heFZhbHVlTGVuZ3RoOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0TWF4VmFsdWVMZW5ndGgoaW50IG1heFZhbHVlTGVuZ3RoKSB7CisgICAgdGhpcy5tYXhWYWx1ZUxlbmd0aCA9IG1heFZhbHVlTGVuZ3RoOworICAgIHRoaXMuX19pc3NldC5tYXhWYWx1ZUxlbmd0aCA9IHRydWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldE1heFZhbHVlTGVuZ3RoKCkgeworICAgIHRoaXMuX19pc3NldC5tYXhWYWx1ZUxlbmd0aCA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIG1heFZhbHVlTGVuZ3RoIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0TWF4VmFsdWVMZW5ndGgoKSB7CisgICAgcmV0dXJuIHRoaXMuX19pc3NldC5tYXhWYWx1ZUxlbmd0aDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldE1heFZhbHVlTGVuZ3RoSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIHRoaXMuX19pc3NldC5tYXhWYWx1ZUxlbmd0aCA9IHZhbHVlOworICB9CisKKyAgcHVibGljIFN0cmluZyBnZXRCbG9vbUZpbHRlclR5cGUoKSB7CisgICAgcmV0dXJuIHRoaXMuYmxvb21GaWx0ZXJUeXBlOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Qmxvb21GaWx0ZXJUeXBlKFN0cmluZyBibG9vbUZpbHRlclR5cGUpIHsKKyAgICB0aGlzLmJsb29tRmlsdGVyVHlwZSA9IGJsb29tRmlsdGVyVHlwZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Qmxvb21GaWx0ZXJUeXBlKCkgeworICAgIHRoaXMuYmxvb21GaWx0ZXJUeXBlID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBibG9vbUZpbHRlclR5cGUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRCbG9vbUZpbHRlclR5cGUoKSB7CisgICAgcmV0dXJuIHRoaXMuYmxvb21GaWx0ZXJUeXBlICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRCbG9vbUZpbHRlclR5cGVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5ibG9vbUZpbHRlclR5cGUgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0Qmxvb21GaWx0ZXJWZWN0b3JTaXplKCkgeworICAgIHJldHVybiB0aGlzLmJsb29tRmlsdGVyVmVjdG9yU2l6ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEJsb29tRmlsdGVyVmVjdG9yU2l6ZShpbnQgYmxvb21GaWx0ZXJWZWN0b3JTaXplKSB7CisgICAgdGhpcy5ibG9vbUZpbHRlclZlY3RvclNpemUgPSBibG9vbUZpbHRlclZlY3RvclNpemU7CisgICAgdGhpcy5fX2lzc2V0LmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IHRydWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldEJsb29tRmlsdGVyVmVjdG9yU2l6ZSgpIHsKKyAgICB0aGlzLl9faXNzZXQuYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gZmFsc2U7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgYmxvb21GaWx0ZXJWZWN0b3JTaXplIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0Qmxvb21GaWx0ZXJWZWN0b3JTaXplKCkgeworICAgIHJldHVybiB0aGlzLl9faXNzZXQuYmxvb21GaWx0ZXJWZWN0b3JTaXplOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Qmxvb21GaWx0ZXJWZWN0b3JTaXplSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIHRoaXMuX19pc3NldC5ibG9vbUZpbHRlclZlY3RvclNpemUgPSB2YWx1ZTsKKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0Qmxvb21GaWx0ZXJOYkhhc2hlcygpIHsKKyAgICByZXR1cm4gdGhpcy5ibG9vbUZpbHRlck5iSGFzaGVzOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Qmxvb21GaWx0ZXJOYkhhc2hlcyhpbnQgYmxvb21GaWx0ZXJOYkhhc2hlcykgeworICAgIHRoaXMuYmxvb21GaWx0ZXJOYkhhc2hlcyA9IGJsb29tRmlsdGVyTmJIYXNoZXM7CisgICAgdGhpcy5fX2lzc2V0LmJsb29tRmlsdGVyTmJIYXNoZXMgPSB0cnVlOworICB9CisKKyAgcHVibGljIHZvaWQgdW5zZXRCbG9vbUZpbHRlck5iSGFzaGVzKCkgeworICAgIHRoaXMuX19pc3NldC5ibG9vbUZpbHRlck5iSGFzaGVzID0gZmFsc2U7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgYmxvb21GaWx0ZXJOYkhhc2hlcyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldEJsb29tRmlsdGVyTmJIYXNoZXMoKSB7CisgICAgcmV0dXJuIHRoaXMuX19pc3NldC5ibG9vbUZpbHRlck5iSGFzaGVzOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Qmxvb21GaWx0ZXJOYkhhc2hlc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICB0aGlzLl9faXNzZXQuYmxvb21GaWx0ZXJOYkhhc2hlcyA9IHZhbHVlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaXNCbG9ja0NhY2hlRW5hYmxlZCgpIHsKKyAgICByZXR1cm4gdGhpcy5ibG9ja0NhY2hlRW5hYmxlZDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEJsb2NrQ2FjaGVFbmFibGVkKGJvb2xlYW4gYmxvY2tDYWNoZUVuYWJsZWQpIHsKKyAgICB0aGlzLmJsb2NrQ2FjaGVFbmFibGVkID0gYmxvY2tDYWNoZUVuYWJsZWQ7CisgICAgdGhpcy5fX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkID0gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0QmxvY2tDYWNoZUVuYWJsZWQoKSB7CisgICAgdGhpcy5fX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkID0gZmFsc2U7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgYmxvY2tDYWNoZUVuYWJsZWQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRCbG9ja0NhY2hlRW5hYmxlZCgpIHsKKyAgICByZXR1cm4gdGhpcy5fX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0QmxvY2tDYWNoZUVuYWJsZWRJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgdGhpcy5fX2lzc2V0LmJsb2NrQ2FjaGVFbmFibGVkID0gdmFsdWU7CisgIH0KKworICBwdWJsaWMgaW50IGdldFRpbWVUb0xpdmUoKSB7CisgICAgcmV0dXJuIHRoaXMudGltZVRvTGl2ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFRpbWVUb0xpdmUoaW50IHRpbWVUb0xpdmUpIHsKKyAgICB0aGlzLnRpbWVUb0xpdmUgPSB0aW1lVG9MaXZlOworICAgIHRoaXMuX19pc3NldC50aW1lVG9MaXZlID0gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0VGltZVRvTGl2ZSgpIHsKKyAgICB0aGlzLl9faXNzZXQudGltZVRvTGl2ZSA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVUb0xpdmUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRUaW1lVG9MaXZlKCkgeworICAgIHJldHVybiB0aGlzLl9faXNzZXQudGltZVRvTGl2ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFRpbWVUb0xpdmVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgdGhpcy5fX2lzc2V0LnRpbWVUb0xpdmUgPSB2YWx1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgTkFNRToKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0TmFtZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0TmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBNQVhWRVJTSU9OUzoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0TWF4VmVyc2lvbnMoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldE1heFZlcnNpb25zKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBDT01QUkVTU0lPTjoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0Q29tcHJlc3Npb24oKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldENvbXByZXNzaW9uKChTdHJpbmcpdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIElOTUVNT1JZOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRJbk1lbW9yeSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0SW5NZW1vcnkoKEJvb2xlYW4pdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIE1BWFZBTFVFTEVOR1RIOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRNYXhWYWx1ZUxlbmd0aCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0TWF4VmFsdWVMZW5ndGgoKEludGVnZXIpdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEJMT09NRklMVEVSVFlQRToKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0Qmxvb21GaWx0ZXJUeXBlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRCbG9vbUZpbHRlclR5cGUoKFN0cmluZyl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgQkxPT01GSUxURVJWRUNUT1JTSVpFOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRCbG9vbUZpbHRlclZlY3RvclNpemUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldEJsb29tRmlsdGVyVmVjdG9yU2l6ZSgoSW50ZWdlcil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgQkxPT01GSUxURVJOQkhBU0hFUzoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0Qmxvb21GaWx0ZXJOYkhhc2hlcygpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0Qmxvb21GaWx0ZXJOYkhhc2hlcygoSW50ZWdlcil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgQkxPQ0tDQUNIRUVOQUJMRUQ6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldEJsb2NrQ2FjaGVFbmFibGVkKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRCbG9ja0NhY2hlRW5hYmxlZCgoQm9vbGVhbil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgVElNRVRPTElWRToKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0VGltZVRvTGl2ZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0VGltZVRvTGl2ZSgoSW50ZWdlcil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIE5BTUU6CisgICAgICByZXR1cm4gZ2V0TmFtZSgpOworCisgICAgY2FzZSBNQVhWRVJTSU9OUzoKKyAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXRNYXhWZXJzaW9ucygpKTsKKworICAgIGNhc2UgQ09NUFJFU1NJT046CisgICAgICByZXR1cm4gZ2V0Q29tcHJlc3Npb24oKTsKKworICAgIGNhc2UgSU5NRU1PUlk6CisgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oaXNJbk1lbW9yeSgpKTsKKworICAgIGNhc2UgTUFYVkFMVUVMRU5HVEg6CisgICAgICByZXR1cm4gbmV3IEludGVnZXIoZ2V0TWF4VmFsdWVMZW5ndGgoKSk7CisKKyAgICBjYXNlIEJMT09NRklMVEVSVFlQRToKKyAgICAgIHJldHVybiBnZXRCbG9vbUZpbHRlclR5cGUoKTsKKworICAgIGNhc2UgQkxPT01GSUxURVJWRUNUT1JTSVpFOgorICAgICAgcmV0dXJuIG5ldyBJbnRlZ2VyKGdldEJsb29tRmlsdGVyVmVjdG9yU2l6ZSgpKTsKKworICAgIGNhc2UgQkxPT01GSUxURVJOQkhBU0hFUzoKKyAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXRCbG9vbUZpbHRlck5iSGFzaGVzKCkpOworCisgICAgY2FzZSBCTE9DS0NBQ0hFRU5BQkxFRDoKKyAgICAgIHJldHVybiBuZXcgQm9vbGVhbihpc0Jsb2NrQ2FjaGVFbmFibGVkKCkpOworCisgICAgY2FzZSBUSU1FVE9MSVZFOgorICAgICAgcmV0dXJuIG5ldyBJbnRlZ2VyKGdldFRpbWVUb0xpdmUoKSk7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgTkFNRToKKyAgICAgIHJldHVybiBpc1NldE5hbWUoKTsKKyAgICBjYXNlIE1BWFZFUlNJT05TOgorICAgICAgcmV0dXJuIGlzU2V0TWF4VmVyc2lvbnMoKTsKKyAgICBjYXNlIENPTVBSRVNTSU9OOgorICAgICAgcmV0dXJuIGlzU2V0Q29tcHJlc3Npb24oKTsKKyAgICBjYXNlIElOTUVNT1JZOgorICAgICAgcmV0dXJuIGlzU2V0SW5NZW1vcnkoKTsKKyAgICBjYXNlIE1BWFZBTFVFTEVOR1RIOgorICAgICAgcmV0dXJuIGlzU2V0TWF4VmFsdWVMZW5ndGgoKTsKKyAgICBjYXNlIEJMT09NRklMVEVSVFlQRToKKyAgICAgIHJldHVybiBpc1NldEJsb29tRmlsdGVyVHlwZSgpOworICAgIGNhc2UgQkxPT01GSUxURVJWRUNUT1JTSVpFOgorICAgICAgcmV0dXJuIGlzU2V0Qmxvb21GaWx0ZXJWZWN0b3JTaXplKCk7CisgICAgY2FzZSBCTE9PTUZJTFRFUk5CSEFTSEVTOgorICAgICAgcmV0dXJuIGlzU2V0Qmxvb21GaWx0ZXJOYkhhc2hlcygpOworICAgIGNhc2UgQkxPQ0tDQUNIRUVOQUJMRUQ6CisgICAgICByZXR1cm4gaXNTZXRCbG9ja0NhY2hlRW5hYmxlZCgpOworICAgIGNhc2UgVElNRVRPTElWRToKKyAgICAgIHJldHVybiBpc1NldFRpbWVUb0xpdmUoKTsKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBDb2x1bW5EZXNjcmlwdG9yKQorICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChDb2x1bW5EZXNjcmlwdG9yKXRoYXQpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhDb2x1bW5EZXNjcmlwdG9yIHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfbmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldE5hbWUoKTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9uYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0TmFtZSgpOworICAgIGlmICh0aGlzX3ByZXNlbnRfbmFtZSB8fCB0aGF0X3ByZXNlbnRfbmFtZSkgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X25hbWUgJiYgdGhhdF9wcmVzZW50X25hbWUpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMubmFtZSwgdGhhdC5uYW1lKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X21heFZlcnNpb25zID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9tYXhWZXJzaW9ucyA9IHRydWU7CisgICAgaWYgKHRoaXNfcHJlc2VudF9tYXhWZXJzaW9ucyB8fCB0aGF0X3ByZXNlbnRfbWF4VmVyc2lvbnMpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tYXhWZXJzaW9ucyAmJiB0aGF0X3ByZXNlbnRfbWF4VmVyc2lvbnMpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhpcy5tYXhWZXJzaW9ucyAhPSB0aGF0Lm1heFZlcnNpb25zKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfY29tcHJlc3Npb24gPSB0cnVlICYmIHRoaXMuaXNTZXRDb21wcmVzc2lvbigpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbXByZXNzaW9uID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29tcHJlc3Npb24oKTsKKyAgICBpZiAodGhpc19wcmVzZW50X2NvbXByZXNzaW9uIHx8IHRoYXRfcHJlc2VudF9jb21wcmVzc2lvbikgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X2NvbXByZXNzaW9uICYmIHRoYXRfcHJlc2VudF9jb21wcmVzc2lvbikpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghdGhpcy5jb21wcmVzc2lvbi5lcXVhbHModGhhdC5jb21wcmVzc2lvbikpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbk1lbW9yeSA9IHRydWU7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW5NZW1vcnkgPSB0cnVlOworICAgIGlmICh0aGlzX3ByZXNlbnRfaW5NZW1vcnkgfHwgdGhhdF9wcmVzZW50X2luTWVtb3J5KSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW5NZW1vcnkgJiYgdGhhdF9wcmVzZW50X2luTWVtb3J5KSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoaXMuaW5NZW1vcnkgIT0gdGhhdC5pbk1lbW9yeSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X21heFZhbHVlTGVuZ3RoID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9tYXhWYWx1ZUxlbmd0aCA9IHRydWU7CisgICAgaWYgKHRoaXNfcHJlc2VudF9tYXhWYWx1ZUxlbmd0aCB8fCB0aGF0X3ByZXNlbnRfbWF4VmFsdWVMZW5ndGgpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tYXhWYWx1ZUxlbmd0aCAmJiB0aGF0X3ByZXNlbnRfbWF4VmFsdWVMZW5ndGgpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhpcy5tYXhWYWx1ZUxlbmd0aCAhPSB0aGF0Lm1heFZhbHVlTGVuZ3RoKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfYmxvb21GaWx0ZXJUeXBlID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Qmxvb21GaWx0ZXJUeXBlKCk7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfYmxvb21GaWx0ZXJUeXBlID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Qmxvb21GaWx0ZXJUeXBlKCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF9ibG9vbUZpbHRlclR5cGUgfHwgdGhhdF9wcmVzZW50X2Jsb29tRmlsdGVyVHlwZSkgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X2Jsb29tRmlsdGVyVHlwZSAmJiB0aGF0X3ByZXNlbnRfYmxvb21GaWx0ZXJUeXBlKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCF0aGlzLmJsb29tRmlsdGVyVHlwZS5lcXVhbHModGhhdC5ibG9vbUZpbHRlclR5cGUpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9ibG9vbUZpbHRlclZlY3RvclNpemUgPSB0cnVlOworICAgIGlmICh0aGlzX3ByZXNlbnRfYmxvb21GaWx0ZXJWZWN0b3JTaXplIHx8IHRoYXRfcHJlc2VudF9ibG9vbUZpbHRlclZlY3RvclNpemUpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9ibG9vbUZpbHRlclZlY3RvclNpemUgJiYgdGhhdF9wcmVzZW50X2Jsb29tRmlsdGVyVmVjdG9yU2l6ZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGlzLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSAhPSB0aGF0LmJsb29tRmlsdGVyVmVjdG9yU2l6ZSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2Jsb29tRmlsdGVyTmJIYXNoZXMgPSB0cnVlOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2Jsb29tRmlsdGVyTmJIYXNoZXMgPSB0cnVlOworICAgIGlmICh0aGlzX3ByZXNlbnRfYmxvb21GaWx0ZXJOYkhhc2hlcyB8fCB0aGF0X3ByZXNlbnRfYmxvb21GaWx0ZXJOYkhhc2hlcykgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X2Jsb29tRmlsdGVyTmJIYXNoZXMgJiYgdGhhdF9wcmVzZW50X2Jsb29tRmlsdGVyTmJIYXNoZXMpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhpcy5ibG9vbUZpbHRlck5iSGFzaGVzICE9IHRoYXQuYmxvb21GaWx0ZXJOYkhhc2hlcykKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2Jsb2NrQ2FjaGVFbmFibGVkID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9ibG9ja0NhY2hlRW5hYmxlZCA9IHRydWU7CisgICAgaWYgKHRoaXNfcHJlc2VudF9ibG9ja0NhY2hlRW5hYmxlZCB8fCB0aGF0X3ByZXNlbnRfYmxvY2tDYWNoZUVuYWJsZWQpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9ibG9ja0NhY2hlRW5hYmxlZCAmJiB0aGF0X3ByZXNlbnRfYmxvY2tDYWNoZUVuYWJsZWQpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhpcy5ibG9ja0NhY2hlRW5hYmxlZCAhPSB0aGF0LmJsb2NrQ2FjaGVFbmFibGVkKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZVRvTGl2ZSA9IHRydWU7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGltZVRvTGl2ZSA9IHRydWU7CisgICAgaWYgKHRoaXNfcHJlc2VudF90aW1lVG9MaXZlIHx8IHRoYXRfcHJlc2VudF90aW1lVG9MaXZlKSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGltZVRvTGl2ZSAmJiB0aGF0X3ByZXNlbnRfdGltZVRvTGl2ZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGlzLnRpbWVUb0xpdmUgIT0gdGhhdC50aW1lVG9MaXZlKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgVEZpZWxkIGZpZWxkOworICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgIHdoaWxlICh0cnVlKQorICAgIHsKKyAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgIHsKKyAgICAgICAgY2FzZSBOQU1FOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5uYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTUFYVkVSU0lPTlM6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTMyKSB7CisgICAgICAgICAgICB0aGlzLm1heFZlcnNpb25zID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0Lm1heFZlcnNpb25zID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIENPTVBSRVNTSU9OOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5jb21wcmVzc2lvbiA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIElOTUVNT1JZOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkJPT0wpIHsKKyAgICAgICAgICAgIHRoaXMuaW5NZW1vcnkgPSBpcHJvdC5yZWFkQm9vbCgpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmluTWVtb3J5ID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE1BWFZBTFVFTEVOR1RIOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkkzMikgeworICAgICAgICAgICAgdGhpcy5tYXhWYWx1ZUxlbmd0aCA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgICAgIHRoaXMuX19pc3NldC5tYXhWYWx1ZUxlbmd0aCA9IHRydWU7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBCTE9PTUZJTFRFUlRZUEU6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICB0aGlzLmJsb29tRmlsdGVyVHlwZSA9IGlwcm90LnJlYWRTdHJpbmcoKTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEJMT09NRklMVEVSVkVDVE9SU0laRToKKyAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgIHRoaXMuYmxvb21GaWx0ZXJWZWN0b3JTaXplID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmJsb29tRmlsdGVyVmVjdG9yU2l6ZSA9IHRydWU7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBCTE9PTUZJTFRFUk5CSEFTSEVTOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkkzMikgeworICAgICAgICAgICAgdGhpcy5ibG9vbUZpbHRlck5iSGFzaGVzID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmJsb29tRmlsdGVyTmJIYXNoZXMgPSB0cnVlOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQkxPQ0tDQUNIRUVOQUJMRUQ6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuQk9PTCkgeworICAgICAgICAgICAgdGhpcy5ibG9ja0NhY2hlRW5hYmxlZCA9IGlwcm90LnJlYWRCb29sKCk7CisgICAgICAgICAgICB0aGlzLl9faXNzZXQuYmxvY2tDYWNoZUVuYWJsZWQgPSB0cnVlOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVElNRVRPTElWRToKKyAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgIHRoaXMudGltZVRvTGl2ZSA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgICAgIHRoaXMuX19pc3NldC50aW1lVG9MaXZlID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICB9CisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICB2YWxpZGF0ZSgpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgdmFsaWRhdGUoKTsKKworICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgIGlmICh0aGlzLm5hbWUgIT0gbnVsbCkgeworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKE5BTUVfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLm5hbWUpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIH0KKyAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oTUFYX1ZFUlNJT05TX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTMyKHRoaXMubWF4VmVyc2lvbnMpOworICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICBpZiAodGhpcy5jb21wcmVzc2lvbiAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQ09NUFJFU1NJT05fRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZVN0cmluZyh0aGlzLmNvbXByZXNzaW9uKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElOX01FTU9SWV9GSUVMRF9ERVNDKTsKKyAgICBvcHJvdC53cml0ZUJvb2wodGhpcy5pbk1lbW9yeSk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihNQVhfVkFMVUVfTEVOR1RIX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTMyKHRoaXMubWF4VmFsdWVMZW5ndGgpOworICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICBpZiAodGhpcy5ibG9vbUZpbHRlclR5cGUgIT0gbnVsbCkgeworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKEJMT09NX0ZJTFRFUl9UWVBFX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVTdHJpbmcodGhpcy5ibG9vbUZpbHRlclR5cGUpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIH0KKyAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQkxPT01fRklMVEVSX1ZFQ1RPUl9TSVpFX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTMyKHRoaXMuYmxvb21GaWx0ZXJWZWN0b3JTaXplKTsKKyAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKEJMT09NX0ZJTFRFUl9OQl9IQVNIRVNfRklFTERfREVTQyk7CisgICAgb3Byb3Qud3JpdGVJMzIodGhpcy5ibG9vbUZpbHRlck5iSGFzaGVzKTsKKyAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKEJMT0NLX0NBQ0hFX0VOQUJMRURfRklFTERfREVTQyk7CisgICAgb3Byb3Qud3JpdGVCb29sKHRoaXMuYmxvY2tDYWNoZUVuYWJsZWQpOworICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVElNRV9UT19MSVZFX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTMyKHRoaXMudGltZVRvTGl2ZSk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiQ29sdW1uRGVzY3JpcHRvcigiKTsKKyAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgIHNiLmFwcGVuZCgibmFtZToiKTsKKyAgICBpZiAodGhpcy5uYW1lID09IG51bGwpIHsKKyAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgIH0gZWxzZSB7CisgICAgICBzYi5hcHBlbmQodGhpcy5uYW1lKTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJtYXhWZXJzaW9uczoiKTsKKyAgICBzYi5hcHBlbmQodGhpcy5tYXhWZXJzaW9ucyk7CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJjb21wcmVzc2lvbjoiKTsKKyAgICBpZiAodGhpcy5jb21wcmVzc2lvbiA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMuY29tcHJlc3Npb24pOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICBzYi5hcHBlbmQoImluTWVtb3J5OiIpOworICAgIHNiLmFwcGVuZCh0aGlzLmluTWVtb3J5KTsKKyAgICBmaXJzdCA9IGZhbHNlOworICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICBzYi5hcHBlbmQoIm1heFZhbHVlTGVuZ3RoOiIpOworICAgIHNiLmFwcGVuZCh0aGlzLm1heFZhbHVlTGVuZ3RoKTsKKyAgICBmaXJzdCA9IGZhbHNlOworICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICBzYi5hcHBlbmQoImJsb29tRmlsdGVyVHlwZToiKTsKKyAgICBpZiAodGhpcy5ibG9vbUZpbHRlclR5cGUgPT0gbnVsbCkgeworICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLmJsb29tRmlsdGVyVHlwZSk7CisgICAgfQorICAgIGZpcnN0ID0gZmFsc2U7CisgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgIHNiLmFwcGVuZCgiYmxvb21GaWx0ZXJWZWN0b3JTaXplOiIpOworICAgIHNiLmFwcGVuZCh0aGlzLmJsb29tRmlsdGVyVmVjdG9yU2l6ZSk7CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJibG9vbUZpbHRlck5iSGFzaGVzOiIpOworICAgIHNiLmFwcGVuZCh0aGlzLmJsb29tRmlsdGVyTmJIYXNoZXMpOworICAgIGZpcnN0ID0gZmFsc2U7CisgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgIHNiLmFwcGVuZCgiYmxvY2tDYWNoZUVuYWJsZWQ6Iik7CisgICAgc2IuYXBwZW5kKHRoaXMuYmxvY2tDYWNoZUVuYWJsZWQpOworICAgIGZpcnN0ID0gZmFsc2U7CisgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgIHNiLmFwcGVuZCgidGltZVRvTGl2ZToiKTsKKyAgICBzYi5hcHBlbmQodGhpcy50aW1lVG9MaXZlKTsKKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9IYmFzZS5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9IYmFzZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNzc4M2UKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0hiYXNlLmphdmEKQEAgLTAsMCArMSwyMjEzNiBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisvKioKKyAqIEF1dG9nZW5lcmF0ZWQgYnkgVGhyaWZ0CisgKgorICogRE8gTk9UIEVESVQgVU5MRVNTIFlPVSBBUkUgU1VSRSBUSEFUIFlPVSBLTk9XIFdIQVQgWU9VIEFSRSBET0lORworICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC4qOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0Lm1ldGFfZGF0YS4qOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnByb3RvY29sLio7CisKK3B1YmxpYyBjbGFzcyBIYmFzZSB7CisKKyAgcHVibGljIGludGVyZmFjZSBJZmFjZSB7CisKKyAgICAvKioKKyAgICAgKiBCcmluZ3MgYSB0YWJsZSBvbi1saW5lIChlbmFibGVzIGl0KQorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0aGUgdGFibGUKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICovCisgICAgcHVibGljIHZvaWQgZW5hYmxlVGFibGUoYnl0ZVtdIHRhYmxlTmFtZSkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEaXNhYmxlcyBhIHRhYmxlICh0YWtlcyBpdCBvZmYtbGluZSkgSWYgaXQgaXMgYmVpbmcgc2VydmVkLCB0aGUgbWFzdGVyCisgICAgICogd2lsbCB0ZWxsIHRoZSBzZXJ2ZXJzIHRvIHN0b3Agc2VydmluZyBpdC4KKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGhlIHRhYmxlCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRpc2FibGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZSB0byBjaGVjaworICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0YWJsZSBpcyBvbi1saW5lCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzVGFibGVFbmFibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgcHVibGljIHZvaWQgY29tcGFjdChieXRlW10gdGFibGVOYW1lT3JSZWdpb25OYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIHB1YmxpYyB2b2lkIG1ham9yQ29tcGFjdChieXRlW10gdGFibGVOYW1lT3JSZWdpb25OYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIExpc3QgYWxsIHRoZSB1c2Vyc3BhY2UgdGFibGVzLgorICAgICAqIEByZXR1cm4gLSByZXR1cm5zIGEgbGlzdCBvZiBuYW1lcworICAgICAqLworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0VGFibGVOYW1lcygpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogTGlzdCBhbGwgdGhlIGNvbHVtbiBmYW1pbGllcyBhc3NvaWNhdGVkIHdpdGggYSB0YWJsZS4KKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIHRhYmxlIG5hbWUKKyAgICAgKiBAcmV0dXJuIGxpc3Qgb2YgY29sdW1uIGZhbWlseSBkZXNjcmlwdG9ycworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgTWFwPGJ5dGVbXSxDb2x1bW5EZXNjcmlwdG9yPiBnZXRDb2x1bW5EZXNjcmlwdG9ycyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIExpc3QgdGhlIHJlZ2lvbnMgYXNzb2NpYXRlZCB3aXRoIGEgdGFibGUuCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSB0YWJsZSBuYW1lCisgICAgICogQHJldHVybiBsaXN0IG9mIHJlZ2lvbiBkZXNjcmlwdG9ycworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUUmVnaW9uSW5mbz4gZ2V0VGFibGVSZWdpb25zKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgdGFibGUgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbGllcy4gIFRoZSBuYW1lCisgICAgICogZmllbGQgZm9yIGVhY2ggQ29sdW1uRGVzY3JpcHRvciBtdXN0IGJlIHNldCBhbmQgbXVzdCBlbmQgaW4gYQorICAgICAqIGNvbG9uICg6KS4gIEFsbCBvdGhlciBmaWVsZHMgYXJlIG9wdGlvbmFsIGFuZCB3aWxsIGdldCBkZWZhdWx0CisgICAgICogdmFsdWVzIGlmIG5vdCBleHBsaWNpdGx5IHNwZWNpZmllZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gY3JlYXRlCisgICAgICogQHBhcmFtIGNvbHVtbkZhbWlsaWVzIGxpc3Qgb2YgY29sdW1uIGZhbWlseSBkZXNjcmlwdG9ycworICAgICAqIAorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50IGlmIGFuIGlucHV0IHBhcmFtZXRlciBpcyBpbnZhbGlkCisgICAgICogQHRocm93cyBBbHJlYWR5RXhpc3RzIGlmIHRoZSB0YWJsZSBuYW1lIGFscmVhZHkgZXhpc3RzCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSBjb2x1bW5GYW1pbGllcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNyZWF0ZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8Q29sdW1uRGVzY3JpcHRvcj4gY29sdW1uRmFtaWxpZXMpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIEFscmVhZHlFeGlzdHMsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBEZWxldGVzIGEgdGFibGUKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUgdG8gZGVsZXRlCisgICAgICogQHRocm93cyBJT0Vycm9yIGlmIHRhYmxlIGRvZXNuJ3QgZXhpc3Qgb24gc2VydmVyIG9yIHRoZXJlIHdhcyBzb21lIG90aGVyCisgICAgICogcHJvYmxlbQorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBkZWxldGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhIHNpbmdsZSBUQ2VsbCBmb3IgdGhlIHNwZWNpZmllZCB0YWJsZSwgcm93LCBhbmQgY29sdW1uIGF0IHRoZQorICAgICAqIGxhdGVzdCB0aW1lc3RhbXAuIFJldHVybnMgYW4gZW1wdHkgbGlzdCBpZiBubyBzdWNoIHZhbHVlIGV4aXN0cy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAgICogQHJldHVybiB2YWx1ZSBmb3Igc3BlY2lmaWVkIHJvdy9jb2x1bW4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4pIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHZlcnNpb25zIGZvciB0aGUgc3BlY2lmaWVkIHRhYmxlLAorICAgICAqIHJvdywgYW5kIGNvbHVtbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBuYW1lCisgICAgICogQHBhcmFtIG51bVZlcnNpb25zIG51bWJlciBvZiB2ZXJzaW9ucyB0byByZXRyaWV2ZQorICAgICAqIEByZXR1cm4gbGlzdCBvZiBjZWxscyBmb3Igc3BlY2lmaWVkIHJvdy9jb2x1bW4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiBAcGFyYW0gbnVtVmVyc2lvbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0VmVyKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4sIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdmVyc2lvbnMgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUsCisgICAgICogcm93LCBhbmQgY29sdW1uLiAgT25seSB2ZXJzaW9ucyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNwZWNpZmllZAorICAgICAqIHRpbWVzdGFtcCB3aWxsIGJlIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgICAqIEBwYXJhbSBjb2x1bW4gY29sdW1uIG5hbWUKKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcAorICAgICAqIEBwYXJhbSBudW1WZXJzaW9ucyBudW1iZXIgb2YgdmVyc2lvbnMgdG8gcmV0cmlldmUKKyAgICAgKiBAcmV0dXJuIGxpc3Qgb2YgY2VsbHMgZm9yIHNwZWNpZmllZCByb3cvY29sdW1uCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgICAqIEBwYXJhbSBudW1WZXJzaW9ucworICAgICAqLworICAgIHB1YmxpYyBMaXN0PFRDZWxsPiBnZXRWZXJUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uLCBsb25nIHRpbWVzdGFtcCwgaW50IG51bVZlcnNpb25zKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhbGwgdGhlIGRhdGEgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUgYW5kIHJvdyBhdCB0aGUgbGF0ZXN0CisgICAgICogdGltZXN0YW1wLiBSZXR1cm5zIGFuIGVtcHR5IGxpc3QgaWYgdGhlIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcmV0dXJuIFRSb3dSZXN1bHQgY29udGFpbmluZyB0aGUgcm93IGFuZCBtYXAgb2YgY29sdW1ucyB0byBUQ2VsbHMKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqLworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IGdldFJvdyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93KSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCB0aGUgc3BlY2lmaWVkIGNvbHVtbnMgZm9yIHRoZSBzcGVjaWZpZWQgdGFibGUgYW5kIHJvdyBhdCB0aGUgbGF0ZXN0CisgICAgICogdGltZXN0YW1wLiBSZXR1cm5zIGFuIGVtcHR5IGxpc3QgaWYgdGhlIHJvdyBkb2VzIG5vdCBleGlzdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcGFyYW0gY29sdW1ucyBMaXN0IG9mIGNvbHVtbnMgdG8gcmV0dXJuLCBudWxsIGZvciBhbGwgY29sdW1ucworICAgICAqIEByZXR1cm4gVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSByb3cgYW5kIG1hcCBvZiBjb2x1bW5zIHRvIFRDZWxscworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIGNvbHVtbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRSb3dXaXRoQ29sdW1ucyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBMaXN0PGJ5dGVbXT4gY29sdW1ucykgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBHZXQgYWxsIHRoZSBkYXRhIGZvciB0aGUgc3BlY2lmaWVkIHRhYmxlIGFuZCByb3cgYXQgdGhlIHNwZWNpZmllZAorICAgICAqIHRpbWVzdGFtcC4gUmV0dXJucyBhbiBlbXB0eSBsaXN0IGlmIHRoZSByb3cgZG9lcyBub3QgZXhpc3QuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAgICogQHJldHVybiBUUm93UmVzdWx0IGNvbnRhaW5pbmcgdGhlIHJvdyBhbmQgbWFwIG9mIGNvbHVtbnMgdG8gVENlbGxzCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93VHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IHRoZSBzcGVjaWZpZWQgY29sdW1ucyBmb3IgdGhlIHNwZWNpZmllZCB0YWJsZSBhbmQgcm93IGF0IHRoZSBzcGVjaWZpZWQKKyAgICAgKiB0aW1lc3RhbXAuIFJldHVybnMgYW4gZW1wdHkgbGlzdCBpZiB0aGUgcm93IGRvZXMgbm90IGV4aXN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgICAqIEBwYXJhbSBjb2x1bW5zIExpc3Qgb2YgY29sdW1ucyB0byByZXR1cm4sIG51bGwgZm9yIGFsbCBjb2x1bW5zCisgICAgICogQHJldHVybiBUUm93UmVzdWx0IGNvbnRhaW5pbmcgdGhlIHJvdyBhbmQgbWFwIG9mIGNvbHVtbnMgdG8gVENlbGxzCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gY29sdW1ucworICAgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRSb3dXaXRoQ29sdW1uc1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBBcHBseSBhIHNlcmllcyBvZiBtdXRhdGlvbnMgKHVwZGF0ZXMvZGVsZXRlcykgdG8gYSByb3cgaW4gYQorICAgICAqIHNpbmdsZSB0cmFuc2FjdGlvbi4gIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24sIHRoZW4gdGhlCisgICAgICogdHJhbnNhY3Rpb24gaXMgYWJvcnRlZC4gIERlZmF1bHQgY3VycmVudCB0aW1lc3RhbXAgaXMgdXNlZCwgYW5kCisgICAgICogYWxsIGVudHJpZXMgd2lsbCBoYXZlIGFuIGlkZW50aWNhbCB0aW1lc3RhbXAuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAgICogQHBhcmFtIG11dGF0aW9ucyBsaXN0IG9mIG11dGF0aW9uIGNvbW1hbmRzCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gbXV0YXRpb25zCisgICAgICovCisgICAgcHVibGljIHZvaWQgbXV0YXRlUm93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucykgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFwcGx5IGEgc2VyaWVzIG9mIG11dGF0aW9ucyAodXBkYXRlcy9kZWxldGVzKSB0byBhIHJvdyBpbiBhCisgICAgICogc2luZ2xlIHRyYW5zYWN0aW9uLiAgSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biwgdGhlbiB0aGUKKyAgICAgKiB0cmFuc2FjdGlvbiBpcyBhYm9ydGVkLiAgVGhlIHNwZWNpZmllZCB0aW1lc3RhbXAgaXMgdXNlZCwgYW5kCisgICAgICogYWxsIGVudHJpZXMgd2lsbCBoYXZlIGFuIGlkZW50aWNhbCB0aW1lc3RhbXAuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvdyByb3cga2V5CisgICAgICogQHBhcmFtIG11dGF0aW9ucyBsaXN0IG9mIG11dGF0aW9uIGNvbW1hbmRzCisgICAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEBwYXJhbSBtdXRhdGlvbnMKKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIHZvaWQgbXV0YXRlUm93VHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEFwcGx5IGEgc2VyaWVzIG9mIGJhdGNoZXMgKGVhY2ggYSBzZXJpZXMgb2YgbXV0YXRpb25zIG9uIGEgc2luZ2xlIHJvdykKKyAgICAgKiBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbi4gIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24sIHRoZW4gdGhlCisgICAgICogdHJhbnNhY3Rpb24gaXMgYWJvcnRlZC4gIERlZmF1bHQgY3VycmVudCB0aW1lc3RhbXAgaXMgdXNlZCwgYW5kCisgICAgICogYWxsIGVudHJpZXMgd2lsbCBoYXZlIGFuIGlkZW50aWNhbCB0aW1lc3RhbXAuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvd0JhdGNoZXMgbGlzdCBvZiByb3cgYmF0Y2hlcworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93QmF0Y2hlcworICAgICAqLworICAgIHB1YmxpYyB2b2lkIG11dGF0ZVJvd3MoYnl0ZVtdIHRhYmxlTmFtZSwgTGlzdDxCYXRjaE11dGF0aW9uPiByb3dCYXRjaGVzKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQXBwbHkgYSBzZXJpZXMgb2YgYmF0Y2hlcyAoZWFjaCBhIHNlcmllcyBvZiBtdXRhdGlvbnMgb24gYSBzaW5nbGUgcm93KQorICAgICAqIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiAgSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biwgdGhlbiB0aGUKKyAgICAgKiB0cmFuc2FjdGlvbiBpcyBhYm9ydGVkLiAgVGhlIHNwZWNpZmllZCB0aW1lc3RhbXAgaXMgdXNlZCwgYW5kCisgICAgICogYWxsIGVudHJpZXMgd2lsbCBoYXZlIGFuIGlkZW50aWNhbCB0aW1lc3RhbXAuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvd0JhdGNoZXMgbGlzdCBvZiByb3cgYmF0Y2hlcworICAgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3dCYXRjaGVzCisgICAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG11dGF0ZVJvd3NUcyhieXRlW10gdGFibGVOYW1lLCBMaXN0PEJhdGNoTXV0YXRpb24+IHJvd0JhdGNoZXMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQXRvbWljYWxseSBpbmNyZW1lbnQgdGhlIGNvbHVtbiB2YWx1ZSBzcGVjaWZpZWQuICBSZXR1cm5zIHRoZSBuZXh0IHZhbHVlIHBvc3QgaW5jcmVtZW50LgorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSByb3cgcm93IHRvIGluY3JlbWVudAorICAgICAqIEBwYXJhbSBjb2x1bW4gbmFtZSBvZiBjb2x1bW4KKyAgICAgKiBAcGFyYW0gdmFsdWUgYW1vdW50IHRvIGluY3JlbWVudCBieQorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBsb25nIGF0b21pY0luY3JlbWVudChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uLCBsb25nIHZhbHVlKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4uCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBkZWxldGVkCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZQorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlQWxsKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4pIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogRGVsZXRlIGFsbCBjZWxscyB0aGF0IG1hdGNoIHRoZSBwYXNzZWQgcm93IGFuZCBjb2x1bW4gYW5kIHdob3NlCisgICAgICogdGltZXN0YW1wIGlzIGVxdWFsLXRvIG9yIG9sZGVyIHRoYW4gdGhlIHBhc3NlZCB0aW1lc3RhbXAuCisgICAgICogCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHJvdyBSb3cgdG8gdXBkYXRlCisgICAgICogQHBhcmFtIGNvbHVtbiBuYW1lIG9mIGNvbHVtbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBkZWxldGVkCisgICAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlQWxsVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29tcGxldGVseSBkZWxldGUgdGhlIHJvdydzIGNlbGxzLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSByb3cga2V5IG9mIHRoZSByb3cgdG8gYmUgY29tcGxldGVseSBkZWxldGVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlQWxsUm93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3cpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogQ29tcGxldGVseSBkZWxldGUgdGhlIHJvdydzIGNlbGxzIG1hcmtlZCB3aXRoIGEgdGltZXN0YW1wCisgICAgICogZXF1YWwtdG8gb3Igb2xkZXIgdGhhbiB0aGUgcGFzc2VkIHRpbWVzdGFtcC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gcm93IGtleSBvZiB0aGUgcm93IHRvIGJlIGNvbXBsZXRlbHkgZGVsZXRlZC4KKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcAorICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbFJvd1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cgYW5kCisgICAgICogZW5kaW5nIGF0IHRoZSBsYXN0IHJvdyBpbiB0aGUgdGFibGUuICBSZXR1cm4gdGhlIHNwZWNpZmllZCBjb2x1bW5zLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgICAqIHRvIHBhc3MgYSByZWdleCBpbiB0aGUgY29sdW1uIHF1YWxpZmllci4KKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4uICBzZW5kICIiIChlbXB0eSBzdHJpbmcpIHRvCisgICAgICogICAgICAgICAgICAgICAgIHN0YXJ0IGF0IHRoZSBmaXJzdCByb3cuCisgICAgICogCisgICAgICogQHJldHVybiBzY2FubmVyIGlkIHRvIGJlIHVzZWQgd2l0aCBvdGhlciBzY2FubmVyIHByb2NlZHVyZXMKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lCisgICAgICogQHBhcmFtIHN0YXJ0Um93CisgICAgICogQHBhcmFtIGNvbHVtbnMKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgTGlzdDxieXRlW10+IGNvbHVtbnMpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhbmQgc3RvcHBpbmcgYXQgdGhlCisgICAgICogc3BlY2lmaWVkIHJvd3MuICBlbmRpbmcgYXQgdGhlIGxhc3Qgcm93IGluIHRoZSB0YWJsZS4gIFJldHVybiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY29sdW1ucy4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY29sdW1ucyBjb2x1bW5zIHRvIHNjYW4uIElmIGNvbHVtbiBuYW1lIGlzIGEgY29sdW1uIGZhbWlseSwgYWxsCisgICAgICogY29sdW1ucyBvZiB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmYW1pbHkgYXJlIHJldHVybmVkLiAgSXRzIGFsc28gcG9zc2libGUKKyAgICAgKiB0byBwYXNzIGEgcmVnZXggaW4gdGhlIGNvbHVtbiBxdWFsaWZpZXIuCisgICAgICogQHBhcmFtIHRhYmxlTmFtZSBuYW1lIG9mIHRhYmxlCisgICAgICogQHBhcmFtIHN0YXJ0Um93IHN0YXJ0aW5nIHJvdyBpbiB0YWJsZSB0byBzY2FuLiAgc2VuZCAiIiAoZW1wdHkgc3RyaW5nKSB0bworICAgICAqICAgICAgICAgICAgICAgICBzdGFydCBhdCB0aGUgZmlyc3Qgcm93LgorICAgICAqIEBwYXJhbSBzdG9wUm93IHJvdyB0byBzdG9wIHNjYW5uaW5nIG9uLiAgVGhpcyByb3cgaXMgKm5vdCogaW5jbHVkZWQgaW4gdGhlCisgICAgICogICAgICAgICAgICAgICAgc2Nhbm5lcidzIHJlc3VsdHMKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHNjYW5uZXIgaWQgdG8gYmUgdXNlZCB3aXRoIG90aGVyIHNjYW5uZXIgcHJvY2VkdXJlcworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cKKyAgICAgKiBAcGFyYW0gc3RvcFJvdworICAgICAqIEBwYXJhbSBjb2x1bW5zCisgICAgICovCisgICAgcHVibGljIGludCBzY2FubmVyT3BlbldpdGhTdG9wKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgYnl0ZVtdIHN0b3BSb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEdldCBhIHNjYW5uZXIgb24gdGhlIGN1cnJlbnQgdGFibGUgc3RhcnRpbmcgYXQgdGhlIHNwZWNpZmllZCByb3cgYW5kCisgICAgICogZW5kaW5nIGF0IHRoZSBsYXN0IHJvdyBpbiB0aGUgdGFibGUuICBSZXR1cm4gdGhlIHNwZWNpZmllZCBjb2x1bW5zLgorICAgICAqIE9ubHkgdmFsdWVzIHdpdGggdGhlIHNwZWNpZmllZCB0aW1lc3RhbXAgYXJlIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBjb2x1bW5zIGNvbHVtbnMgdG8gc2Nhbi4gSWYgY29sdW1uIG5hbWUgaXMgYSBjb2x1bW4gZmFtaWx5LCBhbGwKKyAgICAgKiBjb2x1bW5zIG9mIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZhbWlseSBhcmUgcmV0dXJuZWQuICBJdHMgYWxzbyBwb3NzaWJsZQorICAgICAqIHRvIHBhc3MgYSByZWdleCBpbiB0aGUgY29sdW1uIHF1YWxpZmllci4KKyAgICAgKiBAcGFyYW0gdGFibGVOYW1lIG5hbWUgb2YgdGFibGUKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cgc3RhcnRpbmcgcm93IGluIHRhYmxlIHRvIHNjYW4uICBzZW5kICIiIChlbXB0eSBzdHJpbmcpIHRvCisgICAgICogICAgICAgICAgICAgICAgIHN0YXJ0IGF0IHRoZSBmaXJzdCByb3cuCisgICAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHNjYW5uZXIgaWQgdG8gYmUgdXNlZCB3aXRoIG90aGVyIHNjYW5uZXIgcHJvY2VkdXJlcworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cKKyAgICAgKiBAcGFyYW0gY29sdW1ucworICAgICAqIEBwYXJhbSB0aW1lc3RhbXAKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LCBMaXN0PGJ5dGVbXT4gY29sdW1ucywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogR2V0IGEgc2Nhbm5lciBvbiB0aGUgY3VycmVudCB0YWJsZSBzdGFydGluZyBhbmQgc3RvcHBpbmcgYXQgdGhlCisgICAgICogc3BlY2lmaWVkIHJvd3MuICBlbmRpbmcgYXQgdGhlIGxhc3Qgcm93IGluIHRoZSB0YWJsZS4gIFJldHVybiB0aGUKKyAgICAgKiBzcGVjaWZpZWQgY29sdW1ucy4gIE9ubHkgdmFsdWVzIHdpdGggdGhlIHNwZWNpZmllZCB0aW1lc3RhbXAgYXJlCisgICAgICogcmV0dXJuZWQuCisgICAgICogCisgICAgICogQHBhcmFtIGNvbHVtbnMgY29sdW1ucyB0byBzY2FuLiBJZiBjb2x1bW4gbmFtZSBpcyBhIGNvbHVtbiBmYW1pbHksIGFsbAorICAgICAqIGNvbHVtbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW4gZmFtaWx5IGFyZSByZXR1cm5lZC4gIEl0cyBhbHNvIHBvc3NpYmxlCisgICAgICogdG8gcGFzcyBhIHJlZ2V4IGluIHRoZSBjb2x1bW4gcXVhbGlmaWVyLgorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUgbmFtZSBvZiB0YWJsZQorICAgICAqIEBwYXJhbSBzdGFydFJvdyBzdGFydGluZyByb3cgaW4gdGFibGUgdG8gc2Nhbi4gIHNlbmQgIiIgKGVtcHR5IHN0cmluZykgdG8KKyAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnQgYXQgdGhlIGZpcnN0IHJvdy4KKyAgICAgKiBAcGFyYW0gc3RvcFJvdyByb3cgdG8gc3RvcCBzY2FubmluZyBvbi4gIFRoaXMgcm93IGlzICpub3QqIGluY2x1ZGVkCisgICAgICogICAgICAgICAgICAgICAgaW4gdGhlIHNjYW5uZXIncyByZXN1bHRzCisgICAgICogQHBhcmFtIHRpbWVzdGFtcCB0aW1lc3RhbXAKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHNjYW5uZXIgaWQgdG8gYmUgdXNlZCB3aXRoIG90aGVyIHNjYW5uZXIgcHJvY2VkdXJlcworICAgICAqIAorICAgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICAgKiBAcGFyYW0gc3RhcnRSb3cKKyAgICAgKiBAcGFyYW0gc3RvcFJvdworICAgICAqIEBwYXJhbSBjb2x1bW5zCisgICAgICogQHBhcmFtIHRpbWVzdGFtcAorICAgICAqLworICAgIHB1YmxpYyBpbnQgc2Nhbm5lck9wZW5XaXRoU3RvcFRzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgYnl0ZVtdIHN0b3BSb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm5zIHRoZSBzY2FubmVyJ3MgY3VycmVudCByb3cgdmFsdWUgYW5kIGFkdmFuY2VzIHRvIHRoZSBuZXh0CisgICAgICogcm93IGluIHRoZSB0YWJsZS4gIFdoZW4gdGhlcmUgYXJlIG5vIG1vcmUgcm93cyBpbiB0aGUgdGFibGUsIG9yIGEga2V5CisgICAgICogZ3JlYXRlci10aGFuLW9yLWVxdWFsLXRvIHRoZSBzY2FubmVyJ3Mgc3BlY2lmaWVkIHN0b3BSb3cgaXMgcmVhY2hlZCwKKyAgICAgKiBhbiBlbXB0eSBsaXN0IGlzIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZCBpZCBvZiBhIHNjYW5uZXIgcmV0dXJuZWQgYnkgc2Nhbm5lck9wZW4KKyAgICAgKiBAcmV0dXJuIGEgVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSBjdXJyZW50IHJvdyBhbmQgYSBtYXAgb2YgdGhlIGNvbHVtbnMgdG8gVENlbGxzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50IGlmIFNjYW5uZXJJRCBpcyBpbnZhbGlkCisgICAgICogQHRocm93cyBOb3RGb3VuZCB3aGVuIHRoZSBzY2FubmVyIHJlYWNoZXMgdGhlIGVuZAorICAgICAqIAorICAgICAqIEBwYXJhbSBpZAorICAgICAqLworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IHNjYW5uZXJHZXQoaW50IGlkKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uOworCisgICAgLyoqCisgICAgICogUmV0dXJucywgc3RhcnRpbmcgYXQgdGhlIHNjYW5uZXIncyBjdXJyZW50IHJvdyB2YWx1ZSBuYlJvd3Mgd29ydGggb2YKKyAgICAgKiByb3dzIGFuZCBhZHZhbmNlcyB0byB0aGUgbmV4dCByb3cgaW4gdGhlIHRhYmxlLiAgV2hlbiB0aGVyZSBhcmUgbm8gbW9yZQorICAgICAqIHJvd3MgaW4gdGhlIHRhYmxlLCBvciBhIGtleSBncmVhdGVyLXRoYW4tb3ItZXF1YWwtdG8gdGhlIHNjYW5uZXIncworICAgICAqIHNwZWNpZmllZCBzdG9wUm93IGlzIHJlYWNoZWQsICBhbiBlbXB0eSBsaXN0IGlzIHJldHVybmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZCBpZCBvZiBhIHNjYW5uZXIgcmV0dXJuZWQgYnkgc2Nhbm5lck9wZW4KKyAgICAgKiBAcGFyYW0gbmJSb3dzIG51bWJlciBvZiByZXN1bHRzIHRvIHJlZ3R1cm4KKyAgICAgKiBAcmV0dXJuIGEgVFJvd1Jlc3VsdCBjb250YWluaW5nIHRoZSBjdXJyZW50IHJvdyBhbmQgYSBtYXAgb2YgdGhlIGNvbHVtbnMgdG8gVENlbGxzLgorICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50IGlmIFNjYW5uZXJJRCBpcyBpbnZhbGlkCisgICAgICogQHRocm93cyBOb3RGb3VuZCB3aGVuIHRoZSBzY2FubmVyIHJlYWNoZXMgdGhlIGVuZAorICAgICAqIAorICAgICAqIEBwYXJhbSBpZAorICAgICAqIEBwYXJhbSBuYlJvd3MKKyAgICAgKi8KKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBzY2FubmVyR2V0TGlzdChpbnQgaWQsIGludCBuYlJvd3MpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb247CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHNlcnZlci1zdGF0ZSBhc3NvY2lhdGVkIHdpdGggYW4gb3BlbiBzY2FubmVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBpZCBpZCBvZiBhIHNjYW5uZXIgcmV0dXJuZWQgYnkgc2Nhbm5lck9wZW4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudCBpZiBTY2FubmVySUQgaXMgaW52YWxpZAorICAgICAqIAorICAgICAqIEBwYXJhbSBpZAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNjYW5uZXJDbG9zZShpbnQgaWQpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb247CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ2xpZW50IGltcGxlbWVudHMgSWZhY2UgeworICAgIHB1YmxpYyBDbGllbnQoVFByb3RvY29sIHByb3QpCisgICAgeworICAgICAgdGhpcyhwcm90LCBwcm90KTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2xpZW50KFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KQorICAgIHsKKyAgICAgIGlwcm90XyA9IGlwcm90OworICAgICAgb3Byb3RfID0gb3Byb3Q7CisgICAgfQorCisgICAgcHJvdGVjdGVkIFRQcm90b2NvbCBpcHJvdF87CisgICAgcHJvdGVjdGVkIFRQcm90b2NvbCBvcHJvdF87CisKKyAgICBwcm90ZWN0ZWQgaW50IHNlcWlkXzsKKworICAgIHB1YmxpYyBUUHJvdG9jb2wgZ2V0SW5wdXRQcm90b2NvbCgpCisgICAgeworICAgICAgcmV0dXJuIHRoaXMuaXByb3RfOworICAgIH0KKworICAgIHB1YmxpYyBUUHJvdG9jb2wgZ2V0T3V0cHV0UHJvdG9jb2woKQorICAgIHsKKyAgICAgIHJldHVybiB0aGlzLm9wcm90XzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBlbmFibGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZW5hYmxlVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJlY3ZfZW5hYmxlVGFibGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2VuYWJsZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZW5hYmxlVGFibGUiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBlbmFibGVUYWJsZV9hcmdzIGFyZ3MgPSBuZXcgZW5hYmxlVGFibGVfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X2VuYWJsZVRhYmxlKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGVuYWJsZVRhYmxlX3Jlc3VsdCByZXN1bHQgPSBuZXcgZW5hYmxlVGFibGVfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRpc2FibGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZGlzYWJsZVRhYmxlKHRhYmxlTmFtZSk7CisgICAgICByZWN2X2Rpc2FibGVUYWJsZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfZGlzYWJsZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGlzYWJsZVRhYmxlIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZGlzYWJsZVRhYmxlX2FyZ3MgYXJncyA9IG5ldyBkaXNhYmxlVGFibGVfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X2Rpc2FibGVUYWJsZSgpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBkaXNhYmxlVGFibGVfcmVzdWx0IHJlc3VsdCA9IG5ldyBkaXNhYmxlVGFibGVfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzVGFibGVFbmFibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9pc1RhYmxlRW5hYmxlZCh0YWJsZU5hbWUpOworICAgICAgcmV0dXJuIHJlY3ZfaXNUYWJsZUVuYWJsZWQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2lzVGFibGVFbmFibGVkKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiaXNUYWJsZUVuYWJsZWQiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBpc1RhYmxlRW5hYmxlZF9hcmdzIGFyZ3MgPSBuZXcgaXNUYWJsZUVuYWJsZWRfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiByZWN2X2lzVGFibGVFbmFibGVkKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGlzVGFibGVFbmFibGVkX3Jlc3VsdCByZXN1bHQgPSBuZXcgaXNUYWJsZUVuYWJsZWRfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgImlzVGFibGVFbmFibGVkIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjb21wYWN0KGJ5dGVbXSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9jb21wYWN0KHRhYmxlTmFtZU9yUmVnaW9uTmFtZSk7CisgICAgICByZWN2X2NvbXBhY3QoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2NvbXBhY3QoYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJjb21wYWN0IiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgY29tcGFjdF9hcmdzIGFyZ3MgPSBuZXcgY29tcGFjdF9hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IHRhYmxlTmFtZU9yUmVnaW9uTmFtZTsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlY3ZfY29tcGFjdCgpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBjb21wYWN0X3Jlc3VsdCByZXN1bHQgPSBuZXcgY29tcGFjdF9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbWFqb3JDb21wYWN0KGJ5dGVbXSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9tYWpvckNvbXBhY3QodGFibGVOYW1lT3JSZWdpb25OYW1lKTsKKyAgICAgIHJlY3ZfbWFqb3JDb21wYWN0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9tYWpvckNvbXBhY3QoYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJtYWpvckNvbXBhY3QiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBtYWpvckNvbXBhY3RfYXJncyBhcmdzID0gbmV3IG1ham9yQ29tcGFjdF9hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IHRhYmxlTmFtZU9yUmVnaW9uTmFtZTsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlY3ZfbWFqb3JDb21wYWN0KCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIG1ham9yQ29tcGFjdF9yZXN1bHQgcmVzdWx0ID0gbmV3IG1ham9yQ29tcGFjdF9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgcHVibGljIExpc3Q8Ynl0ZVtdPiBnZXRUYWJsZU5hbWVzKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2dldFRhYmxlTmFtZXMoKTsKKyAgICAgIHJldHVybiByZWN2X2dldFRhYmxlTmFtZXMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2dldFRhYmxlTmFtZXMoKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFRhYmxlTmFtZXMiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBnZXRUYWJsZU5hbWVzX2FyZ3MgYXJncyA9IG5ldyBnZXRUYWJsZU5hbWVzX2FyZ3MoKTsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gcmVjdl9nZXRUYWJsZU5hbWVzKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldFRhYmxlTmFtZXNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRUYWJsZU5hbWVzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRUYWJsZU5hbWVzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTWFwPGJ5dGVbXSxDb2x1bW5EZXNjcmlwdG9yPiBnZXRDb2x1bW5EZXNjcmlwdG9ycyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZ2V0Q29sdW1uRGVzY3JpcHRvcnModGFibGVOYW1lKTsKKyAgICAgIHJldHVybiByZWN2X2dldENvbHVtbkRlc2NyaXB0b3JzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9nZXRDb2x1bW5EZXNjcmlwdG9ycyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldENvbHVtbkRlc2NyaXB0b3JzIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncyBhcmdzID0gbmV3IGdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4gcmVjdl9nZXRDb2x1bW5EZXNjcmlwdG9ycygpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRDb2x1bW5EZXNjcmlwdG9ycyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJlZ2lvbkluZm8+IGdldFRhYmxlUmVnaW9ucyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZ2V0VGFibGVSZWdpb25zKHRhYmxlTmFtZSk7CisgICAgICByZXR1cm4gcmVjdl9nZXRUYWJsZVJlZ2lvbnMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2dldFRhYmxlUmVnaW9ucyhieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFRhYmxlUmVnaW9ucyIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIGdldFRhYmxlUmVnaW9uc19hcmdzIGFyZ3MgPSBuZXcgZ2V0VGFibGVSZWdpb25zX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJlZ2lvbkluZm8+IHJlY3ZfZ2V0VGFibGVSZWdpb25zKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldFRhYmxlUmVnaW9uc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFRhYmxlUmVnaW9uc19yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAiZ2V0VGFibGVSZWdpb25zIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBjcmVhdGVUYWJsZShieXRlW10gdGFibGVOYW1lLCBMaXN0PENvbHVtbkRlc2NyaXB0b3I+IGNvbHVtbkZhbWlsaWVzKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBBbHJlYWR5RXhpc3RzLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9jcmVhdGVUYWJsZSh0YWJsZU5hbWUsIGNvbHVtbkZhbWlsaWVzKTsKKyAgICAgIHJlY3ZfY3JlYXRlVGFibGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2NyZWF0ZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8Q29sdW1uRGVzY3JpcHRvcj4gY29sdW1uRmFtaWxpZXMpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiY3JlYXRlVGFibGUiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBjcmVhdGVUYWJsZV9hcmdzIGFyZ3MgPSBuZXcgY3JlYXRlVGFibGVfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLmNvbHVtbkZhbWlsaWVzID0gY29sdW1uRmFtaWxpZXM7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X2NyZWF0ZVRhYmxlKCkgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgQWxyZWFkeUV4aXN0cywgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgY3JlYXRlVGFibGVfcmVzdWx0IHJlc3VsdCA9IG5ldyBjcmVhdGVUYWJsZV9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlhICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlhOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5leGlzdCAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5leGlzdDsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVUYWJsZShieXRlW10gdGFibGVOYW1lKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZGVsZXRlVGFibGUodGFibGVOYW1lKTsKKyAgICAgIHJlY3ZfZGVsZXRlVGFibGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2RlbGV0ZVRhYmxlKGJ5dGVbXSB0YWJsZU5hbWUpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGVsZXRlVGFibGUiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBkZWxldGVUYWJsZV9hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlVGFibGVfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X2RlbGV0ZVRhYmxlKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGRlbGV0ZVRhYmxlX3Jlc3VsdCByZXN1bHQgPSBuZXcgZGVsZXRlVGFibGVfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRDZWxsPiBnZXQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbikgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2dldCh0YWJsZU5hbWUsIHJvdywgY29sdW1uKTsKKyAgICAgIHJldHVybiByZWN2X2dldCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfZ2V0KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4pIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZ2V0IiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZ2V0X2FyZ3MgYXJncyA9IG5ldyBnZXRfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MuY29sdW1uID0gY29sdW1uOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VENlbGw+IHJlY3ZfZ2V0KCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldF9yZXN1bHQgcmVzdWx0ID0gbmV3IGdldF9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAiZ2V0IGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0VmVyKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4sIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2dldFZlcih0YWJsZU5hbWUsIHJvdywgY29sdW1uLCBudW1WZXJzaW9ucyk7CisgICAgICByZXR1cm4gcmVjdl9nZXRWZXIoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2dldFZlcihieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uLCBpbnQgbnVtVmVyc2lvbnMpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZ2V0VmVyIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZ2V0VmVyX2FyZ3MgYXJncyA9IG5ldyBnZXRWZXJfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MuY29sdW1uID0gY29sdW1uOworICAgICAgYXJncy5udW1WZXJzaW9ucyA9IG51bVZlcnNpb25zOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VENlbGw+IHJlY3ZfZ2V0VmVyKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldFZlcl9yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFZlcl9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAiZ2V0VmVyIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gZ2V0VmVyVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwgbG9uZyB0aW1lc3RhbXAsIGludCBudW1WZXJzaW9ucykgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2dldFZlclRzKHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHRpbWVzdGFtcCwgbnVtVmVyc2lvbnMpOworICAgICAgcmV0dXJuIHJlY3ZfZ2V0VmVyVHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2dldFZlclRzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4sIGxvbmcgdGltZXN0YW1wLCBpbnQgbnVtVmVyc2lvbnMpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZ2V0VmVyVHMiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBnZXRWZXJUc19hcmdzIGFyZ3MgPSBuZXcgZ2V0VmVyVHNfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MuY29sdW1uID0gY29sdW1uOworICAgICAgYXJncy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICBhcmdzLm51bVZlcnNpb25zID0gbnVtVmVyc2lvbnM7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gcmVjdl9nZXRWZXJUcygpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBnZXRWZXJUc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFZlclRzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRWZXJUcyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3cpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9nZXRSb3codGFibGVOYW1lLCByb3cpOworICAgICAgcmV0dXJuIHJlY3ZfZ2V0Um93KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9nZXRSb3coYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdykgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXRSb3ciLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBnZXRSb3dfYXJncyBhcmdzID0gbmV3IGdldFJvd19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93ID0gcm93OworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gcmVjdl9nZXRSb3coKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgZ2V0Um93X3Jlc3VsdCByZXN1bHQgPSBuZXcgZ2V0Um93X3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRSb3cgZmFpbGVkOiB1bmtub3duIHJlc3VsdCIpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IGdldFJvd1dpdGhDb2x1bW5zKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZ2V0Um93V2l0aENvbHVtbnModGFibGVOYW1lLCByb3csIGNvbHVtbnMpOworICAgICAgcmV0dXJuIHJlY3ZfZ2V0Um93V2l0aENvbHVtbnMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2dldFJvd1dpdGhDb2x1bW5zKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFJvd1dpdGhDb2x1bW5zIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZ2V0Um93V2l0aENvbHVtbnNfYXJncyBhcmdzID0gbmV3IGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5yb3cgPSByb3c7CisgICAgICBhcmdzLmNvbHVtbnMgPSBjb2x1bW5zOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gcmVjdl9nZXRSb3dXaXRoQ29sdW1ucygpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRSb3dXaXRoQ29sdW1ucyBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0Um93VHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9nZXRSb3dUcyh0YWJsZU5hbWUsIHJvdywgdGltZXN0YW1wKTsKKyAgICAgIHJldHVybiByZWN2X2dldFJvd1RzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9nZXRSb3dUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXRSb3dUcyIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIGdldFJvd1RzX2FyZ3MgYXJncyA9IG5ldyBnZXRSb3dUc19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93ID0gcm93OworICAgICAgYXJncy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiByZWN2X2dldFJvd1RzKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldFJvd1RzX3Jlc3VsdCByZXN1bHQgPSBuZXcgZ2V0Um93VHNfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgImdldFJvd1RzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRSb3dXaXRoQ29sdW1uc1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2dldFJvd1dpdGhDb2x1bW5zVHModGFibGVOYW1lLCByb3csIGNvbHVtbnMsIHRpbWVzdGFtcCk7CisgICAgICByZXR1cm4gcmVjdl9nZXRSb3dXaXRoQ29sdW1uc1RzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9nZXRSb3dXaXRoQ29sdW1uc1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXRSb3dXaXRoQ29sdW1uc1RzIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzIGFyZ3MgPSBuZXcgZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93ID0gcm93OworICAgICAgYXJncy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gcmVjdl9nZXRSb3dXaXRoQ29sdW1uc1RzKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRSb3dXaXRoQ29sdW1uc1RzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJnZXRSb3dXaXRoQ29sdW1uc1RzIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtdXRhdGVSb3coYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9tdXRhdGVSb3codGFibGVOYW1lLCByb3csIG11dGF0aW9ucyk7CisgICAgICByZWN2X211dGF0ZVJvdygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfbXV0YXRlUm93KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucykgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJtdXRhdGVSb3ciLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBtdXRhdGVSb3dfYXJncyBhcmdzID0gbmV3IG11dGF0ZVJvd19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93ID0gcm93OworICAgICAgYXJncy5tdXRhdGlvbnMgPSBtdXRhdGlvbnM7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X211dGF0ZVJvdygpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIG11dGF0ZVJvd19yZXN1bHQgcmVzdWx0ID0gbmV3IG11dGF0ZVJvd19yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlhICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlhOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG11dGF0ZVJvd1RzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX211dGF0ZVJvd1RzKHRhYmxlTmFtZSwgcm93LCBtdXRhdGlvbnMsIHRpbWVzdGFtcCk7CisgICAgICByZWN2X211dGF0ZVJvd1RzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9tdXRhdGVSb3dUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoIm11dGF0ZVJvd1RzIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgbXV0YXRlUm93VHNfYXJncyBhcmdzID0gbmV3IG11dGF0ZVJvd1RzX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5yb3cgPSByb3c7CisgICAgICBhcmdzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjdl9tdXRhdGVSb3dUcygpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIG11dGF0ZVJvd1RzX3Jlc3VsdCByZXN1bHQgPSBuZXcgbXV0YXRlUm93VHNfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pYSAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pYTsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBtdXRhdGVSb3dzKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfbXV0YXRlUm93cyh0YWJsZU5hbWUsIHJvd0JhdGNoZXMpOworICAgICAgcmVjdl9tdXRhdGVSb3dzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9tdXRhdGVSb3dzKGJ5dGVbXSB0YWJsZU5hbWUsIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJtdXRhdGVSb3dzIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgbXV0YXRlUm93c19hcmdzIGFyZ3MgPSBuZXcgbXV0YXRlUm93c19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93QmF0Y2hlcyA9IHJvd0JhdGNoZXM7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X211dGF0ZVJvd3MoKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBtdXRhdGVSb3dzX3Jlc3VsdCByZXN1bHQgPSBuZXcgbXV0YXRlUm93c19yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlhICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlhOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG11dGF0ZVJvd3NUcyhieXRlW10gdGFibGVOYW1lLCBMaXN0PEJhdGNoTXV0YXRpb24+IHJvd0JhdGNoZXMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9tdXRhdGVSb3dzVHModGFibGVOYW1lLCByb3dCYXRjaGVzLCB0aW1lc3RhbXApOworICAgICAgcmVjdl9tdXRhdGVSb3dzVHMoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX211dGF0ZVJvd3NUcyhieXRlW10gdGFibGVOYW1lLCBMaXN0PEJhdGNoTXV0YXRpb24+IHJvd0JhdGNoZXMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoIm11dGF0ZVJvd3NUcyIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIG11dGF0ZVJvd3NUc19hcmdzIGFyZ3MgPSBuZXcgbXV0YXRlUm93c1RzX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5yb3dCYXRjaGVzID0gcm93QmF0Y2hlczsKKyAgICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjdl9tdXRhdGVSb3dzVHMoKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBtdXRhdGVSb3dzVHNfcmVzdWx0IHJlc3VsdCA9IG5ldyBtdXRhdGVSb3dzVHNfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pYSAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pYTsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBhdG9taWNJbmNyZW1lbnQoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwgbG9uZyB2YWx1ZSkgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfYXRvbWljSW5jcmVtZW50KHRhYmxlTmFtZSwgcm93LCBjb2x1bW4sIHZhbHVlKTsKKyAgICAgIHJldHVybiByZWN2X2F0b21pY0luY3JlbWVudCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfYXRvbWljSW5jcmVtZW50KGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSByb3csIGJ5dGVbXSBjb2x1bW4sIGxvbmcgdmFsdWUpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiYXRvbWljSW5jcmVtZW50IiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgYXRvbWljSW5jcmVtZW50X2FyZ3MgYXJncyA9IG5ldyBhdG9taWNJbmNyZW1lbnRfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MuY29sdW1uID0gY29sdW1uOworICAgICAgYXJncy52YWx1ZSA9IHZhbHVlOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgcmVjdl9hdG9taWNJbmNyZW1lbnQoKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBhdG9taWNJbmNyZW1lbnRfcmVzdWx0IHJlc3VsdCA9IG5ldyBhdG9taWNJbmNyZW1lbnRfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlhICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlhOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJhdG9taWNJbmNyZW1lbnQgZmFpbGVkOiB1bmtub3duIHJlc3VsdCIpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZGVsZXRlQWxsKHRhYmxlTmFtZSwgcm93LCBjb2x1bW4pOworICAgICAgcmVjdl9kZWxldGVBbGwoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX2RlbGV0ZUFsbChieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBieXRlW10gY29sdW1uKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImRlbGV0ZUFsbCIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIGRlbGV0ZUFsbF9hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlQWxsX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5yb3cgPSByb3c7CisgICAgICBhcmdzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlY3ZfZGVsZXRlQWxsKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGRlbGV0ZUFsbF9yZXN1bHQgcmVzdWx0ID0gbmV3IGRlbGV0ZUFsbF9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgZGVsZXRlQWxsVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9kZWxldGVBbGxUcyh0YWJsZU5hbWUsIHJvdywgY29sdW1uLCB0aW1lc3RhbXApOworICAgICAgcmVjdl9kZWxldGVBbGxUcygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfZGVsZXRlQWxsVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgYnl0ZVtdIGNvbHVtbiwgbG9uZyB0aW1lc3RhbXApIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGVsZXRlQWxsVHMiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBkZWxldGVBbGxUc19hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlQWxsVHNfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MuY29sdW1uID0gY29sdW1uOworICAgICAgYXJncy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWN2X2RlbGV0ZUFsbFRzKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIGRlbGV0ZUFsbFRzX3Jlc3VsdCByZXN1bHQgPSBuZXcgZGVsZXRlQWxsVHNfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbFJvdyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93KSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfZGVsZXRlQWxsUm93KHRhYmxlTmFtZSwgcm93KTsKKyAgICAgIHJlY3ZfZGVsZXRlQWxsUm93KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9kZWxldGVBbGxSb3coYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdykgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJkZWxldGVBbGxSb3ciLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBkZWxldGVBbGxSb3dfYXJncyBhcmdzID0gbmV3IGRlbGV0ZUFsbFJvd19hcmdzKCk7CisgICAgICBhcmdzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIGFyZ3Mucm93ID0gcm93OworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjdl9kZWxldGVBbGxSb3coKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgZGVsZXRlQWxsUm93X3Jlc3VsdCByZXN1bHQgPSBuZXcgZGVsZXRlQWxsUm93X3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVBbGxSb3dUcyhieXRlW10gdGFibGVOYW1lLCBieXRlW10gcm93LCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX2RlbGV0ZUFsbFJvd1RzKHRhYmxlTmFtZSwgcm93LCB0aW1lc3RhbXApOworICAgICAgcmVjdl9kZWxldGVBbGxSb3dUcygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNlbmRfZGVsZXRlQWxsUm93VHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHJvdywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGVsZXRlQWxsUm93VHMiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBkZWxldGVBbGxSb3dUc19hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlQWxsUm93VHNfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnJvdyA9IHJvdzsKKyAgICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjdl9kZWxldGVBbGxSb3dUcygpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBkZWxldGVBbGxSb3dUc19yZXN1bHQgcmVzdWx0ID0gbmV3IGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgTGlzdDxieXRlW10+IGNvbHVtbnMpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9zY2FubmVyT3Blbih0YWJsZU5hbWUsIHN0YXJ0Um93LCBjb2x1bW5zKTsKKyAgICAgIHJldHVybiByZWN2X3NjYW5uZXJPcGVuKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9zY2FubmVyT3BlbihieXRlW10gdGFibGVOYW1lLCBieXRlW10gc3RhcnRSb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJPcGVuIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgc2Nhbm5lck9wZW5fYXJncyBhcmdzID0gbmV3IHNjYW5uZXJPcGVuX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgICAgYXJncy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVjdl9zY2FubmVyT3BlbigpIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBzY2FubmVyT3Blbl9yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJPcGVuX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJzY2FubmVyT3BlbiBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisgICAgfQorCisgICAgcHVibGljIGludCBzY2FubmVyT3BlbldpdGhTdG9wKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgYnl0ZVtdIHN0b3BSb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIHNlbmRfc2Nhbm5lck9wZW5XaXRoU3RvcCh0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zKTsKKyAgICAgIHJldHVybiByZWN2X3NjYW5uZXJPcGVuV2l0aFN0b3AoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX3NjYW5uZXJPcGVuV2l0aFN0b3AoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LCBieXRlW10gc3RvcFJvdywgTGlzdDxieXRlW10+IGNvbHVtbnMpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lck9wZW5XaXRoU3RvcCIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncyBhcmdzID0gbmV3IHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncygpOworICAgICAgYXJncy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICBhcmdzLnN0YXJ0Um93ID0gc3RhcnRSb3c7CisgICAgICBhcmdzLnN0b3BSb3cgPSBzdG9wUm93OworICAgICAgYXJncy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVjdl9zY2FubmVyT3BlbldpdGhTdG9wKCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIHNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyT3BlbldpdGhTdG9wX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJzY2FubmVyT3BlbldpdGhTdG9wIGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IHNjYW5uZXJPcGVuVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LCBMaXN0PGJ5dGVbXT4gY29sdW1ucywgbG9uZyB0aW1lc3RhbXApIHRocm93cyBJT0Vycm9yLCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9zY2FubmVyT3BlblRzKHRhYmxlTmFtZSwgc3RhcnRSb3csIGNvbHVtbnMsIHRpbWVzdGFtcCk7CisgICAgICByZXR1cm4gcmVjdl9zY2FubmVyT3BlblRzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9zY2FubmVyT3BlblRzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgTGlzdDxieXRlW10+IGNvbHVtbnMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJPcGVuVHMiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBzY2FubmVyT3BlblRzX2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyT3BlblRzX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgICAgYXJncy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIGFyZ3MudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIGludCByZWN2X3NjYW5uZXJPcGVuVHMoKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgc2Nhbm5lck9wZW5Uc19yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJPcGVuVHNfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIHJldHVybiByZXN1bHQuc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChyZXN1bHQuaW8gIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaW87CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgInNjYW5uZXJPcGVuVHMgZmFpbGVkOiB1bmtub3duIHJlc3VsdCIpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgc2Nhbm5lck9wZW5XaXRoU3RvcFRzKGJ5dGVbXSB0YWJsZU5hbWUsIGJ5dGVbXSBzdGFydFJvdywgYnl0ZVtdIHN0b3BSb3csIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zLCBsb25nIHRpbWVzdGFtcCkgdGhyb3dzIElPRXJyb3IsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBzZW5kX3NjYW5uZXJPcGVuV2l0aFN0b3BUcyh0YWJsZU5hbWUsIHN0YXJ0Um93LCBzdG9wUm93LCBjb2x1bW5zLCB0aW1lc3RhbXApOworICAgICAgcmV0dXJuIHJlY3Zfc2Nhbm5lck9wZW5XaXRoU3RvcFRzKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9zY2FubmVyT3BlbldpdGhTdG9wVHMoYnl0ZVtdIHRhYmxlTmFtZSwgYnl0ZVtdIHN0YXJ0Um93LCBieXRlW10gc3RvcFJvdywgTGlzdDxieXRlW10+IGNvbHVtbnMsIGxvbmcgdGltZXN0YW1wKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJPcGVuV2l0aFN0b3BUcyIsIFRNZXNzYWdlVHlwZS5DQUxMLCBzZXFpZF8pKTsKKyAgICAgIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzIGFyZ3MgPSBuZXcgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3MoKTsKKyAgICAgIGFyZ3MudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgYXJncy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgICAgYXJncy5zdG9wUm93ID0gc3RvcFJvdzsKKyAgICAgIGFyZ3MuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgICBhcmdzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgcmVjdl9zY2FubmVyT3BlbldpdGhTdG9wVHMoKSB0aHJvd3MgSU9FcnJvciwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCByZXN1bHQgPSBuZXcgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbihUQXBwbGljYXRpb25FeGNlcHRpb24uTUlTU0lOR19SRVNVTFQsICJzY2FubmVyT3BlbldpdGhTdG9wVHMgZmFpbGVkOiB1bmtub3duIHJlc3VsdCIpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IHNjYW5uZXJHZXQoaW50IGlkKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9zY2FubmVyR2V0KGlkKTsKKyAgICAgIHJldHVybiByZWN2X3NjYW5uZXJHZXQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX3NjYW5uZXJHZXQoaW50IGlkKSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJHZXQiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBzY2FubmVyR2V0X2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyR2V0X2FyZ3MoKTsKKyAgICAgIGFyZ3MuaWQgPSBpZDsKKyAgICAgIGFyZ3Mud3JpdGUob3Byb3RfKTsKKyAgICAgIG9wcm90Xy53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgIG9wcm90Xy5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IHJlY3Zfc2Nhbm5lckdldCgpIHRocm93cyBJT0Vycm9yLCBJbGxlZ2FsQXJndW1lbnQsIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdF8ucmVhZE1lc3NhZ2VCZWdpbigpOworICAgICAgaWYgKG1zZy50eXBlID09IFRNZXNzYWdlVHlwZS5FWENFUFRJT04pIHsKKyAgICAgICAgVEFwcGxpY2F0aW9uRXhjZXB0aW9uIHggPSBUQXBwbGljYXRpb25FeGNlcHRpb24ucmVhZChpcHJvdF8pOworICAgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgdGhyb3cgeDsKKyAgICAgIH0KKyAgICAgIHNjYW5uZXJHZXRfcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyR2V0X3Jlc3VsdCgpOworICAgICAgcmVzdWx0LnJlYWQoaXByb3RfKTsKKyAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgaWYgKHJlc3VsdC5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pYSAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pYTsKKyAgICAgIH0KKyAgICAgIHRocm93IG5ldyBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLk1JU1NJTkdfUkVTVUxULCAic2Nhbm5lckdldCBmYWlsZWQ6IHVua25vd24gcmVzdWx0Iik7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gc2Nhbm5lckdldExpc3QoaW50IGlkLCBpbnQgbmJSb3dzKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9zY2FubmVyR2V0TGlzdChpZCwgbmJSb3dzKTsKKyAgICAgIHJldHVybiByZWN2X3NjYW5uZXJHZXRMaXN0KCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2VuZF9zY2FubmVyR2V0TGlzdChpbnQgaWQsIGludCBuYlJvd3MpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lckdldExpc3QiLCBUTWVzc2FnZVR5cGUuQ0FMTCwgc2VxaWRfKSk7CisgICAgICBzY2FubmVyR2V0TGlzdF9hcmdzIGFyZ3MgPSBuZXcgc2Nhbm5lckdldExpc3RfYXJncygpOworICAgICAgYXJncy5pZCA9IGlkOworICAgICAgYXJncy5uYlJvd3MgPSBuYlJvd3M7CisgICAgICBhcmdzLndyaXRlKG9wcm90Xyk7CisgICAgICBvcHJvdF8ud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICBvcHJvdF8uZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiByZWN2X3NjYW5uZXJHZXRMaXN0KCkgdGhyb3dzIElPRXJyb3IsIElsbGVnYWxBcmd1bWVudCwgVEV4Y2VwdGlvbgorICAgIHsKKyAgICAgIFRNZXNzYWdlIG1zZyA9IGlwcm90Xy5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBpZiAobXNnLnR5cGUgPT0gVE1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5yZWFkKGlwcm90Xyk7CisgICAgICAgIGlwcm90Xy5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICB0aHJvdyB4OworICAgICAgfQorICAgICAgc2Nhbm5lckdldExpc3RfcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyR2V0TGlzdF9yZXN1bHQoKTsKKyAgICAgIHJlc3VsdC5yZWFkKGlwcm90Xyk7CisgICAgICBpcHJvdF8ucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgIGlmIChyZXN1bHQuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdC5zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pbyAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pbzsKKyAgICAgIH0KKyAgICAgIGlmIChyZXN1bHQuaWEgIT0gbnVsbCkgeworICAgICAgICB0aHJvdyByZXN1bHQuaWE7CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgVEFwcGxpY2F0aW9uRXhjZXB0aW9uKFRBcHBsaWNhdGlvbkV4Y2VwdGlvbi5NSVNTSU5HX1JFU1VMVCwgInNjYW5uZXJHZXRMaXN0IGZhaWxlZDogdW5rbm93biByZXN1bHQiKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzY2FubmVyQ2xvc2UoaW50IGlkKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgc2VuZF9zY2FubmVyQ2xvc2UoaWQpOworICAgICAgcmVjdl9zY2FubmVyQ2xvc2UoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZW5kX3NjYW5uZXJDbG9zZShpbnQgaWQpIHRocm93cyBURXhjZXB0aW9uCisgICAgeworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lckNsb3NlIiwgVE1lc3NhZ2VUeXBlLkNBTEwsIHNlcWlkXykpOworICAgICAgc2Nhbm5lckNsb3NlX2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyQ2xvc2VfYXJncygpOworICAgICAgYXJncy5pZCA9IGlkOworICAgICAgYXJncy53cml0ZShvcHJvdF8pOworICAgICAgb3Byb3RfLndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgb3Byb3RfLmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVjdl9zY2FubmVyQ2xvc2UoKSB0aHJvd3MgSU9FcnJvciwgSWxsZWdhbEFyZ3VtZW50LCBURXhjZXB0aW9uCisgICAgeworICAgICAgVE1lc3NhZ2UgbXNnID0gaXByb3RfLnJlYWRNZXNzYWdlQmVnaW4oKTsKKyAgICAgIGlmIChtc2cudHlwZSA9PSBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OKSB7CisgICAgICAgIFRBcHBsaWNhdGlvbkV4Y2VwdGlvbiB4ID0gVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnJlYWQoaXByb3RfKTsKKyAgICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHRocm93IHg7CisgICAgICB9CisgICAgICBzY2FubmVyQ2xvc2VfcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyQ2xvc2VfcmVzdWx0KCk7CisgICAgICByZXN1bHQucmVhZChpcHJvdF8pOworICAgICAgaXByb3RfLnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICBpZiAocmVzdWx0LmlvICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgcmVzdWx0LmlvOworICAgICAgfQorICAgICAgaWYgKHJlc3VsdC5pYSAhPSBudWxsKSB7CisgICAgICAgIHRocm93IHJlc3VsdC5pYTsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgfQorICBwdWJsaWMgc3RhdGljIGNsYXNzIFByb2Nlc3NvciBpbXBsZW1lbnRzIFRQcm9jZXNzb3IgeworICAgIHB1YmxpYyBQcm9jZXNzb3IoSWZhY2UgaWZhY2UpCisgICAgeworICAgICAgaWZhY2VfID0gaWZhY2U7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImVuYWJsZVRhYmxlIiwgbmV3IGVuYWJsZVRhYmxlKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJkaXNhYmxlVGFibGUiLCBuZXcgZGlzYWJsZVRhYmxlKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJpc1RhYmxlRW5hYmxlZCIsIG5ldyBpc1RhYmxlRW5hYmxlZCgpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiY29tcGFjdCIsIG5ldyBjb21wYWN0KCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJtYWpvckNvbXBhY3QiLCBuZXcgbWFqb3JDb21wYWN0KCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJnZXRUYWJsZU5hbWVzIiwgbmV3IGdldFRhYmxlTmFtZXMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImdldENvbHVtbkRlc2NyaXB0b3JzIiwgbmV3IGdldENvbHVtbkRlc2NyaXB0b3JzKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJnZXRUYWJsZVJlZ2lvbnMiLCBuZXcgZ2V0VGFibGVSZWdpb25zKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJjcmVhdGVUYWJsZSIsIG5ldyBjcmVhdGVUYWJsZSgpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiZGVsZXRlVGFibGUiLCBuZXcgZGVsZXRlVGFibGUoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImdldCIsIG5ldyBnZXQoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImdldFZlciIsIG5ldyBnZXRWZXIoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImdldFZlclRzIiwgbmV3IGdldFZlclRzKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJnZXRSb3ciLCBuZXcgZ2V0Um93KCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJnZXRSb3dXaXRoQ29sdW1ucyIsIG5ldyBnZXRSb3dXaXRoQ29sdW1ucygpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiZ2V0Um93VHMiLCBuZXcgZ2V0Um93VHMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImdldFJvd1dpdGhDb2x1bW5zVHMiLCBuZXcgZ2V0Um93V2l0aENvbHVtbnNUcygpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgibXV0YXRlUm93IiwgbmV3IG11dGF0ZVJvdygpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgibXV0YXRlUm93VHMiLCBuZXcgbXV0YXRlUm93VHMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoIm11dGF0ZVJvd3MiLCBuZXcgbXV0YXRlUm93cygpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgibXV0YXRlUm93c1RzIiwgbmV3IG11dGF0ZVJvd3NUcygpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiYXRvbWljSW5jcmVtZW50IiwgbmV3IGF0b21pY0luY3JlbWVudCgpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiZGVsZXRlQWxsIiwgbmV3IGRlbGV0ZUFsbCgpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgiZGVsZXRlQWxsVHMiLCBuZXcgZGVsZXRlQWxsVHMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImRlbGV0ZUFsbFJvdyIsIG5ldyBkZWxldGVBbGxSb3coKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoImRlbGV0ZUFsbFJvd1RzIiwgbmV3IGRlbGV0ZUFsbFJvd1RzKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJzY2FubmVyT3BlbiIsIG5ldyBzY2FubmVyT3BlbigpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgic2Nhbm5lck9wZW5XaXRoU3RvcCIsIG5ldyBzY2FubmVyT3BlbldpdGhTdG9wKCkpOworICAgICAgcHJvY2Vzc01hcF8ucHV0KCJzY2FubmVyT3BlblRzIiwgbmV3IHNjYW5uZXJPcGVuVHMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoInNjYW5uZXJPcGVuV2l0aFN0b3BUcyIsIG5ldyBzY2FubmVyT3BlbldpdGhTdG9wVHMoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoInNjYW5uZXJHZXQiLCBuZXcgc2Nhbm5lckdldCgpKTsKKyAgICAgIHByb2Nlc3NNYXBfLnB1dCgic2Nhbm5lckdldExpc3QiLCBuZXcgc2Nhbm5lckdldExpc3QoKSk7CisgICAgICBwcm9jZXNzTWFwXy5wdXQoInNjYW5uZXJDbG9zZSIsIG5ldyBzY2FubmVyQ2xvc2UoKSk7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHN0YXRpYyBpbnRlcmZhY2UgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb247CisgICAgfQorCisgICAgcHJpdmF0ZSBJZmFjZSBpZmFjZV87CisgICAgcHJvdGVjdGVkIGZpbmFsIEhhc2hNYXA8U3RyaW5nLFByb2Nlc3NGdW5jdGlvbj4gcHJvY2Vzc01hcF8gPSBuZXcgSGFzaE1hcDxTdHJpbmcsUHJvY2Vzc0Z1bmN0aW9uPigpOworCisgICAgcHVibGljIGJvb2xlYW4gcHJvY2VzcyhUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICB7CisgICAgICBUTWVzc2FnZSBtc2cgPSBpcHJvdC5yZWFkTWVzc2FnZUJlZ2luKCk7CisgICAgICBQcm9jZXNzRnVuY3Rpb24gZm4gPSBwcm9jZXNzTWFwXy5nZXQobXNnLm5hbWUpOworICAgICAgaWYgKGZuID09IG51bGwpIHsKKyAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBUVHlwZS5TVFJVQ1QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBUQXBwbGljYXRpb25FeGNlcHRpb24geCA9IG5ldyBUQXBwbGljYXRpb25FeGNlcHRpb24oVEFwcGxpY2F0aW9uRXhjZXB0aW9uLlVOS05PV05fTUVUSE9ELCAiSW52YWxpZCBtZXRob2QgbmFtZTogJyIrbXNnLm5hbWUrIiciKTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKG1zZy5uYW1lLCBUTWVzc2FnZVR5cGUuRVhDRVBUSU9OLCBtc2cuc2VxaWQpKTsKKyAgICAgICAgeC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGZuLnByb2Nlc3MobXNnLnNlcWlkLCBpcHJvdCwgb3Byb3QpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBlbmFibGVUYWJsZSBpbXBsZW1lbnRzIFByb2Nlc3NGdW5jdGlvbiB7CisgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKGludCBzZXFpZCwgVFByb3RvY29sIGlwcm90LCBUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uCisgICAgICB7CisgICAgICAgIGVuYWJsZVRhYmxlX2FyZ3MgYXJncyA9IG5ldyBlbmFibGVUYWJsZV9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGVuYWJsZVRhYmxlX3Jlc3VsdCByZXN1bHQgPSBuZXcgZW5hYmxlVGFibGVfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWZhY2VfLmVuYWJsZVRhYmxlKGFyZ3MudGFibGVOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZW5hYmxlVGFibGUiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBkaXNhYmxlVGFibGUgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBkaXNhYmxlVGFibGVfYXJncyBhcmdzID0gbmV3IGRpc2FibGVUYWJsZV9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGRpc2FibGVUYWJsZV9yZXN1bHQgcmVzdWx0ID0gbmV3IGRpc2FibGVUYWJsZV9yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBpZmFjZV8uZGlzYWJsZVRhYmxlKGFyZ3MudGFibGVOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGlzYWJsZVRhYmxlIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgaXNUYWJsZUVuYWJsZWQgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBpc1RhYmxlRW5hYmxlZF9hcmdzIGFyZ3MgPSBuZXcgaXNUYWJsZUVuYWJsZWRfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBpc1RhYmxlRW5hYmxlZF9yZXN1bHQgcmVzdWx0ID0gbmV3IGlzVGFibGVFbmFibGVkX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIHJlc3VsdC5zdWNjZXNzID0gaWZhY2VfLmlzVGFibGVFbmFibGVkKGFyZ3MudGFibGVOYW1lKTsKKyAgICAgICAgICByZXN1bHQuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiaXNUYWJsZUVuYWJsZWQiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBjb21wYWN0IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgY29tcGFjdF9hcmdzIGFyZ3MgPSBuZXcgY29tcGFjdF9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGNvbXBhY3RfcmVzdWx0IHJlc3VsdCA9IG5ldyBjb21wYWN0X3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5jb21wYWN0KGFyZ3MudGFibGVOYW1lT3JSZWdpb25OYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiY29tcGFjdCIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIG1ham9yQ29tcGFjdCBpbXBsZW1lbnRzIFByb2Nlc3NGdW5jdGlvbiB7CisgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKGludCBzZXFpZCwgVFByb3RvY29sIGlwcm90LCBUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uCisgICAgICB7CisgICAgICAgIG1ham9yQ29tcGFjdF9hcmdzIGFyZ3MgPSBuZXcgbWFqb3JDb21wYWN0X2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgbWFqb3JDb21wYWN0X3Jlc3VsdCByZXN1bHQgPSBuZXcgbWFqb3JDb21wYWN0X3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5tYWpvckNvbXBhY3QoYXJncy50YWJsZU5hbWVPclJlZ2lvbk5hbWUpOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJtYWpvckNvbXBhY3QiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBnZXRUYWJsZU5hbWVzIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0VGFibGVOYW1lc19hcmdzIGFyZ3MgPSBuZXcgZ2V0VGFibGVOYW1lc19hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGdldFRhYmxlTmFtZXNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRUYWJsZU5hbWVzX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIHJlc3VsdC5zdWNjZXNzID0gaWZhY2VfLmdldFRhYmxlTmFtZXMoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZ2V0VGFibGVOYW1lcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIGdldENvbHVtbkRlc2NyaXB0b3JzIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncyBhcmdzID0gbmV3IGdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5nZXRDb2x1bW5EZXNjcmlwdG9ycyhhcmdzLnRhYmxlTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldENvbHVtbkRlc2NyaXB0b3JzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZ2V0VGFibGVSZWdpb25zIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0VGFibGVSZWdpb25zX2FyZ3MgYXJncyA9IG5ldyBnZXRUYWJsZVJlZ2lvbnNfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBnZXRUYWJsZVJlZ2lvbnNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRUYWJsZVJlZ2lvbnNfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uZ2V0VGFibGVSZWdpb25zKGFyZ3MudGFibGVOYW1lKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZ2V0VGFibGVSZWdpb25zIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgY3JlYXRlVGFibGUgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBjcmVhdGVUYWJsZV9hcmdzIGFyZ3MgPSBuZXcgY3JlYXRlVGFibGVfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBjcmVhdGVUYWJsZV9yZXN1bHQgcmVzdWx0ID0gbmV3IGNyZWF0ZVRhYmxlX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5jcmVhdGVUYWJsZShhcmdzLnRhYmxlTmFtZSwgYXJncy5jb2x1bW5GYW1pbGllcyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICAgICAgcmVzdWx0LmlhID0gaWE7CisgICAgICAgIH0gY2F0Y2ggKEFscmVhZHlFeGlzdHMgZXhpc3QpIHsKKyAgICAgICAgICByZXN1bHQuZXhpc3QgPSBleGlzdDsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImNyZWF0ZVRhYmxlIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZGVsZXRlVGFibGUgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBkZWxldGVUYWJsZV9hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlVGFibGVfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBkZWxldGVUYWJsZV9yZXN1bHQgcmVzdWx0ID0gbmV3IGRlbGV0ZVRhYmxlX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5kZWxldGVUYWJsZShhcmdzLnRhYmxlTmFtZSk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImRlbGV0ZVRhYmxlIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZ2V0IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0X2FyZ3MgYXJncyA9IG5ldyBnZXRfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBnZXRfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uZ2V0KGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdywgYXJncy5jb2x1bW4pOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXQiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBnZXRWZXIgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBnZXRWZXJfYXJncyBhcmdzID0gbmV3IGdldFZlcl9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGdldFZlcl9yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFZlcl9yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5nZXRWZXIoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLmNvbHVtbiwgYXJncy5udW1WZXJzaW9ucyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFZlciIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIGdldFZlclRzIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0VmVyVHNfYXJncyBhcmdzID0gbmV3IGdldFZlclRzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgZ2V0VmVyVHNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRWZXJUc19yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5nZXRWZXJUcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1uLCBhcmdzLnRpbWVzdGFtcCwgYXJncy5udW1WZXJzaW9ucyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFZlclRzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZ2V0Um93IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0Um93X2FyZ3MgYXJncyA9IG5ldyBnZXRSb3dfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBnZXRSb3dfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRSb3dfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uZ2V0Um93KGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFJvdyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIGdldFJvd1dpdGhDb2x1bW5zIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZ2V0Um93V2l0aENvbHVtbnNfYXJncyBhcmdzID0gbmV3IGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgZ2V0Um93V2l0aENvbHVtbnNfcmVzdWx0IHJlc3VsdCA9IG5ldyBnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5nZXRSb3dXaXRoQ29sdW1ucyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1ucyk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImdldFJvd1dpdGhDb2x1bW5zIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZ2V0Um93VHMgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBnZXRSb3dUc19hcmdzIGFyZ3MgPSBuZXcgZ2V0Um93VHNfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBnZXRSb3dUc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFJvd1RzX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIHJlc3VsdC5zdWNjZXNzID0gaWZhY2VfLmdldFJvd1RzKGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdywgYXJncy50aW1lc3RhbXApOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXRSb3dUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIGdldFJvd1dpdGhDb2x1bW5zVHMgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MgYXJncyA9IG5ldyBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgZ2V0Um93V2l0aENvbHVtbnNUc19yZXN1bHQgcmVzdWx0ID0gbmV3IGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uZ2V0Um93V2l0aENvbHVtbnNUcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1ucywgYXJncy50aW1lc3RhbXApOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJnZXRSb3dXaXRoQ29sdW1uc1RzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgbXV0YXRlUm93IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgbXV0YXRlUm93X2FyZ3MgYXJncyA9IG5ldyBtdXRhdGVSb3dfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBtdXRhdGVSb3dfcmVzdWx0IHJlc3VsdCA9IG5ldyBtdXRhdGVSb3dfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWZhY2VfLm11dGF0ZVJvdyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MubXV0YXRpb25zKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnQgaWEpIHsKKyAgICAgICAgICByZXN1bHQuaWEgPSBpYTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoIm11dGF0ZVJvdyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIG11dGF0ZVJvd1RzIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgbXV0YXRlUm93VHNfYXJncyBhcmdzID0gbmV3IG11dGF0ZVJvd1RzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgbXV0YXRlUm93VHNfcmVzdWx0IHJlc3VsdCA9IG5ldyBtdXRhdGVSb3dUc19yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBpZmFjZV8ubXV0YXRlUm93VHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93LCBhcmdzLm11dGF0aW9ucywgYXJncy50aW1lc3RhbXApOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgibXV0YXRlUm93VHMiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBtdXRhdGVSb3dzIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgbXV0YXRlUm93c19hcmdzIGFyZ3MgPSBuZXcgbXV0YXRlUm93c19hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIG11dGF0ZVJvd3NfcmVzdWx0IHJlc3VsdCA9IG5ldyBtdXRhdGVSb3dzX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5tdXRhdGVSb3dzKGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvd0JhdGNoZXMpOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgibXV0YXRlUm93cyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIG11dGF0ZVJvd3NUcyBpbXBsZW1lbnRzIFByb2Nlc3NGdW5jdGlvbiB7CisgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKGludCBzZXFpZCwgVFByb3RvY29sIGlwcm90LCBUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uCisgICAgICB7CisgICAgICAgIG11dGF0ZVJvd3NUc19hcmdzIGFyZ3MgPSBuZXcgbXV0YXRlUm93c1RzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgbXV0YXRlUm93c1RzX3Jlc3VsdCByZXN1bHQgPSBuZXcgbXV0YXRlUm93c1RzX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5tdXRhdGVSb3dzVHMoYXJncy50YWJsZU5hbWUsIGFyZ3Mucm93QmF0Y2hlcywgYXJncy50aW1lc3RhbXApOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgibXV0YXRlUm93c1RzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgYXRvbWljSW5jcmVtZW50IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgYXRvbWljSW5jcmVtZW50X2FyZ3MgYXJncyA9IG5ldyBhdG9taWNJbmNyZW1lbnRfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBhdG9taWNJbmNyZW1lbnRfcmVzdWx0IHJlc3VsdCA9IG5ldyBhdG9taWNJbmNyZW1lbnRfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uYXRvbWljSW5jcmVtZW50KGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdywgYXJncy5jb2x1bW4sIGFyZ3MudmFsdWUpOworICAgICAgICAgIHJlc3VsdC5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiYXRvbWljSW5jcmVtZW50IiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZGVsZXRlQWxsIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZGVsZXRlQWxsX2FyZ3MgYXJncyA9IG5ldyBkZWxldGVBbGxfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBkZWxldGVBbGxfcmVzdWx0IHJlc3VsdCA9IG5ldyBkZWxldGVBbGxfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWZhY2VfLmRlbGV0ZUFsbChhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1uKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgiZGVsZXRlQWxsIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZGVsZXRlQWxsVHMgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBkZWxldGVBbGxUc19hcmdzIGFyZ3MgPSBuZXcgZGVsZXRlQWxsVHNfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBkZWxldGVBbGxUc19yZXN1bHQgcmVzdWx0ID0gbmV3IGRlbGV0ZUFsbFRzX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGlmYWNlXy5kZWxldGVBbGxUcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3csIGFyZ3MuY29sdW1uLCBhcmdzLnRpbWVzdGFtcCk7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoImRlbGV0ZUFsbFRzIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgZGVsZXRlQWxsUm93IGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgZGVsZXRlQWxsUm93X2FyZ3MgYXJncyA9IG5ldyBkZWxldGVBbGxSb3dfYXJncygpOworICAgICAgICBhcmdzLnJlYWQoaXByb3QpOworICAgICAgICBpcHJvdC5yZWFkTWVzc2FnZUVuZCgpOworICAgICAgICBkZWxldGVBbGxSb3dfcmVzdWx0IHJlc3VsdCA9IG5ldyBkZWxldGVBbGxSb3dfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWZhY2VfLmRlbGV0ZUFsbFJvdyhhcmdzLnRhYmxlTmFtZSwgYXJncy5yb3cpOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJkZWxldGVBbGxSb3ciLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBkZWxldGVBbGxSb3dUcyBpbXBsZW1lbnRzIFByb2Nlc3NGdW5jdGlvbiB7CisgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKGludCBzZXFpZCwgVFByb3RvY29sIGlwcm90LCBUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uCisgICAgICB7CisgICAgICAgIGRlbGV0ZUFsbFJvd1RzX2FyZ3MgYXJncyA9IG5ldyBkZWxldGVBbGxSb3dUc19hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdCByZXN1bHQgPSBuZXcgZGVsZXRlQWxsUm93VHNfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWZhY2VfLmRlbGV0ZUFsbFJvd1RzKGFyZ3MudGFibGVOYW1lLCBhcmdzLnJvdywgYXJncy50aW1lc3RhbXApOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlQmVnaW4obmV3IFRNZXNzYWdlKCJkZWxldGVBbGxSb3dUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIHNjYW5uZXJPcGVuIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgc2Nhbm5lck9wZW5fYXJncyBhcmdzID0gbmV3IHNjYW5uZXJPcGVuX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgc2Nhbm5lck9wZW5fcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyT3Blbl9yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5zY2FubmVyT3BlbihhcmdzLnRhYmxlTmFtZSwgYXJncy5zdGFydFJvdywgYXJncy5jb2x1bW5zKTsKKyAgICAgICAgICByZXN1bHQuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lck9wZW4iLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBzY2FubmVyT3BlbldpdGhTdG9wIGltcGxlbWVudHMgUHJvY2Vzc0Z1bmN0aW9uIHsKKyAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoaW50IHNlcWlkLCBUUHJvdG9jb2wgaXByb3QsIFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24KKyAgICAgIHsKKyAgICAgICAgc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzIGFyZ3MgPSBuZXcgc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0IHJlc3VsdCA9IG5ldyBzY2FubmVyT3BlbldpdGhTdG9wX3Jlc3VsdCgpOworICAgICAgICB0cnkgeworICAgICAgICAgIHJlc3VsdC5zdWNjZXNzID0gaWZhY2VfLnNjYW5uZXJPcGVuV2l0aFN0b3AoYXJncy50YWJsZU5hbWUsIGFyZ3Muc3RhcnRSb3csIGFyZ3Muc3RvcFJvdywgYXJncy5jb2x1bW5zKTsKKyAgICAgICAgICByZXN1bHQuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lck9wZW5XaXRoU3RvcCIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIHNjYW5uZXJPcGVuVHMgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBzY2FubmVyT3BlblRzX2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyT3BlblRzX2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgc2Nhbm5lck9wZW5Uc19yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJPcGVuVHNfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uc2Nhbm5lck9wZW5UcyhhcmdzLnRhYmxlTmFtZSwgYXJncy5zdGFydFJvdywgYXJncy5jb2x1bW5zLCBhcmdzLnRpbWVzdGFtcCk7CisgICAgICAgICAgcmVzdWx0Ll9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJPcGVuVHMiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBzY2FubmVyT3BlbldpdGhTdG9wVHMgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncyBhcmdzID0gbmV3IHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZXN1bHQuc3VjY2VzcyA9IGlmYWNlXy5zY2FubmVyT3BlbldpdGhTdG9wVHMoYXJncy50YWJsZU5hbWUsIGFyZ3Muc3RhcnRSb3csIGFyZ3Muc3RvcFJvdywgYXJncy5jb2x1bW5zLCBhcmdzLnRpbWVzdGFtcCk7CisgICAgICAgICAgcmVzdWx0Ll9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICAgIH0gY2F0Y2ggKElPRXJyb3IgaW8pIHsKKyAgICAgICAgICByZXN1bHQuaW8gPSBpbzsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJPcGVuV2l0aFN0b3BUcyIsIFRNZXNzYWdlVHlwZS5SRVBMWSwgc2VxaWQpKTsKKyAgICAgICAgcmVzdWx0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVNZXNzYWdlRW5kKCk7CisgICAgICAgIG9wcm90LmdldFRyYW5zcG9ydCgpLmZsdXNoKCk7CisgICAgICB9CisKKyAgICB9CisKKyAgICBwcml2YXRlIGNsYXNzIHNjYW5uZXJHZXQgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBzY2FubmVyR2V0X2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyR2V0X2FyZ3MoKTsKKyAgICAgICAgYXJncy5yZWFkKGlwcm90KTsKKyAgICAgICAgaXByb3QucmVhZE1lc3NhZ2VFbmQoKTsKKyAgICAgICAgc2Nhbm5lckdldF9yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJHZXRfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uc2Nhbm5lckdldChhcmdzLmlkKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FcnJvciBpbykgeworICAgICAgICAgIHJlc3VsdC5pbyA9IGlvOworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnQgaWEpIHsKKyAgICAgICAgICByZXN1bHQuaWEgPSBpYTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VCZWdpbihuZXcgVE1lc3NhZ2UoInNjYW5uZXJHZXQiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBzY2FubmVyR2V0TGlzdCBpbXBsZW1lbnRzIFByb2Nlc3NGdW5jdGlvbiB7CisgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKGludCBzZXFpZCwgVFByb3RvY29sIGlwcm90LCBUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uCisgICAgICB7CisgICAgICAgIHNjYW5uZXJHZXRMaXN0X2FyZ3MgYXJncyA9IG5ldyBzY2FubmVyR2V0TGlzdF9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHNjYW5uZXJHZXRMaXN0X3Jlc3VsdCByZXN1bHQgPSBuZXcgc2Nhbm5lckdldExpc3RfcmVzdWx0KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSBpZmFjZV8uc2Nhbm5lckdldExpc3QoYXJncy5pZCwgYXJncy5uYlJvd3MpOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lckdldExpc3QiLCBUTWVzc2FnZVR5cGUuUkVQTFksIHNlcWlkKSk7CisgICAgICAgIHJlc3VsdC53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUVuZCgpOworICAgICAgICBvcHJvdC5nZXRUcmFuc3BvcnQoKS5mbHVzaCgpOworICAgICAgfQorCisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBzY2FubmVyQ2xvc2UgaW1wbGVtZW50cyBQcm9jZXNzRnVuY3Rpb24geworICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhpbnQgc2VxaWQsIFRQcm90b2NvbCBpcHJvdCwgVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbgorICAgICAgeworICAgICAgICBzY2FubmVyQ2xvc2VfYXJncyBhcmdzID0gbmV3IHNjYW5uZXJDbG9zZV9hcmdzKCk7CisgICAgICAgIGFyZ3MucmVhZChpcHJvdCk7CisgICAgICAgIGlwcm90LnJlYWRNZXNzYWdlRW5kKCk7CisgICAgICAgIHNjYW5uZXJDbG9zZV9yZXN1bHQgcmVzdWx0ID0gbmV3IHNjYW5uZXJDbG9zZV9yZXN1bHQoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBpZmFjZV8uc2Nhbm5lckNsb3NlKGFyZ3MuaWQpOworICAgICAgICB9IGNhdGNoIChJT0Vycm9yIGlvKSB7CisgICAgICAgICAgcmVzdWx0LmlvID0gaW87CisgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgICAgIHJlc3VsdC5pYSA9IGlhOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlTWVzc2FnZUJlZ2luKG5ldyBUTWVzc2FnZSgic2Nhbm5lckNsb3NlIiwgVE1lc3NhZ2VUeXBlLlJFUExZLCBzZXFpZCkpOworICAgICAgICByZXN1bHQud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZU1lc3NhZ2VFbmQoKTsKKyAgICAgICAgb3Byb3QuZ2V0VHJhbnNwb3J0KCkuZmx1c2goKTsKKyAgICAgIH0KKworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBlbmFibGVUYWJsZV9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJlbmFibGVUYWJsZV9hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZW5hYmxlVGFibGVfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBlbmFibGVUYWJsZV9hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBlbmFibGVUYWJsZV9hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGVuYWJsZVRhYmxlX2FyZ3MoZW5hYmxlVGFibGVfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGVuYWJsZVRhYmxlX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGVuYWJsZVRhYmxlX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZW5hYmxlVGFibGVfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChlbmFibGVUYWJsZV9hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhlbmFibGVUYWJsZV9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImVuYWJsZVRhYmxlX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBlbmFibGVUYWJsZV9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImVuYWJsZVRhYmxlX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGVuYWJsZVRhYmxlX3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBlbmFibGVUYWJsZV9yZXN1bHQoKSB7CisgICAgfQorCisgICAgcHVibGljIGVuYWJsZVRhYmxlX3Jlc3VsdCgKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZW5hYmxlVGFibGVfcmVzdWx0KGVuYWJsZVRhYmxlX3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBlbmFibGVUYWJsZV9yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGVuYWJsZVRhYmxlX3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZW5hYmxlVGFibGVfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGVuYWJsZVRhYmxlX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZW5hYmxlVGFibGVfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJlbmFibGVUYWJsZV9yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBkaXNhYmxlVGFibGVfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZGlzYWJsZVRhYmxlX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkaXNhYmxlVGFibGVfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBkaXNhYmxlVGFibGVfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZGlzYWJsZVRhYmxlX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZGlzYWJsZVRhYmxlX2FyZ3MoZGlzYWJsZVRhYmxlX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkaXNhYmxlVGFibGVfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZGlzYWJsZVRhYmxlX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZGlzYWJsZVRhYmxlX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZGlzYWJsZVRhYmxlX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRpc2FibGVUYWJsZV9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImRpc2FibGVUYWJsZV9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGlzYWJsZVRhYmxlX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZGlzYWJsZVRhYmxlX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGRpc2FibGVUYWJsZV9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGlzYWJsZVRhYmxlX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZGlzYWJsZVRhYmxlX3Jlc3VsdCgKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZGlzYWJsZVRhYmxlX3Jlc3VsdChkaXNhYmxlVGFibGVfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRpc2FibGVUYWJsZV9yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGRpc2FibGVUYWJsZV9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRpc2FibGVUYWJsZV9yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZGlzYWJsZVRhYmxlX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZGlzYWJsZVRhYmxlX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZGlzYWJsZVRhYmxlX3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGlzVGFibGVFbmFibGVkX2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImlzVGFibGVFbmFibGVkX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChpc1RhYmxlRW5hYmxlZF9hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGlzVGFibGVFbmFibGVkX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGlzVGFibGVFbmFibGVkX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaXNUYWJsZUVuYWJsZWRfYXJncyhpc1RhYmxlRW5hYmxlZF9hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaXNUYWJsZUVuYWJsZWRfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgaXNUYWJsZUVuYWJsZWRfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBpc1RhYmxlRW5hYmxlZF9hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGlzVGFibGVFbmFibGVkX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGlzVGFibGVFbmFibGVkX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiaXNUYWJsZUVuYWJsZWRfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGlzVGFibGVFbmFibGVkX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiaXNUYWJsZUVuYWJsZWRfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNVQ0NFU1NfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN1Y2Nlc3MiLCBUVHlwZS5CT09MLCAoc2hvcnQpMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIGJvb2xlYW4gc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5CT09MKSkpOworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoaXNUYWJsZUVuYWJsZWRfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGlzVGFibGVFbmFibGVkX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgaXNUYWJsZUVuYWJsZWRfcmVzdWx0KAorICAgICAgYm9vbGVhbiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgaXNUYWJsZUVuYWJsZWRfcmVzdWx0KGlzVGFibGVFbmFibGVkX3Jlc3VsdCBvdGhlcikgeworICAgICAgX19pc3NldC5zdWNjZXNzID0gb3RoZXIuX19pc3NldC5zdWNjZXNzOworICAgICAgdGhpcy5zdWNjZXNzID0gb3RoZXIuc3VjY2VzczsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaXNUYWJsZUVuYWJsZWRfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBpc1RhYmxlRW5hYmxlZF9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKGJvb2xlYW4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChCb29sZWFuKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gbmV3IEJvb2xlYW4oaXNTdWNjZXNzKCkpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3VjY2VzcygpOworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBpc1RhYmxlRW5hYmxlZF9yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoaXNUYWJsZUVuYWJsZWRfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhpc1RhYmxlRW5hYmxlZF9yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgIT0gdGhhdC5zdWNjZXNzKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkJPT0wpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gaXByb3QucmVhZEJvb2woKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1VDQ0VTU19GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCb29sKHRoaXMuc3VjY2Vzcyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiaXNUYWJsZUVuYWJsZWRfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgY29tcGFjdF9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJjb21wYWN0X2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9PUl9SRUdJT05fTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lT3JSZWdpb25OYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUVPUlJFR0lPTk5BTUUgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRU9SUkVHSU9OTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZU9yUmVnaW9uTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChjb21wYWN0X2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY29tcGFjdF9hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBjb21wYWN0X2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lT3JSZWdpb25OYW1lKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lID0gdGFibGVOYW1lT3JSZWdpb25OYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgY29tcGFjdF9hcmdzKGNvbXBhY3RfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSBvdGhlci50YWJsZU5hbWVPclJlZ2lvbk5hbWU7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNvbXBhY3RfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgY29tcGFjdF9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZU9yUmVnaW9uTmFtZShieXRlW10gdGFibGVOYW1lT3JSZWdpb25OYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IHRhYmxlTmFtZU9yUmVnaW9uTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lT3JSZWdpb25OYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUVPUlJFR0lPTk5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRU9SUkVHSU9OTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUVPUlJFR0lPTk5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGNvbXBhY3RfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChjb21wYWN0X2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGNvbXBhY3RfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lT3JSZWdpb25OYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZU9yUmVnaW9uTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lT3JSZWdpb25OYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWVPclJlZ2lvbk5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZU9yUmVnaW9uTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lLCB0aGF0LnRhYmxlTmFtZU9yUmVnaW9uTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUVPUlJFR0lPTk5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9PUl9SRUdJT05fTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJjb21wYWN0X2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWVPclJlZ2lvbk5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBjb21wYWN0X3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiY29tcGFjdF9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChjb21wYWN0X3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBjb21wYWN0X3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgY29tcGFjdF9yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGNvbXBhY3RfcmVzdWx0KGNvbXBhY3RfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNvbXBhY3RfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBjb21wYWN0X3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgY29tcGFjdF9yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoY29tcGFjdF9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGNvbXBhY3RfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJjb21wYWN0X3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIG1ham9yQ29tcGFjdF9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJtYWpvckNvbXBhY3RfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX09SX1JFR0lPTl9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWVPclJlZ2lvbk5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lT3JSZWdpb25OYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRU9SUkVHSU9OTkFNRSA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FT1JSRUdJT05OQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lT3JSZWdpb25OYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKG1ham9yQ29tcGFjdF9hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG1ham9yQ29tcGFjdF9hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBtYWpvckNvbXBhY3RfYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWVPclJlZ2lvbk5hbWUpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSB0YWJsZU5hbWVPclJlZ2lvbk5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtYWpvckNvbXBhY3RfYXJncyhtYWpvckNvbXBhY3RfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSBvdGhlci50YWJsZU5hbWVPclJlZ2lvbk5hbWU7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIG1ham9yQ29tcGFjdF9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBtYWpvckNvbXBhY3RfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoYnl0ZVtdIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSB0YWJsZU5hbWVPclJlZ2lvbk5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZU9yUmVnaW9uTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lT3JSZWdpb25OYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FT1JSRUdJT05OQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lT3JSZWdpb25OYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUVPUlJFR0lPTk5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FT1JSRUdJT05OQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtYWpvckNvbXBhY3RfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChtYWpvckNvbXBhY3RfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMobWFqb3JDb21wYWN0X2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWVPclJlZ2lvbk5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWVPclJlZ2lvbk5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZU9yUmVnaW9uTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZU9yUmVnaW9uTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWVPclJlZ2lvbk5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZU9yUmVnaW9uTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lT3JSZWdpb25OYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWVPclJlZ2lvbk5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSwgdGhhdC50YWJsZU5hbWVPclJlZ2lvbk5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FT1JSRUdJT05OQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfT1JfUkVHSU9OX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lT3JSZWdpb25OYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigibWFqb3JDb21wYWN0X2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWVPclJlZ2lvbk5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWVPclJlZ2lvbk5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZU9yUmVnaW9uTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBtYWpvckNvbXBhY3RfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJtYWpvckNvbXBhY3RfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobWFqb3JDb21wYWN0X3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBtYWpvckNvbXBhY3RfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBtYWpvckNvbXBhY3RfcmVzdWx0KAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtYWpvckNvbXBhY3RfcmVzdWx0KG1ham9yQ29tcGFjdF9yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbWFqb3JDb21wYWN0X3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgbWFqb3JDb21wYWN0X3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgbWFqb3JDb21wYWN0X3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChtYWpvckNvbXBhY3RfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhtYWpvckNvbXBhY3RfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJtYWpvckNvbXBhY3RfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0VGFibGVOYW1lc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRUYWJsZU5hbWVzX2FyZ3MiKTsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChnZXRUYWJsZU5hbWVzX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0VGFibGVOYW1lc19hcmdzKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0VGFibGVOYW1lc19hcmdzKGdldFRhYmxlTmFtZXNfYXJncyBvdGhlcikgeworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRUYWJsZU5hbWVzX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFRhYmxlTmFtZXNfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0VGFibGVOYW1lc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFRhYmxlTmFtZXNfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0VGFibGVOYW1lc19hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRUYWJsZU5hbWVzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRUYWJsZU5hbWVzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0VGFibGVOYW1lc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgTGlzdDxieXRlW10+IHN1Y2Nlc3M7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VDQ0VTUyA9IDA7CisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFNVQ0NFU1MsIG5ldyBGaWVsZE1ldGFEYXRhKCJzdWNjZXNzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBMaXN0TWV0YURhdGEoVFR5cGUuTElTVCwgCisgICAgICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGdldFRhYmxlTmFtZXNfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGdldFRhYmxlTmFtZXNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRUYWJsZU5hbWVzX3Jlc3VsdCgKKyAgICAgIExpc3Q8Ynl0ZVtdPiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0VGFibGVOYW1lc19yZXN1bHQoZ2V0VGFibGVOYW1lc19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBMaXN0PGJ5dGVbXT4gX190aGlzX19zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICAgIGZvciAoYnl0ZVtdIG90aGVyX2VsZW1lbnQgOiBvdGhlci5zdWNjZXNzKSB7CisgICAgICAgICAgX190aGlzX19zdWNjZXNzLmFkZChvdGhlcl9lbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBfX3RoaXNfX3N1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldFRhYmxlTmFtZXNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRUYWJsZU5hbWVzX3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN1Y2Nlc3NTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyAwIDogdGhpcy5zdWNjZXNzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0U3VjY2Vzc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5zdWNjZXNzLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9TdWNjZXNzKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhMaXN0PGJ5dGVbXT4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExpc3Q8Ynl0ZVtdPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGdldFN1Y2Nlc3MoKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0VGFibGVOYW1lc19yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0VGFibGVOYW1lc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldFRhYmxlTmFtZXNfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhpcy5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoYXQuaXNTZXRTdWNjZXNzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N1Y2Nlc3MgfHwgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N1Y2Nlc3MgJiYgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnN1Y2Nlc3MuZXF1YWxzKHRoYXQuc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q5ID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPihfbGlzdDkuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2kxMCA9IDA7IF9pMTAgPCBfbGlzdDkuc2l6ZTsgKytfaTEwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGJ5dGVbXSBfZWxlbTExOworICAgICAgICAgICAgICAgICAgX2VsZW0xMSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuc3VjY2Vzcy5hZGQoX2VsZW0xMSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNVQ0NFU1NfRklFTERfREVTQyk7CisgICAgICAgIHsKKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihuZXcgVExpc3QoVFR5cGUuU1RSSU5HLCB0aGlzLnN1Y2Nlc3Muc2l6ZSgpKSk7CisgICAgICAgICAgZm9yIChieXRlW10gX2l0ZXIxMiA6IHRoaXMuc3VjY2VzcykgICAgICAgICAgeworICAgICAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkoX2l0ZXIxMik7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0VGFibGVOYW1lc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3MoZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRDb2x1bW5EZXNjcmlwdG9yc19hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldENvbHVtbkRlc2NyaXB0b3JzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuTUFQLCAoc2hvcnQpMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4gc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IE1hcE1ldGFEYXRhKFRUeXBlLk1BUCwgCisgICAgICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSwgCisgICAgICAgICAgICAgIG5ldyBTdHJ1Y3RNZXRhRGF0YShUVHlwZS5TVFJVQ1QsIENvbHVtbkRlc2NyaXB0b3IuY2xhc3MpKSkpOworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Q29sdW1uRGVzY3JpcHRvcnNfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfcmVzdWx0KAorICAgICAgTWFwPGJ5dGVbXSxDb2x1bW5EZXNjcmlwdG9yPiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfcmVzdWx0KGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4gX190aGlzX19zdWNjZXNzID0gbmV3IEhhc2hNYXA8Ynl0ZVtdLENvbHVtbkRlc2NyaXB0b3I+KCk7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PGJ5dGVbXSwgQ29sdW1uRGVzY3JpcHRvcj4gb3RoZXJfZWxlbWVudCA6IG90aGVyLnN1Y2Nlc3MuZW50cnlTZXQoKSkgeworCisgICAgICAgICAgYnl0ZVtdIG90aGVyX2VsZW1lbnRfa2V5ID0gb3RoZXJfZWxlbWVudC5nZXRLZXkoKTsKKyAgICAgICAgICBDb2x1bW5EZXNjcmlwdG9yIG90aGVyX2VsZW1lbnRfdmFsdWUgPSBvdGhlcl9lbGVtZW50LmdldFZhbHVlKCk7CisKKyAgICAgICAgICBieXRlW10gX190aGlzX19zdWNjZXNzX2NvcHlfa2V5ID0gb3RoZXJfZWxlbWVudF9rZXk7CisKKyAgICAgICAgICBDb2x1bW5EZXNjcmlwdG9yIF9fdGhpc19fc3VjY2Vzc19jb3B5X3ZhbHVlID0gbmV3IENvbHVtbkRlc2NyaXB0b3Iob3RoZXJfZWxlbWVudF92YWx1ZSk7CisKKyAgICAgICAgICBfX3RoaXNfX3N1Y2Nlc3MucHV0KF9fdGhpc19fc3VjY2Vzc19jb3B5X2tleSwgX190aGlzX19zdWNjZXNzX2NvcHlfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Q29sdW1uRGVzY3JpcHRvcnNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gMCA6IHRoaXMuc3VjY2Vzcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcHV0VG9TdWNjZXNzKGJ5dGVbXSBrZXksIENvbHVtbkRlc2NyaXB0b3IgdmFsKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEhhc2hNYXA8Ynl0ZVtdLENvbHVtbkRlc2NyaXB0b3I+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MucHV0KGtleSwgdmFsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTWFwPGJ5dGVbXSxDb2x1bW5EZXNjcmlwdG9yPiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBnZXRTdWNjZXNzKCk7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gaXNTZXRTdWNjZXNzKCk7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldENvbHVtbkRlc2NyaXB0b3JzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoaXMuaXNTZXRTdWNjZXNzKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3VjY2VzcygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5zdWNjZXNzLmVxdWFscyh0aGF0LnN1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLk1BUCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVE1hcCBfbWFwMTMgPSBpcHJvdC5yZWFkTWFwQmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgSGFzaE1hcDxieXRlW10sQ29sdW1uRGVzY3JpcHRvcj4oMipfbWFwMTMuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2kxNCA9IDA7IF9pMTQgPCBfbWFwMTMuc2l6ZTsgKytfaTE0KQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGJ5dGVbXSBfa2V5MTU7CisgICAgICAgICAgICAgICAgICBDb2x1bW5EZXNjcmlwdG9yIF92YWwxNjsKKyAgICAgICAgICAgICAgICAgIF9rZXkxNSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgICAgICAgIF92YWwxNiA9IG5ldyBDb2x1bW5EZXNjcmlwdG9yKCk7CisgICAgICAgICAgICAgICAgICBfdmFsMTYucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MucHV0KF9rZXkxNSwgX3ZhbDE2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZE1hcEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVNYXBCZWdpbihuZXcgVE1hcChUVHlwZS5TVFJJTkcsIFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoTWFwLkVudHJ5PGJ5dGVbXSwgQ29sdW1uRGVzY3JpcHRvcj4gX2l0ZXIxNyA6IHRoaXMuc3VjY2Vzcy5lbnRyeVNldCgpKSAgICAgICAgICB7CisgICAgICAgICAgICBvcHJvdC53cml0ZUJpbmFyeShfaXRlcjE3LmdldEtleSgpKTsKKyAgICAgICAgICAgIF9pdGVyMTcuZ2V0VmFsdWUoKS53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTWFwRW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRDb2x1bW5EZXNjcmlwdG9yc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRUYWJsZVJlZ2lvbnNfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0VGFibGVSZWdpb25zX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChnZXRUYWJsZVJlZ2lvbnNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRUYWJsZVJlZ2lvbnNfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0VGFibGVSZWdpb25zX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0VGFibGVSZWdpb25zX2FyZ3MoZ2V0VGFibGVSZWdpb25zX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRUYWJsZVJlZ2lvbnNfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZ2V0VGFibGVSZWdpb25zX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0VGFibGVSZWdpb25zX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0VGFibGVSZWdpb25zX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldFRhYmxlUmVnaW9uc19hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFRhYmxlUmVnaW9uc19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuTElTVCwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBMaXN0PFRSZWdpb25JbmZvPiBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBUUmVnaW9uSW5mby5jbGFzcykpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChnZXRUYWJsZVJlZ2lvbnNfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGdldFRhYmxlUmVnaW9uc19yZXN1bHQoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldFRhYmxlUmVnaW9uc19yZXN1bHQoCisgICAgICBMaXN0PFRSZWdpb25JbmZvPiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0VGFibGVSZWdpb25zX3Jlc3VsdChnZXRUYWJsZVJlZ2lvbnNfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgTGlzdDxUUmVnaW9uSW5mbz4gX190aGlzX19zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUmVnaW9uSW5mbz4oKTsKKyAgICAgICAgZm9yIChUUmVnaW9uSW5mbyBvdGhlcl9lbGVtZW50IDogb3RoZXIuc3VjY2VzcykgeworICAgICAgICAgIF9fdGhpc19fc3VjY2Vzcy5hZGQobmV3IFRSZWdpb25JbmZvKG90aGVyX2VsZW1lbnQpKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBfX3RoaXNfX3N1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldFRhYmxlUmVnaW9uc19yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFRhYmxlUmVnaW9uc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gMCA6IHRoaXMuc3VjY2Vzcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxUUmVnaW9uSW5mbz4gZ2V0U3VjY2Vzc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5zdWNjZXNzLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9TdWNjZXNzKFRSZWdpb25JbmZvIGVsZW0pIHsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSZWdpb25JbmZvPigpOworICAgICAgfQorICAgICAgdGhpcy5zdWNjZXNzLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUmVnaW9uSW5mbz4gZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhMaXN0PFRSZWdpb25JbmZvPiBzdWNjZXNzKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3VjY2VzcygpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN1Y2Nlc3MgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2Vzc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRTdWNjZXNzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0U3VjY2VzcygoTGlzdDxUUmVnaW9uSW5mbz4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBnZXRTdWNjZXNzKCk7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gaXNTZXRTdWNjZXNzKCk7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGdldFRhYmxlUmVnaW9uc19yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0VGFibGVSZWdpb25zX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoaXMuaXNTZXRTdWNjZXNzKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3VjY2VzcygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5zdWNjZXNzLmVxdWFscyh0aGF0LnN1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0MTggPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUmVnaW9uSW5mbz4oX2xpc3QxOC5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTE5ID0gMDsgX2kxOSA8IF9saXN0MTguc2l6ZTsgKytfaTE5KQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIFRSZWdpb25JbmZvIF9lbGVtMjA7CisgICAgICAgICAgICAgICAgICBfZWxlbTIwID0gbmV3IFRSZWdpb25JbmZvKCk7CisgICAgICAgICAgICAgICAgICBfZWxlbTIwLnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzLmFkZChfZWxlbTIwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1VDQ0VTU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMuc3VjY2Vzcy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKFRSZWdpb25JbmZvIF9pdGVyMjEgOiB0aGlzLnN1Y2Nlc3MpICAgICAgICAgIHsKKyAgICAgICAgICAgIF9pdGVyMjEud3JpdGUob3Byb3QpOworICAgICAgICAgIH0KKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFRhYmxlUmVnaW9uc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBjcmVhdGVUYWJsZV9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJjcmVhdGVUYWJsZV9hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT0xVTU5fRkFNSUxJRVNfRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbkZhbWlsaWVzIiwgVFR5cGUuTElTVCwgKHNob3J0KTIpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgTGlzdDxDb2x1bW5EZXNjcmlwdG9yPiBjb2x1bW5GYW1pbGllczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0xVTU5GQU1JTElFUyA9IDI7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KENPTFVNTkZBTUlMSUVTLCBuZXcgRmllbGRNZXRhRGF0YSgiY29sdW1uRmFtaWxpZXMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgQ29sdW1uRGVzY3JpcHRvci5jbGFzcykpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoY3JlYXRlVGFibGVfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBjcmVhdGVUYWJsZV9hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBjcmVhdGVUYWJsZV9hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIExpc3Q8Q29sdW1uRGVzY3JpcHRvcj4gY29sdW1uRmFtaWxpZXMpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLmNvbHVtbkZhbWlsaWVzID0gY29sdW1uRmFtaWxpZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBjcmVhdGVUYWJsZV9hcmdzKGNyZWF0ZVRhYmxlX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Q29sdW1uRmFtaWxpZXMoKSkgeworICAgICAgICBMaXN0PENvbHVtbkRlc2NyaXB0b3I+IF9fdGhpc19fY29sdW1uRmFtaWxpZXMgPSBuZXcgQXJyYXlMaXN0PENvbHVtbkRlc2NyaXB0b3I+KCk7CisgICAgICAgIGZvciAoQ29sdW1uRGVzY3JpcHRvciBvdGhlcl9lbGVtZW50IDogb3RoZXIuY29sdW1uRmFtaWxpZXMpIHsKKyAgICAgICAgICBfX3RoaXNfX2NvbHVtbkZhbWlsaWVzLmFkZChuZXcgQ29sdW1uRGVzY3JpcHRvcihvdGhlcl9lbGVtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb2x1bW5GYW1pbGllcyA9IF9fdGhpc19fY29sdW1uRmFtaWxpZXM7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGNyZWF0ZVRhYmxlX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGNyZWF0ZVRhYmxlX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uRmFtaWxpZXNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbkZhbWlsaWVzID09IG51bGwpID8gMCA6IHRoaXMuY29sdW1uRmFtaWxpZXMuc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBqYXZhLnV0aWwuSXRlcmF0b3I8Q29sdW1uRGVzY3JpcHRvcj4gZ2V0Q29sdW1uRmFtaWxpZXNJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5jb2x1bW5GYW1pbGllcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLmNvbHVtbkZhbWlsaWVzLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5GYW1pbGllcyhDb2x1bW5EZXNjcmlwdG9yIGVsZW0pIHsKKyAgICAgIGlmICh0aGlzLmNvbHVtbkZhbWlsaWVzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5GYW1pbGllcyA9IG5ldyBBcnJheUxpc3Q8Q29sdW1uRGVzY3JpcHRvcj4oKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuY29sdW1uRmFtaWxpZXMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PENvbHVtbkRlc2NyaXB0b3I+IGdldENvbHVtbkZhbWlsaWVzKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1uRmFtaWxpZXM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uRmFtaWxpZXMoTGlzdDxDb2x1bW5EZXNjcmlwdG9yPiBjb2x1bW5GYW1pbGllcykgeworICAgICAgdGhpcy5jb2x1bW5GYW1pbGllcyA9IGNvbHVtbkZhbWlsaWVzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1uRmFtaWxpZXMoKSB7CisgICAgICB0aGlzLmNvbHVtbkZhbWlsaWVzID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29sdW1uRmFtaWxpZXMgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldENvbHVtbkZhbWlsaWVzKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1uRmFtaWxpZXMgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5GYW1pbGllc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5GYW1pbGllcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIENPTFVNTkZBTUlMSUVTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1uRmFtaWxpZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRDb2x1bW5GYW1pbGllcygoTGlzdDxDb2x1bW5EZXNjcmlwdG9yPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIENPTFVNTkZBTUlMSUVTOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1uRmFtaWxpZXMoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgQ09MVU1ORkFNSUxJRVM6CisgICAgICAgIHJldHVybiBpc1NldENvbHVtbkZhbWlsaWVzKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgY3JlYXRlVGFibGVfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChjcmVhdGVUYWJsZV9hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhjcmVhdGVUYWJsZV9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbkZhbWlsaWVzID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Q29sdW1uRmFtaWxpZXMoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbHVtbkZhbWlsaWVzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1uRmFtaWxpZXMoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfY29sdW1uRmFtaWxpZXMgfHwgdGhhdF9wcmVzZW50X2NvbHVtbkZhbWlsaWVzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW5GYW1pbGllcyAmJiB0aGF0X3ByZXNlbnRfY29sdW1uRmFtaWxpZXMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmNvbHVtbkZhbWlsaWVzLmVxdWFscyh0aGF0LmNvbHVtbkZhbWlsaWVzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU5GQU1JTElFUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0MjIgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5GYW1pbGllcyA9IG5ldyBBcnJheUxpc3Q8Q29sdW1uRGVzY3JpcHRvcj4oX2xpc3QyMi5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTIzID0gMDsgX2kyMyA8IF9saXN0MjIuc2l6ZTsgKytfaTIzKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIENvbHVtbkRlc2NyaXB0b3IgX2VsZW0yNDsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMjQgPSBuZXcgQ29sdW1uRGVzY3JpcHRvcigpOworICAgICAgICAgICAgICAgICAgX2VsZW0yNC5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uRmFtaWxpZXMuYWRkKF9lbGVtMjQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5jb2x1bW5GYW1pbGllcyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5fRkFNSUxJRVNfRklFTERfREVTQyk7CisgICAgICAgIHsKKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihuZXcgVExpc3QoVFR5cGUuU1RSVUNULCB0aGlzLmNvbHVtbkZhbWlsaWVzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoQ29sdW1uRGVzY3JpcHRvciBfaXRlcjI1IDogdGhpcy5jb2x1bW5GYW1pbGllcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXIyNS53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImNyZWF0ZVRhYmxlX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW5GYW1pbGllczoiKTsKKyAgICAgIGlmICh0aGlzLmNvbHVtbkZhbWlsaWVzID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5jb2x1bW5GYW1pbGllcyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBjcmVhdGVUYWJsZV9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImNyZWF0ZVRhYmxlX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSUFfRklFTERfREVTQyA9IG5ldyBURmllbGQoImlhIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIEVYSVNUX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJleGlzdCIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTMpOworCisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworICAgIHB1YmxpYyBJbGxlZ2FsQXJndW1lbnQgaWE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUEgPSAyOworICAgIHB1YmxpYyBBbHJlYWR5RXhpc3RzIGV4aXN0OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVYSVNUID0gMzsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgICAgcHV0KElBLCBuZXcgRmllbGRNZXRhRGF0YSgiaWEiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgICBwdXQoRVhJU1QsIG5ldyBGaWVsZE1ldGFEYXRhKCJleGlzdCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChjcmVhdGVUYWJsZV9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgY3JlYXRlVGFibGVfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBjcmVhdGVUYWJsZV9yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvLAorICAgICAgSWxsZWdhbEFyZ3VtZW50IGlhLAorICAgICAgQWxyZWFkeUV4aXN0cyBleGlzdCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgICB0aGlzLmV4aXN0ID0gZXhpc3Q7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBjcmVhdGVUYWJsZV9yZXN1bHQoY3JlYXRlVGFibGVfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJYSgpKSB7CisgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KG90aGVyLmlhKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldEV4aXN0KCkpIHsKKyAgICAgICAgdGhpcy5leGlzdCA9IG5ldyBBbHJlYWR5RXhpc3RzKG90aGVyLmV4aXN0KTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgY3JlYXRlVGFibGVfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBjcmVhdGVUYWJsZV9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgQWxyZWFkeUV4aXN0cyBnZXRFeGlzdCgpIHsKKyAgICAgIHJldHVybiB0aGlzLmV4aXN0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEV4aXN0KEFscmVhZHlFeGlzdHMgZXhpc3QpIHsKKyAgICAgIHRoaXMuZXhpc3QgPSBleGlzdDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldEV4aXN0KCkgeworICAgICAgdGhpcy5leGlzdCA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGV4aXN0IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRFeGlzdCgpIHsKKyAgICAgIHJldHVybiB0aGlzLmV4aXN0ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RXhpc3RJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuZXhpc3QgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJYSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElhKChJbGxlZ2FsQXJndW1lbnQpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEVYSVNUOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0RXhpc3QoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRFeGlzdCgoQWxyZWFkeUV4aXN0cyl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGdldElhKCk7CisKKyAgICAgIGNhc2UgRVhJU1Q6CisgICAgICAgIHJldHVybiBnZXRFeGlzdCgpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIHJldHVybiBpc1NldElhKCk7CisgICAgICBjYXNlIEVYSVNUOgorICAgICAgICByZXR1cm4gaXNTZXRFeGlzdCgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGNyZWF0ZVRhYmxlX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChjcmVhdGVUYWJsZV9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGNyZWF0ZVRhYmxlX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SWEoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SWEoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaWEgfHwgdGhhdF9wcmVzZW50X2lhKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pYSAmJiB0aGF0X3ByZXNlbnRfaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlhLmVxdWFscyh0aGF0LmlhKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2V4aXN0ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0RXhpc3QoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2V4aXN0ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0RXhpc3QoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfZXhpc3QgfHwgdGhhdF9wcmVzZW50X2V4aXN0KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9leGlzdCAmJiB0aGF0X3ByZXNlbnRfZXhpc3QpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmV4aXN0LmVxdWFscyh0aGF0LmV4aXN0KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElBOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KCk7CisgICAgICAgICAgICAgIHRoaXMuaWEucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgRVhJU1Q6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5leGlzdCA9IG5ldyBBbHJlYWR5RXhpc3RzKCk7CisgICAgICAgICAgICAgIHRoaXMuZXhpc3QucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldEV4aXN0KCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKEVYSVNUX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmV4aXN0LndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiY3JlYXRlVGFibGVfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaWE6Iik7CisgICAgICBpZiAodGhpcy5pYSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaWEpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiZXhpc3Q6Iik7CisgICAgICBpZiAodGhpcy5leGlzdCA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuZXhpc3QpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlVGFibGVfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZGVsZXRlVGFibGVfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGRlbGV0ZVRhYmxlX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlVGFibGVfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlVGFibGVfYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBkZWxldGVUYWJsZV9hcmdzKGRlbGV0ZVRhYmxlX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkZWxldGVUYWJsZV9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVUYWJsZV9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRlbGV0ZVRhYmxlX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZGVsZXRlVGFibGVfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZGVsZXRlVGFibGVfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJkZWxldGVUYWJsZV9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlVGFibGVfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJkZWxldGVUYWJsZV9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVUYWJsZV9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlVGFibGVfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVUYWJsZV9yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZVRhYmxlX3Jlc3VsdChkZWxldGVUYWJsZV9yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZGVsZXRlVGFibGVfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVUYWJsZV9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRlbGV0ZVRhYmxlX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVUYWJsZV9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRlbGV0ZVRhYmxlX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZGVsZXRlVGFibGVfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImdldF9hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT0xVTU5fRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbiIsIFRUeXBlLlNUUklORywgKHNob3J0KTMpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworICAgIHB1YmxpYyBieXRlW10gY29sdW1uOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTiA9IDM7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChDT0xVTU4sIG5ldyBGaWVsZE1ldGFEYXRhKCJjb2x1bW4iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0X2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0X2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldF9hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBieXRlW10gY29sdW1uKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldF9hcmdzKGdldF9hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Q29sdW1uKCkpIHsKKyAgICAgICAgdGhpcy5jb2x1bW4gPSBvdGhlci5jb2x1bW47CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldF9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Q29sdW1uKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbihieXRlW10gY29sdW1uKSB7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbigpIHsKKyAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29sdW1uIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW4gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldENvbHVtbigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldENvbHVtbigoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gZ2V0Um93KCk7CisKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1uKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93KCk7CisgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgcmV0dXJuIGlzU2V0Q29sdW1uKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0X2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0X2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldF9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhpcy5pc1NldFJvdygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3JvdyB8fCB0aGF0X3ByZXNlbnRfcm93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9yb3cgJiYgdGhhdF9wcmVzZW50X3JvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMucm93LCB0aGF0LnJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9jb2x1bW4gPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW4oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbHVtbiA9IHRydWUgJiYgdGhhdC5pc1NldENvbHVtbigpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW4gfHwgdGhhdF9wcmVzZW50X2NvbHVtbikgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfY29sdW1uICYmIHRoYXRfcHJlc2VudF9jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLmNvbHVtbiwgdGhhdC5jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJPVzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5jb2x1bW4gPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbiAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5fRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuY29sdW1uKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0X2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW46Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW4gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbik7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNVQ0NFU1NfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN1Y2Nlc3MiLCBUVHlwZS5MSVNULCAoc2hvcnQpMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIExpc3Q8VENlbGw+IHN1Y2Nlc3M7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VDQ0VTUyA9IDA7CisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFNVQ0NFU1MsIG5ldyBGaWVsZE1ldGFEYXRhKCJzdWNjZXNzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBMaXN0TWV0YURhdGEoVFR5cGUuTElTVCwgCisgICAgICAgICAgICAgIG5ldyBTdHJ1Y3RNZXRhRGF0YShUVHlwZS5TVFJVQ1QsIFRDZWxsLmNsYXNzKSkpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGdldF9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0X3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0X3Jlc3VsdCgKKyAgICAgIExpc3Q8VENlbGw+IHN1Y2Nlc3MsCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBnZXRfcmVzdWx0KGdldF9yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBMaXN0PFRDZWxsPiBfX3RoaXNfX3N1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRDZWxsPigpOworICAgICAgICBmb3IgKFRDZWxsIG90aGVyX2VsZW1lbnQgOiBvdGhlci5zdWNjZXNzKSB7CisgICAgICAgICAgX190aGlzX19zdWNjZXNzLmFkZChuZXcgVENlbGwob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0X3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZ2V0X3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN1Y2Nlc3NTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyAwIDogdGhpcy5zdWNjZXNzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPFRDZWxsPiBnZXRTdWNjZXNzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnN1Y2Nlc3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1N1Y2Nlc3MoVENlbGwgZWxlbSkgeworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRDZWxsPiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKExpc3Q8VENlbGw+IHN1Y2Nlc3MpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRTdWNjZXNzKCkgeworICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgc3VjY2VzcyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3MgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChMaXN0PFRDZWxsPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGdldFN1Y2Nlc3MoKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0X3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhpcy5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoYXQuaXNTZXRTdWNjZXNzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N1Y2Nlc3MgfHwgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N1Y2Nlc3MgJiYgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnN1Y2Nlc3MuZXF1YWxzKHRoYXQuc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3QyNiA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRDZWxsPihfbGlzdDI2LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pMjcgPSAwOyBfaTI3IDwgX2xpc3QyNi5zaXplOyArK19pMjcpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgVENlbGwgX2VsZW0yODsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMjggPSBuZXcgVENlbGwoKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMjgucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKF9lbGVtMjgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoVENlbGwgX2l0ZXIyOSA6IHRoaXMuc3VjY2VzcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXIyOS53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0X3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInN1Y2Nlc3M6Iik7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5zdWNjZXNzKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGdldFZlcl9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRWZXJfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJyb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJjb2x1bW4iLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTlVNX1ZFUlNJT05TX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJudW1WZXJzaW9ucyIsIFRUeXBlLkkzMiwgKHNob3J0KTQpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworICAgIHB1YmxpYyBieXRlW10gY29sdW1uOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTiA9IDM7CisgICAgcHVibGljIGludCBudW1WZXJzaW9uczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1WRVJTSU9OUyA9IDQ7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIG51bVZlcnNpb25zID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJyb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoQ09MVU1OLCBuZXcgRmllbGRNZXRhRGF0YSgiY29sdW1uIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KE5VTVZFUlNJT05TLCBuZXcgRmllbGRNZXRhRGF0YSgibnVtVmVyc2lvbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0VmVyX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0VmVyX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldFZlcl9hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBieXRlW10gY29sdW1uLAorICAgICAgaW50IG51bVZlcnNpb25zKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICAgIHRoaXMubnVtVmVyc2lvbnMgPSBudW1WZXJzaW9uczsKKyAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBnZXRWZXJfYXJncyhnZXRWZXJfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3coKSkgeworICAgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldENvbHVtbigpKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gb3RoZXIuY29sdW1uOworICAgICAgfQorICAgICAgX19pc3NldC5udW1WZXJzaW9ucyA9IG90aGVyLl9faXNzZXQubnVtVmVyc2lvbnM7CisgICAgICB0aGlzLm51bVZlcnNpb25zID0gb3RoZXIubnVtVmVyc2lvbnM7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldFZlcl9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRWZXJfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Q29sdW1uKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbihieXRlW10gY29sdW1uKSB7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbigpIHsKKyAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29sdW1uIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW4gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE51bVZlcnNpb25zKCkgeworICAgICAgcmV0dXJuIHRoaXMubnVtVmVyc2lvbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TnVtVmVyc2lvbnMoaW50IG51bVZlcnNpb25zKSB7CisgICAgICB0aGlzLm51bVZlcnNpb25zID0gbnVtVmVyc2lvbnM7CisgICAgICB0aGlzLl9faXNzZXQubnVtVmVyc2lvbnMgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0TnVtVmVyc2lvbnMoKSB7CisgICAgICB0aGlzLl9faXNzZXQubnVtVmVyc2lvbnMgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgbnVtVmVyc2lvbnMgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldE51bVZlcnNpb25zKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5udW1WZXJzaW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXROdW1WZXJzaW9uc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1uKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Q29sdW1uKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIE5VTVZFUlNJT05TOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0TnVtVmVyc2lvbnMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXROdW1WZXJzaW9ucygoSW50ZWdlcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFJvdygpOworCisgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgcmV0dXJuIGdldENvbHVtbigpOworCisgICAgICBjYXNlIE5VTVZFUlNJT05TOgorICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoZ2V0TnVtVmVyc2lvbnMoKSk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93KCk7CisgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgcmV0dXJuIGlzU2V0Q29sdW1uKCk7CisgICAgICBjYXNlIE5VTVZFUlNJT05TOgorICAgICAgICByZXR1cm4gaXNTZXROdW1WZXJzaW9ucygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGdldFZlcl9hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFZlcl9hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRWZXJfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoaXMuaXNTZXRSb3coKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhhdC5pc1NldFJvdygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9yb3cgfHwgdGhhdF9wcmVzZW50X3JvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfcm93ICYmIHRoYXRfcHJlc2VudF9yb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnJvdywgdGhhdC5yb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfY29sdW1uID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Q29sdW1uKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9jb2x1bW4gPSB0cnVlICYmIHRoYXQuaXNTZXRDb2x1bW4oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfY29sdW1uIHx8IHRoYXRfcHJlc2VudF9jb2x1bW4pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2NvbHVtbiAmJiB0aGF0X3ByZXNlbnRfY29sdW1uKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5jb2x1bW4sIHRoYXQuY29sdW1uKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X251bVZlcnNpb25zID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X251bVZlcnNpb25zID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfbnVtVmVyc2lvbnMgfHwgdGhhdF9wcmVzZW50X251bVZlcnNpb25zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9udW1WZXJzaW9ucyAmJiB0aGF0X3ByZXNlbnRfbnVtVmVyc2lvbnMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHRoaXMubnVtVmVyc2lvbnMgIT0gdGhhdC5udW1WZXJzaW9ucykKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIE5VTVZFUlNJT05TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTMyKSB7CisgICAgICAgICAgICAgIHRoaXMubnVtVmVyc2lvbnMgPSBpcHJvdC5yZWFkSTMyKCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbiAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5fRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuY29sdW1uKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKE5VTV9WRVJTSU9OU19GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTMyKHRoaXMubnVtVmVyc2lvbnMpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0VmVyX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW46Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW4gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbik7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJudW1WZXJzaW9uczoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLm51bVZlcnNpb25zKTsKKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGdldFZlcl9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImdldFZlcl9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgTGlzdDxUQ2VsbD4gc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgVENlbGwuY2xhc3MpKSkpOworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0VmVyX3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRWZXJfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRWZXJfcmVzdWx0KAorICAgICAgTGlzdDxUQ2VsbD4gc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFZlcl9yZXN1bHQoZ2V0VmVyX3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIExpc3Q8VENlbGw+IF9fdGhpc19fc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KCk7CisgICAgICAgIGZvciAoVENlbGwgb3RoZXJfZWxlbWVudCA6IG90aGVyLnN1Y2Nlc3MpIHsKKyAgICAgICAgICBfX3RoaXNfX3N1Y2Nlc3MuYWRkKG5ldyBUQ2VsbChvdGhlcl9lbGVtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zdWNjZXNzID0gX190aGlzX19zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRWZXJfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRWZXJfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3VjY2Vzc1NpemUoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IDAgOiB0aGlzLnN1Y2Nlc3Muc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBqYXZhLnV0aWwuSXRlcmF0b3I8VENlbGw+IGdldFN1Y2Nlc3NJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gbnVsbCA6IHRoaXMuc3VjY2Vzcy5pdGVyYXRvcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZFRvU3VjY2VzcyhUQ2VsbCBlbGVtKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUQ2VsbD4oKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuc3VjY2Vzcy5hZGQoZWxlbSk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VENlbGw+IGdldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3MoTGlzdDxUQ2VsbD4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExpc3Q8VENlbGw+KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gZ2V0U3VjY2VzcygpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3VjY2VzcygpOworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBnZXRWZXJfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFZlcl9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldFZlcl9yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGlzLmlzU2V0U3VjY2VzcygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhhdC5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3VjY2VzcyB8fCB0aGF0X3ByZXNlbnRfc3VjY2VzcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3VjY2VzcyAmJiB0aGF0X3ByZXNlbnRfc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuc3VjY2Vzcy5lcXVhbHModGhhdC5zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5MSVNUKSB7CisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBUTGlzdCBfbGlzdDMwID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KF9saXN0MzAuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2kzMSA9IDA7IF9pMzEgPCBfbGlzdDMwLnNpemU7ICsrX2kzMSkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBUQ2VsbCBfZWxlbTMyOworICAgICAgICAgICAgICAgICAgX2VsZW0zMiA9IG5ldyBUQ2VsbCgpOworICAgICAgICAgICAgICAgICAgX2VsZW0zMi5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuc3VjY2Vzcy5hZGQoX2VsZW0zMik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNVQ0NFU1NfRklFTERfREVTQyk7CisgICAgICAgIHsKKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihuZXcgVExpc3QoVFR5cGUuU1RSVUNULCB0aGlzLnN1Y2Nlc3Muc2l6ZSgpKSk7CisgICAgICAgICAgZm9yIChUQ2VsbCBfaXRlcjMzIDogdGhpcy5zdWNjZXNzKSAgICAgICAgICB7CisgICAgICAgICAgICBfaXRlcjMzLndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRWZXJfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0VmVyVHNfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0VmVyVHNfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJyb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJjb2x1bW4iLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVElNRVNUQU1QX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0aW1lc3RhbXAiLCBUVHlwZS5JNjQsIChzaG9ydCk0KTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTlVNX1ZFUlNJT05TX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJudW1WZXJzaW9ucyIsIFRUeXBlLkkzMiwgKHNob3J0KTUpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworICAgIHB1YmxpYyBieXRlW10gY29sdW1uOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTiA9IDM7CisgICAgcHVibGljIGxvbmcgdGltZXN0YW1wOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUCA9IDQ7CisgICAgcHVibGljIGludCBudW1WZXJzaW9uczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOVU1WRVJTSU9OUyA9IDU7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHRpbWVzdGFtcCA9IGZhbHNlOworICAgICAgcHVibGljIGJvb2xlYW4gbnVtVmVyc2lvbnMgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChDT0xVTU4sIG5ldyBGaWVsZE1ldGFEYXRhKCJjb2x1bW4iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoVElNRVNUQU1QLCBuZXcgRmllbGRNZXRhRGF0YSgidGltZXN0YW1wIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTY0KSkpOworICAgICAgcHV0KE5VTVZFUlNJT05TLCBuZXcgRmllbGRNZXRhRGF0YSgibnVtVmVyc2lvbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0VmVyVHNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRWZXJUc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRWZXJUc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBieXRlW10gY29sdW1uLAorICAgICAgbG9uZyB0aW1lc3RhbXAsCisgICAgICBpbnQgbnVtVmVyc2lvbnMpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIHRoaXMubnVtVmVyc2lvbnMgPSBudW1WZXJzaW9uczsKKyAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBnZXRWZXJUc19hcmdzKGdldFZlclRzX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Um93KCkpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBvdGhlci5yb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRDb2x1bW4oKSkgeworICAgICAgICB0aGlzLmNvbHVtbiA9IG90aGVyLmNvbHVtbjsKKyAgICAgIH0KKyAgICAgIF9faXNzZXQudGltZXN0YW1wID0gb3RoZXIuX19pc3NldC50aW1lc3RhbXA7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IG90aGVyLnRpbWVzdGFtcDsKKyAgICAgIF9faXNzZXQubnVtVmVyc2lvbnMgPSBvdGhlci5fX2lzc2V0Lm51bVZlcnNpb25zOworICAgICAgdGhpcy5udW1WZXJzaW9ucyA9IG90aGVyLm51bVZlcnNpb25zOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRWZXJUc19hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRWZXJUc19hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3coYnl0ZVtdIHJvdykgeworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRSb3coKSB7CisgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uKGJ5dGVbXSBjb2x1bW4pIHsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1uKCkgeworICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW4gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldENvbHVtbigpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbiAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbklzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUaW1lc3RhbXAoKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVzdGFtcCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TnVtVmVyc2lvbnMoKSB7CisgICAgICByZXR1cm4gdGhpcy5udW1WZXJzaW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXROdW1WZXJzaW9ucyhpbnQgbnVtVmVyc2lvbnMpIHsKKyAgICAgIHRoaXMubnVtVmVyc2lvbnMgPSBudW1WZXJzaW9uczsKKyAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXROdW1WZXJzaW9ucygpIHsKKyAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBudW1WZXJzaW9ucyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0TnVtVmVyc2lvbnMoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0Lm51bVZlcnNpb25zOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldE51bVZlcnNpb25zSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0Lm51bVZlcnNpb25zID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRDb2x1bW4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRDb2x1bW4oKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGltZXN0YW1wKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGltZXN0YW1wKChMb25nKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBOVU1WRVJTSU9OUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldE51bVZlcnNpb25zKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0TnVtVmVyc2lvbnMoKEludGVnZXIpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgIHJldHVybiBnZXRDb2x1bW4oKTsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBuZXcgTG9uZyhnZXRUaW1lc3RhbXAoKSk7CisKKyAgICAgIGNhc2UgTlVNVkVSU0lPTlM6CisgICAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXROdW1WZXJzaW9ucygpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gaXNTZXRDb2x1bW4oKTsKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gaXNTZXRUaW1lc3RhbXAoKTsKKyAgICAgIGNhc2UgTlVNVkVSU0lPTlM6CisgICAgICAgIHJldHVybiBpc1NldE51bVZlcnNpb25zKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0VmVyVHNfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRWZXJUc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRWZXJUc19hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhpcy5pc1NldFJvdygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3JvdyB8fCB0aGF0X3ByZXNlbnRfcm93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9yb3cgJiYgdGhhdF9wcmVzZW50X3JvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMucm93LCB0aGF0LnJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9jb2x1bW4gPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW4oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbHVtbiA9IHRydWUgJiYgdGhhdC5pc1NldENvbHVtbigpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW4gfHwgdGhhdF9wcmVzZW50X2NvbHVtbikgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfY29sdW1uICYmIHRoYXRfcHJlc2VudF9jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLmNvbHVtbiwgdGhhdC5jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RpbWVzdGFtcCB8fCB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgJiYgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy50aW1lc3RhbXAgIT0gdGhhdC50aW1lc3RhbXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9udW1WZXJzaW9ucyA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9udW1WZXJzaW9ucyA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X251bVZlcnNpb25zIHx8IHRoYXRfcHJlc2VudF9udW1WZXJzaW9ucykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfbnVtVmVyc2lvbnMgJiYgdGhhdF9wcmVzZW50X251bVZlcnNpb25zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLm51bVZlcnNpb25zICE9IHRoYXQubnVtVmVyc2lvbnMpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMucm93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLmNvbHVtbiA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JNjQpIHsKKyAgICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIE5VTVZFUlNJT05TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTMyKSB7CisgICAgICAgICAgICAgIHRoaXMubnVtVmVyc2lvbnMgPSBpcHJvdC5yZWFkSTMyKCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC5udW1WZXJzaW9ucyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbiAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5fRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuY29sdW1uKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRJTUVTVEFNUF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihOVU1fVkVSU0lPTlNfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUkzMih0aGlzLm51bVZlcnNpb25zKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFZlclRzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW46Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW4gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbik7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJ0aW1lc3RhbXA6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy50aW1lc3RhbXApOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgibnVtVmVyc2lvbnM6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy5udW1WZXJzaW9ucyk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRWZXJUc19yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImdldFZlclRzX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuTElTVCwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBMaXN0PFRDZWxsPiBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBUQ2VsbC5jbGFzcykpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChnZXRWZXJUc19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0VmVyVHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRWZXJUc19yZXN1bHQoCisgICAgICBMaXN0PFRDZWxsPiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0VmVyVHNfcmVzdWx0KGdldFZlclRzX3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIExpc3Q8VENlbGw+IF9fdGhpc19fc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KCk7CisgICAgICAgIGZvciAoVENlbGwgb3RoZXJfZWxlbWVudCA6IG90aGVyLnN1Y2Nlc3MpIHsKKyAgICAgICAgICBfX3RoaXNfX3N1Y2Nlc3MuYWRkKG5ldyBUQ2VsbChvdGhlcl9lbGVtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zdWNjZXNzID0gX190aGlzX19zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRWZXJUc19yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFZlclRzX3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN1Y2Nlc3NTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyAwIDogdGhpcy5zdWNjZXNzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPFRDZWxsPiBnZXRTdWNjZXNzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnN1Y2Nlc3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1N1Y2Nlc3MoVENlbGwgZWxlbSkgeworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VENlbGw+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRDZWxsPiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKExpc3Q8VENlbGw+IHN1Y2Nlc3MpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRTdWNjZXNzKCkgeworICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgc3VjY2VzcyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3MgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChMaXN0PFRDZWxsPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGdldFN1Y2Nlc3MoKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0VmVyVHNfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFZlclRzX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0VmVyVHNfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhpcy5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoYXQuaXNTZXRTdWNjZXNzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N1Y2Nlc3MgfHwgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N1Y2Nlc3MgJiYgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnN1Y2Nlc3MuZXF1YWxzKHRoYXQuc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3QzNCA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRDZWxsPihfbGlzdDM0LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pMzUgPSAwOyBfaTM1IDwgX2xpc3QzNC5zaXplOyArK19pMzUpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgVENlbGwgX2VsZW0zNjsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMzYgPSBuZXcgVENlbGwoKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMzYucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKF9lbGVtMzYpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoVENlbGwgX2l0ZXIzNyA6IHRoaXMuc3VjY2VzcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXIzNy53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0VmVyVHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0Um93X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImdldFJvd19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJyb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Um93X2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0Um93X2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldFJvd19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3cpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFJvd19hcmdzKGdldFJvd19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRSb3dfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZ2V0Um93X2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBnZXRSb3dfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRSb3dfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0Um93X2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFJvd19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0Um93X3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0Um93X3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuTElTVCwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IHN1Y2Nlc3M7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VDQ0VTUyA9IDA7CisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFNVQ0NFU1MsIG5ldyBGaWVsZE1ldGFEYXRhKCJzdWNjZXNzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBMaXN0TWV0YURhdGEoVFR5cGUuTElTVCwgCisgICAgICAgICAgICAgIG5ldyBTdHJ1Y3RNZXRhRGF0YShUVHlwZS5TVFJVQ1QsIFRSb3dSZXN1bHQuY2xhc3MpKSkpOworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Um93X3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dfcmVzdWx0KAorICAgICAgTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZ2V0Um93X3Jlc3VsdChnZXRSb3dfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgTGlzdDxUUm93UmVzdWx0PiBfX3RoaXNfX3N1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBvdGhlcl9lbGVtZW50IDogb3RoZXIuc3VjY2VzcykgeworICAgICAgICAgIF9fdGhpc19fc3VjY2Vzcy5hZGQobmV3IFRSb3dSZXN1bHQob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Um93X3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZ2V0Um93X3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN1Y2Nlc3NTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyAwIDogdGhpcy5zdWNjZXNzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPFRSb3dSZXN1bHQ+IGdldFN1Y2Nlc3NJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gbnVsbCA6IHRoaXMuc3VjY2Vzcy5pdGVyYXRvcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZFRvU3VjY2VzcyhUUm93UmVzdWx0IGVsZW0pIHsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IGdldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3MoTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3VjY2VzcygpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN1Y2Nlc3MgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2Vzc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRTdWNjZXNzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0U3VjY2VzcygoTGlzdDxUUm93UmVzdWx0Pil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGdldFN1Y2Nlc3MoKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0Um93X3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRSb3dfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRSb3dfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhpcy5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoYXQuaXNTZXRTdWNjZXNzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N1Y2Nlc3MgfHwgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N1Y2Nlc3MgJiYgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnN1Y2Nlc3MuZXF1YWxzKHRoYXQuc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3QzOCA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KF9saXN0Mzguc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2kzOSA9IDA7IF9pMzkgPCBfbGlzdDM4LnNpemU7ICsrX2kzOSkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBUUm93UmVzdWx0IF9lbGVtNDA7CisgICAgICAgICAgICAgICAgICBfZWxlbTQwID0gbmV3IFRSb3dSZXN1bHQoKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNDAucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKF9lbGVtNDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBfaXRlcjQxIDogdGhpcy5zdWNjZXNzKSAgICAgICAgICB7CisgICAgICAgICAgICBfaXRlcjQxLndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRSb3dfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0Um93V2l0aENvbHVtbnNfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0Um93V2l0aENvbHVtbnNfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJyb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1ucyIsIFRUeXBlLkxJU1QsIChzaG9ydCkzKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIGJ5dGVbXSByb3c7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9XID0gMjsKKyAgICBwdWJsaWMgTGlzdDxieXRlW10+IGNvbHVtbnM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OUyA9IDM7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChDT0xVTU5TLCBuZXcgRmllbGRNZXRhRGF0YSgiY29sdW1ucyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Um93V2l0aENvbHVtbnNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MoZ2V0Um93V2l0aENvbHVtbnNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3coKSkgeworICAgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldENvbHVtbnMoKSkgeworICAgICAgICBMaXN0PGJ5dGVbXT4gX190aGlzX19jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICAgIGZvciAoYnl0ZVtdIG90aGVyX2VsZW1lbnQgOiBvdGhlci5jb2x1bW5zKSB7CisgICAgICAgICAgX190aGlzX19jb2x1bW5zLmFkZChvdGhlcl9lbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbHVtbnMgPSBfX3RoaXNfX2NvbHVtbnM7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFJvd1dpdGhDb2x1bW5zX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbnNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0Q29sdW1uc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5jb2x1bW5zLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5zKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLmNvbHVtbnMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhMaXN0PGJ5dGVbXT4gY29sdW1ucykgeworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbnMoKSB7CisgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW5zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1ucyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldENvbHVtbnMoKExpc3Q8Ynl0ZVtdPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFJvdygpOworCisgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgIHJldHVybiBnZXRDb2x1bW5zKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93KCk7CisgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgIHJldHVybiBpc1NldENvbHVtbnMoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBnZXRSb3dXaXRoQ29sdW1uc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldFJvd1dpdGhDb2x1bW5zX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbnMgPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW5zKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1ucygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW5zIHx8IHRoYXRfcHJlc2VudF9jb2x1bW5zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW5zICYmIHRoYXRfcHJlc2VudF9jb2x1bW5zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5jb2x1bW5zLmVxdWFscyh0aGF0LmNvbHVtbnMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJPVzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q0MiA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oX2xpc3Q0Mi5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTQzID0gMDsgX2k0MyA8IF9saXN0NDIuc2l6ZTsgKytfaTQzKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGJ5dGVbXSBfZWxlbTQ0OworICAgICAgICAgICAgICAgICAgX2VsZW00NCA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucy5hZGQoX2VsZW00NCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuY29sdW1ucyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5TX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUklORywgdGhpcy5jb2x1bW5zLnNpemUoKSkpOworICAgICAgICAgIGZvciAoYnl0ZVtdIF9pdGVyNDUgOiB0aGlzLmNvbHVtbnMpICAgICAgICAgIHsKKyAgICAgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KF9pdGVyNDUpOworICAgICAgICAgIH0KKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRSb3dXaXRoQ29sdW1uc19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiY29sdW1uczoiKTsKKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbnMpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0Um93V2l0aENvbHVtbnNfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBUUm93UmVzdWx0LmNsYXNzKSkpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdCgKKyAgICAgIExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdChnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBMaXN0PFRSb3dSZXN1bHQ+IF9fdGhpc19fc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VFJvd1Jlc3VsdD4oKTsKKyAgICAgICAgZm9yIChUUm93UmVzdWx0IG90aGVyX2VsZW1lbnQgOiBvdGhlci5zdWNjZXNzKSB7CisgICAgICAgICAgX190aGlzX19zdWNjZXNzLmFkZChuZXcgVFJvd1Jlc3VsdChvdGhlcl9lbGVtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5zdWNjZXNzID0gX190aGlzX19zdWNjZXNzOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFN1Y2Nlc3NTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyAwIDogdGhpcy5zdWNjZXNzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPFRSb3dSZXN1bHQ+IGdldFN1Y2Nlc3NJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gbnVsbCA6IHRoaXMuc3VjY2Vzcy5pdGVyYXRvcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZFRvU3VjY2VzcyhUUm93UmVzdWx0IGVsZW0pIHsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICB9CisgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PFRSb3dSZXN1bHQ+IGdldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3MoTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3VjY2VzcygpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN1Y2Nlc3MgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2Vzc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRTdWNjZXNzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0U3VjY2VzcygoTGlzdDxUUm93UmVzdWx0Pil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGdldFN1Y2Nlc3MoKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZ2V0Um93V2l0aENvbHVtbnNfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGdldFJvd1dpdGhDb2x1bW5zX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0Um93V2l0aENvbHVtbnNfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhpcy5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoYXQuaXNTZXRTdWNjZXNzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N1Y2Nlc3MgfHwgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N1Y2Nlc3MgJiYgdGhhdF9wcmVzZW50X3N1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnN1Y2Nlc3MuZXF1YWxzKHRoYXQuc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q0NiA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KF9saXN0NDYuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2k0NyA9IDA7IF9pNDcgPCBfbGlzdDQ2LnNpemU7ICsrX2k0NykKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBUUm93UmVzdWx0IF9lbGVtNDg7CisgICAgICAgICAgICAgICAgICBfZWxlbTQ4ID0gbmV3IFRSb3dSZXN1bHQoKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNDgucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MuYWRkKF9lbGVtNDgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBfaXRlcjQ5IDogdGhpcy5zdWNjZXNzKSAgICAgICAgICB7CisgICAgICAgICAgICBfaXRlcjQ5LndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRSb3dXaXRoQ29sdW1uc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRSb3dUc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRSb3dUc19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUSU1FU1RBTVBfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRpbWVzdGFtcCIsIFRUeXBlLkk2NCwgKHNob3J0KTMpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworICAgIHB1YmxpYyBsb25nIHRpbWVzdGFtcDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVAgPSAzOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiB0aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChUSU1FU1RBTVAsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0aW1lc3RhbXAiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JNjQpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZ2V0Um93VHNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dUc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dUc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBsb25nIHRpbWVzdGFtcCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFJvd1RzX2FyZ3MoZ2V0Um93VHNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3coKSkgeworICAgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICAgIH0KKyAgICAgIF9faXNzZXQudGltZXN0YW1wID0gb3RoZXIuX19pc3NldC50aW1lc3RhbXA7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IG90aGVyLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Um93VHNfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZ2V0Um93VHNfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUaW1lc3RhbXAoKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVzdGFtcCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGltZXN0YW1wKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGltZXN0YW1wKChMb25nKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gZ2V0Um93KCk7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gbmV3IExvbmcoZ2V0VGltZXN0YW1wKCkpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZSgpOworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBpc1NldFJvdygpOworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBpc1NldFRpbWVzdGFtcCgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGdldFJvd1RzX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0Um93VHNfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0Um93VHNfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoaXMuaXNTZXRSb3coKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhhdC5pc1NldFJvdygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9yb3cgfHwgdGhhdF9wcmVzZW50X3JvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfcm93ICYmIHRoYXRfcHJlc2VudF9yb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnJvdywgdGhhdC5yb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RpbWVzdGFtcCB8fCB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgJiYgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy50aW1lc3RhbXAgIT0gdGhhdC50aW1lc3RhbXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMucm93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUSU1FU1RBTVBfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUk2NCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJnZXRSb3dUc19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgidGltZXN0YW1wOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMudGltZXN0YW1wKTsKKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGdldFJvd1RzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0Um93VHNfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNVQ0NFU1NfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN1Y2Nlc3MiLCBUVHlwZS5MSVNULCAoc2hvcnQpMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgVFJvd1Jlc3VsdC5jbGFzcykpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChnZXRSb3dUc19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZ2V0Um93VHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dUc19yZXN1bHQoCisgICAgICBMaXN0PFRSb3dSZXN1bHQ+IHN1Y2Nlc3MsCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBnZXRSb3dUc19yZXN1bHQoZ2V0Um93VHNfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgTGlzdDxUUm93UmVzdWx0PiBfX3RoaXNfX3N1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBvdGhlcl9lbGVtZW50IDogb3RoZXIuc3VjY2VzcykgeworICAgICAgICAgIF9fdGhpc19fc3VjY2Vzcy5hZGQobmV3IFRSb3dSZXN1bHQob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Um93VHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRSb3dUc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gMCA6IHRoaXMuc3VjY2Vzcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxUUm93UmVzdWx0PiBnZXRTdWNjZXNzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnN1Y2Nlc3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1N1Y2Nlc3MoVFJvd1Jlc3VsdCBlbGVtKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PigpOworICAgICAgfQorICAgICAgdGhpcy5zdWNjZXNzLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExpc3Q8VFJvd1Jlc3VsdD4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBnZXRTdWNjZXNzKCk7CisKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gaXNTZXRTdWNjZXNzKCk7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGdldFJvd1RzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRSb3dUc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGdldFJvd1RzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoaXMuaXNTZXRTdWNjZXNzKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3VjY2VzcygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5zdWNjZXNzLmVxdWFscyh0aGF0LnN1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0NTAgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PihfbGlzdDUwLnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pNTEgPSAwOyBfaTUxIDwgX2xpc3Q1MC5zaXplOyArK19pNTEpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgVFJvd1Jlc3VsdCBfZWxlbTUyOworICAgICAgICAgICAgICAgICAgX2VsZW01MiA9IG5ldyBUUm93UmVzdWx0KCk7CisgICAgICAgICAgICAgICAgICBfZWxlbTUyLnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzLmFkZChfZWxlbTUyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1VDQ0VTU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMuc3VjY2Vzcy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKFRSb3dSZXN1bHQgX2l0ZXI1MyA6IHRoaXMuc3VjY2VzcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXI1My53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZ2V0Um93VHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFJPV19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgicm93IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIENPTFVNTlNfRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbnMiLCBUVHlwZS5MSVNULCAoc2hvcnQpMyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRJTUVTVEFNUF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGltZXN0YW1wIiwgVFR5cGUuSTY0LCAoc2hvcnQpNCk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworICAgIHB1YmxpYyBieXRlW10gcm93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPVyA9IDI7CisgICAgcHVibGljIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTlMgPSAzOworICAgIHB1YmxpYyBsb25nIHRpbWVzdGFtcDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVAgPSA0OworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiB0aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChDT0xVTU5TLCBuZXcgRmllbGRNZXRhRGF0YSgiY29sdW1ucyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKSk7CisgICAgICBwdXQoVElNRVNUQU1QLCBuZXcgRmllbGRNZXRhRGF0YSgidGltZXN0YW1wIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTY0KSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGdldFJvd1dpdGhDb2x1bW5zVHNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zVHNfYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBieXRlW10gcm93LAorICAgICAgTGlzdDxieXRlW10+IGNvbHVtbnMsCisgICAgICBsb25nIHRpbWVzdGFtcCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MoZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Q29sdW1ucygpKSB7CisgICAgICAgIExpc3Q8Ynl0ZVtdPiBfX3RoaXNfX2NvbHVtbnMgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oKTsKKyAgICAgICAgZm9yIChieXRlW10gb3RoZXJfZWxlbWVudCA6IG90aGVyLmNvbHVtbnMpIHsKKyAgICAgICAgICBfX3RoaXNfX2NvbHVtbnMuYWRkKG90aGVyX2VsZW1lbnQpOworICAgICAgICB9CisgICAgICAgIHRoaXMuY29sdW1ucyA9IF9fdGhpc19fY29sdW1uczsKKyAgICAgIH0KKyAgICAgIF9faXNzZXQudGltZXN0YW1wID0gb3RoZXIuX19pc3NldC50aW1lc3RhbXA7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IG90aGVyLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbnNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0Q29sdW1uc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5jb2x1bW5zLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5zKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLmNvbHVtbnMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhMaXN0PGJ5dGVbXT4gY29sdW1ucykgeworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbnMoKSB7CisgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW5zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1ucyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMudGltZXN0YW1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChsb25nIHRpbWVzdGFtcCkgeworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRpbWVzdGFtcCgpIHsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGltZXN0YW1wIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXBJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldENvbHVtbnMoKExpc3Q8Ynl0ZVtdPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGltZXN0YW1wKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGltZXN0YW1wKChMb25nKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gZ2V0Um93KCk7CisKKyAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgcmV0dXJuIGdldENvbHVtbnMoKTsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBuZXcgTG9uZyhnZXRUaW1lc3RhbXAoKSk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93KCk7CisgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgIHJldHVybiBpc1NldENvbHVtbnMoKTsKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gaXNTZXRUaW1lc3RhbXAoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZ2V0Um93V2l0aENvbHVtbnNUc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhnZXRSb3dXaXRoQ29sdW1uc1RzX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbnMgPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW5zKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1ucygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW5zIHx8IHRoYXRfcHJlc2VudF9jb2x1bW5zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW5zICYmIHRoYXRfcHJlc2VudF9jb2x1bW5zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5jb2x1bW5zLmVxdWFscyh0aGF0LmNvbHVtbnMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RpbWVzdGFtcCB8fCB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgJiYgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy50aW1lc3RhbXAgIT0gdGhhdC50aW1lc3RhbXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMucm93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5MSVNUKSB7CisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBUTGlzdCBfbGlzdDU0ID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPihfbGlzdDU0LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pNTUgPSAwOyBfaTU1IDwgX2xpc3Q1NC5zaXplOyArK19pNTUpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgYnl0ZVtdIF9lbGVtNTY7CisgICAgICAgICAgICAgICAgICBfZWxlbTU2ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5zLmFkZChfZWxlbTU2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQ09MVU1OU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJJTkcsIHRoaXMuY29sdW1ucy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKGJ5dGVbXSBfaXRlcjU3IDogdGhpcy5jb2x1bW5zKSAgICAgICAgICB7CisgICAgICAgICAgICBvcHJvdC53cml0ZUJpbmFyeShfaXRlcjU3KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRJTUVTVEFNUF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFJvd1dpdGhDb2x1bW5zVHNfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInJvdzoiKTsKKyAgICAgIGlmICh0aGlzLnJvdyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMucm93KTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImNvbHVtbnM6Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5jb2x1bW5zKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInRpbWVzdGFtcDoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBnZXRSb3dXaXRoQ29sdW1uc1RzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZ2V0Um93V2l0aENvbHVtbnNUc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBUUm93UmVzdWx0LmNsYXNzKSkpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBnZXRSb3dXaXRoQ29sdW1uc1RzX3Jlc3VsdCgKKyAgICAgIExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0KGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgTGlzdDxUUm93UmVzdWx0PiBfX3RoaXNfX3N1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBvdGhlcl9lbGVtZW50IDogb3RoZXIuc3VjY2VzcykgeworICAgICAgICAgIF9fdGhpc19fc3VjY2Vzcy5hZGQobmV3IFRSb3dSZXN1bHQob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZ2V0Um93V2l0aENvbHVtbnNUc19yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3VjY2Vzc1NpemUoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IDAgOiB0aGlzLnN1Y2Nlc3Muc2l6ZSgpOworICAgIH0KKworICAgIHB1YmxpYyBqYXZhLnV0aWwuSXRlcmF0b3I8VFJvd1Jlc3VsdD4gZ2V0U3VjY2Vzc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5zdWNjZXNzLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9TdWNjZXNzKFRSb3dSZXN1bHQgZWxlbSkgeworICAgICAgaWYgKHRoaXMuc3VjY2VzcyA9PSBudWxsKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VFJvd1Jlc3VsdD4oKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuc3VjY2Vzcy5hZGQoZWxlbSk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhMaXN0PFRSb3dSZXN1bHQ+IHN1Y2Nlc3MpIHsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRTdWNjZXNzKCkgeworICAgICAgdGhpcy5zdWNjZXNzID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgc3VjY2VzcyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3MgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChMaXN0PFRSb3dSZXN1bHQ+KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gZ2V0U3VjY2VzcygpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3VjY2VzcygpOworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBnZXRSb3dXaXRoQ29sdW1uc1RzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChnZXRSb3dXaXRoQ29sdW1uc1RzX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZ2V0Um93V2l0aENvbHVtbnNUc19yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGlzLmlzU2V0U3VjY2VzcygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfc3VjY2VzcyA9IHRydWUgJiYgdGhhdC5pc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3VjY2VzcyB8fCB0aGF0X3ByZXNlbnRfc3VjY2VzcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3VjY2VzcyAmJiB0aGF0X3ByZXNlbnRfc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuc3VjY2Vzcy5lcXVhbHModGhhdC5zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5MSVNUKSB7CisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBUTGlzdCBfbGlzdDU4ID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMuc3VjY2VzcyA9IG5ldyBBcnJheUxpc3Q8VFJvd1Jlc3VsdD4oX2xpc3Q1OC5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTU5ID0gMDsgX2k1OSA8IF9saXN0NTguc2l6ZTsgKytfaTU5KQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIFRSb3dSZXN1bHQgX2VsZW02MDsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNjAgPSBuZXcgVFJvd1Jlc3VsdCgpOworICAgICAgICAgICAgICAgICAgX2VsZW02MC5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuc3VjY2Vzcy5hZGQoX2VsZW02MCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNVQ0NFU1NfRklFTERfREVTQyk7CisgICAgICAgIHsKKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihuZXcgVExpc3QoVFR5cGUuU1RSVUNULCB0aGlzLnN1Y2Nlc3Muc2l6ZSgpKSk7CisgICAgICAgICAgZm9yIChUUm93UmVzdWx0IF9pdGVyNjEgOiB0aGlzLnN1Y2Nlc3MpICAgICAgICAgIHsKKyAgICAgICAgICAgIF9pdGVyNjEud3JpdGUob3Byb3QpOworICAgICAgICAgIH0KKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImdldFJvd1dpdGhDb2x1bW5zVHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgbXV0YXRlUm93X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoIm11dGF0ZVJvd19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBNVVRBVElPTlNfRklFTERfREVTQyA9IG5ldyBURmllbGQoIm11dGF0aW9ucyIsIFRUeXBlLkxJU1QsIChzaG9ydCkzKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIGJ5dGVbXSByb3c7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9XID0gMjsKKyAgICBwdWJsaWMgTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1VVEFUSU9OUyA9IDM7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChNVVRBVElPTlMsIG5ldyBGaWVsZE1ldGFEYXRhKCJtdXRhdGlvbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgTXV0YXRpb24uY2xhc3MpKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKG11dGF0ZVJvd19hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dfYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBieXRlW10gcm93LAorICAgICAgTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIG11dGF0ZVJvd19hcmdzKG11dGF0ZVJvd19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0TXV0YXRpb25zKCkpIHsKKyAgICAgICAgTGlzdDxNdXRhdGlvbj4gX190aGlzX19tdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgICAgICBmb3IgKE11dGF0aW9uIG90aGVyX2VsZW1lbnQgOiBvdGhlci5tdXRhdGlvbnMpIHsKKyAgICAgICAgICBfX3RoaXNfX211dGF0aW9ucy5hZGQobmV3IE11dGF0aW9uKG90aGVyX2VsZW1lbnQpKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLm11dGF0aW9ucyA9IF9fdGhpc19fbXV0YXRpb25zOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBtdXRhdGVSb3dfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgbXV0YXRlUm93X2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE11dGF0aW9uc1NpemUoKSB7CisgICAgICByZXR1cm4gKHRoaXMubXV0YXRpb25zID09IG51bGwpID8gMCA6IHRoaXMubXV0YXRpb25zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPE11dGF0aW9uPiBnZXRNdXRhdGlvbnNJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5tdXRhdGlvbnMuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb011dGF0aW9ucyhNdXRhdGlvbiBlbGVtKSB7CisgICAgICBpZiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgeworICAgICAgICB0aGlzLm11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KCk7CisgICAgICB9CisgICAgICB0aGlzLm11dGF0aW9ucy5hZGQoZWxlbSk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8TXV0YXRpb24+IGdldE11dGF0aW9ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLm11dGF0aW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNdXRhdGlvbnMoTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zKSB7CisgICAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldE11dGF0aW9ucygpIHsKKyAgICAgIHRoaXMubXV0YXRpb25zID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgbXV0YXRpb25zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRNdXRhdGlvbnMoKSB7CisgICAgICByZXR1cm4gdGhpcy5tdXRhdGlvbnMgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNdXRhdGlvbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMubXV0YXRpb25zID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIE1VVEFUSU9OUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldE11dGF0aW9ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldE11dGF0aW9ucygoTGlzdDxNdXRhdGlvbj4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgY2FzZSBNVVRBVElPTlM6CisgICAgICAgIHJldHVybiBnZXRNdXRhdGlvbnMoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgTVVUQVRJT05TOgorICAgICAgICByZXR1cm4gaXNTZXRNdXRhdGlvbnMoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtdXRhdGVSb3dfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChtdXRhdGVSb3dfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMobXV0YXRlUm93X2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X211dGF0aW9ucyA9IHRydWUgJiYgdGhpcy5pc1NldE11dGF0aW9ucygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfbXV0YXRpb25zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0TXV0YXRpb25zKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X211dGF0aW9ucyB8fCB0aGF0X3ByZXNlbnRfbXV0YXRpb25zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tdXRhdGlvbnMgJiYgdGhhdF9wcmVzZW50X211dGF0aW9ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMubXV0YXRpb25zLmVxdWFscyh0aGF0Lm11dGF0aW9ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMucm93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIE1VVEFUSU9OUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0NjIgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5tdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPihfbGlzdDYyLnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pNjMgPSAwOyBfaTYzIDwgX2xpc3Q2Mi5zaXplOyArK19pNjMpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgTXV0YXRpb24gX2VsZW02NDsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNjQgPSBuZXcgTXV0YXRpb24oKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNjQucmVhZChpcHJvdCk7CisgICAgICAgICAgICAgICAgICB0aGlzLm11dGF0aW9ucy5hZGQoX2VsZW02NCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMubXV0YXRpb25zICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKE1VVEFUSU9OU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMubXV0YXRpb25zLnNpemUoKSkpOworICAgICAgICAgIGZvciAoTXV0YXRpb24gX2l0ZXI2NSA6IHRoaXMubXV0YXRpb25zKSAgICAgICAgICB7CisgICAgICAgICAgICBfaXRlcjY1LndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigibXV0YXRlUm93X2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJtdXRhdGlvbnM6Iik7CisgICAgICBpZiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLm11dGF0aW9ucyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBtdXRhdGVSb3dfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJtdXRhdGVSb3dfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJQV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWEiLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkyKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGlhOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElBID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgICAgcHV0KElBLCBuZXcgRmllbGRNZXRhRGF0YSgiaWEiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobXV0YXRlUm93X3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dfcmVzdWx0KAorICAgICAgSU9FcnJvciBpbywKKyAgICAgIElsbGVnYWxBcmd1bWVudCBpYSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dfcmVzdWx0KG11dGF0ZVJvd19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElhKCkpIHsKKyAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQob3RoZXIuaWEpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBtdXRhdGVSb3dfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBtdXRhdGVSb3dfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBnZXRJYSgpIHsKKyAgICAgIHJldHVybiB0aGlzLmlhOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgdGhpcy5pYSA9IGlhOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SWEoKSB7CisgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaWEgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWEgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJYUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pYSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElhKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SWEoKElsbGVnYWxBcmd1bWVudCl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGdldElhKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGlzU2V0SWEoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtdXRhdGVSb3dfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKG11dGF0ZVJvd19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKG11dGF0ZVJvd19yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pYSA9IHRydWUgJiYgdGhpcy5pc1NldElhKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pYSA9IHRydWUgJiYgdGhhdC5pc1NldElhKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lhIHx8IHRoYXRfcHJlc2VudF9pYSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaWEgJiYgdGhhdF9wcmVzZW50X2lhKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pYS5lcXVhbHModGhhdC5pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJQToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlhID0gbmV3IElsbGVnYWxBcmd1bWVudCgpOworICAgICAgICAgICAgICB0aGlzLmlhLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SWEoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSUFfRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaWEud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJtdXRhdGVSb3dfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaWE6Iik7CisgICAgICBpZiAodGhpcy5pYSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaWEpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgbXV0YXRlUm93VHNfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgibXV0YXRlUm93VHNfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJyb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTVVUQVRJT05TX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJtdXRhdGlvbnMiLCBUVHlwZS5MSVNULCAoc2hvcnQpMyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRJTUVTVEFNUF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGltZXN0YW1wIiwgVFR5cGUuSTY0LCAoc2hvcnQpNCk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworICAgIHB1YmxpYyBieXRlW10gcm93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPVyA9IDI7CisgICAgcHVibGljIExpc3Q8TXV0YXRpb24+IG11dGF0aW9uczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNVVRBVElPTlMgPSAzOworICAgIHB1YmxpYyBsb25nIHRpbWVzdGFtcDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVAgPSA0OworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiB0aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChNVVRBVElPTlMsIG5ldyBGaWVsZE1ldGFEYXRhKCJtdXRhdGlvbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgTXV0YXRpb24uY2xhc3MpKSkpOworICAgICAgcHV0KFRJTUVTVEFNUCwgbmV3IEZpZWxkTWV0YURhdGEoInRpbWVzdGFtcCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChtdXRhdGVSb3dUc19hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd1RzX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd1RzX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lLAorICAgICAgYnl0ZVtdIHJvdywKKyAgICAgIExpc3Q8TXV0YXRpb24+IG11dGF0aW9ucywKKyAgICAgIGxvbmcgdGltZXN0YW1wKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dUc19hcmdzKG11dGF0ZVJvd1RzX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Um93KCkpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBvdGhlci5yb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRNdXRhdGlvbnMoKSkgeworICAgICAgICBMaXN0PE11dGF0aW9uPiBfX3RoaXNfX211dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KCk7CisgICAgICAgIGZvciAoTXV0YXRpb24gb3RoZXJfZWxlbWVudCA6IG90aGVyLm11dGF0aW9ucykgeworICAgICAgICAgIF9fdGhpc19fbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24ob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMubXV0YXRpb25zID0gX190aGlzX19tdXRhdGlvbnM7CisgICAgICB9CisgICAgICBfX2lzc2V0LnRpbWVzdGFtcCA9IG90aGVyLl9faXNzZXQudGltZXN0YW1wOworICAgICAgdGhpcy50aW1lc3RhbXAgPSBvdGhlci50aW1lc3RhbXA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIG11dGF0ZVJvd1RzX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IG11dGF0ZVJvd1RzX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldE11dGF0aW9uc1NpemUoKSB7CisgICAgICByZXR1cm4gKHRoaXMubXV0YXRpb25zID09IG51bGwpID8gMCA6IHRoaXMubXV0YXRpb25zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPE11dGF0aW9uPiBnZXRNdXRhdGlvbnNJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5tdXRhdGlvbnMuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb011dGF0aW9ucyhNdXRhdGlvbiBlbGVtKSB7CisgICAgICBpZiAodGhpcy5tdXRhdGlvbnMgPT0gbnVsbCkgeworICAgICAgICB0aGlzLm11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KCk7CisgICAgICB9CisgICAgICB0aGlzLm11dGF0aW9ucy5hZGQoZWxlbSk7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8TXV0YXRpb24+IGdldE11dGF0aW9ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLm11dGF0aW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNdXRhdGlvbnMoTGlzdDxNdXRhdGlvbj4gbXV0YXRpb25zKSB7CisgICAgICB0aGlzLm11dGF0aW9ucyA9IG11dGF0aW9uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldE11dGF0aW9ucygpIHsKKyAgICAgIHRoaXMubXV0YXRpb25zID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgbXV0YXRpb25zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRNdXRhdGlvbnMoKSB7CisgICAgICByZXR1cm4gdGhpcy5tdXRhdGlvbnMgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRNdXRhdGlvbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMubXV0YXRpb25zID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGhpcy50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wKGxvbmcgdGltZXN0YW1wKSB7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGltZXN0YW1wKCkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0aW1lc3RhbXAgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLl9faXNzZXQudGltZXN0YW1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcElzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIE1VVEFUSU9OUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldE11dGF0aW9ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldE11dGF0aW9ucygoTGlzdDxNdXRhdGlvbj4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRpbWVzdGFtcCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRpbWVzdGFtcCgoTG9uZyl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFJvdygpOworCisgICAgICBjYXNlIE1VVEFUSU9OUzoKKyAgICAgICAgcmV0dXJuIGdldE11dGF0aW9ucygpOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgcmV0dXJuIG5ldyBMb25nKGdldFRpbWVzdGFtcCgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgTVVUQVRJT05TOgorICAgICAgICByZXR1cm4gaXNTZXRNdXRhdGlvbnMoKTsKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gaXNTZXRUaW1lc3RhbXAoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtdXRhdGVSb3dUc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKG11dGF0ZVJvd1RzX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKG11dGF0ZVJvd1RzX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X211dGF0aW9ucyA9IHRydWUgJiYgdGhpcy5pc1NldE11dGF0aW9ucygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfbXV0YXRpb25zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0TXV0YXRpb25zKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X211dGF0aW9ucyB8fCB0aGF0X3ByZXNlbnRfbXV0YXRpb25zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9tdXRhdGlvbnMgJiYgdGhhdF9wcmVzZW50X211dGF0aW9ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMubXV0YXRpb25zLmVxdWFscyh0aGF0Lm11dGF0aW9ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGltZXN0YW1wIHx8IHRoYXRfcHJlc2VudF90aW1lc3RhbXApIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RpbWVzdGFtcCAmJiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCAhPSB0aGF0LnRpbWVzdGFtcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgTVVUQVRJT05TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q2NiA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLm11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8TXV0YXRpb24+KF9saXN0NjYuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2k2NyA9IDA7IF9pNjcgPCBfbGlzdDY2LnNpemU7ICsrX2k2NykKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBNdXRhdGlvbiBfZWxlbTY4OworICAgICAgICAgICAgICAgICAgX2VsZW02OCA9IG5ldyBNdXRhdGlvbigpOworICAgICAgICAgICAgICAgICAgX2VsZW02OC5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICAgIHRoaXMubXV0YXRpb25zLmFkZChfZWxlbTY4KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLm11dGF0aW9ucyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihNVVRBVElPTlNfRklFTERfREVTQyk7CisgICAgICAgIHsKKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RCZWdpbihuZXcgVExpc3QoVFR5cGUuU1RSVUNULCB0aGlzLm11dGF0aW9ucy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKE11dGF0aW9uIF9pdGVyNjkgOiB0aGlzLm11dGF0aW9ucykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXI2OS53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUSU1FU1RBTVBfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUk2NCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJtdXRhdGVSb3dUc19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgibXV0YXRpb25zOiIpOworICAgICAgaWYgKHRoaXMubXV0YXRpb25zID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5tdXRhdGlvbnMpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgidGltZXN0YW1wOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMudGltZXN0YW1wKTsKKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIG11dGF0ZVJvd1RzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgibXV0YXRlUm93VHNfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJQV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWEiLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkyKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGlhOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElBID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgICAgcHV0KElBLCBuZXcgRmllbGRNZXRhRGF0YSgiaWEiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobXV0YXRlUm93VHNfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd1RzX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgbXV0YXRlUm93VHNfcmVzdWx0KAorICAgICAgSU9FcnJvciBpbywKKyAgICAgIElsbGVnYWxBcmd1bWVudCBpYSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dUc19yZXN1bHQobXV0YXRlUm93VHNfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJYSgpKSB7CisgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KG90aGVyLmlhKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbXV0YXRlUm93VHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBtdXRhdGVSb3dUc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElBOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SWEoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJYSgoSWxsZWdhbEFyZ3VtZW50KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gZ2V0SWEoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gaXNTZXRJYSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIG11dGF0ZVJvd1RzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChtdXRhdGVSb3dUc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKG11dGF0ZVJvd1RzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SWEoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SWEoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaWEgfHwgdGhhdF9wcmVzZW50X2lhKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pYSAmJiB0aGF0X3ByZXNlbnRfaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlhLmVxdWFscyh0aGF0LmlhKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElBOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KCk7CisgICAgICAgICAgICAgIHRoaXMuaWEucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIm11dGF0ZVJvd1RzX3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlhOiIpOworICAgICAgaWYgKHRoaXMuaWEgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlhKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIG11dGF0ZVJvd3NfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgibXV0YXRlUm93c19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfQkFUQ0hFU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgicm93QmF0Y2hlcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkyKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1dCQVRDSEVTID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoUk9XQkFUQ0hFUywgbmV3IEZpZWxkTWV0YURhdGEoInJvd0JhdGNoZXMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgQmF0Y2hNdXRhdGlvbi5jbGFzcykpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobXV0YXRlUm93c19hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd3NfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgbXV0YXRlUm93c19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMucm93QmF0Y2hlcyA9IHJvd0JhdGNoZXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dzX2FyZ3MobXV0YXRlUm93c19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvd0JhdGNoZXMoKSkgeworICAgICAgICBMaXN0PEJhdGNoTXV0YXRpb24+IF9fdGhpc19fcm93QmF0Y2hlcyA9IG5ldyBBcnJheUxpc3Q8QmF0Y2hNdXRhdGlvbj4oKTsKKyAgICAgICAgZm9yIChCYXRjaE11dGF0aW9uIG90aGVyX2VsZW1lbnQgOiBvdGhlci5yb3dCYXRjaGVzKSB7CisgICAgICAgICAgX190aGlzX19yb3dCYXRjaGVzLmFkZChuZXcgQmF0Y2hNdXRhdGlvbihvdGhlcl9lbGVtZW50KSk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5yb3dCYXRjaGVzID0gX190aGlzX19yb3dCYXRjaGVzOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBtdXRhdGVSb3dzX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IG11dGF0ZVJvd3NfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRSb3dCYXRjaGVzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5yb3dCYXRjaGVzID09IG51bGwpID8gMCA6IHRoaXMucm93QmF0Y2hlcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxCYXRjaE11dGF0aW9uPiBnZXRSb3dCYXRjaGVzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMucm93QmF0Y2hlcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnJvd0JhdGNoZXMuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1Jvd0JhdGNoZXMoQmF0Y2hNdXRhdGlvbiBlbGVtKSB7CisgICAgICBpZiAodGhpcy5yb3dCYXRjaGVzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5yb3dCYXRjaGVzID0gbmV3IEFycmF5TGlzdDxCYXRjaE11dGF0aW9uPigpOworICAgICAgfQorICAgICAgdGhpcy5yb3dCYXRjaGVzLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxCYXRjaE11dGF0aW9uPiBnZXRSb3dCYXRjaGVzKCkgeworICAgICAgcmV0dXJuIHRoaXMucm93QmF0Y2hlczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dCYXRjaGVzKExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcykgeworICAgICAgdGhpcy5yb3dCYXRjaGVzID0gcm93QmF0Y2hlczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvd0JhdGNoZXMoKSB7CisgICAgICB0aGlzLnJvd0JhdGNoZXMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3dCYXRjaGVzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3dCYXRjaGVzKCkgeworICAgICAgcmV0dXJuIHRoaXMucm93QmF0Y2hlcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0JhdGNoZXNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93QmF0Y2hlcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPV0JBVENIRVM6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRSb3dCYXRjaGVzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93QmF0Y2hlcygoTGlzdDxCYXRjaE11dGF0aW9uPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFJPV0JBVENIRVM6CisgICAgICAgIHJldHVybiBnZXRSb3dCYXRjaGVzKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPV0JBVENIRVM6CisgICAgICAgIHJldHVybiBpc1NldFJvd0JhdGNoZXMoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtdXRhdGVSb3dzX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygobXV0YXRlUm93c19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhtdXRhdGVSb3dzX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93QmF0Y2hlcyA9IHRydWUgJiYgdGhpcy5pc1NldFJvd0JhdGNoZXMoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3Jvd0JhdGNoZXMgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3dCYXRjaGVzKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3Jvd0JhdGNoZXMgfHwgdGhhdF9wcmVzZW50X3Jvd0JhdGNoZXMpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3Jvd0JhdGNoZXMgJiYgdGhhdF9wcmVzZW50X3Jvd0JhdGNoZXMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLnJvd0JhdGNoZXMuZXF1YWxzKHRoYXQucm93QmF0Y2hlcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XQkFUQ0hFUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0NzAgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5yb3dCYXRjaGVzID0gbmV3IEFycmF5TGlzdDxCYXRjaE11dGF0aW9uPihfbGlzdDcwLnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pNzEgPSAwOyBfaTcxIDwgX2xpc3Q3MC5zaXplOyArK19pNzEpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgQmF0Y2hNdXRhdGlvbiBfZWxlbTcyOworICAgICAgICAgICAgICAgICAgX2VsZW03MiA9IG5ldyBCYXRjaE11dGF0aW9uKCk7CisgICAgICAgICAgICAgICAgICBfZWxlbTcyLnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgICAgdGhpcy5yb3dCYXRjaGVzLmFkZChfZWxlbTcyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMucm93QmF0Y2hlcyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfQkFUQ0hFU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMucm93QmF0Y2hlcy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKEJhdGNoTXV0YXRpb24gX2l0ZXI3MyA6IHRoaXMucm93QmF0Y2hlcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXI3My53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIm11dGF0ZVJvd3NfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInJvd0JhdGNoZXM6Iik7CisgICAgICBpZiAodGhpcy5yb3dCYXRjaGVzID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3dCYXRjaGVzKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIG11dGF0ZVJvd3NfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJtdXRhdGVSb3dzX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSUFfRklFTERfREVTQyA9IG5ldyBURmllbGQoImlhIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMik7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBpYTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJQSA9IDI7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICAgIHB1dChJQSwgbmV3IEZpZWxkTWV0YURhdGEoImlhIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKG11dGF0ZVJvd3NfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd3NfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dzX3Jlc3VsdCgKKyAgICAgIElPRXJyb3IgaW8sCisgICAgICBJbGxlZ2FsQXJndW1lbnQgaWEpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pbyA9IGlvOworICAgICAgdGhpcy5pYSA9IGlhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgbXV0YXRlUm93c19yZXN1bHQobXV0YXRlUm93c19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElhKCkpIHsKKyAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQob3RoZXIuaWEpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBtdXRhdGVSb3dzX3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgbXV0YXRlUm93c19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElBOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SWEoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJYSgoSWxsZWdhbEFyZ3VtZW50KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gZ2V0SWEoKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gaXNTZXRJYSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIG11dGF0ZVJvd3NfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKG11dGF0ZVJvd3NfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhtdXRhdGVSb3dzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SWEoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lhID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SWEoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaWEgfHwgdGhhdF9wcmVzZW50X2lhKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pYSAmJiB0aGF0X3ByZXNlbnRfaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlhLmVxdWFscyh0aGF0LmlhKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElBOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KCk7CisgICAgICAgICAgICAgIHRoaXMuaWEucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIm11dGF0ZVJvd3NfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaWE6Iik7CisgICAgICBpZiAodGhpcy5pYSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaWEpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgbXV0YXRlUm93c1RzX2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoIm11dGF0ZVJvd3NUc19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfQkFUQ0hFU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgicm93QmF0Y2hlcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVElNRVNUQU1QX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0aW1lc3RhbXAiLCBUVHlwZS5JNjQsIChzaG9ydCkzKTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1dCQVRDSEVTID0gMjsKKyAgICBwdWJsaWMgbG9uZyB0aW1lc3RhbXA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVElNRVNUQU1QID0gMzsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgcHVibGljIGJvb2xlYW4gdGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChST1dCQVRDSEVTLCBuZXcgRmllbGRNZXRhRGF0YSgicm93QmF0Y2hlcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBCYXRjaE11dGF0aW9uLmNsYXNzKSkpKTsKKyAgICAgIHB1dChUSU1FU1RBTVAsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0aW1lc3RhbXAiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JNjQpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobXV0YXRlUm93c1RzX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgbXV0YXRlUm93c1RzX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIG11dGF0ZVJvd3NUc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIExpc3Q8QmF0Y2hNdXRhdGlvbj4gcm93QmF0Y2hlcywKKyAgICAgIGxvbmcgdGltZXN0YW1wKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3dCYXRjaGVzID0gcm93QmF0Y2hlczsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dzVHNfYXJncyhtdXRhdGVSb3dzVHNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3dCYXRjaGVzKCkpIHsKKyAgICAgICAgTGlzdDxCYXRjaE11dGF0aW9uPiBfX3RoaXNfX3Jvd0JhdGNoZXMgPSBuZXcgQXJyYXlMaXN0PEJhdGNoTXV0YXRpb24+KCk7CisgICAgICAgIGZvciAoQmF0Y2hNdXRhdGlvbiBvdGhlcl9lbGVtZW50IDogb3RoZXIucm93QmF0Y2hlcykgeworICAgICAgICAgIF9fdGhpc19fcm93QmF0Y2hlcy5hZGQobmV3IEJhdGNoTXV0YXRpb24ob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMucm93QmF0Y2hlcyA9IF9fdGhpc19fcm93QmF0Y2hlczsKKyAgICAgIH0KKyAgICAgIF9faXNzZXQudGltZXN0YW1wID0gb3RoZXIuX19pc3NldC50aW1lc3RhbXA7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IG90aGVyLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbXV0YXRlUm93c1RzX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IG11dGF0ZVJvd3NUc19hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldFJvd0JhdGNoZXNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLnJvd0JhdGNoZXMgPT0gbnVsbCkgPyAwIDogdGhpcy5yb3dCYXRjaGVzLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPEJhdGNoTXV0YXRpb24+IGdldFJvd0JhdGNoZXNJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5yb3dCYXRjaGVzID09IG51bGwpID8gbnVsbCA6IHRoaXMucm93QmF0Y2hlcy5pdGVyYXRvcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZFRvUm93QmF0Y2hlcyhCYXRjaE11dGF0aW9uIGVsZW0pIHsKKyAgICAgIGlmICh0aGlzLnJvd0JhdGNoZXMgPT0gbnVsbCkgeworICAgICAgICB0aGlzLnJvd0JhdGNoZXMgPSBuZXcgQXJyYXlMaXN0PEJhdGNoTXV0YXRpb24+KCk7CisgICAgICB9CisgICAgICB0aGlzLnJvd0JhdGNoZXMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PEJhdGNoTXV0YXRpb24+IGdldFJvd0JhdGNoZXMoKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3dCYXRjaGVzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0JhdGNoZXMoTGlzdDxCYXRjaE11dGF0aW9uPiByb3dCYXRjaGVzKSB7CisgICAgICB0aGlzLnJvd0JhdGNoZXMgPSByb3dCYXRjaGVzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Um93QmF0Y2hlcygpIHsKKyAgICAgIHRoaXMucm93QmF0Y2hlcyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHJvd0JhdGNoZXMgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFJvd0JhdGNoZXMoKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3dCYXRjaGVzICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93QmF0Y2hlc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5yb3dCYXRjaGVzID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGhpcy50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wKGxvbmcgdGltZXN0YW1wKSB7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGltZXN0YW1wKCkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0aW1lc3RhbXAgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLl9faXNzZXQudGltZXN0YW1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcElzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XQkFUQ0hFUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvd0JhdGNoZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRSb3dCYXRjaGVzKChMaXN0PEJhdGNoTXV0YXRpb24+KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUaW1lc3RhbXAoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUaW1lc3RhbXAoKExvbmcpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1dCQVRDSEVTOgorICAgICAgICByZXR1cm4gZ2V0Um93QmF0Y2hlcygpOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgcmV0dXJuIG5ldyBMb25nKGdldFRpbWVzdGFtcCgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XQkFUQ0hFUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93QmF0Y2hlcygpOworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBpc1NldFRpbWVzdGFtcCgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIG11dGF0ZVJvd3NUc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKG11dGF0ZVJvd3NUc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhtdXRhdGVSb3dzVHNfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9yb3dCYXRjaGVzID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93QmF0Y2hlcygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93QmF0Y2hlcyA9IHRydWUgJiYgdGhhdC5pc1NldFJvd0JhdGNoZXMoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93QmF0Y2hlcyB8fCB0aGF0X3ByZXNlbnRfcm93QmF0Y2hlcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfcm93QmF0Y2hlcyAmJiB0aGF0X3ByZXNlbnRfcm93QmF0Y2hlcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMucm93QmF0Y2hlcy5lcXVhbHModGhhdC5yb3dCYXRjaGVzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgfHwgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGltZXN0YW1wICYmIHRoYXRfcHJlc2VudF90aW1lc3RhbXApKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHRoaXMudGltZXN0YW1wICE9IHRoYXQudGltZXN0YW1wKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJPV0JBVENIRVM6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5MSVNUKSB7CisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBUTGlzdCBfbGlzdDc0ID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMucm93QmF0Y2hlcyA9IG5ldyBBcnJheUxpc3Q8QmF0Y2hNdXRhdGlvbj4oX2xpc3Q3NC5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTc1ID0gMDsgX2k3NSA8IF9saXN0NzQuc2l6ZTsgKytfaTc1KQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIEJhdGNoTXV0YXRpb24gX2VsZW03NjsKKyAgICAgICAgICAgICAgICAgIF9lbGVtNzYgPSBuZXcgQmF0Y2hNdXRhdGlvbigpOworICAgICAgICAgICAgICAgICAgX2VsZW03Ni5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICAgIHRoaXMucm93QmF0Y2hlcy5hZGQoX2VsZW03Nik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JNjQpIHsKKyAgICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMucm93QmF0Y2hlcyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfQkFUQ0hFU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMucm93QmF0Y2hlcy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKEJhdGNoTXV0YXRpb24gX2l0ZXI3NyA6IHRoaXMucm93QmF0Y2hlcykgICAgICAgICAgeworICAgICAgICAgICAgX2l0ZXI3Ny53cml0ZShvcHJvdCk7CisgICAgICAgICAgfQorICAgICAgICAgIG9wcm90LndyaXRlTGlzdEVuZCgpOworICAgICAgICB9CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUSU1FU1RBTVBfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUk2NCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJtdXRhdGVSb3dzVHNfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInJvd0JhdGNoZXM6Iik7CisgICAgICBpZiAodGhpcy5yb3dCYXRjaGVzID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3dCYXRjaGVzKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInRpbWVzdGFtcDoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBtdXRhdGVSb3dzVHNfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJtdXRhdGVSb3dzVHNfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJQV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWEiLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkyKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGlhOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElBID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgICAgcHV0KElBLCBuZXcgRmllbGRNZXRhRGF0YSgiaWEiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAobXV0YXRlUm93c1RzX3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dzVHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBtdXRhdGVSb3dzVHNfcmVzdWx0KAorICAgICAgSU9FcnJvciBpbywKKyAgICAgIElsbGVnYWxBcmd1bWVudCBpYSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBtdXRhdGVSb3dzVHNfcmVzdWx0KG11dGF0ZVJvd3NUc19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElhKCkpIHsKKyAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQob3RoZXIuaWEpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBtdXRhdGVSb3dzVHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBtdXRhdGVSb3dzVHNfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBnZXRJYSgpIHsKKyAgICAgIHJldHVybiB0aGlzLmlhOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhKElsbGVnYWxBcmd1bWVudCBpYSkgeworICAgICAgdGhpcy5pYSA9IGlhOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SWEoKSB7CisgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaWEgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWEgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJYUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pYSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElhKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SWEoKElsbGVnYWxBcmd1bWVudCl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGdldElhKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGlzU2V0SWEoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBtdXRhdGVSb3dzVHNfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKG11dGF0ZVJvd3NUc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKG11dGF0ZVJvd3NUc19yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pYSA9IHRydWUgJiYgdGhpcy5pc1NldElhKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pYSA9IHRydWUgJiYgdGhhdC5pc1NldElhKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lhIHx8IHRoYXRfcHJlc2VudF9pYSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaWEgJiYgdGhhdF9wcmVzZW50X2lhKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pYS5lcXVhbHModGhhdC5pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJQToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlhID0gbmV3IElsbGVnYWxBcmd1bWVudCgpOworICAgICAgICAgICAgICB0aGlzLmlhLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SWEoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSUFfRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaWEud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJtdXRhdGVSb3dzVHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaWE6Iik7CisgICAgICBpZiAodGhpcy5pYSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaWEpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgYXRvbWljSW5jcmVtZW50X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImF0b21pY0luY3JlbWVudF9hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT0xVTU5fRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbiIsIFRUeXBlLlNUUklORywgKHNob3J0KTMpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBWQUxVRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidmFsdWUiLCBUVHlwZS5JNjQsIChzaG9ydCk0KTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIGJ5dGVbXSByb3c7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUk9XID0gMjsKKyAgICBwdWJsaWMgYnl0ZVtdIGNvbHVtbjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0xVTU4gPSAzOworICAgIHB1YmxpYyBsb25nIHZhbHVlOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFID0gNDsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgcHVibGljIGJvb2xlYW4gdmFsdWUgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInJvdyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChDT0xVTU4sIG5ldyBGaWVsZE1ldGFEYXRhKCJjb2x1bW4iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoVkFMVUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ2YWx1ZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChhdG9taWNJbmNyZW1lbnRfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBhdG9taWNJbmNyZW1lbnRfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgYXRvbWljSW5jcmVtZW50X2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lLAorICAgICAgYnl0ZVtdIHJvdywKKyAgICAgIGJ5dGVbXSBjb2x1bW4sCisgICAgICBsb25nIHZhbHVlKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgIHRoaXMuX19pc3NldC52YWx1ZSA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBhdG9taWNJbmNyZW1lbnRfYXJncyhhdG9taWNJbmNyZW1lbnRfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3coKSkgeworICAgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldENvbHVtbigpKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gb3RoZXIuY29sdW1uOworICAgICAgfQorICAgICAgX19pc3NldC52YWx1ZSA9IG90aGVyLl9faXNzZXQudmFsdWU7CisgICAgICB0aGlzLnZhbHVlID0gb3RoZXIudmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGF0b21pY0luY3JlbWVudF9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBhdG9taWNJbmNyZW1lbnRfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICAgIHRoaXMucm93ID0gcm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Q29sdW1uKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbihieXRlW10gY29sdW1uKSB7CisgICAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbigpIHsKKyAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29sdW1uIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW4gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgbG9uZyBnZXRWYWx1ZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGxvbmcgdmFsdWUpIHsKKyAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgIHRoaXMuX19pc3NldC52YWx1ZSA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRWYWx1ZSgpIHsKKyAgICAgIHRoaXMuX19pc3NldC52YWx1ZSA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB2YWx1ZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VmFsdWUoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRDb2x1bW4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRDb2x1bW4oKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRWYWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFZhbHVlKChMb25nKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gZ2V0Um93KCk7CisKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1uKCk7CisKKyAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgIHJldHVybiBuZXcgTG9uZyhnZXRWYWx1ZSgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gaXNTZXRDb2x1bW4oKTsKKyAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgIHJldHVybiBpc1NldFZhbHVlKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgYXRvbWljSW5jcmVtZW50X2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoYXRvbWljSW5jcmVtZW50X2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGF0b21pY0luY3JlbWVudF9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhpcy5pc1NldFJvdygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3JvdyB8fCB0aGF0X3ByZXNlbnRfcm93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9yb3cgJiYgdGhhdF9wcmVzZW50X3JvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMucm93LCB0aGF0LnJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9jb2x1bW4gPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW4oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbHVtbiA9IHRydWUgJiYgdGhhdC5pc1NldENvbHVtbigpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW4gfHwgdGhhdF9wcmVzZW50X2NvbHVtbikgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfY29sdW1uICYmIHRoYXRfcHJlc2VudF9jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLmNvbHVtbiwgdGhhdC5jb2x1bW4pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdmFsdWUgPSB0cnVlOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdmFsdWUgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF92YWx1ZSB8fCB0aGF0X3ByZXNlbnRfdmFsdWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3ZhbHVlICYmIHRoYXRfcHJlc2VudF92YWx1ZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy52YWx1ZSAhPSB0aGF0LnZhbHVlKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJPVzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5jb2x1bW4gPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JNjQpIHsKKyAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnZhbHVlID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuY29sdW1uICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKENPTFVNTl9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5jb2x1bW4pOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVkFMVUVfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUk2NCh0aGlzLnZhbHVlKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImF0b21pY0luY3JlbWVudF9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiY29sdW1uOiIpOworICAgICAgaWYgKHRoaXMuY29sdW1uID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5jb2x1bW4pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgidmFsdWU6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy52YWx1ZSk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBhdG9taWNJbmNyZW1lbnRfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJhdG9taWNJbmNyZW1lbnRfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNVQ0NFU1NfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN1Y2Nlc3MiLCBUVHlwZS5JNjQsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElBX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpYSIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTIpOworCisgICAgcHVibGljIGxvbmcgc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBpYTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJQSA9IDI7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JNjQpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICAgIHB1dChJQSwgbmV3IEZpZWxkTWV0YURhdGEoImlhIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGF0b21pY0luY3JlbWVudF9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYXRvbWljSW5jcmVtZW50X3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgYXRvbWljSW5jcmVtZW50X3Jlc3VsdCgKKyAgICAgIGxvbmcgc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8sCisgICAgICBJbGxlZ2FsQXJndW1lbnQgaWEpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICAgIHRoaXMuaWEgPSBpYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGF0b21pY0luY3JlbWVudF9yZXN1bHQoYXRvbWljSW5jcmVtZW50X3Jlc3VsdCBvdGhlcikgeworICAgICAgX19pc3NldC5zdWNjZXNzID0gb3RoZXIuX19pc3NldC5zdWNjZXNzOworICAgICAgdGhpcy5zdWNjZXNzID0gb3RoZXIuc3VjY2VzczsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElhKCkpIHsKKyAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQob3RoZXIuaWEpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBhdG9taWNJbmNyZW1lbnRfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBhdG9taWNJbmNyZW1lbnRfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3MobG9uZyBzdWNjZXNzKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3VjY2VzcygpIHsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN1Y2Nlc3MgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2Vzc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExvbmcpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJYSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElhKChJbGxlZ2FsQXJndW1lbnQpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gbmV3IExvbmcoZ2V0U3VjY2VzcygpKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIHJldHVybiBnZXRJYSgpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gaXNTZXRTdWNjZXNzKCk7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGlzU2V0SWEoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBhdG9taWNJbmNyZW1lbnRfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGF0b21pY0luY3JlbWVudF9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGF0b21pY0luY3JlbWVudF9yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgIT0gdGhhdC5zdWNjZXNzKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoaXMuaXNTZXRJYSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoYXQuaXNTZXRJYSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pYSB8fCB0aGF0X3ByZXNlbnRfaWEpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lhICYmIHRoYXRfcHJlc2VudF9pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaWEuZXF1YWxzKHRoYXQuaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJQToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlhID0gbmV3IElsbGVnYWxBcmd1bWVudCgpOworICAgICAgICAgICAgICB0aGlzLmlhLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1VDQ0VTU19GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVJNjQodGhpcy5zdWNjZXNzKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImF0b21pY0luY3JlbWVudF9yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpYToiKTsKKyAgICAgIGlmICh0aGlzLmlhID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pYSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBkZWxldGVBbGxfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZGVsZXRlQWxsX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFJPV19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgicm93IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIENPTFVNTl9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1uIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMyk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworICAgIHB1YmxpYyBieXRlW10gcm93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPVyA9IDI7CisgICAgcHVibGljIGJ5dGVbXSBjb2x1bW47CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OID0gMzsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgicm93IiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KENPTFVNTiwgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbiIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVBbGxfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVBbGxfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lLAorICAgICAgYnl0ZVtdIHJvdywKKyAgICAgIGJ5dGVbXSBjb2x1bW4pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZGVsZXRlQWxsX2FyZ3MoZGVsZXRlQWxsX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0Um93KCkpIHsKKyAgICAgICAgdGhpcy5yb3cgPSBvdGhlci5yb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRDb2x1bW4oKSkgeworICAgICAgICB0aGlzLmNvbHVtbiA9IG90aGVyLmNvbHVtbjsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZGVsZXRlQWxsX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGRlbGV0ZUFsbF9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3coYnl0ZVtdIHJvdykgeworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRSb3coKSB7CisgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uKGJ5dGVbXSBjb2x1bW4pIHsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1uKCkgeworICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW4gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldENvbHVtbigpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbiAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbklzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1uKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Q29sdW1uKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgY2FzZSBDT0xVTU46CisgICAgICAgIHJldHVybiBnZXRDb2x1bW4oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gaXNTZXRDb2x1bW4oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBkZWxldGVBbGxfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVBbGxfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZGVsZXRlQWxsX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbiA9IHRydWUgJiYgdGhpcy5pc1NldENvbHVtbigpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfY29sdW1uID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1uKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2NvbHVtbiB8fCB0aGF0X3ByZXNlbnRfY29sdW1uKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW4gJiYgdGhhdF9wcmVzZW50X2NvbHVtbikpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuY29sdW1uLCB0aGF0LmNvbHVtbikpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMucm93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLmNvbHVtbiA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuY29sdW1uICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKENPTFVNTl9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5jb2x1bW4pOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJkZWxldGVBbGxfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInJvdzoiKTsKKyAgICAgIGlmICh0aGlzLnJvdyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMucm93KTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImNvbHVtbjoiKTsKKyAgICAgIGlmICh0aGlzLmNvbHVtbiA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuY29sdW1uKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGRlbGV0ZUFsbF9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImRlbGV0ZUFsbF9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVBbGxfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGRlbGV0ZUFsbF9yZXN1bHQoKSB7CisgICAgfQorCisgICAgcHVibGljIGRlbGV0ZUFsbF9yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZUFsbF9yZXN1bHQoZGVsZXRlQWxsX3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkZWxldGVBbGxfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVBbGxfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJbygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElvKChJT0Vycm9yKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBnZXRJbygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBkZWxldGVBbGxfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGRlbGV0ZUFsbF9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRlbGV0ZUFsbF9yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhpcy5pc1NldElvKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pbyA9IHRydWUgJiYgdGhhdC5pc1NldElvKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lvIHx8IHRoYXRfcHJlc2VudF9pbykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaW8gJiYgdGhhdF9wcmVzZW50X2lvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5pby5lcXVhbHModGhhdC5pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImRlbGV0ZUFsbF9yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBkZWxldGVBbGxUc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJkZWxldGVBbGxUc19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT0xVTU5fRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbiIsIFRUeXBlLlNUUklORywgKHNob3J0KTMpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUSU1FU1RBTVBfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRpbWVzdGFtcCIsIFRUeXBlLkk2NCwgKHNob3J0KTQpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworICAgIHB1YmxpYyBieXRlW10gY29sdW1uOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTiA9IDM7CisgICAgcHVibGljIGxvbmcgdGltZXN0YW1wOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUCA9IDQ7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHRpbWVzdGFtcCA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgicm93IiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KENPTFVNTiwgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbiIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChUSU1FU1RBTVAsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0aW1lc3RhbXAiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JNjQpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZGVsZXRlQWxsVHNfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVBbGxUc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVBbGxUc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3csCisgICAgICBieXRlW10gY29sdW1uLAorICAgICAgbG9uZyB0aW1lc3RhbXApCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZUFsbFRzX2FyZ3MoZGVsZXRlQWxsVHNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRSb3coKSkgeworICAgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldENvbHVtbigpKSB7CisgICAgICAgIHRoaXMuY29sdW1uID0gb3RoZXIuY29sdW1uOworICAgICAgfQorICAgICAgX19pc3NldC50aW1lc3RhbXAgPSBvdGhlci5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gb3RoZXIudGltZXN0YW1wOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkZWxldGVBbGxUc19hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVBbGxUc19hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3coYnl0ZVtdIHJvdykgeworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRSb3coKSB7CisgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRDb2x1bW4oKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW47CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uKGJ5dGVbXSBjb2x1bW4pIHsKKyAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1uKCkgeworICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW4gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldENvbHVtbigpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbiAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbklzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUaW1lc3RhbXAoKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVzdGFtcCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1uKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Q29sdW1uKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRpbWVzdGFtcCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRpbWVzdGFtcCgoTG9uZyl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFJvdygpOworCisgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgcmV0dXJuIGdldENvbHVtbigpOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgcmV0dXJuIG5ldyBMb25nKGdldFRpbWVzdGFtcCgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICByZXR1cm4gaXNTZXRDb2x1bW4oKTsKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gaXNTZXRUaW1lc3RhbXAoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBkZWxldGVBbGxUc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKGRlbGV0ZUFsbFRzX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRlbGV0ZUFsbFRzX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbiA9IHRydWUgJiYgdGhpcy5pc1NldENvbHVtbigpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfY29sdW1uID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1uKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2NvbHVtbiB8fCB0aGF0X3ByZXNlbnRfY29sdW1uKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW4gJiYgdGhhdF9wcmVzZW50X2NvbHVtbikpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuY29sdW1uLCB0aGF0LmNvbHVtbikpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGltZXN0YW1wIHx8IHRoYXRfcHJlc2VudF90aW1lc3RhbXApIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RpbWVzdGFtcCAmJiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCAhPSB0aGF0LnRpbWVzdGFtcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgQ09MVU1OOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMuY29sdW1uID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9IGlwcm90LnJlYWRJNjQoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbiAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5fRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuY29sdW1uKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRJTUVTVEFNUF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImRlbGV0ZUFsbFRzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW46Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW4gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbik7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJ0aW1lc3RhbXA6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy50aW1lc3RhbXApOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlQWxsVHNfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJkZWxldGVBbGxUc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVBbGxUc19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsVHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVBbGxUc19yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZUFsbFRzX3Jlc3VsdChkZWxldGVBbGxUc19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZGVsZXRlQWxsVHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVBbGxUc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRlbGV0ZUFsbFRzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVBbGxUc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRlbGV0ZUFsbFRzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZGVsZXRlQWxsVHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlQWxsUm93X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImRlbGV0ZUFsbFJvd19hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAyOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJyb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoZGVsZXRlQWxsUm93X2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93X2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSByb3cpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd19hcmdzKGRlbGV0ZUFsbFJvd19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkZWxldGVBbGxSb3dfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgZGVsZXRlQWxsUm93X2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhieXRlW10gcm93KSB7CisgICAgICB0aGlzLnJvdyA9IHJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFJvdygpIHsKKyAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgcm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5yb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMucm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUYWJsZU5hbWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUYWJsZU5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Um93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgUk9XOgorICAgICAgICByZXR1cm4gaXNTZXRSb3coKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBkZWxldGVBbGxSb3dfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVBbGxSb3dfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZGVsZXRlQWxsUm93X2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldFRhYmxlTmFtZSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgfHwgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGFibGVOYW1lICYmIHRoYXRfcHJlc2VudF90YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnRhYmxlTmFtZSwgdGhhdC50YWJsZU5hbWUpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9yb3cgPSB0cnVlICYmIHRoYXQuaXNTZXRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfcm93IHx8IHRoYXRfcHJlc2VudF9yb3cpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5yb3csIHRoYXQucm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgdmFsaWRhdGUoKTsKKworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVEFCTEVfTkFNRV9GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy50YWJsZU5hbWUpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpZiAodGhpcy5yb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImRlbGV0ZUFsbFJvd19hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgicm93OiIpOworICAgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlQWxsUm93X3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiZGVsZXRlQWxsUm93X3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKGRlbGV0ZUFsbFJvd19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93X3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93X3Jlc3VsdCgKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93X3Jlc3VsdChkZWxldGVBbGxSb3dfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd19yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IGRlbGV0ZUFsbFJvd19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRlbGV0ZUFsbFJvd19yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoZGVsZXRlQWxsUm93X3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZGVsZXRlQWxsUm93X3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZGVsZXRlQWxsUm93X3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIGRlbGV0ZUFsbFJvd1RzX2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoImRlbGV0ZUFsbFJvd1RzX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFJPV19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgicm93IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRJTUVTVEFNUF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGltZXN0YW1wIiwgVFR5cGUuSTY0LCAoc2hvcnQpMyk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworICAgIHB1YmxpYyBieXRlW10gcm93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJPVyA9IDI7CisgICAgcHVibGljIGxvbmcgdGltZXN0YW1wOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUCA9IDM7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHRpbWVzdGFtcCA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChUQUJMRU5BTUUsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0YWJsZU5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgicm93IiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFRJTUVTVEFNUCwgbmV3IEZpZWxkTWV0YURhdGEoInRpbWVzdGFtcCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVBbGxSb3dUc19hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd1RzX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd1RzX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lLAorICAgICAgYnl0ZVtdIHJvdywKKyAgICAgIGxvbmcgdGltZXN0YW1wKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93VHNfYXJncyhkZWxldGVBbGxSb3dUc19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICAgIHRoaXMucm93ID0gb3RoZXIucm93OworICAgICAgfQorICAgICAgX19pc3NldC50aW1lc3RhbXAgPSBvdGhlci5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gb3RoZXIudGltZXN0YW1wOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBkZWxldGVBbGxSb3dUc19hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVBbGxSb3dUc19hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRSb3coYnl0ZVtdIHJvdykgeworICAgICAgdGhpcy5yb3cgPSByb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRSb3coKSB7CisgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMudGltZXN0YW1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChsb25nIHRpbWVzdGFtcCkgeworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRpbWVzdGFtcCgpIHsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGltZXN0YW1wIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXBJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUaW1lc3RhbXAoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUaW1lc3RhbXAoKExvbmcpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBST1c6CisgICAgICAgIHJldHVybiBnZXRSb3coKTsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBuZXcgTG9uZyhnZXRUaW1lc3RhbXAoKSk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGlzU2V0VGFibGVOYW1lKCk7CisgICAgICBjYXNlIFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Um93KCk7CisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgcmV0dXJuIGlzU2V0VGltZXN0YW1wKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2YgZGVsZXRlQWxsUm93VHNfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVBbGxSb3dUc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhkZWxldGVBbGxSb3dUc19hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3JvdyA9IHRydWUgJiYgdGhpcy5pc1NldFJvdygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3JvdyB8fCB0aGF0X3ByZXNlbnRfcm93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9yb3cgJiYgdGhhdF9wcmVzZW50X3JvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMucm93LCB0aGF0LnJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGltZXN0YW1wIHx8IHRoYXRfcHJlc2VudF90aW1lc3RhbXApIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RpbWVzdGFtcCAmJiB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCAhPSB0aGF0LnRpbWVzdGFtcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTY0KSB7CisgICAgICAgICAgICAgIHRoaXMudGltZXN0YW1wID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMucm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRJTUVTVEFNUF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoImRlbGV0ZUFsbFJvd1RzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgICBpZiAodGhpcy5yb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJ0aW1lc3RhbXA6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy50aW1lc3RhbXApOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgZGVsZXRlQWxsUm93VHNfcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJkZWxldGVBbGxSb3dUc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChkZWxldGVBbGxSb3dUc19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93VHNfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBkZWxldGVBbGxSb3dUc19yZXN1bHQoCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdChkZWxldGVBbGxSb3dUc19yZXN1bHQgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgZGVsZXRlQWxsUm93VHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBkZWxldGVBbGxSb3dUc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gaXNTZXRJbygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChkZWxldGVBbGxSb3dUc19yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGRlbGV0ZUFsbFJvd1RzX3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiZGVsZXRlQWxsUm93VHNfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lck9wZW5fYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lck9wZW5fYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBUQUJMRV9OQU1FX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0YWJsZU5hbWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1RBUlRfUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdGFydFJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBDT0xVTU5TX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJjb2x1bW5zIiwgVFR5cGUuTElTVCwgKHNob3J0KTMpOworCisgICAgcHVibGljIGJ5dGVbXSB0YWJsZU5hbWU7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEFCTEVOQU1FID0gMTsKKyAgICBwdWJsaWMgYnl0ZVtdIHN0YXJ0Um93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUQVJUUk9XID0gMjsKKyAgICBwdWJsaWMgTGlzdDxieXRlW10+IGNvbHVtbnM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OUyA9IDM7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFNUQVJUUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgic3RhcnRSb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoQ09MVU1OUywgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJPcGVuX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5fYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5fYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBieXRlW10gc3RhcnRSb3csCisgICAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBzY2FubmVyT3Blbl9hcmdzKHNjYW5uZXJPcGVuX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIGlmIChvdGhlci5pc1NldFRhYmxlTmFtZSgpKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gb3RoZXIudGFibGVOYW1lOworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0U3RhcnRSb3coKSkgeworICAgICAgICB0aGlzLnN0YXJ0Um93ID0gb3RoZXIuc3RhcnRSb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRDb2x1bW5zKCkpIHsKKyAgICAgICAgTGlzdDxieXRlW10+IF9fdGhpc19fY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworICAgICAgICBmb3IgKGJ5dGVbXSBvdGhlcl9lbGVtZW50IDogb3RoZXIuY29sdW1ucykgeworICAgICAgICAgIF9fdGhpc19fY29sdW1ucy5hZGQob3RoZXJfZWxlbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb2x1bW5zID0gX190aGlzX19jb2x1bW5zOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyT3Blbl9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBzY2FubmVyT3Blbl9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFN0YXJ0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMuc3RhcnRSb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RhcnRSb3coYnl0ZVtdIHN0YXJ0Um93KSB7CisgICAgICB0aGlzLnN0YXJ0Um93ID0gc3RhcnRSb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRTdGFydFJvdygpIHsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdGFydFJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0U3RhcnRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5zdGFydFJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnN0YXJ0Um93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbnNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0Q29sdW1uc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5jb2x1bW5zLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5zKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLmNvbHVtbnMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhMaXN0PGJ5dGVbXT4gY29sdW1ucykgeworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbnMoKSB7CisgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW5zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1ucyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFNUQVJUUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3RhcnRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdGFydFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldENvbHVtbnMoKExpc3Q8Ynl0ZVtdPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgcmV0dXJuIGdldFRhYmxlTmFtZSgpOworCisgICAgICBjYXNlIFNUQVJUUk9XOgorICAgICAgICByZXR1cm4gZ2V0U3RhcnRSb3coKTsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1ucygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZSgpOworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3RhcnRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Q29sdW1ucygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJPcGVuX2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoc2Nhbm5lck9wZW5fYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lck9wZW5fYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhpcy5pc1NldFN0YXJ0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhhdC5pc1NldFN0YXJ0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N0YXJ0Um93IHx8IHRoYXRfcHJlc2VudF9zdGFydFJvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3RhcnRSb3cgJiYgdGhhdF9wcmVzZW50X3N0YXJ0Um93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5zdGFydFJvdywgdGhhdC5zdGFydFJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Q29sdW1ucygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfY29sdW1ucyA9IHRydWUgJiYgdGhhdC5pc1NldENvbHVtbnMoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfY29sdW1ucyB8fCB0aGF0X3ByZXNlbnRfY29sdW1ucykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfY29sdW1ucyAmJiB0aGF0X3ByZXNlbnRfY29sdW1ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuY29sdW1ucy5lcXVhbHModGhhdC5jb2x1bW5zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgICB0aGlzLnN0YXJ0Um93ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5MSVNUKSB7CisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBUTGlzdCBfbGlzdDc4ID0gaXByb3QucmVhZExpc3RCZWdpbigpOworICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPihfbGlzdDc4LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pNzkgPSAwOyBfaTc5IDwgX2xpc3Q3OC5zaXplOyArK19pNzkpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgYnl0ZVtdIF9lbGVtODA7CisgICAgICAgICAgICAgICAgICBfZWxlbTgwID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5zLmFkZChfZWxlbTgwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuc3RhcnRSb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1RBUlRfUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnN0YXJ0Um93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuY29sdW1ucyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5TX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUklORywgdGhpcy5jb2x1bW5zLnNpemUoKSkpOworICAgICAgICAgIGZvciAoYnl0ZVtdIF9pdGVyODEgOiB0aGlzLmNvbHVtbnMpICAgICAgICAgIHsKKyAgICAgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KF9pdGVyODEpOworICAgICAgICAgIH0KKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJzY2FubmVyT3Blbl9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgic3RhcnRSb3c6Iik7CisgICAgICBpZiAodGhpcy5zdGFydFJvdyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3RhcnRSb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiY29sdW1uczoiKTsKKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbnMpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lck9wZW5fcmVzdWx0IGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJzY2FubmVyT3Blbl9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkkzMiwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBpbnQgc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChzY2FubmVyT3Blbl9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5fcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyT3Blbl9yZXN1bHQoCisgICAgICBpbnQgc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIHNjYW5uZXJPcGVuX3Jlc3VsdChzY2FubmVyT3Blbl9yZXN1bHQgb3RoZXIpIHsKKyAgICAgIF9faXNzZXQuc3VjY2VzcyA9IG90aGVyLl9faXNzZXQuc3VjY2VzczsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IG90aGVyLnN1Y2Nlc3M7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNjYW5uZXJPcGVuX3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lck9wZW5fcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhpbnQgc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoZ2V0U3VjY2VzcygpKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lck9wZW5fcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKHNjYW5uZXJPcGVuX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lck9wZW5fcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3VjY2VzcyB8fCB0aGF0X3ByZXNlbnRfc3VjY2VzcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3VjY2VzcyAmJiB0aGF0X3ByZXNlbnRfc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy5zdWNjZXNzICE9IHRoYXQuc3VjY2VzcykKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUkzMih0aGlzLnN1Y2Nlc3MpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJPcGVuX3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInN1Y2Nlc3M6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy5zdWNjZXNzKTsKKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRBQkxFX05BTUVfRklFTERfREVTQyA9IG5ldyBURmllbGQoInRhYmxlTmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVEFSVF9ST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN0YXJ0Um93IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNUT1BfUk9XX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdG9wUm93IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMyk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIENPTFVNTlNfRklFTERfREVTQyA9IG5ldyBURmllbGQoImNvbHVtbnMiLCBUVHlwZS5MSVNULCAoc2hvcnQpNCk7CisKKyAgICBwdWJsaWMgYnl0ZVtdIHRhYmxlTmFtZTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUQUJMRU5BTUUgPSAxOworICAgIHB1YmxpYyBieXRlW10gc3RhcnRSb3c7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBUlRST1cgPSAyOworICAgIHB1YmxpYyBieXRlW10gc3RvcFJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVE9QUk9XID0gMzsKKyAgICBwdWJsaWMgTGlzdDxieXRlW10+IGNvbHVtbnM7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OUyA9IDQ7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFNUQVJUUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgic3RhcnRSb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoU1RPUFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInN0b3BSb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoQ09MVU1OUywgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncygKKyAgICAgIGJ5dGVbXSB0YWJsZU5hbWUsCisgICAgICBieXRlW10gc3RhcnRSb3csCisgICAgICBieXRlW10gc3RvcFJvdywKKyAgICAgIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgICAgdGhpcy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgICAgdGhpcy5zdG9wUm93ID0gc3RvcFJvdzsKKyAgICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wX2FyZ3Moc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFN0YXJ0Um93KCkpIHsKKyAgICAgICAgdGhpcy5zdGFydFJvdyA9IG90aGVyLnN0YXJ0Um93OworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0U3RvcFJvdygpKSB7CisgICAgICAgIHRoaXMuc3RvcFJvdyA9IG90aGVyLnN0b3BSb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRDb2x1bW5zKCkpIHsKKyAgICAgICAgTGlzdDxieXRlW10+IF9fdGhpc19fY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworICAgICAgICBmb3IgKGJ5dGVbXSBvdGhlcl9lbGVtZW50IDogb3RoZXIuY29sdW1ucykgeworICAgICAgICAgIF9fdGhpc19fY29sdW1ucy5hZGQob3RoZXJfZWxlbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb2x1bW5zID0gX190aGlzX19jb2x1bW5zOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wX2FyZ3MgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncyh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWUoYnl0ZVtdIHRhYmxlTmFtZSkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSB0YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUYWJsZU5hbWUoKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRhYmxlTmFtZSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRTdGFydFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN0YXJ0Um93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0Um93KGJ5dGVbXSBzdGFydFJvdykgeworICAgICAgdGhpcy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3RhcnRSb3coKSB7CisgICAgICB0aGlzLnN0YXJ0Um93ID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgc3RhcnRSb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN0YXJ0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMuc3RhcnRSb3cgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFydFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5zdGFydFJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRTdG9wUm93KCkgeworICAgICAgcmV0dXJuIHRoaXMuc3RvcFJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdG9wUm93KGJ5dGVbXSBzdG9wUm93KSB7CisgICAgICB0aGlzLnN0b3BSb3cgPSBzdG9wUm93OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3RvcFJvdygpIHsKKyAgICAgIHRoaXMuc3RvcFJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN0b3BSb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN0b3BSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5zdG9wUm93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RvcFJvd0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5zdG9wUm93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbnNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0Q29sdW1uc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5jb2x1bW5zLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5zKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLmNvbHVtbnMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhMaXN0PGJ5dGVbXT4gY29sdW1ucykgeworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbnMoKSB7CisgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW5zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1ucyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFNUQVJUUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3RhcnRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdGFydFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBTVE9QUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3RvcFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN0b3BSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldENvbHVtbnMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRDb2x1bW5zKChMaXN0PGJ5dGVbXT4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFN0YXJ0Um93KCk7CisKKyAgICAgIGNhc2UgU1RPUFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFN0b3BSb3coKTsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1ucygpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZSgpOworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3RhcnRSb3coKTsKKyAgICAgIGNhc2UgU1RPUFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3RvcFJvdygpOworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICByZXR1cm4gaXNTZXRDb2x1bW5zKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKHNjYW5uZXJPcGVuV2l0aFN0b3BfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90YWJsZU5hbWUgPSB0cnVlICYmIHRoYXQuaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfdGFibGVOYW1lIHx8IHRoYXRfcHJlc2VudF90YWJsZU5hbWUpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X3RhYmxlTmFtZSAmJiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy50YWJsZU5hbWUsIHRoYXQudGFibGVOYW1lKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N0YXJ0Um93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0U3RhcnRSb3coKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N0YXJ0Um93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3RhcnRSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3RhcnRSb3cgfHwgdGhhdF9wcmVzZW50X3N0YXJ0Um93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdGFydFJvdyAmJiB0aGF0X3ByZXNlbnRfc3RhcnRSb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnN0YXJ0Um93LCB0aGF0LnN0YXJ0Um93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N0b3BSb3cgPSB0cnVlICYmIHRoaXMuaXNTZXRTdG9wUm93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdG9wUm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3RvcFJvdygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdG9wUm93IHx8IHRoYXRfcHJlc2VudF9zdG9wUm93KSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdG9wUm93ICYmIHRoYXRfcHJlc2VudF9zdG9wUm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5zdG9wUm93LCB0aGF0LnN0b3BSb3cpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfY29sdW1ucyA9IHRydWUgJiYgdGhpcy5pc1NldENvbHVtbnMoKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2NvbHVtbnMgPSB0cnVlICYmIHRoYXQuaXNTZXRDb2x1bW5zKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X2NvbHVtbnMgfHwgdGhhdF9wcmVzZW50X2NvbHVtbnMpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2NvbHVtbnMgJiYgdGhhdF9wcmVzZW50X2NvbHVtbnMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmNvbHVtbnMuZXF1YWxzKHRoYXQuY29sdW1ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgU1RBUlRST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdGFydFJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBTVE9QUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMuc3RvcFJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q4MiA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oX2xpc3Q4Mi5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTgzID0gMDsgX2k4MyA8IF9saXN0ODIuc2l6ZTsgKytfaTgzKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGJ5dGVbXSBfZWxlbTg0OworICAgICAgICAgICAgICAgICAgX2VsZW04NCA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucy5hZGQoX2VsZW04NCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnN0YXJ0Um93ICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNUQVJUX1JPV19GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5zdGFydFJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnN0b3BSb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1RPUF9ST1dfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuc3RvcFJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQ09MVU1OU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJJTkcsIHRoaXMuY29sdW1ucy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKGJ5dGVbXSBfaXRlcjg1IDogdGhpcy5jb2x1bW5zKSAgICAgICAgICB7CisgICAgICAgICAgICBvcHJvdC53cml0ZUJpbmFyeShfaXRlcjg1KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigic2Nhbm5lck9wZW5XaXRoU3RvcF9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgidGFibGVOYW1lOiIpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy50YWJsZU5hbWUpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgic3RhcnRSb3c6Iik7CisgICAgICBpZiAodGhpcy5zdGFydFJvdyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3RhcnRSb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgic3RvcFJvdzoiKTsKKyAgICAgIGlmICh0aGlzLnN0b3BSb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN0b3BSb3cpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiY29sdW1uczoiKTsKKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmNvbHVtbnMpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoInNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0Iik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNVQ0NFU1NfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN1Y2Nlc3MiLCBUVHlwZS5JMzIsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisKKyAgICBwdWJsaWMgaW50IHN1Y2Nlc3M7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VDQ0VTUyA9IDA7CisgICAgcHVibGljIElPRXJyb3IgaW87CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU8gPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFNVQ0NFU1MsIG5ldyBGaWVsZE1ldGFEYXRhKCJzdWNjZXNzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTMyKSkpOworICAgICAgcHV0KElPLCBuZXcgRmllbGRNZXRhRGF0YSgiaW8iLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQoKSB7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0KAorICAgICAgaW50IHN1Y2Nlc3MsCisgICAgICBJT0Vycm9yIGlvKQorICAgIHsKKyAgICAgIHRoaXMoKTsKKyAgICAgIHRoaXMuc3VjY2VzcyA9IHN1Y2Nlc3M7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wX3Jlc3VsdChzY2FubmVyT3BlbldpdGhTdG9wX3Jlc3VsdCBvdGhlcikgeworICAgICAgX19pc3NldC5zdWNjZXNzID0gb3RoZXIuX19pc3NldC5zdWNjZXNzOworICAgICAgdGhpcy5zdWNjZXNzID0gb3RoZXIuc3VjY2VzczsKKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQgY2xvbmUoKSB7CisgICAgICByZXR1cm4gbmV3IHNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhpbnQgc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoZ2V0U3VjY2VzcygpKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoc2Nhbm5lck9wZW5XaXRoU3RvcF9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKHNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3VjY2VzcyB8fCB0aGF0X3ByZXNlbnRfc3VjY2VzcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3VjY2VzcyAmJiB0aGF0X3ByZXNlbnRfc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy5zdWNjZXNzICE9IHRoYXQuc3VjY2VzcykKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUkzMih0aGlzLnN1Y2Nlc3MpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJPcGVuV2l0aFN0b3BfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lck9wZW5Uc19hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJzY2FubmVyT3BlblRzX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNUQVJUX1JPV19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3RhcnRSb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1ucyIsIFRUeXBlLkxJU1QsIChzaG9ydCkzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVElNRVNUQU1QX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0aW1lc3RhbXAiLCBUVHlwZS5JNjQsIChzaG9ydCk0KTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIGJ5dGVbXSBzdGFydFJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVEFSVFJPVyA9IDI7CisgICAgcHVibGljIExpc3Q8Ynl0ZVtdPiBjb2x1bW5zOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTFVNTlMgPSAzOworICAgIHB1YmxpYyBsb25nIHRpbWVzdGFtcDsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVAgPSA0OworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiB0aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoVEFCTEVOQU1FLCBuZXcgRmllbGRNZXRhRGF0YSgidGFibGVOYW1lIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFNUQVJUUk9XLCBuZXcgRmllbGRNZXRhRGF0YSgic3RhcnRSb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgICBwdXQoQ09MVU1OUywgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbnMiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSkpOworICAgICAgcHV0KFRJTUVTVEFNUCwgbmV3IEZpZWxkTWV0YURhdGEoInRpbWVzdGFtcCIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChzY2FubmVyT3BlblRzX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5Uc19hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyT3BlblRzX2FyZ3MoCisgICAgICBieXRlW10gdGFibGVOYW1lLAorICAgICAgYnl0ZVtdIHN0YXJ0Um93LAorICAgICAgTGlzdDxieXRlW10+IGNvbHVtbnMsCisgICAgICBsb25nIHRpbWVzdGFtcCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5Uc19hcmdzKHNjYW5uZXJPcGVuVHNfYXJncyBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0VGFibGVOYW1lKCkpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBvdGhlci50YWJsZU5hbWU7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRTdGFydFJvdygpKSB7CisgICAgICAgIHRoaXMuc3RhcnRSb3cgPSBvdGhlci5zdGFydFJvdzsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldENvbHVtbnMoKSkgeworICAgICAgICBMaXN0PGJ5dGVbXT4gX190aGlzX19jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICAgIGZvciAoYnl0ZVtdIG90aGVyX2VsZW1lbnQgOiBvdGhlci5jb2x1bW5zKSB7CisgICAgICAgICAgX190aGlzX19jb2x1bW5zLmFkZChvdGhlcl9lbGVtZW50KTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLmNvbHVtbnMgPSBfX3RoaXNfX2NvbHVtbnM7CisgICAgICB9CisgICAgICBfX2lzc2V0LnRpbWVzdGFtcCA9IG90aGVyLl9faXNzZXQudGltZXN0YW1wOworICAgICAgdGhpcy50aW1lc3RhbXAgPSBvdGhlci50aW1lc3RhbXA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNjYW5uZXJPcGVuVHNfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lck9wZW5Uc19hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0VGFibGVOYW1lKCkgeworICAgICAgcmV0dXJuIHRoaXMudGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZShieXRlW10gdGFibGVOYW1lKSB7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRhYmxlTmFtZSgpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGFibGVOYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWUgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUYWJsZU5hbWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYnl0ZVtdIGdldFN0YXJ0Um93KCkgeworICAgICAgcmV0dXJuIHRoaXMuc3RhcnRSb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RhcnRSb3coYnl0ZVtdIHN0YXJ0Um93KSB7CisgICAgICB0aGlzLnN0YXJ0Um93ID0gc3RhcnRSb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRTdGFydFJvdygpIHsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdGFydFJvdyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0U3RhcnRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5zdGFydFJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0YXJ0Um93SXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLnN0YXJ0Um93ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgaW50IGdldENvbHVtbnNTaXplKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgamF2YS51dGlsLkl0ZXJhdG9yPGJ5dGVbXT4gZ2V0Q29sdW1uc0l0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyBudWxsIDogdGhpcy5jb2x1bW5zLml0ZXJhdG9yKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgYWRkVG9Db2x1bW5zKGJ5dGVbXSBlbGVtKSB7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgICB9CisgICAgICB0aGlzLmNvbHVtbnMuYWRkKGVsZW0pOworICAgIH0KKworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gZ2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhMaXN0PGJ5dGVbXT4gY29sdW1ucykgeworICAgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldENvbHVtbnMoKSB7CisgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW5zIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgICAgcmV0dXJuIHRoaXMuY29sdW1ucyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMudGltZXN0YW1wOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChsb25nIHRpbWVzdGFtcCkgeworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFRpbWVzdGFtcCgpIHsKKyAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdGltZXN0YW1wIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRUaW1lc3RhbXAoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXBJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGFibGVOYW1lKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGFibGVOYW1lKChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFNUQVJUUk9XOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3RhcnRSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdGFydFJvdygoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0Q29sdW1ucygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldENvbHVtbnMoKExpc3Q8Ynl0ZVtdPil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0VGltZXN0YW1wKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0VGltZXN0YW1wKChMb25nKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gZ2V0VGFibGVOYW1lKCk7CisKKyAgICAgIGNhc2UgU1RBUlRST1c6CisgICAgICAgIHJldHVybiBnZXRTdGFydFJvdygpOworCisgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgIHJldHVybiBnZXRDb2x1bW5zKCk7CisKKyAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICByZXR1cm4gbmV3IExvbmcoZ2V0VGltZXN0YW1wKCkpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBpc1NldFRhYmxlTmFtZSgpOworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3RhcnRSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Q29sdW1ucygpOworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBpc1NldFRpbWVzdGFtcCgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJPcGVuVHNfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyT3BlblRzX2FyZ3MpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKHNjYW5uZXJPcGVuVHNfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhpcy5pc1NldFN0YXJ0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhhdC5pc1NldFN0YXJ0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N0YXJ0Um93IHx8IHRoYXRfcHJlc2VudF9zdGFydFJvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3RhcnRSb3cgJiYgdGhhdF9wcmVzZW50X3N0YXJ0Um93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5zdGFydFJvdywgdGhhdC5zdGFydFJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Q29sdW1ucygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfY29sdW1ucyA9IHRydWUgJiYgdGhhdC5pc1NldENvbHVtbnMoKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfY29sdW1ucyB8fCB0aGF0X3ByZXNlbnRfY29sdW1ucykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfY29sdW1ucyAmJiB0aGF0X3ByZXNlbnRfY29sdW1ucykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuY29sdW1ucy5lcXVhbHModGhhdC5jb2x1bW5zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgfHwgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfdGltZXN0YW1wICYmIHRoYXRfcHJlc2VudF90aW1lc3RhbXApKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHRoaXMudGltZXN0YW1wICE9IHRoYXQudGltZXN0YW1wKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMudGFibGVOYW1lID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFNUQVJUUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMuc3RhcnRSb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0ODYgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5zID0gbmV3IEFycmF5TGlzdDxieXRlW10+KF9saXN0ODYuc2l6ZSk7CisgICAgICAgICAgICAgICAgZm9yIChpbnQgX2k4NyA9IDA7IF9pODcgPCBfbGlzdDg2LnNpemU7ICsrX2k4NykKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICBieXRlW10gX2VsZW04ODsKKyAgICAgICAgICAgICAgICAgIF9lbGVtODggPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMuYWRkKF9lbGVtODgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpcHJvdC5yZWFkTGlzdEVuZCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTY0KSB7CisgICAgICAgICAgICAgIHRoaXMudGltZXN0YW1wID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihUQUJMRV9OQU1FX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnRhYmxlTmFtZSk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLnN0YXJ0Um93ICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNUQVJUX1JPV19GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5zdGFydFJvdyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlmICh0aGlzLmNvbHVtbnMgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQ09MVU1OU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJJTkcsIHRoaXMuY29sdW1ucy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKGJ5dGVbXSBfaXRlcjg5IDogdGhpcy5jb2x1bW5zKSAgICAgICAgICB7CisgICAgICAgICAgICBvcHJvdC53cml0ZUJpbmFyeShfaXRlcjg5KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRJTUVTVEFNUF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJPcGVuVHNfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInRhYmxlTmFtZToiKTsKKyAgICAgIGlmICh0aGlzLnRhYmxlTmFtZSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMudGFibGVOYW1lKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInN0YXJ0Um93OiIpOworICAgICAgaWYgKHRoaXMuc3RhcnRSb3cgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN0YXJ0Um93KTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImNvbHVtbnM6Iik7CisgICAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5jb2x1bW5zKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoInRpbWVzdGFtcDoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnRpbWVzdGFtcCk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBzY2FubmVyT3BlblRzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lck9wZW5Uc19yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkkzMiwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBpbnQgc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICAgIHB1YmxpYyBib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICB9fSk7CisKKyAgICBzdGF0aWMgeworICAgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChzY2FubmVyT3BlblRzX3Jlc3VsdC5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyT3BlblRzX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5Uc19yZXN1bHQoCisgICAgICBpbnQgc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8pCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIHNjYW5uZXJPcGVuVHNfcmVzdWx0KHNjYW5uZXJPcGVuVHNfcmVzdWx0IG90aGVyKSB7CisgICAgICBfX2lzc2V0LnN1Y2Nlc3MgPSBvdGhlci5fX2lzc2V0LnN1Y2Nlc3M7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBvdGhlci5zdWNjZXNzOworICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyT3BlblRzX3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lck9wZW5Uc19yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKGludCBzdWNjZXNzKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0U3VjY2VzcygpIHsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN1Y2Nlc3MgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFN1Y2Nlc3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2Vzc0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKEludGVnZXIpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXRTdWNjZXNzKCkpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0U3VjY2VzcygpOworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBzY2FubmVyT3BlblRzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyT3BlblRzX3Jlc3VsdCl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lck9wZW5Uc19yZXN1bHQgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgIT0gdGhhdC5zdWNjZXNzKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkkzMikgeworICAgICAgICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBpcHJvdC5yZWFkSTMyKCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFNVQ0NFU1NfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlSTMyKHRoaXMuc3VjY2Vzcyk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElvKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElPX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlvLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigic2Nhbm5lck9wZW5Uc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3MiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVEFCTEVfTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGFibGVOYW1lIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFNUQVJUX1JPV19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3RhcnRSb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1RPUF9ST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN0b3BSb3ciLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkzKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1ucyIsIFRUeXBlLkxJU1QsIChzaG9ydCk0KTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVElNRVNUQU1QX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJ0aW1lc3RhbXAiLCBUVHlwZS5JNjQsIChzaG9ydCk1KTsKKworICAgIHB1YmxpYyBieXRlW10gdGFibGVOYW1lOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRBQkxFTkFNRSA9IDE7CisgICAgcHVibGljIGJ5dGVbXSBzdGFydFJvdzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVEFSVFJPVyA9IDI7CisgICAgcHVibGljIGJ5dGVbXSBzdG9wUm93OworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUT1BST1cgPSAzOworICAgIHB1YmxpYyBMaXN0PGJ5dGVbXT4gY29sdW1uczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0xVTU5TID0gNDsKKyAgICBwdWJsaWMgbG9uZyB0aW1lc3RhbXA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVElNRVNUQU1QID0gNTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgcHVibGljIGJvb2xlYW4gdGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KFRBQkxFTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoInRhYmxlTmFtZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICAgIHB1dChTVEFSVFJPVywgbmV3IEZpZWxkTWV0YURhdGEoInN0YXJ0Um93IiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KFNUT1BST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJzdG9wUm93IiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgICAgcHV0KENPTFVNTlMsIG5ldyBGaWVsZE1ldGFEYXRhKCJjb2x1bW5zIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBMaXN0TWV0YURhdGEoVFR5cGUuTElTVCwgCisgICAgICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpKTsKKyAgICAgIHB1dChUSU1FU1RBTVAsIG5ldyBGaWVsZE1ldGFEYXRhKCJ0aW1lc3RhbXAiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JNjQpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoc2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzKAorICAgICAgYnl0ZVtdIHRhYmxlTmFtZSwKKyAgICAgIGJ5dGVbXSBzdGFydFJvdywKKyAgICAgIGJ5dGVbXSBzdG9wUm93LAorICAgICAgTGlzdDxieXRlW10+IGNvbHVtbnMsCisgICAgICBsb25nIHRpbWVzdGFtcCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnRhYmxlTmFtZSA9IHRhYmxlTmFtZTsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICAgIHRoaXMuc3RvcFJvdyA9IHN0b3BSb3c7CisgICAgICB0aGlzLmNvbHVtbnMgPSBjb2x1bW5zOworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzKHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzIG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRUYWJsZU5hbWUoKSkgeworICAgICAgICB0aGlzLnRhYmxlTmFtZSA9IG90aGVyLnRhYmxlTmFtZTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldFN0YXJ0Um93KCkpIHsKKyAgICAgICAgdGhpcy5zdGFydFJvdyA9IG90aGVyLnN0YXJ0Um93OworICAgICAgfQorICAgICAgaWYgKG90aGVyLmlzU2V0U3RvcFJvdygpKSB7CisgICAgICAgIHRoaXMuc3RvcFJvdyA9IG90aGVyLnN0b3BSb3c7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRDb2x1bW5zKCkpIHsKKyAgICAgICAgTGlzdDxieXRlW10+IF9fdGhpc19fY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworICAgICAgICBmb3IgKGJ5dGVbXSBvdGhlcl9lbGVtZW50IDogb3RoZXIuY29sdW1ucykgeworICAgICAgICAgIF9fdGhpc19fY29sdW1ucy5hZGQob3RoZXJfZWxlbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgdGhpcy5jb2x1bW5zID0gX190aGlzX19jb2x1bW5zOworICAgICAgfQorICAgICAgX19pc3NldC50aW1lc3RhbXAgPSBvdGhlci5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gb3RoZXIudGltZXN0YW1wOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGJ5dGVbXSBnZXRUYWJsZU5hbWUoKSB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZU5hbWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGFibGVOYW1lKGJ5dGVbXSB0YWJsZU5hbWUpIHsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gdGFibGVOYW1lOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0VGFibGVOYW1lKCkgeworICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCB0YWJsZU5hbWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldFRhYmxlTmFtZSgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlTmFtZSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFRhYmxlTmFtZUlzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0U3RhcnRSb3coKSB7CisgICAgICByZXR1cm4gdGhpcy5zdGFydFJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdGFydFJvdyhieXRlW10gc3RhcnRSb3cpIHsKKyAgICAgIHRoaXMuc3RhcnRSb3cgPSBzdGFydFJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN0YXJ0Um93KCkgeworICAgICAgdGhpcy5zdGFydFJvdyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHN0YXJ0Um93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdGFydFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN0YXJ0Um93ICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RhcnRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3RhcnRSb3cgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBieXRlW10gZ2V0U3RvcFJvdygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN0b3BSb3c7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3RvcFJvdyhieXRlW10gc3RvcFJvdykgeworICAgICAgdGhpcy5zdG9wUm93ID0gc3RvcFJvdzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN0b3BSb3coKSB7CisgICAgICB0aGlzLnN0b3BSb3cgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdG9wUm93IGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdG9wUm93KCkgeworICAgICAgcmV0dXJuIHRoaXMuc3RvcFJvdyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN0b3BSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3RvcFJvdyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRDb2x1bW5zU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5jb2x1bW5zID09IG51bGwpID8gMCA6IHRoaXMuY29sdW1ucy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxieXRlW10+IGdldENvbHVtbnNJdGVyYXRvcigpIHsKKyAgICAgIHJldHVybiAodGhpcy5jb2x1bW5zID09IG51bGwpID8gbnVsbCA6IHRoaXMuY29sdW1ucy5pdGVyYXRvcigpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGFkZFRvQ29sdW1ucyhieXRlW10gZWxlbSkgeworICAgICAgaWYgKHRoaXMuY29sdW1ucyA9PSBudWxsKSB7CisgICAgICAgIHRoaXMuY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworICAgICAgfQorICAgICAgdGhpcy5jb2x1bW5zLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxieXRlW10+IGdldENvbHVtbnMoKSB7CisgICAgICByZXR1cm4gdGhpcy5jb2x1bW5zOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldENvbHVtbnMoTGlzdDxieXRlW10+IGNvbHVtbnMpIHsKKyAgICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRDb2x1bW5zKCkgeworICAgICAgdGhpcy5jb2x1bW5zID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29sdW1ucyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0Q29sdW1ucygpIHsKKyAgICAgIHJldHVybiB0aGlzLmNvbHVtbnMgIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5zSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRUaW1lc3RhbXAobG9uZyB0aW1lc3RhbXApIHsKKyAgICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRUaW1lc3RhbXAoKSB7CisgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVzdGFtcCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0VGltZXN0YW1wKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC50aW1lc3RhbXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0VGltZXN0YW1wSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFRBQkxFTkFNRToKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFRhYmxlTmFtZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFRhYmxlTmFtZSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN0YXJ0Um93KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0U3RhcnRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgU1RPUFJPVzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN0b3BSb3coKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdG9wUm93KChieXRlW10pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIENPTFVNTlM6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRDb2x1bW5zKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0Q29sdW1ucygoTGlzdDxieXRlW10+KXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRUaW1lc3RhbXAoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRUaW1lc3RhbXAoKExvbmcpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgIHJldHVybiBnZXRUYWJsZU5hbWUoKTsKKworICAgICAgY2FzZSBTVEFSVFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFN0YXJ0Um93KCk7CisKKyAgICAgIGNhc2UgU1RPUFJPVzoKKyAgICAgICAgcmV0dXJuIGdldFN0b3BSb3coKTsKKworICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICByZXR1cm4gZ2V0Q29sdW1ucygpOworCisgICAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgICAgcmV0dXJuIG5ldyBMb25nKGdldFRpbWVzdGFtcCgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgVEFCTEVOQU1FOgorICAgICAgICByZXR1cm4gaXNTZXRUYWJsZU5hbWUoKTsKKyAgICAgIGNhc2UgU1RBUlRST1c6CisgICAgICAgIHJldHVybiBpc1NldFN0YXJ0Um93KCk7CisgICAgICBjYXNlIFNUT1BST1c6CisgICAgICAgIHJldHVybiBpc1NldFN0b3BSb3coKTsKKyAgICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgICAgcmV0dXJuIGlzU2V0Q29sdW1ucygpOworICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgIHJldHVybiBpc1NldFRpbWVzdGFtcCgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKHNjYW5uZXJPcGVuV2l0aFN0b3BUc19hcmdzKXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhzY2FubmVyT3BlbldpdGhTdG9wVHNfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3RhYmxlTmFtZSA9IHRydWUgJiYgdGhpcy5pc1NldFRhYmxlTmFtZSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfdGFibGVOYW1lID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VGFibGVOYW1lKCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RhYmxlTmFtZSB8fCB0aGF0X3ByZXNlbnRfdGFibGVOYW1lKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90YWJsZU5hbWUgJiYgdGhhdF9wcmVzZW50X3RhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudGFibGVOYW1lLCB0aGF0LnRhYmxlTmFtZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhpcy5pc1NldFN0YXJ0Um93KCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdGFydFJvdyA9IHRydWUgJiYgdGhhdC5pc1NldFN0YXJ0Um93KCk7CisgICAgICBpZiAodGhpc19wcmVzZW50X3N0YXJ0Um93IHx8IHRoYXRfcHJlc2VudF9zdGFydFJvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3RhcnRSb3cgJiYgdGhhdF9wcmVzZW50X3N0YXJ0Um93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5zdGFydFJvdywgdGhhdC5zdGFydFJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9zdG9wUm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0U3RvcFJvdygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfc3RvcFJvdyA9IHRydWUgJiYgdGhhdC5pc1NldFN0b3BSb3coKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3RvcFJvdyB8fCB0aGF0X3ByZXNlbnRfc3RvcFJvdykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3RvcFJvdyAmJiB0aGF0X3ByZXNlbnRfc3RvcFJvdykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuc3RvcFJvdywgdGhhdC5zdG9wUm93KSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2NvbHVtbnMgPSB0cnVlICYmIHRoaXMuaXNTZXRDb2x1bW5zKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1ucygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW5zIHx8IHRoYXRfcHJlc2VudF9jb2x1bW5zKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9jb2x1bW5zICYmIHRoYXRfcHJlc2VudF9jb2x1bW5zKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5jb2x1bW5zLmVxdWFscyh0aGF0LmNvbHVtbnMpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3RpbWVzdGFtcCA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X3RpbWVzdGFtcCB8fCB0aGF0X3ByZXNlbnRfdGltZXN0YW1wKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgJiYgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy50aW1lc3RhbXAgIT0gdGhhdC50aW1lc3RhbXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBUQUJMRU5BTUU6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy50YWJsZU5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgU1RBUlRST1c6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdGFydFJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBTVE9QUk9XOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICAgIHRoaXMuc3RvcFJvdyA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuTElTVCkgeworICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgVExpc3QgX2xpc3Q5MCA9IGlwcm90LnJlYWRMaXN0QmVnaW4oKTsKKyAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oX2xpc3Q5MC5zaXplKTsKKyAgICAgICAgICAgICAgICBmb3IgKGludCBfaTkxID0gMDsgX2k5MSA8IF9saXN0OTAuc2l6ZTsgKytfaTkxKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGJ5dGVbXSBfZWxlbTkyOworICAgICAgICAgICAgICAgICAgX2VsZW05MiA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1ucy5hZGQoX2VsZW05Mik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBUSU1FU1RBTVA6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JNjQpIHsKKyAgICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgaWYgKHRoaXMudGFibGVOYW1lICE9IG51bGwpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFRBQkxFX05BTUVfRklFTERfREVTQyk7CisgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudGFibGVOYW1lKTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuc3RhcnRSb3cgIT0gbnVsbCkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1RBUlRfUk9XX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnN0YXJ0Um93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuc3RvcFJvdyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVE9QX1JPV19GSUVMRF9ERVNDKTsKKyAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5zdG9wUm93KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaWYgKHRoaXMuY29sdW1ucyAhPSBudWxsKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihDT0xVTU5TX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUklORywgdGhpcy5jb2x1bW5zLnNpemUoKSkpOworICAgICAgICAgIGZvciAoYnl0ZVtdIF9pdGVyOTMgOiB0aGlzLmNvbHVtbnMpICAgICAgICAgIHsKKyAgICAgICAgICAgIG9wcm90LndyaXRlQmluYXJ5KF9pdGVyOTMpOworICAgICAgICAgIH0KKyAgICAgICAgICBvcHJvdC53cml0ZUxpc3RFbmQoKTsKKyAgICAgICAgfQorICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVElNRVNUQU1QX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVJNjQodGhpcy50aW1lc3RhbXApOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigic2Nhbm5lck9wZW5XaXRoU3RvcFRzX2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJ0YWJsZU5hbWU6Iik7CisgICAgICBpZiAodGhpcy50YWJsZU5hbWUgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnRhYmxlTmFtZSk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJzdGFydFJvdzoiKTsKKyAgICAgIGlmICh0aGlzLnN0YXJ0Um93ID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5zdGFydFJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJzdG9wUm93OiIpOworICAgICAgaWYgKHRoaXMuc3RvcFJvdyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuc3RvcFJvdyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJjb2x1bW5zOiIpOworICAgICAgaWYgKHRoaXMuY29sdW1ucyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuY29sdW1ucyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJ0aW1lc3RhbXA6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy50aW1lc3RhbXApOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuSTMyLCAoc2hvcnQpMCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElPX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpbyIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTEpOworCisgICAgcHVibGljIGludCBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgICAgcHVibGljIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkkzMikpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCgKKyAgICAgIGludCBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbykKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5fX2lzc2V0LnN1Y2Nlc3MgPSB0cnVlOworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdChzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0IG90aGVyKSB7CisgICAgICBfX2lzc2V0LnN1Y2Nlc3MgPSBvdGhlci5fX2lzc2V0LnN1Y2Nlc3M7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBvdGhlci5zdWNjZXNzOworICAgICAgaWYgKG90aGVyLmlzU2V0SW8oKSkgeworICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3Iob3RoZXIuaW8pOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0KHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0U3VjY2VzcygpIHsKKyAgICAgIHJldHVybiB0aGlzLnN1Y2Nlc3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0U3VjY2VzcyhpbnQgc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuX19pc3NldC5zdWNjZXNzID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5zdWNjZXNzOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyBJT0Vycm9yIGdldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW8oSU9FcnJvciBpbykgeworICAgICAgdGhpcy5pbyA9IGlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHVuc2V0SW8oKSB7CisgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgaW8gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldElvKCkgeworICAgICAgcmV0dXJuIHRoaXMuaW8gIT0gbnVsbDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJb0lzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICAgIGlmICghdmFsdWUpIHsKKyAgICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldFN1Y2Nlc3MoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRTdWNjZXNzKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElvKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SW8oKElPRXJyb3IpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gbmV3IEludGVnZXIoZ2V0U3VjY2VzcygpKTsKKworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lck9wZW5XaXRoU3RvcFRzX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhzY2FubmVyT3BlbldpdGhTdG9wVHNfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3VjY2VzcyA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfc3VjY2VzcyB8fCB0aGF0X3ByZXNlbnRfc3VjY2VzcykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfc3VjY2VzcyAmJiB0aGF0X3ByZXNlbnRfc3VjY2VzcykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy5zdWNjZXNzICE9IHRoYXQuc3VjY2VzcykKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGlzLmlzU2V0SW8oKTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lvID0gdHJ1ZSAmJiB0aGF0LmlzU2V0SW8oKTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaW8gfHwgdGhhdF9wcmVzZW50X2lvKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pbyAmJiB0aGF0X3ByZXNlbnRfaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKCF0aGlzLmlvLmVxdWFscyh0aGF0LmlvKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgVEZpZWxkIGZpZWxkOworICAgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgICB3aGlsZSAodHJ1ZSkKKyAgICAgIHsKKyAgICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICAgIHsKKyAgICAgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQuc3VjY2VzcyA9IHRydWU7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICBvcHJvdC53cml0ZUkzMih0aGlzLnN1Y2Nlc3MpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJPcGVuV2l0aFN0b3BUc19yZXN1bHQoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJzdWNjZXNzOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMuc3VjY2Vzcyk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgICAgc2IuYXBwZW5kKCJpbzoiKTsKKyAgICAgIGlmICh0aGlzLmlvID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5pbyk7CisgICAgICB9CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBzY2FubmVyR2V0X2FyZ3MgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoInNjYW5uZXJHZXRfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJRF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWQiLCBUVHlwZS5JMzIsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBpbnQgaWQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUQgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpZCA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJRCwgbmV3IEZpZWxkTWV0YURhdGEoImlkIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTMyKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJHZXRfYXJncy5jbGFzcywgbWV0YURhdGFNYXApOworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyR2V0X2FyZ3MoKSB7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJHZXRfYXJncygKKyAgICAgIGludCBpZCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlkID0gaWQ7CisgICAgICB0aGlzLl9faXNzZXQuaWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lckdldF9hcmdzKHNjYW5uZXJHZXRfYXJncyBvdGhlcikgeworICAgICAgX19pc3NldC5pZCA9IG90aGVyLl9faXNzZXQuaWQ7CisgICAgICB0aGlzLmlkID0gb3RoZXIuaWQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHNjYW5uZXJHZXRfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lckdldF9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SWQoKSB7CisgICAgICByZXR1cm4gdGhpcy5pZDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZChpbnQgaWQpIHsKKyAgICAgIHRoaXMuaWQgPSBpZDsKKyAgICAgIHRoaXMuX19pc3NldC5pZCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJZCgpIHsKKyAgICAgIHRoaXMuX19pc3NldC5pZCA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpZCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWQoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LmlkOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElkSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSUQ6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElkKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSUQ6CisgICAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXRJZCgpKTsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSUQ6CisgICAgICAgIHJldHVybiBpc1NldElkKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lckdldF9hcmdzKQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKHNjYW5uZXJHZXRfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lckdldF9hcmdzIHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaWQgPSB0cnVlOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWQgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pZCB8fCB0aGF0X3ByZXNlbnRfaWQpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lkICYmIHRoYXRfcHJlc2VudF9pZCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAodGhpcy5pZCAhPSB0aGF0LmlkKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSUQ6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5pZCA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICB2YWxpZGF0ZSgpOworCisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJRF9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTMyKHRoaXMuaWQpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigic2Nhbm5lckdldF9hcmdzKCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgiaWQ6Iik7CisgICAgICBzYi5hcHBlbmQodGhpcy5pZCk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBzY2FubmVyR2V0X3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lckdldF9yZXN1bHQiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgU1VDQ0VTU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgic3VjY2VzcyIsIFRUeXBlLkxJU1QsIChzaG9ydCkwKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSU9fRklFTERfREVTQyA9IG5ldyBURmllbGQoImlvIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMSk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElBX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpYSIsIFRUeXBlLlNUUlVDVCwgKHNob3J0KTIpOworCisgICAgcHVibGljIExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzczsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUNDRVNTID0gMDsKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBpYTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJQSA9IDI7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoU1VDQ0VTUywgbmV3IEZpZWxkTWV0YURhdGEoInN1Y2Nlc3MiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IExpc3RNZXRhRGF0YShUVHlwZS5MSVNULCAKKyAgICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgVFJvd1Jlc3VsdC5jbGFzcykpKSk7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICAgIHB1dChJQSwgbmV3IEZpZWxkTWV0YURhdGEoImlhIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJHZXRfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJHZXRfcmVzdWx0KCkgeworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyR2V0X3Jlc3VsdCgKKyAgICAgIExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcywKKyAgICAgIElPRXJyb3IgaW8sCisgICAgICBJbGxlZ2FsQXJndW1lbnQgaWEpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICAgIHRoaXMuaWEgPSBpYTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAgICovCisgICAgcHVibGljIHNjYW5uZXJHZXRfcmVzdWx0KHNjYW5uZXJHZXRfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRTdWNjZXNzKCkpIHsKKyAgICAgICAgTGlzdDxUUm93UmVzdWx0PiBfX3RoaXNfX3N1Y2Nlc3MgPSBuZXcgQXJyYXlMaXN0PFRSb3dSZXN1bHQ+KCk7CisgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBvdGhlcl9lbGVtZW50IDogb3RoZXIuc3VjY2VzcykgeworICAgICAgICAgIF9fdGhpc19fc3VjY2Vzcy5hZGQobmV3IFRSb3dSZXN1bHQob3RoZXJfZWxlbWVudCkpOworICAgICAgICB9CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IF9fdGhpc19fc3VjY2VzczsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElvKCkpIHsKKyAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKG90aGVyLmlvKTsKKyAgICAgIH0KKyAgICAgIGlmIChvdGhlci5pc1NldElhKCkpIHsKKyAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQob3RoZXIuaWEpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyR2V0X3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lckdldF9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gMCA6IHRoaXMuc3VjY2Vzcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxUUm93UmVzdWx0PiBnZXRTdWNjZXNzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnN1Y2Nlc3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1N1Y2Nlc3MoVFJvd1Jlc3VsdCBlbGVtKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PigpOworICAgICAgfQorICAgICAgdGhpcy5zdWNjZXNzLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExpc3Q8VFJvd1Jlc3VsdD4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJYSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElhKChJbGxlZ2FsQXJndW1lbnQpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gZ2V0U3VjY2VzcygpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGdldElhKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gaXNTZXRJYSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJHZXRfcmVzdWx0KQorICAgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKHNjYW5uZXJHZXRfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhzY2FubmVyR2V0X3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoaXMuaXNTZXRTdWNjZXNzKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3VjY2VzcygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5zdWNjZXNzLmVxdWFscyh0aGF0LnN1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoaXMuaXNTZXRJYSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoYXQuaXNTZXRJYSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pYSB8fCB0aGF0X3ByZXNlbnRfaWEpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lhICYmIHRoYXRfcHJlc2VudF9pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaWEuZXF1YWxzKHRoYXQuaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0OTQgPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PihfbGlzdDk0LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pOTUgPSAwOyBfaTk1IDwgX2xpc3Q5NC5zaXplOyArK19pOTUpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgVFJvd1Jlc3VsdCBfZWxlbTk2OworICAgICAgICAgICAgICAgICAgX2VsZW05NiA9IG5ldyBUUm93UmVzdWx0KCk7CisgICAgICAgICAgICAgICAgICBfZWxlbTk2LnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzLmFkZChfZWxlbTk2KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaXByb3QucmVhZExpc3RFbmQoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElPOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcigpOworICAgICAgICAgICAgICB0aGlzLmlvLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIElBOgorICAgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSVUNUKSB7CisgICAgICAgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KCk7CisgICAgICAgICAgICAgIHRoaXMuaWEucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgICB2YWxpZGF0ZSgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisKKyAgICAgIGlmICh0aGlzLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihTVUNDRVNTX0ZJRUxEX0RFU0MpOworICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0QmVnaW4obmV3IFRMaXN0KFRUeXBlLlNUUlVDVCwgdGhpcy5zdWNjZXNzLnNpemUoKSkpOworICAgICAgICAgIGZvciAoVFJvd1Jlc3VsdCBfaXRlcjk3IDogdGhpcy5zdWNjZXNzKSAgICAgICAgICB7CisgICAgICAgICAgICBfaXRlcjk3LndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJHZXRfcmVzdWx0KCIpOworICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICAgIHNiLmFwcGVuZCgic3VjY2VzczoiKTsKKyAgICAgIGlmICh0aGlzLnN1Y2Nlc3MgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLnN1Y2Nlc3MpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaW86Iik7CisgICAgICBpZiAodGhpcy5pbyA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaW8pOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICAgIHNiLmFwcGVuZCgiaWE6Iik7CisgICAgICBpZiAodGhpcy5pYSA9PSBudWxsKSB7CisgICAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2IuYXBwZW5kKHRoaXMuaWEpOworICAgICAgfQorICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lckdldExpc3RfYXJncyBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lckdldExpc3RfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJRF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWQiLCBUVHlwZS5JMzIsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTkJfUk9XU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgibmJSb3dzIiwgVFR5cGUuSTMyLCAoc2hvcnQpMik7CisKKyAgICBwdWJsaWMgaW50IGlkOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElEID0gMTsKKyAgICBwdWJsaWMgaW50IG5iUm93czsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQlJPV1MgPSAyOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpZCA9IGZhbHNlOworICAgICAgcHVibGljIGJvb2xlYW4gbmJSb3dzID0gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgICAgcHV0KElELCBuZXcgRmllbGRNZXRhRGF0YSgiaWQiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5JMzIpKSk7CisgICAgICBwdXQoTkJST1dTLCBuZXcgRmllbGRNZXRhRGF0YSgibmJSb3dzIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTMyKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJHZXRMaXN0X2FyZ3MuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lckdldExpc3RfYXJncygpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lckdldExpc3RfYXJncygKKyAgICAgIGludCBpZCwKKyAgICAgIGludCBuYlJvd3MpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdHJ1ZTsKKyAgICAgIHRoaXMubmJSb3dzID0gbmJSb3dzOworICAgICAgdGhpcy5fX2lzc2V0Lm5iUm93cyA9IHRydWU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgICAqLworICAgIHB1YmxpYyBzY2FubmVyR2V0TGlzdF9hcmdzKHNjYW5uZXJHZXRMaXN0X2FyZ3Mgb3RoZXIpIHsKKyAgICAgIF9faXNzZXQuaWQgPSBvdGhlci5fX2lzc2V0LmlkOworICAgICAgdGhpcy5pZCA9IG90aGVyLmlkOworICAgICAgX19pc3NldC5uYlJvd3MgPSBvdGhlci5fX2lzc2V0Lm5iUm93czsKKyAgICAgIHRoaXMubmJSb3dzID0gb3RoZXIubmJSb3dzOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyR2V0TGlzdF9hcmdzIGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBzY2FubmVyR2V0TGlzdF9hcmdzKHRoaXMpOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0SWQoKSB7CisgICAgICByZXR1cm4gdGhpcy5pZDsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJZChpbnQgaWQpIHsKKyAgICAgIHRoaXMuaWQgPSBpZDsKKyAgICAgIHRoaXMuX19pc3NldC5pZCA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJZCgpIHsKKyAgICAgIHRoaXMuX19pc3NldC5pZCA9IGZhbHNlOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpZCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWQoKSB7CisgICAgICByZXR1cm4gdGhpcy5fX2lzc2V0LmlkOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElkSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdmFsdWU7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXROYlJvd3MoKSB7CisgICAgICByZXR1cm4gdGhpcy5uYlJvd3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TmJSb3dzKGludCBuYlJvd3MpIHsKKyAgICAgIHRoaXMubmJSb3dzID0gbmJSb3dzOworICAgICAgdGhpcy5fX2lzc2V0Lm5iUm93cyA9IHRydWU7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXROYlJvd3MoKSB7CisgICAgICB0aGlzLl9faXNzZXQubmJSb3dzID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIG5iUm93cyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0TmJSb3dzKCkgeworICAgICAgcmV0dXJuIHRoaXMuX19pc3NldC5uYlJvd3M7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0TmJSb3dzSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgdGhpcy5fX2lzc2V0Lm5iUm93cyA9IHZhbHVlOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElEOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJZCgoSW50ZWdlcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgTkJST1dTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0TmJSb3dzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0TmJSb3dzKChJbnRlZ2VyKXZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICAgIGNhc2UgSUQ6CisgICAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXRJZCgpKTsKKworICAgICAgY2FzZSBOQlJPV1M6CisgICAgICAgIHJldHVybiBuZXcgSW50ZWdlcihnZXROYlJvd3MoKSk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElEOgorICAgICAgICByZXR1cm4gaXNTZXRJZCgpOworICAgICAgY2FzZSBOQlJPV1M6CisgICAgICAgIHJldHVybiBpc1NldE5iUm93cygpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJHZXRMaXN0X2FyZ3MpCisgICAgICAgIHJldHVybiB0aGlzLmVxdWFscygoc2Nhbm5lckdldExpc3RfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lckdldExpc3RfYXJncyB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lkID0gdHJ1ZTsKKyAgICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X2lkID0gdHJ1ZTsKKyAgICAgIGlmICh0aGlzX3ByZXNlbnRfaWQgfHwgdGhhdF9wcmVzZW50X2lkKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pZCAmJiB0aGF0X3ByZXNlbnRfaWQpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHRoaXMuaWQgIT0gdGhhdC5pZCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X25iUm93cyA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9uYlJvd3MgPSB0cnVlOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9uYlJvd3MgfHwgdGhhdF9wcmVzZW50X25iUm93cykgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfbmJSb3dzICYmIHRoYXRfcHJlc2VudF9uYlJvd3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKHRoaXMubmJSb3dzICE9IHRoYXQubmJSb3dzKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSUQ6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5pZCA9IGlwcm90LnJlYWRJMzIoKTsKKyAgICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdHJ1ZTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBOQlJPV1M6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5JMzIpIHsKKyAgICAgICAgICAgICAgdGhpcy5uYlJvd3MgPSBpcHJvdC5yZWFkSTMyKCk7CisgICAgICAgICAgICAgIHRoaXMuX19pc3NldC5uYlJvd3MgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElEX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVJMzIodGhpcy5pZCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oTkJfUk9XU19GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlSTMyKHRoaXMubmJSb3dzKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJHZXRMaXN0X2FyZ3MoIik7CisgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgICAgc2IuYXBwZW5kKCJpZDoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLmlkKTsKKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoIm5iUm93czoiKTsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLm5iUm93cyk7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgc2IuYXBwZW5kKCIpIik7CisgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICAgIH0KKworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBzY2FubmVyR2V0TGlzdF9yZXN1bHQgaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSAgIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoInNjYW5uZXJHZXRMaXN0X3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVUNDRVNTX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJzdWNjZXNzIiwgVFR5cGUuTElTVCwgKHNob3J0KTApOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSUFfRklFTERfREVTQyA9IG5ldyBURmllbGQoImlhIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMik7CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1MgPSAwOworICAgIHB1YmxpYyBJT0Vycm9yIGlvOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElPID0gMTsKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGlhOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElBID0gMjsKKworICAgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChTVUNDRVNTLCBuZXcgRmllbGRNZXRhRGF0YSgic3VjY2VzcyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgTGlzdE1ldGFEYXRhKFRUeXBlLkxJU1QsIAorICAgICAgICAgICAgICBuZXcgU3RydWN0TWV0YURhdGEoVFR5cGUuU1RSVUNULCBUUm93UmVzdWx0LmNsYXNzKSkpKTsKKyAgICAgIHB1dChJTywgbmV3IEZpZWxkTWV0YURhdGEoImlvIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgICAgcHV0KElBLCBuZXcgRmllbGRNZXRhRGF0YSgiaWEiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJVQ1QpKSk7CisgICAgfX0pOworCisgICAgc3RhdGljIHsKKyAgICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoc2Nhbm5lckdldExpc3RfcmVzdWx0LmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJHZXRMaXN0X3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lckdldExpc3RfcmVzdWx0KAorICAgICAgTGlzdDxUUm93UmVzdWx0PiBzdWNjZXNzLAorICAgICAgSU9FcnJvciBpbywKKyAgICAgIElsbGVnYWxBcmd1bWVudCBpYSkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBzdWNjZXNzOworICAgICAgdGhpcy5pbyA9IGlvOworICAgICAgdGhpcy5pYSA9IGlhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lckdldExpc3RfcmVzdWx0KHNjYW5uZXJHZXRMaXN0X3Jlc3VsdCBvdGhlcikgeworICAgICAgaWYgKG90aGVyLmlzU2V0U3VjY2VzcygpKSB7CisgICAgICAgIExpc3Q8VFJvd1Jlc3VsdD4gX190aGlzX19zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PigpOworICAgICAgICBmb3IgKFRSb3dSZXN1bHQgb3RoZXJfZWxlbWVudCA6IG90aGVyLnN1Y2Nlc3MpIHsKKyAgICAgICAgICBfX3RoaXNfX3N1Y2Nlc3MuYWRkKG5ldyBUUm93UmVzdWx0KG90aGVyX2VsZW1lbnQpKTsKKyAgICAgICAgfQorICAgICAgICB0aGlzLnN1Y2Nlc3MgPSBfX3RoaXNfX3N1Y2Nlc3M7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJYSgpKSB7CisgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KG90aGVyLmlhKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2Nhbm5lckdldExpc3RfcmVzdWx0IGNsb25lKCkgeworICAgICAgcmV0dXJuIG5ldyBzY2FubmVyR2V0TGlzdF9yZXN1bHQodGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRTdWNjZXNzU2l6ZSgpIHsKKyAgICAgIHJldHVybiAodGhpcy5zdWNjZXNzID09IG51bGwpID8gMCA6IHRoaXMuc3VjY2Vzcy5zaXplKCk7CisgICAgfQorCisgICAgcHVibGljIGphdmEudXRpbC5JdGVyYXRvcjxUUm93UmVzdWx0PiBnZXRTdWNjZXNzSXRlcmF0b3IoKSB7CisgICAgICByZXR1cm4gKHRoaXMuc3VjY2VzcyA9PSBudWxsKSA/IG51bGwgOiB0aGlzLnN1Y2Nlc3MuaXRlcmF0b3IoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBhZGRUb1N1Y2Nlc3MoVFJvd1Jlc3VsdCBlbGVtKSB7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PigpOworICAgICAgfQorICAgICAgdGhpcy5zdWNjZXNzLmFkZChlbGVtKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdDxUUm93UmVzdWx0PiBnZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTdWNjZXNzKExpc3Q8VFJvd1Jlc3VsdD4gc3VjY2VzcykgeworICAgICAgdGhpcy5zdWNjZXNzID0gc3VjY2VzczsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldFN1Y2Nlc3MoKSB7CisgICAgICB0aGlzLnN1Y2Nlc3MgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBzdWNjZXNzIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRTdWNjZXNzKCkgeworICAgICAgcmV0dXJuIHRoaXMuc3VjY2VzcyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFN1Y2Nlc3NJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuc3VjY2VzcyA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIElPRXJyb3IgZ2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJbyhJT0Vycm9yIGlvKSB7CisgICAgICB0aGlzLmlvID0gaW87CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJbygpIHsKKyAgICAgIHRoaXMuaW8gPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpbyBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SW8oKSB7CisgICAgICByZXR1cm4gdGhpcy5pbyAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlvID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50IGdldElhKCkgeworICAgICAgcmV0dXJuIHRoaXMuaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWEoSWxsZWdhbEFyZ3VtZW50IGlhKSB7CisgICAgICB0aGlzLmlhID0gaWE7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdW5zZXRJYSgpIHsKKyAgICAgIHRoaXMuaWEgPSBudWxsOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpYSBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYSAhPSBudWxsOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElhSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgICAgaWYgKCF2YWx1ZSkgeworICAgICAgICB0aGlzLmlhID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0U3VjY2VzcygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldFN1Y2Nlc3MoKExpc3Q8VFJvd1Jlc3VsdD4pdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJYSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElhKChJbGxlZ2FsQXJndW1lbnQpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBTVUNDRVNTOgorICAgICAgICByZXR1cm4gZ2V0U3VjY2VzcygpOworCisgICAgICBjYXNlIElPOgorICAgICAgICByZXR1cm4gZ2V0SW8oKTsKKworICAgICAgY2FzZSBJQToKKyAgICAgICAgcmV0dXJuIGdldElhKCk7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIFNVQ0NFU1M6CisgICAgICAgIHJldHVybiBpc1NldFN1Y2Nlc3MoKTsKKyAgICAgIGNhc2UgSU86CisgICAgICAgIHJldHVybiBpc1NldElvKCk7CisgICAgICBjYXNlIElBOgorICAgICAgICByZXR1cm4gaXNTZXRJYSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhhdCBpbnN0YW5jZW9mIHNjYW5uZXJHZXRMaXN0X3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyR2V0TGlzdF9yZXN1bHQpdGhhdCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKHNjYW5uZXJHZXRMaXN0X3Jlc3VsdCB0aGF0KSB7CisgICAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3N1Y2Nlc3MgPSB0cnVlICYmIHRoaXMuaXNTZXRTdWNjZXNzKCk7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9zdWNjZXNzID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3VjY2VzcygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9zdWNjZXNzIHx8IHRoYXRfcHJlc2VudF9zdWNjZXNzKSB7CisgICAgICAgIGlmICghKHRoaXNfcHJlc2VudF9zdWNjZXNzICYmIHRoYXRfcHJlc2VudF9zdWNjZXNzKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICghdGhpcy5zdWNjZXNzLmVxdWFscyh0aGF0LnN1Y2Nlc3MpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoaXMuaXNTZXRJYSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoYXQuaXNTZXRJYSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pYSB8fCB0aGF0X3ByZXNlbnRfaWEpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lhICYmIHRoYXRfcHJlc2VudF9pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaWEuZXF1YWxzKHRoYXQuaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgU1VDQ0VTUzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkxJU1QpIHsKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFRMaXN0IF9saXN0OTggPSBpcHJvdC5yZWFkTGlzdEJlZ2luKCk7CisgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzID0gbmV3IEFycmF5TGlzdDxUUm93UmVzdWx0PihfbGlzdDk4LnNpemUpOworICAgICAgICAgICAgICAgIGZvciAoaW50IF9pOTkgPSAwOyBfaTk5IDwgX2xpc3Q5OC5zaXplOyArK19pOTkpCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgVFJvd1Jlc3VsdCBfZWxlbTEwMDsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMTAwID0gbmV3IFRSb3dSZXN1bHQoKTsKKyAgICAgICAgICAgICAgICAgIF9lbGVtMTAwLnJlYWQoaXByb3QpOworICAgICAgICAgICAgICAgICAgdGhpcy5zdWNjZXNzLmFkZChfZWxlbTEwMCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlwcm90LnJlYWRMaXN0RW5kKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJTzoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlvID0gbmV3IElPRXJyb3IoKTsKKyAgICAgICAgICAgICAgdGhpcy5pby5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgY2FzZSBJQToKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUlVDVCkgeworICAgICAgICAgICAgICB0aGlzLmlhID0gbmV3IElsbGVnYWxBcmd1bWVudCgpOworICAgICAgICAgICAgICB0aGlzLmlhLnJlYWQoaXByb3QpOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworCisgICAgICBpZiAodGhpcy5pc1NldFN1Y2Nlc3MoKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1VDQ0VTU19GSUVMRF9ERVNDKTsKKyAgICAgICAgeworICAgICAgICAgIG9wcm90LndyaXRlTGlzdEJlZ2luKG5ldyBUTGlzdChUVHlwZS5TVFJVQ1QsIHRoaXMuc3VjY2Vzcy5zaXplKCkpKTsKKyAgICAgICAgICBmb3IgKFRSb3dSZXN1bHQgX2l0ZXIxMDEgOiB0aGlzLnN1Y2Nlc3MpICAgICAgICAgIHsKKyAgICAgICAgICAgIF9pdGVyMTAxLndyaXRlKG9wcm90KTsKKyAgICAgICAgICB9CisgICAgICAgICAgb3Byb3Qud3JpdGVMaXN0RW5kKCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU2V0SW8oKSkgeworICAgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oSU9fRklFTERfREVTQyk7CisgICAgICAgIHRoaXMuaW8ud3JpdGUob3Byb3QpOworICAgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNTZXRJYSgpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJQV9GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pYS53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoInNjYW5uZXJHZXRMaXN0X3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoInN1Y2Nlc3M6Iik7CisgICAgICBpZiAodGhpcy5zdWNjZXNzID09IG51bGwpIHsKKyAgICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBzYi5hcHBlbmQodGhpcy5zdWNjZXNzKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlhOiIpOworICAgICAgaWYgKHRoaXMuaWEgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlhKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworICBwdWJsaWMgc3RhdGljIGNsYXNzIHNjYW5uZXJDbG9zZV9hcmdzIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgICB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJzY2FubmVyQ2xvc2VfYXJncyIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJRF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaWQiLCBUVHlwZS5JMzIsIChzaG9ydCkxKTsKKworICAgIHB1YmxpYyBpbnQgaWQ7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUQgPSAxOworCisgICAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgICBwdWJsaWMgYm9vbGVhbiBpZCA9IGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICAgIHB1dChJRCwgbmV3IEZpZWxkTWV0YURhdGEoImlkIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuSTMyKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJDbG9zZV9hcmdzLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgICAgfQorCisgICAgcHVibGljIHNjYW5uZXJDbG9zZV9hcmdzKCkgeworICAgIH0KKworICAgIHB1YmxpYyBzY2FubmVyQ2xvc2VfYXJncygKKyAgICAgIGludCBpZCkKKyAgICB7CisgICAgICB0aGlzKCk7CisgICAgICB0aGlzLmlkID0gaWQ7CisgICAgICB0aGlzLl9faXNzZXQuaWQgPSB0cnVlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lckNsb3NlX2FyZ3Moc2Nhbm5lckNsb3NlX2FyZ3Mgb3RoZXIpIHsKKyAgICAgIF9faXNzZXQuaWQgPSBvdGhlci5fX2lzc2V0LmlkOworICAgICAgdGhpcy5pZCA9IG90aGVyLmlkOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBzY2FubmVyQ2xvc2VfYXJncyBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lckNsb3NlX2FyZ3ModGhpcyk7CisgICAgfQorCisgICAgcHVibGljIGludCBnZXRJZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLmlkOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElkKGludCBpZCkgeworICAgICAgdGhpcy5pZCA9IGlkOworICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElkKCkgeworICAgICAgdGhpcy5fX2lzc2V0LmlkID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlkIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLl9faXNzZXQuaWQ7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWRJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICB0aGlzLl9faXNzZXQuaWQgPSB2YWx1ZTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJRDoKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB1bnNldElkKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2V0SWQoKEludGVnZXIpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJRDoKKyAgICAgICAgcmV0dXJuIG5ldyBJbnRlZ2VyKGdldElkKCkpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJRDoKKyAgICAgICAgcmV0dXJuIGlzU2V0SWQoKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBzY2FubmVyQ2xvc2VfYXJncykKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyQ2xvc2VfYXJncyl0aGF0KTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoc2Nhbm5lckNsb3NlX2FyZ3MgdGhhdCkgeworICAgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pZCA9IHRydWU7CisgICAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pZCA9IHRydWU7CisgICAgICBpZiAodGhpc19wcmVzZW50X2lkIHx8IHRoYXRfcHJlc2VudF9pZCkgeworICAgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaWQgJiYgdGhhdF9wcmVzZW50X2lkKSkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmICh0aGlzLmlkICE9IHRoYXQuaWQpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIFRGaWVsZCBmaWVsZDsKKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpCisgICAgICB7CisgICAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgICB7CisgICAgICAgICAgY2FzZSBJRDoKKyAgICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkkzMikgeworICAgICAgICAgICAgICB0aGlzLmlkID0gaXByb3QucmVhZEkzMigpOworICAgICAgICAgICAgICB0aGlzLl9faXNzZXQuaWQgPSB0cnVlOworICAgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgICAgdmFsaWRhdGUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgIHZhbGlkYXRlKCk7CisKKyAgICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElEX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVJMzIodGhpcy5pZCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkU3RvcCgpOworICAgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJzY2FubmVyQ2xvc2VfYXJncygiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlkOiIpOworICAgICAgc2IuYXBwZW5kKHRoaXMuaWQpOworICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIHNiLmFwcGVuZCgiKSIpOworICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgICB9CisKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgY2xhc3Mgc2Nhbm5lckNsb3NlX3Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlICAgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgic2Nhbm5lckNsb3NlX3Jlc3VsdCIpOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBJT19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiaW8iLCBUVHlwZS5TVFJVQ1QsIChzaG9ydCkxKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSUFfRklFTERfREVTQyA9IG5ldyBURmllbGQoImlhIiwgVFR5cGUuU1RSVUNULCAoc2hvcnQpMik7CisKKyAgICBwdWJsaWMgSU9FcnJvciBpbzsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTyA9IDE7CisgICAgcHVibGljIElsbGVnYWxBcmd1bWVudCBpYTsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJQSA9IDI7CisKKyAgICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgICBwdXQoSU8sIG5ldyBGaWVsZE1ldGFEYXRhKCJpbyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUlVDVCkpKTsKKyAgICAgIHB1dChJQSwgbmV3IEZpZWxkTWV0YURhdGEoImlhIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSVUNUKSkpOworICAgIH19KTsKKworICAgIHN0YXRpYyB7CisgICAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKHNjYW5uZXJDbG9zZV9yZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lckNsb3NlX3Jlc3VsdCgpIHsKKyAgICB9CisKKyAgICBwdWJsaWMgc2Nhbm5lckNsb3NlX3Jlc3VsdCgKKyAgICAgIElPRXJyb3IgaW8sCisgICAgICBJbGxlZ2FsQXJndW1lbnQgaWEpCisgICAgeworICAgICAgdGhpcygpOworICAgICAgdGhpcy5pbyA9IGlvOworICAgICAgdGhpcy5pYSA9IGlhOworICAgIH0KKworICAgIC8qKgorICAgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICAgKi8KKyAgICBwdWJsaWMgc2Nhbm5lckNsb3NlX3Jlc3VsdChzY2FubmVyQ2xvc2VfcmVzdWx0IG90aGVyKSB7CisgICAgICBpZiAob3RoZXIuaXNTZXRJbygpKSB7CisgICAgICAgIHRoaXMuaW8gPSBuZXcgSU9FcnJvcihvdGhlci5pbyk7CisgICAgICB9CisgICAgICBpZiAob3RoZXIuaXNTZXRJYSgpKSB7CisgICAgICAgIHRoaXMuaWEgPSBuZXcgSWxsZWdhbEFyZ3VtZW50KG90aGVyLmlhKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgc2Nhbm5lckNsb3NlX3Jlc3VsdCBjbG9uZSgpIHsKKyAgICAgIHJldHVybiBuZXcgc2Nhbm5lckNsb3NlX3Jlc3VsdCh0aGlzKTsKKyAgICB9CisKKyAgICBwdWJsaWMgSU9FcnJvciBnZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldElvKElPRXJyb3IgaW8pIHsKKyAgICAgIHRoaXMuaW8gPSBpbzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElvKCkgeworICAgICAgdGhpcy5pbyA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlvIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJbygpIHsKKyAgICAgIHJldHVybiB0aGlzLmlvICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SW9Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaW8gPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyBJbGxlZ2FsQXJndW1lbnQgZ2V0SWEoKSB7CisgICAgICByZXR1cm4gdGhpcy5pYTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRJYShJbGxlZ2FsQXJndW1lbnQgaWEpIHsKKyAgICAgIHRoaXMuaWEgPSBpYTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB1bnNldElhKCkgeworICAgICAgdGhpcy5pYSA9IG51bGw7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlhIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXRJYSgpIHsKKyAgICAgIHJldHVybiB0aGlzLmlhICE9IG51bGw7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0SWFJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIHRoaXMuaWEgPSBudWxsOworICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgICBjYXNlIElPOgorICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHVuc2V0SW8oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzZXRJbygoSU9FcnJvcil2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdW5zZXRJYSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNldElhKChJbGxlZ2FsQXJndW1lbnQpdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGdldElvKCk7CisKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIHJldHVybiBnZXRJYSgpOworCisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgICAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgICAgY2FzZSBJTzoKKyAgICAgICAgcmV0dXJuIGlzU2V0SW8oKTsKKyAgICAgIGNhc2UgSUE6CisgICAgICAgIHJldHVybiBpc1NldElhKCk7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGF0IGluc3RhbmNlb2Ygc2Nhbm5lckNsb3NlX3Jlc3VsdCkKKyAgICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChzY2FubmVyQ2xvc2VfcmVzdWx0KXRoYXQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhzY2FubmVyQ2xvc2VfcmVzdWx0IHRoYXQpIHsKKyAgICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoaXMuaXNTZXRJbygpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaW8gPSB0cnVlICYmIHRoYXQuaXNTZXRJbygpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pbyB8fCB0aGF0X3ByZXNlbnRfaW8pIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lvICYmIHRoYXRfcHJlc2VudF9pbykpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaW8uZXF1YWxzKHRoYXQuaW8pKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoaXMuaXNTZXRJYSgpOworICAgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWEgPSB0cnVlICYmIHRoYXQuaXNTZXRJYSgpOworICAgICAgaWYgKHRoaXNfcHJlc2VudF9pYSB8fCB0aGF0X3ByZXNlbnRfaWEpIHsKKyAgICAgICAgaWYgKCEodGhpc19wcmVzZW50X2lhICYmIHRoYXRfcHJlc2VudF9pYSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAoIXRoaXMuaWEuZXF1YWxzKHRoYXQuaWEpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBURmllbGQgZmllbGQ7CisgICAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICAgIHdoaWxlICh0cnVlKQorICAgICAgeworICAgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgICAgeworICAgICAgICAgIGNhc2UgSU86CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pbyA9IG5ldyBJT0Vycm9yKCk7CisgICAgICAgICAgICAgIHRoaXMuaW8ucmVhZChpcHJvdCk7CisgICAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGNhc2UgSUE6CisgICAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJVQ1QpIHsKKyAgICAgICAgICAgICAgdGhpcy5pYSA9IG5ldyBJbGxlZ2FsQXJndW1lbnQoKTsKKyAgICAgICAgICAgICAgdGhpcy5pYS5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICAgIHZhbGlkYXRlKCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKworICAgICAgaWYgKHRoaXMuaXNTZXRJbygpKSB7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihJT19GSUVMRF9ERVNDKTsKKyAgICAgICAgdGhpcy5pby53cml0ZShvcHJvdCk7CisgICAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NldElhKCkpIHsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElBX0ZJRUxEX0RFU0MpOworICAgICAgICB0aGlzLmlhLndyaXRlKG9wcm90KTsKKyAgICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgICAgfQorICAgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICAgIG9wcm90LndyaXRlU3RydWN0RW5kKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigic2Nhbm5lckNsb3NlX3Jlc3VsdCgiKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgICBzYi5hcHBlbmQoImlvOiIpOworICAgICAgaWYgKHRoaXMuaW8gPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlvKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgICBzYi5hcHBlbmQoImlhOiIpOworICAgICAgaWYgKHRoaXMuaWEgPT0gbnVsbCkgeworICAgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNiLmFwcGVuZCh0aGlzLmlhKTsKKyAgICAgIH0KKyAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICBzYi5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgICAgfQorCisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9JT0Vycm9yLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0lPRXJyb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjgwZDBkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9JT0Vycm9yLmphdmEKQEAgLTAsMCArMSwyNDAgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIEFuIElPRXJyb3IgZXhjZXB0aW9uIHNpZ25hbHMgdGhhdCBhbiBlcnJvciBvY2N1cnJlZCBjb21tdW5pY2F0aW5nCisgKiB0byB0aGUgSGJhc2UgbWFzdGVyIG9yIGFuIEhiYXNlIHJlZ2lvbiBzZXJ2ZXIuICBBbHNvIHVzZWQgdG8gcmV0dXJuCisgKiBtb3JlIGdlbmVyYWwgSGJhc2UgZXJyb3IgY29uZGl0aW9ucy4KKyAqLworcHVibGljIGNsYXNzIElPRXJyb3IgZXh0ZW5kcyBFeGNlcHRpb24gaW1wbGVtZW50cyBUQmFzZSwgamF2YS5pby5TZXJpYWxpemFibGUsIENsb25lYWJsZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRTdHJ1Y3QgU1RSVUNUX0RFU0MgPSBuZXcgVFN0cnVjdCgiSU9FcnJvciIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTUVTU0FHRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgibWVzc2FnZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworCisgIHB1YmxpYyBTdHJpbmcgbWVzc2FnZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRSA9IDE7CisKKyAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgIHB1dChNRVNTQUdFLCBuZXcgRmllbGRNZXRhRGF0YSgibWVzc2FnZSIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgIH19KTsKKworICBzdGF0aWMgeworICAgIEZpZWxkTWV0YURhdGEuYWRkU3RydWN0TWV0YURhdGFNYXAoSU9FcnJvci5jbGFzcywgbWV0YURhdGFNYXApOworICB9CisKKyAgcHVibGljIElPRXJyb3IoKSB7CisgIH0KKworICBwdWJsaWMgSU9FcnJvcigKKyAgICBTdHJpbmcgbWVzc2FnZSkKKyAgeworICAgIHRoaXMoKTsKKyAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOworICB9CisKKyAgLyoqCisgICAqIFBlcmZvcm1zIGEgZGVlcCBjb3B5IG9uIDxpPm90aGVyPC9pPi4KKyAgICovCisgIHB1YmxpYyBJT0Vycm9yKElPRXJyb3Igb3RoZXIpIHsKKyAgICBpZiAob3RoZXIuaXNTZXRNZXNzYWdlKCkpIHsKKyAgICAgIHRoaXMubWVzc2FnZSA9IG90aGVyLm1lc3NhZ2U7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBJT0Vycm9yIGNsb25lKCkgeworICAgIHJldHVybiBuZXcgSU9FcnJvcih0aGlzKTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICByZXR1cm4gdGhpcy5tZXNzYWdlOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0TWVzc2FnZShTdHJpbmcgbWVzc2FnZSkgeworICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldE1lc3NhZ2UoKSB7CisgICAgdGhpcy5tZXNzYWdlID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBtZXNzYWdlIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0TWVzc2FnZSgpIHsKKyAgICByZXR1cm4gdGhpcy5tZXNzYWdlICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNZXNzYWdlSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIGlmICghdmFsdWUpIHsKKyAgICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRNZXNzYWdlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRNZXNzYWdlKChTdHJpbmcpdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgcmV0dXJuIGdldE1lc3NhZ2UoKTsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgcmV0dXJuIGlzU2V0TWVzc2FnZSgpOworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBpZiAodGhhdCBpbnN0YW5jZW9mIElPRXJyb3IpCisgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKElPRXJyb3IpdGhhdCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKElPRXJyb3IgdGhhdCkgeworICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF9tZXNzYWdlID0gdHJ1ZSAmJiB0aGlzLmlzU2V0TWVzc2FnZSgpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X21lc3NhZ2UgPSB0cnVlICYmIHRoYXQuaXNTZXRNZXNzYWdlKCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF9tZXNzYWdlIHx8IHRoYXRfcHJlc2VudF9tZXNzYWdlKSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfbWVzc2FnZSAmJiB0aGF0X3ByZXNlbnRfbWVzc2FnZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghdGhpcy5tZXNzYWdlLmVxdWFscyh0aGF0Lm1lc3NhZ2UpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgVEZpZWxkIGZpZWxkOworICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgIHdoaWxlICh0cnVlKQorICAgIHsKKyAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgIHsKKyAgICAgICAgY2FzZSBNRVNTQUdFOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgIH0KKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgIHZhbGlkYXRlKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSgpOworCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgaWYgKHRoaXMubWVzc2FnZSAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oTUVTU0FHRV9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHRoaXMubWVzc2FnZSk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgfQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiSU9FcnJvcigiKTsKKyAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgIHNiLmFwcGVuZCgibWVzc2FnZToiKTsKKyAgICBpZiAodGhpcy5tZXNzYWdlID09IG51bGwpIHsKKyAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgIH0gZWxzZSB7CisgICAgICBzYi5hcHBlbmQodGhpcy5tZXNzYWdlKTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBzYi5hcHBlbmQoIikiKTsKKyAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgfQorCit9CisKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9nZW5lcmF0ZWQvSWxsZWdhbEFyZ3VtZW50LmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0lsbGVnYWxBcmd1bWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1MWVmNjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL0lsbGVnYWxBcmd1bWVudC5qYXZhCkBAIC0wLDAgKzEsMjM5IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQXV0b2dlbmVyYXRlZCBieSBUaHJpZnQKKyAqCisgKiBETyBOT1QgRURJVCBVTkxFU1MgWU9VIEFSRSBTVVJFIFRIQVQgWU9VIEtOT1cgV0hBVCBZT1UgQVJFIERPSU5HCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKKworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0Lio7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQubWV0YV9kYXRhLio7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQucHJvdG9jb2wuKjsKKworLyoqCisgKiBBbiBJbGxlZ2FsQXJndW1lbnQgZXhjZXB0aW9uIGluZGljYXRlcyBhbiBpbGxlZ2FsIG9yIGludmFsaWQKKyAqIGFyZ3VtZW50IHdhcyBwYXNzZWQgaW50byBhIHByb2NlZHVyZS4KKyAqLworcHVibGljIGNsYXNzIElsbGVnYWxBcmd1bWVudCBleHRlbmRzIEV4Y2VwdGlvbiBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJJbGxlZ2FsQXJndW1lbnQiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIE1FU1NBR0VfRklFTERfREVTQyA9IG5ldyBURmllbGQoIm1lc3NhZ2UiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKworICBwdWJsaWMgU3RyaW5nIG1lc3NhZ2U7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0UgPSAxOworCisgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+IG1ldGFEYXRhTWFwID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKG5ldyBIYXNoTWFwPEludGVnZXIsIEZpZWxkTWV0YURhdGE+KCkge3sKKyAgICBwdXQoTUVTU0FHRSwgbmV3IEZpZWxkTWV0YURhdGEoIm1lc3NhZ2UiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICB9fSk7CisKKyAgc3RhdGljIHsKKyAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKElsbGVnYWxBcmd1bWVudC5jbGFzcywgbWV0YURhdGFNYXApOworICB9CisKKyAgcHVibGljIElsbGVnYWxBcmd1bWVudCgpIHsKKyAgfQorCisgIHB1YmxpYyBJbGxlZ2FsQXJndW1lbnQoCisgICAgU3RyaW5nIG1lc3NhZ2UpCisgIHsKKyAgICB0aGlzKCk7CisgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgfQorCisgIC8qKgorICAgKiBQZXJmb3JtcyBhIGRlZXAgY29weSBvbiA8aT5vdGhlcjwvaT4uCisgICAqLworICBwdWJsaWMgSWxsZWdhbEFyZ3VtZW50KElsbGVnYWxBcmd1bWVudCBvdGhlcikgeworICAgIGlmIChvdGhlci5pc1NldE1lc3NhZ2UoKSkgeworICAgICAgdGhpcy5tZXNzYWdlID0gb3RoZXIubWVzc2FnZTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElsbGVnYWxBcmd1bWVudCBjbG9uZSgpIHsKKyAgICByZXR1cm4gbmV3IElsbGVnYWxBcmd1bWVudCh0aGlzKTsKKyAgfQorCisgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKKyAgICByZXR1cm4gdGhpcy5tZXNzYWdlOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0TWVzc2FnZShTdHJpbmcgbWVzc2FnZSkgeworICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldE1lc3NhZ2UoKSB7CisgICAgdGhpcy5tZXNzYWdlID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBtZXNzYWdlIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0TWVzc2FnZSgpIHsKKyAgICByZXR1cm4gdGhpcy5tZXNzYWdlICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRNZXNzYWdlSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIGlmICghdmFsdWUpIHsKKyAgICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgc2V0RmllbGRWYWx1ZShpbnQgZmllbGRJRCwgT2JqZWN0IHZhbHVlKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRNZXNzYWdlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRNZXNzYWdlKChTdHJpbmcpdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgcmV0dXJuIGdldE1lc3NhZ2UoKTsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgY29ycmVzcG9uZGluZyB0byBmaWVsZElEIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0KGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBNRVNTQUdFOgorICAgICAgcmV0dXJuIGlzU2V0TWVzc2FnZSgpOworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBpZiAodGhhdCBpbnN0YW5jZW9mIElsbGVnYWxBcmd1bWVudCkKKyAgICAgIHJldHVybiB0aGlzLmVxdWFscygoSWxsZWdhbEFyZ3VtZW50KXRoYXQpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhJbGxlZ2FsQXJndW1lbnQgdGhhdCkgeworICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF9tZXNzYWdlID0gdHJ1ZSAmJiB0aGlzLmlzU2V0TWVzc2FnZSgpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X21lc3NhZ2UgPSB0cnVlICYmIHRoYXQuaXNTZXRNZXNzYWdlKCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF9tZXNzYWdlIHx8IHRoYXRfcHJlc2VudF9tZXNzYWdlKSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfbWVzc2FnZSAmJiB0aGF0X3ByZXNlbnRfbWVzc2FnZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghdGhpcy5tZXNzYWdlLmVxdWFscyh0aGF0Lm1lc3NhZ2UpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHJlYWQoVFByb3RvY29sIGlwcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgVEZpZWxkIGZpZWxkOworICAgIGlwcm90LnJlYWRTdHJ1Y3RCZWdpbigpOworICAgIHdoaWxlICh0cnVlKQorICAgIHsKKyAgICAgIGZpZWxkID0gaXByb3QucmVhZEZpZWxkQmVnaW4oKTsKKyAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUT1ApIHsgCisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgc3dpdGNoIChmaWVsZC5pZCkKKyAgICAgIHsKKyAgICAgICAgY2FzZSBNRVNTQUdFOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gaXByb3QucmVhZFN0cmluZygpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgIH0KKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgIHZhbGlkYXRlKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSgpOworCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgaWYgKHRoaXMubWVzc2FnZSAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oTUVTU0FHRV9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlU3RyaW5nKHRoaXMubWVzc2FnZSk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgfQorICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiSWxsZWdhbEFyZ3VtZW50KCIpOworICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgc2IuYXBwZW5kKCJtZXNzYWdlOiIpOworICAgIGlmICh0aGlzLm1lc3NhZ2UgPT0gbnVsbCkgeworICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLm1lc3NhZ2UpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9NdXRhdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9NdXRhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyMWJlYWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL011dGF0aW9uLmphdmEKQEAgLTAsMCArMSwzODUgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIEEgTXV0YXRpb24gb2JqZWN0IGlzIHVzZWQgdG8gZWl0aGVyIHVwZGF0ZSBvciBkZWxldGUgYSBjb2x1bW4tdmFsdWUuCisgKi8KK3B1YmxpYyBjbGFzcyBNdXRhdGlvbiBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJNdXRhdGlvbiIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgSVNfREVMRVRFX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpc0RlbGV0ZSIsIFRUeXBlLkJPT0wsIChzaG9ydCkxKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIENPTFVNTl9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1uIiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBWQUxVRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidmFsdWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkzKTsKKworICBwdWJsaWMgYm9vbGVhbiBpc0RlbGV0ZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSVNERUxFVEUgPSAxOworICBwdWJsaWMgYnl0ZVtdIGNvbHVtbjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OID0gMjsKKyAgcHVibGljIGJ5dGVbXSB2YWx1ZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUUgPSAzOworCisgIHByaXZhdGUgZmluYWwgSXNzZXQgX19pc3NldCA9IG5ldyBJc3NldCgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJc3NldCBpbXBsZW1lbnRzIGphdmEuaW8uU2VyaWFsaXphYmxlIHsKKyAgICBwdWJsaWMgYm9vbGVhbiBpc0RlbGV0ZSA9IGZhbHNlOworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgIHB1dChJU0RFTEVURSwgbmV3IEZpZWxkTWV0YURhdGEoImlzRGVsZXRlIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkJPT0wpKSk7CisgICAgcHV0KENPTFVNTiwgbmV3IEZpZWxkTWV0YURhdGEoImNvbHVtbiIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5TVFJJTkcpKSk7CisgICAgcHV0KFZBTFVFLCBuZXcgRmllbGRNZXRhRGF0YSgidmFsdWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICB9fSk7CisKKyAgc3RhdGljIHsKKyAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKE11dGF0aW9uLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgIH0KKworICBwdWJsaWMgTXV0YXRpb24oKSB7CisgICAgdGhpcy5pc0RlbGV0ZSA9IGZhbHNlOworCisgIH0KKworICBwdWJsaWMgTXV0YXRpb24oCisgICAgYm9vbGVhbiBpc0RlbGV0ZSwKKyAgICBieXRlW10gY29sdW1uLAorICAgIGJ5dGVbXSB2YWx1ZSkKKyAgeworICAgIHRoaXMoKTsKKyAgICB0aGlzLmlzRGVsZXRlID0gaXNEZWxldGU7CisgICAgdGhpcy5fX2lzc2V0LmlzRGVsZXRlID0gdHJ1ZTsKKyAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgIH0KKworICAvKioKKyAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgKi8KKyAgcHVibGljIE11dGF0aW9uKE11dGF0aW9uIG90aGVyKSB7CisgICAgX19pc3NldC5pc0RlbGV0ZSA9IG90aGVyLl9faXNzZXQuaXNEZWxldGU7CisgICAgdGhpcy5pc0RlbGV0ZSA9IG90aGVyLmlzRGVsZXRlOworICAgIGlmIChvdGhlci5pc1NldENvbHVtbigpKSB7CisgICAgICB0aGlzLmNvbHVtbiA9IG90aGVyLmNvbHVtbjsKKyAgICB9CisgICAgaWYgKG90aGVyLmlzU2V0VmFsdWUoKSkgeworICAgICAgdGhpcy52YWx1ZSA9IG90aGVyLnZhbHVlOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTXV0YXRpb24gY2xvbmUoKSB7CisgICAgcmV0dXJuIG5ldyBNdXRhdGlvbih0aGlzKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGlzSXNEZWxldGUoKSB7CisgICAgcmV0dXJuIHRoaXMuaXNEZWxldGU7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRJc0RlbGV0ZShib29sZWFuIGlzRGVsZXRlKSB7CisgICAgdGhpcy5pc0RlbGV0ZSA9IGlzRGVsZXRlOworICAgIHRoaXMuX19pc3NldC5pc0RlbGV0ZSA9IHRydWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldElzRGVsZXRlKCkgeworICAgIHRoaXMuX19pc3NldC5pc0RlbGV0ZSA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGlzRGVsZXRlIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0SXNEZWxldGUoKSB7CisgICAgcmV0dXJuIHRoaXMuX19pc3NldC5pc0RlbGV0ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldElzRGVsZXRlSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIHRoaXMuX19pc3NldC5pc0RlbGV0ZSA9IHZhbHVlOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRDb2x1bW4oKSB7CisgICAgcmV0dXJuIHRoaXMuY29sdW1uOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Q29sdW1uKGJ5dGVbXSBjb2x1bW4pIHsKKyAgICB0aGlzLmNvbHVtbiA9IGNvbHVtbjsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1uKCkgeworICAgIHRoaXMuY29sdW1uID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb2x1bW4gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW4oKSB7CisgICAgcmV0dXJuIHRoaXMuY29sdW1uICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRDb2x1bW5Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5jb2x1bW4gPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBieXRlW10gZ2V0VmFsdWUoKSB7CisgICAgcmV0dXJuIHRoaXMudmFsdWU7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRWYWx1ZShieXRlW10gdmFsdWUpIHsKKyAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldFZhbHVlKCkgeworICAgIHRoaXMudmFsdWUgPSBudWxsOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHZhbHVlIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0VmFsdWUoKSB7CisgICAgcmV0dXJuIHRoaXMudmFsdWUgIT0gbnVsbDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFZhbHVlSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIGlmICghdmFsdWUpIHsKKyAgICAgIHRoaXMudmFsdWUgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgSVNERUxFVEU6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldElzRGVsZXRlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRJc0RlbGV0ZSgoQm9vbGVhbil2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgQ09MVU1OOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRDb2x1bW4oKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldENvbHVtbigoYnl0ZVtdKXZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBWQUxVRToKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0VmFsdWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldFZhbHVlKChieXRlW10pdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBJU0RFTEVURToKKyAgICAgIHJldHVybiBuZXcgQm9vbGVhbihpc0lzRGVsZXRlKCkpOworCisgICAgY2FzZSBDT0xVTU46CisgICAgICByZXR1cm4gZ2V0Q29sdW1uKCk7CisKKyAgICBjYXNlIFZBTFVFOgorICAgICAgcmV0dXJuIGdldFZhbHVlKCk7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgSVNERUxFVEU6CisgICAgICByZXR1cm4gaXNTZXRJc0RlbGV0ZSgpOworICAgIGNhc2UgQ09MVU1OOgorICAgICAgcmV0dXJuIGlzU2V0Q29sdW1uKCk7CisgICAgY2FzZSBWQUxVRToKKyAgICAgIHJldHVybiBpc1NldFZhbHVlKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmICh0aGF0IGluc3RhbmNlb2YgTXV0YXRpb24pCisgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKE11dGF0aW9uKXRoYXQpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhNdXRhdGlvbiB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X2lzRGVsZXRlID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9pc0RlbGV0ZSA9IHRydWU7CisgICAgaWYgKHRoaXNfcHJlc2VudF9pc0RlbGV0ZSB8fCB0aGF0X3ByZXNlbnRfaXNEZWxldGUpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9pc0RlbGV0ZSAmJiB0aGF0X3ByZXNlbnRfaXNEZWxldGUpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodGhpcy5pc0RlbGV0ZSAhPSB0aGF0LmlzRGVsZXRlKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfY29sdW1uID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Q29sdW1uKCk7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfY29sdW1uID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1uKCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF9jb2x1bW4gfHwgdGhhdF9wcmVzZW50X2NvbHVtbikgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X2NvbHVtbiAmJiB0aGF0X3ByZXNlbnRfY29sdW1uKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLmNvbHVtbiwgdGhhdC5jb2x1bW4pKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdmFsdWUgPSB0cnVlICYmIHRoaXMuaXNTZXRWYWx1ZSgpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3ZhbHVlID0gdHJ1ZSAmJiB0aGF0LmlzU2V0VmFsdWUoKTsKKyAgICBpZiAodGhpc19wcmVzZW50X3ZhbHVlIHx8IHRoYXRfcHJlc2VudF92YWx1ZSkgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X3ZhbHVlICYmIHRoYXRfcHJlc2VudF92YWx1ZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy52YWx1ZSwgdGhhdC52YWx1ZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICBURmllbGQgZmllbGQ7CisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgd2hpbGUgKHRydWUpCisgICAgeworICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgeworICAgICAgICBjYXNlIElTREVMRVRFOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkJPT0wpIHsKKyAgICAgICAgICAgIHRoaXMuaXNEZWxldGUgPSBpcHJvdC5yZWFkQm9vbCgpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmlzRGVsZXRlID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIENPTFVNTjoKKyAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgIHRoaXMuY29sdW1uID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgIH0KKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgIHZhbGlkYXRlKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSgpOworCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElTX0RFTEVURV9GSUVMRF9ERVNDKTsKKyAgICBvcHJvdC53cml0ZUJvb2wodGhpcy5pc0RlbGV0ZSk7CisgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIGlmICh0aGlzLmNvbHVtbiAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oQ09MVU1OX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5jb2x1bW4pOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIH0KKyAgICBpZiAodGhpcy52YWx1ZSAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVkFMVUVfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnZhbHVlKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJNdXRhdGlvbigiKTsKKyAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgIHNiLmFwcGVuZCgiaXNEZWxldGU6Iik7CisgICAgc2IuYXBwZW5kKHRoaXMuaXNEZWxldGUpOworICAgIGZpcnN0ID0gZmFsc2U7CisgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgIHNiLmFwcGVuZCgiY29sdW1uOiIpOworICAgIGlmICh0aGlzLmNvbHVtbiA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMuY29sdW1uKTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJ2YWx1ZToiKTsKKyAgICBpZiAodGhpcy52YWx1ZSA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMudmFsdWUpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9UQ2VsbC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9UQ2VsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjOTQwNTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL1RDZWxsLmphdmEKQEAgLTAsMCArMSwzMTEgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIFRDZWxsIC0gVXNlZCB0byB0cmFuc3BvcnQgYSBjZWxsIHZhbHVlIChieXRlW10pIGFuZCB0aGUgdGltZXN0YW1wIGl0IHdhcworICogc3RvcmVkIHdpdGggdG9nZXRoZXIgYXMgYSByZXN1bHQgZm9yIGdldCBhbmQgZ2V0Um93IG1ldGhvZHMuIFRoaXMgcHJvbW90ZXMKKyAqIHRoZSB0aW1lc3RhbXAgb2YgYSBjZWxsIHRvIGEgZmlyc3QtY2xhc3MgdmFsdWUsIG1ha2luZyBpdCBlYXN5IHRvIHRha2UKKyAqIG5vdGUgb2YgdGVtcG9yYWwgZGF0YS4gQ2VsbCBpcyB1c2VkIGFsbCB0aGUgd2F5IGZyb20gSFN0b3JlIHVwIHRvIEhUYWJsZS4KKyAqLworcHVibGljIGNsYXNzIFRDZWxsIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoIlRDZWxsIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBWQUxVRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidmFsdWUiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkxKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIFRJTUVTVEFNUF9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidGltZXN0YW1wIiwgVFR5cGUuSTY0LCAoc2hvcnQpMik7CisKKyAgcHVibGljIGJ5dGVbXSB2YWx1ZTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUUgPSAxOworICBwdWJsaWMgbG9uZyB0aW1lc3RhbXA7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUCA9IDI7CisKKyAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICAgIHB1YmxpYyBib29sZWFuIHRpbWVzdGFtcCA9IGZhbHNlOworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgIHB1dChWQUxVRSwgbmV3IEZpZWxkTWV0YURhdGEoInZhbHVlIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORykpKTsKKyAgICBwdXQoVElNRVNUQU1QLCBuZXcgRmllbGRNZXRhRGF0YSgidGltZXN0YW1wIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgfX0pOworCisgIHN0YXRpYyB7CisgICAgRmllbGRNZXRhRGF0YS5hZGRTdHJ1Y3RNZXRhRGF0YU1hcChUQ2VsbC5jbGFzcywgbWV0YURhdGFNYXApOworICB9CisKKyAgcHVibGljIFRDZWxsKCkgeworICB9CisKKyAgcHVibGljIFRDZWxsKAorICAgIGJ5dGVbXSB2YWx1ZSwKKyAgICBsb25nIHRpbWVzdGFtcCkKKyAgeworICAgIHRoaXMoKTsKKyAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IHRydWU7CisgIH0KKworICAvKioKKyAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgKi8KKyAgcHVibGljIFRDZWxsKFRDZWxsIG90aGVyKSB7CisgICAgaWYgKG90aGVyLmlzU2V0VmFsdWUoKSkgeworICAgICAgdGhpcy52YWx1ZSA9IG90aGVyLnZhbHVlOworICAgIH0KKyAgICBfX2lzc2V0LnRpbWVzdGFtcCA9IG90aGVyLl9faXNzZXQudGltZXN0YW1wOworICAgIHRoaXMudGltZXN0YW1wID0gb3RoZXIudGltZXN0YW1wOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBUQ2VsbCBjbG9uZSgpIHsKKyAgICByZXR1cm4gbmV3IFRDZWxsKHRoaXMpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gdGhpcy52YWx1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFZhbHVlKGJ5dGVbXSB2YWx1ZSkgeworICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0VmFsdWUoKSB7CisgICAgdGhpcy52YWx1ZSA9IG51bGw7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgdmFsdWUgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gdGhpcy52YWx1ZSAhPSBudWxsOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0VmFsdWVJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy52YWx1ZSA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIGxvbmcgZ2V0VGltZXN0YW1wKCkgeworICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcChsb25nIHRpbWVzdGFtcCkgeworICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wOworICAgIHRoaXMuX19pc3NldC50aW1lc3RhbXAgPSB0cnVlOworICB9CisKKyAgcHVibGljIHZvaWQgdW5zZXRUaW1lc3RhbXAoKSB7CisgICAgdGhpcy5fX2lzc2V0LnRpbWVzdGFtcCA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHRpbWVzdGFtcCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldFRpbWVzdGFtcCgpIHsKKyAgICByZXR1cm4gdGhpcy5fX2lzc2V0LnRpbWVzdGFtcDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFRpbWVzdGFtcElzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdmFsdWU7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFZBTFVFOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRWYWx1ZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0VmFsdWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRUaW1lc3RhbXAoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldFRpbWVzdGFtcCgoTG9uZyl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFZBTFVFOgorICAgICAgcmV0dXJuIGdldFZhbHVlKCk7CisKKyAgICBjYXNlIFRJTUVTVEFNUDoKKyAgICAgIHJldHVybiBuZXcgTG9uZyhnZXRUaW1lc3RhbXAoKSk7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgVkFMVUU6CisgICAgICByZXR1cm4gaXNTZXRWYWx1ZSgpOworICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgcmV0dXJuIGlzU2V0VGltZXN0YW1wKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmICh0aGF0IGluc3RhbmNlb2YgVENlbGwpCisgICAgICByZXR1cm4gdGhpcy5lcXVhbHMoKFRDZWxsKXRoYXQpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhUQ2VsbCB0aGF0KSB7CisgICAgaWYgKHRoYXQgPT0gbnVsbCkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X3ZhbHVlID0gdHJ1ZSAmJiB0aGlzLmlzU2V0VmFsdWUoKTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF92YWx1ZSA9IHRydWUgJiYgdGhhdC5pc1NldFZhbHVlKCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF92YWx1ZSB8fCB0aGF0X3ByZXNlbnRfdmFsdWUpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF92YWx1ZSAmJiB0aGF0X3ByZXNlbnRfdmFsdWUpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMudmFsdWUsIHRoYXQudmFsdWUpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfdGltZXN0YW1wID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF90aW1lc3RhbXAgPSB0cnVlOworICAgIGlmICh0aGlzX3ByZXNlbnRfdGltZXN0YW1wIHx8IHRoYXRfcHJlc2VudF90aW1lc3RhbXApIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF90aW1lc3RhbXAgJiYgdGhhdF9wcmVzZW50X3RpbWVzdGFtcCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh0aGlzLnRpbWVzdGFtcCAhPSB0aGF0LnRpbWVzdGFtcCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIFRGaWVsZCBmaWVsZDsKKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICB3aGlsZSAodHJ1ZSkKKyAgICB7CisgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICB7CisgICAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICB0aGlzLnZhbHVlID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVElNRVNUQU1QOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkk2NCkgeworICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSBpcHJvdC5yZWFkSTY0KCk7CisgICAgICAgICAgICB0aGlzLl9faXNzZXQudGltZXN0YW1wID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpcHJvdC5yZWFkRmllbGRFbmQoKTsKKyAgICB9CisgICAgaXByb3QucmVhZFN0cnVjdEVuZCgpOworCisKKyAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzIG9mIHByaW1pdGl2ZSB0eXBlLCB3aGljaCBjYW4ndCBiZSBjaGVja2VkIGluIHRoZSB2YWxpZGF0ZSBtZXRob2QKKyAgICB2YWxpZGF0ZSgpOworICB9CisKKyAgcHVibGljIHZvaWQgd3JpdGUoVFByb3RvY29sIG9wcm90KSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgdmFsaWRhdGUoKTsKKworICAgIG9wcm90LndyaXRlU3RydWN0QmVnaW4oU1RSVUNUX0RFU0MpOworICAgIGlmICh0aGlzLnZhbHVlICE9IG51bGwpIHsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihWQUxVRV9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMudmFsdWUpOworICAgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIH0KKyAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oVElNRVNUQU1QX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTY0KHRoaXMudGltZXN0YW1wKTsKKyAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJUQ2VsbCgiKTsKKyAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKKworICAgIHNiLmFwcGVuZCgidmFsdWU6Iik7CisgICAgaWYgKHRoaXMudmFsdWUgPT0gbnVsbCkgeworICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLnZhbHVlKTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJ0aW1lc3RhbXA6Iik7CisgICAgc2IuYXBwZW5kKHRoaXMudGltZXN0YW1wKTsKKyAgICBmaXJzdCA9IGZhbHNlOworICAgIHNiLmFwcGVuZCgiKSIpOworICAgIHJldHVybiBzYi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHZvaWQgdmFsaWRhdGUoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcworICAgIC8vIGNoZWNrIHRoYXQgZmllbGRzIG9mIHR5cGUgZW51bSBoYXZlIHZhbGlkIHZhbHVlcworICB9CisKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9UUmVnaW9uSW5mby5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9UUmVnaW9uSW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmMzY5MzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvZ2VuZXJhdGVkL1RSZWdpb25JbmZvLmphdmEKQEAgLTAsMCArMSw1MjggQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLyoqCisgKiBBdXRvZ2VuZXJhdGVkIGJ5IFRocmlmdAorICoKKyAqIERPIE5PVCBFRElUIFVOTEVTUyBZT1UgQVJFIFNVUkUgVEhBVCBZT1UgS05PVyBXSEFUIFlPVSBBUkUgRE9JTkcKKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkOworCitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworCitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5tZXRhX2RhdGEuKjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC4qOworCisvKioKKyAqIEEgVFJlZ2lvbkluZm8gY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYW4gSFRhYmxlIHJlZ2lvbi4KKyAqLworcHVibGljIGNsYXNzIFRSZWdpb25JbmZvIGltcGxlbWVudHMgVEJhc2UsIGphdmEuaW8uU2VyaWFsaXphYmxlLCBDbG9uZWFibGUgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUU3RydWN0IFNUUlVDVF9ERVNDID0gbmV3IFRTdHJ1Y3QoIlRSZWdpb25JbmZvIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBTVEFSVF9LRVlfRklFTERfREVTQyA9IG5ldyBURmllbGQoInN0YXJ0S2V5IiwgVFR5cGUuU1RSSU5HLCAoc2hvcnQpMSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBFTkRfS0VZX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJlbmRLZXkiLCBUVHlwZS5TVFJJTkcsIChzaG9ydCkyKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVEZpZWxkIElEX0ZJRUxEX0RFU0MgPSBuZXcgVEZpZWxkKCJpZCIsIFRUeXBlLkk2NCwgKHNob3J0KTMpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgTkFNRV9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgibmFtZSIsIFRUeXBlLlNUUklORywgKHNob3J0KTQpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgVkVSU0lPTl9GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgidmVyc2lvbiIsIFRUeXBlLkJZVEUsIChzaG9ydCk1KTsKKworICBwdWJsaWMgYnl0ZVtdIHN0YXJ0S2V5OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVEFSVEtFWSA9IDE7CisgIHB1YmxpYyBieXRlW10gZW5kS2V5OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTkRLRVkgPSAyOworICBwdWJsaWMgbG9uZyBpZDsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSUQgPSAzOworICBwdWJsaWMgYnl0ZVtdIG5hbWU7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5BTUUgPSA0OworICBwdWJsaWMgYnl0ZSB2ZXJzaW9uOworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWRVJTSU9OID0gNTsKKworICBwcml2YXRlIGZpbmFsIElzc2V0IF9faXNzZXQgPSBuZXcgSXNzZXQoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSXNzZXQgaW1wbGVtZW50cyBqYXZhLmlvLlNlcmlhbGl6YWJsZSB7CisgICAgcHVibGljIGJvb2xlYW4gaWQgPSBmYWxzZTsKKyAgICBwdWJsaWMgYm9vbGVhbiB2ZXJzaW9uID0gZmFsc2U7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPiBtZXRhRGF0YU1hcCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZU1hcChuZXcgSGFzaE1hcDxJbnRlZ2VyLCBGaWVsZE1ldGFEYXRhPigpIHt7CisgICAgcHV0KFNUQVJUS0VZLCBuZXcgRmllbGRNZXRhRGF0YSgic3RhcnRLZXkiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChFTkRLRVksIG5ldyBGaWVsZE1ldGFEYXRhKCJlbmRLZXkiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChJRCwgbmV3IEZpZWxkTWV0YURhdGEoImlkIiwgVEZpZWxkUmVxdWlyZW1lbnRUeXBlLkRFRkFVTFQsIAorICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLkk2NCkpKTsKKyAgICBwdXQoTkFNRSwgbmV3IEZpZWxkTWV0YURhdGEoIm5hbWUiLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChWRVJTSU9OLCBuZXcgRmllbGRNZXRhRGF0YSgidmVyc2lvbiIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IEZpZWxkVmFsdWVNZXRhRGF0YShUVHlwZS5CWVRFKSkpOworICB9fSk7CisKKyAgc3RhdGljIHsKKyAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKFRSZWdpb25JbmZvLmNsYXNzLCBtZXRhRGF0YU1hcCk7CisgIH0KKworICBwdWJsaWMgVFJlZ2lvbkluZm8oKSB7CisgIH0KKworICBwdWJsaWMgVFJlZ2lvbkluZm8oCisgICAgYnl0ZVtdIHN0YXJ0S2V5LAorICAgIGJ5dGVbXSBlbmRLZXksCisgICAgbG9uZyBpZCwKKyAgICBieXRlW10gbmFtZSwKKyAgICBieXRlIHZlcnNpb24pCisgIHsKKyAgICB0aGlzKCk7CisgICAgdGhpcy5zdGFydEtleSA9IHN0YXJ0S2V5OworICAgIHRoaXMuZW5kS2V5ID0gZW5kS2V5OworICAgIHRoaXMuaWQgPSBpZDsKKyAgICB0aGlzLl9faXNzZXQuaWQgPSB0cnVlOworICAgIHRoaXMubmFtZSA9IG5hbWU7CisgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKKyAgICB0aGlzLl9faXNzZXQudmVyc2lvbiA9IHRydWU7CisgIH0KKworICAvKioKKyAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgKi8KKyAgcHVibGljIFRSZWdpb25JbmZvKFRSZWdpb25JbmZvIG90aGVyKSB7CisgICAgaWYgKG90aGVyLmlzU2V0U3RhcnRLZXkoKSkgeworICAgICAgdGhpcy5zdGFydEtleSA9IG90aGVyLnN0YXJ0S2V5OworICAgIH0KKyAgICBpZiAob3RoZXIuaXNTZXRFbmRLZXkoKSkgeworICAgICAgdGhpcy5lbmRLZXkgPSBvdGhlci5lbmRLZXk7CisgICAgfQorICAgIF9faXNzZXQuaWQgPSBvdGhlci5fX2lzc2V0LmlkOworICAgIHRoaXMuaWQgPSBvdGhlci5pZDsKKyAgICBpZiAob3RoZXIuaXNTZXROYW1lKCkpIHsKKyAgICAgIHRoaXMubmFtZSA9IG90aGVyLm5hbWU7CisgICAgfQorICAgIF9faXNzZXQudmVyc2lvbiA9IG90aGVyLl9faXNzZXQudmVyc2lvbjsKKyAgICB0aGlzLnZlcnNpb24gPSBvdGhlci52ZXJzaW9uOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBUUmVnaW9uSW5mbyBjbG9uZSgpIHsKKyAgICByZXR1cm4gbmV3IFRSZWdpb25JbmZvKHRoaXMpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRTdGFydEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5zdGFydEtleTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFN0YXJ0S2V5KGJ5dGVbXSBzdGFydEtleSkgeworICAgIHRoaXMuc3RhcnRLZXkgPSBzdGFydEtleTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0U3RhcnRLZXkoKSB7CisgICAgdGhpcy5zdGFydEtleSA9IG51bGw7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgZmllbGQgc3RhcnRLZXkgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRTdGFydEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5zdGFydEtleSAhPSBudWxsOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0U3RhcnRLZXlJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5zdGFydEtleSA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRFbmRLZXkoKSB7CisgICAgcmV0dXJuIHRoaXMuZW5kS2V5OworICB9CisKKyAgcHVibGljIHZvaWQgc2V0RW5kS2V5KGJ5dGVbXSBlbmRLZXkpIHsKKyAgICB0aGlzLmVuZEtleSA9IGVuZEtleTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0RW5kS2V5KCkgeworICAgIHRoaXMuZW5kS2V5ID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBlbmRLZXkgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRFbmRLZXkoKSB7CisgICAgcmV0dXJuIHRoaXMuZW5kS2V5ICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRFbmRLZXlJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5lbmRLZXkgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBsb25nIGdldElkKCkgeworICAgIHJldHVybiB0aGlzLmlkOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0SWQobG9uZyBpZCkgeworICAgIHRoaXMuaWQgPSBpZDsKKyAgICB0aGlzLl9faXNzZXQuaWQgPSB0cnVlOworICB9CisKKyAgcHVibGljIHZvaWQgdW5zZXRJZCgpIHsKKyAgICB0aGlzLl9faXNzZXQuaWQgPSBmYWxzZTsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBpZCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldElkKCkgeworICAgIHJldHVybiB0aGlzLl9faXNzZXQuaWQ7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRJZElzU2V0KGJvb2xlYW4gdmFsdWUpIHsKKyAgICB0aGlzLl9faXNzZXQuaWQgPSB2YWx1ZTsKKyAgfQorCisgIHB1YmxpYyBieXRlW10gZ2V0TmFtZSgpIHsKKyAgICByZXR1cm4gdGhpcy5uYW1lOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0TmFtZShieXRlW10gbmFtZSkgeworICAgIHRoaXMubmFtZSA9IG5hbWU7CisgIH0KKworICBwdWJsaWMgdm9pZCB1bnNldE5hbWUoKSB7CisgICAgdGhpcy5uYW1lID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBuYW1lIGlzIHNldCAoaGFzIGJlZW4gYXNpZ25lZCBhIHZhbHVlKSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCisgIHB1YmxpYyBib29sZWFuIGlzU2V0TmFtZSgpIHsKKyAgICByZXR1cm4gdGhpcy5uYW1lICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXROYW1lSXNTZXQoYm9vbGVhbiB2YWx1ZSkgeworICAgIGlmICghdmFsdWUpIHsKKyAgICAgIHRoaXMubmFtZSA9IG51bGw7CisgICAgfQorICB9CisKKyAgcHVibGljIGJ5dGUgZ2V0VmVyc2lvbigpIHsKKyAgICByZXR1cm4gdGhpcy52ZXJzaW9uOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihieXRlIHZlcnNpb24pIHsKKyAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uOworICAgIHRoaXMuX19pc3NldC52ZXJzaW9uID0gdHJ1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0VmVyc2lvbigpIHsKKyAgICB0aGlzLl9faXNzZXQudmVyc2lvbiA9IGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIHZlcnNpb24gaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRWZXJzaW9uKCkgeworICAgIHJldHVybiB0aGlzLl9faXNzZXQudmVyc2lvbjsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldFZlcnNpb25Jc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgdGhpcy5fX2lzc2V0LnZlcnNpb24gPSB2YWx1ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQsIE9iamVjdCB2YWx1ZSkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgU1RBUlRLRVk6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldFN0YXJ0S2V5KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRTdGFydEtleSgoYnl0ZVtdKXZhbHVlKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBFTkRLRVk6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldEVuZEtleSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0RW5kS2V5KChieXRlW10pdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIElEOgorICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgICAgdW5zZXRJZCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0SWQoKExvbmcpdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIE5BTUU6CisgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgICB1bnNldE5hbWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNldE5hbWUoKGJ5dGVbXSl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgVkVSU0lPTjoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0VmVyc2lvbigpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0VmVyc2lvbigoQnl0ZSl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJGaWVsZCAiICsgZmllbGRJRCArICIgZG9lc24ndCBleGlzdCEiKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgT2JqZWN0IGdldEZpZWxkVmFsdWUoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFNUQVJUS0VZOgorICAgICAgcmV0dXJuIGdldFN0YXJ0S2V5KCk7CisKKyAgICBjYXNlIEVOREtFWToKKyAgICAgIHJldHVybiBnZXRFbmRLZXkoKTsKKworICAgIGNhc2UgSUQ6CisgICAgICByZXR1cm4gbmV3IExvbmcoZ2V0SWQoKSk7CisKKyAgICBjYXNlIE5BTUU6CisgICAgICByZXR1cm4gZ2V0TmFtZSgpOworCisgICAgY2FzZSBWRVJTSU9OOgorICAgICAgcmV0dXJuIG5ldyBCeXRlKGdldFZlcnNpb24oKSk7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvcnJlc3BvbmRpbmcgdG8gZmllbGRJRCBpcyBzZXQgKGhhcyBiZWVuIGFzaWduZWQgYSB2YWx1ZSkgYW5kIGZhbHNlIG90aGVyd2lzZQorICBwdWJsaWMgYm9vbGVhbiBpc1NldChpbnQgZmllbGRJRCkgeworICAgIHN3aXRjaCAoZmllbGRJRCkgeworICAgIGNhc2UgU1RBUlRLRVk6CisgICAgICByZXR1cm4gaXNTZXRTdGFydEtleSgpOworICAgIGNhc2UgRU5ES0VZOgorICAgICAgcmV0dXJuIGlzU2V0RW5kS2V5KCk7CisgICAgY2FzZSBJRDoKKyAgICAgIHJldHVybiBpc1NldElkKCk7CisgICAgY2FzZSBOQU1FOgorICAgICAgcmV0dXJuIGlzU2V0TmFtZSgpOworICAgIGNhc2UgVkVSU0lPTjoKKyAgICAgIHJldHVybiBpc1NldFZlcnNpb24oKTsKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBUUmVnaW9uSW5mbykKKyAgICAgIHJldHVybiB0aGlzLmVxdWFscygoVFJlZ2lvbkluZm8pdGhhdCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKFRSZWdpb25JbmZvIHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfc3RhcnRLZXkgPSB0cnVlICYmIHRoaXMuaXNTZXRTdGFydEtleSgpOworICAgIGJvb2xlYW4gdGhhdF9wcmVzZW50X3N0YXJ0S2V5ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0U3RhcnRLZXkoKTsKKyAgICBpZiAodGhpc19wcmVzZW50X3N0YXJ0S2V5IHx8IHRoYXRfcHJlc2VudF9zdGFydEtleSkgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X3N0YXJ0S2V5ICYmIHRoYXRfcHJlc2VudF9zdGFydEtleSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy5zdGFydEtleSwgdGhhdC5zdGFydEtleSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF9lbmRLZXkgPSB0cnVlICYmIHRoaXMuaXNTZXRFbmRLZXkoKTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9lbmRLZXkgPSB0cnVlICYmIHRoYXQuaXNTZXRFbmRLZXkoKTsKKyAgICBpZiAodGhpc19wcmVzZW50X2VuZEtleSB8fCB0aGF0X3ByZXNlbnRfZW5kS2V5KSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfZW5kS2V5ICYmIHRoYXRfcHJlc2VudF9lbmRLZXkpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuZW5kS2V5LCB0aGF0LmVuZEtleSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF9pZCA9IHRydWU7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfaWQgPSB0cnVlOworICAgIGlmICh0aGlzX3ByZXNlbnRfaWQgfHwgdGhhdF9wcmVzZW50X2lkKSB7CisgICAgICBpZiAoISh0aGlzX3ByZXNlbnRfaWQgJiYgdGhhdF9wcmVzZW50X2lkKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoaXMuaWQgIT0gdGhhdC5pZCkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGJvb2xlYW4gdGhpc19wcmVzZW50X25hbWUgPSB0cnVlICYmIHRoaXMuaXNTZXROYW1lKCk7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfbmFtZSA9IHRydWUgJiYgdGhhdC5pc1NldE5hbWUoKTsKKyAgICBpZiAodGhpc19wcmVzZW50X25hbWUgfHwgdGhhdF9wcmVzZW50X25hbWUpIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF9uYW1lICYmIHRoYXRfcHJlc2VudF9uYW1lKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLm5hbWUsIHRoYXQubmFtZSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBib29sZWFuIHRoaXNfcHJlc2VudF92ZXJzaW9uID0gdHJ1ZTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF92ZXJzaW9uID0gdHJ1ZTsKKyAgICBpZiAodGhpc19wcmVzZW50X3ZlcnNpb24gfHwgdGhhdF9wcmVzZW50X3ZlcnNpb24pIHsKKyAgICAgIGlmICghKHRoaXNfcHJlc2VudF92ZXJzaW9uICYmIHRoYXRfcHJlc2VudF92ZXJzaW9uKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHRoaXMudmVyc2lvbiAhPSB0aGF0LnZlcnNpb24pCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIHZvaWQgcmVhZChUUHJvdG9jb2wgaXByb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICBURmllbGQgZmllbGQ7CisgICAgaXByb3QucmVhZFN0cnVjdEJlZ2luKCk7CisgICAgd2hpbGUgKHRydWUpCisgICAgeworICAgICAgZmllbGQgPSBpcHJvdC5yZWFkRmllbGRCZWdpbigpOworICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RPUCkgeyAKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBzd2l0Y2ggKGZpZWxkLmlkKQorICAgICAgeworICAgICAgICBjYXNlIFNUQVJUS0VZOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5zdGFydEtleSA9IGlwcm90LnJlYWRCaW5hcnkoKTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEVOREtFWToKKyAgICAgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVFJJTkcpIHsKKyAgICAgICAgICAgIHRoaXMuZW5kS2V5ID0gaXByb3QucmVhZEJpbmFyeSgpOworICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgSUQ6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuSTY0KSB7CisgICAgICAgICAgICB0aGlzLmlkID0gaXByb3QucmVhZEk2NCgpOworICAgICAgICAgICAgdGhpcy5fX2lzc2V0LmlkID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgeyAKKyAgICAgICAgICAgIFRQcm90b2NvbFV0aWwuc2tpcChpcHJvdCwgZmllbGQudHlwZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIE5BTUU6CisgICAgICAgICAgaWYgKGZpZWxkLnR5cGUgPT0gVFR5cGUuU1RSSU5HKSB7CisgICAgICAgICAgICB0aGlzLm5hbWUgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBWRVJTSU9OOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLkJZVEUpIHsKKyAgICAgICAgICAgIHRoaXMudmVyc2lvbiA9IGlwcm90LnJlYWRCeXRlKCk7CisgICAgICAgICAgICB0aGlzLl9faXNzZXQudmVyc2lvbiA9IHRydWU7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaXByb3QucmVhZEZpZWxkRW5kKCk7CisgICAgfQorICAgIGlwcm90LnJlYWRTdHJ1Y3RFbmQoKTsKKworCisgICAgLy8gY2hlY2sgZm9yIHJlcXVpcmVkIGZpZWxkcyBvZiBwcmltaXRpdmUgdHlwZSwgd2hpY2ggY2FuJ3QgYmUgY2hlY2tlZCBpbiB0aGUgdmFsaWRhdGUgbWV0aG9kCisgICAgdmFsaWRhdGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHdyaXRlKFRQcm90b2NvbCBvcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIHZhbGlkYXRlKCk7CisKKyAgICBvcHJvdC53cml0ZVN0cnVjdEJlZ2luKFNUUlVDVF9ERVNDKTsKKyAgICBpZiAodGhpcy5zdGFydEtleSAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oU1RBUlRfS0VZX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5zdGFydEtleSk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgfQorICAgIGlmICh0aGlzLmVuZEtleSAhPSBudWxsKSB7CisgICAgICBvcHJvdC53cml0ZUZpZWxkQmVnaW4oRU5EX0tFWV9GSUVMRF9ERVNDKTsKKyAgICAgIG9wcm90LndyaXRlQmluYXJ5KHRoaXMuZW5kS2V5KTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKElEX0ZJRUxEX0RFU0MpOworICAgIG9wcm90LndyaXRlSTY0KHRoaXMuaWQpOworICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICBpZiAodGhpcy5uYW1lICE9IG51bGwpIHsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihOQU1FX0ZJRUxEX0RFU0MpOworICAgICAgb3Byb3Qud3JpdGVCaW5hcnkodGhpcy5uYW1lKTsKKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKFZFUlNJT05fRklFTERfREVTQyk7CisgICAgb3Byb3Qud3JpdGVCeXRlKHRoaXMudmVyc2lvbik7CisgICAgb3Byb3Qud3JpdGVGaWVsZEVuZCgpOworICAgIG9wcm90LndyaXRlRmllbGRTdG9wKCk7CisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RFbmQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgeworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigiVFJlZ2lvbkluZm8oIik7CisgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisKKyAgICBzYi5hcHBlbmQoInN0YXJ0S2V5OiIpOworICAgIGlmICh0aGlzLnN0YXJ0S2V5ID09IG51bGwpIHsKKyAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgIH0gZWxzZSB7CisgICAgICBzYi5hcHBlbmQodGhpcy5zdGFydEtleSk7CisgICAgfQorICAgIGZpcnN0ID0gZmFsc2U7CisgICAgaWYgKCFmaXJzdCkgc2IuYXBwZW5kKCIsICIpOworICAgIHNiLmFwcGVuZCgiZW5kS2V5OiIpOworICAgIGlmICh0aGlzLmVuZEtleSA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMuZW5kS2V5KTsKKyAgICB9CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJpZDoiKTsKKyAgICBzYi5hcHBlbmQodGhpcy5pZCk7CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBpZiAoIWZpcnN0KSBzYi5hcHBlbmQoIiwgIik7CisgICAgc2IuYXBwZW5kKCJuYW1lOiIpOworICAgIGlmICh0aGlzLm5hbWUgPT0gbnVsbCkgeworICAgICAgc2IuYXBwZW5kKCJudWxsIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHNiLmFwcGVuZCh0aGlzLm5hbWUpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICBzYi5hcHBlbmQoInZlcnNpb246Iik7CisgICAgc2IuYXBwZW5kKHRoaXMudmVyc2lvbik7CisgICAgZmlyc3QgPSBmYWxzZTsKKyAgICBzYi5hcHBlbmQoIikiKTsKKyAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMKKyAgICAvLyBjaGVjayB0aGF0IGZpZWxkcyBvZiB0eXBlIGVudW0gaGF2ZSB2YWxpZCB2YWx1ZXMKKyAgfQorCit9CisKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9nZW5lcmF0ZWQvVFJvd1Jlc3VsdC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L2dlbmVyYXRlZC9UUm93UmVzdWx0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzAwZWI1OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9nZW5lcmF0ZWQvVFJvd1Jlc3VsdC5qYXZhCkBAIC0wLDAgKzEsMzU4IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy8qKgorICogQXV0b2dlbmVyYXRlZCBieSBUaHJpZnQKKyAqCisgKiBETyBOT1QgRURJVCBVTkxFU1MgWU9VIEFSRSBTVVJFIFRIQVQgWU9VIEtOT1cgV0hBVCBZT1UgQVJFIERPSU5HCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZDsKKworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKKworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0Lio7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQubWV0YV9kYXRhLio7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQucHJvdG9jb2wuKjsKKworLyoqCisgKiBIb2xkcyByb3cgbmFtZSBhbmQgdGhlbiBhIG1hcCBvZiBjb2x1bW5zIHRvIGNlbGxzLgorICovCitwdWJsaWMgY2xhc3MgVFJvd1Jlc3VsdCBpbXBsZW1lbnRzIFRCYXNlLCBqYXZhLmlvLlNlcmlhbGl6YWJsZSwgQ2xvbmVhYmxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVFN0cnVjdCBTVFJVQ1RfREVTQyA9IG5ldyBUU3RydWN0KCJUUm93UmVzdWx0Iik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRGaWVsZCBST1dfRklFTERfREVTQyA9IG5ldyBURmllbGQoInJvdyIsIFRUeXBlLlNUUklORywgKHNob3J0KTEpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBURmllbGQgQ09MVU1OU19GSUVMRF9ERVNDID0gbmV3IFRGaWVsZCgiY29sdW1ucyIsIFRUeXBlLk1BUCwgKHNob3J0KTIpOworCisgIHB1YmxpYyBieXRlW10gcm93OworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBST1cgPSAxOworICBwdWJsaWMgTWFwPGJ5dGVbXSxUQ2VsbD4gY29sdW1uczsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OUyA9IDI7CisKKyAgcHJpdmF0ZSBmaW5hbCBJc3NldCBfX2lzc2V0ID0gbmV3IElzc2V0KCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIElzc2V0IGltcGxlbWVudHMgamF2YS5pby5TZXJpYWxpemFibGUgeworICB9CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4gbWV0YURhdGFNYXAgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVNYXAobmV3IEhhc2hNYXA8SW50ZWdlciwgRmllbGRNZXRhRGF0YT4oKSB7eworICAgIHB1dChST1csIG5ldyBGaWVsZE1ldGFEYXRhKCJyb3ciLCBURmllbGRSZXF1aXJlbWVudFR5cGUuREVGQVVMVCwgCisgICAgICAgIG5ldyBGaWVsZFZhbHVlTWV0YURhdGEoVFR5cGUuU1RSSU5HKSkpOworICAgIHB1dChDT0xVTU5TLCBuZXcgRmllbGRNZXRhRGF0YSgiY29sdW1ucyIsIFRGaWVsZFJlcXVpcmVtZW50VHlwZS5ERUZBVUxULCAKKyAgICAgICAgbmV3IE1hcE1ldGFEYXRhKFRUeXBlLk1BUCwgCisgICAgICAgICAgICBuZXcgRmllbGRWYWx1ZU1ldGFEYXRhKFRUeXBlLlNUUklORyksIAorICAgICAgICAgICAgbmV3IFN0cnVjdE1ldGFEYXRhKFRUeXBlLlNUUlVDVCwgVENlbGwuY2xhc3MpKSkpOworICB9fSk7CisKKyAgc3RhdGljIHsKKyAgICBGaWVsZE1ldGFEYXRhLmFkZFN0cnVjdE1ldGFEYXRhTWFwKFRSb3dSZXN1bHQuY2xhc3MsIG1ldGFEYXRhTWFwKTsKKyAgfQorCisgIHB1YmxpYyBUUm93UmVzdWx0KCkgeworICB9CisKKyAgcHVibGljIFRSb3dSZXN1bHQoCisgICAgYnl0ZVtdIHJvdywKKyAgICBNYXA8Ynl0ZVtdLFRDZWxsPiBjb2x1bW5zKQorICB7CisgICAgdGhpcygpOworICAgIHRoaXMucm93ID0gcm93OworICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7CisgIH0KKworICAvKioKKyAgICogUGVyZm9ybXMgYSBkZWVwIGNvcHkgb24gPGk+b3RoZXI8L2k+LgorICAgKi8KKyAgcHVibGljIFRSb3dSZXN1bHQoVFJvd1Jlc3VsdCBvdGhlcikgeworICAgIGlmIChvdGhlci5pc1NldFJvdygpKSB7CisgICAgICB0aGlzLnJvdyA9IG90aGVyLnJvdzsKKyAgICB9CisgICAgaWYgKG90aGVyLmlzU2V0Q29sdW1ucygpKSB7CisgICAgICBNYXA8Ynl0ZVtdLFRDZWxsPiBfX3RoaXNfX2NvbHVtbnMgPSBuZXcgSGFzaE1hcDxieXRlW10sVENlbGw+KCk7CisgICAgICBmb3IgKE1hcC5FbnRyeTxieXRlW10sIFRDZWxsPiBvdGhlcl9lbGVtZW50IDogb3RoZXIuY29sdW1ucy5lbnRyeVNldCgpKSB7CisKKyAgICAgICAgYnl0ZVtdIG90aGVyX2VsZW1lbnRfa2V5ID0gb3RoZXJfZWxlbWVudC5nZXRLZXkoKTsKKyAgICAgICAgVENlbGwgb3RoZXJfZWxlbWVudF92YWx1ZSA9IG90aGVyX2VsZW1lbnQuZ2V0VmFsdWUoKTsKKworICAgICAgICBieXRlW10gX190aGlzX19jb2x1bW5zX2NvcHlfa2V5ID0gb3RoZXJfZWxlbWVudF9rZXk7CisKKyAgICAgICAgVENlbGwgX190aGlzX19jb2x1bW5zX2NvcHlfdmFsdWUgPSBuZXcgVENlbGwob3RoZXJfZWxlbWVudF92YWx1ZSk7CisKKyAgICAgICAgX190aGlzX19jb2x1bW5zLnB1dChfX3RoaXNfX2NvbHVtbnNfY29weV9rZXksIF9fdGhpc19fY29sdW1uc19jb3B5X3ZhbHVlKTsKKyAgICAgIH0KKyAgICAgIHRoaXMuY29sdW1ucyA9IF9fdGhpc19fY29sdW1uczsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFRSb3dSZXN1bHQgY2xvbmUoKSB7CisgICAgcmV0dXJuIG5ldyBUUm93UmVzdWx0KHRoaXMpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBnZXRSb3coKSB7CisgICAgcmV0dXJuIHRoaXMucm93OworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Um93KGJ5dGVbXSByb3cpIHsKKyAgICB0aGlzLnJvdyA9IHJvdzsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Um93KCkgeworICAgIHRoaXMucm93ID0gbnVsbDsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCByb3cgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRSb3coKSB7CisgICAgcmV0dXJuIHRoaXMucm93ICE9IG51bGw7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRSb3dJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5yb3cgPSBudWxsOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uc1NpemUoKSB7CisgICAgcmV0dXJuICh0aGlzLmNvbHVtbnMgPT0gbnVsbCkgPyAwIDogdGhpcy5jb2x1bW5zLnNpemUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHB1dFRvQ29sdW1ucyhieXRlW10ga2V5LCBUQ2VsbCB2YWwpIHsKKyAgICBpZiAodGhpcy5jb2x1bW5zID09IG51bGwpIHsKKyAgICAgIHRoaXMuY29sdW1ucyA9IG5ldyBIYXNoTWFwPGJ5dGVbXSxUQ2VsbD4oKTsKKyAgICB9CisgICAgdGhpcy5jb2x1bW5zLnB1dChrZXksIHZhbCk7CisgIH0KKworICBwdWJsaWMgTWFwPGJ5dGVbXSxUQ2VsbD4gZ2V0Q29sdW1ucygpIHsKKyAgICByZXR1cm4gdGhpcy5jb2x1bW5zOworICB9CisKKyAgcHVibGljIHZvaWQgc2V0Q29sdW1ucyhNYXA8Ynl0ZVtdLFRDZWxsPiBjb2x1bW5zKSB7CisgICAgdGhpcy5jb2x1bW5zID0gY29sdW1uczsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHVuc2V0Q29sdW1ucygpIHsKKyAgICB0aGlzLmNvbHVtbnMgPSBudWxsOworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIGZpZWxkIGNvbHVtbnMgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXRDb2x1bW5zKCkgeworICAgIHJldHVybiB0aGlzLmNvbHVtbnMgIT0gbnVsbDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldENvbHVtbnNJc1NldChib29sZWFuIHZhbHVlKSB7CisgICAgaWYgKCF2YWx1ZSkgeworICAgICAgdGhpcy5jb2x1bW5zID0gbnVsbDsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRGaWVsZFZhbHVlKGludCBmaWVsZElELCBPYmplY3QgdmFsdWUpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFJPVzoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0Um93KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRSb3coKGJ5dGVbXSl2YWx1ZSk7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CisgICAgICAgIHVuc2V0Q29sdW1ucygpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc2V0Q29sdW1ucygoTWFwPGJ5dGVbXSxUQ2VsbD4pdmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgcHVibGljIE9iamVjdCBnZXRGaWVsZFZhbHVlKGludCBmaWVsZElEKSB7CisgICAgc3dpdGNoIChmaWVsZElEKSB7CisgICAgY2FzZSBST1c6CisgICAgICByZXR1cm4gZ2V0Um93KCk7CisKKyAgICBjYXNlIENPTFVNTlM6CisgICAgICByZXR1cm4gZ2V0Q29sdW1ucygpOworCisgICAgZGVmYXVsdDoKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkZpZWxkICIgKyBmaWVsZElEICsgIiBkb2Vzbid0IGV4aXN0ISIpOworICAgIH0KKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZCBjb3JyZXNwb25kaW5nIHRvIGZpZWxkSUQgaXMgc2V0IChoYXMgYmVlbiBhc2lnbmVkIGEgdmFsdWUpIGFuZCBmYWxzZSBvdGhlcndpc2UKKyAgcHVibGljIGJvb2xlYW4gaXNTZXQoaW50IGZpZWxkSUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkSUQpIHsKKyAgICBjYXNlIFJPVzoKKyAgICAgIHJldHVybiBpc1NldFJvdygpOworICAgIGNhc2UgQ09MVU1OUzoKKyAgICAgIHJldHVybiBpc1NldENvbHVtbnMoKTsKKyAgICBkZWZhdWx0OgorICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmllbGQgIiArIGZpZWxkSUQgKyAiIGRvZXNuJ3QgZXhpc3QhIik7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgdGhhdCkgeworICAgIGlmICh0aGF0ID09IG51bGwpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgaWYgKHRoYXQgaW5zdGFuY2VvZiBUUm93UmVzdWx0KQorICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKChUUm93UmVzdWx0KXRoYXQpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGVxdWFscyhUUm93UmVzdWx0IHRoYXQpIHsKKyAgICBpZiAodGhhdCA9PSBudWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGlzLmlzU2V0Um93KCk7CisgICAgYm9vbGVhbiB0aGF0X3ByZXNlbnRfcm93ID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Um93KCk7CisgICAgaWYgKHRoaXNfcHJlc2VudF9yb3cgfHwgdGhhdF9wcmVzZW50X3JvdykgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X3JvdyAmJiB0aGF0X3ByZXNlbnRfcm93KSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLnJvdywgdGhhdC5yb3cpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbGVhbiB0aGlzX3ByZXNlbnRfY29sdW1ucyA9IHRydWUgJiYgdGhpcy5pc1NldENvbHVtbnMoKTsKKyAgICBib29sZWFuIHRoYXRfcHJlc2VudF9jb2x1bW5zID0gdHJ1ZSAmJiB0aGF0LmlzU2V0Q29sdW1ucygpOworICAgIGlmICh0aGlzX3ByZXNlbnRfY29sdW1ucyB8fCB0aGF0X3ByZXNlbnRfY29sdW1ucykgeworICAgICAgaWYgKCEodGhpc19wcmVzZW50X2NvbHVtbnMgJiYgdGhhdF9wcmVzZW50X2NvbHVtbnMpKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIXRoaXMuY29sdW1ucy5lcXVhbHModGhhdC5jb2x1bW5zKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBwdWJsaWMgdm9pZCByZWFkKFRQcm90b2NvbCBpcHJvdCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgIFRGaWVsZCBmaWVsZDsKKyAgICBpcHJvdC5yZWFkU3RydWN0QmVnaW4oKTsKKyAgICB3aGlsZSAodHJ1ZSkKKyAgICB7CisgICAgICBmaWVsZCA9IGlwcm90LnJlYWRGaWVsZEJlZ2luKCk7CisgICAgICBpZiAoZmllbGQudHlwZSA9PSBUVHlwZS5TVE9QKSB7IAorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIHN3aXRjaCAoZmllbGQuaWQpCisgICAgICB7CisgICAgICAgIGNhc2UgUk9XOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLlNUUklORykgeworICAgICAgICAgICAgdGhpcy5yb3cgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgfSBlbHNlIHsgCisgICAgICAgICAgICBUUHJvdG9jb2xVdGlsLnNraXAoaXByb3QsIGZpZWxkLnR5cGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBDT0xVTU5TOgorICAgICAgICAgIGlmIChmaWVsZC50eXBlID09IFRUeXBlLk1BUCkgeworICAgICAgICAgICAgeworICAgICAgICAgICAgICBUTWFwIF9tYXA0ID0gaXByb3QucmVhZE1hcEJlZ2luKCk7CisgICAgICAgICAgICAgIHRoaXMuY29sdW1ucyA9IG5ldyBIYXNoTWFwPGJ5dGVbXSxUQ2VsbD4oMipfbWFwNC5zaXplKTsKKyAgICAgICAgICAgICAgZm9yIChpbnQgX2k1ID0gMDsgX2k1IDwgX21hcDQuc2l6ZTsgKytfaTUpCisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBieXRlW10gX2tleTY7CisgICAgICAgICAgICAgICAgVENlbGwgX3ZhbDc7CisgICAgICAgICAgICAgICAgX2tleTYgPSBpcHJvdC5yZWFkQmluYXJ5KCk7CisgICAgICAgICAgICAgICAgX3ZhbDcgPSBuZXcgVENlbGwoKTsKKyAgICAgICAgICAgICAgICBfdmFsNy5yZWFkKGlwcm90KTsKKyAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbnMucHV0KF9rZXk2LCBfdmFsNyk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgaXByb3QucmVhZE1hcEVuZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0gZWxzZSB7IAorICAgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgVFByb3RvY29sVXRpbC5za2lwKGlwcm90LCBmaWVsZC50eXBlKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlwcm90LnJlYWRGaWVsZEVuZCgpOworICAgIH0KKyAgICBpcHJvdC5yZWFkU3RydWN0RW5kKCk7CisKKworICAgIC8vIGNoZWNrIGZvciByZXF1aXJlZCBmaWVsZHMgb2YgcHJpbWl0aXZlIHR5cGUsIHdoaWNoIGNhbid0IGJlIGNoZWNrZWQgaW4gdGhlIHZhbGlkYXRlIG1ldGhvZAorICAgIHZhbGlkYXRlKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB3cml0ZShUUHJvdG9jb2wgb3Byb3QpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSgpOworCisgICAgb3Byb3Qud3JpdGVTdHJ1Y3RCZWdpbihTVFJVQ1RfREVTQyk7CisgICAgaWYgKHRoaXMucm93ICE9IG51bGwpIHsKKyAgICAgIG9wcm90LndyaXRlRmllbGRCZWdpbihST1dfRklFTERfREVTQyk7CisgICAgICBvcHJvdC53cml0ZUJpbmFyeSh0aGlzLnJvdyk7CisgICAgICBvcHJvdC53cml0ZUZpZWxkRW5kKCk7CisgICAgfQorICAgIGlmICh0aGlzLmNvbHVtbnMgIT0gbnVsbCkgeworICAgICAgb3Byb3Qud3JpdGVGaWVsZEJlZ2luKENPTFVNTlNfRklFTERfREVTQyk7CisgICAgICB7CisgICAgICAgIG9wcm90LndyaXRlTWFwQmVnaW4obmV3IFRNYXAoVFR5cGUuU1RSSU5HLCBUVHlwZS5TVFJVQ1QsIHRoaXMuY29sdW1ucy5zaXplKCkpKTsKKyAgICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZVtdLCBUQ2VsbD4gX2l0ZXI4IDogdGhpcy5jb2x1bW5zLmVudHJ5U2V0KCkpICAgICAgICB7CisgICAgICAgICAgb3Byb3Qud3JpdGVCaW5hcnkoX2l0ZXI4LmdldEtleSgpKTsKKyAgICAgICAgICBfaXRlcjguZ2V0VmFsdWUoKS53cml0ZShvcHJvdCk7CisgICAgICAgIH0KKyAgICAgICAgb3Byb3Qud3JpdGVNYXBFbmQoKTsKKyAgICAgIH0KKyAgICAgIG9wcm90LndyaXRlRmllbGRFbmQoKTsKKyAgICB9CisgICAgb3Byb3Qud3JpdGVGaWVsZFN0b3AoKTsKKyAgICBvcHJvdC53cml0ZVN0cnVjdEVuZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJUUm93UmVzdWx0KCIpOworICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworCisgICAgc2IuYXBwZW5kKCJyb3c6Iik7CisgICAgaWYgKHRoaXMucm93ID09IG51bGwpIHsKKyAgICAgIHNiLmFwcGVuZCgibnVsbCIpOworICAgIH0gZWxzZSB7CisgICAgICBzYi5hcHBlbmQodGhpcy5yb3cpOworICAgIH0KKyAgICBmaXJzdCA9IGZhbHNlOworICAgIGlmICghZmlyc3QpIHNiLmFwcGVuZCgiLCAiKTsKKyAgICBzYi5hcHBlbmQoImNvbHVtbnM6Iik7CisgICAgaWYgKHRoaXMuY29sdW1ucyA9PSBudWxsKSB7CisgICAgICBzYi5hcHBlbmQoIm51bGwiKTsKKyAgICB9IGVsc2UgeworICAgICAgc2IuYXBwZW5kKHRoaXMuY29sdW1ucyk7CisgICAgfQorICAgIGZpcnN0ID0gZmFsc2U7CisgICAgc2IuYXBwZW5kKCIpIik7CisgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB2YWxpZGF0ZSgpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAvLyBjaGVjayBmb3IgcmVxdWlyZWQgZmllbGRzCisgICAgLy8gY2hlY2sgdGhhdCBmaWVsZHMgb2YgdHlwZSBlbnVtIGhhdmUgdmFsaWQgdmFsdWVzCisgIH0KKworfQorCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvcGFja2FnZS5odG1sIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L3BhY2thZ2UuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MWQ2NjlkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L3BhY2thZ2UuaHRtbApAQCAtMCwwICsxLDc4IEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgMy4yIEZpbmFsLy9FTiI+Cis8aHRtbD4KKworPCEtLQorICAgTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgICBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAgIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAgIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgICAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICAgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy0tPgorCis8aGVhZCAvPgorPGJvZHkgYmdjb2xvcj0id2hpdGUiPgorUHJvdmlkZXMgYW4gSEJhc2UgPGEgaHJlZj0iaHR0cDovL2RldmVsb3BlcnMuZmFjZWJvb2suY29tL3RocmlmdC8iPlRocmlmdDwvYT4KK3NlcnZpY2UuCisKK1RoaXMgZGlyZWN0b3J5IGNvbnRhaW5zIGEgVGhyaWZ0IGludGVyZmFjZSBkZWZpbml0aW9uIGZpbGUgZm9yIGFuIEhiYXNlIFJQQworc2VydmljZSBhbmQgYSBKYXZhIHNlcnZlciBpbXBsZW1lbnRhdGlvbi4KKworPGgyPjxhIG5hbWU9IndoYXRpc3RocmlmdCI+V2hhdCBpcyBUaHJpZnQ/PC9hPjwvaDI+IAorCis8cD4iVGhyaWZ0IGlzIGEgc29mdHdhcmUgZnJhbWV3b3JrIGZvciBzY2FsYWJsZSBjcm9zcy1sYW5ndWFnZSBzZXJ2aWNlcworZGV2ZWxvcG1lbnQuIEl0IGNvbWJpbmVzIGEgcG93ZXJmdWwgc29mdHdhcmUgc3RhY2sgd2l0aCBhIGNvZGUgZ2VuZXJhdGlvbgorZW5naW5lIHRvIGJ1aWxkIHNlcnZpY2VzIHRoYXQgd29yayBlZmZpY2llbnRseSBhbmQgc2VhbWxlc3NseSBiZXR3ZWVuIEMrKywKK0phdmEsIFB5dGhvbiwgUEhQLCBhbmQgUnVieS4gVGhyaWZ0IHdhcyBkZXZlbG9wZWQgYXQgRmFjZWJvb2ssIGFuZCB3ZSBhcmUgbm93CityZWxlYXNpbmcgaXQgYXMgb3BlbiBzb3VyY2UuIiAgRm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24sIHNlZQoraHR0cDovL2RldmVsb3BlcnMuZmFjZWJvb2suY29tL3RocmlmdC8uICBGYWNlYm9vayBoYXMgYW5ub3VuY2VkIHRoZWlyIGludGVudAordG8gbWlncmF0ZSBUaHJpZnQgaW50byBBcGFjaGUgSW5jdWJhdG9yLgorPC9wPgorCis8aDI+PGEgbmFtZT0iZGVzY3JpcHRpb24iPkRlc2NyaXB0aW9uPC9hPjwvaDI+CisKKzxwPlRoZSA8YSBocmVmPSJnZW5lcmF0ZWQvSGJhc2UuSWZhY2UuaHRtbCI+SGJhc2UgQVBJPC9hPiBpcyBkZWZpbmVkIGluIHRoZQorZmlsZSBIYmFzZS50aHJpZnQuICBBIHNlcnZlci1zaWRlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBUEkgaXMgaW4ge0BsaW5rCitvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuVGhyaWZ0U2VydmVyfS4gIFRoZSBnZW5lcmF0ZWQgaW50ZXJmYWNlcywKK3R5cGVzLCBhbmQgUlBDIHV0aWxpdHkgZmlsZXMgYXJlIGNoZWNrZWQgaW50byBTVk4gdW5kZXIgdGhlIHtAbGluaworb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZH0gZGlyZWN0b3J5LgorCis8L3A+CisKKzxwPlRoZSBmaWxlcyB3ZXJlIGdlbmVyYXRlZCBieSBydW5uaW5nIHRoZSBjb21tYW5kczoKKzxwcmU+CisgIHRocmlmdCAtc3RyaWN0IC0tZ2VuIGphdmEgSGJhc2UudGhyaWZ0CisgIG12IGdlbi1qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3RocmlmdC9nZW5lcmF0ZWQgLgorICBybSAtcmYgZ2VuLWphdmEKKzwvcHJlPgorPC9wPgorCis8cD5UaGUgJ3RocmlmdCcgYmluYXJ5IGlzIHRoZSBUaHJpZnQgY29tcGlsZXIsIGFuZCBpdCBpcyBkaXN0cmlidXRlZCBhcyBhIHBhcnQKK29mCit0aGUgVGhyaWZ0IHBhY2thZ2UuICBBZGRpdGlvbmFsbHksIHNwZWNpZmljIGxhbmd1YWdlIHJ1bnRpbWUgbGlicmFyaWVzIGFyZSBhCitwYXJ0IG9mIHRoZSBUaHJpZnQgcGFja2FnZS4gIEEgdmVyc2lvbiBvZiB0aGUgSmF2YSBydW50aW1lIGlzIGNoZWNrZWQgaW50byBTVk4KK3VuZGVyIHRoZSBoYmFzZS9saWIgZGlyZWN0b3J5LgorPC9wPgorCis8cD5UbyBzdGFydCBUaHJpZnRTZXJ2ZXIsIHVzZToKKzxwcmU+CisgIC4vYmluL2hiYXNlLWRhZW1vbi5zaCBzdGFydCB0aHJpZnQgWy0tcG9ydD1QT1JUXQorPC9wcmU+CitUaGUgZGVmYXVsdCBwb3J0IGlzIDkwOTAuCis8L3A+CisKKzxwPlRvIHN0b3AsIHVzZToKKzxwcmU+CisgIC4vYmluL2hiYXNlLWRhZW1vbi5zaCBzdG9wIHRocmlmdAorPC9wcmU+Cis8L3A+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0Jhc2U2NC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9CYXNlNjQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjdhZjc3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9CYXNlNjQuamF2YQpAQCAtMCwwICsxLDE2MzggQEAKKy8qKgorICogRW5jb2RlcyBhbmQgZGVjb2RlcyB0byBhbmQgZnJvbSBCYXNlNjQgbm90YXRpb24uCisgKiAKKyAqIDxwPgorICogSG9tZXBhZ2U6IDxhIGhyZWY9Imh0dHA6Ly9paGFyZGVyLm5ldC9iYXNlNjQiPmh0dHA6Ly9paGFyZGVyLm5ldC9iYXNlNjQ8L2E+LgorICogPC9wPgorICoKKyAqIDxwPgorICogQ2hhbmdlIExvZzoKKyAqIDwvcD4KKyAqIDx1bD4KKyAqICAgPGxpPnYyLjIuMSAtIEZpeGVkIGJ1ZyB1c2luZyBVUkxfU0FGRSBhbmQgT1JERVJFRCBlbmNvZGluZ3MuIEZpeGVkIGJ1ZworICogICAgIHdoZW4gdXNpbmcgdmVyeSBzbWFsbCBmaWxlcyAofjwgNDAgYnl0ZXMpLjwvbGk+CisgKiAgIDxsaT52Mi4yIC0gQWRkZWQgc29tZSBoZWxwZXIgbWV0aG9kcyBmb3IgZW5jb2RpbmcvZGVjb2RpbmcgZGlyZWN0bHkgZnJvbQorICogICAgIG9uZSBmaWxlIHRvIHRoZSBuZXh0LiBBbHNvIGFkZGVkIGEgbWFpbigpIG1ldGhvZCB0byBzdXBwb3J0IGNvbW1hbmQKKyAqICAgICBsaW5lIGVuY29kaW5nL2RlY29kaW5nIGZyb20gb25lIGZpbGUgdG8gdGhlIG5leHQuIEFsc28gYWRkZWQgdGhlc2UKKyAqICAgICBCYXNlNjQgZGlhbGVjdHM6CisgKiAgICAgPG9sPgorICogICAgICAgPGxpPlRoZSBkZWZhdWx0IGlzIFJGQzM1NDggZm9ybWF0LjwvbGk+CisgKiAgICAgICA8bGk+VXNpbmcgQmFzZTY0LlVSTFNBRkUgZ2VuZXJhdGVzIFVSTCBhbmQgZmlsZSBuYW1lIGZyaWVuZGx5IGZvcm1hdCBhcworICogICAgICAgICBkZXNjcmliZWQgaW4gU2VjdGlvbiA0IG9mIFJGQzM1NDguCisgKiAgICAgICAgIGh0dHA6Ly93d3cuZmFxcy5vcmcvcmZjcy9yZmMzNTQ4Lmh0bWw8L2xpPgorICogICAgICAgPGxpPlVzaW5nIEJhc2U2NC5PUkRFUkVEIGdlbmVyYXRlcyBVUkwgYW5kIGZpbGUgbmFtZSBmcmllbmRseSBmb3JtYXQKKyAqICAgICAgICAgdGhhdCBwcmVzZXJ2ZXMgbGV4aWNhbCBvcmRlcmluZyBhcyBkZXNjcmliZWQgaW4KKyAqICAgICAgICAgaHR0cDovL3d3dy5mYXFzLm9yZy9xYS9yZmNjLTE5NDAuaHRtbDwvbGk+CisgKiAgICAgPC9vbD4KKyAqICAgICA8cD4KKyAqICAgICBTcGVjaWFsIHRoYW5rcyB0byBKaW0gS2VsbGVybWFuIGF0IDxhIGhyZWY9Imh0dHA6Ly93d3cucG93ZXJzZXQuY29tLyI+CisgKiAgICAgaHR0cDovL3d3dy5wb3dlcnNldC5jb20vPC9hPiBmb3IgY29udHJpYnV0aW5nIHRoZSBuZXcgQmFzZTY0IGRpYWxlY3RzLgorICogICA8L2xpPgorICogCisgKiAgIDxsaT52Mi4xIC0gQ2xlYW5lZCB1cCBqYXZhZG9jIGNvbW1lbnRzIGFuZCB1bnVzZWQgdmFyaWFibGVzIGFuZCBtZXRob2RzLgorICogICAgIEFkZGVkIHNvbWUgY29udmVuaWVuY2UgbWV0aG9kcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyB0byBhbmQgZnJvbSBmaWxlcy4KKyAqICAgPC9saT4KKyAqICAgPGxpPnYyLjAuMiAtIE5vdyBzcGVjaWZpZXMgVVRGLTggZW5jb2RpbmcgaW4gcGxhY2VzIHdoZXJlIHRoZSBjb2RlIGZhaWxzIG9uCisgKiAgICAgc3lzdGVtcyB3aXRoIG90aGVyIGVuY29kaW5ncyAobGlrZSBFQkNESUMpLjwvbGk+CisgKiAgIDxsaT52Mi4wLjEgLSBGaXhlZCBhbiBlcnJvciB3aGVuIGRlY29kaW5nIGEgc2luZ2xlIGJ5dGUsIHRoYXQgaXMsIHdoZW4gdGhlCisgKiAgICAgZW5jb2RlZCBkYXRhIHdhcyBhIHNpbmdsZSBieXRlLjwvbGk+CisgKiAgIDxsaT52Mi4wIC0gSSBnb3QgcmlkIG9mIG1ldGhvZHMgdGhhdCB1c2VkIGJvb2xlYW5zIHRvIHNldCBvcHRpb25zLiBOb3cKKyAqICAgICBldmVyeXRoaW5nIGlzIG1vcmUgY29uc29saWRhdGVkIGFuZCBjbGVhbmVyLiBUaGUgY29kZSBub3cgZGV0ZWN0cyB3aGVuCisgKiAgICAgZGF0YSB0aGF0J3MgYmVpbmcgZGVjb2RlZCBpcyBnemlwLWNvbXByZXNzZWQgYW5kIHdpbGwgZGVjb21wcmVzcyBpdAorICogICAgIGF1dG9tYXRpY2FsbHkuIEdlbmVyYWxseSB0aGluZ3MgYXJlIGNsZWFuZXIuIFlvdSdsbCBwcm9iYWJseSBoYXZlIHRvCisgKiAgICAgY2hhbmdlIHNvbWUgbWV0aG9kIGNhbGxzIHRoYXQgeW91IHdlcmUgbWFraW5nIHRvIHN1cHBvcnQgdGhlIG5ldyBvcHRpb25zCisgKiAgICAgZm9ybWF0ICg8dHQ+aW50PC90dD5zIHRoYXQgeW91ICJPUiIgdG9nZXRoZXIpLjwvbGk+CisgKiAgIDxsaT52MS41LjEgLSBGaXhlZCBidWcgd2hlbiBkZWNvbXByZXNzaW5nIGFuZCBkZWNvZGluZyB0byBhIGJ5dGVbXSB1c2luZworICogICAgIDx0dD5kZWNvZGUoIFN0cmluZyBzLCBib29sZWFuIGd6aXBDb21wcmVzc2VkICk8L3R0Pi4gQWRkZWQgdGhlIGFiaWxpdHkgdG8KKyAqICAgICAic3VzcGVuZCIgZW5jb2RpbmcgaW4gdGhlIE91dHB1dCBTdHJlYW0gc28geW91IGNhbiB0dXJuIG9uIGFuZCBvZmYgdGhlCisgKiAgICAgZW5jb2RpbmcgaWYgeW91IG5lZWQgdG8gZW1iZWQgYmFzZTY0IGRhdGEgaW4gYW4gb3RoZXJ3aXNlICJub3JtYWwiIHN0cmVhbQorICogICAgIChsaWtlIGFuIFhNTCBmaWxlKS48L2xpPiAgCisgKiAgIDxsaT52MS41IC0gT3V0cHV0IHN0cmVhbSBwYXNlcyBvbiBmbHVzaCgpIGNvbW1hbmQgYnV0IGRvZXNuJ3QgZG8gYW55dGhpbmcKKyAqICAgICBpdHNlbGYuIFRoaXMgaGVscHMgd2hlbiB1c2luZyBHWklQIHN0cmVhbXMuIEFkZGVkIHRoZSBhYmlsaXR5IHRvCisgKiAgICAgR1ppcC1jb21wcmVzcyBvYmplY3RzIGJlZm9yZSBlbmNvZGluZyB0aGVtLjwvbGk+CisgKiAgIDxsaT52MS40IC0gQWRkZWQgaGVscGVyIG1ldGhvZHMgdG8gcmVhZC93cml0ZSBmaWxlcy48L2xpPgorICogICA8bGk+djEuMy42IC0gRml4ZWQgT3V0cHV0U3RyZWFtLmZsdXNoKCkgc28gdGhhdCAncG9zaXRpb24nIGlzIHJlc2V0LjwvbGk+CisgKiAgIDxsaT52MS4zLjUgLSBBZGRlZCBmbGFnIHRvIHR1cm4gb24gYW5kIG9mZiBsaW5lIGJyZWFrcy4gRml4ZWQgYnVnIGluIGlucHV0CisgKiAgICAgc3RyZWFtIHdoZXJlIGxhc3QgYnVmZmVyIGJlaW5nIHJlYWQsIGlmIG5vdCBjb21wbGV0ZWx5IGZ1bGwsIHdhcyBub3QKKyAqICAgICByZXR1cm5lZC48L2xpPgorICogICA8bGk+djEuMy40IC0gRml4ZWQgd2hlbiAiaW1wcm9wZXJseSBwYWRkZWQgc3RyZWFtIiBlcnJvciB3YXMgdGhyb3duIGF0IHRoZQorICogICAgIHdyb25nIHRpbWUuPC9saT4KKyAqICAgPGxpPnYxLjMuMyAtIEZpeGVkIEkvTyBzdHJlYW1zIHdoaWNoIHdlcmUgdG90YWxseSBtZXNzZWQgdXAuPC9saT4KKyAqIDwvdWw+CisgKgorICogPHA+CisgKiBJIGFtIHBsYWNpbmcgdGhpcyBjb2RlIGluIHRoZSBQdWJsaWMgRG9tYWluLiBEbyB3aXRoIGl0IGFzIHlvdSB3aWxsLiBUaGlzCisgKiBzb2Z0d2FyZSBjb21lcyB3aXRoIG5vIGd1YXJhbnRlZXMgb3Igd2FycmFudGllcyBidXQgd2l0aCBwbGVudHkgb2YKKyAqIHdlbGwtd2lzaGluZyBpbnN0ZWFkIQorICogPHA+CisgKiBQbGVhc2UgdmlzaXQgPGEgaHJlZj0iaHR0cDovL2loYXJkZXIubmV0L2Jhc2U2NCI+aHR0cDovL2loYXJkZXIubmV0L2Jhc2U2NDwvYT4KKyAqIHBlcmlvZGljYWxseSB0byBjaGVjayBmb3IgdXBkYXRlcyBvciB0byBjb250cmlidXRlIGltcHJvdmVtZW50cy4KKyAqIDxwPgorICogYXV0aG9yOiBSb2JlcnQgSGFyZGVyLCByb2JAaWhhcmRlci5uZXQKKyAqIDxicj4KKyAqIHZlcnNpb246IDIuMi4xCisgKi8KKworLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWx0ZXJJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLkNsYXNzTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5HWklQSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5HWklQT3V0cHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKKy8qKgorICogRW5jb2RlcyBhbmQgZGVjb2RlcyB0byBhbmQgZnJvbSBCYXNlNjQgbm90YXRpb24uCisgKi8KK3B1YmxpYyBjbGFzcyBCYXNlNjQgeworCisgIC8qICoqKioqKioqIFAgVSBCIEwgSSBDICAgRiBJIEUgTCBEIFMgKioqKioqKiogKi8KKworICAvKiogTm8gb3B0aW9ucyBzcGVjaWZpZWQuIFZhbHVlIGlzIHplcm8uICovCisgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE5PX09QVElPTlMgPSAwOworCisgIC8qKiBTcGVjaWZ5IGVuY29kaW5nLiAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBFTkNPREUgPSAxOworCisgIC8qKiBTcGVjaWZ5IGRlY29kaW5nLiAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBERUNPREUgPSAwOworCisgIC8qKiBTcGVjaWZ5IHRoYXQgZGF0YSBzaG91bGQgYmUgZ3ppcC1jb21wcmVzc2VkLiAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBHWklQID0gMjsKKworICAvKiogRG9uJ3QgYnJlYWsgbGluZXMgd2hlbiBlbmNvZGluZyAodmlvbGF0ZXMgc3RyaWN0IEJhc2U2NCBzcGVjaWZpY2F0aW9uKSAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBET05UX0JSRUFLX0xJTkVTID0gODsKKworICAvKioKKyAgICogRW5jb2RlIHVzaW5nIEJhc2U2NC1saWtlIGVuY29kaW5nIHRoYXQgaXMgVVJMIGFuZCBGaWxlbmFtZSBzYWZlIGFzCisgICAqIGRlc2NyaWJlZCBpbiBTZWN0aW9uIDQgb2YgUkZDMzU0ODogCisgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cuZmFxcy5vcmcvcmZjcy9yZmMzNTQ4Lmh0bWwiPgorICAgKiBodHRwOi8vd3d3LmZhcXMub3JnL3JmY3MvcmZjMzU0OC5odG1sPC9hPi4KKyAgICogSXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCBkYXRhIGVuY29kZWQgdGhpcyB3YXkgaXMgPGVtPm5vdDwvZW0+CisgICAqIG9mZmljaWFsbHkgdmFsaWQgQmFzZTY0LCBvciBhdCB0aGUgdmVyeSBsZWFzdCBzaG91bGQgbm90IGJlIGNhbGxlZCBCYXNlNjQKKyAgICogd2l0aG91dCBhbHNvIHNwZWNpZnlpbmcgdGhhdCBpcyB3YXMgZW5jb2RlZCB1c2luZyB0aGUgVVJMIGFuZAorICAgKiBGaWxlbmFtZSBzYWZlIGRpYWxlY3QuCisgICAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBVUkxfU0FGRSA9IDE2OworCisgIC8qKgorICAgKiBFbmNvZGUgdXNpbmcgdGhlIHNwZWNpYWwgIm9yZGVyZWQiIGRpYWxlY3Qgb2YgQmFzZTY0IGRlc2NyaWJlZCBoZXJlOgorICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LmZhcXMub3JnL3FhL3JmY2MtMTk0MC5odG1sIj4KKyAgICogaHR0cDovL3d3dy5mYXFzLm9yZy9xYS9yZmNjLTE5NDAuaHRtbDwvYT4uCisgICAqLworICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBPUkRFUkVEID0gMzI7CisKKyAgLyogKioqKioqKiogUCBSIEkgViBBIFQgRSAgIEYgSSBFIEwgRCBTICoqKioqKioqICovCisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coQmFzZTY0LmNsYXNzKTsKKworICAvKiogTWF4aW11bSBsaW5lIGxlbmd0aCAoNzYpIG9mIEJhc2U2NCBvdXRwdXQuICovCisgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBNQVhfTElORV9MRU5HVEggPSA3NjsKKworICAvKiogVGhlIGVxdWFscyBzaWduICg9KSBhcyBhIGJ5dGUuICovCisgIHByaXZhdGUgZmluYWwgc3RhdGljIGJ5dGUgRVFVQUxTX1NJR04gPSAoYnl0ZSkgJz0nOworCisgIC8qKiBUaGUgbmV3IGxpbmUgY2hhcmFjdGVyIChcbikgYXMgYSBieXRlLiAqLworICBwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlIE5FV19MSU5FID0gKGJ5dGUpICdcbic7CisKKyAgLyoqIFByZWZlcnJlZCBlbmNvZGluZy4gKi8KKyAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFBSRUZFUlJFRF9FTkNPRElORyA9ICJVVEYtOCI7CisKKyAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgYnl0ZSBXSElURV9TUEFDRV9FTkMgPSAtNTsgLy8gSW5kaWNhdGVzIHdoaXRlIHNwYWNlCisgIHByaXZhdGUgZmluYWwgc3RhdGljIGJ5dGUgRVFVQUxTX1NJR05fRU5DID0gLTE7IC8vIEluZGljYXRlcyBlcXVhbHMgc2lnbgorCisgIC8qICoqKioqKioqIFMgVCBBIE4gRCBBIFIgRCAgIEIgQSBTIEUgNiA0ICAgQSBMIFAgSCBBIEIgRSBUICoqKioqKioqICovCisKKyAgLyoqIFRoZSA2NCB2YWxpZCBCYXNlNjQgdmFsdWVzLiAqLworCisgIC8qCisgICAqIEhvc3QgcGxhdGZvcm0gbWF5IGJlIHNvbWV0aGluZyBmdW5ueSBsaWtlIEVCQ0RJQywgc28gd2UgaGFyZGNvZGUgdGhlc2UKKyAgICogdmFsdWVzLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgYnl0ZVtdIF9TVEFOREFSRF9BTFBIQUJFVCA9IHsgKGJ5dGUpICdBJywgKGJ5dGUpICdCJywKKyAgICAoYnl0ZSkgJ0MnLCAoYnl0ZSkgJ0QnLCAoYnl0ZSkgJ0UnLCAoYnl0ZSkgJ0YnLCAoYnl0ZSkgJ0cnLCAoYnl0ZSkgJ0gnLAorICAgIChieXRlKSAnSScsIChieXRlKSAnSicsIChieXRlKSAnSycsIChieXRlKSAnTCcsIChieXRlKSAnTScsIChieXRlKSAnTicsCisgICAgKGJ5dGUpICdPJywgKGJ5dGUpICdQJywgKGJ5dGUpICdRJywgKGJ5dGUpICdSJywgKGJ5dGUpICdTJywgKGJ5dGUpICdUJywKKyAgICAoYnl0ZSkgJ1UnLCAoYnl0ZSkgJ1YnLCAoYnl0ZSkgJ1cnLCAoYnl0ZSkgJ1gnLCAoYnl0ZSkgJ1knLCAoYnl0ZSkgJ1onLAorICAgIChieXRlKSAnYScsIChieXRlKSAnYicsIChieXRlKSAnYycsIChieXRlKSAnZCcsIChieXRlKSAnZScsIChieXRlKSAnZicsCisgICAgKGJ5dGUpICdnJywgKGJ5dGUpICdoJywgKGJ5dGUpICdpJywgKGJ5dGUpICdqJywgKGJ5dGUpICdrJywgKGJ5dGUpICdsJywKKyAgICAoYnl0ZSkgJ20nLCAoYnl0ZSkgJ24nLCAoYnl0ZSkgJ28nLCAoYnl0ZSkgJ3AnLCAoYnl0ZSkgJ3EnLCAoYnl0ZSkgJ3InLAorICAgIChieXRlKSAncycsIChieXRlKSAndCcsIChieXRlKSAndScsIChieXRlKSAndicsIChieXRlKSAndycsIChieXRlKSAneCcsCisgICAgKGJ5dGUpICd5JywgKGJ5dGUpICd6JywgKGJ5dGUpICcwJywgKGJ5dGUpICcxJywgKGJ5dGUpICcyJywgKGJ5dGUpICczJywKKyAgICAoYnl0ZSkgJzQnLCAoYnl0ZSkgJzUnLCAoYnl0ZSkgJzYnLCAoYnl0ZSkgJzcnLCAoYnl0ZSkgJzgnLCAoYnl0ZSkgJzknLAorICAgIChieXRlKSAnKycsIChieXRlKSAnLycKKyAgfTsKKworICAvKioKKyAgICogVHJhbnNsYXRlcyBhIEJhc2U2NCB2YWx1ZSB0byBlaXRoZXIgaXRzIDYtYml0IHJlY29uc3RydWN0aW9uIHZhbHVlIG9yIGEKKyAgICogbmVnYXRpdmUgbnVtYmVyIGluZGljYXRpbmcgc29tZSBvdGhlciBtZWFuaW5nLgorICAgKi8KKyAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgYnl0ZVtdIF9TVEFOREFSRF9ERUNPREFCRVQgPSB7CisgICAgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgICAgICAgICAgICAgLy8gRGVjaW1hbCAwIC0gOAorICAgIC01LCAtNSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoaXRlc3BhY2U6IFRhYiwgTmV3bGluZQorICAgIC05LCAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgMTEgLSAxMgorICAgIC01LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoaXRlc3BhY2U6IFJldHVybgorICAgIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAvLyBEZWNpbWFsIDE0IC0gMjYKKyAgICAtOSwgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWNpbWFsIDI3IC0gMzEKKyAgICAtNSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlOiBTcGFjZQorICAgIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAgICAgICAgIC8vIERlY2ltYWwgMzMgLSA0MgorICAgIDYyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsdXMgc2lnbiBhdCBkZWNpbWFsIDQzCisgICAgLTksIC05LCAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCA0NCAtIDQ2CisgICAgNjMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2xhc2ggYXQgZGVjaW1hbCA0NworICAgIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCAgICAgICAgIC8vIE51bWJlcnMgemVybyAtIG5pbmUKKyAgICAtOSwgLTksIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWNpbWFsIDU4IC0gNjAKKyAgICAtMSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBFcXVhbHMgc2lnbiBhdCBkZWNpbWFsIDYxCisgICAgLTksIC05LCAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCA2MiAtIDY0CisgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsICAgLy8gTGV0dGVycyAnQScgLSAnTicKKyAgICAxNCwgMTUsIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAvLyBMZXR0ZXJzICdPJyAtICdaJworICAgIC05LCAtOSwgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgOTEgLSA5NgorICAgIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAvLyBMZXR0ZXJzICdhJyAtICdtJworICAgIDM5LCA0MCwgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsIDQ4LCA0OSwgNTAsIDUxLCAvLyBMZXR0ZXJzICduJyAtJ3onCisgICAgLTksIC05LCAtOSwgLTkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAxMjMgLSAxMjYKKyAgfTsKKworICAvKiAqKioqKioqKiBVIFIgTCAgIFMgQSBGIEUgICBCIEEgUyBFIDYgNCAgIEEgTCBQIEggQSBCIEUgVCAqKioqKioqKiAqLworCisgIC8qKgorICAgKiBVc2VkIGluIHRoZSBVUkwgYW5kIEZpbGVuYW1lIHNhZmUgZGlhbGVjdCBkZXNjcmliZWQgaW4gU2VjdGlvbiA0IG9mIFJGQzM1NDgKKyAgICogPGEgaHJlZj0iaHR0cDovL3d3dy5mYXFzLm9yZy9yZmNzL3JmYzM1NDguaHRtbCI+CisgICAqIGh0dHA6Ly93d3cuZmFxcy5vcmcvcmZjcy9yZmMzNTQ4Lmh0bWw8L2E+LgorICAgKiBOb3RpY2UgdGhhdCB0aGUgbGFzdCB0d28gYnl0ZXMgYmVjb21lICJoeXBoZW4iIGFuZCAidW5kZXJzY29yZSIgaW5zdGVhZCBvZgorICAgKiAicGx1cyIgYW5kICJzbGFzaC4iCisgICAqLworICBwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlW10gX1VSTF9TQUZFX0FMUEhBQkVUID0geyAoYnl0ZSkgJ0EnLCAoYnl0ZSkgJ0InLAorICAgIChieXRlKSAnQycsIChieXRlKSAnRCcsIChieXRlKSAnRScsIChieXRlKSAnRicsIChieXRlKSAnRycsIChieXRlKSAnSCcsCisgICAgKGJ5dGUpICdJJywgKGJ5dGUpICdKJywgKGJ5dGUpICdLJywgKGJ5dGUpICdMJywgKGJ5dGUpICdNJywgKGJ5dGUpICdOJywKKyAgICAoYnl0ZSkgJ08nLCAoYnl0ZSkgJ1AnLCAoYnl0ZSkgJ1EnLCAoYnl0ZSkgJ1InLCAoYnl0ZSkgJ1MnLCAoYnl0ZSkgJ1QnLAorICAgIChieXRlKSAnVScsIChieXRlKSAnVicsIChieXRlKSAnVycsIChieXRlKSAnWCcsIChieXRlKSAnWScsIChieXRlKSAnWicsCisgICAgKGJ5dGUpICdhJywgKGJ5dGUpICdiJywgKGJ5dGUpICdjJywgKGJ5dGUpICdkJywgKGJ5dGUpICdlJywgKGJ5dGUpICdmJywKKyAgICAoYnl0ZSkgJ2cnLCAoYnl0ZSkgJ2gnLCAoYnl0ZSkgJ2knLCAoYnl0ZSkgJ2onLCAoYnl0ZSkgJ2snLCAoYnl0ZSkgJ2wnLAorICAgIChieXRlKSAnbScsIChieXRlKSAnbicsIChieXRlKSAnbycsIChieXRlKSAncCcsIChieXRlKSAncScsIChieXRlKSAncicsCisgICAgKGJ5dGUpICdzJywgKGJ5dGUpICd0JywgKGJ5dGUpICd1JywgKGJ5dGUpICd2JywgKGJ5dGUpICd3JywgKGJ5dGUpICd4JywKKyAgICAoYnl0ZSkgJ3knLCAoYnl0ZSkgJ3onLCAoYnl0ZSkgJzAnLCAoYnl0ZSkgJzEnLCAoYnl0ZSkgJzInLCAoYnl0ZSkgJzMnLAorICAgIChieXRlKSAnNCcsIChieXRlKSAnNScsIChieXRlKSAnNicsIChieXRlKSAnNycsIChieXRlKSAnOCcsIChieXRlKSAnOScsCisgICAgKGJ5dGUpICctJywgKGJ5dGUpICdfJworICB9OworCisgIC8qKgorICAgKiBVc2VkIGluIGRlY29kaW5nIFVSTCBhbmQgRmlsZW5hbWUgc2FmZSBkaWFsZWN0cyBvZiBCYXNlNjQuCisgICAqLworICBwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlW10gX1VSTF9TQUZFX0RFQ09EQUJFVCA9IHsKKyAgICAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAwIC0gOAorICAgIC01LCAtNSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlOiBUYWIsIE5ld2xpbmUKKyAgICAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAxMSAtIDEyCisgICAgLTUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoaXRlc3BhY2U6IFJldHVybgorICAgIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAvLyBEZWNpbWFsIDE0IC0gMjYKKyAgICAtOSwgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAyNyAtIDMxCisgICAgLTUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdoaXRlc3BhY2U6IFNwYWNlCisgICAgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgIC8vIERlY2ltYWwgMzMgLSA0MgorICAgIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbHVzIHNpZ24gYXQgNDMKKyAgICAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCA0NAorICAgIDYyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaW51cyBzaWduIGF0IDQ1CisgICAgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgNDYKKyAgICAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2xhc2ggYXQgNDcKKyAgICA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwgICAgICAgICAgICAgLy8gTnVtYmVycyAwIC0gOQorICAgIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWNpbWFsIDU4IC0gNjAKKyAgICAtMSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXF1YWxzIHNpZ24gYXQgNjEKKyAgICAtOSwgLTksIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCA2MiAtIDY0CisgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsICAgICAgIC8vIExldHRlcnMgJ0EnIC0gJ04nCisgICAgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwgICAgIC8vIExldHRlcnMgJ08nIC0gJ1onCisgICAgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgOTEgLSA5NAorICAgIDYzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmRlcnNjb3JlIGF0IDk1CisgICAgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgOTYKKyAgICAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLCAzMiwgMzMsIDM0LCAzNSwgMzYsIDM3LCAzOCwgLy8gTGV0dGVycyAnYScgLSAnbScKKyAgICAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3LCA0OCwgNDksIDUwLCA1MSwgLy8gTGV0dGVycyAnbicgLSAneicKKyAgICAtOSwgLTksIC05LCAtOSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAxMjMgLSAxMjYKKyAgfTsKKworICAvKiAqKioqKioqKiBPIFIgRCBFIFIgRSBEICAgQiBBIFMgRSA2IDQgICBBIEwgUCBIIEEgQiBFIFQgKioqKioqKiogKi8KKworICAvKioKKyAgICogSW4gYWRkaXRpb24gdG8gYmVpbmcgVVJMIGFuZCBmaWxlIG5hbWUgZnJpZW5kbHksIHRoaXMgZW5jb2RpbmcgcHJlc2VydmVzCisgICAqIHRoZSBzb3J0IG9yZGVyIG9mIGVuY29kZWQgdmFsdWVzLiBXaGF0ZXZlciBpcyBpbnB1dCwgYmUgaXQgc3RyaW5nIG9yCisgICAqIGp1c3QgYW4gYXJyYXkgb2YgYnl0ZXMsIHdoZW4geW91IHVzZSB0aGlzIGVuY29kaW5nLCB0aGUgZW5jb2RlZCB2YWx1ZSBzb3J0cworICAgKiBleGFjdGx5IHRoZSBzYW1lIGFzIHRoZSBpbnB1dCB2YWx1ZS4gSXQgaXMgZGVzY3JpYmVkIGluIHRoZSBSRkMgY2hhbmdlCisgICAqIHJlcXVlc3Q6IDxhIGhyZWY9Imh0dHA6Ly93d3cuZmFxcy5vcmcvcWEvcmZjYy0xOTQwLmh0bWwiPgorICAgKiBodHRwOi8vd3d3LmZhcXMub3JnL3FhL3JmY2MtMTk0MC5odG1sPC9hPi4KKyAgICogCisgICAqIEl0IHJlcGxhY2VzICJwbHVzIiBhbmQgInNsYXNoIiB3aXRoICJoeXBoZW4iIGFuZCAidW5kZXJzY29yZSIgYW5kIAorICAgKiByZWFycmFuZ2VzIHRoZSBhbHBoYWJldCBzbyB0aGF0IHRoZSBjaGFyYWN0ZXJzIGFyZSBpbiB0aGVpciBuYXR1cmFsIHNvcnQKKyAgICogb3JkZXIuCisgICAqLworICBwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlW10gX09SREVSRURfQUxQSEFCRVQgPSB7IChieXRlKSAnLScsIChieXRlKSAnMCcsCisgICAgKGJ5dGUpICcxJywgKGJ5dGUpICcyJywgKGJ5dGUpICczJywgKGJ5dGUpICc0JywgKGJ5dGUpICc1JywgKGJ5dGUpICc2JywKKyAgICAoYnl0ZSkgJzcnLCAoYnl0ZSkgJzgnLCAoYnl0ZSkgJzknLCAoYnl0ZSkgJ0EnLCAoYnl0ZSkgJ0InLCAoYnl0ZSkgJ0MnLAorICAgIChieXRlKSAnRCcsIChieXRlKSAnRScsIChieXRlKSAnRicsIChieXRlKSAnRycsIChieXRlKSAnSCcsIChieXRlKSAnSScsCisgICAgKGJ5dGUpICdKJywgKGJ5dGUpICdLJywgKGJ5dGUpICdMJywgKGJ5dGUpICdNJywgKGJ5dGUpICdOJywgKGJ5dGUpICdPJywKKyAgICAoYnl0ZSkgJ1AnLCAoYnl0ZSkgJ1EnLCAoYnl0ZSkgJ1InLCAoYnl0ZSkgJ1MnLCAoYnl0ZSkgJ1QnLCAoYnl0ZSkgJ1UnLAorICAgIChieXRlKSAnVicsIChieXRlKSAnVycsIChieXRlKSAnWCcsIChieXRlKSAnWScsIChieXRlKSAnWicsIChieXRlKSAnXycsCisgICAgKGJ5dGUpICdhJywgKGJ5dGUpICdiJywgKGJ5dGUpICdjJywgKGJ5dGUpICdkJywgKGJ5dGUpICdlJywgKGJ5dGUpICdmJywKKyAgICAoYnl0ZSkgJ2cnLCAoYnl0ZSkgJ2gnLCAoYnl0ZSkgJ2knLCAoYnl0ZSkgJ2onLCAoYnl0ZSkgJ2snLCAoYnl0ZSkgJ2wnLAorICAgIChieXRlKSAnbScsIChieXRlKSAnbicsIChieXRlKSAnbycsIChieXRlKSAncCcsIChieXRlKSAncScsIChieXRlKSAncicsCisgICAgKGJ5dGUpICdzJywgKGJ5dGUpICd0JywgKGJ5dGUpICd1JywgKGJ5dGUpICd2JywgKGJ5dGUpICd3JywgKGJ5dGUpICd4JywKKyAgICAoYnl0ZSkgJ3knLCAoYnl0ZSkgJ3onCisgIH07CisKKyAgLyoqCisgICAqIFVzZWQgaW4gZGVjb2RpbmcgdGhlICJvcmRlcmVkIiBkaWFsZWN0IG9mIEJhc2U2NC4KKyAgICovCisgIHByaXZhdGUgZmluYWwgc3RhdGljIGJ5dGVbXSBfT1JERVJFRF9ERUNPREFCRVQgPSB7CisgICAgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgMCAtIDgKKyAgICAtNSwgLTUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hpdGVzcGFjZTogVGFiLCBOZXdsaW5lCisgICAgLTksIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgMTEgLSAxMgorICAgIC01LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlOiBSZXR1cm4KKyAgICAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLy8gRGVjaW1hbCAxNCAtIDI2CisgICAgLTksIC05LCAtOSwgLTksIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgMjcgLSAzMQorICAgIC01LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGl0ZXNwYWNlOiBTcGFjZQorICAgIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAtOSwgLTksIC05LCAgICAgICAgICAgICAvLyBEZWNpbWFsIDMzIC0gNDIKKyAgICAtOSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGx1cyBzaWduIGF0IDQzCisgICAgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgNDQKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWludXMgc2lnbiBhdCA0NQorICAgIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWNpbWFsIDQ2CisgICAgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNsYXNoIGF0IGRlY2ltYWwgNDcKKyAgICAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgICAgICAgICAgICAgICAgICAgICAgLy8gTnVtYmVycyAwIC0gOQorICAgIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWNpbWFsIDU4IC0gNjAKKyAgICAtMSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXF1YWxzIHNpZ24gYXQgNjEKKyAgICAtOSwgLTksIC05LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCA2MiAtIDY0CisgICAgMTEsIDEyLCAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIC8vIExldHRlcnMgJ0EnIC0gJ00nCisgICAgMjQsIDI1LCAyNiwgMjcsIDI4LCAyOSwgMzAsIDMxLCAzMiwgMzMsIDM0LCAzNSwgMzYsIC8vIExldHRlcnMgJ04nIC0gJ1onCisgICAgLTksIC05LCAtOSwgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgOTEgLSA5NAorICAgIDM3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmRlcnNjb3JlIGF0IDk1CisgICAgLTksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlY2ltYWwgOTYKKyAgICAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgLy8gTGV0dGVycyAnYScgLSAnbScKKyAgICA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDYyLCA2MywgLy8gTGV0dGVycyAnbicgLSAneicKKyAgICAtOSwgLTksIC05LCAtOSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVjaW1hbCAxMjMgLSAxMjYKKyAgfTsKKworICAvKiAqKioqKioqKiBEIEUgVCBFIFIgTSBJIE4gRSAgIFcgSCBJIEMgSCAgIEEgTCBIIEEgQiBFIFQgKioqKioqKiogKi8KKworICAvKioKKyAgICogUmV0dXJucyBvbmUgb2YgdGhlIF9TT01FVEhJTkdfQUxQSEFCRVQgYnl0ZSBhcnJheXMgZGVwZW5kaW5nIG9uIHRoZSBvcHRpb25zCisgICAqIHNwZWNpZmllZC4gSXQncyBwb3NzaWJsZSwgdGhvdWdoIHNpbGx5LCB0byBzcGVjaWZ5IE9SREVSRUQgYW5kIFVSTFNBRkUgaW4KKyAgICogd2hpY2ggY2FzZSBvbmUgb2YgdGhlbSB3aWxsIGJlIHBpY2tlZCwgdGhvdWdoIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSBhcyB0bworICAgKiB3aGljaCBvbmUgd2lsbCBiZSBwaWNrZWQuCisgICAqLworICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGJ5dGVbXSBnZXRBbHBoYWJldChpbnQgb3B0aW9ucykgeworICAgIGlmICgob3B0aW9ucyAmIFVSTF9TQUZFKSA9PSBVUkxfU0FGRSkgeworICAgICAgcmV0dXJuIF9VUkxfU0FGRV9BTFBIQUJFVDsKKworICAgIH0gZWxzZSBpZiAoKG9wdGlvbnMgJiBPUkRFUkVEKSA9PSBPUkRFUkVEKSB7CisgICAgICByZXR1cm4gX09SREVSRURfQUxQSEFCRVQ7CisgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIF9TVEFOREFSRF9BTFBIQUJFVDsKKyAgICB9CisgIH0gLy8gZW5kIGdldEFscGhhYmV0CisKKyAgLyoqCisgICAqIFJldHVybnMgb25lIG9mIHRoZSBfU09NRVRISU5HX0RFQ09EQUJFVCBieXRlIGFycmF5cyBkZXBlbmRpbmcgb24gdGhlCisgICAqIG9wdGlvbnMgc3BlY2lmaWVkLiBJdCdzIHBvc3NpYmxlLCB0aG91Z2ggc2lsbHksIHRvIHNwZWNpZnkgT1JERVJFRCBhbmQKKyAgICogVVJMX1NBRkUgaW4gd2hpY2ggY2FzZSBvbmUgb2YgdGhlbSB3aWxsIGJlIHBpY2tlZCwgdGhvdWdoIHRoZXJlIGlzIG5vCisgICAqIGd1YXJhbnRlZSBhcyB0byB3aGljaCBvbmUgd2lsbCBiZSBwaWNrZWQuCisgICAqLworICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGJ5dGVbXSBnZXREZWNvZGFiZXQoaW50IG9wdGlvbnMpIHsKKyAgICBpZiAoKG9wdGlvbnMgJiBVUkxfU0FGRSkgPT0gVVJMX1NBRkUpIHsKKyAgICAgIHJldHVybiBfVVJMX1NBRkVfREVDT0RBQkVUOworICAgICAgCisgICAgfSBlbHNlIGlmICgob3B0aW9ucyAmIE9SREVSRUQpID09IE9SREVSRUQpIHsKKyAgICAgIHJldHVybiBfT1JERVJFRF9ERUNPREFCRVQ7CisgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIF9TVEFOREFSRF9ERUNPREFCRVQ7CisgICAgfQorICB9IC8vIGVuZCBnZXREZWNvZGFiZXQKKworICAvKiogRGVmZWF0cyBpbnN0YW50aWF0aW9uLiAqLworICBwcml2YXRlIEJhc2U2NCgpIHt9CisKKyAgLyoqCisgICAqIE1haW4gcHJvZ3JhbS4gVXNlZCBmb3IgdGVzdGluZy4KKyAgICogCisgICAqIEVuY29kZXMgb3IgZGVjb2RlcyB0d28gZmlsZXMgZnJvbSB0aGUgY29tbWFuZCBsaW5lCisgICAqIAorICAgKiBAcGFyYW0gYXJncyBjb21tYW5kIGFyZ3VtZW50cworICAgKi8KKyAgcHVibGljIGZpbmFsIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworICAgIGlmIChhcmdzLmxlbmd0aCA8IDMpIHsKKyAgICAgIHVzYWdlKCJOb3QgZW5vdWdoIGFyZ3VtZW50cy4iKTsKKworICAgIH0gZWxzZSB7CisgICAgICBTdHJpbmcgZmxhZyA9IGFyZ3NbMF07CisgICAgICBTdHJpbmcgaW5maWxlID0gYXJnc1sxXTsKKyAgICAgIFN0cmluZyBvdXRmaWxlID0gYXJnc1syXTsKKyAgICAgIGlmIChmbGFnLmVxdWFscygiLWUiKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5jb2RlCisgICAgICAgIGVuY29kZUZpbGVUb0ZpbGUoaW5maWxlLCBvdXRmaWxlKTsKKworICAgICAgfSBlbHNlIGlmIChmbGFnLmVxdWFscygiLWQiKSkgeyAgICAgICAgICAgICAgICAgICAvLyBkZWNvZGUKKyAgICAgICAgZGVjb2RlRmlsZVRvRmlsZShpbmZpbGUsIG91dGZpbGUpOworCisgICAgICB9IGVsc2UgeworICAgICAgICB1c2FnZSgiVW5rbm93biBmbGFnOiAiICsgZmxhZyk7CisgICAgICB9CisgICAgfQorICB9IC8vIGVuZCBtYWluCisKKyAgLyoqCisgICAqIFByaW50cyBjb21tYW5kIGxpbmUgdXNhZ2UuCisgICAqIAorICAgKiBAcGFyYW0gbXNnIEEgbWVzc2FnZSB0byBpbmNsdWRlIHdpdGggdXNhZ2UgaW5mby4KKyAgICovCisgIHByaXZhdGUgZmluYWwgc3RhdGljIHZvaWQgdXNhZ2UoU3RyaW5nIG1zZykgeworICAgIFN5c3RlbS5lcnIucHJpbnRsbihtc2cpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IGphdmEgQmFzZTY0IC1lfC1kIGlucHV0ZmlsZSBvdXRwdXRmaWxlIik7CisgIH0gLy8gZW5kIHVzYWdlCisKKyAgLyogKioqKioqKiogRSBOIEMgTyBEIEkgTiBHICAgTSBFIFQgSCBPIEQgUyAqKioqKioqKiAqLworCisgIC8qKgorICAgKiBFbmNvZGVzIHVwIHRvIHRoZSBmaXJzdCB0aHJlZSBieXRlcyBvZiBhcnJheSA8dmFyPnRocmVlQnl0ZXM8L3Zhcj4gYW5kCisgICAqIHJldHVybnMgYSBmb3VyLWJ5dGUgYXJyYXkgaW4gQmFzZTY0IG5vdGF0aW9uLiBUaGUgYWN0dWFsIG51bWJlciBvZgorICAgKiBzaWduaWZpY2FudCBieXRlcyBpbiB5b3VyIGFycmF5IGlzIGdpdmVuIGJ5IDx2YXI+bnVtU2lnQnl0ZXM8L3Zhcj4uIFRoZQorICAgKiBhcnJheSA8dmFyPnRocmVlQnl0ZXM8L3Zhcj4gbmVlZHMgb25seSBiZSBhcyBiaWcgYXMgPHZhcj5udW1TaWdCeXRlczwvdmFyPi4KKyAgICogQ29kZSBjYW4gcmV1c2UgYSBieXRlIGFycmF5IGJ5IHBhc3NpbmcgYSBmb3VyLWJ5dGUgYXJyYXkgYXMgPHZhcj5iNDwvdmFyPi4KKyAgICogCisgICAqIEBwYXJhbSBiNCBBIHJldXNhYmxlIGJ5dGUgYXJyYXkgdG8gcmVkdWNlIGFycmF5IGluc3RhbnRpYXRpb24KKyAgICogQHBhcmFtIHRocmVlQnl0ZXMgdGhlIGFycmF5IHRvIGNvbnZlcnQKKyAgICogQHBhcmFtIG51bVNpZ0J5dGVzIHRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4geW91ciBhcnJheQorICAgKiBAcmV0dXJuIGZvdXIgYnl0ZSBhcnJheSBpbiBCYXNlNjQgbm90YXRpb24uCisgICAqIEBzaW5jZSAxLjUuMQorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBieXRlW10gZW5jb2RlM3RvNChieXRlW10gYjQsIGJ5dGVbXSB0aHJlZUJ5dGVzLAorICAgICAgaW50IG51bVNpZ0J5dGVzLCBpbnQgb3B0aW9ucykgeworICAgIGVuY29kZTN0bzQodGhyZWVCeXRlcywgMCwgbnVtU2lnQnl0ZXMsIGI0LCAwLCBvcHRpb25zKTsKKyAgICByZXR1cm4gYjQ7CisgIH0gLy8gZW5kIGVuY29kZTN0bzQKKworICAvKioKKyAgICogRW5jb2RlcyB1cCB0byB0aHJlZSBieXRlcyBvZiB0aGUgYXJyYXkgPHZhcj5zb3VyY2U8L3Zhcj4gYW5kIHdyaXRlcyB0aGUKKyAgICogcmVzdWx0aW5nIGZvdXIgQmFzZTY0IGJ5dGVzIHRvIDx2YXI+ZGVzdGluYXRpb248L3Zhcj4uIFRoZSBzb3VyY2UgYW5kCisgICAqIGRlc3RpbmF0aW9uIGFycmF5cyBjYW4gYmUgbWFuaXB1bGF0ZWQgYW55d2hlcmUgYWxvbmcgdGhlaXIgbGVuZ3RoIGJ5CisgICAqIHNwZWNpZnlpbmcgPHZhcj5zcmNPZmZzZXQ8L3Zhcj4gYW5kIDx2YXI+ZGVzdE9mZnNldDwvdmFyPi4gVGhpcyBtZXRob2QKKyAgICogZG9lcyBub3QgY2hlY2sgdG8gbWFrZSBzdXJlIHlvdXIgYXJyYXlzIGFyZSBsYXJnZSBlbm91Z2ggdG8gYWNjb21vZGF0ZQorICAgKiA8dmFyPnNyY09mZnNldDwvdmFyPiArIDMgZm9yIHRoZSA8dmFyPnNvdXJjZTwvdmFyPiBhcnJheSBvcgorICAgKiA8dmFyPmRlc3RPZmZzZXQ8L3Zhcj4gKyA0IGZvciB0aGUgPHZhcj5kZXN0aW5hdGlvbjwvdmFyPiBhcnJheS4gVGhlCisgICAqIGFjdHVhbCBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4geW91ciBhcnJheSBpcyBnaXZlbiBieQorICAgKiA8dmFyPm51bVNpZ0J5dGVzPC92YXI+LgorICAgKiA8cD4KKyAgICogVGhpcyBpcyB0aGUgbG93ZXN0IGxldmVsIG9mIHRoZSBlbmNvZGluZyBtZXRob2RzIHdpdGggYWxsIHBvc3NpYmxlCisgICAqIHBhcmFtZXRlcnMuCisgICAqIAorICAgKiBAcGFyYW0gc291cmNlIHRoZSBhcnJheSB0byBjb252ZXJ0CisgICAqIEBwYXJhbSBzcmNPZmZzZXQgdGhlIGluZGV4IHdoZXJlIGNvbnZlcnNpb24gYmVnaW5zCisgICAqIEBwYXJhbSBudW1TaWdCeXRlcyB0aGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHlvdXIgYXJyYXkKKyAgICogQHBhcmFtIGRlc3RpbmF0aW9uIHRoZSBhcnJheSB0byBob2xkIHRoZSBjb252ZXJzaW9uCisgICAqIEBwYXJhbSBkZXN0T2Zmc2V0IHRoZSBpbmRleCB3aGVyZSBvdXRwdXQgd2lsbCBiZSBwdXQKKyAgICogQHJldHVybiB0aGUgPHZhcj5kZXN0aW5hdGlvbjwvdmFyPiBhcnJheQorICAgKiBAc2luY2UgMS4zCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGJ5dGVbXSBlbmNvZGUzdG80KGJ5dGVbXSBzb3VyY2UsIGludCBzcmNPZmZzZXQsCisgICAgICBpbnQgbnVtU2lnQnl0ZXMsIGJ5dGVbXSBkZXN0aW5hdGlvbiwgaW50IGRlc3RPZmZzZXQsIGludCBvcHRpb25zKSB7CisgICAgYnl0ZVtdIEFMUEhBQkVUID0gZ2V0QWxwaGFiZXQob3B0aW9ucyk7CisKKyAgICAvLyAgICAgICAgICAgMSAgICAgICAgIDIgICAgICAgICAzICAKKyAgICAvLyAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMSBCaXQgcG9zaXRpb24KKyAgICAvLyAtLS0tLS0tLTAwMDAwMDAwMTExMTExMTEyMjIyMjIyMiBBcnJheSBwb3NpdGlvbiBmcm9tIHRocmVlQnl0ZXMKKyAgICAvLyAtLS0tLS0tLXwgICAgfHwgICAgfHwgICAgfHwgICAgfCBTaXggYml0IGdyb3VwcyB0byBpbmRleCBBTFBIQUJFVAorICAgIC8vICAgICAgICAgID4+MTggID4+MTIgID4+IDYgID4+IDAgIFJpZ2h0IHNoaWZ0IG5lY2Vzc2FyeQorICAgIC8vICAgICAgICAgICAgICAgIDB4M2YgIDB4M2YgIDB4M2YgIEFkZGl0aW9uYWwgQU5ECisKKyAgICAvLyBDcmVhdGUgYnVmZmVyIHdpdGggemVyby1wYWRkaW5nIGlmIHRoZXJlIGFyZSBvbmx5IG9uZSBvciB0d28KKyAgICAvLyBzaWduaWZpY2FudCBieXRlcyBwYXNzZWQgaW4gdGhlIGFycmF5LgorICAgIC8vIFdlIGhhdmUgdG8gc2hpZnQgbGVmdCAyNCBpbiBvcmRlciB0byBmbHVzaCBvdXQgdGhlIDEncyB0aGF0IGFwcGVhcgorICAgIC8vIHdoZW4gSmF2YSB0cmVhdHMgYSB2YWx1ZSBhcyBuZWdhdGl2ZSB0aGF0IGlzIGNhc3QgZnJvbSBhIGJ5dGUgdG8gYW4gaW50LgorICAgIGludCBpbkJ1ZmYgPQorICAgICAgICAobnVtU2lnQnl0ZXMgPiAwID8gKChzb3VyY2Vbc3JjT2Zmc2V0XSA8PCAyNCkgPj4+IDgpIDogMCkKKyAgICAgICAgICAgIHwgKG51bVNpZ0J5dGVzID4gMSA/ICgoc291cmNlW3NyY09mZnNldCArIDFdIDw8IDI0KSA+Pj4gMTYpIDogMCkKKyAgICAgICAgICAgIHwgKG51bVNpZ0J5dGVzID4gMiA/ICgoc291cmNlW3NyY09mZnNldCArIDJdIDw8IDI0KSA+Pj4gMjQpIDogMCk7CisKKyAgICBzd2l0Y2ggKG51bVNpZ0J5dGVzKSB7CisgICAgY2FzZSAzOgorICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldF0gPSBBTFBIQUJFVFsoaW5CdWZmID4+PiAxOCldOworICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDFdID0gQUxQSEFCRVRbKGluQnVmZiA+Pj4gMTIpICYgMHgzZl07CisgICAgICBkZXN0aW5hdGlvbltkZXN0T2Zmc2V0ICsgMl0gPSBBTFBIQUJFVFsoaW5CdWZmID4+PiA2KSAmIDB4M2ZdOworICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDNdID0gQUxQSEFCRVRbKGluQnVmZikgJiAweDNmXTsKKyAgICAgIHJldHVybiBkZXN0aW5hdGlvbjsKKworICAgIGNhc2UgMjoKKyAgICAgIGRlc3RpbmF0aW9uW2Rlc3RPZmZzZXRdID0gQUxQSEFCRVRbKGluQnVmZiA+Pj4gMTgpXTsKKyAgICAgIGRlc3RpbmF0aW9uW2Rlc3RPZmZzZXQgKyAxXSA9IEFMUEhBQkVUWyhpbkJ1ZmYgPj4+IDEyKSAmIDB4M2ZdOworICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDJdID0gQUxQSEFCRVRbKGluQnVmZiA+Pj4gNikgJiAweDNmXTsKKyAgICAgIGRlc3RpbmF0aW9uW2Rlc3RPZmZzZXQgKyAzXSA9IEVRVUFMU19TSUdOOworICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uOworCisgICAgY2FzZSAxOgorICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldF0gPSBBTFBIQUJFVFsoaW5CdWZmID4+PiAxOCldOworICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDFdID0gQUxQSEFCRVRbKGluQnVmZiA+Pj4gMTIpICYgMHgzZl07CisgICAgICBkZXN0aW5hdGlvbltkZXN0T2Zmc2V0ICsgMl0gPSBFUVVBTFNfU0lHTjsKKyAgICAgIGRlc3RpbmF0aW9uW2Rlc3RPZmZzZXQgKyAzXSA9IEVRVUFMU19TSUdOOworICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uOworCisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBkZXN0aW5hdGlvbjsKKyAgICB9IC8vIGVuZCBzd2l0Y2gKKyAgfSAvLyBlbmQgZW5jb2RlM3RvNAorCisgIC8qKgorICAgKiBTZXJpYWxpemVzIGFuIG9iamVjdCBhbmQgcmV0dXJucyB0aGUgQmFzZTY0LWVuY29kZWQgdmVyc2lvbiBvZiB0aGF0CisgICAqIHNlcmlhbGl6ZWQgb2JqZWN0LiBJZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBzZXJpYWxpemVkIG9yIHRoZXJlIGlzIGFub3RoZXIKKyAgICogZXJyb3IsIHRoZSBtZXRob2Qgd2lsbCByZXR1cm4gPHR0Pm51bGw8L3R0Pi4gVGhlIG9iamVjdCBpcyBub3QKKyAgICogR1ppcC1jb21wcmVzc2VkIGJlZm9yZSBiZWluZyBlbmNvZGVkLgorICAgKiAKKyAgICogQHBhcmFtIHNlcmlhbGl6YWJsZU9iamVjdCBUaGUgb2JqZWN0IHRvIGVuY29kZQorICAgKiBAcmV0dXJuIFRoZSBCYXNlNjQtZW5jb2RlZCBvYmplY3QKKyAgICogQHNpbmNlIDEuNAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlT2JqZWN0KFNlcmlhbGl6YWJsZSBzZXJpYWxpemFibGVPYmplY3QpIHsKKyAgICByZXR1cm4gZW5jb2RlT2JqZWN0KHNlcmlhbGl6YWJsZU9iamVjdCwgTk9fT1BUSU9OUyk7CisgIH0gLy8gZW5kIGVuY29kZU9iamVjdAorCisgIC8qKgorICAgKiBTZXJpYWxpemVzIGFuIG9iamVjdCBhbmQgcmV0dXJucyB0aGUgQmFzZTY0LWVuY29kZWQgdmVyc2lvbiBvZiB0aGF0CisgICAqIHNlcmlhbGl6ZWQgb2JqZWN0LiBJZiB0aGUgb2JqZWN0IGNhbm5vdCBiZSBzZXJpYWxpemVkIG9yIHRoZXJlIGlzIGFub3RoZXIKKyAgICogZXJyb3IsIHRoZSBtZXRob2Qgd2lsbCByZXR1cm4gPHR0Pm51bGw8L3R0Pi4KKyAgICogPHA+CisgICAqIFZhbGlkIG9wdGlvbnM6CisgICAqIDx1bD4KKyAgICogICA8bGk+R1pJUDogZ3ppcC1jb21wcmVzc2VzIG9iamVjdCBiZWZvcmUgZW5jb2RpbmcgaXQuPC9saT4KKyAgICogICA8bGk+RE9OVF9CUkVBS19MSU5FUzogZG9uJ3QgYnJlYWsgbGluZXMgYXQgNzYgY2hhcmFjdGVycy4gPGk+Tm90ZToKKyAgICogICAgIFRlY2huaWNhbGx5LCB0aGlzIG1ha2VzIHlvdXIgZW5jb2Rpbmcgbm9uLWNvbXBsaWFudC48L2k+PC9saT4KKyAgICogPC91bD4KKyAgICogPHA+CisgICAqIEV4YW1wbGU6IDxjb2RlPmVuY29kZU9iamVjdCggbXlPYmosIEJhc2U2NC5HWklQICk8L2NvZGU+IG9yCisgICAqIDxwPgorICAgKiBFeGFtcGxlOgorICAgKiA8Y29kZT5lbmNvZGVPYmplY3QoIG15T2JqLCBCYXNlNjQuR1pJUCB8IEJhc2U2NC5ET05UX0JSRUFLX0xJTkVTICk8L2NvZGU+CisgICAqIAorICAgKiBAcGFyYW0gc2VyaWFsaXphYmxlT2JqZWN0IFRoZSBvYmplY3QgdG8gZW5jb2RlCisgICAqIEBwYXJhbSBvcHRpb25zIFNwZWNpZmllZCBvcHRpb25zCisgICAqIEBzZWUgQmFzZTY0I0daSVAKKyAgICogQHNlZSBCYXNlNjQjRE9OVF9CUkVBS19MSU5FUworICAgKiBAcmV0dXJuIFRoZSBCYXNlNjQtZW5jb2RlZCBvYmplY3QKKyAgICogQHNpbmNlIDIuMAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlT2JqZWN0KFNlcmlhbGl6YWJsZSBzZXJpYWxpemFibGVPYmplY3QsCisgICAgICBpbnQgb3B0aW9ucykgeworCisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgT3V0cHV0U3RyZWFtIGI2NG9zID0gbnVsbDsKKyAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgLy8gT2JqZWN0T3V0cHV0U3RyZWFtIC0+IChHWklQKSAtPiBCYXNlNjQgLT4gQnl0ZUFycmF5T3V0cHV0U3RyZWFtCisgICAgICBiNjRvcyA9IG5ldyBCYXNlNjRPdXRwdXRTdHJlYW0oYmFvcywgRU5DT0RFIHwgb3B0aW9ucyk7CisKKyAgICAgIG9vcyA9ICgob3B0aW9ucyAmIEdaSVApID09IEdaSVApID8KKyAgICAgICAgICBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG5ldyBHWklQT3V0cHV0U3RyZWFtKGI2NG9zKSkgOgorICAgICAgICAgICAgbmV3IE9iamVjdE91dHB1dFN0cmVhbShiNjRvcyk7CisKKyAgICAgIG9vcy53cml0ZU9iamVjdChzZXJpYWxpemFibGVPYmplY3QpOworICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYmFvcy50b0J5dGVBcnJheSgpLCBQUkVGRVJSRURfRU5DT0RJTkcpOworCisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB1dWUpIHsKKyAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJhb3MudG9CeXRlQXJyYXkoKSk7CisgICAgICAKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoImVycm9yIGVuY29kaW5nIG9iamVjdCIsIGUpOworICAgICAgcmV0dXJuIG51bGw7CisgICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKG9vcyAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgb29zLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nIE9iamVjdE91dHB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoYjY0b3MgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGI2NG9zLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nIEJhc2U2NE91dHB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBiYW9zLmNsb3NlKCk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuZXJyb3IoImVycm9yIGNsb3NpbmcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIiwgZSk7CisgICAgICB9CisgICAgfSAvLyBlbmQgZmluYWxseQorICB9IC8vIGVuZCBlbmNvZGUKKworICAvKioKKyAgICogRW5jb2RlcyBhIGJ5dGUgYXJyYXkgaW50byBCYXNlNjQgbm90YXRpb24uIERvZXMgbm90IEdaaXAtY29tcHJlc3MgZGF0YS4KKyAgICogCisgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGRhdGEgdG8gY29udmVydAorICAgKiBAcmV0dXJuIGVuY29kZWQgYnl0ZSBhcnJheQorICAgKiBAc2luY2UgMS40CisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGVCeXRlcyhieXRlW10gc291cmNlKSB7CisgICAgcmV0dXJuIGVuY29kZUJ5dGVzKHNvdXJjZSwgMCwgc291cmNlLmxlbmd0aCwgTk9fT1BUSU9OUyk7CisgIH0gLy8gZW5kIGVuY29kZUJ5dGVzCisKKyAgLyoqCisgICAqIEVuY29kZXMgYSBieXRlIGFycmF5IGludG8gQmFzZTY0IG5vdGF0aW9uLgorICAgKiA8cD4KKyAgICogVmFsaWQgb3B0aW9uczoKKyAgICogPHVsPgorICAgKiAgIDxsaT5HWklQOiBnemlwLWNvbXByZXNzZXMgb2JqZWN0IGJlZm9yZSBlbmNvZGluZyBpdC48L2xpPgorICAgKiAgIDxsaT5ET05UX0JSRUFLX0xJTkVTOiBkb24ndCBicmVhayBsaW5lcyBhdCA3NiBjaGFyYWN0ZXJzLiA8aT5Ob3RlOgorICAgKiAgICAgVGVjaG5pY2FsbHksIHRoaXMgbWFrZXMgeW91ciBlbmNvZGluZyBub24tY29tcGxpYW50LjwvaT48L2xpPgorICAgKiA8L3VsPgorICAgKiAKKyAgICogPHA+CisgICAqIEV4YW1wbGU6IDxjb2RlPmVuY29kZUJ5dGVzKCBteURhdGEsIEJhc2U2NC5HWklQICk8L2NvZGU+IG9yCisgICAqIDxwPgorICAgKiBFeGFtcGxlOgorICAgKiA8Y29kZT5lbmNvZGVCeXRlcyggbXlEYXRhLCBCYXNlNjQuR1pJUCB8IEJhc2U2NC5ET05UX0JSRUFLX0xJTkVTICk8L2NvZGU+CisgICAqIAorICAgKiBAcGFyYW0gc291cmNlIFRoZSBkYXRhIHRvIGNvbnZlcnQKKyAgICogQHBhcmFtIG9wdGlvbnMgU3BlY2lmaWVkIG9wdGlvbnMKKyAgICogQHNlZSBCYXNlNjQjR1pJUAorICAgKiBAc2VlIEJhc2U2NCNET05UX0JSRUFLX0xJTkVTCisgICAqIEBzZWUgQmFzZTY0I1VSTF9TQUZFCisgICAqIEBzZWUgQmFzZTY0I09SREVSRUQKKyAgICogQHJldHVybiBlbmNvZGVkIGJ5dGUgYXJyYXkKKyAgICogQHNpbmNlIDIuMAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlQnl0ZXMoYnl0ZVtdIHNvdXJjZSwgaW50IG9wdGlvbnMpIHsKKyAgICByZXR1cm4gZW5jb2RlQnl0ZXMoc291cmNlLCAwLCBzb3VyY2UubGVuZ3RoLCBvcHRpb25zKTsKKyAgfSAvLyBlbmQgZW5jb2RlQnl0ZXMKKworICAvKioKKyAgICogRW5jb2RlcyBhIGJ5dGUgYXJyYXkgaW50byBCYXNlNjQgbm90YXRpb24uIERvZXMgbm90IEdaaXAtY29tcHJlc3MgZGF0YS4KKyAgICogCisgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGRhdGEgdG8gY29udmVydAorICAgKiBAcGFyYW0gb2ZmIE9mZnNldCBpbiBhcnJheSB3aGVyZSBjb252ZXJzaW9uIHNob3VsZCBiZWdpbgorICAgKiBAcGFyYW0gbGVuIExlbmd0aCBvZiBkYXRhIHRvIGNvbnZlcnQKKyAgICogQHJldHVybiBlbmNvZGVkIGJ5dGUgYXJyYXkKKyAgICogQHNpbmNlIDEuNAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlQnl0ZXMoYnl0ZVtdIHNvdXJjZSwgaW50IG9mZiwgaW50IGxlbikgeworICAgIHJldHVybiBlbmNvZGVCeXRlcyhzb3VyY2UsIG9mZiwgbGVuLCBOT19PUFRJT05TKTsKKyAgfSAvLyBlbmQgZW5jb2RlQnl0ZXMKKworICAvKioKKyAgICogRW5jb2RlcyBhIGJ5dGUgYXJyYXkgaW50byBCYXNlNjQgbm90YXRpb24uCisgICAqIDxwPgorICAgKiBWYWxpZCBvcHRpb25zOgorICAgKiA8dWw+CisgICAqICAgPGxpPkdaSVA6IGd6aXAtY29tcHJlc3NlcyBvYmplY3QgYmVmb3JlIGVuY29kaW5nIGl0LjwvbGk+CisgICAqICAgPGxpPkRPTlRfQlJFQUtfTElORVM6IGRvbid0IGJyZWFrIGxpbmVzIGF0IDc2IGNoYXJhY3RlcnMuIDxpPk5vdGU6CisgICAqICAgICBUZWNobmljYWxseSwgdGhpcyBtYWtlcyB5b3VyIGVuY29kaW5nIG5vbi1jb21wbGlhbnQuPC9pPjwvbGk+CisgICAqIDwvdWw+CisgICAqIAorICAgKiA8cD4KKyAgICogRXhhbXBsZTogPGNvZGU+ZW5jb2RlQnl0ZXMoIG15RGF0YSwgQmFzZTY0LkdaSVAgKTwvY29kZT4gb3IKKyAgICogPHA+CisgICAqIEV4YW1wbGU6CisgICAqIDxjb2RlPmVuY29kZUJ5dGVzKCBteURhdGEsIEJhc2U2NC5HWklQIHwgQmFzZTY0LkRPTlRfQlJFQUtfTElORVMgKTwvY29kZT4KKyAgICogCisgICAqIEBwYXJhbSBzb3VyY2UgVGhlIGRhdGEgdG8gY29udmVydAorICAgKiBAcGFyYW0gb2ZmIE9mZnNldCBpbiBhcnJheSB3aGVyZSBjb252ZXJzaW9uIHNob3VsZCBiZWdpbgorICAgKiBAcGFyYW0gbGVuIExlbmd0aCBvZiBkYXRhIHRvIGNvbnZlcnQKKyAgICogQHBhcmFtIG9wdGlvbnMgU3BlY2lmaWVkIG9wdGlvbnMKKyAgICogQHNlZSBCYXNlNjQjR1pJUAorICAgKiBAc2VlIEJhc2U2NCNET05UX0JSRUFLX0xJTkVTCisgICAqIEBzZWUgQmFzZTY0I1VSTF9TQUZFCisgICAqIEBzZWUgQmFzZTY0I09SREVSRUQKKyAgICogQHJldHVybiBlbmNvZGVkIGJ5dGUgYXJyYXkKKyAgICogQHNpbmNlIDIuMAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlQnl0ZXMoYnl0ZVtdIHNvdXJjZSwgaW50IG9mZiwgaW50IGxlbiwgaW50IG9wdGlvbnMpIHsKKyAgICBpZiAoKG9wdGlvbnMgJiBHWklQKSA9PSBHWklQKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21wcmVzcz8KKyAgICAgIC8vIEdaaXAgLT4gQmFzZTY0IC0+IEJ5dGVBcnJheQorICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgICBHWklQT3V0cHV0U3RyZWFtIGd6b3MgPSBudWxsOworCisgICAgICB0cnkgeworICAgICAgICBnem9zID0gCisgICAgICAgICAgbmV3IEdaSVBPdXRwdXRTdHJlYW0obmV3IEJhc2U2NE91dHB1dFN0cmVhbShiYW9zLCBFTkNPREUgfCBvcHRpb25zKSk7CisKKyAgICAgICAgZ3pvcy53cml0ZShzb3VyY2UsIG9mZiwgbGVuKTsKKyAgICAgICAgZ3pvcy5jbG9zZSgpOworICAgICAgICBnem9zID0gbnVsbDsKKyAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYmFvcy50b0J5dGVBcnJheSgpLCBQUkVGRVJSRURfRU5DT0RJTkcpOworCisgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHV1ZSkgeworICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhiYW9zLnRvQnl0ZUFycmF5KCkpOworCisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiZXJyb3IgZW5jb2RpbmcgYnl0ZSBhcnJheSIsIGUpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgCisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBpZiAoZ3pvcyAhPSBudWxsKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGd6b3MuY2xvc2UoKTsKKyAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nIEdaSVBPdXRwdXRTdHJlYW0iLCBlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBiYW9zLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nIEJ5dGVBcnJheU91dHB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9IC8vIGVuZCBmaW5hbGx5CisKKyAgICB9IC8vIGVuZCBDb21wcmVzcworICAgIAorICAgIC8vIERvbid0IGNvbXByZXNzLiBCZXR0ZXIgbm90IHRvIHVzZSBzdHJlYW1zIGF0IGFsbCB0aGVuLgorCisgICAgYm9vbGVhbiBicmVha0xpbmVzID0gKChvcHRpb25zICYgRE9OVF9CUkVBS19MSU5FUykgPT0gMCk7CisKKyAgICBpbnQgbGVuNDMgPSBsZW4gKiA0IC8gMzsKKyAgICBieXRlW10gb3V0QnVmZiA9CisgICAgICBuZXcgYnl0ZVsobGVuNDMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFpbiA0OjMKKyAgICAgICAgICAgICAgICsgKChsZW4gJSAzKSA+IDAgPyA0IDogMCkgICAgICAgICAgICAgICAgICAgICAgICAvLyBwYWRkaW5nCisgICAgICAgICAgICAgICArIChicmVha0xpbmVzID8gKGxlbjQzIC8gTUFYX0xJTkVfTEVOR1RIKSA6IDApXTsgLy8gTmV3IGxpbmVzCisgICAgaW50IGQgPSAwOworICAgIGludCBlID0gMDsKKyAgICBpbnQgbGVuMiA9IGxlbiAtIDI7CisgICAgaW50IGxpbmVMZW5ndGggPSAwOworICAgIGZvciAoOyBkIDwgbGVuMjsgZCArPSAzLCBlICs9IDQpIHsKKyAgICAgIGVuY29kZTN0bzQoc291cmNlLCBkICsgb2ZmLCAzLCBvdXRCdWZmLCBlLCBvcHRpb25zKTsKKworICAgICAgbGluZUxlbmd0aCArPSA0OworICAgICAgaWYgKGJyZWFrTGluZXMgJiYgbGluZUxlbmd0aCA9PSBNQVhfTElORV9MRU5HVEgpIHsKKyAgICAgICAgb3V0QnVmZltlICsgNF0gPSBORVdfTElORTsKKyAgICAgICAgZSsrOworICAgICAgICBsaW5lTGVuZ3RoID0gMDsKKyAgICAgIH0gLy8gZW5kIGlmOiBlbmQgb2YgbGluZQorICAgIH0gLy8gZW5kIGZvcjogZWFjaCBwaWVjZSBvZiBhcnJheQorCisgICAgaWYgKGQgPCBsZW4pIHsKKyAgICAgIGVuY29kZTN0bzQoc291cmNlLCBkICsgb2ZmLCBsZW4gLSBkLCBvdXRCdWZmLCBlLCBvcHRpb25zKTsKKyAgICAgIGUgKz0gNDsKKyAgICB9IC8vIGVuZCBpZjogc29tZSBwYWRkaW5nIG5lZWRlZAorCisgICAgLy8gUmV0dXJuIHZhbHVlIGFjY29yZGluZyB0byByZWxldmFudCBlbmNvZGluZy4KKyAgICB0cnkgeworICAgICAgcmV0dXJuIG5ldyBTdHJpbmcob3V0QnVmZiwgMCwgZSwgUFJFRkVSUkVEX0VOQ09ESU5HKTsKKworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdXVlKSB7CisgICAgICByZXR1cm4gbmV3IFN0cmluZyhvdXRCdWZmLCAwLCBlKTsKKyAgICB9CisgIH0gLy8gZW5kIGVuY29kZUJ5dGVzCisKKyAgLyogKioqKioqKiogRCBFIEMgTyBEIEkgTiBHICAgTSBFIFQgSCBPIEQgUyAqKioqKioqKiAqLworCisgIC8qKgorICAgKiBEZWNvZGVzIGZvdXIgYnl0ZXMgZnJvbSBhcnJheSA8dmFyPnNvdXJjZTwvdmFyPiBhbmQgd3JpdGVzIHRoZSByZXN1bHRpbmcKKyAgICogYnl0ZXMgKHVwIHRvIHRocmVlIG9mIHRoZW0pIHRvIDx2YXI+ZGVzdGluYXRpb248L3Zhcj4uIFRoZSBzb3VyY2UgYW5kCisgICAqIGRlc3RpbmF0aW9uIGFycmF5cyBjYW4gYmUgbWFuaXB1bGF0ZWQgYW55d2hlcmUgYWxvbmcgdGhlaXIgbGVuZ3RoIGJ5CisgICAqIHNwZWNpZnlpbmcgPHZhcj5zcmNPZmZzZXQ8L3Zhcj4gYW5kIDx2YXI+ZGVzdE9mZnNldDwvdmFyPi4gVGhpcyBtZXRob2QKKyAgICogZG9lcyBub3QgY2hlY2sgdG8gbWFrZSBzdXJlIHlvdXIgYXJyYXlzIGFyZSBsYXJnZSBlbm91Z2ggdG8gYWNjb21vZGF0ZQorICAgKiA8dmFyPnNyY09mZnNldDwvdmFyPiArIDQgZm9yIHRoZSA8dmFyPnNvdXJjZTwvdmFyPiBhcnJheSBvcgorICAgKiA8dmFyPmRlc3RPZmZzZXQ8L3Zhcj4gKyAzIGZvciB0aGUgPHZhcj5kZXN0aW5hdGlvbjwvdmFyPiBhcnJheS4gVGhpcworICAgKiBtZXRob2QgcmV0dXJucyB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB0aGF0IHdlcmUgY29udmVydGVkIGZyb20gdGhlCisgICAqIEJhc2U2NCBlbmNvZGluZy4KKyAgICogPHA+CisgICAqIFRoaXMgaXMgdGhlIGxvd2VzdCBsZXZlbCBvZiB0aGUgZGVjb2RpbmcgbWV0aG9kcyB3aXRoIGFsbCBwb3NzaWJsZQorICAgKiBwYXJhbWV0ZXJzLgorICAgKiA8L3A+CisgICAqIAorICAgKiBAcGFyYW0gc291cmNlIHRoZSBhcnJheSB0byBjb252ZXJ0CisgICAqIEBwYXJhbSBzcmNPZmZzZXQgdGhlIGluZGV4IHdoZXJlIGNvbnZlcnNpb24gYmVnaW5zCisgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiB0aGUgYXJyYXkgdG8gaG9sZCB0aGUgY29udmVyc2lvbgorICAgKiBAcGFyYW0gZGVzdE9mZnNldCB0aGUgaW5kZXggd2hlcmUgb3V0cHV0IHdpbGwgYmUgcHV0CisgICAqIEBwYXJhbSBvcHRpb25zCisgICAqIEBzZWUgQmFzZTY0I1VSTF9TQUZFCisgICAqIEBzZWUgQmFzZTY0I09SREVSRUQKKyAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGRlY29kZWQgYnl0ZXMgY29udmVydGVkCisgICAqIEBzaW5jZSAxLjMKKyAgICovCisgIHByb3RlY3RlZCBzdGF0aWMgaW50IGRlY29kZTR0bzMoYnl0ZVtdIHNvdXJjZSwgaW50IHNyY09mZnNldCwKKyAgICAgIGJ5dGVbXSBkZXN0aW5hdGlvbiwgaW50IGRlc3RPZmZzZXQsIGludCBvcHRpb25zKSB7CisgICAgYnl0ZVtdIERFQ09EQUJFVCA9IGdldERlY29kYWJldChvcHRpb25zKTsKKworICAgIGlmIChzb3VyY2Vbc3JjT2Zmc2V0ICsgMl0gPT0gRVFVQUxTX1NJR04pIHsgICAgICAgICAgICAgICAgIC8vIEV4YW1wbGU6IERrPT0KKyAgICAgIC8vIFR3byB3YXlzIHRvIGRvIHRoZSBzYW1lIHRoaW5nLiBEb24ndCBrbm93IHdoaWNoIHdheSBJIGxpa2UgYmVzdC4KKyAgICAgIC8vIGludCBvdXRCdWZmID0gKCAoIERFQ09EQUJFVFsgc291cmNlWyBzcmNPZmZzZXQgXSBdIDw8IDI0ICkgPj4+IDYgKQorICAgICAgLy8gfCAoICggREVDT0RBQkVUWyBzb3VyY2VbIHNyY09mZnNldCArIDFdIF0gPDwgMjQgKSA+Pj4gMTIgKTsKKyAgICAgIGludCBvdXRCdWZmID0KKyAgICAgICAgICAoKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0XV0gJiAweEZGKSA8PCAxOCkKKyAgICAgICAgICAgICAgfCAoKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0ICsgMV1dICYgMHhGRikgPDwgMTIpOworCisgICAgICBkZXN0aW5hdGlvbltkZXN0T2Zmc2V0XSA9IChieXRlKSAob3V0QnVmZiA+Pj4gMTYpOworICAgICAgcmV0dXJuIDE7CisgICAgICAKKyAgICB9IGVsc2UgaWYgKHNvdXJjZVtzcmNPZmZzZXQgKyAzXSA9PSBFUVVBTFNfU0lHTikgeyAgICAgICAgICAvLyBFeGFtcGxlOiBEa0w9CisgICAgICAvLyBUd28gd2F5cyB0byBkbyB0aGUgc2FtZSB0aGluZy4gRG9uJ3Qga25vdyB3aGljaCB3YXkgSSBsaWtlIGJlc3QuCisgICAgICAvLyBpbnQgb3V0QnVmZiA9ICggKCBERUNPREFCRVRbIHNvdXJjZVsgc3JjT2Zmc2V0IF0gXSA8PCAyNCApID4+PiA2ICkKKyAgICAgIC8vIHwgKCAoIERFQ09EQUJFVFsgc291cmNlWyBzcmNPZmZzZXQgKyAxIF0gXSA8PCAyNCApID4+PiAxMiApCisgICAgICAvLyB8ICggKCBERUNPREFCRVRbIHNvdXJjZVsgc3JjT2Zmc2V0ICsgMiBdIF0gPDwgMjQgKSA+Pj4gMTggKTsKKyAgICAgIGludCBvdXRCdWZmID0KKyAgICAgICAgICAoKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0XV0gJiAweEZGKSA8PCAxOCkKKyAgICAgICAgICAgICAgfCAoKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0ICsgMV1dICYgMHhGRikgPDwgMTIpCisgICAgICAgICAgICAgIHwgKChERUNPREFCRVRbc291cmNlW3NyY09mZnNldCArIDJdXSAmIDB4RkYpIDw8IDYpOworCisgICAgICBkZXN0aW5hdGlvbltkZXN0T2Zmc2V0XSA9IChieXRlKSAob3V0QnVmZiA+Pj4gMTYpOworICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDFdID0gKGJ5dGUpIChvdXRCdWZmID4+PiA4KTsKKyAgICAgIHJldHVybiAyOworCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXhhbXBsZTogRGtMRQorICAgICAgdHJ5IHsKKyAgICAgICAgLy8gVHdvIHdheXMgdG8gZG8gdGhlIHNhbWUgdGhpbmcuIERvbid0IGtub3cgd2hpY2ggd2F5IEkgbGlrZSBiZXN0LgorICAgICAgICAvLyBpbnQgb3V0QnVmZiA9ICggKCBERUNPREFCRVRbIHNvdXJjZVsgc3JjT2Zmc2V0IF0gXSA8PCAyNCApID4+PiA2ICkKKyAgICAgICAgLy8gfCAoICggREVDT0RBQkVUWyBzb3VyY2VbIHNyY09mZnNldCArIDEgXSBdIDw8IDI0ICkgPj4+IDEyICkKKyAgICAgICAgLy8gfCAoICggREVDT0RBQkVUWyBzb3VyY2VbIHNyY09mZnNldCArIDIgXSBdIDw8IDI0ICkgPj4+IDE4ICkKKyAgICAgICAgLy8gfCAoICggREVDT0RBQkVUWyBzb3VyY2VbIHNyY09mZnNldCArIDMgXSBdIDw8IDI0ICkgPj4+IDI0ICk7CisgICAgICAgIGludCBvdXRCdWZmID0KKyAgICAgICAgICAgICgoREVDT0RBQkVUW3NvdXJjZVtzcmNPZmZzZXRdXSAmIDB4RkYpIDw8IDE4KQorICAgICAgICAgICAgICAgIHwgKChERUNPREFCRVRbc291cmNlW3NyY09mZnNldCArIDFdXSAmIDB4RkYpIDw8IDEyKQorICAgICAgICAgICAgICAgIHwgKChERUNPREFCRVRbc291cmNlW3NyY09mZnNldCArIDJdXSAmIDB4RkYpIDw8IDYpCisgICAgICAgICAgICAgICAgfCAoKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0ICsgM11dICYgMHhGRikpOworCisgICAgICAgIGRlc3RpbmF0aW9uW2Rlc3RPZmZzZXRdID0gKGJ5dGUpIChvdXRCdWZmID4+IDE2KTsKKyAgICAgICAgZGVzdGluYXRpb25bZGVzdE9mZnNldCArIDFdID0gKGJ5dGUpIChvdXRCdWZmID4+IDgpOworICAgICAgICBkZXN0aW5hdGlvbltkZXN0T2Zmc2V0ICsgMl0gPSAoYnl0ZSkgKG91dEJ1ZmYpOworCisgICAgICAgIHJldHVybiAzOworICAgICAgICAKKyAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiZXJyb3IgZGVjb2RpbmcgYnl0ZXMgYXQgIiArIHNvdXJjZVtzcmNPZmZzZXRdICsgIjogIiArIAorICAgICAgICAgICAgKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0XV0pICsgIiwgIiArIHNvdXJjZVtzcmNPZmZzZXQgKyAxXSArCisgICAgICAgICAgICAiOiAiICsgKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0ICsgMV1dKSArICIsICIgKworICAgICAgICAgICAgc291cmNlW3NyY09mZnNldCArIDJdICsgIjogIiArIChERUNPREFCRVRbc291cmNlW3NyY09mZnNldCArIDJdXSkgKworICAgICAgICAgICAgIiwgIiArIHNvdXJjZVtzcmNPZmZzZXQgKyAzXSArICI6ICIgKworICAgICAgICAgICAgKERFQ09EQUJFVFtzb3VyY2Vbc3JjT2Zmc2V0ICsgM11dKSwgZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICAgIH0gLy8gZW5kIGNhdGNoCisgICAgfQorICB9IC8vIGVuZCBkZWNvZGVUb0J5dGVzCisKKyAgLyoqCisgICAqIFZlcnkgbG93LWxldmVsIGFjY2VzcyB0byBkZWNvZGluZyBBU0NJSSBjaGFyYWN0ZXJzIGluIHRoZSBmb3JtIG9mIGEgYnl0ZQorICAgKiBhcnJheS4gRG9lcyBub3Qgc3VwcG9ydCBhdXRvbWF0aWNhbGx5IGd1bnppcHBpbmcgb3IgYW55IG90aGVyICJmYW5jeSIKKyAgICogZmVhdHVyZXMuCisgICAqIAorICAgKiBAcGFyYW0gc291cmNlIFRoZSBCYXNlNjQgZW5jb2RlZCBkYXRhCisgICAqIEBwYXJhbSBvZmYgVGhlIG9mZnNldCBvZiB3aGVyZSB0byBiZWdpbiBkZWNvZGluZworICAgKiBAcGFyYW0gbGVuIFRoZSBsZW5ndGggb2YgY2hhcmFjdGVycyB0byBkZWNvZGUKKyAgICogQHBhcmFtIG9wdGlvbnMgCisgICAqIEBzZWUgQmFzZTY0I1VSTF9TQUZFCisgICAqIEBzZWUgQmFzZTY0I09SREVSRUQKKyAgICogQHJldHVybiBkZWNvZGVkIGRhdGEKKyAgICogQHNpbmNlIDEuMworICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlW10gZGVjb2RlKGJ5dGVbXSBzb3VyY2UsIGludCBvZmYsIGludCBsZW4sIGludCBvcHRpb25zKSB7CisgICAgYnl0ZVtdIERFQ09EQUJFVCA9IGdldERlY29kYWJldChvcHRpb25zKTsKKworICAgIGludCBsZW4zNCA9IGxlbiAqIDMgLyA0OworICAgIGJ5dGVbXSBvdXRCdWZmID0gbmV3IGJ5dGVbbGVuMzRdOyAgICAgICAgICAgLy8gVXBwZXIgbGltaXQgb24gc2l6ZSBvZiBvdXRwdXQKKyAgICBpbnQgb3V0QnVmZlBvc24gPSAwOworCisgICAgYnl0ZVtdIGI0ID0gbmV3IGJ5dGVbNF07CisgICAgaW50IGI0UG9zbiA9IDA7CisgICAgaW50IGkgPSAwOworICAgIGJ5dGUgc2JpQ3JvcCA9IDA7CisgICAgYnl0ZSBzYmlEZWNvZGUgPSAwOworICAgIGZvciAoaSA9IG9mZjsgaSA8IG9mZiArIGxlbjsgaSsrKSB7CisgICAgICBzYmlDcm9wID0gKGJ5dGUpIChzb3VyY2VbaV0gJiAweDdmKTsgICAgICAvLyBPbmx5IHRoZSBsb3cgc2V2ZW4gYml0cworICAgICAgc2JpRGVjb2RlID0gREVDT0RBQkVUW3NiaUNyb3BdOworCisgICAgICBpZiAoc2JpRGVjb2RlID49IFdISVRFX1NQQUNFX0VOQykgeyAgICAgICAvLyBXaGl0ZXNwYWNlLCBFcXVhbHMgb3IgYmV0dGVyCisgICAgICAgIGlmIChzYmlEZWNvZGUgPj0gRVFVQUxTX1NJR05fRU5DKSB7ICAgICAvLyBFcXVhbHMgb3IgYmV0dGVyCisgICAgICAgICAgYjRbYjRQb3NuKytdID0gc2JpQ3JvcDsKKyAgICAgICAgICBpZiAoYjRQb3NuID4gMykgeworICAgICAgICAgICAgb3V0QnVmZlBvc24gKz0gZGVjb2RlNHRvMyhiNCwgMCwgb3V0QnVmZiwgb3V0QnVmZlBvc24sIG9wdGlvbnMpOworICAgICAgICAgICAgYjRQb3NuID0gMDsKKworICAgICAgICAgICAgLy8gSWYgdGhhdCB3YXMgdGhlIGVxdWFscyBzaWduLCBicmVhayBvdXQgb2YgJ2ZvcicgbG9vcAorICAgICAgICAgICAgaWYgKHNiaUNyb3AgPT0gRVFVQUxTX1NJR04pCisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0gLy8gZW5kIGlmOiBxdWFydGV0IGJ1aWx0CisgICAgICAgIH0gLy8gZW5kIGlmOiBlcXVhbHMgc2lnbiBvciBiZXR0ZXIKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIExPRy5lcnJvcigiQmFkIEJhc2U2NCBpbnB1dCBjaGFyYWN0ZXIgYXQgIiArIGkgKyAiOiAiICsgc291cmNlW2ldICsKKyAgICAgICAgICAgICIoZGVjaW1hbCkiKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9IC8vIGVuZCBlbHNlOgorICAgIH0gLy8gZWFjaCBpbnB1dCBjaGFyYWN0ZXIKKworICAgIGJ5dGVbXSBvdXQgPSBuZXcgYnl0ZVtvdXRCdWZmUG9zbl07CisgICAgU3lzdGVtLmFycmF5Y29weShvdXRCdWZmLCAwLCBvdXQsIDAsIG91dEJ1ZmZQb3NuKTsKKyAgICByZXR1cm4gb3V0OworICB9IC8vIGVuZCBkZWNvZGUKKworICAvKioKKyAgICogRGVjb2RlcyBkYXRhIGZyb20gQmFzZTY0IG5vdGF0aW9uLCBhdXRvbWF0aWNhbGx5IGRldGVjdGluZyBnemlwLWNvbXByZXNzZWQKKyAgICogZGF0YSBhbmQgZGVjb21wcmVzc2luZyBpdC4KKyAgICogCisgICAqIEBwYXJhbSBzIHRoZSBzdHJpbmcgdG8gZGVjb2RlCisgICAqIEByZXR1cm4gdGhlIGRlY29kZWQgZGF0YQorICAgKiBAc2luY2UgMS40CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkZWNvZGUoU3RyaW5nIHMpIHsKKyAgICByZXR1cm4gZGVjb2RlKHMsIE5PX09QVElPTlMpOworICB9CisKKyAgLyoqCisgICAqIERlY29kZXMgZGF0YSBmcm9tIEJhc2U2NCBub3RhdGlvbiwgYXV0b21hdGljYWxseSBkZXRlY3RpbmcgZ3ppcC1jb21wcmVzc2VkCisgICAqIGRhdGEgYW5kIGRlY29tcHJlc3NpbmcgaXQuCisgICAqIAorICAgKiBAcGFyYW0gcyB0aGUgc3RyaW5nIHRvIGRlY29kZQorICAgKiBAcGFyYW0gb3B0aW9ucworICAgKiBAc2VlIEJhc2U2NCNVUkxfU0FGRQorICAgKiBAc2VlIEJhc2U2NCNPUkRFUkVECisgICAqIEByZXR1cm4gdGhlIGRlY29kZWQgZGF0YQorICAgKiBAc2luY2UgMS40CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkZWNvZGUoU3RyaW5nIHMsIGludCBvcHRpb25zKSB7CisgICAgYnl0ZVtdIGJ5dGVzID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgYnl0ZXMgPSBzLmdldEJ5dGVzKFBSRUZFUlJFRF9FTkNPRElORyk7CisKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVlZSkgeworICAgICAgYnl0ZXMgPSBzLmdldEJ5dGVzKCk7CisgICAgfSAvLyBlbmQgY2F0Y2gKKworICAgIC8vIERlY29kZQorCisgICAgYnl0ZXMgPSBkZWNvZGUoYnl0ZXMsIDAsIGJ5dGVzLmxlbmd0aCwgb3B0aW9ucyk7CisKKyAgICAvLyBDaGVjayB0byBzZWUgaWYgaXQncyBnemlwLWNvbXByZXNzZWQKKyAgICAvLyBHWklQIE1hZ2ljIFR3by1CeXRlIE51bWJlcjogMHg4YjFmICgzNTYxNSkKKworICAgIGlmIChieXRlcyAhPSBudWxsICYmIGJ5dGVzLmxlbmd0aCA+PSA0KSB7CisgICAgICBpbnQgaGVhZCA9IChieXRlc1swXSAmIDB4ZmYpIHwgKChieXRlc1sxXSA8PCA4KSAmIDB4ZmYwMCk7CisgICAgICBpZiAoR1pJUElucHV0U3RyZWFtLkdaSVBfTUFHSUMgPT0gaGVhZCkgeworICAgICAgICBHWklQSW5wdXRTdHJlYW0gZ3ppcyA9IG51bGw7CisgICAgICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYW9zID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgICAgICB0cnkgeworICAgICAgICAgIGd6aXMgPSBuZXcgR1pJUElucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcykpOworCisgICAgICAgICAgYnl0ZVtdIGJ1ZmZlciA9IG5ldyBieXRlWzIwNDhdOworICAgICAgICAgIGZvciAoaW50IGxlbmd0aCA9IDA7IChsZW5ndGggPSBnemlzLnJlYWQoYnVmZmVyKSkgPj0gMDsgKSB7CisgICAgICAgICAgICBiYW9zLndyaXRlKGJ1ZmZlciwgMCwgbGVuZ3RoKTsKKyAgICAgICAgICB9IC8vIGVuZCB3aGlsZTogcmVhZGluZyBpbnB1dAorCisgICAgICAgICAgLy8gTm8gZXJyb3I/IEdldCBuZXcgYnl0ZXMuCisgICAgICAgICAgYnl0ZXMgPSBiYW9zLnRvQnl0ZUFycmF5KCk7CisKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIEp1c3QgcmV0dXJuIG9yaWdpbmFsbHktZGVjb2RlZCBieXRlcworCisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGJhb3MuY2xvc2UoKTsKKyAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nIEJ5dGVBcnJheU91dHB1dFN0cmVhbSIsIGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoZ3ppcyAhPSBudWxsKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBnemlzLmNsb3NlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICBMT0cuZXJyb3IoImVycm9yIGNsb3NpbmcgR1pJUElucHV0U3RyZWFtIiwgZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9IC8vIGVuZCBmaW5hbGx5CisgICAgICB9IC8vIGVuZCBpZjogZ3ppcHBlZAorICAgIH0gLy8gZW5kIGlmOiBieXRlcy5sZW5ndGggPj0gMgorCisgICAgcmV0dXJuIGJ5dGVzOworICB9IC8vIGVuZCBkZWNvZGUKKworICAvKioKKyAgICogQXR0ZW1wdHMgdG8gZGVjb2RlIEJhc2U2NCBkYXRhIGFuZCBkZXNlcmlhbGl6ZSBhIEphdmEgT2JqZWN0IHdpdGhpbi4KKyAgICogUmV0dXJucyA8dHQ+bnVsbDwvdHQ+IGlmIHRoZXJlIHdhcyBhbiBlcnJvci4KKyAgICogCisgICAqIEBwYXJhbSBlbmNvZGVkT2JqZWN0IFRoZSBCYXNlNjQgZGF0YSB0byBkZWNvZGUKKyAgICogQHJldHVybiBUaGUgZGVjb2RlZCBhbmQgZGVzZXJpYWxpemVkIG9iamVjdAorICAgKiBAc2luY2UgMS41CisgICAqLworICBwdWJsaWMgc3RhdGljIE9iamVjdCBkZWNvZGVUb09iamVjdChTdHJpbmcgZW5jb2RlZE9iamVjdCkgeworICAgIC8vIERlY29kZSBhbmQgZ3VuemlwIGlmIG5lY2Vzc2FyeQorICAgIGJ5dGVbXSBvYmpCeXRlcyA9IGRlY29kZShlbmNvZGVkT2JqZWN0KTsKKworICAgIE9iamVjdCBvYmogPSBudWxsOworICAgIE9iamVjdElucHV0U3RyZWFtIG9pcyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIG9pcyA9IG5ldyBPYmplY3RJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob2JqQnl0ZXMpKTsKKyAgICAgIG9iaiA9IG9pcy5yZWFkT2JqZWN0KCk7CisKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoImVycm9yIGRlY29kaW5nIG9iamVjdCIsIGUpOworCisgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoImVycm9yIGRlY29kaW5nIG9iamVjdCIsIGUpOworCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChvaXMgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIG9pcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiZXJyb3IgY2xvc2luZyBPYmplY3RJbnB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSAvLyBlbmQgZmluYWxseQorCisgICAgcmV0dXJuIG9iajsKKyAgfSAvLyBlbmQgZGVjb2RlT2JqZWN0CisKKyAgLyoqCisgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgZW5jb2RpbmcgZGF0YSB0byBhIGZpbGUuCisgICAqIAorICAgKiBAcGFyYW0gZGF0YVRvRW5jb2RlIGJ5dGUgYXJyYXkgb2YgZGF0YSB0byBlbmNvZGUgaW4gYmFzZTY0IGZvcm0KKyAgICogQHBhcmFtIGZpbGVuYW1lIEZpbGVuYW1lIGZvciBzYXZpbmcgZW5jb2RlZCBkYXRhCisgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBzdWNjZXNzZnVsLCA8dHQ+ZmFsc2U8L3R0PiBvdGhlcndpc2UKKyAgICogCisgICAqIEBzaW5jZSAyLjEKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlbmNvZGVUb0ZpbGUoYnl0ZVtdIGRhdGFUb0VuY29kZSwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgQmFzZTY0T3V0cHV0U3RyZWFtIGJvcyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIGJvcyA9IG5ldyBCYXNlNjRPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZW5hbWUpLCBFTkNPREUpOworICAgICAgYm9zLndyaXRlKGRhdGFUb0VuY29kZSk7CisgICAgICBzdWNjZXNzID0gdHJ1ZTsKKworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiZXJyb3IgZW5jb2RpbmcgZmlsZTogIiArIGZpbGVuYW1lLCBlKTsKKyAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgIAorICAgIH0gZmluYWxseSB7CisgICAgICBpZiAoYm9zICE9IG51bGwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBib3MuY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZXJyb3IoImVycm9yIGNsb3NpbmcgQmFzZTY0T3V0cHV0U3RyZWFtIiwgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IC8vIGVuZCBmaW5hbGx5CisKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfSAvLyBlbmQgZW5jb2RlVG9GaWxlCisKKyAgLyoqCisgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgZGVjb2RpbmcgZGF0YSB0byBhIGZpbGUuCisgICAqIAorICAgKiBAcGFyYW0gZGF0YVRvRGVjb2RlIEJhc2U2NC1lbmNvZGVkIGRhdGEgYXMgYSBzdHJpbmcKKyAgICogQHBhcmFtIGZpbGVuYW1lIEZpbGVuYW1lIGZvciBzYXZpbmcgZGVjb2RlZCBkYXRhCisgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiBzdWNjZXNzZnVsLCA8dHQ+ZmFsc2U8L3R0PiBvdGhlcndpc2UKKyAgICogCisgICAqIEBzaW5jZSAyLjEKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWNvZGVUb0ZpbGUoU3RyaW5nIGRhdGFUb0RlY29kZSwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgYm9vbGVhbiBzdWNjZXNzID0gZmFsc2U7CisgICAgQmFzZTY0T3V0cHV0U3RyZWFtIGJvcyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIGJvcyA9IG5ldyBCYXNlNjRPdXRwdXRTdHJlYW0obmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZW5hbWUpLCBERUNPREUpOworICAgICAgYm9zLndyaXRlKGRhdGFUb0RlY29kZS5nZXRCeXRlcyhQUkVGRVJSRURfRU5DT0RJTkcpKTsKKyAgICAgIHN1Y2Nlc3MgPSB0cnVlOworICAgICAgCisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJlcnJvciBkZWNvZGluZyB0byBmaWxlOiAiICsgZmlsZW5hbWUsIGUpOworICAgICAgc3VjY2VzcyA9IGZhbHNlOworCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChib3MgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGJvcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiZXJyb3IgY2xvc2luZyBCYXNlNjRPdXRwdXRTdHJlYW0iLCBlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gLy8gZW5kIGZpbmFsbHkKKworICAgIHJldHVybiBzdWNjZXNzOworICB9IC8vIGVuZCBkZWNvZGVUb0ZpbGUKKworICAvKioKKyAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciByZWFkaW5nIGEgYmFzZTY0LWVuY29kZWQgZmlsZSBhbmQgZGVjb2RpbmcgaXQuCisgICAqIAorICAgKiBAcGFyYW0gZmlsZW5hbWUgRmlsZW5hbWUgZm9yIHJlYWRpbmcgZW5jb2RlZCBkYXRhCisgICAqIEByZXR1cm4gZGVjb2RlZCBieXRlIGFycmF5IG9yIG51bGwgaWYgdW5zdWNjZXNzZnVsCisgICAqIAorICAgKiBAc2luY2UgMi4xCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBkZWNvZGVGcm9tRmlsZShTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICBieXRlW10gZGVjb2RlZERhdGEgPSBudWxsOworICAgIEJhc2U2NElucHV0U3RyZWFtIGJpcyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGZpbGVuYW1lKTsKKyAgICAgIGJ5dGVbXSBidWZmZXIgPSBudWxsOworCisgICAgICAvLyBDaGVjayB0aGUgc2l6ZSBvZiBmaWxlCisgICAgICBpZiAoZmlsZS5sZW5ndGgoKSA+IEludGVnZXIuTUFYX1ZBTFVFKSB7CisgICAgICAgIExPRy5mYXRhbCgiRmlsZSBpcyB0b28gYmlnIGZvciB0aGlzIGNvbnZlbmllbmNlIG1ldGhvZCAoIiArIAorICAgICAgICAgICAgZmlsZS5sZW5ndGgoKSArICIgYnl0ZXMpLiIpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0gLy8gZW5kIGlmOiBmaWxlIHRvbyBiaWcgZm9yIGludCBpbmRleAorICAgICAgCisgICAgICBidWZmZXIgPSBuZXcgYnl0ZVsoaW50KSBmaWxlLmxlbmd0aCgpXTsKKworICAgICAgLy8gT3BlbiBhIHN0cmVhbQorICAgICAgCisgICAgICBiaXMgPSBuZXcgQmFzZTY0SW5wdXRTdHJlYW0obmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oCisgICAgICAgICAgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSksIERFQ09ERSk7CisKKyAgICAgIC8vIFJlYWQgdW50aWwgZG9uZQorICAgICAgCisgICAgICBpbnQgbGVuZ3RoID0gMDsKKyAgICAgIGZvciAoaW50IG51bUJ5dGVzID0gMDsgKG51bUJ5dGVzID0gYmlzLnJlYWQoYnVmZmVyLCBsZW5ndGgsIDQwOTYpKSA+PSAwOyApIHsKKyAgICAgICAgbGVuZ3RoICs9IG51bUJ5dGVzOworICAgICAgfQorICAgICAgCisgICAgICAvLyBTYXZlIGluIGEgdmFyaWFibGUgdG8gcmV0dXJuCisgICAgICAKKyAgICAgIGRlY29kZWREYXRhID0gbmV3IGJ5dGVbbGVuZ3RoXTsKKyAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAwLCBkZWNvZGVkRGF0YSwgMCwgbGVuZ3RoKTsKKworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiRXJyb3IgZGVjb2RpbmcgZnJvbSBmaWxlICIgKyBmaWxlbmFtZSwgZSk7CisgICAgCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChiaXMgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGJpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiZXJyb3IgY2xvc2luZyBCYXNlNjRJbnB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSAvLyBlbmQgZmluYWxseQorCisgICAgcmV0dXJuIGRlY29kZWREYXRhOworICB9IC8vIGVuZCBkZWNvZGVGcm9tRmlsZQorCisgIC8qKgorICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIHJlYWRpbmcgYSBiaW5hcnkgZmlsZSBhbmQgYmFzZTY0LWVuY29kaW5nIGl0LgorICAgKiAKKyAgICogQHBhcmFtIGZpbGVuYW1lIEZpbGVuYW1lIGZvciByZWFkaW5nIGJpbmFyeSBkYXRhCisgICAqIEByZXR1cm4gYmFzZTY0LWVuY29kZWQgc3RyaW5nIG9yIG51bGwgaWYgdW5zdWNjZXNzZnVsCisgICAqIAorICAgKiBAc2luY2UgMi4xCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBlbmNvZGVGcm9tRmlsZShTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICBTdHJpbmcgZW5jb2RlZERhdGEgPSBudWxsOworICAgIEJhc2U2NElucHV0U3RyZWFtIGJpcyA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGZpbGVuYW1lKTsKKyAgICAgIAorICAgICAgLy8gTmVlZCBtYXgoKSBmb3IgbWF0aCBvbiBzbWFsbCBmaWxlcyAodjIuMi4xKQorICAgICAgCisgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbTWF0aC5tYXgoKGludCkgKGZpbGUubGVuZ3RoKCkgKiAxLjQpLCA0MCldOworCisgICAgICAvLyBPcGVuIGEgc3RyZWFtCisKKyAgICAgIGJpcyA9IG5ldyBCYXNlNjRJbnB1dFN0cmVhbShuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgICAgbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSksIEVOQ09ERSk7CisKKyAgICAgIC8vIFJlYWQgdW50aWwgZG9uZQorICAgICAgaW50IGxlbmd0aCA9IDA7CisgICAgICBmb3IgKGludCBudW1CeXRlcyA9IDA7IChudW1CeXRlcyA9IGJpcy5yZWFkKGJ1ZmZlciwgbGVuZ3RoLCA0MDk2KSkgPj0gMDsgKSB7CisgICAgICAgIGxlbmd0aCArPSBudW1CeXRlczsKKyAgICAgIH0KKworICAgICAgLy8gU2F2ZSBpbiBhIHZhcmlhYmxlIHRvIHJldHVybgorICAgICAgCisgICAgICBlbmNvZGVkRGF0YSA9IG5ldyBTdHJpbmcoYnVmZmVyLCAwLCBsZW5ndGgsIFBSRUZFUlJFRF9FTkNPRElORyk7CisKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoIkVycm9yIGVuY29kaW5nIGZyb20gZmlsZSAiICsgZmlsZW5hbWUsIGUpOworICAgICAgCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChiaXMgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGJpcy5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiZXJyb3IgY2xvc2luZyBCYXNlNjRJbnB1dFN0cmVhbSIsIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfSAvLyBlbmQgZmluYWxseQorCisgICAgcmV0dXJuIGVuY29kZWREYXRhOworICB9IC8vIGVuZCBlbmNvZGVGcm9tRmlsZQorCisgIC8qKgorICAgKiBSZWFkcyA8dHQ+aW5maWxlPC90dD4gYW5kIGVuY29kZXMgaXQgdG8gPHR0Pm91dGZpbGU8L3R0Pi4KKyAgICogCisgICAqIEBwYXJhbSBpbmZpbGUgSW5wdXQgZmlsZQorICAgKiBAcGFyYW0gb3V0ZmlsZSBPdXRwdXQgZmlsZQorICAgKiBAc2luY2UgMi4yCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgZW5jb2RlRmlsZVRvRmlsZShTdHJpbmcgaW5maWxlLCBTdHJpbmcgb3V0ZmlsZSkgeworICAgIFN0cmluZyBlbmNvZGVkID0gZW5jb2RlRnJvbUZpbGUoaW5maWxlKTsKKyAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgb3V0ID0gbmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKG91dGZpbGUpKTsKKyAgICAgIG91dC53cml0ZShlbmNvZGVkLmdldEJ5dGVzKCJVUy1BU0NJSSIpKTsgLy8gU3RyaWN0LCA3LWJpdCBvdXRwdXQuCisgICAgCisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJlcnJvciBlbmNvZGluZyBmcm9tIGZpbGUgIiArIGluZmlsZSArICIgdG8gIiArIG91dGZpbGUsIGUpOworCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChvdXQgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy5lcnJvcigiZXJyb3IgY2xvc2luZyAiICsgb3V0ZmlsZSwgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IC8vIGVuZCBmaW5hbGx5CisgIH0gLy8gZW5kIGVuY29kZUZpbGVUb0ZpbGUKKworICAvKioKKyAgICogUmVhZHMgPHR0PmluZmlsZTwvdHQ+IGFuZCBkZWNvZGVzIGl0IHRvIDx0dD5vdXRmaWxlPC90dD4uCisgICAqIAorICAgKiBAcGFyYW0gaW5maWxlIElucHV0IGZpbGUKKyAgICogQHBhcmFtIG91dGZpbGUgT3V0cHV0IGZpbGUKKyAgICogQHNpbmNlIDIuMgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGRlY29kZUZpbGVUb0ZpbGUoU3RyaW5nIGluZmlsZSwgU3RyaW5nIG91dGZpbGUpIHsKKyAgICBieXRlW10gZGVjb2RlZCA9IGRlY29kZUZyb21GaWxlKGluZmlsZSk7CisgICAgT3V0cHV0U3RyZWFtIG91dCA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIG91dCA9IG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRmaWxlKSk7CisgICAgICBvdXQud3JpdGUoZGVjb2RlZCk7CisgICAgICAKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoImVycm9yIGRlY29kaW5nIGZyb20gZmlsZSAiICsgaW5maWxlICsgIiB0byAiICsgb3V0ZmlsZSwgZSk7CisKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmVycm9yKCJlcnJvciBjbG9zaW5nICIgKyBvdXRmaWxlLCBlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gLy8gZW5kIGZpbmFsbHkKKyAgfSAvLyBlbmQgZGVjb2RlRmlsZVRvRmlsZQorCisgIC8qICoqKioqKioqIEkgTiBOIEUgUiAgIEMgTCBBIFMgUyAgIEkgTiBQIFUgVCBTIFQgUiBFIEEgTSAqKioqKioqKiAqLworCisgIC8qKgorICAgKiBBIHtAbGluayBCYXNlNjQuQmFzZTY0SW5wdXRTdHJlYW19IHdpbGwgcmVhZCBkYXRhIGZyb20gYW5vdGhlcgorICAgKiA8dHQ+SW5wdXRTdHJlYW08L3R0PiwgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLCBhbmQKKyAgICogZW5jb2RlL2RlY29kZSB0by9mcm9tIEJhc2U2NCBub3RhdGlvbiBvbiB0aGUgZmx5LgorICAgKiAKKyAgICogQHNlZSBCYXNlNjQKKyAgICogQHNpbmNlIDEuMworICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBCYXNlNjRJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKyAgICBwcml2YXRlIGJvb2xlYW4gZW5jb2RlOyAgICAgICAgICAgICAgICAgICAgIC8vIEVuY29kaW5nIG9yIGRlY29kaW5nCisgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247ICAgICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50IHBvc2l0aW9uIGluIHRoZSBidWZmZXIKKyAgICBwcml2YXRlIGJ5dGVbXSBidWZmZXI7ICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZmZlciBob2xkaW5nIGNvbnZlcnRlZCBkYXRhCisgICAgcHJpdmF0ZSBpbnQgYnVmZmVyTGVuZ3RoOyAgICAgICAgICAgICAgICAgICAvLyBMZW5ndGggb2YgYnVmZmVyICgzIG9yIDQpCisgICAgcHJpdmF0ZSBpbnQgbnVtU2lnQnl0ZXM7ICAgICAgICAgICAgICAgICAgICAvLyBNZWFuaW5nZnVsIGJ5dGVzIGluIHRoZSBidWZmZXIKKyAgICBwcml2YXRlIGludCBsaW5lTGVuZ3RoOworICAgIHByaXZhdGUgYm9vbGVhbiBicmVha0xpbmVzOyAgICAgICAgICAgICAgICAgLy8gQnJlYWsgbGluZXMgYXQgPCA4MCBjaGFyYWN0ZXJzCisgICAgcHJpdmF0ZSBpbnQgb3B0aW9uczsgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWNvcmQgb3B0aW9ucworICAgIHByaXZhdGUgYnl0ZVtdIGRlY29kYWJldDsgICAgICAgICAgICAgICAgICAgLy8gTG9jYWwgY29weSBhdm9pZHMgbWV0aG9kIGNhbGxzCisKKyAgICAvKioKKyAgICAgKiBDb25zdHJ1Y3RzIGEge0BsaW5rIEJhc2U2NElucHV0U3RyZWFtfSBpbiBERUNPREUgbW9kZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW4gdGhlIDx0dD5JbnB1dFN0cmVhbTwvdHQ+IGZyb20gd2hpY2ggdG8gcmVhZCBkYXRhLgorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgQmFzZTY0SW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4pIHsKKyAgICAgIHRoaXMoaW4sIERFQ09ERSk7CisgICAgfSAvLyBlbmQgY29uc3RydWN0b3IKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGxpbmsgQmFzZTY0LkJhc2U2NElucHV0U3RyZWFtfSBpbiBlaXRoZXIgRU5DT0RFIG9yIERFQ09ERSBtb2RlLgorICAgICAqIDxwPgorICAgICAqIFZhbGlkIG9wdGlvbnM6CisgICAgICogCisgICAgICogPHByZT4KKyAgICAgKiAgIEVOQ09ERSBvciBERUNPREU6IEVuY29kZSBvciBEZWNvZGUgYXMgZGF0YSBpcyByZWFkLgorICAgICAqICAgRE9OVF9CUkVBS19MSU5FUzogZG9uJ3QgYnJlYWsgbGluZXMgYXQgNzYgY2hhcmFjdGVycworICAgICAqICAgICAob25seSBtZWFuaW5nZnVsIHdoZW4gZW5jb2RpbmcpCisgICAgICogICAgICZsdDtpJmd0O05vdGU6IFRlY2huaWNhbGx5LCB0aGlzIG1ha2VzIHlvdXIgZW5jb2Rpbmcgbm9uLWNvbXBsaWFudC4mbHQ7L2kmZ3Q7CisgICAgICogPC9wcmU+CisgICAgICogCisgICAgICogPHA+CisgICAgICogRXhhbXBsZTogPGNvZGU+bmV3IEJhc2U2NC5CYXNlNjRJbnB1dFN0cmVhbSggaW4sIEJhc2U2NC5ERUNPREUgKTwvY29kZT4KKyAgICAgKiAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW4gdGhlIDx0dD5JbnB1dFN0cmVhbTwvdHQ+IGZyb20gd2hpY2ggdG8gcmVhZCBkYXRhLgorICAgICAqIEBwYXJhbSBvcHRpb25zIFNwZWNpZmllZCBvcHRpb25zCisgICAgICogQHNlZSBCYXNlNjQjRU5DT0RFCisgICAgICogQHNlZSBCYXNlNjQjREVDT0RFCisgICAgICogQHNlZSBCYXNlNjQjRE9OVF9CUkVBS19MSU5FUworICAgICAqIEBzaW5jZSAyLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgQmFzZTY0SW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW4sIGludCBvcHRpb25zKSB7CisgICAgICBzdXBlcihpbik7CisgICAgICB0aGlzLmJyZWFrTGluZXMgPSAob3B0aW9ucyAmIERPTlRfQlJFQUtfTElORVMpICE9IERPTlRfQlJFQUtfTElORVM7CisgICAgICB0aGlzLmVuY29kZSA9IChvcHRpb25zICYgRU5DT0RFKSA9PSBFTkNPREU7CisgICAgICB0aGlzLmJ1ZmZlckxlbmd0aCA9IGVuY29kZSA/IDQgOiAzOworICAgICAgdGhpcy5idWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJMZW5ndGhdOworICAgICAgdGhpcy5wb3NpdGlvbiA9IC0xOworICAgICAgdGhpcy5saW5lTGVuZ3RoID0gMDsKKyAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7IC8vIFJlY29yZCBmb3IgbGF0ZXIsIG1vc3RseSB0byBkZXRlcm1pbmUgd2hpY2gKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFscGhhYmV0IHRvIHVzZQorICAgICAgdGhpcy5kZWNvZGFiZXQgPSBnZXREZWNvZGFiZXQob3B0aW9ucyk7CisgICAgfSAvLyBlbmQgY29uc3RydWN0b3IKKworICAgIC8qKgorICAgICAqIFJlYWRzIGVub3VnaCBvZiB0aGUgaW5wdXQgc3RyZWFtIHRvIGNvbnZlcnQgdG8vZnJvbSBCYXNlNjQgYW5kIHJldHVybnMKKyAgICAgKiB0aGUgbmV4dCBieXRlLgorICAgICAqIAorICAgICAqIEByZXR1cm4gbmV4dCBieXRlCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAvLyBEbyB3ZSBuZWVkIHRvIGdldCBkYXRhPworICAgICAgaWYgKHBvc2l0aW9uIDwgMCkgeworICAgICAgICBpZiAoZW5jb2RlKSB7CisgICAgICAgICAgYnl0ZVtdIGIzID0gbmV3IGJ5dGVbM107CisgICAgICAgICAgaW50IG51bUJpbmFyeUJ5dGVzID0gMDsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgaW50IGIgPSBpbi5yZWFkKCk7CisKKyAgICAgICAgICAgICAgLy8gSWYgZW5kIG9mIHN0cmVhbSwgYiBpcyAtMS4KKyAgICAgICAgICAgICAgaWYgKGIgPj0gMCkgeworICAgICAgICAgICAgICAgIGIzW2ldID0gKGJ5dGUpIGI7CisgICAgICAgICAgICAgICAgbnVtQmluYXJ5Qnl0ZXMrKzsKKyAgICAgICAgICAgICAgfSAvLyBlbmQgaWY6IG5vdCBlbmQgb2Ygc3RyZWFtCisKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgLy8gT25seSBhIHByb2JsZW0gaWYgd2UgZ290IG5vIGRhdGEgYXQgYWxsLgorICAgICAgICAgICAgICBpZiAoaSA9PSAwKQorICAgICAgICAgICAgICAgIHRocm93IGU7CisKKyAgICAgICAgICAgIH0gLy8gZW5kIGNhdGNoCisgICAgICAgICAgfSAvLyBlbmQgZm9yOiBlYWNoIG5lZWRlZCBpbnB1dCBieXRlCisKKyAgICAgICAgICBpZiAobnVtQmluYXJ5Qnl0ZXMgPiAwKSB7CisgICAgICAgICAgICBlbmNvZGUzdG80KGIzLCAwLCBudW1CaW5hcnlCeXRlcywgYnVmZmVyLCAwLCBvcHRpb25zKTsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gMDsKKyAgICAgICAgICAgIG51bVNpZ0J5dGVzID0gNDsKKworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgfSAvLyBlbmQgZWxzZQorCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYnl0ZVtdIGI0ID0gbmV3IGJ5dGVbNF07CisgICAgICAgICAgaW50IGkgPSAwOworICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKKyAgICAgICAgICAgIC8vIFJlYWQgZm91ciAibWVhbmluZ2Z1bCIgYnl0ZXM6CisgICAgICAgICAgICBpbnQgYiA9IDA7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgIGIgPSBpbi5yZWFkKCk7CisgICAgICAgICAgICB9IHdoaWxlIChiID49IDAgJiYgZGVjb2RhYmV0W2IgJiAweDdmXSA8PSBXSElURV9TUEFDRV9FTkMpOworCisgICAgICAgICAgICBpZiAoYiA8IDApIHsKKyAgICAgICAgICAgICAgYnJlYWs7IC8vIFJlYWRzIGEgLTEgaWYgZW5kIG9mIHN0cmVhbQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBiNFtpXSA9IChieXRlKSBiOworICAgICAgICAgIH0gLy8gZW5kIGZvcjogZWFjaCBuZWVkZWQgaW5wdXQgYnl0ZQorCisgICAgICAgICAgaWYgKGkgPT0gNCkgeworICAgICAgICAgICAgbnVtU2lnQnl0ZXMgPSBkZWNvZGU0dG8zKGI0LCAwLCBidWZmZXIsIDAsIG9wdGlvbnMpOworICAgICAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICAgICAgCisgICAgICAgICAgfSBlbHNlIGlmIChpID09IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gTXVzdCBoYXZlIGJyb2tlbiBvdXQgZnJvbSBhYm92ZS4KKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW1wcm9wZXJseSBwYWRkZWQgQmFzZTY0IGlucHV0LiIpOworICAgICAgICAgIH0gLy8gZW5kCisgICAgICAgIH0gLy8gZW5kIGVsc2U6IGRlY29kZQorICAgICAgfSAvLyBlbmQgZWxzZTogZ2V0IGRhdGEKKworICAgICAgLy8gR290IGRhdGE/CisgICAgICBpZiAocG9zaXRpb24gPj0gMCkgeworICAgICAgICAvLyBFbmQgb2YgcmVsZXZhbnQgZGF0YT8KKyAgICAgICAgaWYgKCAvKiAhZW5jb2RlICYmICovcG9zaXRpb24gPj0gbnVtU2lnQnl0ZXMpIHsKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW5jb2RlICYmIGJyZWFrTGluZXMgJiYgbGluZUxlbmd0aCA+PSBNQVhfTElORV9MRU5HVEgpIHsKKyAgICAgICAgICBsaW5lTGVuZ3RoID0gMDsKKyAgICAgICAgICByZXR1cm4gJ1xuJzsKKworICAgICAgICB9CisgICAgICAgIGxpbmVMZW5ndGgrKzsgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpc24ndCBpbXBvcnRhbnQgd2hlbiBkZWNvZGluZworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0aHJvd2luZyBhbiBleHRyYSAiaWYiIHNlZW1zCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8ganVzdCBhcyB3YXN0ZWZ1bC4KKworICAgICAgICBpbnQgYiA9IGJ1ZmZlcltwb3NpdGlvbisrXTsKKworICAgICAgICBpZiAocG9zaXRpb24gPj0gYnVmZmVyTGVuZ3RoKQorICAgICAgICAgIHBvc2l0aW9uID0gLTE7CisKKyAgICAgICAgcmV0dXJuIGIgJiAweEZGOyAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGhvdyB5b3UgImNhc3QiIGEgYnl0ZSB0aGF0J3MKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRlbmRlZCB0byBiZSB1bnNpZ25lZC4KKworICAgICAgfQorCisgICAgICAvLyBXaGVuIEpESzEuNCBpcyBtb3JlIGFjY2VwdGVkLCB1c2UgYW4gYXNzZXJ0aW9uIGhlcmUuCisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkVycm9yIGluIEJhc2U2NCBjb2RlIHJlYWRpbmcgc3RyZWFtLiIpOworCisgICAgfSAvLyBlbmQgcmVhZAorCisgICAgLyoqCisgICAgICogQ2FsbHMge0BsaW5rICNyZWFkKCl9IHJlcGVhdGVkbHkgdW50aWwgdGhlIGVuZCBvZiBzdHJlYW0gaXMgcmVhY2hlZCBvcgorICAgICAqIDx2YXI+bGVuPC92YXI+IGJ5dGVzIGFyZSByZWFkLiBSZXR1cm5zIG51bWJlciBvZiBieXRlcyByZWFkIGludG8gYXJyYXkKKyAgICAgKiBvciAtMSBpZiBlbmQgb2Ygc3RyZWFtIGlzIGVuY291bnRlcmVkLgorICAgICAqIAorICAgICAqIEBwYXJhbSBkZXN0IGFycmF5IHRvIGhvbGQgdmFsdWVzCisgICAgICogQHBhcmFtIG9mZiBvZmZzZXQgZm9yIGFycmF5CisgICAgICogQHBhcmFtIGxlbiBtYXggbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQgaW50byBhcnJheQorICAgICAqIEByZXR1cm4gYnl0ZXMgcmVhZCBpbnRvIGFycmF5IG9yIC0xIGlmIGVuZCBvZiBzdHJlYW0gaXMgZW5jb3VudGVyZWQuCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gZGVzdCwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGludCBpOworICAgICAgaW50IGI7CisgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgYiA9IHJlYWQoKTsKKyAgICAgICAgaWYgKGIgPj0gMCkgeworICAgICAgICAgIGRlc3Rbb2ZmICsgaV0gPSAoYnl0ZSkgYjsKKyAgICAgICAgfSBlbHNlIGlmIChpID09IDApIHsKKyAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgYnJlYWs7IC8vIE91dCBvZiAnZm9yJyBsb29wCisgICAgICAgIH0KKyAgICAgIH0gLy8gZW5kIGZvcjogZWFjaCBieXRlIHJlYWQKKyAgICAgIHJldHVybiBpOworICAgIH0gLy8gZW5kIHJlYWQKKworICB9IC8vIGVuZCBpbm5lciBjbGFzcyBJbnB1dFN0cmVhbQorCisgIC8qICoqKioqKioqIEkgTiBOIEUgUiAgIEMgTCBBIFMgUyAgIE8gVSBUIFAgVSBUIFMgVCBSIEUgQSBNICoqKioqKioqICovCisKKyAgLyoqCisgICAqIEEge0BsaW5rIEJhc2U2NC5CYXNlNjRPdXRwdXRTdHJlYW19IHdpbGwgd3JpdGUgZGF0YSB0byBhbm90aGVyCisgICAqIDx0dD5PdXRwdXRTdHJlYW08L3R0PiwgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLCBhbmQKKyAgICogZW5jb2RlL2RlY29kZSB0by9mcm9tIEJhc2U2NCBub3RhdGlvbiBvbiB0aGUgZmx5LgorICAgKiAKKyAgICogQHNlZSBCYXNlNjQKKyAgICogQHNpbmNlIDEuMworICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBCYXNlNjRPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgYm9vbGVhbiBlbmNvZGU7CisgICAgcHJpdmF0ZSBpbnQgcG9zaXRpb247CisgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyOworICAgIHByaXZhdGUgaW50IGJ1ZmZlckxlbmd0aDsKKyAgICBwcml2YXRlIGludCBsaW5lTGVuZ3RoOworICAgIHByaXZhdGUgYm9vbGVhbiBicmVha0xpbmVzOworICAgIHByaXZhdGUgYnl0ZVtdIGI0OyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2NyYXRjaCB1c2VkIGluIGEgZmV3IHBsYWNlcworICAgIHByaXZhdGUgYm9vbGVhbiBzdXNwZW5kRW5jb2Rpbmc7CisgICAgcHJpdmF0ZSBpbnQgb3B0aW9uczsgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWNvcmQgZm9yIGxhdGVyCisgICAgcHJpdmF0ZSBieXRlW10gZGVjb2RhYmV0OyAgICAgICAgICAgICAgICAgICAvLyBMb2NhbCBjb3B5IGF2b2lkcyBtZXRob2QgY2FsbHMKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGxpbmsgQmFzZTY0T3V0cHV0U3RyZWFtfSBpbiBFTkNPREUgbW9kZS4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSA8dHQ+T3V0cHV0U3RyZWFtPC90dD4gdG8gd2hpY2ggZGF0YSB3aWxsIGJlIHdyaXR0ZW4uCisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIHB1YmxpYyBCYXNlNjRPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIG91dCkgeworICAgICAgdGhpcyhvdXQsIEVOQ09ERSk7CisgICAgfSAvLyBlbmQgY29uc3RydWN0b3IKKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdHMgYSB7QGxpbmsgQmFzZTY0T3V0cHV0U3RyZWFtfSBpbiBlaXRoZXIgRU5DT0RFIG9yIERFQ09ERSBtb2RlLgorICAgICAqIDxwPgorICAgICAqIFZhbGlkIG9wdGlvbnM6CisgICAgICogCisgICAgICogPHVsPgorICAgICAqICAgPGxpPkVOQ09ERSBvciBERUNPREU6IEVuY29kZSBvciBEZWNvZGUgYXMgZGF0YSBpcyByZWFkLjwvbGk+CisgICAgICogICA8bGk+RE9OVF9CUkVBS19MSU5FUzogZG9uJ3QgYnJlYWsgbGluZXMgYXQgNzYgY2hhcmFjdGVycyAob25seQorICAgICAqICAgICBtZWFuaW5nZnVsIHdoZW4gZW5jb2RpbmcpIDxpPk5vdGU6IFRlY2huaWNhbGx5LCB0aGlzIG1ha2VzIHlvdXIKKyAgICAgKiAgICAgZW5jb2Rpbmcgbm9uLWNvbXBsaWFudC48L2k+PC9saT4KKyAgICAgKiA8L3VsPgorICAgICAqIAorICAgICAqIDxwPgorICAgICAqIEV4YW1wbGU6IDxjb2RlPm5ldyBCYXNlNjQuQmFzZTY0T3V0cHV0U3RyZWFtKCBvdXQsIEJhc2U2NC5FTkNPREUgKTwvY29kZT4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gb3V0IHRoZSA8dHQ+T3V0cHV0U3RyZWFtPC90dD4gdG8gd2hpY2ggZGF0YSB3aWxsIGJlIHdyaXR0ZW4uCisgICAgICogQHBhcmFtIG9wdGlvbnMgU3BlY2lmaWVkIG9wdGlvbnMuCisgICAgICogQHNlZSBCYXNlNjQjRU5DT0RFCisgICAgICogQHNlZSBCYXNlNjQjREVDT0RFCisgICAgICogQHNlZSBCYXNlNjQjRE9OVF9CUkVBS19MSU5FUworICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBwdWJsaWMgQmFzZTY0T3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIGludCBvcHRpb25zKSB7CisgICAgICBzdXBlcihvdXQpOworICAgICAgdGhpcy5icmVha0xpbmVzID0gKG9wdGlvbnMgJiBET05UX0JSRUFLX0xJTkVTKSAhPSBET05UX0JSRUFLX0xJTkVTOworICAgICAgdGhpcy5lbmNvZGUgPSAob3B0aW9ucyAmIEVOQ09ERSkgPT0gRU5DT0RFOworICAgICAgdGhpcy5idWZmZXJMZW5ndGggPSBlbmNvZGUgPyAzIDogNDsKKyAgICAgIHRoaXMuYnVmZmVyID0gbmV3IGJ5dGVbYnVmZmVyTGVuZ3RoXTsKKyAgICAgIHRoaXMucG9zaXRpb24gPSAwOworICAgICAgdGhpcy5saW5lTGVuZ3RoID0gMDsKKyAgICAgIHRoaXMuc3VzcGVuZEVuY29kaW5nID0gZmFsc2U7CisgICAgICB0aGlzLmI0ID0gbmV3IGJ5dGVbNF07CisgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOworICAgICAgdGhpcy5kZWNvZGFiZXQgPSBnZXREZWNvZGFiZXQob3B0aW9ucyk7CisgICAgfSAvLyBlbmQgY29uc3RydWN0b3IKKworICAgIC8qKgorICAgICAqIFdyaXRlcyB0aGUgYnl0ZSB0byB0aGUgb3V0cHV0IHN0cmVhbSBhZnRlciBjb252ZXJ0aW5nIHRvL2Zyb20gQmFzZTY0CisgICAgICogbm90YXRpb24uIFdoZW4gZW5jb2RpbmcsIGJ5dGVzIGFyZSBidWZmZXJlZCB0aHJlZSBhdCBhIHRpbWUgYmVmb3JlIHRoZQorICAgICAqIG91dHB1dCBzdHJlYW0gYWN0dWFsbHkgZ2V0cyBhIHdyaXRlKCkgY2FsbC4gV2hlbiBkZWNvZGluZywgYnl0ZXMgYXJlCisgICAgICogYnVmZmVyZWQgZm91ciBhdCBhIHRpbWUuCisgICAgICogCisgICAgICogQHBhcmFtIHRoZUJ5dGUgdGhlIGJ5dGUgdG8gd3JpdGUKKyAgICAgKiBAc2luY2UgMS4zCisgICAgICovCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IHRoZUJ5dGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAvLyBFbmNvZGluZyBzdXNwZW5kZWQ/CisgICAgICBpZiAoc3VzcGVuZEVuY29kaW5nKSB7CisgICAgICAgIHN1cGVyLm91dC53cml0ZSh0aGVCeXRlKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfSAvLyBlbmQgaWY6IHN1cHNlbmRlZAorCisgICAgICAvLyBFbmNvZGU/CisgICAgICBpZiAoZW5jb2RlKSB7CisgICAgICAgIGJ1ZmZlcltwb3NpdGlvbisrXSA9IChieXRlKSB0aGVCeXRlOworICAgICAgICBpZiAocG9zaXRpb24gPj0gYnVmZmVyTGVuZ3RoKSB7ICAgICAgICAgICAgICAgICAvLyBFbm91Z2ggdG8gZW5jb2RlLgorICAgICAgICAgIG91dC53cml0ZShlbmNvZGUzdG80KGI0LCBidWZmZXIsIGJ1ZmZlckxlbmd0aCwgb3B0aW9ucykpOworICAgICAgICAgIGxpbmVMZW5ndGggKz0gNDsKKyAgICAgICAgICBpZiAoYnJlYWtMaW5lcyAmJiBsaW5lTGVuZ3RoID49IE1BWF9MSU5FX0xFTkdUSCkgeworICAgICAgICAgICAgb3V0LndyaXRlKE5FV19MSU5FKTsKKyAgICAgICAgICAgIGxpbmVMZW5ndGggPSAwOworICAgICAgICAgIH0gLy8gZW5kIGlmOiBlbmQgb2YgbGluZQorCisgICAgICAgICAgcG9zaXRpb24gPSAwOworICAgICAgICB9IC8vIGVuZCBpZjogZW5vdWdoIHRvIG91dHB1dAorICAgICAgCisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBNZWFuaW5nZnVsIEJhc2U2NCBjaGFyYWN0ZXI/CisgICAgICAgIGlmIChkZWNvZGFiZXRbdGhlQnl0ZSAmIDB4N2ZdID4gV0hJVEVfU1BBQ0VfRU5DKSB7CisgICAgICAgICAgYnVmZmVyW3Bvc2l0aW9uKytdID0gKGJ5dGUpIHRoZUJ5dGU7CisgICAgICAgICAgaWYgKHBvc2l0aW9uID49IGJ1ZmZlckxlbmd0aCkgeyAgICAgICAgICAgICAgIC8vIEVub3VnaCB0byBvdXRwdXQuCisgICAgICAgICAgICBpbnQgbGVuID0gZGVjb2RlNHRvMyhidWZmZXIsIDAsIGI0LCAwLCBvcHRpb25zKTsKKyAgICAgICAgICAgIG91dC53cml0ZShiNCwgMCwgbGVuKTsKKyAgICAgICAgICAgIHBvc2l0aW9uID0gMDsKKyAgICAgICAgICB9IC8vIGVuZCBpZjogZW5vdWdoIHRvIG91dHB1dAorICAgICAgICAKKyAgICAgICAgfSBlbHNlIGlmIChkZWNvZGFiZXRbdGhlQnl0ZSAmIDB4N2ZdICE9IFdISVRFX1NQQUNFX0VOQykgeworICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW52YWxpZCBjaGFyYWN0ZXIgaW4gQmFzZTY0IGRhdGEuIik7CisgICAgICAgIH0gLy8gZW5kIGVsc2U6IG5vdCB3aGl0ZSBzcGFjZSBlaXRoZXIKKyAgICAgIH0gLy8gZW5kIGVsc2U6IGRlY29kaW5nCisgICAgfSAvLyBlbmQgd3JpdGUKKworICAgIC8qKgorICAgICAqIENhbGxzIHtAbGluayAjd3JpdGUoaW50KX0gcmVwZWF0ZWRseSB1bnRpbCA8dmFyPmxlbjwvdmFyPiBieXRlcyBhcmUKKyAgICAgKiB3cml0dGVuLgorICAgICAqIAorICAgICAqIEBwYXJhbSB0aGVCeXRlcyBhcnJheSBmcm9tIHdoaWNoIHRvIHJlYWQgYnl0ZXMKKyAgICAgKiBAcGFyYW0gb2ZmIG9mZnNldCBmb3IgYXJyYXkKKyAgICAgKiBAcGFyYW0gbGVuIG1heCBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCBpbnRvIGFycmF5CisgICAgICogQHNpbmNlIDEuMworICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSB0aGVCeXRlcywgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIEVuY29kaW5nIHN1c3BlbmRlZD8KKyAgICAgIGlmIChzdXNwZW5kRW5jb2RpbmcpIHsKKyAgICAgICAgc3VwZXIub3V0LndyaXRlKHRoZUJ5dGVzLCBvZmYsIGxlbik7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gLy8gZW5kIGlmOiBzdXBzZW5kZWQKKworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICB3cml0ZSh0aGVCeXRlc1tvZmYgKyBpXSk7CisgICAgICB9IC8vIGVuZCBmb3I6IGVhY2ggYnl0ZSB3cml0dGVuCisKKyAgICB9IC8vIGVuZCB3cml0ZQorCisgICAgLyoqCisgICAgICogTWV0aG9kIGFkZGVkIGJ5IFBISUwuIFtUaGFua3MsIFBISUwuIC1Sb2JdIFRoaXMgcGFkcyB0aGUgYnVmZmVyIHdpdGhvdXQKKyAgICAgKiBjbG9zaW5nIHRoZSBzdHJlYW0uCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGZsdXNoQmFzZTY0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChwb3NpdGlvbiA+IDApIHsKKyAgICAgICAgaWYgKGVuY29kZSkgeworICAgICAgICAgIG91dC53cml0ZShlbmNvZGUzdG80KGI0LCBidWZmZXIsIHBvc2l0aW9uLCBvcHRpb25zKSk7CisgICAgICAgICAgcG9zaXRpb24gPSAwOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJCYXNlNjQgaW5wdXQgbm90IHByb3Blcmx5IHBhZGRlZC4iKTsKKyAgICAgICAgfSAvLyBlbmQgZWxzZTogZGVjb2RpbmcKKyAgICAgIH0gLy8gZW5kIGlmOiBidWZmZXIgcGFydGlhbGx5IGZ1bGwKKworICAgIH0gLy8gZW5kIGZsdXNoCisKKyAgICAvKioKKyAgICAgKiBGbHVzaGVzIGFuZCBjbG9zZXMgKEkgdGhpbmssIGluIHRoZSBzdXBlcmNsYXNzKSB0aGUgc3RyZWFtLgorICAgICAqIAorICAgICAqIEBzaW5jZSAxLjMKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAvLyAxLiBFbnN1cmUgdGhhdCBwZW5kaW5nIGNoYXJhY3RlcnMgYXJlIHdyaXR0ZW4KKyAgICAgIGZsdXNoQmFzZTY0KCk7CisKKyAgICAgIC8vIDIuIEFjdHVhbGx5IGNsb3NlIHRoZSBzdHJlYW0KKyAgICAgIC8vIEJhc2UgY2xhc3MgYm90aCBmbHVzaGVzIGFuZCBjbG9zZXMuCisgICAgICBzdXBlci5jbG9zZSgpOworCisgICAgICBidWZmZXIgPSBudWxsOworICAgICAgb3V0ID0gbnVsbDsKKyAgICB9IC8vIGVuZCBjbG9zZQorCisgICAgLyoqCisgICAgICogU3VzcGVuZHMgZW5jb2Rpbmcgb2YgdGhlIHN0cmVhbS4gTWF5IGJlIGhlbHBmdWwgaWYgeW91IG5lZWQgdG8gZW1iZWQgYQorICAgICAqIHBpZWNlIG9mIGJhc2U2NDAtZW5jb2RlZCBkYXRhIGluIGEgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzaW5jZSAxLjUuMQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHN1c3BlbmRFbmNvZGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBmbHVzaEJhc2U2NCgpOworICAgICAgdGhpcy5zdXNwZW5kRW5jb2RpbmcgPSB0cnVlOworICAgIH0gLy8gZW5kIHN1c3BlbmRFbmNvZGluZworCisgICAgLyoqCisgICAgICogUmVzdW1lcyBlbmNvZGluZyBvZiB0aGUgc3RyZWFtLiBNYXkgYmUgaGVscGZ1bCBpZiB5b3UgbmVlZCB0byBlbWJlZCBhCisgICAgICogcGllY2Ugb2YgYmFzZTY0MC1lbmNvZGVkIGRhdGEgaW4gYSBzdHJlYW0uCisgICAgICogCisgICAgICogQHNpbmNlIDEuNS4xCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzdW1lRW5jb2RpbmcoKSB7CisgICAgICB0aGlzLnN1c3BlbmRFbmNvZGluZyA9IGZhbHNlOworICAgIH0gLy8gZW5kIHJlc3VtZUVuY29kaW5nCisKKyAgfSAvLyBlbmQgaW5uZXIgY2xhc3MgT3V0cHV0U3RyZWFtCisKK30gLy8gZW5kIGNsYXNzIEJhc2U2NApkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9CeXRlcy5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9CeXRlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4ZDVmOTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0J5dGVzLmphdmEKQEAgLTAsMCArMSw5OTggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXQ7CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS5tYXRoLkJpZ0ludGVnZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uUmF3Q29tcGFyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVVdGlsczsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRoYXQgaGFuZGxlcyBieXRlIGFycmF5cywgY29udmVyc2lvbnMgdG8vZnJvbSBvdGhlciB0eXBlcywKKyAqIGNvbXBhcmlzb25zLCBoYXNoIGNvZGUgZ2VuZXJhdGlvbiwgbWFudWZhY3R1cmluZyBrZXlzIGZvciBIYXNoTWFwcyBvcgorICogSGFzaFNldHMsIGV0Yy4KKyAqLworcHVibGljIGNsYXNzIEJ5dGVzIHsKKyAgLyoqCisgICAqIFNpemUgb2YgbG9uZyBpbiBieXRlcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRU9GX0xPTkcgPSBMb25nLlNJWkUvQnl0ZS5TSVpFOworCisgIC8qKgorICAgKiBTaXplIG9mIGludCBpbiBieXRlcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRU9GX0lOVCA9IEludGVnZXIuU0laRS9CeXRlLlNJWkU7CisgIAorICAvKioKKyAgICogU2l6ZSBvZiBzaG9ydCBpbiBieXRlcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRU9GX1NIT1JUID0gU2hvcnQuU0laRS9CeXRlLlNJWkU7CisKKyAgLyoqCisgICAqIFNpemUgb2YgZmxvYXQgaW4gYnl0ZXMKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJWkVPRl9GTE9BVCA9IEZsb2F0LlNJWkUvQnl0ZS5TSVpFOworCisgIC8qKgorICAgKiBTaXplIG9mIGRvdWJsZSBpbiBieXRlcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0laRU9GX0RPVUJMRSA9IERvdWJsZS5TSVpFL0J5dGUuU0laRTsKKworICAvKioKKyAgICogU2l6ZSBvZiBieXRlIGluIGJ5dGVzCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSVpFT0ZfQllURSA9IDE7CisgIAorICAvKioKKyAgICogRXN0aW1hdGUgb2Ygc2l6ZSBjb3N0IHRvIHBheSBiZXlvbmQgcGF5bG9hZCBpbiBqdm0gZm9yIGluc3RhbmNlIG9mIGJ5dGUgW10uCisgICAqIEVzdGltYXRlIGJhc2VkIG9uIHN0dWR5IG9mIGpoYXQgYW5kIGpwcm9maWxlciBudW1iZXJzLgorICAgKi8KKyAgLy8gSkhhdCBzYXlzIEJVIGlzIDU2IGJ5dGVzLgorICAvLyBTaXplT2Ygd2hpY2ggdXNlcyBqYXZhLmxhbmcuaW5zdHJ1bWVudCBzYXlzIDI0IGJ5dGVzLiAoMyBsb25ncz8pCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVTVElNQVRFRF9IRUFQX1RBWCA9IDE2OworCisgIC8qKgorICAgKiBCeXRlIGFycmF5IGNvbXBhcmF0b3IgY2xhc3MuCisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEJ5dGVBcnJheUNvbXBhcmF0b3IgaW1wbGVtZW50cyBSYXdDb21wYXJhdG9yPGJ5dGUgW10+IHsKKyAgICBwdWJsaWMgQnl0ZUFycmF5Q29tcGFyYXRvcigpIHsKKyAgICAgIHN1cGVyKCk7CisgICAgfQorICAgIHB1YmxpYyBpbnQgY29tcGFyZShieXRlIFtdIGxlZnQsIGJ5dGUgW10gcmlnaHQpIHsKKyAgICAgIHJldHVybiBjb21wYXJlVG8obGVmdCwgcmlnaHQpOworICAgIH0KKyAgICBwdWJsaWMgaW50IGNvbXBhcmUoYnl0ZSBbXSBiMSwgaW50IHMxLCBpbnQgbDEsIGJ5dGUgW10gYjIsIGludCBzMiwgaW50IGwyKSB7CisgICAgICByZXR1cm4gY29tcGFyZVRvKGIxLCBzMSwgbDEsIGIyLCBzMiwgbDIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQYXNzIHRoaXMgdG8gVHJlZU1hcHMgd2hlcmUgYnl0ZSBbXSBhcmUga2V5cy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQ29tcGFyYXRvcjxieXRlIFtdPiBCWVRFU19DT01QQVJBVE9SID0KKyAgICBuZXcgQnl0ZUFycmF5Q29tcGFyYXRvcigpOworCisgIC8qKgorICAgKiBVc2UgY29tcGFyaW5nIGJ5dGUgYXJyYXlzLCBieXRlLWJ5LWJ5dGUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBCWVRFU19SQVdDT01QQVJBVE9SID0KKyAgICBuZXcgQnl0ZUFycmF5Q29tcGFyYXRvcigpOworICAKKyAgLyoqCisgICAqIFJlYWQgYnl0ZS1hcnJheSB3cml0dGVuIHdpdGggYSBXcml0YWJsZWFibGVVdGlscy52aW50IHByZWZpeC4KKyAgICogQHBhcmFtIGluIElucHV0IHRvIHJlYWQgZnJvbS4KKyAgICogQHJldHVybiBieXRlIGFycmF5IHJlYWQgb2ZmIDxjb2RlPmluPC9jb2RlPgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIHJlYWRCeXRlQXJyYXkoZmluYWwgRGF0YUlucHV0IGluKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCBsZW4gPSBXcml0YWJsZVV0aWxzLnJlYWRWSW50KGluKTsKKyAgICBpZiAobGVuIDwgMCkgeworICAgICAgdGhyb3cgbmV3IE5lZ2F0aXZlQXJyYXlTaXplRXhjZXB0aW9uKEludGVnZXIudG9TdHJpbmcobGVuKSk7CisgICAgfQorICAgIGJ5dGUgW10gcmVzdWx0ID0gbmV3IGJ5dGVbbGVuXTsKKyAgICBpbi5yZWFkRnVsbHkocmVzdWx0LCAwLCBsZW4pOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBSZWFkIGJ5dGUtYXJyYXkgd3JpdHRlbiB3aXRoIGEgV3JpdGFibGVhYmxlVXRpbHMudmludCBwcmVmaXguCisgICAqIElPRXhjZXB0aW9uIGlzIGNvbnZlcnRlZCB0byBhIFJ1bnRpbWVFeGNlcHRpb24uCisgICAqIEBwYXJhbSBpbiBJbnB1dCB0byByZWFkIGZyb20uCisgICAqIEByZXR1cm4gYnl0ZSBhcnJheSByZWFkIG9mZiA8Y29kZT5pbjwvY29kZT4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSByZWFkQnl0ZUFycmF5VGhyb3dzUnVudGltZShmaW5hbCBEYXRhSW5wdXQgaW4pIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIHJlYWRCeXRlQXJyYXkoaW4pOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYnl0ZS1hcnJheSB3aXRoIGEgV3JpdGFibGVhYmxlVXRpbHMudmludCBwcmVmaXguCisgICAqIEBwYXJhbSBvdXQKKyAgICogQHBhcmFtIGIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlQnl0ZUFycmF5KGZpbmFsIERhdGFPdXRwdXQgb3V0LCBmaW5hbCBieXRlIFtdIGIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVCeXRlQXJyYXkob3V0LCBiLCAwLCBiLmxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYnl0ZS1hcnJheSB0byBvdXQgd2l0aCBhIHZpbnQgbGVuZ3RoIHByZWZpeC4KKyAgICogQHBhcmFtIG91dAorICAgKiBAcGFyYW0gYgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVCeXRlQXJyYXkoZmluYWwgRGF0YU91dHB1dCBvdXQsIGZpbmFsIGJ5dGUgW10gYiwKKyAgICAgIGZpbmFsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgV3JpdGFibGVVdGlscy53cml0ZVZJbnQob3V0LCBsZW5ndGgpOworICAgIG91dC53cml0ZShiLCBvZmZzZXQsIGxlbmd0aCk7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYnl0ZS1hcnJheSBmcm9tIHNyYyB0byB0Z3Qgd2l0aCBhIHZpbnQgbGVuZ3RoIHByZWZpeC4KKyAgICogQHBhcmFtIHRndAorICAgKiBAcGFyYW0gdGd0T2Zmc2V0CisgICAqIEBwYXJhbSBzcmMKKyAgICogQHBhcmFtIHNyY09mZnNldAorICAgKiBAcGFyYW0gc3JjTGVuZ3RoCisgICAqIEByZXR1cm4gTmV3IG9mZnNldCBpbiBzcmMgYXJyYXkuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCB3cml0ZUJ5dGVBcnJheShmaW5hbCBieXRlIFtdIHRndCwgZmluYWwgaW50IHRndE9mZnNldCwKKyAgICAgIGZpbmFsIGJ5dGUgW10gc3JjLCBmaW5hbCBpbnQgc3JjT2Zmc2V0LCBmaW5hbCBpbnQgc3JjTGVuZ3RoKSB7CisgICAgYnl0ZSBbXSB2aW50ID0gdmludFRvQnl0ZXMoc3JjTGVuZ3RoKTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHZpbnQsIDAsIHRndCwgdGd0T2Zmc2V0LCB2aW50Lmxlbmd0aCk7CisgICAgaW50IG9mZnNldCA9IHRndE9mZnNldCArIHZpbnQubGVuZ3RoOworICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBzcmNPZmZzZXQsIHRndCwgb2Zmc2V0LCBzcmNMZW5ndGgpOworICAgIHJldHVybiBvZmZzZXQgKyBzcmNMZW5ndGg7CisgIH0KKworICAvKioKKyAgICogUHV0IGJ5dGVzIGF0IHRoZSBzcGVjaWZpZWQgYnl0ZSBhcnJheSBwb3NpdGlvbi4KKyAgICogQHBhcmFtIHRndEJ5dGVzIHRoZSBieXRlIGFycmF5CisgICAqIEBwYXJhbSB0Z3RPZmZzZXQgcG9zaXRpb24gaW4gdGhlIGFycmF5CisgICAqIEBwYXJhbSBzcmNCeXRlcyBieXRlIHRvIHdyaXRlIG91dAorICAgKiBAcmV0dXJuIGluY3JlbWVudGVkIG9mZnNldAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcHV0Qnl0ZXMoYnl0ZVtdIHRndEJ5dGVzLCBpbnQgdGd0T2Zmc2V0LCBieXRlW10gc3JjQnl0ZXMsCisgICAgICBpbnQgc3JjT2Zmc2V0LCBpbnQgc3JjTGVuZ3RoKSB7CisgICAgU3lzdGVtLmFycmF5Y29weShzcmNCeXRlcywgc3JjT2Zmc2V0LCB0Z3RCeXRlcywgdGd0T2Zmc2V0LCBzcmNMZW5ndGgpOworICAgIHJldHVybiB0Z3RPZmZzZXQgKyBzcmNMZW5ndGg7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYSBzaW5nbGUgYnl0ZSBvdXQgdG8gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5IHBvc2l0aW9uLgorICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIG9mZnNldCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKKyAgICogQHBhcmFtIGIgYnl0ZSB0byB3cml0ZSBvdXQKKyAgICogQHJldHVybiBpbmNyZW1lbnRlZCBvZmZzZXQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IHB1dEJ5dGUoYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0LCBieXRlIGIpIHsKKyAgICBieXRlc1tvZmZzZXRdID0gYjsKKyAgICByZXR1cm4gb2Zmc2V0ICsgMTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIGEgbmV3IGJ5dGUgYXJyYXksIGNvcGllZCBmcm9tIHRoZSBwYXNzZWQgQnl0ZUJ1ZmZlci4KKyAgICogQHBhcmFtIGJiIEEgQnl0ZUJ1ZmZlcgorICAgKiBAcmV0dXJuIHRoZSBieXRlIGFycmF5CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0b0J5dGVzKEJ5dGVCdWZmZXIgYmIpIHsKKyAgICBpbnQgbGVuZ3RoID0gYmIubGltaXQoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgU3lzdGVtLmFycmF5Y29weShiYi5hcnJheSgpLCBiYi5hcnJheU9mZnNldCgpLCByZXN1bHQsIDAsIGxlbmd0aCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYiBQcmVzdW1lZCBVVEYtOCBlbmNvZGVkIGJ5dGUgYXJyYXkuCisgICAqIEByZXR1cm4gU3RyaW5nIG1hZGUgZnJvbSA8Y29kZT5iPC9jb2RlPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgcmV0dXJuIHRvU3RyaW5nKGIsIDAsIGIubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYiBQcmVzdW1lZCBVVEYtOCBlbmNvZGVkIGJ5dGUgYXJyYXkuCisgICAqIEBwYXJhbSBvZmYKKyAgICogQHBhcmFtIGxlbgorICAgKiBAcmV0dXJuIFN0cmluZyBtYWRlIGZyb20gPGNvZGU+YjwvY29kZT4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGZpbmFsIGJ5dGUgW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgIFN0cmluZyByZXN1bHQgPSBudWxsOworICAgIHRyeSB7CisgICAgICByZXN1bHQgPSBuZXcgU3RyaW5nKGIsIG9mZiwgbGVuLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIHN0cmluZyB0byBhIFVURi04IGJ5dGUgYXJyYXkuCisgICAqIEBwYXJhbSBzCisgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQnl0ZXMoU3RyaW5nIHMpIHsKKyAgICBpZiAocyA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJzdHJpbmcgY2Fubm90IGJlIG51bGwiKTsKKyAgICB9CisgICAgYnl0ZSBbXSByZXN1bHQgPSBudWxsOworICAgIHRyeSB7CisgICAgICByZXN1bHQgPSBzLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORyk7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogQ29udmVydCBhIGJvb2xlYW4gdG8gYSBieXRlIGFycmF5LgorICAgKiBAcGFyYW0gYgorICAgKiBAcmV0dXJuIDxjb2RlPmI8L2NvZGU+IGVuY29kZWQgaW4gYSBieXRlIGFycmF5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIHRvQnl0ZXMoZmluYWwgYm9vbGVhbiBiKSB7CisgICAgYnl0ZSBbXSBiYiA9IG5ldyBieXRlWzFdOworICAgIGJiWzBdID0gYj8gKGJ5dGUpLTE6IChieXRlKTA7CisgICAgcmV0dXJuIGJiOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEByZXR1cm4gVHJ1ZSBvciBmYWxzZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiB0b0Jvb2xlYW4oZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgaWYgKGIgPT0gbnVsbCB8fCBiLmxlbmd0aCA+IDEpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkFycmF5IGlzIHdyb25nIHNpemUiKTsKKyAgICB9CisgICAgcmV0dXJuIGJbMF0gIT0gKGJ5dGUpMDsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0IGEgbG9uZyB2YWx1ZSB0byBhIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIHZhbAorICAgKiBAcmV0dXJuIHRoZSBieXRlIGFycmF5CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0b0J5dGVzKGxvbmcgdmFsKSB7CisgICAgYnl0ZSBbXSBiID0gbmV3IGJ5dGVbOF07CisgICAgZm9yKGludCBpPTc7aT4wO2ktLSkgeworICAgICAgYltpXSA9IChieXRlKSh2YWwpOworICAgICAgdmFsID4+Pj0gODsKKyAgICB9CisgICAgYlswXSA9IChieXRlKSh2YWwpOworICAgIHJldHVybiBiOworICB9CisKKyAgLyoqCisgICAqIENvbnZlcnRzIGEgYnl0ZSBhcnJheSB0byBhIGxvbmcgdmFsdWUKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEByZXR1cm4gdGhlIGxvbmcgdmFsdWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgbG9uZyB0b0xvbmcoYnl0ZVtdIGJ5dGVzKSB7CisgICAgcmV0dXJuIHRvTG9uZyhieXRlcywgMCk7CisgIH0KKworICAvKioKKyAgICogQ29udmVydHMgYSBieXRlIGFycmF5IHRvIGEgbG9uZyB2YWx1ZQorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcmV0dXJuIHRoZSBsb25nIHZhbHVlCisgICAqLworICBwdWJsaWMgc3RhdGljIGxvbmcgdG9Mb25nKGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCkgeworICAgIHJldHVybiB0b0xvbmcoYnl0ZXMsIG9mZnNldCwgU0laRU9GX0xPTkcpOworICB9CisKKyAgLyoqCisgICAqIENvbnZlcnRzIGEgYnl0ZSBhcnJheSB0byBhIGxvbmcgdmFsdWUKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEBwYXJhbSBvZmZzZXQKKyAgICogQHBhcmFtIGxlbmd0aAorICAgKiBAcmV0dXJuIHRoZSBsb25nIHZhbHVlCisgICAqLworICBwdWJsaWMgc3RhdGljIGxvbmcgdG9Mb25nKGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgZmluYWwgaW50IGxlbmd0aCkgeworICAgIGlmIChieXRlcyA9PSBudWxsIHx8IGxlbmd0aCAhPSBTSVpFT0ZfTE9ORyB8fAorICAgICAgICAob2Zmc2V0ICsgbGVuZ3RoID4gYnl0ZXMubGVuZ3RoKSkgeworICAgICAgcmV0dXJuIC0xTDsKKyAgICB9CisgICAgbG9uZyBsID0gMDsKKyAgICBmb3IoaW50IGkgPSBvZmZzZXQ7IGkgPCAob2Zmc2V0ICsgbGVuZ3RoKTsgaSsrKSB7CisgICAgICBsIDw8PSA4OworICAgICAgbCBePSAobG9uZylieXRlc1tpXSAmIDB4RkY7CisgICAgfQorICAgIHJldHVybiBsOworICB9CisgIAorICAvKioKKyAgICogUHV0IGEgbG9uZyB2YWx1ZSBvdXQgdG8gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5IHBvc2l0aW9uLgorICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIG9mZnNldCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKKyAgICogQHBhcmFtIHZhbCBsb25nIHRvIHdyaXRlIG91dAorICAgKiBAcmV0dXJuIGluY3JlbWVudGVkIG9mZnNldAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcHV0TG9uZyhieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGxvbmcgdmFsKSB7CisgICAgaWYgKGJ5dGVzID09IG51bGwgfHwgKGJ5dGVzLmxlbmd0aCAtIG9mZnNldCA8IFNJWkVPRl9MT05HKSkgeworICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisgICAgZm9yKGludCBpPW9mZnNldCs3O2k+b2Zmc2V0O2ktLSkgeworICAgICAgYnl0ZXNbaV0gPSAoYnl0ZSkodmFsKTsKKyAgICAgIHZhbCA+Pj49IDg7CisgICAgfQorICAgIGJ5dGVzW29mZnNldF0gPSAoYnl0ZSkodmFsKTsKKyAgICByZXR1cm4gb2Zmc2V0ICsgU0laRU9GX0xPTkc7CisgIH0KKworICAvKioKKyAgICogUHJlc3VtZXMgZmxvYXQgZW5jb2RlZCBhcyBJRUVFIDc1NCBmbG9hdGluZy1wb2ludCAic2luZ2xlIGZvcm1hdCIKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEByZXR1cm4gRmxvYXQgbWFkZSBmcm9tIHBhc3NlZCBieXRlIGFycmF5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmbG9hdCB0b0Zsb2F0KGJ5dGUgW10gYnl0ZXMpIHsKKyAgICByZXR1cm4gdG9GbG9hdChieXRlcywgMCk7CisgIH0KKworICAvKioKKyAgICogUHJlc3VtZXMgZmxvYXQgZW5jb2RlZCBhcyBJRUVFIDc1NCBmbG9hdGluZy1wb2ludCAic2luZ2xlIGZvcm1hdCIKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEBwYXJhbSBvZmZzZXQKKyAgICogQHJldHVybiBGbG9hdCBtYWRlIGZyb20gcGFzc2VkIGJ5dGUgYXJyYXkuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmbG9hdCB0b0Zsb2F0KGJ5dGUgW10gYnl0ZXMsIGludCBvZmZzZXQpIHsKKyAgICBpbnQgaSA9IHRvSW50KGJ5dGVzLCBvZmZzZXQpOworICAgIHJldHVybiBGbG9hdC5pbnRCaXRzVG9GbG9hdChpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcGFyYW0gZgorICAgKiBAcmV0dXJuIE5ldyBvZmZzZXQgaW4gPGNvZGU+Ynl0ZXM8L2J5dGVzPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcHV0RmxvYXQoYnl0ZSBbXSBieXRlcywgaW50IG9mZnNldCwgZmxvYXQgZikgeworICAgIGludCBpID0gRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMoZik7CisgICAgcmV0dXJuIHB1dEludChieXRlcywgb2Zmc2V0LCBpKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSB0b0J5dGVzKGZpbmFsIGZsb2F0IGYpIHsKKyAgICAvLyBFbmNvZGUgaXQgYXMgaW50CisgICAgaW50IGkgPSBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhmKTsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcyhpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHJldHVybiBSZXR1cm4gZG91YmxlIG1hZGUgZnJvbSBwYXNzZWQgYnl0ZXMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGRvdWJsZSB0b0RvdWJsZShmaW5hbCBieXRlIFtdIGJ5dGVzKSB7CisgICAgcmV0dXJuIHRvRG91YmxlKGJ5dGVzLCAwKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcmV0dXJuIFJldHVybiBkb3VibGUgbWFkZSBmcm9tIHBhc3NlZCBieXRlcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZG91YmxlIHRvRG91YmxlKGZpbmFsIGJ5dGUgW10gYnl0ZXMsIGZpbmFsIGludCBvZmZzZXQpIHsKKyAgICBsb25nIGwgPSB0b0xvbmcoYnl0ZXMsIG9mZnNldCk7CisgICAgcmV0dXJuIERvdWJsZS5sb25nQml0c1RvRG91YmxlKGwpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcGFyYW0gb2Zmc2V0CisgICAqIEBwYXJhbSBkCisgICAqIEByZXR1cm4gTmV3IG9mZnNldCBpbnRvIGFycmF5IDxjb2RlPmJ5dGVzPC9jb2RlPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcHV0RG91YmxlKGJ5dGUgW10gYnl0ZXMsIGludCBvZmZzZXQsIGRvdWJsZSBkKSB7CisgICAgbG9uZyBsID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZCk7CisgICAgcmV0dXJuIHB1dExvbmcoYnl0ZXMsIG9mZnNldCwgbCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gdG9CeXRlcyhmaW5hbCBkb3VibGUgZCkgeworICAgIC8vIEVuY29kZSBpdCBhcyBhIGxvbmcKKyAgICBsb25nIGwgPSBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhkKTsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcyhsKTsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0IGFuIGludCB2YWx1ZSB0byBhIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIHZhbAorICAgKiBAcmV0dXJuIHRoZSBieXRlIGFycmF5CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGVbXSB0b0J5dGVzKGludCB2YWwpIHsKKyAgICBieXRlIFtdIGIgPSBuZXcgYnl0ZVs0XTsKKyAgICBmb3IoaW50IGkgPSAzOyBpID4gMDsgaS0tKSB7CisgICAgICBiW2ldID0gKGJ5dGUpKHZhbCk7CisgICAgICB2YWwgPj4+PSA4OworICAgIH0KKyAgICBiWzBdID0gKGJ5dGUpKHZhbCk7CisgICAgcmV0dXJuIGI7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIGJ5dGUgYXJyYXkgdG8gYW4gaW50IHZhbHVlCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcmV0dXJuIHRoZSBpbnQgdmFsdWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IHRvSW50KGJ5dGVbXSBieXRlcykgeworICAgIHJldHVybiB0b0ludChieXRlcywgMCk7CisgIH0KKworICAvKioKKyAgICogQ29udmVydHMgYSBieXRlIGFycmF5IHRvIGFuIGludCB2YWx1ZQorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHBhcmFtIG9mZnNldAorICAgKiBAcmV0dXJuIHRoZSBpbnQgdmFsdWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IHRvSW50KGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCkgeworICAgIHJldHVybiB0b0ludChieXRlcywgb2Zmc2V0LCBTSVpFT0ZfSU5UKTsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIGJ5dGUgYXJyYXkgdG8gYW4gaW50IHZhbHVlCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcGFyYW0gb2Zmc2V0CisgICAqIEBwYXJhbSBsZW5ndGgKKyAgICogQHJldHVybiB0aGUgaW50IHZhbHVlCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCB0b0ludChieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBpZiAoYnl0ZXMgPT0gbnVsbCB8fCBsZW5ndGggIT0gU0laRU9GX0lOVCB8fAorICAgICAgICAob2Zmc2V0ICsgbGVuZ3RoID4gYnl0ZXMubGVuZ3RoKSkgeworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpbnQgbiA9IDA7CisgICAgZm9yKGludCBpID0gb2Zmc2V0OyBpIDwgKG9mZnNldCArIGxlbmd0aCk7IGkrKykgeworICAgICAgbiA8PD0gODsKKyAgICAgIG4gXj0gYnl0ZXNbaV0gJiAweEZGOworICAgIH0KKyAgICByZXR1cm4gbjsKKyAgfQorICAKKyAgLyoqCisgICAqIFB1dCBhbiBpbnQgdmFsdWUgb3V0IHRvIHRoZSBzcGVjaWZpZWQgYnl0ZSBhcnJheSBwb3NpdGlvbi4KKyAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGFycmF5CisgICAqIEBwYXJhbSBvZmZzZXQgcG9zaXRpb24gaW4gdGhlIGFycmF5CisgICAqIEBwYXJhbSB2YWwgaW50IHRvIHdyaXRlIG91dAorICAgKiBAcmV0dXJuIGluY3JlbWVudGVkIG9mZnNldAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgcHV0SW50KGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgaW50IHZhbCkgeworICAgIGlmIChieXRlcyA9PSBudWxsIHx8IChieXRlcy5sZW5ndGggLSBvZmZzZXQgPCBTSVpFT0ZfSU5UKSkgeworICAgICAgcmV0dXJuIG9mZnNldDsKKyAgICB9CisgICAgZm9yKGludCBpPSBvZmZzZXQrMzsgaSA+IG9mZnNldDsgaS0tKSB7CisgICAgICBieXRlc1tpXSA9IChieXRlKSh2YWwpOworICAgICAgdmFsID4+Pj0gODsKKyAgICB9CisgICAgYnl0ZXNbb2Zmc2V0XSA9IChieXRlKSh2YWwpOworICAgIHJldHVybiBvZmZzZXQgKyBTSVpFT0ZfSU5UOworICB9CisgIAorICAvKioKKyAgICogQ29udmVydCBhIHNob3J0IHZhbHVlIHRvIGEgYnl0ZSBhcnJheQorICAgKiBAcGFyYW0gdmFsCisgICAqIEByZXR1cm4gdGhlIGJ5dGUgYXJyYXkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQnl0ZXMoc2hvcnQgdmFsKSB7CisgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtTSVpFT0ZfU0hPUlRdOworICAgIGJbMV0gPSAoYnl0ZSkodmFsKTsKKyAgICB2YWwgPj4+PSA4OworICAgIGJbMF0gPSAoYnl0ZSkodmFsKTsKKyAgICByZXR1cm4gYjsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIGJ5dGUgYXJyYXkgdG8gYSBzaG9ydCB2YWx1ZQorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHJldHVybiB0aGUgc2hvcnQgdmFsdWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgc2hvcnQgdG9TaG9ydChieXRlW10gYnl0ZXMpIHsKKyAgICByZXR1cm4gdG9TaG9ydChieXRlcywgMCk7CisgIH0KKworICAvKioKKyAgICogQ29udmVydHMgYSBieXRlIGFycmF5IHRvIGEgc2hvcnQgdmFsdWUKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEByZXR1cm4gdGhlIHNob3J0IHZhbHVlCisgICAqLworICBwdWJsaWMgc3RhdGljIHNob3J0IHRvU2hvcnQoYnl0ZVtdIGJ5dGVzLCBpbnQgb2Zmc2V0KSB7CisgICAgcmV0dXJuIHRvU2hvcnQoYnl0ZXMsIG9mZnNldCwgU0laRU9GX1NIT1JUKTsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBhIGJ5dGUgYXJyYXkgdG8gYSBzaG9ydCB2YWx1ZQorICAgKiBAcGFyYW0gYnl0ZXMKKyAgICogQHJldHVybiB0aGUgc2hvcnQgdmFsdWUKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgc2hvcnQgdG9TaG9ydChieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBpZiAoYnl0ZXMgPT0gbnVsbCB8fCBsZW5ndGggIT0gU0laRU9GX1NIT1JUIHx8CisgICAgICAgIChvZmZzZXQgKyBsZW5ndGggPiBieXRlcy5sZW5ndGgpKSB7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHNob3J0IG4gPSAwOworICAgIG4gXj0gYnl0ZXNbb2Zmc2V0XSAmIDB4RkY7CisgICAgbiA8PD0gODsKKyAgICBuIF49IGJ5dGVzW29mZnNldCsxXSAmIDB4RkY7CisgICAgcmV0dXJuIG47CisgIH0KKyAgCisgIC8qKgorICAgKiBQdXQgYSBzaG9ydCB2YWx1ZSBvdXQgdG8gdGhlIHNwZWNpZmllZCBieXRlIGFycmF5IHBvc2l0aW9uLgorICAgKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYXJyYXkKKyAgICogQHBhcmFtIG9mZnNldCBwb3NpdGlvbiBpbiB0aGUgYXJyYXkKKyAgICogQHBhcmFtIHZhbCBzaG9ydCB0byB3cml0ZSBvdXQKKyAgICogQHJldHVybiBpbmNyZW1lbnRlZCBvZmZzZXQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IHB1dFNob3J0KGJ5dGVbXSBieXRlcywgaW50IG9mZnNldCwgc2hvcnQgdmFsKSB7CisgICAgaWYgKGJ5dGVzID09IG51bGwgfHwgKGJ5dGVzLmxlbmd0aCAtIG9mZnNldCA8IFNJWkVPRl9TSE9SVCkpIHsKKyAgICAgIHJldHVybiBvZmZzZXQ7CisgICAgfQorICAgIGJ5dGVzW29mZnNldCsxXSA9IChieXRlKSh2YWwpOworICAgIHZhbCA+Pj49IDg7CisgICAgYnl0ZXNbb2Zmc2V0XSA9IChieXRlKSh2YWwpOworICAgIHJldHVybiBvZmZzZXQgKyBTSVpFT0ZfU0hPUlQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gdmludCBJbnRlZ2VyIHRvIG1ha2UgYSB2aW50IG9mLgorICAgKiBAcmV0dXJuIFZpbnQgYXMgYnl0ZXMgYXJyYXkuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gdmludFRvQnl0ZXMoZmluYWwgbG9uZyB2aW50KSB7CisgICAgbG9uZyBpID0gdmludDsKKyAgICBpbnQgc2l6ZSA9IFdyaXRhYmxlVXRpbHMuZ2V0VkludFNpemUoaSk7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtzaXplXTsKKyAgICBpbnQgb2Zmc2V0ID0gMDsKKyAgICBpZiAoaSA+PSAtMTEyICYmIGkgPD0gMTI3KSB7CisgICAgICByZXN1bHRbb2Zmc2V0XSA9ICgoYnl0ZSlpKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgaW50IGxlbiA9IC0xMTI7CisgICAgaWYgKGkgPCAwKSB7CisgICAgICBpIF49IC0xTDsgLy8gdGFrZSBvbmUncyBjb21wbGVtZW50JworICAgICAgbGVuID0gLTEyMDsKKyAgICB9CisKKyAgICBsb25nIHRtcCA9IGk7CisgICAgd2hpbGUgKHRtcCAhPSAwKSB7CisgICAgICB0bXAgPSB0bXAgPj4gODsKKyAgICBsZW4tLTsKKyAgICB9CisKKyAgICByZXN1bHRbb2Zmc2V0KytdID0gKGJ5dGUpbGVuOworCisgICAgbGVuID0gKGxlbiA8IC0xMjApID8gLShsZW4gKyAxMjApIDogLShsZW4gKyAxMTIpOworCisgICAgZm9yIChpbnQgaWR4ID0gbGVuOyBpZHggIT0gMDsgaWR4LS0pIHsKKyAgICAgIGludCBzaGlmdGJpdHMgPSAoaWR4IC0gMSkgKiA4OworICAgICAgbG9uZyBtYXNrID0gMHhGRkwgPDwgc2hpZnRiaXRzOworICAgICAgcmVzdWx0W29mZnNldCsrXSA9IChieXRlKSgoaSAmIG1hc2spID4+IHNoaWZ0Yml0cyk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGJ1ZmZlcgorICAgKiBAcmV0dXJuIHZpbnQgYnl0ZXMgYXMgYW4gaW50ZWdlci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgbG9uZyBieXRlc1RvVmludChmaW5hbCBieXRlIFtdIGJ1ZmZlcikgeworICAgIGludCBvZmZzZXQgPSAwOworICAgIGJ5dGUgZmlyc3RCeXRlID0gYnVmZmVyW29mZnNldCsrXTsKKyAgICBpbnQgbGVuID0gV3JpdGFibGVVdGlscy5kZWNvZGVWSW50U2l6ZShmaXJzdEJ5dGUpOworICAgIGlmIChsZW4gPT0gMSkgeworICAgICAgcmV0dXJuIGZpcnN0Qnl0ZTsKKyAgICB9CisgICAgbG9uZyBpID0gMDsKKyAgICBmb3IgKGludCBpZHggPSAwOyBpZHggPCBsZW4tMTsgaWR4KyspIHsKKyAgICAgIGJ5dGUgYiA9IGJ1ZmZlcltvZmZzZXQrK107CisgICAgICBpID0gaSA8PCA4OworICAgICAgaSA9IGkgfCAoYiAmIDB4RkYpOworICAgIH0KKyAgICByZXR1cm4gKFdyaXRhYmxlVXRpbHMuaXNOZWdhdGl2ZVZJbnQoZmlyc3RCeXRlKSA/IChpIF4gLTFMKSA6IGkpOworICB9CisKKyAgLyoqCisgICAqIFJlYWRzIGEgemVyby1jb21wcmVzc2VkIGVuY29kZWQgbG9uZyBmcm9tIGlucHV0IHN0cmVhbSBhbmQgcmV0dXJucyBpdC4KKyAgICogQHBhcmFtIGJ1ZmZlciBCaW5hcnkgYXJyYXkKKyAgICogQHBhcmFtIG9mZnNldCBPZmZzZXQgaW50byBhcnJheSBhdCB3aGljaCB2aW50IGJlZ2lucy4KKyAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIAorICAgKiBAcmV0dXJuIGRlc2VyaWFsaXplZCBsb25nIGZyb20gc3RyZWFtLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIHJlYWRWTG9uZyhmaW5hbCBieXRlIFtdIGJ1ZmZlciwgZmluYWwgaW50IG9mZnNldCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlIGZpcnN0Qnl0ZSA9IGJ1ZmZlcltvZmZzZXRdOworICAgIGludCBsZW4gPSBXcml0YWJsZVV0aWxzLmRlY29kZVZJbnRTaXplKGZpcnN0Qnl0ZSk7CisgICAgaWYgKGxlbiA9PSAxKSB7CisgICAgICByZXR1cm4gZmlyc3RCeXRlOworICAgIH0KKyAgICBsb25nIGkgPSAwOworICAgIGZvciAoaW50IGlkeCA9IDA7IGlkeCA8IGxlbi0xOyBpZHgrKykgeworICAgICAgYnl0ZSBiID0gYnVmZmVyW29mZnNldCArIDEgKyBpZHhdOworICAgICAgaSA9IGkgPDwgODsKKyAgICAgIGkgPSBpIHwgKGIgJiAweEZGKTsKKyAgICB9CisgICAgcmV0dXJuIChXcml0YWJsZVV0aWxzLmlzTmVnYXRpdmVWSW50KGZpcnN0Qnl0ZSkgPyAoaSBeIC0xTCkgOiBpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbGVmdAorICAgKiBAcGFyYW0gcmlnaHQKKyAgICogQHJldHVybiAwIGlmIGVxdWFsLCA8IDAgaWYgbGVmdCBpcyBsZXNzIHRoYW4gcmlnaHQsIGV0Yy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBhcmVUbyhmaW5hbCBieXRlIFtdIGxlZnQsIGZpbmFsIGJ5dGUgW10gcmlnaHQpIHsKKyAgICByZXR1cm4gY29tcGFyZVRvKGxlZnQsIDAsIGxlZnQubGVuZ3RoLCByaWdodCwgMCwgcmlnaHQubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYjEKKyAgICogQHBhcmFtIGIyCisgICAqIEBwYXJhbSBzMSBXaGVyZSB0byBzdGFydCBjb21wYXJpbmcgaW4gdGhlIGxlZnQgYnVmZmVyCisgICAqIEBwYXJhbSBzMiBXaGVyZSB0byBzdGFydCBjb21wYXJpbmcgaW4gdGhlIHJpZ2h0IGJ1ZmZlcgorICAgKiBAcGFyYW0gbDEgSG93IG11Y2ggdG8gY29tcGFyZSBmcm9tIHRoZSBsZWZ0IGJ1ZmZlcgorICAgKiBAcGFyYW0gbDIgSG93IG11Y2ggdG8gY29tcGFyZSBmcm9tIHRoZSByaWdodCBidWZmZXIKKyAgICogQHJldHVybiAwIGlmIGVxdWFsLCA8IDAgaWYgbGVmdCBpcyBsZXNzIHRoYW4gcmlnaHQsIGV0Yy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBhcmVUbyhieXRlW10gYjEsIGludCBzMSwgaW50IGwxLAorICAgICAgYnl0ZVtdIGIyLCBpbnQgczIsIGludCBsMikgeworICAgIC8vIEJyaW5nIFdyaXRhYmxlQ29tcGFyYXRvciBjb2RlIGxvY2FsCisgICAgaW50IGVuZDEgPSBzMSArIGwxOworICAgIGludCBlbmQyID0gczIgKyBsMjsKKyAgICBmb3IgKGludCBpID0gczEsIGogPSBzMjsgaSA8IGVuZDEgJiYgaiA8IGVuZDI7IGkrKywgaisrKSB7CisgICAgICBpbnQgYSA9IChiMVtpXSAmIDB4ZmYpOworICAgICAgaW50IGIgPSAoYjJbal0gJiAweGZmKTsKKyAgICAgIGlmIChhICE9IGIpIHsKKyAgICAgICAgcmV0dXJuIGEgLSBiOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbDEgLSBsMjsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gbGVmdAorICAgKiBAcGFyYW0gcmlnaHQKKyAgICogQHJldHVybiBUcnVlIGlmIGVxdWFsCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGJ5dGUgW10gbGVmdCwgZmluYWwgYnl0ZSBbXSByaWdodCkgeworICAgIC8vIENvdWxkIHVzZSBBcnJheXMuZXF1YWxzPworICAgIHJldHVybiBsZWZ0ID09IG51bGwgJiYgcmlnaHQgPT0gbnVsbD8gdHJ1ZToKKyAgICAgIChsZWZ0ID09IG51bGwgfHwgcmlnaHQgPT0gbnVsbCB8fCAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSk/IGZhbHNlOgorICAgICAgICBjb21wYXJlVG8obGVmdCwgcmlnaHQpID09IDA7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gYgorICAgKiBAcmV0dXJuIFJ1bnMge0BsaW5rIFdyaXRhYmxlQ29tcGFyYXRvciNoYXNoQnl0ZXMoYnl0ZVtdLCBpbnQpfSBvbiB0aGUKKyAgICogcGFzc2VkIGluIGFycmF5LiAgVGhpcyBtZXRob2QgaXMgd2hhdCB7QGxpbmsgb3JnLmFwYWNoZS5oYWRvb3AuaW8uVGV4dH0gYW5kCisgICAqIHtAbGluayBJbW11dGFibGVCeXRlc1dyaXRhYmxlfSB1c2UgY2FsY3VsYXRpbmcgaGFzaCBjb2RlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgaGFzaENvZGUoZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgcmV0dXJuIGhhc2hDb2RlKGIsIGIubGVuZ3RoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYgorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqIEByZXR1cm4gUnVucyB7QGxpbmsgV3JpdGFibGVDb21wYXJhdG9yI2hhc2hCeXRlcyhieXRlW10sIGludCl9IG9uIHRoZQorICAgKiBwYXNzZWQgaW4gYXJyYXkuICBUaGlzIG1ldGhvZCBpcyB3aGF0IHtAbGluayBvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0fSBhbmQKKyAgICoge0BsaW5rIEltbXV0YWJsZUJ5dGVzV3JpdGFibGV9IHVzZSBjYWxjdWxhdGluZyBoYXNoIGNvZGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBoYXNoQ29kZShmaW5hbCBieXRlIFtdIGIsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICByZXR1cm4gV3JpdGFibGVDb21wYXJhdG9yLmhhc2hCeXRlcyhiLCBsZW5ndGgpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiCisgICAqIEByZXR1cm4gQSBoYXNoIG9mIDxjb2RlPmI8L2NvZGU+IGFzIGFuIEludGVnZXIgdGhhdCBjYW4gYmUgdXNlZCBhcyBrZXkgaW4KKyAgICogTWFwcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSW50ZWdlciBtYXBLZXkoZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgcmV0dXJuIEludGVnZXIudmFsdWVPZihoYXNoQ29kZShiKSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGIKKyAgICogQHBhcmFtIGxlbmd0aAorICAgKiBAcmV0dXJuIEEgaGFzaCBvZiA8Y29kZT5iPC9jb2RlPiBhcyBhbiBJbnRlZ2VyIHRoYXQgY2FuIGJlIHVzZWQgYXMga2V5IGluCisgICAqIE1hcHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIEludGVnZXIgbWFwS2V5KGZpbmFsIGJ5dGUgW10gYiwgZmluYWwgaW50IGxlbmd0aCkgeworICAgIHJldHVybiBJbnRlZ2VyLnZhbHVlT2YoaGFzaENvZGUoYiwgbGVuZ3RoKSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGEKKyAgICogQHBhcmFtIGIKKyAgICogQHJldHVybiBOZXcgYXJyYXkgdGhhdCBoYXMgYSBpbiBsb3dlciBoYWxmIGFuZCBiIGluIHVwcGVyIGhhbGYuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gYWRkKGZpbmFsIGJ5dGUgW10gYSwgZmluYWwgYnl0ZSBbXSBiKSB7CisgICAgcmV0dXJuIGFkZChhLCBiLCBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVkpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhCisgICAqIEBwYXJhbSBiCisgICAqIEBwYXJhbSBjCisgICAqIEByZXR1cm4gTmV3IGFycmF5IG1hZGUgZnJvbSBhLCBiIGFuZCBjCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gYWRkKGZpbmFsIGJ5dGUgW10gYSwgZmluYWwgYnl0ZSBbXSBiLCBmaW5hbCBieXRlIFtdIGMpIHsKKyAgICBieXRlIFtdIHJlc3VsdCA9IG5ldyBieXRlW2EubGVuZ3RoICsgYi5sZW5ndGggKyBjLmxlbmd0aF07CisgICAgU3lzdGVtLmFycmF5Y29weShhLCAwLCByZXN1bHQsIDAsIGEubGVuZ3RoKTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGIsIDAsIHJlc3VsdCwgYS5sZW5ndGgsIGIubGVuZ3RoKTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KGMsIDAsIHJlc3VsdCwgYS5sZW5ndGggKyBiLmxlbmd0aCwgYy5sZW5ndGgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gYQorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqIEByZXR1cm4gRmlyc3QgPGNvZGU+bGVuZ3RoPC9jb2RlPiBieXRlcyBmcm9tIDxjb2RlPmE8L2NvZGU+CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gaGVhZChmaW5hbCBieXRlIFtdIGEsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBpZihhLmxlbmd0aCA8IGxlbmd0aCkgcmV0dXJuIG51bGw7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgMCwgcmVzdWx0LCAwLCBsZW5ndGgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGEKKyAgICogQHBhcmFtIGxlbmd0aAorICAgKiBAcmV0dXJuIExhc3QgPGNvZGU+bGVuZ3RoPC9jb2RlPiBieXRlcyBmcm9tIDxjb2RlPmE8L2NvZGU+CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gdGFpbChmaW5hbCBieXRlIFtdIGEsIGZpbmFsIGludCBsZW5ndGgpIHsKKyAgICBpZihhLmxlbmd0aCA8IGxlbmd0aCkgcmV0dXJuIG51bGw7CisgICAgYnl0ZSBbXSByZXN1bHQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgIFN5c3RlbS5hcnJheWNvcHkoYSwgYS5sZW5ndGggLSBsZW5ndGgsIHJlc3VsdCwgMCwgbGVuZ3RoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhCisgICAqIEBwYXJhbSBsZW5ndGgKKyAgICogQHJldHVybiBWYWx1ZSBpbiA8Y29kZT5hPC9jb2RlPiBwbHVzIDxjb2RlPmxlbmd0aDwvY29kZT4gcHJlcGVuZGVkIDAgYnl0ZXMKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBwYWRIZWFkKGZpbmFsIGJ5dGUgW10gYSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgIGJ5dGUgW10gcGFkZGluZyA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgZm9yKGludCBpPTA7aTxsZW5ndGg7aSsrKSBwYWRkaW5nW2ldID0gMDsKKyAgICByZXR1cm4gYWRkKHBhZGRpbmcsYSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gYQorICAgKiBAcGFyYW0gbGVuZ3RoCisgICAqIEByZXR1cm4gVmFsdWUgaW4gPGNvZGU+YTwvY29kZT4gcGx1cyA8Y29kZT5sZW5ndGg8L2NvZGU+IGFwcGVuZGVkIDAgYnl0ZXMKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXSBwYWRUYWlsKGZpbmFsIGJ5dGUgW10gYSwgZmluYWwgaW50IGxlbmd0aCkgeworICAgIGJ5dGUgW10gcGFkZGluZyA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgZm9yKGludCBpPTA7aTxsZW5ndGg7aSsrKSBwYWRkaW5nW2ldID0gMDsKKyAgICByZXR1cm4gYWRkKGEscGFkZGluZyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTcGxpdCBwYXNzZWQgcmFuZ2UuICBFeHBlbnNpdmUgb3BlcmF0aW9uIHJlbGF0aXZlbHkuICBVc2VzIEJpZ0ludGVnZXIgbWF0aC4KKyAgICogVXNlZnVsIHNwbGl0dGluZyByYW5nZXMgZm9yIE1hcFJlZHVjZSBqb2JzLgorICAgKiBAcGFyYW0gYSBCZWdpbm5pbmcgb2YgcmFuZ2UKKyAgICogQHBhcmFtIGIgRW5kIG9mIHJhbmdlCisgICAqIEBwYXJhbSBudW0gTnVtYmVyIG9mIHRpbWVzIHRvIHNwbGl0IHJhbmdlLiAgUGFzcyAxIGlmIHlvdSB3YW50IHRvIHNwbGl0CisgICAqIHRoZSByYW5nZSBpbiB0d287IGkuZS4gb25lIHNwbGl0LgorICAgKiBAcmV0dXJuIEFycmF5IG9mIGRpdmlkaW5nIHZhbHVlcworICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdW10gc3BsaXQoZmluYWwgYnl0ZSBbXSBhLCBmaW5hbCBieXRlIFtdIGIsIGZpbmFsIGludCBudW0pIHsKKyAgICBieXRlIFtdIGFQYWRkZWQgPSBudWxsOworICAgIGJ5dGUgW10gYlBhZGRlZCA9IG51bGw7CisgICAgaWYgKGEubGVuZ3RoIDwgYi5sZW5ndGgpIHsKKyAgICAgIGFQYWRkZWQgPSBwYWRUYWlsKGEsYi5sZW5ndGgtYS5sZW5ndGgpOworICAgICAgYlBhZGRlZCA9IGI7CisgICAgfSBlbHNlIGlmIChiLmxlbmd0aCA8IGEubGVuZ3RoKSB7CisgICAgICBhUGFkZGVkID0gYTsKKyAgICAgIGJQYWRkZWQgPSBwYWRUYWlsKGIsYS5sZW5ndGgtYi5sZW5ndGgpOworICAgIH0gZWxzZSB7CisgICAgICBhUGFkZGVkID0gYTsKKyAgICAgIGJQYWRkZWQgPSBiOworICAgIH0KKyAgICBpZiAoY29tcGFyZVRvKGFQYWRkZWQsYlBhZGRlZCkgPiAxKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJiID4gYSIpOworICAgIH0KKyAgICBpZiAobnVtIDw9IDApIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm51bSBjYW5ub3QgYmUgPCAwIik7CisgICAgYnl0ZSBbXSBwcmVwZW5kSGVhZGVyID0gezEsIDB9OworICAgIEJpZ0ludGVnZXIgc3RhcnRCSSA9IG5ldyBCaWdJbnRlZ2VyKGFkZChwcmVwZW5kSGVhZGVyLCBhUGFkZGVkKSk7CisgICAgQmlnSW50ZWdlciBzdG9wQkkgPSBuZXcgQmlnSW50ZWdlcihhZGQocHJlcGVuZEhlYWRlciwgYlBhZGRlZCkpOworICAgIEJpZ0ludGVnZXIgZGlmZkJJID0gc3RvcEJJLnN1YnRyYWN0KHN0YXJ0QkkpOworICAgIEJpZ0ludGVnZXIgc3BsaXRzQkkgPSBCaWdJbnRlZ2VyLnZhbHVlT2YobnVtICsgMSk7CisgICAgaWYoZGlmZkJJLmNvbXBhcmVUbyhzcGxpdHNCSSkgPD0gMCkgcmV0dXJuIG51bGw7CisgICAgQmlnSW50ZWdlciBpbnRlcnZhbEJJID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgaW50ZXJ2YWxCSSA9IGRpZmZCSS5kaXZpZGUoc3BsaXRzQkkpOworICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIGJ5dGUgW11bXSByZXN1bHQgPSBuZXcgYnl0ZVtudW0rMl1bXTsKKyAgICByZXN1bHRbMF0gPSBhOworCisgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbnVtOyBpKyspIHsKKyAgICAgIEJpZ0ludGVnZXIgY3VyQkkgPSBzdGFydEJJLmFkZChpbnRlcnZhbEJJLm11bHRpcGx5KEJpZ0ludGVnZXIudmFsdWVPZihpKSkpOworICAgICAgYnl0ZSBbXSBwYWRkZWQgPSBjdXJCSS50b0J5dGVBcnJheSgpOworICAgICAgaWYgKHBhZGRlZFsxXSA9PSAwKQorICAgICAgICBwYWRkZWQgPSB0YWlsKHBhZGRlZCxwYWRkZWQubGVuZ3RoLTIpOworICAgICAgZWxzZQorICAgICAgICBwYWRkZWQgPSB0YWlsKHBhZGRlZCxwYWRkZWQubGVuZ3RoLTEpOworICAgICAgcmVzdWx0W2ldID0gcGFkZGVkOworICAgIH0KKyAgICByZXN1bHRbbnVtKzFdID0gYjsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIHQKKyAgICogQHJldHVybiBBcnJheSBvZiBieXRlIGFycmF5cyBtYWRlIGZyb20gcGFzc2VkIGFycmF5IG9mIFRleHQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYnl0ZSBbXVtdIHRvQnl0ZUFycmF5cyhmaW5hbCBTdHJpbmcgW10gdCkgeworICAgIGJ5dGUgW11bXSByZXN1bHQgPSBuZXcgYnl0ZVt0Lmxlbmd0aF1bXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHQubGVuZ3RoOyBpKyspIHsKKyAgICAgIHJlc3VsdFtpXSA9IEJ5dGVzLnRvQnl0ZXModFtpXSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcmV0dXJuIEEgYnl0ZSBhcnJheSBvZiBhIGJ5dGUgYXJyYXkgd2hlcmUgZmlyc3QgYW5kIG9ubHkgZW50cnkgaXMKKyAgICogPGNvZGU+Y29sdW1uPC9jb2RlPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdW10gdG9CeXRlQXJyYXlzKGZpbmFsIFN0cmluZyBjb2x1bW4pIHsKKyAgICByZXR1cm4gdG9CeXRlQXJyYXlzKHRvQnl0ZXMoY29sdW1uKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEByZXR1cm4gQSBieXRlIGFycmF5IG9mIGEgYnl0ZSBhcnJheSB3aGVyZSBmaXJzdCBhbmQgb25seSBlbnRyeSBpcworICAgKiA8Y29kZT5jb2x1bW48L2NvZGU+CisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW11bXSB0b0J5dGVBcnJheXMoZmluYWwgYnl0ZSBbXSBjb2x1bW4pIHsKKyAgICBieXRlIFtdW10gcmVzdWx0ID0gbmV3IGJ5dGVbMV1bXTsKKyAgICByZXN1bHRbMF0gPSBjb2x1bW47CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICAKKyAgLyoqCisgICAqIEJpbmFyeSBzZWFyY2ggZm9yIGtleXMgaW4gaW5kZXhlcy4KKyAgICogQHBhcmFtIGFyciBhcnJheSBvZiBieXRlIGFycmF5cyB0byBzZWFyY2ggZm9yCisgICAqIEBwYXJhbSBrZXkgdGhlIGtleSB5b3Ugd2FudCB0byBmaW5kCisgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCBpbiB0aGUga2V5IHlvdSB3YW50IHRvIGZpbmQKKyAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBrZXkKKyAgICogQHBhcmFtIGNvbXBhcmF0b3IgYSBjb21wYXJhdG9yIHRvIGNvbXBhcmUuCisgICAqIEByZXR1cm4gaW5kZXggb2Yga2V5CisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBiaW5hcnlTZWFyY2goYnl0ZSBbXVtdYXJyLCBieXRlIFtda2V5LCBpbnQgb2Zmc2V0LAorICAgICAgaW50IGxlbmd0aCwgUmF3Q29tcGFyYXRvcjxieXRlIFtdPiBjb21wYXJhdG9yKSB7CisgICAgaW50IGxvdyA9IDA7CisgICAgaW50IGhpZ2ggPSBhcnIubGVuZ3RoIC0gMTsKKyAgICAKKyAgICB3aGlsZSAobG93IDw9IGhpZ2gpIHsKKyAgICAgIGludCBtaWQgPSAobG93K2hpZ2gpID4+PiAxOworICAgICAgaW50IGNtcCA9IGNvbXBhcmF0b3IuY29tcGFyZShhcnJbbWlkXSwgMCwgYXJyW21pZF0ubGVuZ3RoLCBrZXksIG9mZnNldCwKKyAgICAgICAgbGVuZ3RoKTsKKyAgICAgIGlmIChjbXAgPCAwKSAKKyAgICAgICAgbG93ID0gbWlkICsgMTsKKyAgICAgIGVsc2UgaWYgKGNtcCA+IDApCisgICAgICAgIGhpZ2ggPSBtaWQgLSAxOworICAgICAgZWxzZSAKKyAgICAgICAgcmV0dXJuIG1pZDsKKyAgICB9CisgICAgcmV0dXJuIC0gKGxvdysxKTsKKyAgfQorCisgIC8qKgorICAgKiBCeXRld2lzZSBiaW5hcnkgaW5jcmVtZW50L2RlaW5jcmVtZW50IG9mIGxvbmcgY29udGFpbmVkIGluIGJ5dGUgYXJyYXkKKyAgICogb24gZ2l2ZW4gYW1vdW50LgorICAgKiAKKyAgICogQHBhcmFtIHZhbHVlIC0gYXJyYXkgb2YgYnl0ZXMgY29udGFpbmluZyBsb25nIChsZW5ndGggPD0gU0laRU9GX0xPTkcpCisgICAqIEBwYXJhbSBhbW91bnQgdmFsdWUgd2lsbCBiZSBpbmNyZW1lbnRlZCBvbiAoZGVpbmNyZW1lbnRlZCBpZiBuZWdhdGl2ZSkKKyAgICogQHJldHVybiBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIGluY3JlbWVudGVkIGxvbmcgKGxlbmd0aCA9PSBTSVpFT0ZfTE9ORykKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAtIGlmIHZhbHVlLmxlbmd0aCA+IFNJWkVPRl9MT05HCisgICAqLworICBwdWJsaWMgc3RhdGljIGJ5dGUgW10gaW5jcmVtZW50Qnl0ZXMoYnl0ZVtdIHZhbHVlLCBsb25nIGFtb3VudCkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIHZhbCA9IHZhbHVlOworICAgIGlmICh2YWwubGVuZ3RoIDwgU0laRU9GX0xPTkcpIHsKKyAgICAgIC8vIEhvcGVmdWxseSB0aGlzIGRvZXNuJ3QgaGFwcGVuIHRvbyBvZnRlbi4KKyAgICAgIGJ5dGUgW10gbmV3dmFsdWU7CisgICAgICBpZiAodmFsWzBdIDwgMCkgeworICAgICAgICBieXRlIFtdIG5lZ2F0aXZlVmFsdWUgPSB7LTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xfTsKKyAgICAgICAgbmV3dmFsdWUgPSBuZWdhdGl2ZVZhbHVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgbmV3dmFsdWUgPSBuZXcgYnl0ZVtTSVpFT0ZfTE9OR107CisgICAgICB9CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbCwgMCwgbmV3dmFsdWUsIG5ld3ZhbHVlLmxlbmd0aCAtIHZhbC5sZW5ndGgsCisgICAgICAgIHZhbC5sZW5ndGgpOworICAgICAgdmFsID0gbmV3dmFsdWU7CisgICAgfSBlbHNlIGlmICh2YWwubGVuZ3RoID4gU0laRU9GX0xPTkcpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkluY3JlbWVudCBCeXRlcyAtIHZhbHVlIHRvbyBiaWc6ICIgKworICAgICAgICB2YWwubGVuZ3RoKTsKKyAgICB9CisgICAgaWYoYW1vdW50ID09IDApIHJldHVybiB2YWw7CisgICAgaWYodmFsWzBdIDwgMCl7CisgICAgICByZXR1cm4gYmluYXJ5SW5jcmVtZW50TmVnKHZhbCwgYW1vdW50KTsKKyAgICB9CisgICAgcmV0dXJuIGJpbmFyeUluY3JlbWVudFBvcyh2YWwsIGFtb3VudCk7CisgIH0KKworICAvKiBpbmNyZW1lbnQvZGVpbmNyZW1lbnQgZm9yIHBvc2l0aXZlIHZhbHVlICovCisgIHByaXZhdGUgc3RhdGljIGJ5dGUgW10gYmluYXJ5SW5jcmVtZW50UG9zKGJ5dGUgW10gdmFsdWUsIGxvbmcgYW1vdW50KSB7CisgICAgbG9uZyBhbW8gPSBhbW91bnQ7CisgICAgaW50IHNpZ24gPSAxOworICAgIGlmIChhbW91bnQgPCAwKSB7CisgICAgICBhbW8gPSAtYW1vdW50OworICAgICAgc2lnbiA9IC0xOworICAgIH0gCisgICAgZm9yKGludCBpPTA7aTx2YWx1ZS5sZW5ndGg7aSsrKSB7CisgICAgICBpbnQgY3VyID0gKChpbnQpYW1vICUgMjU2KSAqIHNpZ247CisgICAgICBhbW8gPSAoYW1vID4+IDgpOworICAgICAgaW50IHZhbCA9IHZhbHVlW3ZhbHVlLmxlbmd0aC1pLTFdICYgMHgwZmY7CisgICAgICBpbnQgdG90YWwgPSB2YWwgKyBjdXI7CisgICAgICBpZih0b3RhbCA+IDI1NSkgeworICAgICAgICBhbW8gKz0gc2lnbjsKKyAgICAgICAgdG90YWwgJT0gMjU2OworICAgICAgfSBlbHNlIGlmICh0b3RhbCA8IDApIHsKKyAgICAgICAgYW1vIC09IHNpZ247CisgICAgICB9CisgICAgICB2YWx1ZVt2YWx1ZS5sZW5ndGgtaS0xXSA9IChieXRlKXRvdGFsOworICAgICAgaWYgKGFtbyA9PSAwKSByZXR1cm4gdmFsdWU7CisgICAgfQorICAgIHJldHVybiB2YWx1ZTsKKyAgfQorCisgIC8qIGluY3JlbWVudC9kZWluY3JlbWVudCBmb3IgbmVnYXRpdmUgdmFsdWUgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgYnl0ZSBbXSBiaW5hcnlJbmNyZW1lbnROZWcoYnl0ZSBbXSB2YWx1ZSwgbG9uZyBhbW91bnQpIHsKKyAgICBsb25nIGFtbyA9IGFtb3VudDsKKyAgICBpbnQgc2lnbiA9IDE7CisgICAgaWYgKGFtb3VudCA8IDApIHsKKyAgICAgIGFtbyA9IC1hbW91bnQ7CisgICAgICBzaWduID0gLTE7CisgICAgfQorICAgIGZvcihpbnQgaT0wO2k8dmFsdWUubGVuZ3RoO2krKykgeworICAgICAgaW50IGN1ciA9ICgoaW50KWFtbyAlIDI1NikgKiBzaWduOworICAgICAgYW1vID0gKGFtbyA+PiA4KTsKKyAgICAgIGludCB2YWwgPSAoKH52YWx1ZVt2YWx1ZS5sZW5ndGgtaS0xXSkgJiAweDBmZikgKyAxOworICAgICAgaW50IHRvdGFsID0gY3VyIC0gdmFsOworICAgICAgaWYodG90YWwgPj0gMCkgeworICAgICAgICBhbW8gKz0gc2lnbjsKKyAgICAgIH0gZWxzZSBpZiAodG90YWwgPCAtMjU2KSB7CisgICAgICAgIGFtbyAtPSBzaWduOworICAgICAgICB0b3RhbCAlPSAyNTY7CisgICAgICB9CisgICAgICB2YWx1ZVt2YWx1ZS5sZW5ndGgtaS0xXSA9IChieXRlKXRvdGFsOworICAgICAgaWYgKGFtbyA9PSAwKSByZXR1cm4gdmFsdWU7CisgICAgfQorICAgIHJldHVybiB2YWx1ZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9GU1V0aWxzLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0ZTVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODBjMWY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9GU1V0aWxzLmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZGZzLkRpc3RyaWJ1dGVkRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlJlbW90ZUV4Y2VwdGlvbkhhbmRsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CisKKy8qKgorICogVXRpbGl0eSBtZXRob2RzIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSB1bmRlcmx5aW5nIGZpbGUgc3lzdGVtLgorICovCitwdWJsaWMgY2xhc3MgRlNVdGlscyB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhGU1V0aWxzLmNsYXNzKTsKKworICAvKioKKyAgICogTm90IGluc3RhbnRpYWJsZQorICAgKi8KKyAgcHJpdmF0ZSBGU1V0aWxzKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlIGlmIGV4aXN0cy4KKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSBkaXIKKyAgICogQHJldHVybiBUcnVlIGlmIGRlbGV0ZWQgPGNvZGU+ZGlyPC9jb2RlPgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZGVsZXRlRGlyZWN0b3J5KGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggZGlyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBmcy5leGlzdHMoZGlyKT8gZnMuZGVsZXRlKGRpciwgdHJ1ZSk6IGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIGlmIGRpcmVjdG9yeSBleGlzdHMuICBJZiBpdCBkb2VzIG5vdCwgY3JlYXRlIGl0LgorICAgKiBAcGFyYW0gZnMgCisgICAqIEBwYXJhbSBkaXIKKyAgICogQHJldHVybiBQYXRoCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBQYXRoIGNoZWNrZGlyKGZpbmFsIEZpbGVTeXN0ZW0gZnMsIGZpbmFsIFBhdGggZGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghZnMuZXhpc3RzKGRpcikpIHsKKyAgICAgIGZzLm1rZGlycyhkaXIpOworICAgIH0KKyAgICByZXR1cm4gZGlyOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZSBmaWxlLgorICAgKiBAcGFyYW0gZnMKKyAgICogQHBhcmFtIHAKKyAgICogQHJldHVybiBQYXRoCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUGF0aCBjcmVhdGUoZmluYWwgRmlsZVN5c3RlbSBmcywgZmluYWwgUGF0aCBwKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmcy5leGlzdHMocCkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmlsZSBhbHJlYWR5IGV4aXN0cyAiICsgcC50b1N0cmluZygpKTsKKyAgICB9CisgICAgaWYgKCFmcy5jcmVhdGVOZXdGaWxlKHApKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCBjcmVhdGUgb2YgIiArIHApOworICAgIH0KKyAgICByZXR1cm4gcDsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBzcGVjaWZpZWQgZmlsZSBzeXN0ZW0gaXMgYXZhaWxhYmxlCisgICAqIAorICAgKiBAcGFyYW0gZnMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrRmlsZVN5c3RlbUF2YWlsYWJsZShmaW5hbCBGaWxlU3lzdGVtIGZzKSAKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIShmcyBpbnN0YW5jZW9mIERpc3RyaWJ1dGVkRmlsZVN5c3RlbSkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgSU9FeGNlcHRpb24gZXhjZXB0aW9uID0gbnVsbDsKKyAgICBEaXN0cmlidXRlZEZpbGVTeXN0ZW0gZGZzID0gKERpc3RyaWJ1dGVkRmlsZVN5c3RlbSkgZnM7CisgICAgdHJ5IHsKKyAgICAgIGlmIChkZnMuZXhpc3RzKG5ldyBQYXRoKCIvIikpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBleGNlcHRpb24gPSBSZW1vdGVFeGNlcHRpb25IYW5kbGVyLmNoZWNrSU9FeGNlcHRpb24oZSk7CisgICAgfQorICAgIHRyeSB7CisgICAgICBmcy5jbG9zZSgpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExPRy5lcnJvcigiZmlsZSBzeXN0ZW0gY2xvc2UgZmFpbGVkOiAiLCBlKTsKKyAgICB9CisgICAgSU9FeGNlcHRpb24gaW8gPSBuZXcgSU9FeGNlcHRpb24oIkZpbGUgc3lzdGVtIGlzIG5vdCBhdmFpbGFibGUiKTsKKyAgICBpby5pbml0Q2F1c2UoZXhjZXB0aW9uKTsKKyAgICB0aHJvdyBpbzsKKyAgfQorICAKKyAgLyoqCisgICAqIFZlcmlmaWVzIGN1cnJlbnQgdmVyc2lvbiBvZiBmaWxlIHN5c3RlbQorICAgKiAKKyAgICogQHBhcmFtIGZzCisgICAqIEBwYXJhbSByb290ZGlyCisgICAqIEByZXR1cm4gbnVsbCBpZiBubyB2ZXJzaW9uIGZpbGUgZXhpc3RzLCB2ZXJzaW9uIHN0cmluZyBvdGhlcndpc2UuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFZlcnNpb24oRmlsZVN5c3RlbSBmcywgUGF0aCByb290ZGlyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBhdGggdmVyc2lvbkZpbGUgPSBuZXcgUGF0aChyb290ZGlyLCBIQ29uc3RhbnRzLlZFUlNJT05fRklMRV9OQU1FKTsKKyAgICBTdHJpbmcgdmVyc2lvbiA9IG51bGw7CisgICAgaWYgKGZzLmV4aXN0cyh2ZXJzaW9uRmlsZSkpIHsKKyAgICAgIEZTRGF0YUlucHV0U3RyZWFtIHMgPQorICAgICAgICBmcy5vcGVuKHZlcnNpb25GaWxlKTsKKyAgICAgIHRyeSB7CisgICAgICAgIHZlcnNpb24gPSBEYXRhSW5wdXRTdHJlYW0ucmVhZFVURihzKTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHMuY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHZlcnNpb247CisgIH0KKyAgCisgIC8qKgorICAgKiBWZXJpZmllcyBjdXJyZW50IHZlcnNpb24gb2YgZmlsZSBzeXN0ZW0KKyAgICogCisgICAqIEBwYXJhbSBmcyBmaWxlIHN5c3RlbQorICAgKiBAcGFyYW0gcm9vdGRpciByb290IGRpcmVjdG9yeSBvZiBIQmFzZSBpbnN0YWxsYXRpb24KKyAgICogQHBhcmFtIG1lc3NhZ2UgaWYgdHJ1ZSwgaXNzdWVzIGEgbWVzc2FnZSBvbiBTeXN0ZW0ub3V0IAorICAgKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrVmVyc2lvbihGaWxlU3lzdGVtIGZzLCBQYXRoIHJvb3RkaXIsIAorICAgICAgYm9vbGVhbiBtZXNzYWdlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN0cmluZyB2ZXJzaW9uID0gZ2V0VmVyc2lvbihmcywgcm9vdGRpcik7CisgICAgCisgICAgaWYgKHZlcnNpb24gPT0gbnVsbCkgeworICAgICAgaWYgKCFyb290UmVnaW9uRXhpc3RzKGZzLCByb290ZGlyKSkgeworICAgICAgICAvLyByb290RGlyIGlzIGVtcHR5IChubyB2ZXJzaW9uIGZpbGUgYW5kIG5vIHJvb3QgcmVnaW9uKQorICAgICAgICAvLyBqdXN0IGNyZWF0ZSBuZXcgdmVyc2lvbiBmaWxlIChIQkFTRS0xMTk1KQorICAgICAgICBGU1V0aWxzLnNldFZlcnNpb24oZnMsIHJvb3RkaXIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgfSBlbHNlIGlmICh2ZXJzaW9uLmNvbXBhcmVUbyhIQ29uc3RhbnRzLkZJTEVfU1lTVEVNX1ZFUlNJT04pID09IDApCisgICAgICAgIHJldHVybjsKKyAgICAKKyAgICAvLyB2ZXJzaW9uIGlzIGRlcHJlY2F0ZWQgcmVxdWlyZSBtaWdyYXRpb24KKyAgICAvLyBPdXRwdXQgb24gc3Rkb3V0IHNvIHVzZXIgc2VlcyBpdCBpbiB0ZXJtaW5hbC4KKyAgICBTdHJpbmcgbXNnID0gIkZpbGUgc3lzdGVtIG5lZWRzIHRvIGJlIHVwZ3JhZGVkLiBSdW4gIiArCisgICAgICAidGhlICcke0hCQVNFX0hPTUV9L2Jpbi9oYmFzZSBtaWdyYXRlJyBzY3JpcHQuIjsKKyAgICBpZiAobWVzc2FnZSkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXQVJOSU5HISAiICsgbXNnKTsKKyAgICB9CisgICAgdGhyb3cgbmV3IEZpbGVTeXN0ZW1WZXJzaW9uRXhjZXB0aW9uKG1zZyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTZXRzIHZlcnNpb24gb2YgZmlsZSBzeXN0ZW0KKyAgICogCisgICAqIEBwYXJhbSBmcworICAgKiBAcGFyYW0gcm9vdGRpcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0VmVyc2lvbihGaWxlU3lzdGVtIGZzLCBQYXRoIHJvb3RkaXIpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBzID0KKyAgICAgIGZzLmNyZWF0ZShuZXcgUGF0aChyb290ZGlyLCBIQ29uc3RhbnRzLlZFUlNJT05fRklMRV9OQU1FKSk7CisgICAgcy53cml0ZVVURihIQ29uc3RhbnRzLkZJTEVfU1lTVEVNX1ZFUlNJT04pOworICAgIHMuY2xvc2UoKTsKKyAgICBMT0cuZGVidWcoIkNyZWF0ZWQgdmVyc2lvbiBmaWxlIHRvOiAiICsgcm9vdGRpci50b1N0cmluZygpKTsKKyAgfQorCisgIC8qKgorICAgKiBWZXJpZmllcyByb290IGRpcmVjdG9yeSBwYXRoIGlzIGEgdmFsaWQgVVJJIHdpdGggYSBzY2hlbWUKKyAgICogCisgICAqIEBwYXJhbSByb290IHJvb3QgZGlyZWN0b3J5IHBhdGgKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBub3QgYSB2YWxpZCBVUkkgd2l0aCBhIHNjaGVtZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHZhbGlkYXRlUm9vdFBhdGgoUGF0aCByb290KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBVUkkgcm9vdFVSSSA9IG5ldyBVUkkocm9vdC50b1N0cmluZygpKTsKKyAgICAgIFN0cmluZyBzY2hlbWUgPSByb290VVJJLmdldFNjaGVtZSgpOworICAgICAgaWYgKHNjaGVtZSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiUm9vdCBkaXJlY3RvcnkgZG9lcyBub3QgY29udGFpbiBhIHNjaGVtZSIpOworICAgICAgfQorICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CisgICAgICBJT0V4Y2VwdGlvbiBpbyA9IG5ldyBJT0V4Y2VwdGlvbigiUm9vdCBkaXJlY3RvcnkgcGF0aCBpcyBub3QgYSB2YWxpZCBVUkkiKTsKKyAgICAgIGlvLmluaXRDYXVzZShlKTsKKyAgICAgIHRocm93IGlvOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFJldHVybiB0aGUgJ3BhdGgnIGNvbXBvbmVudCBvZiBhIFBhdGguICBJbiBIYWRvb3AsIFBhdGggaXMgYW4gVVJJLiAgVGhpcworICAgKiBtZXRob2QgcmV0dXJucyB0aGUgJ3BhdGgnIGNvbXBvbmVudCBvZiBhIFBhdGgncyBVUkk6IGUuZy4gSWYgYSBQYXRoIGlzCisgICAqIDxjb2RlPmhkZnM6Ly9leGFtcGxlLm9yZzo5MDAwL2hiYXNlX3RydW5rL1Rlc3RUYWJsZS9jb21wYWN0aW9uLmRpcjwvY29kZT4sCisgICAqIHRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+L2hiYXNlX3RydW5rL1Rlc3RUYWJsZS9jb21wYWN0aW9uLmRpcjwvY29kZT4uCisgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWZ1bCBpZiB5b3Ugd2FudCB0byBwcmludCBvdXQgYSBQYXRoIHdpdGhvdXQgcXVhbGlmeWluZworICAgKiBGaWxlc3lzdGVtIGluc3RhbmNlLgorICAgKiBAcGFyYW0gcCBGaWxlc3lzdGVtIFBhdGggd2hvc2UgJ3BhdGgnIGNvbXBvbmVudCB3ZSBhcmUgdG8gcmV0dXJuLgorICAgKiBAcmV0dXJuIFBhdGggcG9ydGlvbiBvZiB0aGUgRmlsZXN5c3RlbSAKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFBhdGgoUGF0aCBwKSB7CisgICAgcmV0dXJuIHAudG9VcmkoKS5nZXRQYXRoKCk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGMKKyAgICogQHJldHVybiBQYXRoIHRvIGhiYXNlIHJvb3QgZGlyZWN0b3J5OiBpLmUuIDxjb2RlPmhiYXNlLnJvb3RkaXI8L2NvZGU+IGFzIGEKKyAgICogUGF0aC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUGF0aCBnZXRSb290RGlyKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGVTeXN0ZW0gZnMgPSBGaWxlU3lzdGVtLmdldChjKTsKKyAgICAvLyBHZXQgcm9vdCBkaXJlY3Rvcnkgb2YgSEJhc2UgaW5zdGFsbGF0aW9uCisgICAgUGF0aCByb290ZGlyID0gZnMubWFrZVF1YWxpZmllZChuZXcgUGF0aChjLmdldChIQ29uc3RhbnRzLkhCQVNFX0RJUikpKTsKKyAgICBpZiAoIWZzLmV4aXN0cyhyb290ZGlyKSkgeworICAgICAgU3RyaW5nIG1lc3NhZ2UgPSAiSEJhc2Ugcm9vdCBkaXJlY3RvcnkgIiArIHJvb3RkaXIudG9TdHJpbmcoKSArCisgICAgICAgICIgZG9lcyBub3QgZXhpc3QuIjsKKyAgICAgIExPRy5lcnJvcihtZXNzYWdlKTsKKyAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24obWVzc2FnZSk7CisgICAgfQorICAgIHJldHVybiByb290ZGlyOworICB9CisgIAorICAvKioKKyAgICogQ2hlY2tzIGlmIHJvb3QgcmVnaW9uIGV4aXN0cworICAgKiAKKyAgICogQHBhcmFtIGZzIGZpbGUgc3lzdGVtCisgICAqIEBwYXJhbSByb290ZGlyIHJvb3QgZGlyZWN0b3J5IG9mIEhCYXNlIGluc3RhbGxhdGlvbgorICAgKiBAcmV0dXJuIHRydWUgaWYgZXhpc3RzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiByb290UmVnaW9uRXhpc3RzKEZpbGVTeXN0ZW0gZnMsIFBhdGggcm9vdGRpcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQYXRoIHJvb3RSZWdpb25EaXIgPQorICAgICAgSFJlZ2lvbi5nZXRSZWdpb25EaXIocm9vdGRpciwgSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPKTsKKyAgICByZXR1cm4gZnMuZXhpc3RzKHJvb3RSZWdpb25EaXIpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9GaWxlU3lzdGVtVmVyc2lvbkV4Y2VwdGlvbi5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9GaWxlU3lzdGVtVmVyc2lvbkV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlNWYxNDEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0ZpbGVTeXN0ZW1WZXJzaW9uRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBUaHJvd24gd2hlbiB0aGUgZmlsZSBzeXN0ZW0gbmVlZHMgdG8gYmUgdXBncmFkZWQgKi8KK3B1YmxpYyBjbGFzcyBGaWxlU3lzdGVtVmVyc2lvbkV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTAwNDA1MzM2M0w7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIEZpbGVTeXN0ZW1WZXJzaW9uRXhjZXB0aW9uKCkgeworICAgIHN1cGVyKCk7CisgIH0KKworICAvKiogQHBhcmFtIHMgbWVzc2FnZSAqLworICBwdWJsaWMgRmlsZVN5c3RlbVZlcnNpb25FeGNlcHRpb24oU3RyaW5nIHMpIHsKKyAgICBzdXBlcihzKTsKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0hhc2guamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvSGFzaC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ1YTVlOGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0hhc2guamF2YQpAQCAtMCwwICsxLDExOSBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBjb21tb24gQVBJIGZvciBoYXNoaW5nIGZ1bmN0aW9ucy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEhhc2ggeworICAvKiogQ29uc3RhbnQgdG8gZGVub3RlIGludmFsaWQgaGFzaCB0eXBlLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlZBTElEX0hBU0ggPSAtMTsKKyAgLyoqIENvbnN0YW50IHRvIGRlbm90ZSB7QGxpbmsgSmVua2luc0hhc2h9LiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBKRU5LSU5TX0hBU0ggPSAwOworICAvKiogQ29uc3RhbnQgdG8gZGVub3RlIHtAbGluayBNdXJtdXJIYXNofS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVVSTVVSX0hBU0ggID0gMTsKKyAgCisgIC8qKgorICAgKiBUaGlzIHV0aWxpdHkgbWV0aG9kIGNvbnZlcnRzIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBoYXNoIGZ1bmN0aW9uIG5hbWUKKyAgICogdG8gYSBzeW1ib2xpYyBjb25zdGFudC4gQ3VycmVudGx5IHR3byBmdW5jdGlvbiB0eXBlcyBhcmUgc3VwcG9ydGVkLAorICAgKiAiamVua2lucyIgYW5kICJtdXJtdXIiLgorICAgKiBAcGFyYW0gbmFtZSBoYXNoIGZ1bmN0aW9uIG5hbWUKKyAgICogQHJldHVybiBvbmUgb2YgdGhlIHByZWRlZmluZWQgY29uc3RhbnRzCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBwYXJzZUhhc2hUeXBlKFN0cmluZyBuYW1lKSB7CisgICAgaWYgKCJqZW5raW5zIi5lcXVhbHNJZ25vcmVDYXNlKG5hbWUpKSB7CisgICAgICByZXR1cm4gSkVOS0lOU19IQVNIOworICAgIH0gZWxzZSBpZiAoIm11cm11ciIuZXF1YWxzSWdub3JlQ2FzZShuYW1lKSkgeworICAgICAgcmV0dXJuIE1VUk1VUl9IQVNIOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gSU5WQUxJRF9IQVNIOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFRoaXMgdXRpbGl0eSBtZXRob2QgY29udmVydHMgdGhlIG5hbWUgb2YgdGhlIGNvbmZpZ3VyZWQKKyAgICogaGFzaCB0eXBlIHRvIGEgc3ltYm9saWMgY29uc3RhbnQuCisgICAqIEBwYXJhbSBjb25mIGNvbmZpZ3VyYXRpb24KKyAgICogQHJldHVybiBvbmUgb2YgdGhlIHByZWRlZmluZWQgY29uc3RhbnRzCisgICAqLworICBwdWJsaWMgc3RhdGljIGludCBnZXRIYXNoVHlwZShDb25maWd1cmF0aW9uIGNvbmYpIHsKKyAgICBTdHJpbmcgbmFtZSA9IGNvbmYuZ2V0KCJoYmFzZS5oYXNoLnR5cGUiLCAibXVybXVyIik7CisgICAgcmV0dXJuIHBhcnNlSGFzaFR5cGUobmFtZSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgYSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgaGFzaCBmdW5jdGlvbiBvZiBhIGdpdmVuIHR5cGUuCisgICAqIEBwYXJhbSB0eXBlIHByZWRlZmluZWQgaGFzaCB0eXBlCisgICAqIEByZXR1cm4gaGFzaCBmdW5jdGlvbiBpbnN0YW5jZSwgb3IgbnVsbCBpZiB0eXBlIGlzIGludmFsaWQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSGFzaCBnZXRJbnN0YW5jZShpbnQgdHlwZSkgeworICAgIHN3aXRjaCh0eXBlKSB7CisgICAgY2FzZSBKRU5LSU5TX0hBU0g6CisgICAgICByZXR1cm4gSmVua2luc0hhc2guZ2V0SW5zdGFuY2UoKTsKKyAgICBjYXNlIE1VUk1VUl9IQVNIOgorICAgICAgcmV0dXJuIE11cm11ckhhc2guZ2V0SW5zdGFuY2UoKTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogR2V0IGEgc2luZ2xldG9uIGluc3RhbmNlIG9mIGhhc2ggZnVuY3Rpb24gb2YgYSB0eXBlCisgICAqIGRlZmluZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb24uCisgICAqIEBwYXJhbSBjb25mIGN1cnJlbnQgY29uZmlndXJhdGlvbgorICAgKiBAcmV0dXJuIGRlZmluZWQgaGFzaCB0eXBlLCBvciBudWxsIGlmIHR5cGUgaXMgaW52YWxpZAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIYXNoIGdldEluc3RhbmNlKENvbmZpZ3VyYXRpb24gY29uZikgeworICAgIGludCB0eXBlID0gZ2V0SGFzaFR5cGUoY29uZik7CisgICAgcmV0dXJuIGdldEluc3RhbmNlKHR5cGUpOworICB9CisgIAorICAvKioKKyAgICogQ2FsY3VsYXRlIGEgaGFzaCB1c2luZyBhbGwgYnl0ZXMgZnJvbSB0aGUgaW5wdXQgYXJndW1lbnQsIGFuZAorICAgKiBhIHNlZWQgb2YgLTEuCisgICAqIEBwYXJhbSBieXRlcyBpbnB1dCBieXRlcworICAgKiBAcmV0dXJuIGhhc2ggdmFsdWUKKyAgICovCisgIHB1YmxpYyBpbnQgaGFzaChieXRlW10gYnl0ZXMpIHsKKyAgICByZXR1cm4gaGFzaChieXRlcywgYnl0ZXMubGVuZ3RoLCAtMSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDYWxjdWxhdGUgYSBoYXNoIHVzaW5nIGFsbCBieXRlcyBmcm9tIHRoZSBpbnB1dCBhcmd1bWVudCwKKyAgICogYW5kIGEgcHJvdmlkZWQgc2VlZCB2YWx1ZS4KKyAgICogQHBhcmFtIGJ5dGVzIGlucHV0IGJ5dGVzCisgICAqIEBwYXJhbSBpbml0dmFsIHNlZWQgdmFsdWUKKyAgICogQHJldHVybiBoYXNoIHZhbHVlCisgICAqLworICBwdWJsaWMgaW50IGhhc2goYnl0ZVtdIGJ5dGVzLCBpbnQgaW5pdHZhbCkgeworICAgIHJldHVybiBoYXNoKGJ5dGVzLCBieXRlcy5sZW5ndGgsIGluaXR2YWwpOworICB9CisgIAorICAvKioKKyAgICogQ2FsY3VsYXRlIGEgaGFzaCB1c2luZyBieXRlcyBmcm9tIDAgdG8gPGNvZGU+bGVuZ3RoPC9jb2RlPiwgYW5kCisgICAqIHRoZSBwcm92aWRlZCBzZWVkIHZhbHVlCisgICAqIEBwYXJhbSBieXRlcyBpbnB1dCBieXRlcworICAgKiBAcGFyYW0gbGVuZ3RoIGxlbmd0aCBvZiB0aGUgdmFsaWQgYnl0ZXMgdG8gY29uc2lkZXIKKyAgICogQHBhcmFtIGluaXR2YWwgc2VlZCB2YWx1ZQorICAgKiBAcmV0dXJuIGhhc2ggdmFsdWUKKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBpbnQgaGFzaChieXRlW10gYnl0ZXMsIGludCBsZW5ndGgsIGludCBpbml0dmFsKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvSW5mb1NlcnZlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9JbmZvU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2VlMjY0ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvSW5mb1NlcnZlci5qYXZhCkBAIC0wLDAgKzEsMjM2IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LlVSTDsKKworaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5TdGF0dXNIdHRwU2VydmVyOworaW1wb3J0IG9yZy5tb3J0YmF5Lmh0dHAuSHR0cENvbnRleHQ7CitpbXBvcnQgb3JnLm1vcnRiYXkuaHR0cC5Tb2NrZXRMaXN0ZW5lcjsKK2ltcG9ydCBvcmcubW9ydGJheS5odHRwLmhhbmRsZXIuUmVzb3VyY2VIYW5kbGVyOworaW1wb3J0IG9yZy5tb3J0YmF5LmpldHR5LnNlcnZsZXQuV2ViQXBwbGljYXRpb25Db250ZXh0OworCisvKioKKyAqIENyZWF0ZSBhIEpldHR5IGVtYmVkZGVkIHNlcnZlciB0byBhbnN3ZXIgaHR0cCByZXF1ZXN0cy4gVGhlIHByaW1hcnkgZ29hbAorICogaXMgdG8gc2VydmUgdXAgc3RhdHVzIGluZm9ybWF0aW9uIGZvciB0aGUgc2VydmVyLgorICogVGhlcmUgYXJlIHRocmVlIGNvbnRleHRzOgorICogICAiL3N0YWNrcy8iIC0+IHBvaW50cyB0byBzdGFjayB0cmFjZQorICogICAiL3N0YXRpYy8iIC0+IHBvaW50cyB0byBjb21tb24gc3RhdGljIGZpbGVzIChzcmMvd2ViYXBwcy9zdGF0aWMpCisgKiAgICIvIiAtPiB0aGUganNwIHNlcnZlciBjb2RlIGZyb20gKHNyYy93ZWJhcHBzLzxuYW1lPikKKyAqLworcHVibGljIGNsYXNzIEluZm9TZXJ2ZXIgeworICAvLyBCdWxrIG9mIHRoaXMgY2xhc3MgaXMgY29waWVkIGZyb20KKyAgLy8ge0BsaW5rIG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5TdGF0dXNIdHRwU2VydmVyfS4gIFN0YXR1c0h0dHBTZXJ2ZXIKKyAgLy8gaXMgbm90IGFtZW5hYmxlIHRvIHN1YmNsYXNzaW5nLiAgSXQga2VlcHMgd2ViQXBwQ29udGV4dCBpbmFjY2Vzc2libGUKKyAgLy8gYW5kIHdpbGwgZmluZCB3ZWJhcHBzIG9ubHkgaW4gdGhlIGphciB0aGUgY2xhc3MgU3RhdHVzSHR0cFNlcnZlciB3YXMKKyAgLy8gbG9hZGVkIGZyb20uCisgIHByaXZhdGUgb3JnLm1vcnRiYXkuamV0dHkuU2VydmVyIHdlYlNlcnZlcjsKKyAgcHJpdmF0ZSBTb2NrZXRMaXN0ZW5lciBsaXN0ZW5lcjsKKyAgcHJpdmF0ZSBib29sZWFuIGZpbmRQb3J0OworICBwcml2YXRlIFdlYkFwcGxpY2F0aW9uQ29udGV4dCB3ZWJBcHBDb250ZXh0OworICAKKyAgLyoqCisgICAqIENyZWF0ZSBhIHN0YXR1cyBzZXJ2ZXIgb24gdGhlIGdpdmVuIHBvcnQuCisgICAqIFRoZSBqc3Agc2NyaXB0cyBhcmUgdGFrZW4gZnJvbSBzcmMvd2ViYXBwcy88Y29kZT5uYW1lPGNvZGU+LgorICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgc2VydmVyCisgICAqIEBwYXJhbSBwb3J0IFRoZSBwb3J0IHRvIHVzZSBvbiB0aGUgc2VydmVyCisgICAqIEBwYXJhbSBmaW5kUG9ydCB3aGV0aGVyIHRoZSBzZXJ2ZXIgc2hvdWxkIHN0YXJ0IGF0IHRoZSBnaXZlbiBwb3J0IGFuZCAKKyAgICogaW5jcmVtZW50IGJ5IDEgdW50aWwgaXQgZmluZHMgYSBmcmVlIHBvcnQuCisgICAqLworICBwdWJsaWMgSW5mb1NlcnZlcihTdHJpbmcgbmFtZSwgU3RyaW5nIGJpbmRBZGRyZXNzLCBpbnQgcG9ydCwgYm9vbGVhbiBmaW5kUG9ydCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aGlzLndlYlNlcnZlciA9IG5ldyBvcmcubW9ydGJheS5qZXR0eS5TZXJ2ZXIoKTsKKyAgICB0aGlzLmZpbmRQb3J0ID0gZmluZFBvcnQ7CisgICAgdGhpcy5saXN0ZW5lciA9IG5ldyBTb2NrZXRMaXN0ZW5lcigpOworICAgIHRoaXMubGlzdGVuZXIuc2V0UG9ydChwb3J0KTsKKyAgICB0aGlzLmxpc3RlbmVyLnNldEhvc3QoYmluZEFkZHJlc3MpOworICAgIHRoaXMud2ViU2VydmVyLmFkZExpc3RlbmVyKGxpc3RlbmVyKTsKKworICAgIC8vIFNldCB1cCB0aGUgY29udGV4dCBmb3IgIi9zdGF0aWMvKiIKKyAgICBTdHJpbmcgYXBwRGlyID0gZ2V0V2ViQXBwc1BhdGgoKTsKKyAgICAKKyAgICAvLyBTZXQgdXAgdGhlIGNvbnRleHQgZm9yICIvbG9ncy8iIGlmICJoYWRvb3AubG9nLmRpciIgcHJvcGVydHkgaXMgZGVmaW5lZC4gCisgICAgU3RyaW5nIGxvZ0RpciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiaGJhc2UubG9nLmRpciIpOworICAgIGlmIChsb2dEaXIgIT0gbnVsbCkgeworICAgICAgSHR0cENvbnRleHQgbG9nQ29udGV4dCA9IG5ldyBIdHRwQ29udGV4dCgpOworICAgICAgbG9nQ29udGV4dC5zZXRDb250ZXh0UGF0aCgiL2xvZ3MvKiIpOworICAgICAgbG9nQ29udGV4dC5zZXRSZXNvdXJjZUJhc2UobG9nRGlyKTsKKyAgICAgIGxvZ0NvbnRleHQuYWRkSGFuZGxlcihuZXcgUmVzb3VyY2VIYW5kbGVyKCkpOworICAgICAgd2ViU2VydmVyLmFkZENvbnRleHQobG9nQ29udGV4dCk7CisgICAgfQorICAgIAorICAgIEh0dHBDb250ZXh0IHN0YXRpY0NvbnRleHQgPSBuZXcgSHR0cENvbnRleHQoKTsKKyAgICBzdGF0aWNDb250ZXh0LnNldENvbnRleHRQYXRoKCIvc3RhdGljLyoiKTsKKyAgICBzdGF0aWNDb250ZXh0LnNldFJlc291cmNlQmFzZShhcHBEaXIgKyAiL3N0YXRpYyIpOworICAgIHN0YXRpY0NvbnRleHQuYWRkSGFuZGxlcihuZXcgUmVzb3VyY2VIYW5kbGVyKCkpOworICAgIHRoaXMud2ViU2VydmVyLmFkZENvbnRleHQoc3RhdGljQ29udGV4dCk7CisKKyAgICAvLyBzZXQgdXAgdGhlIGNvbnRleHQgZm9yICIvIiBqc3AgZmlsZXMKKyAgICBTdHJpbmcgd2ViYXBwRGlyID0gZ2V0V2ViQXBwRGlyKG5hbWUpOworICAgIHRoaXMud2ViQXBwQ29udGV4dCA9CisgICAgICB0aGlzLndlYlNlcnZlci5hZGRXZWJBcHBsaWNhdGlvbigiLyIsIHdlYmFwcERpcik7CisgICAgaWYgKG5hbWUuZXF1YWxzKCJtYXN0ZXIiKSkgeworICAgICAgLy8gUHV0IHVwIHRoZSByZXN0IHdlYmFwcC4KKyAgICAgIHRoaXMud2ViU2VydmVyLmFkZFdlYkFwcGxpY2F0aW9uKCIvYXBpIiwgZ2V0V2ViQXBwRGlyKCJyZXN0IikpOworICAgIH0KKyAgICBhZGRTZXJ2bGV0KCJzdGFja3MiLCAiL3N0YWNrcyIsIFN0YXR1c0h0dHBTZXJ2ZXIuU3RhY2tTZXJ2bGV0LmNsYXNzKTsKKyAgICBhZGRTZXJ2bGV0KCJsb2dMZXZlbCIsICIvbG9nTGV2ZWwiLCBvcmcuYXBhY2hlLmhhZG9vcC5sb2cuTG9nTGV2ZWwuU2VydmxldC5jbGFzcyk7CisgIH0KKyAgCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFdlYkFwcERpcihmaW5hbCBTdHJpbmcgd2ViYXBwTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgd2ViYXBwRGlyID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgd2ViYXBwRGlyID0gZ2V0V2ViQXBwc1BhdGgoIndlYmFwcHMiICsgRmlsZS5zZXBhcmF0b3IgKyB3ZWJhcHBOYW1lKTsKKyAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgLy8gUmV0cnkuICBSZXNvdXJjZSBtYXkgYmUgaW5zaWRlIGphciBvbiBhIHdpbmRvd3MgbWFjaGluZS4KKyAgICAgIHdlYmFwcERpciA9IGdldFdlYkFwcHNQYXRoKCJ3ZWJhcHBzLyIgKyB3ZWJhcHBOYW1lKTsKKyAgICB9CisgICAgcmV0dXJuIHdlYmFwcERpcjsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgYSB2YWx1ZSBpbiB0aGUgd2ViYXBwIGNvbnRleHQuIFRoZXNlIHZhbHVlcyBhcmUgYXZhaWxhYmxlIHRvIHRoZSBqc3AKKyAgICogcGFnZXMgYXMgImFwcGxpY2F0aW9uLmdldEF0dHJpYnV0ZShuYW1lKSIuCisgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKKyAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSkgeworICAgIHRoaXMud2ViQXBwQ29udGV4dC5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIEFkZCBhIHNlcnZsZXQgaW4gdGhlIHNlcnZlci4KKyAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHNlcnZsZXQgKGNhbiBiZSBwYXNzZWQgYXMgbnVsbCkKKyAgICogQHBhcmFtIHBhdGhTcGVjIFRoZSBwYXRoIHNwZWMgZm9yIHRoZSBzZXJ2bGV0CisgICAqIEBwYXJhbSBzZXJ2bGV0Q2xhc3MgVGhlIHNlcnZsZXQgY2xhc3MKKyAgICovCisgIHB1YmxpYyA8VCBleHRlbmRzIEh0dHBTZXJ2bGV0PiB2b2lkIGFkZFNlcnZsZXQoU3RyaW5nIG5hbWUsIFN0cmluZyBwYXRoU3BlYywgCisgICAgICBDbGFzczxUPiBzZXJ2bGV0Q2xhc3MpIHsKKyAgICBXZWJBcHBsaWNhdGlvbkNvbnRleHQgY29udGV4dCA9IHdlYkFwcENvbnRleHQ7CisgICAgdHJ5IHsKKyAgICAgIGlmIChuYW1lID09IG51bGwpIHsKKyAgICAgICAgY29udGV4dC5hZGRTZXJ2bGV0KHBhdGhTcGVjLCBzZXJ2bGV0Q2xhc3MuZ2V0TmFtZSgpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnRleHQuYWRkU2VydmxldChuYW1lLCBwYXRoU3BlYywgc2VydmxldENsYXNzLmdldE5hbWUoKSk7CisgICAgICB9IAorICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IG1ha2VSdW50aW1lRXhjZXB0aW9uKCJQcm9ibGVtIGluc3RhbnRpYXRpbmcgY2xhc3MiLCBleCk7CisgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbWFrZVJ1bnRpbWVFeGNlcHRpb24oIlByb2JsZW0gaW5zdGFudGlhdGluZyBjbGFzcyIsIGV4KTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CisgICAgICB0aHJvdyBtYWtlUnVudGltZUV4Y2VwdGlvbigiUHJvYmxlbSBpbnN0YW50aWF0aW5nIGNsYXNzIiwgZXgpOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgUnVudGltZUV4Y2VwdGlvbiBtYWtlUnVudGltZUV4Y2VwdGlvbihTdHJpbmcgbXNnLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICBSdW50aW1lRXhjZXB0aW9uIHJlc3VsdCA9IG5ldyBSdW50aW1lRXhjZXB0aW9uKG1zZyk7CisgICAgaWYgKGNhdXNlICE9IG51bGwpIHsKKyAgICAgIHJlc3VsdC5pbml0Q2F1c2UoY2F1c2UpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSB2YWx1ZSBpbiB0aGUgd2ViYXBwIGNvbnRleHQuCisgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKKyAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZQorICAgKi8KKyAgcHVibGljIE9iamVjdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIG5hbWUpIHsKKyAgICByZXR1cm4gdGhpcy53ZWJBcHBDb250ZXh0LmdldEF0dHJpYnV0ZShuYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXQgdGhlIHBhdGhuYW1lIHRvIHRoZSA8Y29kZT53ZWJhcHBzPC9jb2RlPiBmaWxlcy4KKyAgICogQHJldHVybiB0aGUgcGF0aG5hbWUgYXMgYSBVUkwKKyAgICovCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRXZWJBcHBzUGF0aCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGdldFdlYkFwcHNQYXRoKCJ3ZWJhcHBzIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHBhdGhuYW1lIHRvIHRoZSA8Y29kZT5wYXRjaDwvY29kZT4gZmlsZXMuCisgICAqIEBwYXJhbSBwYXRoIFBhdGggdG8gZmluZC4KKyAgICogQHJldHVybiB0aGUgcGF0aG5hbWUgYXMgYSBVUkwKKyAgICovCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRXZWJBcHBzUGF0aChmaW5hbCBTdHJpbmcgcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBVUkwgdXJsID0gSW5mb1NlcnZlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpLmdldFJlc291cmNlKHBhdGgpOworICAgIGlmICh1cmwgPT0gbnVsbCkgCisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIndlYmFwcHMgbm90IGZvdW5kIGluIENMQVNTUEFUSDogIiArIHBhdGgpOyAKKyAgICByZXR1cm4gdXJsLnRvU3RyaW5nKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBHZXQgdGhlIHBvcnQgdGhhdCB0aGUgc2VydmVyIGlzIG9uCisgICAqIEByZXR1cm4gdGhlIHBvcnQKKyAgICovCisgIHB1YmxpYyBpbnQgZ2V0UG9ydCgpIHsKKyAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5nZXRQb3J0KCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBzZXRUaHJlYWRzKGludCBtaW4sIGludCBtYXgpIHsKKyAgICB0aGlzLmxpc3RlbmVyLnNldE1pblRocmVhZHMobWluKTsKKyAgICB0aGlzLmxpc3RlbmVyLnNldE1heFRocmVhZHMobWF4KTsKKyAgfQorICAKKyAgLyoqCisgICAqIFN0YXJ0IHRoZSBzZXJ2ZXIuIERvZXMgbm90IHdhaXQgZm9yIHRoZSBzZXJ2ZXIgdG8gc3RhcnQuCisgICAqLworICBwdWJsaWMgdm9pZCBzdGFydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgdGhpcy53ZWJTZXJ2ZXIuc3RhcnQoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSBjYXRjaCAob3JnLm1vcnRiYXkudXRpbC5NdWx0aUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgIC8vIGxvb2sgZm9yIHRoZSBtdWx0aSBleGNlcHRpb24gY29udGFpbmluZyBhIGJpbmQgZXhjZXB0aW9uLAorICAgICAgICAgIC8vIGluIHRoYXQgY2FzZSB0cnkgdGhlIG5leHQgcG9ydCBudW1iZXIuCisgICAgICAgICAgYm9vbGVhbiBuZWVkTmV3UG9ydCA9IGZhbHNlOworICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgZXguc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgICAgIEV4Y2VwdGlvbiBzdWIgPSBleC5nZXRFeGNlcHRpb24oaSk7CisgICAgICAgICAgICBpZiAoc3ViIGluc3RhbmNlb2YgamF2YS5uZXQuQmluZEV4Y2VwdGlvbikgeworICAgICAgICAgICAgICBuZWVkTmV3UG9ydCA9IHRydWU7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoIWZpbmRQb3J0IHx8ICFuZWVkTmV3UG9ydCkgeworICAgICAgICAgICAgdGhyb3cgZXg7CisgICAgICAgICAgfQorICAgICAgICAgIHRoaXMubGlzdGVuZXIuc2V0UG9ydChsaXN0ZW5lci5nZXRQb3J0KCkgKyAxKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGllKSB7CisgICAgICB0aHJvdyBpZTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgSU9FeGNlcHRpb24gaWUgPSBuZXcgSU9FeGNlcHRpb24oIlByb2JsZW0gc3RhcnRpbmcgaHR0cCBzZXJ2ZXIiKTsKKyAgICAgIGllLmluaXRDYXVzZShlKTsKKyAgICAgIHRocm93IGllOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIHN0b3AgdGhlIHNlcnZlcgorICAgKi8KKyAgcHVibGljIHZvaWQgc3RvcCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgdGhpcy53ZWJTZXJ2ZXIuc3RvcCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0plbmtpbnNIYXNoLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0plbmtpbnNIYXNoLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTM0YTllOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvSmVua2luc0hhc2guamF2YQpAQCAtMCwwICsxLDI2MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogUHJvZHVjZXMgMzItYml0IGhhc2ggZm9yIGhhc2ggdGFibGUgbG9va3VwLgorICogCisgKiA8cHJlPmxvb2t1cDMuYywgYnkgQm9iIEplbmtpbnMsIE1heSAyMDA2LCBQdWJsaWMgRG9tYWluLgorICoKKyAqIFlvdSBjYW4gdXNlIHRoaXMgZnJlZSBmb3IgYW55IHB1cnBvc2UuICBJdCdzIGluIHRoZSBwdWJsaWMgZG9tYWluLgorICogSXQgaGFzIG5vIHdhcnJhbnR5LgorICogPC9wcmU+CisgKiAKKyAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2J1cnRsZWJ1cnRsZS5uZXQvYm9iL2MvbG9va3VwMy5jIj5sb29rdXAzLmM8L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZGRqLmNvbS8xODQ0MTAyODQiPkhhc2ggRnVuY3Rpb25zIChhbmQgaG93IHRoaXMKKyAqIGZ1bmN0aW9uIGNvbXBhcmVzIHRvIG90aGVycyBzdWNoIGFzIENSQywgTUQ/LCBldGM8L2E+CisgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9idXJ0bGVidXJ0bGUubmV0L2JvYi9oYXNoL2Rvb2JzLmh0bWwiPkhhcyB1cGRhdGUgb24gdGhlCisgKiBEci4gRG9iYnMgQXJ0aWNsZTwvYT4KKyAqLworcHVibGljIGNsYXNzIEplbmtpbnNIYXNoIGV4dGVuZHMgSGFzaCB7CisgIHByaXZhdGUgc3RhdGljIGxvbmcgSU5UX01BU0sgID0gMHgwMDAwMDAwMGZmZmZmZmZmTDsKKyAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBCWVRFX01BU0sgPSAweDAwMDAwMDAwMDAwMDAwZmZMOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgSmVua2luc0hhc2ggX2luc3RhbmNlID0gbmV3IEplbmtpbnNIYXNoKCk7CisgIAorICBwdWJsaWMgc3RhdGljIEhhc2ggZ2V0SW5zdGFuY2UoKSB7CisgICAgcmV0dXJuIF9pbnN0YW5jZTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGxvbmcgcm90KGxvbmcgdmFsLCBpbnQgcG9zKSB7CisgICAgcmV0dXJuICgoSW50ZWdlci5yb3RhdGVMZWZ0KAorICAgICAgICAoaW50KSh2YWwgJiBJTlRfTUFTSyksIHBvcykpICYgSU5UX01BU0spOworICB9CisKKyAgLyoqCisgICAqIHRha2VuIGZyb20gIGhhc2hsaXR0bGUoKSAtLSBoYXNoIGEgdmFyaWFibGUtbGVuZ3RoIGtleSBpbnRvIGEgMzItYml0IHZhbHVlCisgICAqIAorICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgKHRoZSB1bmFsaWduZWQgdmFyaWFibGUtbGVuZ3RoIGFycmF5IG9mIGJ5dGVzKQorICAgKiBAcGFyYW0gbmJ5dGVzIG51bWJlciBvZiBieXRlcyB0byBpbmNsdWRlIGluIGhhc2gKKyAgICogQHBhcmFtIGluaXR2YWwgY2FuIGJlIGFueSBpbnRlZ2VyIHZhbHVlCisgICAqIEByZXR1cm4gYSAzMi1iaXQgdmFsdWUuICBFdmVyeSBiaXQgb2YgdGhlIGtleSBhZmZlY3RzIGV2ZXJ5IGJpdCBvZiB0aGUKKyAgICogcmV0dXJuIHZhbHVlLiAgVHdvIGtleXMgZGlmZmVyaW5nIGJ5IG9uZSBvciB0d28gYml0cyB3aWxsIGhhdmUgdG90YWxseQorICAgKiBkaWZmZXJlbnQgaGFzaCB2YWx1ZXMuCisgICAqIAorICAgKiA8cD5UaGUgYmVzdCBoYXNoIHRhYmxlIHNpemVzIGFyZSBwb3dlcnMgb2YgMi4gIFRoZXJlIGlzIG5vIG5lZWQgdG8gZG8gbW9kCisgICAqIGEgcHJpbWUgKG1vZCBpcyBzb29vIHNsb3chKS4gIElmIHlvdSBuZWVkIGxlc3MgdGhhbiAzMiBiaXRzLCB1c2UgYSBiaXRtYXNrLgorICAgKiBGb3IgZXhhbXBsZSwgaWYgeW91IG5lZWQgb25seSAxMCBiaXRzLCBkbworICAgKiA8Y29kZT5oID0gKGggJiBoYXNobWFzaygxMCkpOzwvY29kZT4KKyAgICogSW4gd2hpY2ggY2FzZSwgdGhlIGhhc2ggdGFibGUgc2hvdWxkIGhhdmUgaGFzaHNpemUoMTApIGVsZW1lbnRzLgorICAgKiAKKyAgICogPHA+SWYgeW91IGFyZSBoYXNoaW5nIG4gc3RyaW5ncyBieXRlW11bXSBrLCBkbyBpdCBsaWtlIHRoaXM6CisgICAqIGZvciAoaW50IGkgPSAwLCBoID0gMDsgaSA8IG47ICsraSkgaCA9IGhhc2goIGtbaV0sIGgpOworICAgKiAKKyAgICogPHA+QnkgQm9iIEplbmtpbnMsIDIwMDYuICBib2JfamVua2luc0BidXJ0bGVidXJ0bGUubmV0LiAgWW91IG1heSB1c2UgdGhpcworICAgKiBjb2RlIGFueSB3YXkgeW91IHdpc2gsIHByaXZhdGUsIGVkdWNhdGlvbmFsLCBvciBjb21tZXJjaWFsLiAgSXQncyBmcmVlLgorICAgKiAKKyAgICogPHA+VXNlIGZvciBoYXNoIHRhYmxlIGxvb2t1cCwgb3IgYW55dGhpbmcgd2hlcmUgb25lIGNvbGxpc2lvbiBpbiAyXl4zMiBpcworICAgKiBhY2NlcHRhYmxlLiAgRG8gTk9UIHVzZSBmb3IgY3J5cHRvZ3JhcGhpYyBwdXJwb3Nlcy4KKyAgKi8KKyAgQE92ZXJyaWRlCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCisgIHB1YmxpYyBpbnQgaGFzaChieXRlW10ga2V5LCBpbnQgbmJ5dGVzLCBpbnQgaW5pdHZhbCkgeworICAgIGludCBsZW5ndGggPSBuYnl0ZXM7CisgICAgbG9uZyBhLCBiLCBjOyAgICAgICAvLyBXZSB1c2UgbG9uZ3MgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHVuc2lnbmVkIGludHMKKyAgICBhID0gYiA9IGMgPSAoMHgwMDAwMDAwMGRlYWRiZWVmTCArIGxlbmd0aCArIGluaXR2YWwpICYgSU5UX01BU0s7CisgICAgaW50IG9mZnNldCA9IDA7CisgICAgZm9yICg7IGxlbmd0aCA+IDEyOyBvZmZzZXQgKz0gMTIsIGxlbmd0aCAtPSAxMikgeworICAgICAgYSA9IChhICsgKGtleVtvZmZzZXQgKyAwXSAgICAmIEJZVEVfTUFTSykpICYgSU5UX01BU0s7CisgICAgICBhID0gKGEgKyAoKChrZXlbb2Zmc2V0ICsgMV0gICYgQllURV9NQVNLKSA8PCAgOCkgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgICBhID0gKGEgKyAoKChrZXlbb2Zmc2V0ICsgMl0gICYgQllURV9NQVNLKSA8PCAxNikgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgICBhID0gKGEgKyAoKChrZXlbb2Zmc2V0ICsgM10gICYgQllURV9NQVNLKSA8PCAyNCkgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgICBiID0gKGIgKyAoa2V5W29mZnNldCArIDRdICAgICYgQllURV9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICAgIGIgPSAoYiArICgoKGtleVtvZmZzZXQgKyA1XSAgJiBCWVRFX01BU0spIDw8ICA4KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICAgIGIgPSAoYiArICgoKGtleVtvZmZzZXQgKyA2XSAgJiBCWVRFX01BU0spIDw8IDE2KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICAgIGIgPSAoYiArICgoKGtleVtvZmZzZXQgKyA3XSAgJiBCWVRFX01BU0spIDw8IDI0KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICAgIGMgPSAoYyArIChrZXlbb2Zmc2V0ICsgOF0gICAgJiBCWVRFX01BU0spKSAmIElOVF9NQVNLOworICAgICAgYyA9IChjICsgKCgoa2V5W29mZnNldCArIDldICAmIEJZVEVfTUFTSykgPDwgIDgpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgICAgYyA9IChjICsgKCgoa2V5W29mZnNldCArIDEwXSAmIEJZVEVfTUFTSykgPDwgMTYpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgICAgYyA9IChjICsgKCgoa2V5W29mZnNldCArIDExXSAmIEJZVEVfTUFTSykgPDwgMjQpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgICAgCisgICAgICAvKgorICAgICAgICogbWl4IC0tIG1peCAzIDMyLWJpdCB2YWx1ZXMgcmV2ZXJzaWJseS4KKyAgICAgICAqIFRoaXMgaXMgcmV2ZXJzaWJsZSwgc28gYW55IGluZm9ybWF0aW9uIGluIChhLGIsYykgYmVmb3JlIG1peCgpIGlzCisgICAgICAgKiBzdGlsbCBpbiAoYSxiLGMpIGFmdGVyIG1peCgpLgorICAgICAgICogCisgICAgICAgKiBJZiBmb3VyIHBhaXJzIG9mIChhLGIsYykgaW5wdXRzIGFyZSBydW4gdGhyb3VnaCBtaXgoKSwgb3IgdGhyb3VnaAorICAgICAgICogbWl4KCkgaW4gcmV2ZXJzZSwgdGhlcmUgYXJlIGF0IGxlYXN0IDMyIGJpdHMgb2YgdGhlIG91dHB1dCB0aGF0CisgICAgICAgKiBhcmUgc29tZXRpbWVzIHRoZSBzYW1lIGZvciBvbmUgcGFpciBhbmQgZGlmZmVyZW50IGZvciBhbm90aGVyIHBhaXIuCisgICAgICAgKiAKKyAgICAgICAqIFRoaXMgd2FzIHRlc3RlZCBmb3I6CisgICAgICAgKiAtIHBhaXJzIHRoYXQgZGlmZmVyZWQgYnkgb25lIGJpdCwgYnkgdHdvIGJpdHMsIGluIGFueSBjb21iaW5hdGlvbgorICAgICAgICogICBvZiB0b3AgYml0cyBvZiAoYSxiLGMpLCBvciBpbiBhbnkgY29tYmluYXRpb24gb2YgYm90dG9tIGJpdHMgb2YKKyAgICAgICAqICAgKGEsYixjKS4KKyAgICAgICAqIC0gImRpZmZlciIgaXMgZGVmaW5lZCBhcyArLCAtLCBeLCBvciB+Xi4gIEZvciArIGFuZCAtLCBJIHRyYW5zZm9ybWVkCisgICAgICAgKiAgIHRoZSBvdXRwdXQgZGVsdGEgdG8gYSBHcmF5IGNvZGUgKGFeKGE+PjEpKSBzbyBhIHN0cmluZyBvZiAxJ3MgKGFzCisgICAgICAgKiAgICBpcyBjb21tb25seSBwcm9kdWNlZCBieSBzdWJ0cmFjdGlvbikgbG9vayBsaWtlIGEgc2luZ2xlIDEtYml0CisgICAgICAgKiAgICBkaWZmZXJlbmNlLgorICAgICAgICogLSB0aGUgYmFzZSB2YWx1ZXMgd2VyZSBwc2V1ZG9yYW5kb20sIGFsbCB6ZXJvIGJ1dCBvbmUgYml0IHNldCwgb3IKKyAgICAgICAqICAgYWxsIHplcm8gcGx1cyBhIGNvdW50ZXIgdGhhdCBzdGFydHMgYXQgemVyby4KKyAgICAgICAqIAorICAgICAgICogU29tZSBrIHZhbHVlcyBmb3IgbXkgImEtPWM7IGFePXJvdChjLGspOyBjKz1iOyIgYXJyYW5nZW1lbnQgdGhhdAorICAgICAgICogc2F0aXNmeSB0aGlzIGFyZQorICAgICAgICogICAgIDQgIDYgIDggMTYgMTkgIDQKKyAgICAgICAqICAgICA5IDE1ICAzIDE4IDI3IDE1CisgICAgICAgKiAgICAxNCAgOSAgMyAgNyAxNyAgMworICAgICAgICogV2VsbCwgIjkgMTUgMyAxOCAyNyAxNSIgZGlkbid0IHF1aXRlIGdldCAzMiBiaXRzIGRpZmZpbmcgZm9yIAorICAgICAgICogImRpZmZlciIgZGVmaW5lZCBhcyArIHdpdGggYSBvbmUtYml0IGJhc2UgYW5kIGEgdHdvLWJpdCBkZWx0YS4gIEkKKyAgICAgICAqIHVzZWQgaHR0cDovL2J1cnRsZWJ1cnRsZS5uZXQvYm9iL2hhc2gvYXZhbGFuY2hlLmh0bWwgdG8gY2hvb3NlCisgICAgICAgKiB0aGUgb3BlcmF0aW9ucywgY29uc3RhbnRzLCBhbmQgYXJyYW5nZW1lbnRzIG9mIHRoZSB2YXJpYWJsZXMuCisgICAgICAgKiAKKyAgICAgICAqIFRoaXMgZG9lcyBub3QgYWNoaWV2ZSBhdmFsYW5jaGUuICBUaGVyZSBhcmUgaW5wdXQgYml0cyBvZiAoYSxiLGMpCisgICAgICAgKiB0aGF0IGZhaWwgdG8gYWZmZWN0IHNvbWUgb3V0cHV0IGJpdHMgb2YgKGEsYixjKSwgZXNwZWNpYWxseSBvZiBhLgorICAgICAgICogVGhlIG1vc3QgdGhvcm91Z2hseSBtaXhlZCB2YWx1ZSBpcyBjLCBidXQgaXQgZG9lc24ndCByZWFsbHkgZXZlbgorICAgICAgICogYWNoaWV2ZSBhdmFsYW5jaGUgaW4gYy4KKyAgICAgICAqIAorICAgICAgICogVGhpcyBhbGxvd3Mgc29tZSBwYXJhbGxlbGlzbS4gIFJlYWQtYWZ0ZXItd3JpdGVzIGFyZSBnb29kIGF0IGRvdWJsaW5nCisgICAgICAgKiB0aGUgbnVtYmVyIG9mIGJpdHMgYWZmZWN0ZWQsIHNvIHRoZSBnb2FsIG9mIG1peGluZyBwdWxscyBpbiB0aGUKKyAgICAgICAqIG9wcG9zaXRlIGRpcmVjdGlvbiBhcyB0aGUgZ29hbCBvZiBwYXJhbGxlbGlzbS4gIEkgZGlkIHdoYXQgSSBjb3VsZC4KKyAgICAgICAqIFJvdGF0ZXMgc2VlbSB0byBjb3N0IGFzIG11Y2ggYXMgc2hpZnRzIG9uIGV2ZXJ5IG1hY2hpbmUgSSBjb3VsZCBsYXkKKyAgICAgICAqIG15IGhhbmRzIG9uLCBhbmQgcm90YXRlcyBhcmUgbXVjaCBraW5kZXIgdG8gdGhlIHRvcCBhbmQgYm90dG9tIGJpdHMsCisgICAgICAgKiBzbyBJIHVzZWQgcm90YXRlcy4KKyAgICAgICAqCisgICAgICAgKiAjZGVmaW5lIG1peChhLGIsYykgXAorICAgICAgICogeyBcCisgICAgICAgKiAgIGEgLT0gYzsgIGEgXj0gcm90KGMsIDQpOyAgYyArPSBiOyBcCisgICAgICAgKiAgIGIgLT0gYTsgIGIgXj0gcm90KGEsIDYpOyAgYSArPSBjOyBcCisgICAgICAgKiAgIGMgLT0gYjsgIGMgXj0gcm90KGIsIDgpOyAgYiArPSBhOyBcCisgICAgICAgKiAgIGEgLT0gYzsgIGEgXj0gcm90KGMsMTYpOyAgYyArPSBiOyBcCisgICAgICAgKiAgIGIgLT0gYTsgIGIgXj0gcm90KGEsMTkpOyAgYSArPSBjOyBcCisgICAgICAgKiAgIGMgLT0gYjsgIGMgXj0gcm90KGIsIDQpOyAgYiArPSBhOyBcCisgICAgICAgKiB9CisgICAgICAgKiAKKyAgICAgICAqIG1peChhLGIsYyk7CisgICAgICAgKi8KKyAgICAgIGEgPSAoYSAtIGMpICYgSU5UX01BU0s7ICBhIF49IHJvdChjLCA0KTsgIGMgPSAoYyArIGIpICYgSU5UX01BU0s7CisgICAgICBiID0gKGIgLSBhKSAmIElOVF9NQVNLOyAgYiBePSByb3QoYSwgNik7ICBhID0gKGEgKyBjKSAmIElOVF9NQVNLOworICAgICAgYyA9IChjIC0gYikgJiBJTlRfTUFTSzsgIGMgXj0gcm90KGIsIDgpOyAgYiA9IChiICsgYSkgJiBJTlRfTUFTSzsKKyAgICAgIGEgPSAoYSAtIGMpICYgSU5UX01BU0s7ICBhIF49IHJvdChjLDE2KTsgIGMgPSAoYyArIGIpICYgSU5UX01BU0s7CisgICAgICBiID0gKGIgLSBhKSAmIElOVF9NQVNLOyAgYiBePSByb3QoYSwxOSk7ICBhID0gKGEgKyBjKSAmIElOVF9NQVNLOworICAgICAgYyA9IChjIC0gYikgJiBJTlRfTUFTSzsgIGMgXj0gcm90KGIsIDQpOyAgYiA9IChiICsgYSkgJiBJTlRfTUFTSzsKKyAgICB9CisKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGxhc3QgYmxvY2s6IGFmZmVjdCBhbGwgMzIgYml0cyBvZiAoYykKKyAgICBzd2l0Y2ggKGxlbmd0aCkgeyAgICAgICAgICAgICAgICAgICAvLyBhbGwgdGhlIGNhc2Ugc3RhdGVtZW50cyBmYWxsIHRocm91Z2gKKyAgICBjYXNlIDEyOgorICAgICAgYyA9IChjICsgKCgoa2V5W29mZnNldCArIDExXSAmIEJZVEVfTUFTSykgPDwgMjQpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgIGNhc2UgMTE6CisgICAgICBjID0gKGMgKyAoKChrZXlbb2Zmc2V0ICsgMTBdICYgQllURV9NQVNLKSA8PCAxNikgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgY2FzZSAxMDoKKyAgICAgIGMgPSAoYyArICgoKGtleVtvZmZzZXQgKyA5XSAgJiBCWVRFX01BU0spIDw8ICA4KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICBjYXNlICA5OgorICAgICAgYyA9IChjICsgKGtleVtvZmZzZXQgKyA4XSAgICAmIEJZVEVfTUFTSykpICYgSU5UX01BU0s7CisgICAgY2FzZSAgODoKKyAgICAgIGIgPSAoYiArICgoKGtleVtvZmZzZXQgKyA3XSAgJiBCWVRFX01BU0spIDw8IDI0KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICBjYXNlICA3OgorICAgICAgYiA9IChiICsgKCgoa2V5W29mZnNldCArIDZdICAmIEJZVEVfTUFTSykgPDwgMTYpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgIGNhc2UgIDY6CisgICAgICBiID0gKGIgKyAoKChrZXlbb2Zmc2V0ICsgNV0gICYgQllURV9NQVNLKSA8PCAgOCkgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgY2FzZSAgNToKKyAgICAgIGIgPSAoYiArIChrZXlbb2Zmc2V0ICsgNF0gICAgJiBCWVRFX01BU0spKSAmIElOVF9NQVNLOworICAgIGNhc2UgIDQ6CisgICAgICBhID0gKGEgKyAoKChrZXlbb2Zmc2V0ICsgM10gICYgQllURV9NQVNLKSA8PCAyNCkgJiBJTlRfTUFTSykpICYgSU5UX01BU0s7CisgICAgY2FzZSAgMzoKKyAgICAgIGEgPSAoYSArICgoKGtleVtvZmZzZXQgKyAyXSAgJiBCWVRFX01BU0spIDw8IDE2KSAmIElOVF9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICBjYXNlICAyOgorICAgICAgYSA9IChhICsgKCgoa2V5W29mZnNldCArIDFdICAmIEJZVEVfTUFTSykgPDwgIDgpICYgSU5UX01BU0spKSAmIElOVF9NQVNLOworICAgIGNhc2UgIDE6CisgICAgICBhID0gKGEgKyAoa2V5W29mZnNldCArIDBdICAgICYgQllURV9NQVNLKSkgJiBJTlRfTUFTSzsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgIDA6CisgICAgICByZXR1cm4gKGludCkoYyAmIElOVF9NQVNLKTsKKyAgICB9CisgICAgLyoKKyAgICAgKiBmaW5hbCAtLSBmaW5hbCBtaXhpbmcgb2YgMyAzMi1iaXQgdmFsdWVzIChhLGIsYykgaW50byBjCisgICAgICogCisgICAgICogUGFpcnMgb2YgKGEsYixjKSB2YWx1ZXMgZGlmZmVyaW5nIGluIG9ubHkgYSBmZXcgYml0cyB3aWxsIHVzdWFsbHkKKyAgICAgKiBwcm9kdWNlIHZhbHVlcyBvZiBjIHRoYXQgbG9vayB0b3RhbGx5IGRpZmZlcmVudC4gIFRoaXMgd2FzIHRlc3RlZCBmb3IKKyAgICAgKiAtIHBhaXJzIHRoYXQgZGlmZmVyZWQgYnkgb25lIGJpdCwgYnkgdHdvIGJpdHMsIGluIGFueSBjb21iaW5hdGlvbgorICAgICAqICAgb2YgdG9wIGJpdHMgb2YgKGEsYixjKSwgb3IgaW4gYW55IGNvbWJpbmF0aW9uIG9mIGJvdHRvbSBiaXRzIG9mCisgICAgICogICAoYSxiLGMpLgorICAgICAqIAorICAgICAqIC0gImRpZmZlciIgaXMgZGVmaW5lZCBhcyArLCAtLCBeLCBvciB+Xi4gIEZvciArIGFuZCAtLCBJIHRyYW5zZm9ybWVkCisgICAgICogICB0aGUgb3V0cHV0IGRlbHRhIHRvIGEgR3JheSBjb2RlIChhXihhPj4xKSkgc28gYSBzdHJpbmcgb2YgMSdzIChhcworICAgICAqICAgaXMgY29tbW9ubHkgcHJvZHVjZWQgYnkgc3VidHJhY3Rpb24pIGxvb2sgbGlrZSBhIHNpbmdsZSAxLWJpdAorICAgICAqICAgZGlmZmVyZW5jZS4KKyAgICAgKiAKKyAgICAgKiAtIHRoZSBiYXNlIHZhbHVlcyB3ZXJlIHBzZXVkb3JhbmRvbSwgYWxsIHplcm8gYnV0IG9uZSBiaXQgc2V0LCBvcgorICAgICAqICAgYWxsIHplcm8gcGx1cyBhIGNvdW50ZXIgdGhhdCBzdGFydHMgYXQgemVyby4KKyAgICAgKiAKKyAgICAgKiBUaGVzZSBjb25zdGFudHMgcGFzc2VkOgorICAgICAqICAgMTQgMTEgMjUgMTYgNCAxNCAyNAorICAgICAqICAgMTIgMTQgMjUgMTYgNCAxNCAyNAorICAgICAqIGFuZCB0aGVzZSBjYW1lIGNsb3NlOgorICAgICAqICAgIDQgIDggMTUgMjYgMyAyMiAyNAorICAgICAqICAgMTAgIDggMTUgMjYgMyAyMiAyNAorICAgICAqICAgMTEgIDggMTUgMjYgMyAyMiAyNAorICAgICAqIAorICAgICAqICNkZWZpbmUgZmluYWwoYSxiLGMpIFwKKyAgICAgKiB7IAorICAgICAqICAgYyBePSBiOyBjIC09IHJvdChiLDE0KTsgXAorICAgICAqICAgYSBePSBjOyBhIC09IHJvdChjLDExKTsgXAorICAgICAqICAgYiBePSBhOyBiIC09IHJvdChhLDI1KTsgXAorICAgICAqICAgYyBePSBiOyBjIC09IHJvdChiLDE2KTsgXAorICAgICAqICAgYSBePSBjOyBhIC09IHJvdChjLDQpOyAgXAorICAgICAqICAgYiBePSBhOyBiIC09IHJvdChhLDE0KTsgXAorICAgICAqICAgYyBePSBiOyBjIC09IHJvdChiLDI0KTsgXAorICAgICAqIH0KKyAgICAgKiAKKyAgICAgKi8KKyAgICBjIF49IGI7IGMgPSAoYyAtIHJvdChiLDE0KSkgJiBJTlRfTUFTSzsKKyAgICBhIF49IGM7IGEgPSAoYSAtIHJvdChjLDExKSkgJiBJTlRfTUFTSzsKKyAgICBiIF49IGE7IGIgPSAoYiAtIHJvdChhLDI1KSkgJiBJTlRfTUFTSzsKKyAgICBjIF49IGI7IGMgPSAoYyAtIHJvdChiLDE2KSkgJiBJTlRfTUFTSzsKKyAgICBhIF49IGM7IGEgPSAoYSAtIHJvdChjLDQpKSAgJiBJTlRfTUFTSzsKKyAgICBiIF49IGE7IGIgPSAoYiAtIHJvdChhLDE0KSkgJiBJTlRfTUFTSzsKKyAgICBjIF49IGI7IGMgPSAoYyAtIHJvdChiLDI0KSkgJiBJTlRfTUFTSzsKKworICAgIHJldHVybiAoaW50KShjICYgSU5UX01BU0spOworICB9CisgIAorICAvKioKKyAgICogQ29tcHV0ZSB0aGUgaGFzaCBvZiB0aGUgc3BlY2lmaWVkIGZpbGUKKyAgICogQHBhcmFtIGFyZ3MgbmFtZSBvZiBmaWxlIHRvIGNvbXB1dGUgaGFzaCBvZi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoYXJncy5sZW5ndGggIT0gMSkgeworICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogSmVua2luc0hhc2ggZmlsZW5hbWUiKTsKKyAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICB9CisgICAgRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShhcmdzWzBdKTsKKyAgICBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVs1MTJdOworICAgIGludCB2YWx1ZSA9IDA7CisgICAgSmVua2luc0hhc2ggaGFzaCA9IG5ldyBKZW5raW5zSGFzaCgpOworICAgIGZvciAoaW50IGxlbmd0aCA9IGluLnJlYWQoYnl0ZXMpOyBsZW5ndGggPiAwIDsgbGVuZ3RoID0gaW4ucmVhZChieXRlcykpIHsKKyAgICAgIHZhbHVlID0gaGFzaC5oYXNoKGJ5dGVzLCBsZW5ndGgsIHZhbHVlKTsKKyAgICB9CisgICAgU3lzdGVtLm91dC5wcmludGxuKE1hdGguYWJzKHZhbHVlKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvS2V5aW5nLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0tleWluZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5ZWQ3MzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL0tleWluZy5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CisKKy8qKgorICogVXRpbGl0eSBjcmVhdGluZyBoYmFzZSBmcmllbmRseSBrZXlzLgorICogVXNlIGZhYnJpY2F0aW5nIHJvdyBuYW1lcyBvciBjb2x1bW4gcXVhbGlmaWVycy4KKyAqIDxwPlRPRE86IEFkZCBjcmVhdGVTY2hlbWVsZXNzIGtleSwgYSBrZXkgdGhhdCBkb2Vzbid0IGNhcmUgaWYgc2NoZW1lIGlzCisgKiBodHRwIG9yIGh0dHBzLgorICogQHNlZSBCeXRlcyNzcGxpdChieXRlW10sIGJ5dGVbXSwgaW50KQorICovCitwdWJsaWMgY2xhc3MgS2V5aW5nIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNRSA9ICJyOiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gVVJJX1JFX1BBUlNFUiA9CisgICAgUGF0dGVybi5jb21waWxlKCJeKFteOi8/I10rOi8vKD86W14vPyNAXStAKT8pKFteOi8/I10rKSguKikkIik7CisKKyAgLyoqCisgICAqIE1ha2VzIGEga2V5IG91dCBvZiBwYXNzZWQgVVJJIGZvciB1c2UgYXMgcm93IG5hbWUgb3IgY29sdW1uIHF1YWxpZmllci4KKyAgICogCisgICAqIFRoaXMgbWV0aG9kIHJ1bnMgdHJhbnNmb3JtcyBvbiB0aGUgcGFzc2VkIFVSSSBzbyBpdCBzaXRzIGJldHRlcgorICAgKiBhcyBhIGtleSAob3IgcG9ydGlvbi1vZi1hLWtleSkgaW4gaGJhc2UuICBUaGUgPGNvZGU+aG9zdDwvY29kZT4gcG9ydGlvbiBvZgorICAgKiB0aGUgVVJJIGF1dGhvcml0eSBpcyByZXZlcnNlZCBzbyBzdWJkb21haW5zIHNvcnQgdW5kZXIgdGhlaXIgcGFyZW50CisgICAqIGRvbWFpbi4gIFRoZSByZXR1cm5lZCBTdHJpbmcgaXMgYW4gb3BhcXVlIFVSSSBvZiBhbiBhcnRpZmljaWFsCisgICAqIDxjb2RlPnI6PC9jb2RlPiBzY2hlbWUgdG8gcHJldmVudCB0aGUgcmVzdWx0IGJlaW5nIGNvbnNpZGVyZWQgYW4gVVJJIG9mCisgICAqIHRoZSBvcmlnaW5hbCBzY2hlbWUuICBIZXJlIGlzIGFuIGV4YW1wbGUgb2YgdGhlIHRyYW5zZm9ybTogVGhlIHVybAorICAgKiA8Y29kZT5odHRwOi8vbHVjZW5lLmFwYWNoZS5vcmcvaW5kZXguaHRtbD9xdWVyeT1zb21ldGhpbmcjbWlkZGxlPGNvZGU+IGlzCisgICAqIHJldHVybmVkIGFzCisgICAqIDxjb2RlPnI6aHR0cDovL29yZy5hcGFjaGUubHVjZW5lL2luZGV4Lmh0bWw/cXVlcnk9c29tZXRoaW5nI21pZGRsZTwvY29kZT4KKyAgICogVGhlIHRyYW5zZm9ybXMgYXJlIHJldmVyc2libGUuICBObyB0cmFuc2Zvcm0gaXMgZG9uZSBpZiBwYXNzZWQgVVJJIGlzCisgICAqIG5vdCBoaWVyYXJjaGljYWwuCisgICAqIAorICAgKiA8cD5JZiBhdXRob3JpdHkgPGNvZGU+dXNlcmluZm88L2NvZGU+IGlzIHByZXNlbnQsIHdpbGwgbWVzcyB1cCB0aGUgc29ydAorICAgKiAodW50aWwgd2UgZG8gbW9yZSB3b3JrKS48L3A+CisgICAqIAorICAgKiBAcGFyYW0gdSBVUkwgdG8gdHJhbnNmb3JtLgorICAgKiBAcmV0dXJuIEFuIG9wYXF1ZSBVUkkgb2YgYXJ0aWZpY2lhbCAncicgc2NoZW1lIHdpdGggaG9zdCBwb3J0aW9uIG9mIFVSSQorICAgKiBhdXRob3JpdHkgcmV2ZXJzZWQgKGlmIHByZXNlbnQpLgorICAgKiBAc2VlICNrZXlUb1VyaShTdHJpbmcpCisgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjM5Ni50eHQiPlJGQzIzOTY8L2E+CisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBjcmVhdGVLZXkoZmluYWwgU3RyaW5nIHUpIHsKKyAgICBpZiAodS5zdGFydHNXaXRoKFNDSEVNRSkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlN0YXJ0cyB3aXRoICIgKyBTQ0hFTUUpOworICAgIH0KKyAgICBNYXRjaGVyIG0gPSBnZXRNYXRjaGVyKHUpOworICAgIGlmIChtID09IG51bGwgfHwgIW0ubWF0Y2hlcygpKSB7CisgICAgICAvLyBJZiBubyBtYXRjaCwgcmV0dXJuIG9yaWdpbmFsIFN0cmluZy4KKyAgICAgIHJldHVybiB1OworICAgIH0KKyAgICByZXR1cm4gU0NIRU1FICsgbS5ncm91cCgxKSArIHJldmVyc2VIb3N0bmFtZShtLmdyb3VwKDIpKSArIG0uZ3JvdXAoMyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBSZXZlcnNlIHRoZSB7QGxpbmsgI2NyZWF0ZUtleShTdHJpbmcpfSB0cmFuc2Zvcm0uCisgICAqIAorICAgKiBAcGFyYW0gcyA8Y29kZT5VUkk8L2NvZGU+IG1hZGUgYnkge0BsaW5rICNjcmVhdGVLZXkoU3RyaW5nKX0uCisgICAqIEByZXR1cm4gJ1Jlc3RvcmVkJyBVUkkgbWFkZSBieSByZXZlcnNpbmcgdGhlIHtAbGluayAjY3JlYXRlS2V5KFN0cmluZyl9CisgICAqIHRyYW5zZm9ybS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGtleVRvVXJpKGZpbmFsIFN0cmluZyBzKSB7CisgICAgaWYgKCFzLnN0YXJ0c1dpdGgoU0NIRU1FKSkgeworICAgICAgcmV0dXJuIHM7CisgICAgfQorICAgIE1hdGNoZXIgbSA9IGdldE1hdGNoZXIocy5zdWJzdHJpbmcoU0NIRU1FLmxlbmd0aCgpKSk7CisgICAgaWYgKG0gPT0gbnVsbCB8fCAhbS5tYXRjaGVzKCkpIHsKKyAgICAgIC8vIElmIG5vIG1hdGNoLCByZXR1cm4gb3JpZ2luYWwgU3RyaW5nLgorICAgICAgcmV0dXJuIHM7CisgICAgfQorICAgIHJldHVybiBtLmdyb3VwKDEpICsgcmV2ZXJzZUhvc3RuYW1lKG0uZ3JvdXAoMikpICsgbS5ncm91cCgzKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgTWF0Y2hlciBnZXRNYXRjaGVyKGZpbmFsIFN0cmluZyB1KSB7CisgICAgaWYgKHUgPT0gbnVsbCB8fCB1Lmxlbmd0aCgpIDw9IDApIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gVVJJX1JFX1BBUlNFUi5tYXRjaGVyKHUpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcmV2ZXJzZUhvc3RuYW1lKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgeworICAgIGlmIChob3N0bmFtZSA9PSBudWxsKSB7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihob3N0bmFtZS5sZW5ndGgoKSk7CisgICAgZm9yIChTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGhvc3RuYW1lLCAiLiIsIGZhbHNlKTsKKyAgICAgICAgc3QuaGFzTW9yZUVsZW1lbnRzKCk7KSB7CisgICAgICBPYmplY3QgbmV4dCA9IHN0Lm5leHRFbGVtZW50KCk7CisgICAgICBpZiAoc2IubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgIHNiLmluc2VydCgwLCAiLiIpOworICAgICAgfQorICAgICAgc2IuaW5zZXJ0KDAsIG5leHQpOworICAgIH0KKyAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvTWVyZ2UuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvTWVyZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YWJiMzUzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9NZXJnZS5qYXZhCkBAIC0wLDAgKzEsMzc3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJlZDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTWFzdGVyTm90UnVubmluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSExvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5HZW5lcmljT3B0aW9uc1BhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlRvb2w7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Ub29sUnVubmVyOworCisvKioKKyAqIFV0aWxpdHkgdGhhdCBjYW4gbWVyZ2UgYW55IHR3byByZWdpb25zIGluIHRoZSBzYW1lIHRhYmxlOiBhZGphY2VudCwKKyAqIG92ZXJsYXBwaW5nIG9yIGRpc2pvaW50LgorICovCitwdWJsaWMgY2xhc3MgTWVyZ2UgZXh0ZW5kcyBDb25maWd1cmVkIGltcGxlbWVudHMgVG9vbCB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWVyZ2UuY2xhc3MpOworICBwcml2YXRlIGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICBwcml2YXRlIFBhdGggcm9vdGRpcjsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBNZXRhVXRpbHMgdXRpbHM7CisgIHByaXZhdGUgYnl0ZSBbXSB0YWJsZU5hbWU7ICAgICAgICAgICAgICAgLy8gTmFtZSBvZiB0YWJsZQorICBwcml2YXRlIHZvbGF0aWxlIGJ5dGUgW10gcmVnaW9uMTsgICAgICAgIC8vIE5hbWUgb2YgcmVnaW9uIDEKKyAgcHJpdmF0ZSB2b2xhdGlsZSBieXRlIFtdIHJlZ2lvbjI7ICAgICAgICAvLyBOYW1lIG9mIHJlZ2lvbiAyCisgIHByaXZhdGUgdm9sYXRpbGUgYm9vbGVhbiBpc01ldGFUYWJsZTsKKyAgcHJpdmF0ZSB2b2xhdGlsZSBIUmVnaW9uSW5mbyBtZXJnZUluZm87CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIE1lcmdlKCkgeworICAgIHRoaXMobmV3IEhCYXNlQ29uZmlndXJhdGlvbigpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY29uZgorICAgKi8KKyAgcHVibGljIE1lcmdlKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB7CisgICAgc3VwZXIoY29uZik7CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICB0aGlzLm1lcmdlSW5mbyA9IG51bGw7CisgIH0KKworICBwdWJsaWMgaW50IHJ1bihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpZiAocGFyc2VBcmdzKGFyZ3MpICE9IDApIHsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvLyBWZXJpZnkgZmlsZSBzeXN0ZW0gaXMgdXAuCisgICAgRmlsZVN5c3RlbSBmcyA9IEZpbGVTeXN0ZW0uZ2V0KHRoaXMuY29uZik7ICAgICAgICAgICAgICAvLyBnZXQgREZTIGhhbmRsZQorICAgIExPRy5pbmZvKCJWZXJpZnlpbmcgdGhhdCBmaWxlIHN5c3RlbSBpcyBhdmFpbGFibGUuLi4iKTsKKyAgICB0cnkgeworICAgICAgRlNVdGlscy5jaGVja0ZpbGVTeXN0ZW1BdmFpbGFibGUoZnMpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiRmlsZSBzeXN0ZW0gaXMgbm90IGF2YWlsYWJsZSIsIGUpOworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICAKKyAgICAvLyBWZXJpZnkgSEJhc2UgaXMgZG93bgorICAgIExPRy5pbmZvKCJWZXJpZnlpbmcgdGhhdCBIQmFzZSBpcyBub3QgcnVubmluZy4uLiIpOworICAgIHRyeSB7CisgICAgICBIQmFzZUFkbWluLmNoZWNrSEJhc2VBdmFpbGFibGUoY29uZik7CisgICAgICBMT0cuZmF0YWwoIkhCYXNlIGNsdXN0ZXIgbXVzdCBiZSBvZmYtbGluZS4iKTsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9IGNhdGNoIChNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLiBJZ25vcmUuCisgICAgfQorICAgIAorICAgIC8vIEluaXRpYWxpemUgTWV0YVV0aWxzIGFuZCBhbmQgZ2V0IHRoZSByb290IG9mIHRoZSBIQmFzZSBpbnN0YWxsYXRpb24KKyAgICAKKyAgICB0aGlzLnV0aWxzID0gbmV3IE1ldGFVdGlscyhjb25mKTsKKyAgICB0aGlzLnJvb3RkaXIgPSBGU1V0aWxzLmdldFJvb3REaXIodGhpcy5jb25mKTsKKyAgICB0cnkgeworICAgICAgaWYgKGlzTWV0YVRhYmxlKSB7CisgICAgICAgIG1lcmdlVHdvTWV0YVJlZ2lvbnMoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIG1lcmdlVHdvUmVnaW9ucygpOworICAgICAgfQorICAgICAgcmV0dXJuIDA7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiTWVyZ2UgZmFpbGVkIiwgZSk7CisgICAgICB1dGlscy5zY2FuTWV0YVJlZ2lvbihIUmVnaW9uSW5mby5GSVJTVF9NRVRBX1JFR0lPTklORk8sCisgICAgICAgICAgbmV3IE1ldGFVdGlscy5TY2FubmVyTGlzdGVuZXIoKSB7CisgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KEhSZWdpb25JbmZvIGluZm8pIHsKKyAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGluZm8udG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICk7CisKKyAgICAgIHJldHVybiAtMTsKKyAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHRoaXMudXRpbHMgIT0gbnVsbCkgeworICAgICAgICB0aGlzLnV0aWxzLnNodXRkb3duKCk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICAvKiogQHJldHVybiBIUmVnaW9uSW5mbyBmb3IgbWVyZ2UgcmVzdWx0ICovCisgIEhSZWdpb25JbmZvIGdldE1lcmdlZEhSZWdpb25JbmZvKCkgeworICAgIHJldHVybiB0aGlzLm1lcmdlSW5mbzsKKyAgfQorCisgIC8qCisgICAqIE1lcmdlIHR3byBtZXRhIHJlZ2lvbnMuIFRoaXMgaXMgdW5saWtlbHkgdG8gYmUgbmVlZGVkIHNvb24gYXMgd2UgaGF2ZSBvbmx5CisgICAqIHNlZW5kIHRoZSBtZXRhIHRhYmxlIHNwbGl0IG9uY2UgYW5kIHRoYXQgd2FzIHdpdGggNjRNQiByZWdpb25zLiBXaXRoIDI1Nk1CCisgICAqIHJlZ2lvbnMsIGl0IHdpbGwgYmUgc29tZSB0aW1lIGJlZm9yZSBzb21lb25lIGhhcyBlbm91Z2ggZGF0YSBpbiBIQmFzZSB0bworICAgKiBzcGxpdCB0aGUgbWV0YSByZWdpb24gYW5kIGV2ZW4gbGVzcyBsaWtlbHkgdGhhdCBhIG1lcmdlIG9mIHR3byBtZXRhCisgICAqIHJlZ2lvbnMgd2lsbCBiZSBuZWVkZWQsIGJ1dCBpdCBpcyBpbmNsdWRlZCBmb3IgY29tcGxldGVuZXNzLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIG1lcmdlVHdvTWV0YVJlZ2lvbnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gcm9vdFJlZ2lvbiA9IHV0aWxzLmdldFJvb3RSZWdpb24oKTsKKyAgICBMaXN0PEtleVZhbHVlPiBjZWxsczEgPQorICAgICAgcm9vdFJlZ2lvbi5nZXQocmVnaW9uMSwgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgLTEsIC0xKTsKKyAgICBIUmVnaW9uSW5mbyBpbmZvMSA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mbygoY2VsbHMxID09IG51bGwpPyBudWxsOiBjZWxsczEuZ2V0KDApLmdldFZhbHVlKCkpOworICAgIExpc3Q8S2V5VmFsdWU+IGNlbGxzMiA9CisgICAgICByb290UmVnaW9uLmdldChyZWdpb24yLCBIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPLCAtMSwgLTEpOworICAgIEhSZWdpb25JbmZvIGluZm8yID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvKChjZWxsczIgPT0gbnVsbCk/IG51bGw6IGNlbGxzMi5nZXQoMCkuZ2V0VmFsdWUoKSk7CisgICAgSFJlZ2lvbiBtZXJnZWQgPSBtZXJnZShpbmZvMSwgcm9vdFJlZ2lvbiwgaW5mbzIsIHJvb3RSZWdpb24pOyAKKyAgICBMT0cuaW5mbygiQWRkaW5nICIgKyBtZXJnZWQuZ2V0UmVnaW9uSW5mbygpICsgIiB0byAiICsKKyAgICAgICAgcm9vdFJlZ2lvbi5nZXRSZWdpb25JbmZvKCkpOworICAgIEhSZWdpb24uYWRkUmVnaW9uVG9NRVRBKHJvb3RSZWdpb24sIG1lcmdlZCk7CisgICAgbWVyZ2VkLmNsb3NlKCk7CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIE1ldGFTY2FubmVyTGlzdGVuZXIKKyAgaW1wbGVtZW50cyBNZXRhVXRpbHMuU2Nhbm5lckxpc3RlbmVyIHsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGUgW10gcmVnaW9uMTsKKyAgICBwcml2YXRlIGZpbmFsIGJ5dGUgW10gcmVnaW9uMjsKKyAgICBwcml2YXRlIEhSZWdpb25JbmZvIG1ldGExID0gbnVsbDsKKyAgICBwcml2YXRlIEhSZWdpb25JbmZvIG1ldGEyID0gbnVsbDsKKyAgICAKKyAgICBNZXRhU2Nhbm5lckxpc3RlbmVyKGZpbmFsIGJ5dGUgW10gcmVnaW9uMSwgZmluYWwgYnl0ZSBbXSByZWdpb24yKSB7CisgICAgICB0aGlzLnJlZ2lvbjEgPSByZWdpb24xOworICAgICAgdGhpcy5yZWdpb24yID0gcmVnaW9uMjsKKyAgICB9CisgICAgCisgICAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc1JvdyhIUmVnaW9uSW5mbyBpbmZvKSB7CisgICAgICBpZiAobWV0YTEgPT0gbnVsbCAmJiBIUmVnaW9uLnJvd0lzSW5SYW5nZShpbmZvLCByZWdpb24xKSkgeworICAgICAgICBtZXRhMSA9IGluZm87CisgICAgICB9CisgICAgICBpZiAocmVnaW9uMiAhPSBudWxsICYmIG1ldGEyID09IG51bGwgJiYKKyAgICAgICAgICBIUmVnaW9uLnJvd0lzSW5SYW5nZShpbmZvLCByZWdpb24yKSkgeworICAgICAgICBtZXRhMiA9IGluZm87CisgICAgICB9CisgICAgICByZXR1cm4gbWV0YTEgPT0gbnVsbCB8fCAocmVnaW9uMiAhPSBudWxsICYmIG1ldGEyID09IG51bGwpOworICAgIH0KKyAgICAKKyAgICBIUmVnaW9uSW5mbyBnZXRNZXRhMSgpIHsKKyAgICAgIHJldHVybiBtZXRhMTsKKyAgICB9CisgICAgCisgICAgSFJlZ2lvbkluZm8gZ2V0TWV0YTIoKSB7CisgICAgICByZXR1cm4gbWV0YTI7CisgICAgfQorICB9CisgIAorICAvKgorICAgKiBNZXJnZXMgdHdvIHJlZ2lvbnMgZnJvbSBhIHVzZXIgdGFibGUuCisgICAqLworICBwcml2YXRlIHZvaWQgbWVyZ2VUd29SZWdpb25zKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMT0cuaW5mbygiTWVyZ2luZyByZWdpb25zICIgKyBCeXRlcy50b1N0cmluZyh0aGlzLnJlZ2lvbjEpICsgIiBhbmQgIiArCisgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHRoaXMucmVnaW9uMikgKyAiIGluIHRhYmxlICIgKyBCeXRlcy50b1N0cmluZyh0aGlzLnRhYmxlTmFtZSkpOworICAgIC8vIFNjYW4gdGhlIHJvb3QgcmVnaW9uIGZvciBhbGwgdGhlIG1ldGEgcmVnaW9ucyB0aGF0IGNvbnRhaW4gdGhlIHJlZ2lvbnMKKyAgICAvLyB3ZSdyZSBtZXJnaW5nLgorICAgIE1ldGFTY2FubmVyTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgTWV0YVNjYW5uZXJMaXN0ZW5lcihyZWdpb24xLCByZWdpb24yKTsKKyAgICB0aGlzLnV0aWxzLnNjYW5Sb290UmVnaW9uKGxpc3RlbmVyKTsKKyAgICBIUmVnaW9uSW5mbyBtZXRhMSA9IGxpc3RlbmVyLmdldE1ldGExKCk7CisgICAgaWYgKG1ldGExID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IGZpbmQgbWV0YSByZWdpb24gZm9yICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb24xKSk7CisgICAgfQorICAgIEhSZWdpb25JbmZvIG1ldGEyID0gbGlzdGVuZXIuZ2V0TWV0YTIoKTsKKyAgICBpZiAobWV0YTIgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZCBub3QgZmluZCBtZXRhIHJlZ2lvbiBmb3IgIiArIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbjIpKTsKKyAgICB9CisgICAgTE9HLmluZm8oIkZvdW5kIG1ldGEgZm9yIHJlZ2lvbjEgIiArIEJ5dGVzLnRvU3RyaW5nKG1ldGExLmdldFJlZ2lvbk5hbWUoKSkgKworICAgICAgIiwgbWV0YSBmb3IgcmVnaW9uMiAiICsgQnl0ZXMudG9TdHJpbmcobWV0YTIuZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgSFJlZ2lvbiBtZXRhUmVnaW9uMSA9IHRoaXMudXRpbHMuZ2V0TWV0YVJlZ2lvbihtZXRhMSk7CisgICAgTGlzdDxLZXlWYWx1ZT4gY2VsbHMxID0gbWV0YVJlZ2lvbjEuZ2V0KHJlZ2lvbjEsIEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8sIC0xLCAtMSk7CisgICAgSFJlZ2lvbkluZm8gaW5mbzEgPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm8oKGNlbGxzMSA9PSBudWxsKT8gbnVsbDogY2VsbHMxLmdldCgwKS5nZXRWYWx1ZSgpKTsKKyAgICBpZiAoaW5mbzE9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImluZm8xIGlzIG51bGwgdXNpbmcga2V5ICIgKworICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKHJlZ2lvbjEpICsgIiBpbiAiICsgbWV0YTEpOworICAgIH0KKworICAgIEhSZWdpb24gbWV0YVJlZ2lvbjIgPSBudWxsOworICAgIGlmIChCeXRlcy5lcXVhbHMobWV0YTEuZ2V0UmVnaW9uTmFtZSgpLCBtZXRhMi5nZXRSZWdpb25OYW1lKCkpKSB7CisgICAgICBtZXRhUmVnaW9uMiA9IG1ldGFSZWdpb24xOworICAgIH0gZWxzZSB7CisgICAgICBtZXRhUmVnaW9uMiA9IHV0aWxzLmdldE1ldGFSZWdpb24obWV0YTIpOworICAgIH0KKyAgICBMaXN0PEtleVZhbHVlPiBjZWxsczIgPSBtZXRhUmVnaW9uMi5nZXQocmVnaW9uMiwgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgLTEsIC0xKTsKKyAgICBIUmVnaW9uSW5mbyBpbmZvMiA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mbygoY2VsbHMyID09IG51bGwpPyBudWxsOiBjZWxsczIuZ2V0KDApLmdldFZhbHVlKCkpOworICAgIGlmIChpbmZvMiA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oImluZm8yIGlzIG51bGwgdXNpbmcga2V5ICIgKyBtZXRhMik7CisgICAgfQorICAgIEhSZWdpb24gbWVyZ2VkID0gbWVyZ2UoaW5mbzEsIG1ldGFSZWdpb24xLCBpbmZvMiwgbWV0YVJlZ2lvbjIpOworCisgICAgLy8gTm93IGZpbmQgdGhlIG1ldGEgcmVnaW9uIHdoaWNoIHdpbGwgY29udGFpbiB0aGUgbmV3bHkgbWVyZ2VkIHJlZ2lvbgorCisgICAgbGlzdGVuZXIgPSBuZXcgTWV0YVNjYW5uZXJMaXN0ZW5lcihtZXJnZWQuZ2V0UmVnaW9uTmFtZSgpLCBudWxsKTsKKyAgICB1dGlscy5zY2FuUm9vdFJlZ2lvbihsaXN0ZW5lcik7CisgICAgSFJlZ2lvbkluZm8gbWVyZ2VkSW5mbyA9IGxpc3RlbmVyLmdldE1ldGExKCk7CisgICAgaWYgKG1lcmdlZEluZm8gPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZCBub3QgZmluZCBtZXRhIHJlZ2lvbiBmb3IgIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcobWVyZ2VkLmdldFJlZ2lvbk5hbWUoKSkpOworICAgIH0KKyAgICBIUmVnaW9uIG1lcmdlTWV0YSA9IG51bGw7CisgICAgaWYgKEJ5dGVzLmVxdWFscyhtZXJnZWRJbmZvLmdldFJlZ2lvbk5hbWUoKSwgbWV0YTEuZ2V0UmVnaW9uTmFtZSgpKSkgeworICAgICAgbWVyZ2VNZXRhID0gbWV0YVJlZ2lvbjE7CisgICAgfSBlbHNlIGlmIChCeXRlcy5lcXVhbHMobWVyZ2VkSW5mby5nZXRSZWdpb25OYW1lKCksIG1ldGEyLmdldFJlZ2lvbk5hbWUoKSkpIHsKKyAgICAgIG1lcmdlTWV0YSA9IG1ldGFSZWdpb24yOworICAgIH0gZWxzZSB7CisgICAgICBtZXJnZU1ldGEgPSB1dGlscy5nZXRNZXRhUmVnaW9uKG1lcmdlZEluZm8pOworICAgIH0KKyAgICBMT0cuaW5mbygiQWRkaW5nICIgKyBtZXJnZWQuZ2V0UmVnaW9uSW5mbygpICsgIiB0byAiICsKKyAgICAgICAgbWVyZ2VNZXRhLmdldFJlZ2lvbkluZm8oKSk7CisKKyAgICBIUmVnaW9uLmFkZFJlZ2lvblRvTUVUQShtZXJnZU1ldGEsIG1lcmdlZCk7CisgICAgbWVyZ2VkLmNsb3NlKCk7CisgIH0KKyAgCisgIC8qCisgICAqIEFjdHVhbGx5IG1lcmdlIHR3byByZWdpb25zIGFuZCB1cGRhdGUgdGhlaXIgaW5mbyBpbiB0aGUgbWV0YSByZWdpb24ocykKKyAgICogSWYgdGhlIG1ldGEgaXMgc3BsaXQsIG1ldGExIG1heSBiZSBkaWZmZXJlbnQgZnJvbSBtZXRhMi4gKGFuZCB3ZSBtYXkgaGF2ZQorICAgKiB0byBzY2FuIHRoZSBtZXRhIGlmIHRoZSByZXN1bHRpbmcgbWVyZ2VkIHJlZ2lvbiBkb2VzIG5vdCBnbyBpbiBlaXRoZXIpCisgICAqIFJldHVybnMgSFJlZ2lvbiBvYmplY3QgZm9yIG5ld2x5IG1lcmdlZCByZWdpb24KKyAgICovCisgIHByaXZhdGUgSFJlZ2lvbiBtZXJnZShIUmVnaW9uSW5mbyBpbmZvMSwgSFJlZ2lvbiBtZXRhMSwgSFJlZ2lvbkluZm8gaW5mbzIsCisgICAgICBIUmVnaW9uIG1ldGEyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChpbmZvMSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvdWxkIG5vdCBmaW5kICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb24xKSArICIgaW4gIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcobWV0YTEuZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgfQorICAgIGlmIChpbmZvMiA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvdW5kIG5vdCBmaW5kICIgKyBCeXRlcy50b1N0cmluZyhyZWdpb24yKSArICIgaW4gIiArCisgICAgICAgICAgQnl0ZXMudG9TdHJpbmcobWV0YTIuZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgfQorICAgIEhSZWdpb24gbWVyZ2VkID0gbnVsbDsKKyAgICBITG9nIGxvZyA9IHV0aWxzLmdldExvZygpOworICAgIEhSZWdpb24gcjEgPSBIUmVnaW9uLm9wZW5IUmVnaW9uKGluZm8xLCB0aGlzLnJvb3RkaXIsIGxvZywgdGhpcy5jb25mKTsKKyAgICB0cnkgeworICAgICAgSFJlZ2lvbiByMiA9IEhSZWdpb24ub3BlbkhSZWdpb24oaW5mbzIsIHRoaXMucm9vdGRpciwgbG9nLCB0aGlzLmNvbmYpOworICAgICAgdHJ5IHsKKyAgICAgICAgbWVyZ2VkID0gSFJlZ2lvbi5tZXJnZShyMSwgcjIpOworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgaWYgKCFyMi5pc0Nsb3NlZCgpKSB7CisgICAgICAgICAgcjIuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBpZiAoIXIxLmlzQ2xvc2VkKCkpIHsKKyAgICAgICAgcjEuY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgLy8gUmVtb3ZlIHRoZSBvbGQgcmVnaW9ucyBmcm9tIG1ldGEuCisgICAgLy8gSFJlZ2lvbi5tZXJnZSBoYXMgYWxyZWFkeSBkZWxldGVkIHRoZWlyIGZpbGVzCisgICAgCisgICAgcmVtb3ZlUmVnaW9uRnJvbU1ldGEobWV0YTEsIGluZm8xKTsKKyAgICByZW1vdmVSZWdpb25Gcm9tTWV0YShtZXRhMiwgaW5mbzIpOworCisgICAgdGhpcy5tZXJnZUluZm8gPSBtZXJnZWQuZ2V0UmVnaW9uSW5mbygpOworICAgIHJldHVybiBtZXJnZWQ7CisgIH0KKyAgCisgIC8qCisgICAqIFJlbW92ZXMgYSByZWdpb24ncyBtZXRhIGluZm9ybWF0aW9uIGZyb20gdGhlIHBhc3NlZCA8Y29kZT5tZXRhPC9jb2RlPgorICAgKiByZWdpb24uCisgICAqIAorICAgKiBAcGFyYW0gbWV0YSBNRVRBIEhSZWdpb24gdG8gYmUgdXBkYXRlZAorICAgKiBAcGFyYW0gcmVnaW9uaW5mbyBIUmVnaW9uSW5mbyBvZiByZWdpb24gdG8gcmVtb3ZlIGZyb20gPGNvZGU+bWV0YTwvY29kZT4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJlbW92ZVJlZ2lvbkZyb21NZXRhKEhSZWdpb24gbWV0YSwgSFJlZ2lvbkluZm8gcmVnaW9uaW5mbykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiUmVtb3ZpbmcgcmVnaW9uOiAiICsgcmVnaW9uaW5mbyArICIgZnJvbSAiICsgbWV0YSk7CisgICAgfQorICAgIG1ldGEuZGVsZXRlQWxsKHJlZ2lvbmluZm8uZ2V0UmVnaW9uTmFtZSgpLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwgbnVsbCk7CisgIH0KKworICAvKgorICAgKiBBZGRzIGEgcmVnaW9uJ3MgbWV0YSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBwYXNzZWQgPGNvZGU+bWV0YTwvY29kZT4KKyAgICogcmVnaW9uLgorICAgKiAKKyAgICogQHBhcmFtIG1ldGFpbmZvIE1FVEEgSFJlZ2lvbkluZm8gdG8gYmUgdXBkYXRlZAorICAgKiBAcGFyYW0gcmVnaW9uIEhSZWdpb24gdG8gYWRkIHRvIDxjb2RlPm1ldGE8L2NvZGU+CisgICAqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgaW50IHBhcnNlQXJncyhTdHJpbmdbXSBhcmdzKSB7CisgICAgR2VuZXJpY09wdGlvbnNQYXJzZXIgcGFyc2VyID0KKyAgICAgIG5ldyBHZW5lcmljT3B0aW9uc1BhcnNlcih0aGlzLmdldENvbmYoKSwgYXJncyk7CisgICAgCisgICAgU3RyaW5nW10gcmVtYWluaW5nQXJncyA9IHBhcnNlci5nZXRSZW1haW5pbmdBcmdzKCk7CisgICAgaWYgKHJlbWFpbmluZ0FyZ3MubGVuZ3RoICE9IDMpIHsKKyAgICAgIHVzYWdlKCk7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHRhYmxlTmFtZSA9IEJ5dGVzLnRvQnl0ZXMocmVtYWluaW5nQXJnc1swXSk7CisgICAgaXNNZXRhVGFibGUgPSBCeXRlcy5jb21wYXJlVG8odGFibGVOYW1lLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSkgPT0gMDsKKyAgICAKKyAgICByZWdpb24xID0gQnl0ZXMudG9CeXRlcyhyZW1haW5pbmdBcmdzWzFdKTsKKyAgICByZWdpb24yID0gQnl0ZXMudG9CeXRlcyhyZW1haW5pbmdBcmdzWzJdKTsKKyAgICBpbnQgc3RhdHVzID0gMDsKKyAgICBpZiAobm90SW5UYWJsZSh0YWJsZU5hbWUsIHJlZ2lvbjEpIHx8IG5vdEluVGFibGUodGFibGVOYW1lLCByZWdpb24yKSkgeworICAgICAgc3RhdHVzID0gLTE7CisgICAgfSBlbHNlIGlmIChCeXRlcy5lcXVhbHMocmVnaW9uMSwgcmVnaW9uMikpIHsKKyAgICAgIExPRy5lcnJvcigiQ2FuJ3QgbWVyZ2UgYSByZWdpb24gd2l0aCBpdHNlbGYiKTsKKyAgICAgIHN0YXR1cyA9IC0xOworICAgIH0KKyAgICByZXR1cm4gc3RhdHVzOworICB9CisgIAorICBwcml2YXRlIGJvb2xlYW4gbm90SW5UYWJsZShmaW5hbCBieXRlIFtdIHRuLCBmaW5hbCBieXRlIFtdIHJuKSB7CisgICAgaWYgKFdyaXRhYmxlQ29tcGFyYXRvci5jb21wYXJlQnl0ZXModG4sIDAsIHRuLmxlbmd0aCwgcm4sIDAsIHRuLmxlbmd0aCkgIT0gMCkgeworICAgICAgTE9HLmVycm9yKCJSZWdpb24gIiArIEJ5dGVzLnRvU3RyaW5nKHJuKSArICIgZG9lcyBub3QgYmVsb25nIHRvIHRhYmxlICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyh0bikpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHVzYWdlKCkgeworICAgIFN5c3RlbS5lcnIucHJpbnRsbigKKyAgICAgICAgIlVzYWdlOiBiaW4vaGJhc2UgbWVyZ2UgPHRhYmxlLW5hbWU+IDxyZWdpb24tMT4gPHJlZ2lvbi0yPlxuIik7CisgIH0KKyAgCisgIC8qKgorICAgKiBNYWluIHByb2dyYW0KKyAgICogCisgICAqIEBwYXJhbSBhcmdzCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgaW50IHN0YXR1cyA9IDA7CisgICAgdHJ5IHsKKyAgICAgIHN0YXR1cyA9IFRvb2xSdW5uZXIucnVuKG5ldyBNZXJnZSgpLCBhcmdzKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJleGl0aW5nIGR1ZSB0byBlcnJvciIsIGUpOworICAgICAgc3RhdHVzID0gLTE7CisgICAgfQorICAgIFN5c3RlbS5leGl0KHN0YXR1cyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvTWV0YVV0aWxzLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01ldGFVdGlscy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmYmE0NjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01ldGFVdGlscy5qYXZhCkBAIC0wLDAgKzEsNDYyIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSExvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSW50ZXJuYWxTY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5TdG9yZTsKKworLyoqCisgKiBDb250YWlucyB1dGlsaXR5IG1ldGhvZHMgZm9yIG1hbmlwdWxhdGluZyBIQmFzZSBtZXRhIHRhYmxlcy4KKyAqIEJlIHN1cmUgdG8gY2FsbCB7QGxpbmsgI3NodXRkb3duKCl9IHdoZW4gZG9uZSB3aXRoIHRoaXMgY2xhc3Mgc28gaXQgY2xvc2VzCisgKiByZXNvdXJjZXMgb3BlbmVkIGR1cmluZyBtZXRhIHByb2Nlc3NpbmcgKFJPT1QsIE1FVEEsIGV0Yy4pLiAgQmUgY2FyZWZ1bAorICogaG93IHlvdSB1c2UgdGhpcyBjbGFzcy4gIElmIHVzZWQgZHVyaW5nIG1pZ3JhdGlvbnMsIGJlIGNhcmVmdWwgd2hlbiB1c2luZworICogdGhpcyBjbGFzcyB0byBjaGVjayB3aGV0aGVyIG1pZ3JhdGlvbiBpcyBuZWVkZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBNZXRhVXRpbHMgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWV0YVV0aWxzLmNsYXNzKTsKKyAgcHJpdmF0ZSBmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBGaWxlU3lzdGVtIGZzOworICBwcml2YXRlIFBhdGggcm9vdGRpcjsKKyAgcHJpdmF0ZSBITG9nIGxvZzsKKyAgcHJpdmF0ZSBIUmVnaW9uIHJvb3RSZWdpb247CisgIHByaXZhdGUgTWFwPGJ5dGUgW10sIEhSZWdpb24+IG1ldGFSZWdpb25zID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkU29ydGVkTWFwKAorICAgIG5ldyBUcmVlTWFwPGJ5dGUgW10sIEhSZWdpb24+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpKTsKKyAgCisgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICovCisgIHB1YmxpYyBNZXRhVXRpbHMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMobmV3IEhCYXNlQ29uZmlndXJhdGlvbigpKTsKKyAgfQorICAKKyAgLyoqIEBwYXJhbSBjb25mIEhCYXNlQ29uZmlndXJhdGlvbiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAqLworICBwdWJsaWMgTWV0YVV0aWxzKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgY29uZi5zZXRJbnQoImhiYXNlLmNsaWVudC5yZXRyaWVzLm51bWJlciIsIDEpOworICAgIHRoaXMucm9vdFJlZ2lvbiA9IG51bGw7CisgICAgaW5pdGlhbGl6ZSgpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgREZTIGlzIGF2YWlsYWJsZSBhbmQgdGhhdCBIQmFzZSBpcyBvZmYtbGluZS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRoaXMuZnMgPSBGaWxlU3lzdGVtLmdldCh0aGlzLmNvbmYpOworICAgIC8vIEdldCByb290IGRpcmVjdG9yeSBvZiBIQmFzZSBpbnN0YWxsYXRpb24KKyAgICB0aGlzLnJvb3RkaXIgPSBGU1V0aWxzLmdldFJvb3REaXIodGhpcy5jb25mKTsKKyAgfQorCisgIC8qKiBAcmV0dXJuIHRoZSBITG9nIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICovCisgIHB1YmxpYyBzeW5jaHJvbml6ZWQgSExvZyBnZXRMb2coKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLmxvZyA9PSBudWxsKSB7CisgICAgICBQYXRoIGxvZ2RpciA9IG5ldyBQYXRoKHRoaXMuZnMuZ2V0SG9tZURpcmVjdG9yeSgpLAorICAgICAgICAgIEhDb25zdGFudHMuSFJFR0lPTl9MT0dESVJfTkFNRSArICJfIiArIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgIHRoaXMubG9nID0gbmV3IEhMb2codGhpcy5mcywgbG9nZGlyLCB0aGlzLmNvbmYsIG51bGwpOworICAgIH0KKyAgICByZXR1cm4gdGhpcy5sb2c7CisgIH0KKyAgCisgIC8qKgorICAgKiBAcmV0dXJuIEhSZWdpb24gZm9yIHJvb3QgcmVnaW9uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBIUmVnaW9uIGdldFJvb3RSZWdpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICh0aGlzLnJvb3RSZWdpb24gPT0gbnVsbCkgeworICAgICAgb3BlblJvb3RSZWdpb24oKTsKKyAgICB9CisgICAgcmV0dXJuIHRoaXMucm9vdFJlZ2lvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIE9wZW4gb3IgcmV0dXJuIGNhY2hlZCBvcGVuZWQgbWV0YSByZWdpb24KKyAgICogCisgICAqIEBwYXJhbSBtZXRhSW5mbyBIUmVnaW9uSW5mbyBmb3IgbWV0YSByZWdpb24KKyAgICogQHJldHVybiBtZXRhIEhSZWdpb24KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIEhSZWdpb24gZ2V0TWV0YVJlZ2lvbihIUmVnaW9uSW5mbyBtZXRhSW5mbykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIG1ldGEgPSBtZXRhUmVnaW9ucy5nZXQobWV0YUluZm8uZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICBpZiAobWV0YSA9PSBudWxsKSB7CisgICAgICBtZXRhID0gb3Blbk1ldGFSZWdpb24obWV0YUluZm8pOworICAgICAgdGhpcy5tZXRhUmVnaW9ucy5wdXQobWV0YUluZm8uZ2V0UmVnaW9uTmFtZSgpLCBtZXRhKTsKKyAgICB9CisgICAgcmV0dXJuIG1ldGE7CisgIH0KKyAgCisgIC8qKgorICAgKiBDbG9zZXMgY2F0YWxvZyByZWdpb25zIGlmIG9wZW4uIEFsc28gY2xvc2VzIGFuZCBkZWxldGVzIHRoZSBITG9nLiBZb3UKKyAgICogbXVzdCBjYWxsIHRoaXMgbWV0aG9kIGlmIHlvdSB3YW50IHRvIHBlcnNpc3QgY2hhbmdlcyBtYWRlIGR1cmluZyBhCisgICAqIE1ldGFVdGlscyBlZGl0IHNlc3Npb24uCisgICAqLworICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICBpZiAodGhpcy5yb290UmVnaW9uICE9IG51bGwpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHRoaXMucm9vdFJlZ2lvbi5jbG9zZSgpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuZXJyb3IoImNsb3Npbmcgcm9vdCByZWdpb24iLCBlKTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHRoaXMucm9vdFJlZ2lvbiA9IG51bGw7CisgICAgICB9CisgICAgfQorICAgIHRyeSB7CisgICAgICBmb3IgKEhSZWdpb24gcjogbWV0YVJlZ2lvbnMudmFsdWVzKCkpIHsKKyAgICAgICAgci5jbG9zZSgpOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiY2xvc2luZyBtZXRhIHJlZ2lvbiIsIGUpOworICAgIH0gZmluYWxseSB7CisgICAgICBtZXRhUmVnaW9ucy5jbGVhcigpOworICAgIH0KKyAgICB0cnkgeworICAgICAgaWYgKHRoaXMubG9nICE9IG51bGwpIHsKKyAgICAgICAgdGhpcy5sb2cucm9sbFdyaXRlcigpOworICAgICAgICB0aGlzLmxvZy5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgfQorICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiY2xvc2luZyBITG9nIiwgZSk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMubG9nID0gbnVsbDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVXNlZCBieSBzY2FuUm9vdFJlZ2lvbiBhbmQgc2Nhbk1ldGFSZWdpb24gdG8gY2FsbCBiYWNrIHRoZSBjYWxsZXIgc28gaXQKKyAgICogY2FuIHByb2Nlc3MgdGhlIGRhdGEgZm9yIGEgcm93LgorICAgKi8KKyAgcHVibGljIGludGVyZmFjZSBTY2FubmVyTGlzdGVuZXIgeworICAgIC8qKgorICAgICAqIENhbGxiYWNrIHNvIGNsaWVudCBvZiBzY2FubmVyIGNhbiBwcm9jZXNzIHJvdyBjb250ZW50cworICAgICAqIAorICAgICAqIEBwYXJhbSBpbmZvIEhSZWdpb25JbmZvIGZvciByb3cKKyAgICAgKiBAcmV0dXJuIGZhbHNlIHRvIHRlcm1pbmF0ZSB0aGUgc2NhbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KEhSZWdpb25JbmZvIGluZm8pIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIFNjYW5zIHRoZSByb290IHJlZ2lvbi4gRm9yIGV2ZXJ5IG1ldGEgcmVnaW9uIGZvdW5kLCBjYWxscyB0aGUgbGlzdGVuZXIgd2l0aAorICAgKiB0aGUgSFJlZ2lvbkluZm8gb2YgdGhlIG1ldGEgcmVnaW9uLgorICAgKiAKKyAgICogQHBhcmFtIGxpc3RlbmVyIG1ldGhvZCB0byBiZSBjYWxsZWQgZm9yIGVhY2ggbWV0YSByZWdpb24gZm91bmQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2NhblJvb3RSZWdpb24oU2Nhbm5lckxpc3RlbmVyIGxpc3RlbmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIE9wZW4gcm9vdCByZWdpb24gc28gd2UgY2FuIHNjYW4gaXQKKyAgICBpZiAodGhpcy5yb290UmVnaW9uID09IG51bGwpIHsKKyAgICAgIG9wZW5Sb290UmVnaW9uKCk7CisgICAgfQorCisgICAgSW50ZXJuYWxTY2FubmVyIHJvb3RTY2FubmVyID0gcm9vdFJlZ2lvbi5nZXRTY2FubmVyKAorICAgICAgICBIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPX0FSUkFZLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywKKyAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKworICAgIHRyeSB7CisgICAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIHdoaWxlIChyb290U2Nhbm5lci5uZXh0KHJlc3VsdHMpKSB7CisgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBudWxsOworICAgICAgICBmb3IgKEtleVZhbHVlIGt2OiByZXN1bHRzKSB7CisgICAgICAgICAgaW5mbyA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mb09yTnVsbChrdi5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICBpZiAoaW5mbyA9PSBudWxsKSB7CisgICAgICAgICAgICBMT0cud2FybigicmVnaW9uIGluZm8gaXMgbnVsbCBmb3Igcm93ICIgKworICAgICAgICAgICAgICBCeXRlcy50b1N0cmluZyhrdi5nZXRSb3coKSkgKyAiIGluIHRhYmxlICIgKworICAgICAgICAgICAgICAgIEhDb25zdGFudHMuUk9PVF9UQUJMRV9OQU1FKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoIWxpc3RlbmVyLnByb2Nlc3NSb3coaW5mbykpIHsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgICByZXN1bHRzLmNsZWFyKCk7CisgICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICByb290U2Nhbm5lci5jbG9zZSgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTY2FucyBhIG1ldGEgcmVnaW9uLiBGb3IgZXZlcnkgcmVnaW9uIGZvdW5kLCBjYWxscyB0aGUgbGlzdGVuZXIgd2l0aAorICAgKiB0aGUgSFJlZ2lvbkluZm8gb2YgdGhlIHJlZ2lvbi4KKyAgICogVE9ETzogVXNlIFZpc2l0b3IgcmF0aGVyIHRoYW4gTGlzdGVuZXIgcGF0dGVybi4gIEFsbG93IG11bHRpcGxlIFZpc2l0b3JzLgorICAgKiBVc2UgdGhpcyBldmVyeXdoZXJlIHdlIHNjYW4gbWV0YSByZWdpb25zOiBlLmcuIGluIG1ldGFzY2FubmVycywgaW4gY2xvc2UKKyAgICogaGFuZGxpbmcsIGV0Yy4gIEhhdmUgaXQgcGFzcyBpbiB0aGUgd2hvbGUgcm93LCBub3QganVzdCBIUmVnaW9uSW5mby4KKyAgICogCisgICAqIEBwYXJhbSBtZXRhUmVnaW9uSW5mbyBIUmVnaW9uSW5mbyBmb3IgbWV0YSByZWdpb24KKyAgICogQHBhcmFtIGxpc3RlbmVyIG1ldGhvZCB0byBiZSBjYWxsZWQgZm9yIGVhY2ggbWV0YSByZWdpb24gZm91bmQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2Nhbk1ldGFSZWdpb24oSFJlZ2lvbkluZm8gbWV0YVJlZ2lvbkluZm8sCisgICAgU2Nhbm5lckxpc3RlbmVyIGxpc3RlbmVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIE9wZW4gbWV0YSByZWdpb24gc28gd2UgY2FuIHNjYW4gaXQKKyAgICBIUmVnaW9uIG1ldGFSZWdpb24gPSBvcGVuTWV0YVJlZ2lvbihtZXRhUmVnaW9uSW5mbyk7CisgICAgc2Nhbk1ldGFSZWdpb24obWV0YVJlZ2lvbiwgbGlzdGVuZXIpOworICB9CisKKyAgLyoqCisgICAqIFNjYW4gdGhlIHBhc3NlZCBpbiBtZXRhcmVnaW9uIDxjb2RlPm08L2NvZGU+IGludm9raW5nIHRoZSBwYXNzZWQKKyAgICogPGNvZGU+bGlzdGVuZXI8L2NvZGU+IHBlciByb3cgZm91bmQuCisgICAqIEBwYXJhbSBtCisgICAqIEBwYXJhbSBsaXN0ZW5lcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBzY2FuTWV0YVJlZ2lvbihmaW5hbCBIUmVnaW9uIG0sIGZpbmFsIFNjYW5uZXJMaXN0ZW5lciBsaXN0ZW5lcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnRlcm5hbFNjYW5uZXIgbWV0YVNjYW5uZXIgPSBtLmdldFNjYW5uZXIoSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GT19BUlJBWSwKKyAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgIHRyeSB7CisgICAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIHdoaWxlIChtZXRhU2Nhbm5lci5uZXh0KHJlc3VsdHMpKSB7CisgICAgICAgIEhSZWdpb25JbmZvIGluZm8gPSBudWxsOworICAgICAgICBmb3IgKEtleVZhbHVlIGt2OiByZXN1bHRzKSB7CisgICAgICAgICAgaWYgKEtleVZhbHVlLk1FVEFfQ09NUEFSQVRPUi5jb21wYXJlQ29sdW1ucyhrdiwKKyAgICAgICAgICAgIEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8sIDAsIEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8ubGVuZ3RoLAorICAgICAgICAgICAgICBIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFlfU1RSLmxlbmd0aCgpKSA9PSAwKSB7CisgICAgICAgICAgICBpbmZvID0gV3JpdGFibGVzLmdldEhSZWdpb25JbmZvT3JOdWxsKGt2LmdldFZhbHVlKCkpOworICAgICAgICAgICAgaWYgKGluZm8gPT0gbnVsbCkgeworICAgICAgICAgICAgICBMT0cud2FybigicmVnaW9uIGluZm8gaXMgbnVsbCBmb3Igcm93ICIgKworICAgICAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGt2LmdldFJvdygpKSArCisgICAgICAgICAgICAgICAgIiBpbiB0YWJsZSAiICsgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmICghbGlzdGVuZXIucHJvY2Vzc1JvdyhpbmZvKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHJlc3VsdHMuY2xlYXIoKTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgbWV0YVNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN5bmNocm9uaXplZCBIUmVnaW9uIG9wZW5Sb290UmVnaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5yb290UmVnaW9uICE9IG51bGwpIHsKKyAgICAgIHJldHVybiB0aGlzLnJvb3RSZWdpb247CisgICAgfQorICAgIHRoaXMucm9vdFJlZ2lvbiA9IEhSZWdpb24ub3BlbkhSZWdpb24oSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLAorICAgICAgdGhpcy5yb290ZGlyLCBnZXRMb2coKSwgdGhpcy5jb25mKTsKKyAgICB0aGlzLnJvb3RSZWdpb24uY29tcGFjdFN0b3JlcygpOworICAgIHJldHVybiB0aGlzLnJvb3RSZWdpb247CisgIH0KKworICBwcml2YXRlIEhSZWdpb24gb3Blbk1ldGFSZWdpb24oSFJlZ2lvbkluZm8gbWV0YUluZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiBtZXRhID0KKyAgICAgIEhSZWdpb24ub3BlbkhSZWdpb24obWV0YUluZm8sIHRoaXMucm9vdGRpciwgZ2V0TG9nKCksIHRoaXMuY29uZik7CisgICAgbWV0YS5jb21wYWN0U3RvcmVzKCk7CisgICAgcmV0dXJuIG1ldGE7CisgIH0KKyAKKyAgLyoqCisgICAqIFNldCBhIHNpbmdsZSByZWdpb24gb24vb2ZmbGluZS4KKyAgICogVGhpcyBpcyBhIHRvb2wgdG8gcmVwYWlyIHRhYmxlcyB0aGF0IGhhdmUgb2ZmbGluZWQgdGFibGVzIGluIHRoZWlyIG1pZHN0LgorICAgKiBDYW4gaGFwcGVuIG9uIG9jY2FzaW9uLiAgVXNlIGF0IHlvdXIgb3duIHJpc2suICBDYWxsIGZyb20gYSBiaXQgb2YgamF2YQorICAgKiBvciBqeXRob24gc2NyaXB0LiAgVGhpcyBtZXRob2QgaXMgJ2V4cGVuc2l2ZScgaW4gdGhhdCBpdCBjcmVhdGVzIGEKKyAgICoge0BsaW5rIEhUYWJsZX0gaW5zdGFuY2UgcGVyIGludm9jYXRpb24gdG8gZ28gYWdhaW5zdCA8Y29kZT4uTUVUQS48L2NvZGU+CisgICAqIEBwYXJhbSBjIEEgY29uZmlndXJhdGlvbiB0aGF0IGhhcyBpdHMgPGNvZGU+aGJhc2UubWFzdGVyPC9jb2RlPgorICAgKiBwcm9wZXJseSBzZXQuCisgICAqIEBwYXJhbSByb3cgUm93IGluIHRoZSBjYXRhbG9nIC5NRVRBLiB0YWJsZSB3aG9zZSBIUmVnaW9uSW5mbydzIG9mZmxpbmUKKyAgICogc3RhdHVzIHdlIHdhbnQgdG8gY2hhbmdlLgorICAgKiBAcGFyYW0gb25saW5lT2ZmbGluZSBQYXNzIDxjb2RlPnRydWU8L2NvZGU+IHRvIE9GRkxJTkUgdGhlIHJlZ2lvbi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGNoYW5nZU9ubGluZVN0YXR1cyAoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGMsCisgICAgICBmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYm9vbGVhbiBvbmxpbmVPZmZsaW5lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZSB0ID0gbmV3IEhUYWJsZShjLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSk7CisgICAgQ2VsbCBjZWxsID0gdC5nZXQocm93LCBIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKTsKKyAgICBpZiAoY2VsbCA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIm5vIGluZm9ybWF0aW9uIGZvciByb3cgIiArIEJ5dGVzLnRvU3RyaW5nKHJvdykpOworICAgIH0KKyAgICAvLyBUaHJvd3MgZXhjZXB0aW9uIGlmIG51bGwuCisgICAgSFJlZ2lvbkluZm8gaW5mbyA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mbyhjZWxsKTsKKyAgICBCYXRjaFVwZGF0ZSBiID0gbmV3IEJhdGNoVXBkYXRlKHJvdyk7CisgICAgaW5mby5zZXRPZmZsaW5lKG9ubGluZU9mZmxpbmUpOworICAgIGIucHV0KEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8sIFdyaXRhYmxlcy5nZXRCeXRlcyhpbmZvKSk7CisgICAgYi5kZWxldGUoSENvbnN0YW50cy5DT0xfU0VSVkVSKTsKKyAgICBiLmRlbGV0ZShIQ29uc3RhbnRzLkNPTF9TVEFSVENPREUpOworICAgIHQuY29tbWl0KGIpOworICB9CisgIAorICAvKioKKyAgICogT2ZmbGluZSB2ZXJzaW9uIG9mIHRoZSBvbmxpbmUgVGFibGVPcGVyYXRpb24sCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3Rlci5BZGRDb2x1bW4uCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIGhjZCBBZGQgdGhpcyBjb2x1bW4gdG8gPGNvZGU+dGFibGVOYW1lPC9jb2RlPgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkQ29sdW1uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgSENvbHVtbkRlc2NyaXB0b3IgaGNkKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIExpc3Q8SFJlZ2lvbkluZm8+IG1ldGFzID0gZ2V0TUVUQVJvd3ModGFibGVOYW1lKTsKKyAgICBmb3IgKEhSZWdpb25JbmZvIGhyaTogbWV0YXMpIHsKKyAgICAgIGZpbmFsIEhSZWdpb24gbSA9IGdldE1ldGFSZWdpb24oaHJpKTsKKyAgICAgIHNjYW5NZXRhUmVnaW9uKG0sIG5ldyBTY2FubmVyTGlzdGVuZXIoKSB7CisgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpblRhYmxlID0gdHJ1ZTsKKyAgICAgICAgCisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKKyAgICAgICAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc1JvdyhIUmVnaW9uSW5mbyBpbmZvKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgIExPRy5kZWJ1ZygiVGVzdGluZyAiICsgQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSArICIgYWdhaW5zdCAiICsKKyAgICAgICAgICAgIEJ5dGVzLnRvU3RyaW5nKGluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpKSk7CisgICAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgdGFibGVOYW1lKSkgeworICAgICAgICAgICAgdGhpcy5pblRhYmxlID0gZmFsc2U7CisgICAgICAgICAgICBpbmZvLmdldFRhYmxlRGVzYygpLmFkZEZhbWlseShoY2QpOworICAgICAgICAgICAgdXBkYXRlTUVUQVJlZ2lvbkluZm8obSwgaW5mbyk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gSWYgd2UgZ290IGhlcmUgYW5kIHdlIGhhdmUgbm90IHlldCBlbmNvdW50ZXJlZCB0aGUgdGFibGUgeWV0LAorICAgICAgICAgIC8vIGluVGFibGUgd2lsbCBiZSBmYWxzZS4gIE90aGVyd2lzZSwgd2UndmUgcGFzc2VkIG91dCB0aGUgdGFibGUuCisgICAgICAgICAgLy8gU3RvcCB0aGUgc2Nhbm5lci4KKyAgICAgICAgICByZXR1cm4gdGhpcy5pblRhYmxlOworICAgICAgICB9fSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogT2ZmbGluZSB2ZXJzaW9uIG9mIHRoZSBvbmxpbmUgVGFibGVPcGVyYXRpb24sCisgICAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3Rlci5EZWxldGVDb2x1bW4uCisgICAqIEBwYXJhbSB0YWJsZU5hbWUKKyAgICogQHBhcmFtIGNvbHVtbkZhbWlseSBOYW1lIG9mIGNvbHVtbiBuYW1lIHRvIHJlbW92ZS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlQ29sdW1uKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lLAorICAgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW5GYW1pbHkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTGlzdDxIUmVnaW9uSW5mbz4gbWV0YXMgPSBnZXRNRVRBUm93cyh0YWJsZU5hbWUpOworICAgIGZvciAoSFJlZ2lvbkluZm8gaHJpOiBtZXRhcykgeworICAgICAgZmluYWwgSFJlZ2lvbiBtID0gZ2V0TWV0YVJlZ2lvbihocmkpOworICAgICAgc2Nhbk1ldGFSZWdpb24obSwgbmV3IFNjYW5uZXJMaXN0ZW5lcigpIHsKKyAgICAgICAgcHJpdmF0ZSBib29sZWFuIGluVGFibGUgPSB0cnVlOworICAgICAgICAKKyAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQorICAgICAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KEhSZWdpb25JbmZvIGluZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhpbmZvLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgdGFibGVOYW1lKSkgeworICAgICAgICAgICAgdGhpcy5pblRhYmxlID0gZmFsc2U7CisgICAgICAgICAgICBpbmZvLmdldFRhYmxlRGVzYygpLnJlbW92ZUZhbWlseShjb2x1bW5GYW1pbHkpOworICAgICAgICAgICAgdXBkYXRlTUVUQVJlZ2lvbkluZm8obSwgaW5mbyk7CisgICAgICAgICAgICBQYXRoIHRhYmxlZGlyID0gbmV3IFBhdGgocm9vdGRpciwKKyAgICAgICAgICAgICAgaW5mby5nZXRUYWJsZURlc2MoKS5nZXROYW1lQXNTdHJpbmcoKSk7CisgICAgICAgICAgICBQYXRoIHAgPSBTdG9yZS5nZXRTdG9yZUhvbWVkaXIodGFibGVkaXIsIGluZm8uZ2V0RW5jb2RlZE5hbWUoKSwKKyAgICAgICAgICAgICAgY29sdW1uRmFtaWx5KTsKKyAgICAgICAgICAgIGlmICghZnMuZGVsZXRlKHAsIHRydWUpKSB7CisgICAgICAgICAgICAgIExPRy53YXJuKCJGYWlsZWQgZGVsZXRlIG9mICIgKyBwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gSWYgd2UgZ290IGhlcmUgYW5kIHdlIGhhdmUgbm90IHlldCBlbmNvdW50ZXJlZCB0aGUgdGFibGUgeWV0LAorICAgICAgICAgIC8vIGluVGFibGUgd2lsbCBiZSBmYWxzZS4gIE90aGVyd2lzZSwgd2UndmUgcGFzc2VkIG91dCB0aGUgdGFibGUuCisgICAgICAgICAgLy8gU3RvcCB0aGUgc2Nhbm5lci4KKyAgICAgICAgICByZXR1cm4gdGhpcy5pblRhYmxlOworICAgICAgICB9fSk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogVXBkYXRlIENPTF9SRUdJT05JTkZPIGluIG1ldGEgcmVnaW9uIHIgd2l0aCBIUmVnaW9uSW5mbyBocmkKKyAgICogCisgICAqIEBwYXJhbSByCisgICAqIEBwYXJhbSBocmkKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdXBkYXRlTUVUQVJlZ2lvbkluZm8oSFJlZ2lvbiByLCBmaW5hbCBIUmVnaW9uSW5mbyBocmkpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChMT0cuaXNEZWJ1Z0VuYWJsZWQoKSkgeworICAgICAgSFJlZ2lvbkluZm8gaCA9IFdyaXRhYmxlcy5nZXRIUmVnaW9uSW5mb09yTnVsbCgKKyAgICAgICAgci5nZXQoaHJpLmdldFJlZ2lvbk5hbWUoKSwgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgLTEsIC0xKS5nZXQoMCkuZ2V0VmFsdWUoKSk7CisgICAgICBMT0cuZGVidWcoIk9sZCAiICsgQnl0ZXMudG9TdHJpbmcoSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTykgKworICAgICAgICAiIGZvciAiICsgaHJpLnRvU3RyaW5nKCkgKyAiIGluICIgKyByLnRvU3RyaW5nKCkgKyAiIGlzOiAiICsKKyAgICAgICAgaC50b1N0cmluZygpKTsKKyAgICB9CisgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShocmkuZ2V0UmVnaW9uTmFtZSgpKTsKKyAgICBiLnB1dChIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPLCBXcml0YWJsZXMuZ2V0Qnl0ZXMoaHJpKSk7CisgICAgci5iYXRjaFVwZGF0ZShiLCBudWxsKTsKKyAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgIEhSZWdpb25JbmZvIGggPSBXcml0YWJsZXMuZ2V0SFJlZ2lvbkluZm9Pck51bGwoCisgICAgICAgICAgci5nZXQoaHJpLmdldFJlZ2lvbk5hbWUoKSwgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgLTEsIC0xKS5nZXQoMCkuZ2V0VmFsdWUoKSk7CisgICAgICAgIExPRy5kZWJ1ZygiTmV3ICIgKyBCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKSArCisgICAgICAgICAgIiBmb3IgIiArIGhyaS50b1N0cmluZygpICsgIiBpbiAiICsgci50b1N0cmluZygpICsgIiBpczogIiArCisgICAgICAgICAgaC50b1N0cmluZygpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBMaXN0IG9mIHtAbGluayBIUmVnaW9uSW5mb30gcm93cyBmb3VuZCBpbiB0aGUgUk9PVCBvciBNRVRBCisgICAqIGNhdGFsb2cgdGFibGUuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgTmFtZSBvZiB0YWJsZSB0byBnbyBsb29raW5nIGZvci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAc2VlICNnZXRNZXRhUmVnaW9uKEhSZWdpb25JbmZvKQorICAgKi8KKyAgcHVibGljIExpc3Q8SFJlZ2lvbkluZm8+IGdldE1FVEFSb3dzKGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIExpc3Q8SFJlZ2lvbkluZm8+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8SFJlZ2lvbkluZm8+KCk7CisgICAgLy8gSWYgcGFzc2VkIHRhYmxlIG5hbWUgaXMgTUVUQSwgdGhlbiAgcmV0dXJuIHRoZSByb290IHJlZ2lvbi4KKyAgICBpZiAoQnl0ZXMuZXF1YWxzKEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FLCB0YWJsZU5hbWUpKSB7CisgICAgICByZXN1bHQuYWRkKG9wZW5Sb290UmVnaW9uKCkuZ2V0UmVnaW9uSW5mbygpKTsKKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIC8vIFJldHVybiBhbGwgbWV0YSByZWdpb25zIHRoYXQgY29udGFpbiB0aGUgcGFzc2VkIHRhYmxlbmFtZS4KKyAgICBzY2FuUm9vdFJlZ2lvbihuZXcgU2Nhbm5lckxpc3RlbmVyKCkgeworICAgICAgcHJpdmF0ZSBmaW5hbCBMb2cgU0xfTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpKTsKKyAgICAgIAorICAgICAgcHVibGljIGJvb2xlYW4gcHJvY2Vzc1JvdyhIUmVnaW9uSW5mbyBpbmZvKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBTTF9MT0cuZGVidWcoIlRlc3RpbmcgIiArIGluZm8pOworICAgICAgICBpZiAoQnl0ZXMuZXF1YWxzKGluZm8uZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLAorICAgICAgICAgICAgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpKSB7CisgICAgICAgICAgcmVzdWx0LmFkZChpbmZvKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9fSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBuIFRhYmxlIG5hbWUuCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBhIGNhdGFsb2cgdGFibGUsIC1ST09ULSBvciAuTUVUQS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc01ldGFUYWJsZU5hbWUoZmluYWwgYnl0ZSBbXSBuKSB7CisgICAgcmV0dXJuIEJ5dGVzLmVxdWFscyhuLCBIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSkgfHwKKyAgICAgIEJ5dGVzLmVxdWFscyhuLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01pZ3JhdGUuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvTWlncmF0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwYzc0MTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01pZ3JhdGUuamF2YQpAQCAtMCwwICsxLDM2NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY2xpLk9wdGlvbnM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmVkOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5NYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuR2VuZXJpY09wdGlvbnNQYXJzZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Ub29sOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVG9vbFJ1bm5lcjsKKworLyoqCisgKiBQZXJmb3JtIGEgbWlncmF0aW9uLgorICogSEJhc2Uga2VlcHMgYSBmaWxlIGluIGhkZnMgbmFtZWQgaGJhc2UudmVyc2lvbiBqdXN0IHVuZGVyIHRoZSBoYmFzZS5yb290ZGlyLgorICogVGhpcyBmaWxlIGhvbGRzIHRoZSB2ZXJzaW9uIG9mIHRoZSBoYmFzZSBkYXRhIGluIHRoZSBGaWxlc3lzdGVtLiAgV2hlbiB0aGUKKyAqIHNvZnR3YXJlIGNoYW5nZXMgaW4gYSBtYW5uZXIgaW5jb21wYXRpYmxlIHdpdGggdGhlIGRhdGEgaW4gdGhlIEZpbGVzeXN0ZW0sCisgKiBpdCB1cGRhdGVzIGl0cyBpbnRlcm5hbCB2ZXJzaW9uIG51bWJlciwKKyAqIHtAbGluayBIQ29uc3RhbnRzI0ZJTEVfU1lTVEVNX1ZFUlNJT059LiAgVGhpcyB3cmFwcGVyIHNjcmlwdCBtYW5hZ2VzIG1vdmluZworICogdGhlIGZpbGVzeXN0ZW0gYWNyb3NzIHZlcnNpb25zIHVudGlsIHRoZXJlJ3MgYSBtYXRjaCB3aXRoIGN1cnJlbnQgc29mdHdhcmUncworICogdmVyc2lvbiBudW1iZXIuICBUaGlzIHNjcmlwdCB3aWxsIG9ubHkgY3Jvc3MgYSBwYXJ0aWN1bGFyIHZlcnNpb24gZGl2aWRlLiAgWW91IG1heQorICogbmVlZCB0byBpbnN0YWxsIGVhcmxpZXIgb3IgbGF0ZXIgaGJhc2UgdG8gbWlncmF0ZSBlYXJsaWVyIChvciBvbGRlcikgdmVyc2lvbnMuCisgKiAKKyAqIDxwPlRoaXMgd3JhcHBlciBzY3JpcHQgY29tcHJpc2VzIGEgc2V0IG9mIG1pZ3JhdGlvbiBzdGVwcy4gIFdoaWNoIHN0ZXBzCisgKiBhcmUgcnVuIGRlcGVuZHMgb24gdGhlIHNwYW4gYmV0d2VlbiB0aGUgdmVyc2lvbiBvZiB0aGUgaGJhc2UgZGF0YSBpbiB0aGUKKyAqIEZpbGVzeXN0ZW0gYW5kIHRoZSB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IHNvZnRhcmUuCisgKiAKKyAqIDxwPkEgbWlncmF0aW9uIHNjcmlwdCBtdXN0IGFjY29tcGFueSBhbnkgcGF0Y2ggdGhhdCBjaGFuZ2VzIGRhdGEgZm9ybWF0cy4KKyAqIAorICogPHA+VGhpcyBzY3JpcHQgaGFzIGEgJ2NoZWNrJyBhbmQgJ2V4ZWN1dGUnIG1vZGUuICBBZGRpbmcgbWlncmF0aW9uIHN0ZXBzLAorICogaXRzIGltcG9ydGFudCB0byBrZWVwIHRoaXMgaW4gbWluZC4gIFRlc3RpbmcgaWYgbWlncmF0aW9uIG5lZWRzIHRvIGJlIHJ1biwKKyAqIGJlIGNhcmVmdWwgbm90IHRvIG1ha2UgcHJlc3VtcHRpb25zIGFib3V0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkYXRhIGluCisgKiB0aGUgZmlsZXN5c3RlbS4gIEl0IG1heSBoYXZlIGEgZm9ybWF0IGZyb20gbWFueSB2ZXJzaW9ucyBwcmV2aW91cyB3aXRoCisgKiBsYXlvdXQgbm90IGFzIGV4cGVjdGVkIG9yIGtleXMgYW5kIHZhbHVlcyBvZiBhIGZvcm1hdCBub3QgZXhwZWN0ZWQuICBUb29scworICogc3VjaCBhcyB7QGxpbmsgTWV0YVV0aWxzfSBtYXkgbm90IHdvcmsgYXMgZXhwZWN0ZWQgd2hlbiBydW5uaW5nIGFnYWluc3QKKyAqIG9sZCBmb3JtYXRzIC0tIG9yLCB3b3JzZSwgZmFpbCBpbiB3YXlzIHRoYXQgYXJlIGhhcmQgdG8gZmlndXJlIChPbmUgc3VjaCBpcworICogZWRpdHMgbWFkZSBieSBwcmV2aW91cyBtaWdyYXRpb24gc3RlcHMgbm90IGJlaW5nIGFwcGFyZW50IGluIGxhdGVyIG1pZ3JhdGlvbgorICogc3RlcHMpLiAgVGhlIHVwc2hvdCBpcyBhbHdheXMgdmVyaWZ5IHByZXN1bXB0aW9ucyBtaWdyYXRpbmcuCisgKiAKKyAqIDxwPlRoaXMgc2NyaXB0IHdpbGwgbWlncmF0ZSBhbiBoYmFzZSAwLjE4Lnggb25seS4KKyAqIAorICogQHNlZSA8YSBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZS9Ib3dUb01pZ3JhdGUiPkhvdyBUbyBNaWdyYXRpb248L2E+CisgKi8KK3B1YmxpYyBjbGFzcyBNaWdyYXRlIGV4dGVuZHMgQ29uZmlndXJlZCBpbXBsZW1lbnRzIFRvb2wgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWlncmF0ZS5jbGFzcyk7CisgIHByaXZhdGUgZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisgIHByaXZhdGUgRmlsZVN5c3RlbSBmczsKKyAgCisgIC8vIEdldHMgc2V0IGJ5IG1pZ3JhdGlvbiBtZXRob2RzIGlmIHdlIGFyZSBpbiByZWFkT25seSBtb2RlLgorICBib29sZWFuIG1pZ3JhdGlvbk5lZWRlZCA9IGZhbHNlOworCisgIGJvb2xlYW4gcmVhZE9ubHkgPSBmYWxzZTsKKworICAvLyBGaWxlc3lzdGVtIHZlcnNpb24gb2YgaGJhc2UgMC4xLnguCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGZsb2F0IEhCQVNFXzBfMV9WRVJTSU9OID0gMC4xZjsKKyAgCisgIC8vIEZpbGVzeXN0ZW0gdmVyc2lvbiB3ZSBjYW4gbWlncmF0ZSBmcm9tCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBQUkVWSU9VU19WRVJTSU9OID0gNDsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNSUdSQVRJT05fTElOSyA9IAorICAgICIgU2VlIGh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlL0hvd1RvTWlncmF0ZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4iOworCisgIC8qKiBkZWZhdWx0IGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBNaWdyYXRlKCkgeworICAgIHRoaXMobmV3IEhCYXNlQ29uZmlndXJhdGlvbigpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBjb25mCisgICAqLworICBwdWJsaWMgTWlncmF0ZShIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgeworICAgIHN1cGVyKGNvbmYpOworICAgIHRoaXMuY29uZiA9IGNvbmY7CisgIH0KKyAgCisgIC8qCisgICAqIFNldHMgdGhlIGhiYXNlIHJvb3RkaXIgYXMgZnMuZGVmYXVsdC5uYW1lLgorICAgKiBAcmV0dXJuIFRydWUgaWYgc3VjY2VlZGVkLgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIHNldEZzRGVmYXVsdE5hbWUoKSB7CisgICAgLy8gVmFsaWRhdGUgcm9vdCBkaXJlY3RvcnkgcGF0aAorICAgIFBhdGggcmQgPSBuZXcgUGF0aChjb25mLmdldChIQ29uc3RhbnRzLkhCQVNFX0RJUikpOworICAgIHRyeSB7CisgICAgICAvLyBWYWxpZGF0ZSByb290IGRpcmVjdG9yeSBwYXRoCisgICAgICBGU1V0aWxzLnZhbGlkYXRlUm9vdFBhdGgocmQpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiTm90IHN0YXJ0aW5nIG1pZ3JhdGlvbiBiZWNhdXNlIHRoZSByb290IGRpcmVjdG9yeSBwYXRoICciICsKKyAgICAgICAgICByZC50b1N0cmluZygpICsgIicgaXMgbm90IHZhbGlkLiBDaGVjayB0aGUgc2V0dGluZyBvZiB0aGUiICsKKyAgICAgICAgICAiIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyICciICsgSENvbnN0YW50cy5IQkFTRV9ESVIgKyAiJyIsIGUpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB0aGlzLmNvbmYuc2V0KCJmcy5kZWZhdWx0Lm5hbWUiLCByZC50b1N0cmluZygpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBzdWNjZWVkZWQgdmVyaWZ5aW5nIGZpbGVzeXN0ZW0uCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gdmVyaWZ5RmlsZXN5c3RlbSgpIHsKKyAgICB0cnkgeworICAgICAgLy8gVmVyaWZ5IGZpbGUgc3lzdGVtIGlzIHVwLgorICAgICAgZnMgPSBGaWxlU3lzdGVtLmdldChjb25mKTsgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgREZTIGhhbmRsZQorICAgICAgTE9HLmluZm8oIlZlcmlmeWluZyB0aGF0IGZpbGUgc3lzdGVtIGlzIGF2YWlsYWJsZS4uIik7CisgICAgICBGU1V0aWxzLmNoZWNrRmlsZVN5c3RlbUF2YWlsYWJsZShmcyk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoIkZpbGUgc3lzdGVtIGlzIG5vdCBhdmFpbGFibGUiLCBlKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgYm9vbGVhbiBub3RSdW5uaW5nKCkgeworICAgIC8vIFZlcmlmeSBIQmFzZSBpcyBkb3duCisgICAgTE9HLmluZm8oIlZlcmlmeWluZyB0aGF0IEhCYXNlIGlzIG5vdCBydW5uaW5nLi4uLiIgKworICAgICAgICAgICJUcnlzIHRlbiB0aW1lcyAgdG8gY29ubmVjdCB0byBydW5uaW5nIG1hc3RlciIpOworICAgIHRyeSB7CisgICAgICBIQmFzZUFkbWluLmNoZWNrSEJhc2VBdmFpbGFibGUoY29uZik7CisgICAgICBMT0cuZmF0YWwoIkhCYXNlIGNsdXN0ZXIgbXVzdCBiZSBvZmYtbGluZS4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGNhdGNoIChNYXN0ZXJOb3RSdW5uaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIGludCBydW4oU3RyaW5nW10gYXJncykgeworICAgIGlmIChwYXJzZUFyZ3MoYXJncykgIT0gMCkgeworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIXNldEZzRGVmYXVsdE5hbWUoKSkgeworICAgICAgcmV0dXJuIC0yOworICAgIH0KKyAgICBpZiAoIXZlcmlmeUZpbGVzeXN0ZW0oKSkgeworICAgICAgcmV0dXJuIC0zOworICAgIH0KKyAgICBpZiAoIW5vdFJ1bm5pbmcoKSkgeworICAgICAgcmV0dXJuIC00OworICAgIH0KKworICAgIHRyeSB7CisgICAgICBMT0cuaW5mbygiU3RhcnRpbmcgdXBncmFkZSIgKyAocmVhZE9ubHkgPyAiIGNoZWNrIiA6ICIiKSk7CisKKyAgICAgIC8vIFNlZSBpZiB0aGVyZSBpcyBhIGZpbGUgc3lzdGVtIHZlcnNpb24gZmlsZQorICAgICAgU3RyaW5nIHZlcnNpb25TdHIgPSBGU1V0aWxzLmdldFZlcnNpb24oZnMsIEZTVXRpbHMuZ2V0Um9vdERpcih0aGlzLmNvbmYpKTsKKyAgICAgIGlmICh2ZXJzaW9uU3RyID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGaWxlIHN5c3RlbSB2ZXJzaW9uIGZpbGUgIiArCisgICAgICAgICAgICBIQ29uc3RhbnRzLlZFUlNJT05fRklMRV9OQU1FICsKKyAgICAgICAgICAgICIgZG9lcyBub3QgZXhpc3QuIE5vIHVwZ3JhZGUgcG9zc2libGUuIiArIE1JR1JBVElPTl9MSU5LKTsKKyAgICAgIH0KKyAgICAgIGlmICh2ZXJzaW9uU3RyLmNvbXBhcmVUbyhIQ29uc3RhbnRzLkZJTEVfU1lTVEVNX1ZFUlNJT04pID09IDApIHsKKyAgICAgICAgTE9HLmluZm8oIk5vIHVwZ3JhZGUgbmVjZXNzYXJ5LiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGZsb2F0IHZlcnNpb24gPSBGbG9hdC5wYXJzZUZsb2F0KHZlcnNpb25TdHIpOworICAgICAgaWYgKHZlcnNpb24gPT0gSEJBU0VfMF8xX1ZFUlNJT04gfHwKKyAgICAgICAgICBJbnRlZ2VyLnZhbHVlT2YodmVyc2lvblN0cikuaW50VmFsdWUoKSA8IFBSRVZJT1VTX1ZFUlNJT04pIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9ICJDYW5ub3QgdXBncmFkZSBmcm9tICIgKyB2ZXJzaW9uU3RyICsgIiB0byAiICsKKyAgICAgICAgSENvbnN0YW50cy5GSUxFX1NZU1RFTV9WRVJTSU9OICsgIiB5b3UgbXVzdCBpbnN0YWxsIGhiYXNlLTAuMi54LCBydW4gIiArCisgICAgICAgICJ0aGUgdXBncmFkZSB0b29sLCByZWluc3RhbGwgdGhpcyB2ZXJzaW9uIGFuZCBydW4gdGhpcyB1dGlsaXR5IGFnYWluLiIgKworICAgICAgICBNSUdSQVRJT05fTElOSzsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG1zZyk7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihtc2cpOworICAgICAgfQorCisgICAgICBtaWdyYXRlNFRvNigpOworCisgICAgICBpZiAoIXJlYWRPbmx5KSB7CisgICAgICAgIC8vIFNldCBmaWxlIHN5c3RlbSB2ZXJzaW9uCisgICAgICAgIExPRy5pbmZvKCJTZXR0aW5nIGZpbGUgc3lzdGVtIHZlcnNpb24uIik7CisgICAgICAgIEZTVXRpbHMuc2V0VmVyc2lvbihmcywgRlNVdGlscy5nZXRSb290RGlyKHRoaXMuY29uZikpOworICAgICAgICBMT0cuaW5mbygiVXBncmFkZSBzdWNjZXNzZnVsLiIpOworICAgICAgfSBlbHNlIGlmICh0aGlzLm1pZ3JhdGlvbk5lZWRlZCkgeworICAgICAgICBMT0cuaW5mbygiVXBncmFkZSBuZWVkZWQuIik7CisgICAgICB9CisgICAgICByZXR1cm4gMDsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmZhdGFsKCJVcGdyYWRlIiArICAocmVhZE9ubHkgPyAiIGNoZWNrIiA6ICIiKSArICIgZmFpbGVkIiwgZSk7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICB9CisgIAorICAvLyBNb3ZlIHRoZSBmaWxleXN0ZW0gdmVyc2lvbiBmcm9tIDQgdG8gNi4KKyAgLy8gSW4gaGVyZSB3ZSByZXdyaXRlIHRoZSBjYXRhbG9nIHRhYmxlIHJlZ2lvbnMgc28gdGhleSBrZWVwIDEwIHZlcnNpb25zCisgIC8vIGluc3RlYWQgb2YgMS4KKyAgcHJpdmF0ZSB2b2lkIG1pZ3JhdGU0VG82KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5yZWFkT25seSAmJiB0aGlzLm1pZ3JhdGlvbk5lZWRlZCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBmaW5hbCBNZXRhVXRpbHMgdXRpbHMgPSBuZXcgTWV0YVV0aWxzKHRoaXMuY29uZik7CisgICAgdHJ5IHsKKyAgICAgIC8vIFRoZXNlIHR3byBvcGVyYXRpb25zIGFyZSBlZmZlY3RpdmVseSB1c2VsZXNzLiAgLVJPT1QtIGlzIGhhcmRjb2RlLAorICAgICAgLy8gYXQgbGVhc3QgdW50aWwgaGJhc2UgMC4yMC4wIHdoZW4gd2Ugc3RvcmUgaXQgb3V0IGluIFpLLgorICAgICAgdXBkYXRlVmVyc2lvbnModXRpbHMuZ2V0Um9vdFJlZ2lvbigpLmdldFJlZ2lvbkluZm8oKSk7CisgICAgICBlbmFibGVCbG9ja0NhY2hlKHV0aWxzLmdldFJvb3RSZWdpb24oKS5nZXRSZWdpb25JbmZvKCkpOworICAgICAgLy8gU2NhbiB0aGUgcm9vdCByZWdpb24KKyAgICAgIHV0aWxzLnNjYW5Sb290UmVnaW9uKG5ldyBNZXRhVXRpbHMuU2Nhbm5lckxpc3RlbmVyKCkgeworICAgICAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZXNzUm93KEhSZWdpb25JbmZvIGluZm8pCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgaWYgKHJlYWRPbmx5ICYmICFtaWdyYXRpb25OZWVkZWQpIHsKKyAgICAgICAgICAgIG1pZ3JhdGlvbk5lZWRlZCA9IHRydWU7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIHVwZGF0ZVZlcnNpb25zKHV0aWxzLmdldFJvb3RSZWdpb24oKSwgaW5mbyk7CisgICAgICAgICAgZW5hYmxlQmxvY2tDYWNoZSh1dGlscy5nZXRSb290UmVnaW9uKCksIGluZm8pOworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICB9KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdXRpbHMuc2h1dGRvd24oKTsKKyAgICB9CisgIH0KKworICAvKgorICAgKiBFbmFibGUgYmxvY2tjYWNoaW5nIG9uIGNhdGFsb2cgdGFibGVzLgorICAgKiBAcGFyYW0gbXIKKyAgICogQHBhcmFtIG9sZEhyaQorICAgKi8KKyAgdm9pZCBlbmFibGVCbG9ja0NhY2hlKEhSZWdpb24gbXIsIEhSZWdpb25JbmZvIG9sZEhyaSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWVuYWJsZUJsb2NrQ2FjaGUob2xkSHJpKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBCYXRjaFVwZGF0ZSBiID0gbmV3IEJhdGNoVXBkYXRlKG9sZEhyaS5nZXRSZWdpb25OYW1lKCkpOworICAgIGIucHV0KEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8sIFdyaXRhYmxlcy5nZXRCeXRlcyhvbGRIcmkpKTsKKyAgICBtci5iYXRjaFVwZGF0ZShiKTsKKyAgICBMT0cuaW5mbygiRW5hYmxlZCBibG9ja2NhY2hlIG9uICIgKyBvbGRIcmkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICB9CisKKyAgLyoKKyAgICogQHBhcmFtIGhyaSBVcGRhdGUgdmVyc2lvbnMuCisgICAqIEBwYXJhbSB0cnVlIGlmIHdlIGNoYW5nZWQgdmFsdWUKKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiBlbmFibGVCbG9ja0NhY2hlKGZpbmFsIEhSZWdpb25JbmZvIGhyaSkgeworICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisgICAgSENvbHVtbkRlc2NyaXB0b3IgaGNkID0KKyAgICAgIGhyaS5nZXRUYWJsZURlc2MoKS5nZXRGYW1pbHkoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKTsKKyAgICBpZiAoaGNkID09IG51bGwpIHsKKyAgICAgIExPRy5pbmZvKCJObyBpbmZvIGZhbWlseSBpbjogIiArIGhyaS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICAvLyBTZXQgYmxvY2tjYWNoZSBlbmFibGVkLgorICAgIGhjZC5zZXRCbG9ja0NhY2hlRW5hYmxlZCh0cnVlKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisKKyAgLyoKKyAgICogVXBkYXRlIHZlcnNpb25zIGtlcHQgaW4gaGlzdG9yaWFuLgorICAgKiBAcGFyYW0gbXIKKyAgICogQHBhcmFtIG9sZEhyaQorICAgKi8KKyAgdm9pZCB1cGRhdGVWZXJzaW9ucyhIUmVnaW9uIG1yLCBIUmVnaW9uSW5mbyBvbGRIcmkpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCF1cGRhdGVWZXJzaW9ucyhvbGRIcmkpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUob2xkSHJpLmdldFJlZ2lvbk5hbWUoKSk7CisgICAgYi5wdXQoSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgV3JpdGFibGVzLmdldEJ5dGVzKG9sZEhyaSkpOworICAgIG1yLmJhdGNoVXBkYXRlKGIpOworICAgIExPRy5pbmZvKCJVcHBlZCB2ZXJzaW9ucyBvbiAiICsgb2xkSHJpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpKTsKKyAgfQorCisgIC8qCisgICAqIEBwYXJhbSBocmkgVXBkYXRlIHZlcnNpb25zLgorICAgKiBAcGFyYW0gdHJ1ZSBpZiB3ZSBjaGFuZ2VkIHZhbHVlCisgICAqLworICBwcml2YXRlIGJvb2xlYW4gdXBkYXRlVmVyc2lvbnMoZmluYWwgSFJlZ2lvbkluZm8gaHJpKSB7CisgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBoY2QgPQorICAgICAgaHJpLmdldFRhYmxlRGVzYygpLmdldEZhbWlseShIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFlfSElTVE9SSUFOKTsKKyAgICBpZiAoaGNkID09IG51bGwpIHsKKyAgICAgIExPRy5pbmZvKCJObyByZWdpb24gaGlzdG9yaWFuIGZhbWlseSBpbjogIiArIGhyaS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSk7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICAvLyBTZXQgaGlzdG9yaWFuIHJlY29yZHMgc28gdGhleSB0aW1lb3V0IGFmdGVyIGEgd2Vlay4KKyAgICBpZiAoaGNkLmdldFRpbWVUb0xpdmUoKSA9PSBIQ29uc3RhbnRzLkZPUkVWRVIpIHsKKyAgICAgIGhjZC5zZXRUaW1lVG9MaXZlKEhDb25zdGFudHMuV0VFS19JTl9TRUNPTkRTKTsKKyAgICAgIHJlc3VsdCA9IHRydWU7CisgICAgfQorICAgIC8vIFNldCB0aGUgdmVyc2lvbnMgdXAgdG8gMTAgZnJvbSBvbGQgZGVmYXVsdCBvZiAxLgorICAgIGhjZCA9IGhyaS5nZXRUYWJsZURlc2MoKS5nZXRGYW1pbHkoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKTsKKyAgICBpZiAoaGNkLmdldE1heFZlcnNpb25zKCkgPT0gMSkgeworICAgICAgLy8gU2V0IGl0IHRvIDEwLCBhbiBhcmJpdHJhcnkgaGlnaCBudW1iZXIKKyAgICAgIGhjZC5zZXRNYXhWZXJzaW9ucygxMCk7CisgICAgICByZXN1bHQgPSB0cnVlOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcHJpdmF0ZSBpbnQgcGFyc2VBcmdzKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBPcHRpb25zIG9wdHMgPSBuZXcgT3B0aW9ucygpOworICAgIEdlbmVyaWNPcHRpb25zUGFyc2VyIHBhcnNlciA9CisgICAgICBuZXcgR2VuZXJpY09wdGlvbnNQYXJzZXIodGhpcy5nZXRDb25mKCksIG9wdHMsIGFyZ3MpOworICAgIFN0cmluZ1tdIHJlbWFpbmluZ0FyZ3MgPSBwYXJzZXIuZ2V0UmVtYWluaW5nQXJncygpOworICAgIGlmIChyZW1haW5pbmdBcmdzLmxlbmd0aCAhPSAxKSB7CisgICAgICB1c2FnZSgpOworICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAocmVtYWluaW5nQXJnc1swXS5jb21wYXJlVG8oImNoZWNrIikgPT0gMCkgeworICAgICAgdGhpcy5yZWFkT25seSA9IHRydWU7CisgICAgfSBlbHNlIGlmIChyZW1haW5pbmdBcmdzWzBdLmNvbXBhcmVUbygidXBncmFkZSIpICE9IDApIHsKKyAgICAgIHVzYWdlKCk7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisgIAorICBwcml2YXRlIHZvaWQgdXNhZ2UoKSB7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCJVc2FnZTogYmluL2hiYXNlIG1pZ3JhdGUge2NoZWNrIHwgdXBncmFkZX0gW29wdGlvbnNdIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCk7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgIGNoZWNrICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmZvcm0gdXBncmFkZSBjaGVja3Mgb25seS4iKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgdXBncmFkZSAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyZm9ybSB1cGdyYWRlIGNoZWNrcyBhbmQgbW9kaWZ5IGhiYXNlLiIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICBPcHRpb25zIGFyZToiKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgICAtY29uZiA8Y29uZmlndXJhdGlvbiBmaWxlPiAgICAgc3BlY2lmeSBhbiBhcHBsaWNhdGlvbiBjb25maWd1cmF0aW9uIGZpbGUiKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgICAtRCA8cHJvcGVydHk9dmFsdWU+ICAgICAgICAgICAgdXNlIHZhbHVlIGZvciBnaXZlbiBwcm9wZXJ0eSIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICAgIC1mcyA8bG9jYWx8bmFtZW5vZGU6cG9ydD4gICAgICBzcGVjaWZ5IGEgbmFtZW5vZGUiKTsKKyAgfQorCisgIC8qKgorICAgKiBNYWluIHByb2dyYW0KKyAgICogCisgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBpbnQgc3RhdHVzID0gMDsKKyAgICB0cnkgeworICAgICAgc3RhdHVzID0gVG9vbFJ1bm5lci5ydW4obmV3IE1pZ3JhdGUoKSwgYXJncyk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcihlKTsKKyAgICAgIHN0YXR1cyA9IC0xOworICAgIH0KKyAgICBTeXN0ZW0uZXhpdChzdGF0dXMpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9NdXJtdXJIYXNoLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL011cm11ckhhc2guamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjUwNGFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9NdXJtdXJIYXNoLmphdmEKQEAgLTAsMCArMSw4NCBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworLyoqCisgKiBUaGlzIGlzIGEgdmVyeSBmYXN0LCBub24tY3J5cHRvZ3JhcGhpYyBoYXNoIHN1aXRhYmxlIGZvciBnZW5lcmFsIGhhc2gtYmFzZWQKKyAqIGxvb2t1cC4gIFNlZSBodHRwOi8vbXVybXVyaGFzaC5nb29nbGVwYWdlcy5jb20vIGZvciBtb3JlIGRldGFpbHMuCisgKiAKKyAqIDxwPlRoZSBDIHZlcnNpb24gb2YgTXVybXVySGFzaCAyLjAgZm91bmQgYXQgdGhhdCBzaXRlIHdhcyBwb3J0ZWQKKyAqIHRvIEphdmEgYnkgQW5kcnplaiBCaWFsZWNraSAoYWIgYXQgZ2V0b3B0IG9yZykuPC9wPgorICovCitwdWJsaWMgY2xhc3MgTXVybXVySGFzaCBleHRlbmRzIEhhc2ggeworICBwcml2YXRlIHN0YXRpYyBNdXJtdXJIYXNoIF9pbnN0YW5jZSA9IG5ldyBNdXJtdXJIYXNoKCk7CisgIAorICBwdWJsaWMgc3RhdGljIEhhc2ggZ2V0SW5zdGFuY2UoKSB7CisgICAgcmV0dXJuIF9pbnN0YW5jZTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaChieXRlW10gZGF0YSwgaW50IGxlbmd0aCwgaW50IHNlZWQpIHsKKyAgICBpbnQgbSA9IDB4NWJkMWU5OTU7CisgICAgaW50IHIgPSAyNDsKKworICAgIGludCBoID0gc2VlZCBeIGxlbmd0aDsKKworICAgIGludCBsZW5fNCA9IGxlbmd0aCA+PiAyOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5fNDsgaSsrKSB7CisgICAgICBpbnQgaV80ID0gaSA8PCAyOworICAgICAgaW50IGsgPSBkYXRhW2lfNCArIDNdOworICAgICAgayA9IGsgPDwgODsKKyAgICAgIGsgPSBrIHwgKGRhdGFbaV80ICsgMl0gJiAweGZmKTsKKyAgICAgIGsgPSBrIDw8IDg7CisgICAgICBrID0gayB8IChkYXRhW2lfNCArIDFdICYgMHhmZik7CisgICAgICBrID0gayA8PCA4OworICAgICAgayA9IGsgfCAoZGF0YVtpXzQgKyAwXSAmIDB4ZmYpOworICAgICAgayAqPSBtOworICAgICAgayBePSBrID4+PiByOworICAgICAgayAqPSBtOworICAgICAgaCAqPSBtOworICAgICAgaCBePSBrOworICAgIH0KKworICAgIC8vIGF2b2lkIGNhbGN1bGF0aW5nIG1vZHVsbworICAgIGludCBsZW5fbSA9IGxlbl80IDw8IDI7CisgICAgaW50IGxlZnQgPSBsZW5ndGggLSBsZW5fbTsKKworICAgIGlmIChsZWZ0ICE9IDApIHsKKyAgICAgIGlmIChsZWZ0ID49IDMpIHsKKyAgICAgICAgaCBePSBkYXRhW2xlbmd0aCAtIDNdIDw8IDE2OworICAgICAgfQorICAgICAgaWYgKGxlZnQgPj0gMikgeworICAgICAgICBoIF49IGRhdGFbbGVuZ3RoIC0gMl0gPDwgODsKKyAgICAgIH0KKyAgICAgIGlmIChsZWZ0ID49IDEpIHsKKyAgICAgICAgaCBePSBkYXRhW2xlbmd0aCAtIDFdOworICAgICAgfQorCisgICAgICBoICo9IG07CisgICAgfQorCisgICAgaCBePSBoID4+PiAxMzsKKyAgICBoICo9IG07CisgICAgaCBePSBoID4+PiAxNTsKKworICAgIHJldHVybiBoOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1BhaXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvUGFpci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4ZjE3ZmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1BhaXIuamF2YQpAQCAtMCwwICsxLDk5IEBACitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKKworLyoqCisgKiBBIGdlbmVyaWMgY2xhc3MgZm9yIHBhaXJzLgorICogQHBhcmFtIDxUMT4gCisgKiBAcGFyYW0gPFQyPiAKKyAqLworcHVibGljIGNsYXNzIFBhaXI8VDEsIFQyPiBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZQoreworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMzk4NjI0NDYwNjU4NTU1MjU2OUw7CisgIHByb3RlY3RlZCBUMSBmaXJzdCA9IG51bGw7CisgIHByb3RlY3RlZCBUMiBzZWNvbmQgPSBudWxsOworCisgIC8qKgorICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgKi8KKyAgcHVibGljIFBhaXIoKQorICB7CisgIH0KKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogQHBhcmFtIGEKKyAgICogQHBhcmFtIGIKKyAgICovCisgIHB1YmxpYyBQYWlyKFQxIGEsIFQyIGIpCisgIHsKKyAgICB0aGlzLmZpcnN0ID0gYTsKKyAgICB0aGlzLnNlY29uZCA9IGI7CisgIH0KKworICAvKioKKyAgICogUmVwbGFjZSB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUgcGFpci4KKyAgICogQHBhcmFtIGEKKyAgICovCisgIHB1YmxpYyB2b2lkIHNldEZpcnN0KFQxIGEpCisgIHsKKyAgICB0aGlzLmZpcnN0ID0gYTsKKyAgfQorCisgIC8qKgorICAgKiBSZXBsYWNlIHRoZSBzZWNvbmQgZWxlbWVudCBvZiB0aGUgcGFpci4KKyAgICogQHBhcmFtIGIgCisgICAqLworICBwdWJsaWMgdm9pZCBzZXRTZWNvbmQoVDIgYikKKyAgeworICAgIHRoaXMuc2Vjb25kID0gYjsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIGZpcnN0IGVsZW1lbnQgc3RvcmVkIGluIHRoZSBwYWlyLgorICAgKiBAcmV0dXJuIFQxCisgICAqLworICBwdWJsaWMgVDEgZ2V0Rmlyc3QoKQorICB7CisgICAgcmV0dXJuIGZpcnN0OworICB9CisKKyAgLyoqCisgICAqIFJldHVybiB0aGUgc2Vjb25kIGVsZW1lbnQgc3RvcmVkIGluIHRoZSBwYWlyLgorICAgKiBAcmV0dXJuIFQyCisgICAqLworICBwdWJsaWMgVDIgZ2V0U2Vjb25kKCkKKyAgeworICAgIHJldHVybiBzZWNvbmQ7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGVxdWFscyhPYmplY3QgeCwgT2JqZWN0IHkpCisgIHsKKyAgICAgcmV0dXJuICh4ID09IG51bGwgJiYgeSA9PSBudWxsKSB8fCAoeCAhPSBudWxsICYmIHguZXF1YWxzKHkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikKKyAgeworICAgIHJldHVybiBvdGhlciBpbnN0YW5jZW9mIFBhaXIgJiYgZXF1YWxzKGZpcnN0LCAoKFBhaXIpb3RoZXIpLmZpcnN0KSAmJgorICAgICAgZXF1YWxzKHNlY29uZCwgKChQYWlyKW90aGVyKS5zZWNvbmQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKQorICB7CisgICAgaWYgKGZpcnN0ID09IG51bGwpCisgICAgICByZXR1cm4gKHNlY29uZCA9PSBudWxsKSA/IDAgOiBzZWNvbmQuaGFzaENvZGUoKSArIDE7CisgICAgZWxzZSBpZiAoc2Vjb25kID09IG51bGwpCisgICAgICByZXR1cm4gZmlyc3QuaGFzaENvZGUoKSArIDI7CisgICAgZWxzZQorICAgICAgcmV0dXJuIGZpcnN0Lmhhc2hDb2RlKCkgKiAxNyArIHNlY29uZC5oYXNoQ29kZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKQorICB7CisgICAgcmV0dXJuICJ7IiArIGdldEZpcnN0KCkgKyAiLCIgKyBnZXRTZWNvbmQoKSArICJ9IjsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU2xlZXBlci5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9TbGVlcGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2UyYWNhMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU2xlZXBlci5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKKworLyoqCisgKiBTbGVlcGVyIGZvciBjdXJyZW50IHRocmVhZC4KKyAqIFNsZWVwcyBmb3IgcGFzc2VkIHBlcmlvZC4gIEFsc28gY2hlY2tzIHBhc3NlZCBib29sZWFuIGFuZCBpZiBpbnRlcnJ1cHRlZCwKKyAqIHdpbGwgcmV0dXJuIGlmIHRoZSBmbGFnIGlzIHNldCAocmF0aGVyIHRoYW4gZ28gYmFjayB0byBzbGVlcCB1bnRpbCBpdHMgCisgKiBzbGVlcCB0aW1lIGlzIHVwKS4KKyAqLworcHVibGljIGNsYXNzIFNsZWVwZXIgeworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgcGVyaW9kOworICBwcml2YXRlIEF0b21pY0Jvb2xlYW4gc3RvcDsKKyAgCisgIC8qKgorICAgKiBAcGFyYW0gc2xlZXAKKyAgICogQHBhcmFtIHN0b3AKKyAgICovCisgIHB1YmxpYyBTbGVlcGVyKGZpbmFsIGludCBzbGVlcCwgZmluYWwgQXRvbWljQm9vbGVhbiBzdG9wKSB7CisgICAgdGhpcy5wZXJpb2QgPSBzbGVlcDsKKyAgICB0aGlzLnN0b3AgPSBzdG9wOworICB9CisgIAorICAvKioKKyAgICogU2xlZXAgZm9yIHBlcmlvZC4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNsZWVwKCkgeworICAgIHNsZWVwKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFNsZWVwIGZvciBwZXJpb2QgYWRqdXN0ZWQgYnkgcGFzc2VkIDxjb2RlPnN0YXJ0VGltZTxjb2RlPgorICAgKiBAcGFyYW0gc3RhcnRUaW1lIFRpbWUgc29tZSB0YXNrIHN0YXJ0ZWQgcHJldmlvdXMgdG8gbm93LiAgVGltZSB0byBzbGVlcAorICAgKiB3aWxsIGJlIGRvY2tlZCBjdXJyZW50IHRpbWUgbWludXMgcGFzc2VkIDxjb2RlPnN0YXJ0VGltZTxjb2RlPi4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNsZWVwKGZpbmFsIGxvbmcgc3RhcnRUaW1lKSB7CisgICAgaWYgKHRoaXMuc3RvcC5nZXQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGxvbmcgd2FpdFRpbWUgPSB0aGlzLnBlcmlvZCAtIChub3cgLSBzdGFydFRpbWUpOworICAgIGlmICh3YWl0VGltZSA+IHRoaXMucGVyaW9kKSB7CisgICAgICBMT0cud2FybigiQ2FsY3VsYXRlZCB3YWl0IHRpbWUgPiAiICsgdGhpcy5wZXJpb2QgKworICAgICAgICAiOyBzZXR0aW5nIHRvIHRoaXMucGVyaW9kOiAiICsgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyAiLCAiICsKKyAgICAgICAgc3RhcnRUaW1lKTsKKyAgICAgIHdhaXRUaW1lID0gdGhpcy5wZXJpb2Q7CisgICAgfQorICAgIHdoaWxlICh3YWl0VGltZSA+IDApIHsKKyAgICAgIGxvbmcgd29rZSA9IC0xOworICAgICAgdHJ5IHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKHdhaXRUaW1lKTsKKyAgICAgICAgd29rZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgICBsb25nIHNsZXB0ID0gd29rZSAtIG5vdzsKKyAgICAgICAgaWYgKHNsZXB0ID4gKDEwICogdGhpcy5wZXJpb2QpKSB7CisgICAgICAgICAgTE9HLndhcm4oIldlIHNsZXB0ICIgKyBzbGVwdCArICJtcywgdGVuIHRpbWVzIGxvbmdlciB0aGFuIHNjaGVkdWxlZDogIiArCisgICAgICAgICAgICB0aGlzLnBlcmlvZCk7CisgICAgICAgIH0KKyAgICAgIH0gY2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gaWV4KSB7CisgICAgICAgIC8vIFdlIHdlIGludGVycnVwdGVkIGJlY2F1c2Ugd2UncmUgbWVhbnQgdG8gc3RvcD8gIElmIG5vdCwganVzdAorICAgICAgICAvLyBjb250aW51ZSBpZ25vcmluZyB0aGUgaW50ZXJydXB0aW9uCisgICAgICAgIGlmICh0aGlzLnN0b3AuZ2V0KCkpIHsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIC8vIFJlY2FsY3VsYXRlIHdhaXRUaW1lLgorICAgICAgd29rZSA9ICh3b2tlID09IC0xKT8gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk6IHdva2U7CisgICAgICB3YWl0VGltZSA9IHRoaXMucGVyaW9kIC0gKHdva2UgLSBzdGFydFRpbWUpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0U29ydGVkTWFwLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRTb3J0ZWRNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0U29ydGVkTWFwLmphdmEKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU29mdFZhbHVlLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRWYWx1ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhYWE4MmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRWYWx1ZS5qYXZhCkBAIC0wLDAgKzEsNDkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBIFNvZnRSZWZlcmVuY2UgZGVyaXZhdGl2ZSBzbyB0aGF0IHdlIGNhbiB0cmFjayBkb3duIHdoYXQga2V5cyB0byByZW1vdmUuCisgKi8KK2NsYXNzIFNvZnRWYWx1ZTxLLCBWPiBleHRlbmRzIFNvZnRSZWZlcmVuY2U8Vj4gaW1wbGVtZW50cyBNYXAuRW50cnk8SywgVj4geworICBwcml2YXRlIGZpbmFsIEsga2V5OworCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBTb2Z0VmFsdWUoSyBrZXksIFYgdmFsdWUsIFJlZmVyZW5jZVF1ZXVlIHF1ZXVlKSB7CisgICAgc3VwZXIodmFsdWUsIHF1ZXVlKTsKKyAgICB0aGlzLmtleSA9IGtleTsKKyAgfQorCisgIHB1YmxpYyBLIGdldEtleSgpIHsKKyAgICByZXR1cm4gdGhpcy5rZXk7CisgIH0KKworICBwdWJsaWMgViBnZXRWYWx1ZSgpIHsKKyAgICByZXR1cm4gZ2V0KCk7CisgIH0KKworICBwdWJsaWMgViBzZXRWYWx1ZShWIHZhbHVlKSB7CisgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk5vdCBpbXBsZW1lbnRlZCIpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0VmFsdWVNYXAuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU29mdFZhbHVlTWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBhODFiNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU29mdFZhbHVlTWFwLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5sYW5nLnJlZi5SZWZlcmVuY2VRdWV1ZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworLyoqCisgKiBBIE1hcCB0aGF0IHVzZXMgU29mdCBSZWZlcmVuY2UgdmFsdWVzIGludGVybmFsbHkuIFVzZSBhcyBhIHNpbXBsZSBjYWNoZS4KKyAqIAorICogQHBhcmFtIDxLPiBrZXkgY2xhc3MKKyAqIEBwYXJhbSA8Vj4gdmFsdWUgY2xhc3MKKyAqLworcHVibGljIGNsYXNzIFNvZnRWYWx1ZU1hcDxLLFY+IGltcGxlbWVudHMgTWFwPEssVj4geworICBwcml2YXRlIGZpbmFsIE1hcDxLLCBTb2Z0VmFsdWU8SyxWPj4gaW50ZXJuYWxNYXAgPQorICAgIG5ldyBIYXNoTWFwPEssIFNvZnRWYWx1ZTxLLFY+PigpOworICBwcml2YXRlIGZpbmFsIFJlZmVyZW5jZVF1ZXVlPD8+IHJxOworICAKKyAgcHVibGljIFNvZnRWYWx1ZU1hcCgpIHsKKyAgICB0aGlzKG5ldyBSZWZlcmVuY2VRdWV1ZSgpKTsKKyAgfQorICAKKyAgcHVibGljIFNvZnRWYWx1ZU1hcChmaW5hbCBSZWZlcmVuY2VRdWV1ZTw/PiBycSkgeworICAgIHRoaXMucnEgPSBycTsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3Mgc29mdCByZWZlcmVuY2VzIGFuZCBjbGVhbnMgYW55IHRoYXQgaGF2ZSBiZWVuIHBsYWNlZCBvbgorICAgKiBSZWZlcmVuY2VRdWV1ZS4KKyAgICogQHJldHVybiBIb3cgbWFueSByZWZlcmVuY2VzIGNsZWFyZWQuCisgICAqLworICBwdWJsaWMgaW50IGNoZWNrUmVmZXJlbmNlcygpIHsKKyAgICBpbnQgaSA9IDA7CisgICAgZm9yIChPYmplY3Qgb2JqID0gbnVsbDsgKG9iaiA9IHRoaXMucnEucG9sbCgpKSAhPSBudWxsOykgeworICAgICAgaSsrOworICAgICAgdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoKChTb2Z0VmFsdWU8SyxWPilvYmopLmdldEtleSgpKTsKKyAgICB9CisgICAgcmV0dXJuIGk7CisgIH0KKworICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBTb2Z0VmFsdWU8SyxWPiBvbGRWYWx1ZSA9IHRoaXMuaW50ZXJuYWxNYXAucHV0KGtleSwKKyAgICAgIG5ldyBTb2Z0VmFsdWU8SyxWPihrZXksIHZhbHVlLCB0aGlzLnJxKSk7CisgICAgcmV0dXJuIG9sZFZhbHVlID09IG51bGwgPyBudWxsIDogb2xkVmFsdWUuZ2V0KCk7CisgIH0KKyAgCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwIG1hcCkgeworICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsKKyAgfQorICAKKyAgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBTb2Z0VmFsdWU8SyxWPiB2YWx1ZSA9IHRoaXMuaW50ZXJuYWxNYXAuZ2V0KGtleSk7CisgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBpZiAodmFsdWUuZ2V0KCkgPT0gbnVsbCkgeworICAgICAgdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoa2V5KTsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gdmFsdWUuZ2V0KCk7CisgIH0KKworICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIFNvZnRWYWx1ZTxLLFY+IHZhbHVlID0gdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoa2V5KTsKKyAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/IG51bGwgOiB2YWx1ZS5nZXQoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsgCisgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxNYXAuY29udGFpbnNLZXkoa2V5KTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKy8qICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIHJldHVybiBpbnRlcm5hbE1hcC5jb250YWluc1ZhbHVlKHZhbHVlKTsqLworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiRG9uJ3Qgc3VwcG9ydCBjb250YWluc1ZhbHVlISIpOworICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIHJldHVybiB0aGlzLmludGVybmFsTWFwLmlzRW1wdHkoKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICByZXR1cm4gdGhpcy5pbnRlcm5hbE1hcC5zaXplKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICB0aGlzLmludGVybmFsTWFwLmNsZWFyKCk7CisgIH0KKworICBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICByZXR1cm4gdGhpcy5pbnRlcm5hbE1hcC5rZXlTZXQoKTsKKyAgfQorCisgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssVj4+IGVudHJ5U2V0KCkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIFNldDxNYXAuRW50cnk8SywgU29mdFZhbHVlPEssVj4+PiBlbnRyaWVzID0gdGhpcy5pbnRlcm5hbE1hcC5lbnRyeVNldCgpOworICAgIFNldDxNYXAuRW50cnk8SywgVj4+IHJlYWxfZW50cmllcyA9IG5ldyBIYXNoU2V0PE1hcC5FbnRyeTxLLFY+PigpOworICAgIGZvcihNYXAuRW50cnk8SywgU29mdFZhbHVlPEssVj4+IGVudHJ5IDogZW50cmllcykgeworICAgICAgcmVhbF9lbnRyaWVzLmFkZChlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlYWxfZW50cmllczsKKyAgfQorCisgIHB1YmxpYyBDb2xsZWN0aW9uPFY+IHZhbHVlcygpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBDb2xsZWN0aW9uPFNvZnRWYWx1ZTxLLFY+PiBzb2Z0VmFsdWVzID0gdGhpcy5pbnRlcm5hbE1hcC52YWx1ZXMoKTsKKyAgICBBcnJheUxpc3Q8Vj4gaGFyZFZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8Vj4oKTsKKyAgICBmb3IoU29mdFZhbHVlPEssVj4gc29mdFZhbHVlIDogc29mdFZhbHVlcykgeworICAgICAgaGFyZFZhbHVlcy5hZGQoc29mdFZhbHVlLmdldCgpKTsKKyAgICB9CisgICAgcmV0dXJuIGhhcmRWYWx1ZXM7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRWYWx1ZVNvcnRlZE1hcC5qYXZhIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0VmFsdWVTb3J0ZWRNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmY1ODZlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0VmFsdWVTb3J0ZWRNYXAuamF2YQpAQCAtMCwwICsxLDE4OCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWw7CisKK2ltcG9ydCBqYXZhLmxhbmcucmVmLlJlZmVyZW5jZVF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKKy8qKgorICogQSBTb3J0ZWRNYXAgaW1wbGVtZW50YXRpb24gdGhhdCB1c2VzIFNvZnQgUmVmZXJlbmNlIHZhbHVlcworICogaW50ZXJuYWxseSB0byBtYWtlIGl0IHBsYXkgd2VsbCB3aXRoIHRoZSBHQyB3aGVuIGluIGEgbG93LW1lbW9yeQorICogc2l0dWF0aW9uLiBVc2UgYXMgYSBjYWNoZSB3aGVyZSB5b3UgYWxzbyBuZWVkIFNvcnRlZE1hcCBmdW5jdGlvbmFsaXR5LgorICogCisgKiBAcGFyYW0gPEs+IGtleSBjbGFzcworICogQHBhcmFtIDxWPiB2YWx1ZSBjbGFzcworICovCitwdWJsaWMgY2xhc3MgU29mdFZhbHVlU29ydGVkTWFwPEssVj4gaW1wbGVtZW50cyBTb3J0ZWRNYXA8SyxWPiB7CisgIHByaXZhdGUgZmluYWwgU29ydGVkTWFwPEssIFNvZnRWYWx1ZTxLLFY+PiBpbnRlcm5hbE1hcDsKKyAgcHJpdmF0ZSBmaW5hbCBSZWZlcmVuY2VRdWV1ZSBycSA9IG5ldyBSZWZlcmVuY2VRdWV1ZSgpOworICAKKyAgLyoqIENvbnN0cnVjdG9yICovCisgIHB1YmxpYyBTb2Z0VmFsdWVTb3J0ZWRNYXAoKSB7CisgICAgdGhpcyhuZXcgVHJlZU1hcDxLLCBTb2Z0VmFsdWU8SyxWPj4oKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDb25zdHJ1Y3RvcgorICAgKiBAcGFyYW0gYworICAgKi8KKyAgcHVibGljIFNvZnRWYWx1ZVNvcnRlZE1hcChmaW5hbCBDb21wYXJhdG9yPEs+IGMpIHsKKyAgICB0aGlzKG5ldyBUcmVlTWFwPEssIFNvZnRWYWx1ZTxLLFY+PihjKSk7CisgIH0KKyAgCisgIC8qKiBGb3IgaGVhZE1hcCBhbmQgdGFpbE1hcCBzdXBwb3J0ICovCisgIHByaXZhdGUgU29mdFZhbHVlU29ydGVkTWFwKFNvcnRlZE1hcDxLLFNvZnRWYWx1ZTxLLFY+PiBvcmlnaW5hbCkgeworICAgIHRoaXMuaW50ZXJuYWxNYXAgPSBvcmlnaW5hbDsKKyAgfQorCisgIC8qKgorICAgKiBDaGVja3Mgc29mdCByZWZlcmVuY2VzIGFuZCBjbGVhbnMgYW55IHRoYXQgaGF2ZSBiZWVuIHBsYWNlZCBvbgorICAgKiBSZWZlcmVuY2VRdWV1ZS4gIENhbGwgaWYgZ2V0L3B1dCBldGMuIGFyZSBub3QgY2FsbGVkIHJlZ3VsYXJseS4KKyAgICogSW50ZXJuYWxseSB0aGVzZSBjYWxsIGNoZWNrUmVmZXJlbmNlcyBvbiBlYWNoIGFjY2Vzcy4KKyAgICogQHJldHVybiBIb3cgbWFueSByZWZlcmVuY2VzIGNsZWFyZWQuCisgICAqLworICBwdWJsaWMgaW50IGNoZWNrUmVmZXJlbmNlcygpIHsKKyAgICBpbnQgaSA9IDA7CisgICAgZm9yIChPYmplY3Qgb2JqID0gbnVsbDsgKG9iaiA9IHRoaXMucnEucG9sbCgpKSAhPSBudWxsOykgeworICAgICAgaSsrOworICAgICAgdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoKChTb2Z0VmFsdWU8SyxWPilvYmopLmdldEtleSgpKTsKKyAgICB9CisgICAgcmV0dXJuIGk7CisgIH0KKworICBwdWJsaWMgViBwdXQoSyBrZXksIFYgdmFsdWUpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBTb2Z0VmFsdWU8SyxWPiBvbGRWYWx1ZSA9IHRoaXMuaW50ZXJuYWxNYXAucHV0KGtleSwKKyAgICAgIG5ldyBTb2Z0VmFsdWU8SyxWPihrZXksIHZhbHVlLCB0aGlzLnJxKSk7CisgICAgcmV0dXJuIG9sZFZhbHVlID09IG51bGwgPyBudWxsIDogb2xkVmFsdWUuZ2V0KCk7CisgIH0KKyAgCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgdm9pZCBwdXRBbGwoTWFwIG1hcCkgeworICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJOb3QgaW1wbGVtZW50ZWQiKTsKKyAgfQorICAKKyAgcHVibGljIFYgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBTb2Z0VmFsdWU8SyxWPiB2YWx1ZSA9IHRoaXMuaW50ZXJuYWxNYXAuZ2V0KGtleSk7CisgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBpZiAodmFsdWUuZ2V0KCkgPT0gbnVsbCkgeworICAgICAgdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoa2V5KTsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gdmFsdWUuZ2V0KCk7CisgIH0KKworICBwdWJsaWMgViByZW1vdmUoT2JqZWN0IGtleSkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIFNvZnRWYWx1ZTxLLFY+IHZhbHVlID0gdGhpcy5pbnRlcm5hbE1hcC5yZW1vdmUoa2V5KTsKKyAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/IG51bGwgOiB2YWx1ZS5nZXQoKTsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsgCisgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxNYXAuY29udGFpbnNLZXkoa2V5KTsKKyAgfQorICAKKyAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKy8qICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIHJldHVybiBpbnRlcm5hbE1hcC5jb250YWluc1ZhbHVlKHZhbHVlKTsqLworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiRG9uJ3Qgc3VwcG9ydCBjb250YWluc1ZhbHVlISIpOworICB9CisKKyAgcHVibGljIEsgZmlyc3RLZXkoKSB7CisgICAgY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgcmV0dXJuIGludGVybmFsTWFwLmZpcnN0S2V5KCk7CisgIH0KKworICBwdWJsaWMgSyBsYXN0S2V5KCkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIHJldHVybiBpbnRlcm5hbE1hcC5sYXN0S2V5KCk7CisgIH0KKyAgCisgIHB1YmxpYyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPiBoZWFkTWFwKEsga2V5KSB7CisgICAgY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgcmV0dXJuIG5ldyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPih0aGlzLmludGVybmFsTWFwLmhlYWRNYXAoa2V5KSk7CisgIH0KKyAgCisgIHB1YmxpYyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPiB0YWlsTWFwKEsga2V5KSB7CisgICAgY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgcmV0dXJuIG5ldyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPih0aGlzLmludGVybmFsTWFwLnRhaWxNYXAoa2V5KSk7CisgIH0KKyAgCisgIHB1YmxpYyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPiBzdWJNYXAoSyBmcm9tS2V5LCBLIHRvS2V5KSB7CisgICAgY2hlY2tSZWZlcmVuY2VzKCk7CisgICAgcmV0dXJuIG5ldyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SyxWPih0aGlzLmludGVybmFsTWFwLnN1Yk1hcChmcm9tS2V5LCB0b0tleSkpOworICB9CisgIAorICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIHJldHVybiB0aGlzLmludGVybmFsTWFwLmlzRW1wdHkoKTsKKyAgfQorCisgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICByZXR1cm4gdGhpcy5pbnRlcm5hbE1hcC5zaXplKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCBjbGVhcigpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICB0aGlzLmludGVybmFsTWFwLmNsZWFyKCk7CisgIH0KKworICBwdWJsaWMgU2V0PEs+IGtleVNldCgpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICByZXR1cm4gdGhpcy5pbnRlcm5hbE1hcC5rZXlTZXQoKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgQ29tcGFyYXRvciBjb21wYXJhdG9yKCkgeworICAgIHJldHVybiB0aGlzLmludGVybmFsTWFwLmNvbXBhcmF0b3IoKTsKKyAgfQorCisgIHB1YmxpYyBTZXQ8TWFwLkVudHJ5PEssVj4+IGVudHJ5U2V0KCkgeworICAgIGNoZWNrUmVmZXJlbmNlcygpOworICAgIFNldDxNYXAuRW50cnk8SywgU29mdFZhbHVlPEssVj4+PiBlbnRyaWVzID0gdGhpcy5pbnRlcm5hbE1hcC5lbnRyeVNldCgpOworICAgIFNldDxNYXAuRW50cnk8SywgVj4+IHJlYWxfZW50cmllcyA9IG5ldyBUcmVlU2V0PE1hcC5FbnRyeTxLLFY+PigpOworICAgIGZvcihNYXAuRW50cnk8SywgU29mdFZhbHVlPEssVj4+IGVudHJ5IDogZW50cmllcykgeworICAgICAgcmVhbF9lbnRyaWVzLmFkZChlbnRyeS5nZXRWYWx1ZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlYWxfZW50cmllczsKKyAgfQorCisgIHB1YmxpYyBDb2xsZWN0aW9uPFY+IHZhbHVlcygpIHsKKyAgICBjaGVja1JlZmVyZW5jZXMoKTsKKyAgICBDb2xsZWN0aW9uPFNvZnRWYWx1ZTxLLFY+PiBzb2Z0VmFsdWVzID0gdGhpcy5pbnRlcm5hbE1hcC52YWx1ZXMoKTsKKyAgICBBcnJheUxpc3Q8Vj4gaGFyZFZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8Vj4oKTsKKyAgICBmb3IoU29mdFZhbHVlPEssVj4gc29mdFZhbHVlIDogc29mdFZhbHVlcykgeworICAgICAgaGFyZFZhbHVlcy5hZGQoc29mdFZhbHVlLmdldCgpKTsKKyAgICB9CisgICAgcmV0dXJuIGhhcmRWYWx1ZXM7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1N0cmluZ3MuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU3RyaW5ncy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExNzMxMmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1N0cmluZ3MuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworLyoqCisgKiBVdGlsbGl0eSBmb3IgU3RyaW5ncy4KKyAqLworcHVibGljIGNsYXNzIFN0cmluZ3MgeworICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBERUZBVUxUX1NFUEFSQVRPUiA9ICI9IjsKKyAgcHVibGljIGZpbmFsIHN0YXRpYyBTdHJpbmcgREVGQVVMVF9LRVlWQUxVRV9TRVBBUkFUT1IgPSAiLCAiOworICAKKyAgLyoqCisgICAqIEFwcGVuZCB0byBhIFN0cmluZ0J1aWxkZXIgYSBrZXkvdmFsdWUuCisgICAqIFVzZXMgZGVmYXVsdCBzZXBhcmF0b3JzLgorICAgKiBAcGFyYW0gc2IgU3RyaW5nQnVpbGRlciB0byB1c2UKKyAgICogQHBhcmFtIGtleSBLZXkgdG8gYXBwZW5kLgorICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gYXBwZW5kLgorICAgKiBAcmV0dXJuIFBhc3NlZCA8Y29kZT5zYjwvY29kZT4gcG9wdWxhdGVkIHdpdGgga2V5L3ZhbHVlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmdCdWlsZGVyIGFwcGVuZEtleVZhbHVlKGZpbmFsIFN0cmluZ0J1aWxkZXIgc2IsCisgICAgICBmaW5hbCBTdHJpbmcga2V5LCBmaW5hbCBPYmplY3QgdmFsdWUpIHsKKyAgICByZXR1cm4gYXBwZW5kS2V5VmFsdWUoc2IsIGtleSwgdmFsdWUsIERFRkFVTFRfU0VQQVJBVE9SLAorICAgICAgREVGQVVMVF9LRVlWQUxVRV9TRVBBUkFUT1IpOworICB9CisKKyAgLyoqCisgICAqIEFwcGVuZCB0byBhIFN0cmluZ0J1aWxkZXIgYSBrZXkvdmFsdWUuCisgICAqIFVzZXMgZGVmYXVsdCBzZXBhcmF0b3JzLgorICAgKiBAcGFyYW0gc2IgU3RyaW5nQnVpbGRlciB0byB1c2UKKyAgICogQHBhcmFtIGtleSBLZXkgdG8gYXBwZW5kLgorICAgKiBAcGFyYW0gdmFsdWUgVmFsdWUgdG8gYXBwZW5kLgorICAgKiBAcGFyYW0gc2VwYXJhdG9yIFZhbHVlIHRvIHVzZSBiZXR3ZWVuIGtleSBhbmQgdmFsdWUuCisgICAqIEBwYXJhbSBrZXlWYWx1ZVNlcGFyYXRvciBWYWx1ZSB0byB1c2UgYmV0d2VlbiBrZXkvdmFsdWUgc2V0cy4KKyAgICogQHJldHVybiBQYXNzZWQgPGNvZGU+c2I8L2NvZGU+IHBvcHVsYXRlZCB3aXRoIGtleS92YWx1ZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nQnVpbGRlciBhcHBlbmRLZXlWYWx1ZShmaW5hbCBTdHJpbmdCdWlsZGVyIHNiLAorICAgICAgZmluYWwgU3RyaW5nIGtleSwgZmluYWwgT2JqZWN0IHZhbHVlLCBmaW5hbCBTdHJpbmcgc2VwYXJhdG9yLAorICAgICAgZmluYWwgU3RyaW5nIGtleVZhbHVlU2VwYXJhdG9yKSB7CisgICAgaWYgKHNiLmxlbmd0aCgpID4gMCkgeworICAgICAgc2IuYXBwZW5kKGtleVZhbHVlU2VwYXJhdG9yKTsKKyAgICB9CisgICAgcmV0dXJuIHNiLmFwcGVuZChrZXkpLmFwcGVuZChzZXBhcmF0b3IpLmFwcGVuZCh2YWx1ZSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1RocmVhZHMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGhyZWFkcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5Y2RkMGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1RocmVhZHMuamF2YQpAQCAtMCwwICsxLDgzIEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEubGFuZy5UaHJlYWQuVW5jYXVnaHRFeGNlcHRpb25IYW5kbGVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKKy8qKgorICogVGhyZWFkIFV0aWxpdHkKKyAqLworcHVibGljIGNsYXNzIFRocmVhZHMgeworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUaHJlYWRzLmNsYXNzKTsKKyAgCisgIC8qKgorICAgKiBVdGlsaXR5IG1ldGhvZCB0aGF0IHNldHMgbmFtZSwgZGFlbW9uIHN0YXR1cyBhbmQgc3RhcnRzIHBhc3NlZCB0aHJlYWQuCisgICAqIEBwYXJhbSB0CisgICAqIEBwYXJhbSBuYW1lCisgICAqIEByZXR1cm4gUmV0dXJucyB0aGUgcGFzc2VkIFRocmVhZCA8Y29kZT50PC9jb2RlPi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgVGhyZWFkIHNldERhZW1vblRocmVhZFJ1bm5pbmcoZmluYWwgVGhyZWFkIHQsCisgICAgZmluYWwgU3RyaW5nIG5hbWUpIHsKKyAgICByZXR1cm4gc2V0RGFlbW9uVGhyZWFkUnVubmluZyh0LCBuYW1lLCBudWxsKTsKKyAgfQorICAgIAorICAvKioKKyAgICogVXRpbGl0eSBtZXRob2QgdGhhdCBzZXRzIG5hbWUsIGRhZW1vbiBzdGF0dXMgYW5kIHN0YXJ0cyBwYXNzZWQgdGhyZWFkLgorICAgKiBAcGFyYW0gdAorICAgKiBAcGFyYW0gbmFtZQorICAgKiBAcGFyYW0gaGFuZGxlciBBIGhhbmRsZXIgdG8gc2V0IG9uIHRoZSB0aHJlYWQuICBQYXNzIG51bGwgaWYgd2FudCB0bworICAgKiB1c2UgZGVmYXVsdCBoYW5kbGVyLgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIHBhc3NlZCBUaHJlYWQgPGNvZGU+dDwvY29kZT4uCisgICAqLworICBwdWJsaWMgc3RhdGljIFRocmVhZCBzZXREYWVtb25UaHJlYWRSdW5uaW5nKGZpbmFsIFRocmVhZCB0LAorICAgIGZpbmFsIFN0cmluZyBuYW1lLCBmaW5hbCBVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIgaGFuZGxlcikgeworICAgIHQuc2V0TmFtZShuYW1lKTsKKyAgICBpZiAoaGFuZGxlciAhPSBudWxsKSB7CisgICAgICB0LnNldFVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcihoYW5kbGVyKTsKKyAgICB9CisgICAgdC5zZXREYWVtb24odHJ1ZSk7CisgICAgdC5zdGFydCgpOworICAgIHJldHVybiB0OworICB9CisKKyAgLyoqCisgICAqIFNodXRkb3duIHBhc3NlZCB0aHJlYWQgdXNpbmcgaXNBbGl2ZSBhbmQgam9pbi4KKyAgICogQHBhcmFtIHQgVGhyZWFkIHRvIHNodXRkb3duCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgc2h1dGRvd24oZmluYWwgVGhyZWFkIHQpIHsKKyAgICBzaHV0ZG93bih0LCAwKTsKKyAgfQorCisgIC8qKgorICAgKiBTaHV0ZG93biBwYXNzZWQgdGhyZWFkIHVzaW5nIGlzQWxpdmUgYW5kIGpvaW4uCisgICAqIEBwYXJhbSBqb2lud2FpdCBQYXNzIDAgaWYgd2UncmUgdG8gd2FpdCBmb3JldmVyLgorICAgKiBAcGFyYW0gdCBUaHJlYWQgdG8gc2h1dGRvd24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzaHV0ZG93bihmaW5hbCBUaHJlYWQgdCwgZmluYWwgbG9uZyBqb2lud2FpdCkgeworICAgIHdoaWxlICh0LmlzQWxpdmUoKSkgeworICAgICAgdHJ5IHsKKyAgICAgICAgdC5qb2luKGpvaW53YWl0KTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTE9HLndhcm4odC5nZXROYW1lKCkgKyAiOyBqb2lud2FpdD0iICsgam9pbndhaXQsIGUpOworICAgICAgfQorICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVmVyc2lvbkluZm8uamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVmVyc2lvbkluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2Y3NWYwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9WZXJzaW9uSW5mby5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlZlcnNpb25Bbm5vdGF0aW9uOworCisvKioKKyAqIFRoaXMgY2xhc3MgZmluZHMgdGhlIHBhY2thZ2UgaW5mbyBmb3IgaGJhc2UgYW5kIHRoZSBWZXJzaW9uQW5ub3RhdGlvbgorICogaW5mb3JtYXRpb24uICBUYWtlbiBmcm9tIGhhZG9vcC4gIE9ubHkgbmFtZSBvZiBhbm5vdGF0aW9uIGlzIGRpZmZlcmVudC4KKyAqLworcHVibGljIGNsYXNzIFZlcnNpb25JbmZvIHsKKyAgcHJpdmF0ZSBzdGF0aWMgUGFja2FnZSBteVBhY2thZ2U7CisgIHByaXZhdGUgc3RhdGljIFZlcnNpb25Bbm5vdGF0aW9uIHZlcnNpb247CisgIAorICBzdGF0aWMgeworICAgIG15UGFja2FnZSA9IFZlcnNpb25Bbm5vdGF0aW9uLmNsYXNzLmdldFBhY2thZ2UoKTsKKyAgICB2ZXJzaW9uID0gbXlQYWNrYWdlLmdldEFubm90YXRpb24oVmVyc2lvbkFubm90YXRpb24uY2xhc3MpOworICB9CisKKyAgLyoqCisgICAqIEdldCB0aGUgbWV0YS1kYXRhIGZvciB0aGUgaGJhc2UgcGFja2FnZS4KKyAgICogQHJldHVybgorICAgKi8KKyAgc3RhdGljIFBhY2thZ2UgZ2V0UGFja2FnZSgpIHsKKyAgICByZXR1cm4gbXlQYWNrYWdlOworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSBoYmFzZSB2ZXJzaW9uLgorICAgKiBAcmV0dXJuIHRoZSBoYmFzZSB2ZXJzaW9uIHN0cmluZywgZWcuICIwLjYuMy1kZXYiCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRWZXJzaW9uKCkgeworICAgIHJldHVybiB2ZXJzaW9uICE9IG51bGwgPyB2ZXJzaW9uLnZlcnNpb24oKSA6ICJVbmtub3duIjsKKyAgfQorICAKKyAgLyoqCisgICAqIEdldCB0aGUgc3VidmVyc2lvbiByZXZpc2lvbiBudW1iZXIgZm9yIHRoZSByb290IGRpcmVjdG9yeQorICAgKiBAcmV0dXJuIHRoZSByZXZpc2lvbiBudW1iZXIsIGVnLiAiNDUxNDUxIgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UmV2aXNpb24oKSB7CisgICAgcmV0dXJuIHZlcnNpb24gIT0gbnVsbCA/IHZlcnNpb24ucmV2aXNpb24oKSA6ICJVbmtub3duIjsKKyAgfQorICAKKyAgLyoqCisgICAqIFRoZSBkYXRlIHRoYXQgaGJhc2Ugd2FzIGNvbXBpbGVkLgorICAgKiBAcmV0dXJuIHRoZSBjb21waWxhdGlvbiBkYXRlIGluIHVuaXggZGF0ZSBmb3JtYXQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERhdGUoKSB7CisgICAgcmV0dXJuIHZlcnNpb24gIT0gbnVsbCA/IHZlcnNpb24uZGF0ZSgpIDogIlVua25vd24iOworICB9CisgIAorICAvKioKKyAgICogVGhlIHVzZXIgdGhhdCBjb21waWxlZCBoYmFzZS4KKyAgICogQHJldHVybiB0aGUgdXNlcm5hbWUgb2YgdGhlIHVzZXIKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFVzZXIoKSB7CisgICAgcmV0dXJuIHZlcnNpb24gIT0gbnVsbCA/IHZlcnNpb24udXNlcigpIDogIlVua25vd24iOworICB9CisgIAorICAvKioKKyAgICogR2V0IHRoZSBzdWJ2ZXJzaW9uIFVSTCBmb3IgdGhlIHJvb3QgaGJhc2UgZGlyZWN0b3J5LgorICAgKiBAcmV0dXJuIHRoZSB1cmwKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFVybCgpIHsKKyAgICByZXR1cm4gdmVyc2lvbiAhPSBudWxsID8gdmVyc2lvbi51cmwoKSA6ICJVbmtub3duIjsKKyAgfQorICAKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJIQmFzZSAiICsgZ2V0VmVyc2lvbigpKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN1YnZlcnNpb24gIiArIGdldFVybCgpICsgIiAtciAiICsgZ2V0UmV2aXNpb24oKSk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJDb21waWxlZCBieSAiICsgZ2V0VXNlcigpICsgIiBvbiAiICsgZ2V0RGF0ZSgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Xcml0YWJsZXMuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvV3JpdGFibGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2IzN2QwZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvV3JpdGFibGVzLmphdmEKQEAgLTAsMCArMSwxOTYgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uRGF0YUlucHV0QnVmZmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlOworCisvKioKKyAqIFV0aWxpdHkgY2xhc3Mgd2l0aCBtZXRob2RzIGZvciBtYW5pcHVsYXRpbmcgV3JpdGFibGUgb2JqZWN0cworICovCitwdWJsaWMgY2xhc3MgV3JpdGFibGVzIHsKKyAgLyoqCisgICAqIEBwYXJhbSB3CisgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIDxjb2RlPnc8L2NvZGU+IGdvdHRlbiBieSBydW5uaW5nIGl0cyAKKyAgICoge0BsaW5rIFdyaXRhYmxlI3dyaXRlKGphdmEuaW8uRGF0YU91dHB1dCl9IG1ldGhvZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAc2VlICNnZXRXcml0YWJsZShieXRlW10sIFdyaXRhYmxlKQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGdldEJ5dGVzKGZpbmFsIFdyaXRhYmxlIHcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHcgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiV3JpdGFibGUgY2Fubm90IGJlIG51bGwiKTsKKyAgICB9CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShieXRlU3RyZWFtKTsKKyAgICB0cnkgeworICAgICAgdy53cml0ZShvdXQpOworICAgICAgb3V0LmNsb3NlKCk7CisgICAgICBvdXQgPSBudWxsOworICAgICAgcmV0dXJuIGJ5dGVTdHJlYW0udG9CeXRlQXJyYXkoKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKG91dCAhPSBudWxsKSB7CisgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTZXQgYnl0ZXMgaW50byB0aGUgcGFzc2VkIFdyaXRhYmxlIGJ5IGNhbGxpbmcgaXRzCisgICAqIHtAbGluayBXcml0YWJsZSNyZWFkRmllbGRzKGphdmEuaW8uRGF0YUlucHV0KX0uCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcGFyYW0gdyBBbiBlbXB0eSBXcml0YWJsZSAodXN1YWxseSBtYWRlIGJ5IGNhbGxpbmcgdGhlIG51bGwtYXJnCisgICAqIGNvbnN0cnVjdG9yKS4KKyAgICogQHJldHVybiBUaGUgcGFzc2VkIFdyaXRhYmxlIGFmdGVyIGl0cyByZWFkRmllbGRzIGhhcyBiZWVuIGNhbGxlZCBmZWQKKyAgICogYnkgdGhlIHBhc3NlZCA8Y29kZT5ieXRlczwvY29kZT4gYXJyYXkgb3IgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCisgICAqIGlmIHBhc3NlZCBudWxsIG9yIGFuIGVtcHR5IDxjb2RlPmJ5dGVzPC9jb2RlPiBhcnJheS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0YWJsZSBnZXRXcml0YWJsZShmaW5hbCBieXRlIFtdIGJ5dGVzLCBmaW5hbCBXcml0YWJsZSB3KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBnZXRXcml0YWJsZShieXRlcywgMCwgYnl0ZXMubGVuZ3RoLCB3KTsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgYnl0ZXMgaW50byB0aGUgcGFzc2VkIFdyaXRhYmxlIGJ5IGNhbGxpbmcgaXRzCisgICAqIHtAbGluayBXcml0YWJsZSNyZWFkRmllbGRzKGphdmEuaW8uRGF0YUlucHV0KX0uCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcGFyYW0gb2Zmc2V0CisgICAqIEBwYXJhbSBsZW5ndGgKKyAgICogQHBhcmFtIHcgQW4gZW1wdHkgV3JpdGFibGUgKHVzdWFsbHkgbWFkZSBieSBjYWxsaW5nIHRoZSBudWxsLWFyZworICAgKiBjb25zdHJ1Y3RvcikuCisgICAqIEByZXR1cm4gVGhlIHBhc3NlZCBXcml0YWJsZSBhZnRlciBpdHMgcmVhZEZpZWxkcyBoYXMgYmVlbiBjYWxsZWQgZmVkCisgICAqIGJ5IHRoZSBwYXNzZWQgPGNvZGU+Ynl0ZXM8L2NvZGU+IGFycmF5IG9yIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgorICAgKiBpZiBwYXNzZWQgbnVsbCBvciBhbiBlbXB0eSA8Y29kZT5ieXRlczwvY29kZT4gYXJyYXkuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgV3JpdGFibGUgZ2V0V3JpdGFibGUoZmluYWwgYnl0ZSBbXSBieXRlcywgZmluYWwgaW50IG9mZnNldCwKKyAgICBmaW5hbCBpbnQgbGVuZ3RoLCBmaW5hbCBXcml0YWJsZSB3KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChieXRlcyA9PSBudWxsIHx8IGxlbmd0aCA8PTApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbid0IGJ1aWxkIGEgd3JpdGFibGUgd2l0aCBlbXB0eSAiICsKKyAgICAgICAgImJ5dGVzIGFycmF5Iik7CisgICAgfQorICAgIGlmICh3ID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIldyaXRhYmxlIGNhbm5vdCBiZSBudWxsIik7CisgICAgfQorICAgIERhdGFJbnB1dEJ1ZmZlciBpbiA9IG5ldyBEYXRhSW5wdXRCdWZmZXIoKTsKKyAgICB0cnkgeworICAgICAgaW4ucmVzZXQoYnl0ZXMsIG9mZnNldCwgbGVuZ3RoKTsKKyAgICAgIHcucmVhZEZpZWxkcyhpbik7CisgICAgICByZXR1cm4gdzsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaW4uY2xvc2UoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEByZXR1cm4gQSBIUmVnaW9uSW5mbyBpbnN0YW5jZSBidWlsdCBvdXQgb2YgcGFzc2VkIDxjb2RlPmJ5dGVzPC9jb2RlPi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBIUmVnaW9uSW5mbyBnZXRIUmVnaW9uSW5mbyhmaW5hbCBieXRlIFtdIGJ5dGVzKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiAoSFJlZ2lvbkluZm8pZ2V0V3JpdGFibGUoYnl0ZXMsIG5ldyBIUmVnaW9uSW5mbygpKTsKKyAgfQorIAorICAvKioKKyAgICogQHBhcmFtIGJ5dGVzCisgICAqIEByZXR1cm4gQSBIUmVnaW9uSW5mbyBpbnN0YW5jZSBidWlsdCBvdXQgb2YgcGFzc2VkIDxjb2RlPmJ5dGVzPC9jb2RlPgorICAgKiBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwYXNzZWQgYnl0ZXMgYXJlIG51bGwgb3IgYW4gZW1wdHkgYXJyYXkuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSFJlZ2lvbkluZm8gZ2V0SFJlZ2lvbkluZm9Pck51bGwoZmluYWwgYnl0ZSBbXSBieXRlcykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gKGJ5dGVzID09IG51bGwgfHwgYnl0ZXMubGVuZ3RoIDw9IDApPworICAgICAgKEhSZWdpb25JbmZvKW51bGw6IGdldEhSZWdpb25JbmZvKGJ5dGVzKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gY2VsbCBDZWxsIG9iamVjdCBjb250YWluaW5nIHRoZSBzZXJpYWxpemVkIEhSZWdpb25JbmZvCisgICAqIEByZXR1cm4gQSBIUmVnaW9uSW5mbyBpbnN0YW5jZSBidWlsdCBvdXQgb2YgcGFzc2VkIDxjb2RlPmNlbGw8L2NvZGU+LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgc3RhdGljIEhSZWdpb25JbmZvIGdldEhSZWdpb25JbmZvKGZpbmFsIENlbGwgY2VsbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoY2VsbCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcmV0dXJuIGdldEhSZWdpb25JbmZvKGNlbGwuZ2V0VmFsdWUoKSk7CisgIH0KKworICAvKioKKyAgICogQ29weSBvbmUgV3JpdGFibGUgdG8gYW5vdGhlci4gIENvcGllcyBieXRlcyB1c2luZyBkYXRhIHN0cmVhbXMuCisgICAqIEBwYXJhbSBzcmMgU291cmNlIFdyaXRhYmxlCisgICAqIEBwYXJhbSB0Z3QgVGFyZ2V0IFdyaXRhYmxlCisgICAqIEByZXR1cm4gVGhlIHRhcmdldCBXcml0YWJsZS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0YWJsZSBjb3B5V3JpdGFibGUoZmluYWwgV3JpdGFibGUgc3JjLCBmaW5hbCBXcml0YWJsZSB0Z3QpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGNvcHlXcml0YWJsZShnZXRCeXRlcyhzcmMpLCB0Z3QpOworICB9CisKKyAgLyoqCisgICAqIENvcHkgb25lIFdyaXRhYmxlIHRvIGFub3RoZXIuICBDb3BpZXMgYnl0ZXMgdXNpbmcgZGF0YSBzdHJlYW1zLgorICAgKiBAcGFyYW0gYnl0ZXMgU291cmNlIFdyaXRhYmxlCisgICAqIEBwYXJhbSB0Z3QgVGFyZ2V0IFdyaXRhYmxlCisgICAqIEByZXR1cm4gVGhlIHRhcmdldCBXcml0YWJsZS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBXcml0YWJsZSBjb3B5V3JpdGFibGUoZmluYWwgYnl0ZSBbXSBieXRlcywgZmluYWwgV3JpdGFibGUgdGd0KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcykpOworICAgIHRyeSB7CisgICAgICB0Z3QucmVhZEZpZWxkcyhkaXMpOworICAgIH0gZmluYWxseSB7CisgICAgICBkaXMuY2xvc2UoKTsKKyAgICB9CisgICAgcmV0dXJuIHRndDsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYworICAgKiBAcmV0dXJuIENlbGwgdmFsdWUgYXMgYSBVVEYtOCBTdHJpbmcKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNlbGxUb1N0cmluZyhDZWxsIGMpIHsKKyAgICBpZiAoYyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIHJldHVybiBCeXRlcy50b1N0cmluZyhjLmdldFZhbHVlKCkpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGMKKyAgICogQHJldHVybiBDZWxsIGFzIGEgbG9uZy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgbG9uZyBjZWxsVG9Mb25nKENlbGwgYykgeworICAgIGlmIChjID09IG51bGwpIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gQnl0ZXMudG9Mb25nKGMuZ2V0VmFsdWUoKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvSFF1b3J1bVBlZXIuamF2YSBiL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3pvb2tlZXBlci9IUXVvcnVtUGVlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlkMTdiMzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvSFF1b3J1bVBlZXIuamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnpvb2tlZXBlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuc2VydmVyLlNlcnZlckNvbmZpZzsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5zZXJ2ZXIuWm9vS2VlcGVyU2VydmVyTWFpbjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5zZXJ2ZXIucXVvcnVtLlF1b3J1bVBlZXJDb25maWc7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuc2VydmVyLnF1b3J1bS5RdW9ydW1QZWVyTWFpbjsKKworLyoqCisgKiBIQmFzZSdzIHZlcnNpb24gb2YgWm9vS2VlcGVyJ3MgUXVvcnVtUGVlci4gV2hlbiBIQmFzZSBpcyBzZXQgdG8gbWFuYWdlCisgKiBab29LZWVwZXIsIHRoaXMgY2xhc3MgaXMgdXNlZCB0byBzdGFydCB1cCBRdW9ydW1QZWVyIGluc3RhbmNlcy4gQnkgZG9pbmcKKyAqIHRoaW5ncyBpbiBoZXJlIHJhdGhlciB0aGFuIGRpcmVjdGx5IGNhbGxpbmcgdG8gWm9vS2VlcGVyLCB3ZSBoYXZlIG1vcmUKKyAqIGNvbnRyb2wgb3ZlciB0aGUgcHJvY2Vzcy4gQ3VycmVudGx5LCB0aGlzIGNsYXNzIGFsbG93cyB1cyB0byBwYXJzZSB0aGUKKyAqIHpvby5jZmcgYW5kIGluamVjdCB2YXJpYWJsZXMgZnJvbSBIQmFzZSdzIHNpdGUueG1sIGNvbmZpZ3VyYXRpb24gaW4uCisgKi8KK3B1YmxpYyBjbGFzcyBIUXVvcnVtUGVlciBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coSFF1b3J1bVBlZXIuY2xhc3MpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFSSUFCTEVfU1RBUlQgPSAiJHsiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVkFSSUFCTEVfU1RBUlRfTEVOR1RIID0gVkFSSUFCTEVfU1RBUlQubGVuZ3RoKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWQVJJQUJMRV9FTkQgPSAifSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBWQVJJQUJMRV9FTkRfTEVOR1RIID0gVkFSSUFCTEVfRU5ELmxlbmd0aCgpOworCisgIC8qKgorICAgKiBQYXJzZSBab29LZWVwZXIgY29uZmlndXJhdGlvbiBhbmQgcnVuIGEgUXVvcnVtUGVlci4KKyAgICogV2hpbGUgcGFyc2luZyB0aGUgem9vLmNmZywgd2Ugc3Vic3RpdHV0ZSB2YXJpYWJsZXMgd2l0aCB2YWx1ZXMgZnJvbQorICAgKiBoYmFzZS1zaXRlLnhtbC4KKyAgICogQHBhcmFtIGFyZ3MgU3RyaW5nW10gb2YgY29tbWFuZCBsaW5lIGFyZ3VtZW50cy4gTm90IHVzZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgdHJ5IHsKKyAgICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IHBhcnNlWm9vS2VlcGVyQ29uZmlnKCk7CisgICAgICBRdW9ydW1QZWVyQ29uZmlnLnBhcnNlUHJvcGVydGllcyhwcm9wZXJ0aWVzKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIFN5c3RlbS5leGl0KC0xKTsKKyAgICB9CisgICAgaWYgKFNlcnZlckNvbmZpZy5pc1N0YW5kYWxvbmUoKSkgeworICAgICAgWm9vS2VlcGVyU2VydmVyTWFpbi5tYWluKGFyZ3MpOworICAgIH0gZWxzZSB7CisgICAgICBRdW9ydW1QZWVyTWFpbi5ydW5QZWVyRnJvbUNvbmZpZygpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBQYXJzZSBab29LZWVwZXIncyB6b28uY2ZnLCBpbmplY3RpbmcgSEJhc2UgQ29uZmlndXJhdGlvbiB2YXJpYWJsZXMgaW4uCisgICAqIEByZXR1cm4gUHJvcGVydGllcyBwYXJzZWQgZnJvbSBjb25maWcgc3RyZWFtIHdpdGggdmFyaWFibGVzIHN1YnN0aXR1dGVkLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFueXRoaW5nIGdvZXMgd3JvbmcgcGFyc2luZyBjb25maWcKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUHJvcGVydGllcyBwYXJzZVpvb0tlZXBlckNvbmZpZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQ2xhc3NMb2FkZXIgY2wgPSBIUXVvcnVtUGVlci5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOworICAgIElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gY2wuZ2V0UmVzb3VyY2VBc1N0cmVhbShaT09LRUVQRVJfQ09ORklHX05BTUUpOworICAgIGlmIChpbnB1dFN0cmVhbSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oWk9PS0VFUEVSX0NPTkZJR19OQU1FICsgIiBub3QgZm91bmQiKTsKKyAgICB9CisgICAgcmV0dXJuIHBhcnNlQ29uZmlnKGlucHV0U3RyZWFtKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZSBab29LZWVwZXIncyB6b28uY2ZnLCBpbmplY3RpbmcgSEJhc2UgQ29uZmlndXJhdGlvbiB2YXJpYWJsZXMgaW4uCisgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgZm9yIHRlc3Rpbmcgc28gd2UgY2FuIHBhc3Mgb3VyIG93biBJbnB1dFN0cmVhbS4KKyAgICogQHBhcmFtIGlucHV0U3RyZWFtIElucHV0U3RyZWFtIHRvIHJlYWQgZnJvbS4KKyAgICogQHJldHVybiBQcm9wZXJ0aWVzIHBhcnNlZCBmcm9tIGNvbmZpZyBzdHJlYW0gd2l0aCB2YXJpYWJsZXMgc3Vic3RpdHV0ZWQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW55dGhpbmcgZ29lcyB3cm9uZyBwYXJzaW5nIGNvbmZpZworICAgKi8KKyAgcHVibGljIHN0YXRpYyBQcm9wZXJ0aWVzIHBhcnNlQ29uZmlnKElucHV0U3RyZWFtIGlucHV0U3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIFByb3BlcnRpZXMgcHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CisgICAgdHJ5IHsKKyAgICAgIHByb3BlcnRpZXMubG9hZChpbnB1dFN0cmVhbSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgU3RyaW5nIG1zZyA9ICJmYWlsIHRvIHJlYWQgcHJvcGVydGllcyBmcm9tICIgKyBaT09LRUVQRVJfQ09ORklHX05BTUU7CisgICAgICBMT0cuZmF0YWwobXNnKTsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihtc2cpOworICAgIH0KKyAgICBmb3IgKEVudHJ5PE9iamVjdCwgT2JqZWN0PiBlbnRyeSA6IHByb3BlcnRpZXMuZW50cnlTZXQoKSkgeworICAgICAgU3RyaW5nIHZhbHVlID0gZW50cnkuZ2V0VmFsdWUoKS50b1N0cmluZygpLnRyaW0oKTsKKyAgICAgIFN0cmluZ0J1aWxkZXIgbmV3VmFsdWUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgaW50IHZhclN0YXJ0ID0gdmFsdWUuaW5kZXhPZihWQVJJQUJMRV9TVEFSVCk7CisgICAgICBpbnQgdmFyRW5kID0gMDsKKyAgICAgIHdoaWxlICh2YXJTdGFydCAhPSAtMSkgeworICAgICAgICB2YXJFbmQgPSB2YWx1ZS5pbmRleE9mKFZBUklBQkxFX0VORCwgdmFyU3RhcnQpOworICAgICAgICBpZiAodmFyRW5kID09IC0xKSB7CisgICAgICAgICAgU3RyaW5nIG1zZyA9ICJ2YXJpYWJsZSBhdCAiICsgdmFyU3RhcnQgKyAiIGhhcyBubyBlbmQgbWFya2VyIjsKKyAgICAgICAgICBMT0cuZmF0YWwobXNnKTsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24obXNnKTsKKyAgICAgICAgfQorICAgICAgICBTdHJpbmcgdmFyaWFibGUgPSB2YWx1ZS5zdWJzdHJpbmcodmFyU3RhcnQgKyBWQVJJQUJMRV9TVEFSVF9MRU5HVEgsIHZhckVuZCk7CisKKyAgICAgICAgU3RyaW5nIHN1YnN0aXR1dGVWYWx1ZSA9IFN5c3RlbS5nZXRQcm9wZXJ0eSh2YXJpYWJsZSk7CisgICAgICAgIGlmIChzdWJzdGl0dXRlVmFsdWUgPT0gbnVsbCkgeworICAgICAgICAgIHN1YnN0aXR1dGVWYWx1ZSA9IGNvbmYuZ2V0KHZhcmlhYmxlKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3Vic3RpdHV0ZVZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICBTdHJpbmcgbXNnID0gInZhcmlhYmxlICIgKyB2YXJpYWJsZSArICIgbm90IHNldCBpbiBzeXN0ZW0gcHJvcGVydHkgIgorICAgICAgICAgICAgICAgICAgICAgKyAib3IgaGJhc2UgY29uZmlncyI7CisgICAgICAgICAgTE9HLmZhdGFsKG1zZyk7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKG1zZyk7CisgICAgICAgIH0KKyAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciAnaGJhc2UubWFzdGVyLmhvc3RuYW1lJyBwcm9wZXJ0eSBiZWluZyAnbG9jYWwnCisgICAgICAgIGlmICh2YXJpYWJsZS5lcXVhbHMoSENvbnN0YW50cy5NQVNURVJfSE9TVF9OQU1FKSAmJiBzdWJzdGl0dXRlVmFsdWUuZXF1YWxzKCJsb2NhbCIpKSB7CisgICAgICAgICAgc3Vic3RpdHV0ZVZhbHVlID0gImxvY2FsaG9zdCI7CisgICAgICAgIH0KKyAgICAgICAgbmV3VmFsdWUuYXBwZW5kKHN1YnN0aXR1dGVWYWx1ZSk7CisKKyAgICAgICAgdmFyRW5kICs9IFZBUklBQkxFX0VORF9MRU5HVEg7CisgICAgICAgIHZhclN0YXJ0ID0gdmFsdWUuaW5kZXhPZihWQVJJQUJMRV9TVEFSVCwgdmFyRW5kKTsKKyAgICAgIH0KKworICAgICAgbmV3VmFsdWUuYXBwZW5kKHZhbHVlLnN1YnN0cmluZyh2YXJFbmQpKTsKKworICAgICAgU3RyaW5nIGtleSA9IGVudHJ5LmdldEtleSgpLnRvU3RyaW5nKCkudHJpbSgpOworICAgICAgcHJvcGVydGllcy5zZXRQcm9wZXJ0eShrZXksIG5ld1ZhbHVlLnRvU3RyaW5nKCkpOworICAgIH0KKyAgICByZXR1cm4gcHJvcGVydGllczsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2Uvem9va2VlcGVyL1dhdGNoZXJXcmFwcGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvV2F0Y2hlcldyYXBwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmM0MGUwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2phdmEvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2Uvem9va2VlcGVyL1dhdGNoZXJXcmFwcGVyLmphdmEKQEAgLTAsMCArMSw0OSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnpvb2tlZXBlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLldhdGNoZWRFdmVudDsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVyOworCisvKioKKyAqIFBsYWNlLWhvbGRlciBXYXRjaGVyLgorICogRG9lcyBub3RoaW5nIGN1cnJlbnRseS4KKyAqLworcHVibGljIGNsYXNzIFdhdGNoZXJXcmFwcGVyIGltcGxlbWVudHMgV2F0Y2hlciB7CisgIHByaXZhdGUgZmluYWwgV2F0Y2hlciBvdGhlcldhdGNoZXI7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB3aXRoIGEgV2F0Y2hlciB0byBwYXNzIGV2ZW50cyB0by4KKyAgICogQHBhcmFtIG90aGVyV2F0Y2hlciBXYXRjaGVyIHRvIHBhc3MgZXZlbnRzIHRvLgorICAgKi8KKyAgcHVibGljIFdhdGNoZXJXcmFwcGVyKFdhdGNoZXIgb3RoZXJXYXRjaGVyKSB7CisgICAgdGhpcy5vdGhlcldhdGNoZXIgPSBvdGhlcldhdGNoZXI7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGV2ZW50IFdhdGNoZWRFdmVudCBmcm9tIFpvb0tlZXBlci4KKyAgICovCisgIHB1YmxpYyB2b2lkIHByb2Nlc3MoV2F0Y2hlZEV2ZW50IGV2ZW50KSB7CisgICAgaWYgKG90aGVyV2F0Y2hlciAhPSBudWxsKSB7CisgICAgICBvdGhlcldhdGNoZXIucHJvY2VzcyhldmVudCk7CisgICAgfQorICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3pvb2tlZXBlci9ab29LZWVwZXJXcmFwcGVyLmphdmEgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvWm9vS2VlcGVyV3JhcHBlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4ZTFmNWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvWm9vS2VlcGVyV3JhcHBlci5qYXZhCkBAIC0wLDAgKzEsNTM3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKK2ltcG9ydCBqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5Qcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5NYXAuRW50cnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVySW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuU3RyaW5nVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuQ3JlYXRlTW9kZTsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5LZWVwZXJFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5ab29EZWZzLklkczsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5ab29LZWVwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuWm9vS2VlcGVyLlN0YXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5kYXRhLlN0YXQ7CisKKy8qKgorICogV3JhcHMgYSBab29LZWVwZXIgaW5zdGFuY2UgYW5kIGFkZHMgSEJhc2Ugc3BlY2lmaWMgZnVuY3Rpb25hbGl0eS4KKyAqCisgKiBUaGlzIGNsYXNzIHByb3ZpZGVzIG1ldGhvZHMgdG86CisgKiAtIHJlYWQvd3JpdGUvZGVsZXRlIHRoZSByb290IHJlZ2lvbiBsb2NhdGlvbiBpbiBab29LZWVwZXIuCisgKiAtIHNldC9jaGVjayBvdXQgb2Ygc2FmZSBtb2RlIGZsYWcuCisgKi8KK3B1YmxpYyBjbGFzcyBab29LZWVwZXJXcmFwcGVyIGltcGxlbWVudHMgSENvbnN0YW50cyB7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFpvb0tlZXBlcldyYXBwZXIuY2xhc3MpOworCisgIC8vIFRPRE86IFJlcGxhY2UgdGhpcyB3aXRoIFpvb0tlZXBlciBjb25zdGFudCB3aGVuIFpPT0tFRVBFUi0yNzcgaXMgcmVzb2x2ZWQuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgWk5PREVfUEFUSF9TRVBBUkFUT1IgPSAnLyc7CisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHF1b3J1bVNlcnZlcnMgPSBudWxsOworICBzdGF0aWMgeworICAgIGxvYWRab29LZWVwZXJDb25maWcoKTsKKyAgfQorCisgIHByaXZhdGUgZmluYWwgWm9vS2VlcGVyIHpvb0tlZXBlcjsKKyAgcHJpdmF0ZSBmaW5hbCBXYXRjaGVyV3JhcHBlciB3YXRjaGVyOworCisgIHByaXZhdGUgZmluYWwgU3RyaW5nIHJvb3RSZWdpb25aTm9kZTsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgb3V0T2ZTYWZlTW9kZVpOb2RlOworICBwcml2YXRlIGZpbmFsIFN0cmluZyByc1pOb2RlOworICBwcml2YXRlIGZpbmFsIFN0cmluZyBtYXN0ZXJFbGVjdGlvblpOb2RlOworCisgIC8qKgorICAgKiBDcmVhdGUgYSBab29LZWVwZXJXcmFwcGVyLgorICAgKiBAcGFyYW0gY29uZiBIQmFzZUNvbmZpZ3VyYXRpb24gdG8gcmVhZCBzZXR0aW5ncyBmcm9tLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGEgY29ubmVjdGlvbiBlcnJvciBvY2N1cnMuCisgICAqLworICBwdWJsaWMgWm9vS2VlcGVyV3JhcHBlcihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgdGhyb3dzIElPRXhjZXB0aW9uIHsgCisgICAgdGhpcyhjb25mLCBudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBab29LZWVwZXJXcmFwcGVyLgorICAgKiBAcGFyYW0gY29uZiBIQmFzZUNvbmZpZ3VyYXRpb24gdG8gcmVhZCBzZXR0aW5ncyBmcm9tLgorICAgKiBAcGFyYW0gd2F0Y2hlciBab29LZWVwZXIgd2F0Y2hlciB0byByZWdpc3Rlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhIGNvbm5lY3Rpb24gZXJyb3Igb2NjdXJzLgorICAgKi8KKyAgcHVibGljIFpvb0tlZXBlcldyYXBwZXIoSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIFdhdGNoZXIgd2F0Y2hlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAocXVvcnVtU2VydmVycyA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvdWxkIG5vdCByZWFkIHF1b3J1bSBzZXJ2ZXJzIGZyb20gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgWk9PS0VFUEVSX0NPTkZJR19OQU1FKTsKKyAgICB9CisKKyAgICBpbnQgc2Vzc2lvblRpbWVvdXQgPSBjb25mLmdldEludCgiem9va2VlcGVyLnNlc3Npb24udGltZW91dCIsIDEwICogMTAwMCk7CisgICAgdGhpcy53YXRjaGVyID0gbmV3IFdhdGNoZXJXcmFwcGVyKHdhdGNoZXIpOworICAgIHRyeSB7CisgICAgICB6b29LZWVwZXIgPSBuZXcgWm9vS2VlcGVyKHF1b3J1bVNlcnZlcnMsIHNlc3Npb25UaW1lb3V0LCB0aGlzLndhdGNoZXIpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5lcnJvcigiRmFpbGVkIHRvIGNyZWF0ZSBab29LZWVwZXIgb2JqZWN0OiAiICsgZSk7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZSk7CisgICAgfQorCisgICAgU3RyaW5nIHBhcmVudFpOb2RlID0gY29uZi5nZXQoInpvb2tlZXBlci56bm9kZS5wYXJlbnQiLCAiL2hiYXNlIik7CisKKyAgICBTdHJpbmcgcm9vdFNlcnZlclpOb2RlTmFtZSA9IGNvbmYuZ2V0KCJ6b29rZWVwZXIuem5vZGUucm9vdHNlcnZlciIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm9vdC1yZWdpb24tc2VydmVyIik7CisgICAgU3RyaW5nIG91dE9mU2FmZU1vZGVaTm9kZU5hbWUgPSBjb25mLmdldCgiem9va2VlcGVyLnpub2RlLnNhZmVtb2RlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzYWZlLW1vZGUiKTsKKyAgICBTdHJpbmcgcnNaTm9kZU5hbWUgPSBjb25mLmdldCgiem9va2VlcGVyLnpub2RlLnJzIiwgInJzIik7CisgICAgU3RyaW5nIG1hc3RlckFkZHJlc3NaTm9kZU5hbWUgPSBjb25mLmdldCgiem9va2VlcGVyLnpub2RlLm1hc3RlciIsCisgICAgICAibWFzdGVyIik7CisgICAgCisgICAgcm9vdFJlZ2lvblpOb2RlID0gZ2V0Wk5vZGUocGFyZW50Wk5vZGUsIHJvb3RTZXJ2ZXJaTm9kZU5hbWUpOworICAgIG91dE9mU2FmZU1vZGVaTm9kZSA9IGdldFpOb2RlKHBhcmVudFpOb2RlLCBvdXRPZlNhZmVNb2RlWk5vZGVOYW1lKTsKKyAgICByc1pOb2RlID0gZ2V0Wk5vZGUocGFyZW50Wk5vZGUsIHJzWk5vZGVOYW1lKTsKKyAgICBtYXN0ZXJFbGVjdGlvblpOb2RlID0gZ2V0Wk5vZGUocGFyZW50Wk5vZGUsIG1hc3RlckFkZHJlc3NaTm9kZU5hbWUpOworICB9CisKKyAgLyoqCisgICAqIFRoaXMgaXMgZm9yIHRlc3RpbmcgS2VlcGVyRXhjZXB0aW9uLlNlc3Npb25FeHBpcmVkRXhjc2VwdGlvbi4KKyAgICogU2VlIEhCQVNFLTEyMzIuCisgICAqIEByZXR1cm4gbG9uZyBzZXNzaW9uIElEIG9mIHRoaXMgWm9vS2VlcGVyIHNlc3Npb24uCisgICAqLworICBwdWJsaWMgbG9uZyBnZXRTZXNzaW9uSUQoKSB7CisgICAgcmV0dXJuIHpvb0tlZXBlci5nZXRTZXNzaW9uSWQoKTsKKyAgfQorCisgIC8qKgorICAgKiBUaGlzIGlzIGZvciB0ZXN0aW5nIEtlZXBlckV4Y2VwdGlvbi5TZXNzaW9uRXhwaXJlZEV4Y3NlcHRpb24uCisgICAqIFNlZSBIQkFTRS0xMjMyLgorICAgKiBAcmV0dXJuIGJ5dGVbXSBwYXNzd29yZCBvZiB0aGlzIFpvb0tlZXBlciBzZXNzaW9uLgorICAgKi8KKyAgcHVibGljIGJ5dGVbXSBnZXRTZXNzaW9uUGFzc3dvcmQoKSB7CisgICAgcmV0dXJuIHpvb0tlZXBlci5nZXRTZXNzaW9uUGFzc3dkKCk7CisgIH0KKworICAvKioKKyAgICogVGhpcyBpcyBmb3IgdGVzdHMgdG8gZGlyZWN0bHkgc2V0IHRoZSBab29LZWVwZXIgcXVvcnVtIHNlcnZlcnMuCisgICAqIEBwYXJhbSBzZXJ2ZXJzIGNvbW1hIHNlcGFyYXRlZCBob3N0OnBvcnQgWm9vS2VlcGVyIHF1b3J1bSBzZXJ2ZXJzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHNldFF1b3J1bVNlcnZlcnMoU3RyaW5nIHNlcnZlcnMpIHsKKyAgICBxdW9ydW1TZXJ2ZXJzID0gc2VydmVyczsKKyAgfQorCisgIC8qKiBAcmV0dXJuIGNvbW1hIHNlcGFyYXRlZCBob3N0OnBvcnQgbGlzdCBvZiBab29LZWVwZXIgcXVvcnVtIHNlcnZlcnMuICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFF1b3J1bVNlcnZlcnMoKSB7CisgICAgcmV0dXJuIHF1b3J1bVNlcnZlcnM7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRab29LZWVwZXJDb25maWcoKSB7CisgICAgUHJvcGVydGllcyBwcm9wZXJ0aWVzID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgcHJvcGVydGllcyA9IEhRdW9ydW1QZWVyLnBhcnNlWm9vS2VlcGVyQ29uZmlnKCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJmYWlsIHRvIHJlYWQgcHJvcGVydGllcyBmcm9tICIgKyBaT09LRUVQRVJfQ09ORklHX05BTUUpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIFN0cmluZyBjbGllbnRQb3J0ID0gbnVsbDsKKyAgICBMaXN0PFN0cmluZz4gc2VydmVycyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOworCisgICAgLy8gVGhlIGNsaWVudFBvcnQgb3B0aW9uIG1heSBjb21lIGFmdGVyIHRoZSBzZXJ2ZXIuWCBob3N0cywgc28gd2UgbmVlZCB0bworICAgIC8vIGdyYWIgZXZlcnl0aGluZyBhbmQgdGhlbiBjcmVhdGUgdGhlIGZpbmFsIGhvc3Q6cG9ydCBjb21tYSBzZXBhcmF0ZWQgbGlzdC4KKyAgICBib29sZWFuIGFueVZhbGlkID0gZmFsc2U7CisgICAgZm9yIChFbnRyeTxPYmplY3QsT2JqZWN0PiBwcm9wZXJ0eSA6IHByb3BlcnRpZXMuZW50cnlTZXQoKSkgeworICAgICAgU3RyaW5nIGtleSA9IHByb3BlcnR5LmdldEtleSgpLnRvU3RyaW5nKCkudHJpbSgpOworICAgICAgU3RyaW5nIHZhbHVlID0gcHJvcGVydHkuZ2V0VmFsdWUoKS50b1N0cmluZygpLnRyaW0oKTsKKyAgICAgIGlmIChrZXkuZXF1YWxzKCJjbGllbnRQb3J0IikpIHsKKyAgICAgICAgY2xpZW50UG9ydCA9IHZhbHVlOworICAgICAgfQorICAgICAgZWxzZSBpZiAoa2V5LnN0YXJ0c1dpdGgoInNlcnZlci4iKSkgeworICAgICAgICBTdHJpbmcgaG9zdCA9IHZhbHVlLnN1YnN0cmluZygwLCB2YWx1ZS5pbmRleE9mKCc6JykpOworICAgICAgICBzZXJ2ZXJzLmFkZChob3N0KTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoaG9zdCk7CisgICAgICAgICAgYW55VmFsaWQgPSB0cnVlOworICAgICAgICB9IGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLndhcm4oU3RyaW5nVXRpbHMuc3RyaW5naWZ5RXhjZXB0aW9uKGUpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIGlmICghYW55VmFsaWQpIHsKKyAgICAgIExPRy5lcnJvcigibm8gdmFsaWQgcXVvcnVtIHNlcnZlcnMgZm91bmQgaW4gIiArIFpPT0tFRVBFUl9DT05GSUdfTkFNRSk7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKGNsaWVudFBvcnQgPT0gbnVsbCkgeworICAgICAgTE9HLmVycm9yKCJubyBjbGllbnRQb3J0IGZvdW5kIGluICIgKyBaT09LRUVQRVJfQ09ORklHX05BTUUpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChzZXJ2ZXJzLmlzRW1wdHkoKSkgeworICAgICAgTE9HLmZhdGFsKCJObyBzZXJ2ZXIuWCBsaW5lcyBmb3VuZCBpbiBjb25mL3pvby5jZmcuIEhCYXNlIG11c3QgaGF2ZSBhICIgKworICAgICAgICAgICAgICAgICJab29LZWVwZXIgY2x1c3RlciBjb25maWd1cmVkIGZvciBpdHMgb3BlcmF0aW9uLiIpOworICAgICAgU3lzdGVtLmV4aXQoLTEpOworICAgIH0KKworICAgIFN0cmluZ0J1aWxkZXIgaG9zdFBvcnRCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcnZlcnMuc2l6ZSgpOyArK2kpIHsKKyAgICAgIFN0cmluZyBob3N0ID0gc2VydmVycy5nZXQoaSk7CisgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgaG9zdFBvcnRCdWlsZGVyLmFwcGVuZCgnLCcpOworICAgICAgfQorICAgICAgaG9zdFBvcnRCdWlsZGVyLmFwcGVuZChob3N0KTsKKyAgICAgIGhvc3RQb3J0QnVpbGRlci5hcHBlbmQoJzonKTsKKyAgICAgIGhvc3RQb3J0QnVpbGRlci5hcHBlbmQoY2xpZW50UG9ydCk7CisgICAgfQorCisgICAgcXVvcnVtU2VydmVycyA9IGhvc3RQb3J0QnVpbGRlci50b1N0cmluZygpOworICAgIExPRy5pbmZvKCJRdW9ydW0gc2VydmVyczogIiArIHF1b3J1bVNlcnZlcnMpOworICB9CisKKyAgLyoqIEByZXR1cm4gdHJ1ZSBpZiBjdXJyZW50bHkgY29ubmVjdGVkIHRvIFpvb0tlZXBlciwgZmFsc2Ugb3RoZXJ3aXNlLiAqLworICBwdWJsaWMgYm9vbGVhbiBpc0Nvbm5lY3RlZCgpIHsKKyAgICByZXR1cm4gem9vS2VlcGVyLmdldFN0YXRlKCkgPT0gU3RhdGVzLkNPTk5FQ1RFRDsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkIGxvY2F0aW9uIG9mIHNlcnZlciBzdG9yaW5nIHJvb3QgcmVnaW9uLgorICAgKiBAcmV0dXJuIEhTZXJ2ZXJBZGRyZXNzIHBvaW50aW5nIHRvIHNlcnZlciBzZXJ2aW5nIHJvb3QgcmVnaW9uIG9yIG51bGwgaWYKKyAgICogICAgICAgICB0aGVyZSB3YXMgYSBwcm9ibGVtIHJlYWRpbmcgdGhlIFpOb2RlLgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzIHJlYWRSb290UmVnaW9uTG9jYXRpb24oKSB7CisgICAgcmV0dXJuIHJlYWRBZGRyZXNzKHJvb3RSZWdpb25aTm9kZSwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogUmVhZCBhZGRyZXNzIG9mIG1hc3RlciBzZXJ2ZXIuCisgICAqIEByZXR1cm4gSFNlcnZlckFkZHJlc3Mgb2YgbWFzdGVyIHNlcnZlci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGVyZSdzIGEgcHJvYmxlbSByZWFkaW5nIHRoZSBaTm9kZS4KKyAgICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyByZWFkTWFzdGVyQWRkcmVzc09yVGhyb3coKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkQWRkcmVzc09yVGhyb3cobWFzdGVyRWxlY3Rpb25aTm9kZSwgbnVsbCk7CisgIH0KKworICAvKioKKyAgICogUmVhZCBtYXN0ZXIgYWRkcmVzcyBhbmQgc2V0IGEgd2F0Y2ggb24gaXQuCisgICAqIEBwYXJhbSB3YXRjaGVyIFdhdGNoZXIgdG8gc2V0IG9uIG1hc3RlciBhZGRyZXNzIFpOb2RlIGlmIG5vdCBudWxsLgorICAgKiBAcmV0dXJuIEhTZXJ2ZXJBZGRyZXNzIG9mIG1hc3RlciBvciBudWxsIGlmIHRoZXJlIHdhcyBhIHByb2JsZW0gcmVhZGluZyB0aGUKKyAgICogICAgICAgICBaTm9kZS4gVGhlIHdhdGNoZXIgaXMgc2V0IG9ubHkgaWYgdGhlIHJlc3VsdCBpcyBub3QgbnVsbC4KKyAgICovCisgIHB1YmxpYyBIU2VydmVyQWRkcmVzcyByZWFkTWFzdGVyQWRkcmVzcyhXYXRjaGVyIHdhdGNoZXIpIHsKKyAgICByZXR1cm4gcmVhZEFkZHJlc3MobWFzdGVyRWxlY3Rpb25aTm9kZSwgd2F0Y2hlcik7CisgIH0KKworICAvKioKKyAgICogU2V0IGEgd2F0Y2hlciBvbiB0aGUgbWFzdGVyIGFkZHJlc3MgWk5vZGUuIFRoZSB3YXRjaGVyIHdpbGwgYmUgc2V0IHVubGVzcworICAgKiBhbiBleGNlcHRpb24gb2NjdXJzIHdpdGggWm9vS2VlcGVyLgorICAgKiBAcGFyYW0gd2F0Y2hlciBXYXRjaGVyIHRvIHNldCBvbiBtYXN0ZXIgYWRkcmVzcyBaTm9kZS4KKyAgICogQHJldHVybiB0cnVlIGlmIHdhdGNoZXIgd2FzIHNldCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gd2F0Y2hNYXN0ZXJBZGRyZXNzKFdhdGNoZXIgd2F0Y2hlcikgeworICAgIHRyeSB7CisgICAgICB6b29LZWVwZXIuZXhpc3RzKG1hc3RlckVsZWN0aW9uWk5vZGUsIHdhdGNoZXIpOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHNldCB3YXRjaGVyIG9uIFpOb2RlICIgKyBtYXN0ZXJFbGVjdGlvblpOb2RlLCBlKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHNldCB3YXRjaGVyIG9uIFpOb2RlICIgKyBtYXN0ZXJFbGVjdGlvblpOb2RlLCBlKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgTE9HLmRlYnVnKCJTZXQgd2F0Y2hlciBvbiBtYXN0ZXIgYWRkcmVzcyBaTm9kZSAiICsgbWFzdGVyRWxlY3Rpb25aTm9kZSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBwcml2YXRlIEhTZXJ2ZXJBZGRyZXNzIHJlYWRBZGRyZXNzKFN0cmluZyB6bm9kZSwgV2F0Y2hlciB3YXRjaGVyKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiByZWFkQWRkcmVzc09yVGhyb3coem5vZGUsIHdhdGNoZXIpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgSFNlcnZlckFkZHJlc3MgcmVhZEFkZHJlc3NPclRocm93KFN0cmluZyB6bm9kZSwgV2F0Y2hlciB3YXRjaGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGVbXSBkYXRhOworICAgIHRyeSB7CisgICAgICBkYXRhID0gem9vS2VlcGVyLmdldERhdGEoem5vZGUsIHdhdGNoZXIsIG51bGwpOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICB9IGNhdGNoIChLZWVwZXJFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgIH0KKworICAgIFN0cmluZyBhZGRyZXNzU3RyaW5nID0gQnl0ZXMudG9TdHJpbmcoZGF0YSk7CisgICAgTE9HLmRlYnVnKCJSZWFkIFpOb2RlICIgKyB6bm9kZSArICIgZ290ICIgKyBhZGRyZXNzU3RyaW5nKTsKKyAgICBIU2VydmVyQWRkcmVzcyBhZGRyZXNzID0gbmV3IEhTZXJ2ZXJBZGRyZXNzKGFkZHJlc3NTdHJpbmcpOworICAgIHJldHVybiBhZGRyZXNzOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGVuc3VyZUV4aXN0cyhmaW5hbCBTdHJpbmcgem5vZGUpIHsKKyAgICB0cnkgeworICAgICAgem9vS2VlcGVyLmNyZWF0ZSh6bm9kZSwgbmV3IGJ5dGVbMF0sCisgICAgICAgICAgICAgICAgICAgICAgIElkcy5PUEVOX0FDTF9VTlNBRkUsIENyZWF0ZU1vZGUuUEVSU0lTVEVOVCk7CisgICAgICBMT0cuZGVidWcoIkNyZWF0ZWQgWk5vZGUgIiArIHpub2RlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbi5Ob2RlRXhpc3RzRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiB0cnVlOyAgICAgIC8vIG9rLCBtb3ZlIG9uLgorICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbi5Ob05vZGVFeGNlcHRpb24gZSkgeworICAgICAgcmV0dXJuIGVuc3VyZVBhcmVudEV4aXN0cyh6bm9kZSkgJiYgZW5zdXJlRXhpc3RzKHpub2RlKTsKKyAgICB9IGNhdGNoIChLZWVwZXJFeGNlcHRpb24gZSkgeworICAgICAgTE9HLndhcm4oIkZhaWxlZCB0byBjcmVhdGUgIiArIHpub2RlICsgIjoiLCBlKTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGNyZWF0ZSAiICsgem5vZGUgKyAiOiIsIGUpOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gZW5zdXJlUGFyZW50RXhpc3RzKGZpbmFsIFN0cmluZyB6bm9kZSkgeworICAgIGludCBpbmRleCA9IHpub2RlLmxhc3RJbmRleE9mKFpOT0RFX1BBVEhfU0VQQVJBVE9SKTsKKyAgICBpZiAoaW5kZXggPD0gMCkgeyAgIC8vIFBhcmVudCBpcyByb290LCB3aGljaCBhbHdheXMgZXhpc3RzLgorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBlbnN1cmVFeGlzdHMoem5vZGUuc3Vic3RyaW5nKDAsIGluZGV4KSk7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlIFpOb2RlIGNvbnRhaW5pbmcgcm9vdCByZWdpb24gbG9jYXRpb24uCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBvcGVyYXRpb24gc3VjY2VlZGVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBkZWxldGVSb290UmVnaW9uTG9jYXRpb24oKSAgeworICAgIGlmICghZW5zdXJlUGFyZW50RXhpc3RzKHJvb3RSZWdpb25aTm9kZSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgem9vS2VlcGVyLmRlbGV0ZShyb290UmVnaW9uWk5vZGUsIC0xKTsKKyAgICAgIExPRy5kZWJ1ZygiRGVsZXRlZCBaTm9kZSAiICsgcm9vdFJlZ2lvblpOb2RlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbi5Ob05vZGVFeGNlcHRpb24gZSkgeworICAgICAgcmV0dXJuIHRydWU7ICAgIC8vIG9rLCBtb3ZlIG9uLgorICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGRlbGV0ZSAiICsgcm9vdFJlZ2lvblpOb2RlICsgIjogIiArIGUpOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgdG8gZGVsZXRlICIgKyByb290UmVnaW9uWk5vZGUgKyAiOiAiICsgZSk7CisgICAgfQorCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGNyZWF0ZVJvb3RSZWdpb25Mb2NhdGlvbihTdHJpbmcgYWRkcmVzcykgeworICAgIGJ5dGVbXSBkYXRhID0gQnl0ZXMudG9CeXRlcyhhZGRyZXNzKTsKKyAgICB0cnkgeworICAgICAgem9vS2VlcGVyLmNyZWF0ZShyb290UmVnaW9uWk5vZGUsIGRhdGEsIElkcy5PUEVOX0FDTF9VTlNBRkUsCisgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZU1vZGUuUEVSU0lTVEVOVCk7CisgICAgICBMT0cuZGVidWcoIkNyZWF0ZWQgWk5vZGUgIiArIHJvb3RSZWdpb25aTm9kZSArICIgd2l0aCBkYXRhICIgKyBhZGRyZXNzKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGNyZWF0ZSByb290IHJlZ2lvbiBpbiBab29LZWVwZXI6ICIgKyBlKTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGNyZWF0ZSByb290IHJlZ2lvbiBpbiBab29LZWVwZXI6ICIgKyBlKTsKKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gdXBkYXRlUm9vdFJlZ2lvbkxvY2F0aW9uKFN0cmluZyBhZGRyZXNzKSB7CisgICAgYnl0ZVtdIGRhdGEgPSBCeXRlcy50b0J5dGVzKGFkZHJlc3MpOworICAgIHRyeSB7CisgICAgICB6b29LZWVwZXIuc2V0RGF0YShyb290UmVnaW9uWk5vZGUsIGRhdGEsIC0xKTsKKyAgICAgIExPRy5kZWJ1ZygiU2V0RGF0YSBvZiBaTm9kZSAiICsgcm9vdFJlZ2lvblpOb2RlICsgIiB3aXRoICIgKyBhZGRyZXNzKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHNldCByb290IHJlZ2lvbiBsb2NhdGlvbiBpbiBab29LZWVwZXI6ICIgKyBlKTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHNldCByb290IHJlZ2lvbiBsb2NhdGlvbiBpbiBab29LZWVwZXI6ICIgKyBlKTsKKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgcm9vdCByZWdpb24gbG9jYXRpb24gdG8gWm9vS2VlcGVyLiBJZiBhZGRyZXNzIGlzIG51bGwsIGRlbGV0ZSBaTm9kZS4KKyAgICogY29udGFpbmluZyByb290IHJlZ2lvbiBsb2NhdGlvbi4KKyAgICogQHBhcmFtIGFkZHJlc3MgSFNlcnZlckFkZHJlc3MgdG8gd3JpdGUgdG8gWksuCisgICAqIEByZXR1cm4gdHJ1ZSBpZiBvcGVyYXRpb24gc3VjY2VlZGVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiB3cml0ZVJvb3RSZWdpb25Mb2NhdGlvbihIU2VydmVyQWRkcmVzcyBhZGRyZXNzKSB7CisgICAgaWYgKGFkZHJlc3MgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIGRlbGV0ZVJvb3RSZWdpb25Mb2NhdGlvbigpOworICAgIH0KKworICAgIGlmICghZW5zdXJlUGFyZW50RXhpc3RzKHJvb3RSZWdpb25aTm9kZSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBTdHJpbmcgYWRkcmVzc1N0cmluZyA9IGFkZHJlc3MudG9TdHJpbmcoKTsKKworICAgIGlmIChjaGVja0V4aXN0ZW5jZU9mKHJvb3RSZWdpb25aTm9kZSkpIHsKKyAgICAgIHJldHVybiB1cGRhdGVSb290UmVnaW9uTG9jYXRpb24oYWRkcmVzc1N0cmluZyk7CisgICAgfQorCisgICAgcmV0dXJuIGNyZWF0ZVJvb3RSZWdpb25Mb2NhdGlvbihhZGRyZXNzU3RyaW5nKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhZGRyZXNzIG9mIG1hc3RlciB0byBab29LZWVwZXIuCisgICAqIEBwYXJhbSBhZGRyZXNzIEhTZXJ2ZXJBZGRyZXNzIG9mIG1hc3Rlci4KKyAgICogQHJldHVybiB0cnVlIGlmIG9wZXJhdGlvbiBzdWNjZWVkZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICovCisgIHB1YmxpYyBib29sZWFuIHdyaXRlTWFzdGVyQWRkcmVzcyhIU2VydmVyQWRkcmVzcyBhZGRyZXNzKSB7CisgICAgaWYgKCFlbnN1cmVQYXJlbnRFeGlzdHMobWFzdGVyRWxlY3Rpb25aTm9kZSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBTdHJpbmcgYWRkcmVzc1N0ciA9IGFkZHJlc3MudG9TdHJpbmcoKTsKKyAgICBieXRlW10gZGF0YSA9IEJ5dGVzLnRvQnl0ZXMoYWRkcmVzc1N0cik7CisgICAgdHJ5IHsKKyAgICAgIHpvb0tlZXBlci5jcmVhdGUobWFzdGVyRWxlY3Rpb25aTm9kZSwgZGF0YSwgSWRzLk9QRU5fQUNMX1VOU0FGRSwgQ3JlYXRlTW9kZS5FUEhFTUVSQUwpOworICAgICAgTE9HLmRlYnVnKCJXcm90ZSBtYXN0ZXIgYWRkcmVzcyAiICsgYWRkcmVzcyArICIgdG8gWm9vS2VlcGVyIik7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIHdyaXRlIG1hc3RlciBhZGRyZXNzICIgKyBhZGRyZXNzICsgIiB0byBab29LZWVwZXIiLCBlKTsKKyAgICB9IGNhdGNoIChLZWVwZXJFeGNlcHRpb24gZSkgeworICAgICAgTE9HLndhcm4oIkZhaWxlZCB0byB3cml0ZSBtYXN0ZXIgYWRkcmVzcyAiICsgYWRkcmVzcyArICIgdG8gWm9vS2VlcGVyIiwgZSk7CisgICAgfQorCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIGlmIHdlJ3JlIG91dCBvZiBzYWZlIG1vZGUuIEJlaW5nIG91dCBvZiBzYWZlIG1vZGUgaXMgc2lnbmlmaWVkIGJ5IGFuCisgICAqIGVwaGVtZXJhbCBaTm9kZSBleGlzdGluZyBpbiBab29LZWVwZXIuCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB3ZSdyZSBvdXQgb2Ygc2FmZSBtb2RlLCBmYWxzZSBvdGhlcndpc2UuCisgICAqLworICBwdWJsaWMgYm9vbGVhbiBjaGVja091dE9mU2FmZU1vZGUoKSB7CisgICAgaWYgKCFlbnN1cmVQYXJlbnRFeGlzdHMob3V0T2ZTYWZlTW9kZVpOb2RlKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiBjaGVja0V4aXN0ZW5jZU9mKG91dE9mU2FmZU1vZGVaTm9kZSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGVwaGVtZXJhbCBaTm9kZSBzaWduaWZ5aW5nIHRoYXQgd2UncmUgb3V0IG9mIHNhZmUgbW9kZS4KKyAgICogQHJldHVybiB0cnVlIGlmIGVwaGVtZXJhbCBaTm9kZSBjcmVhdGVkIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gd3JpdGVPdXRPZlNhZmVNb2RlKCkgeworICAgIGlmICghZW5zdXJlUGFyZW50RXhpc3RzKG91dE9mU2FmZU1vZGVaTm9kZSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB0cnkgeworICAgICAgem9vS2VlcGVyLmNyZWF0ZShvdXRPZlNhZmVNb2RlWk5vZGUsIG5ldyBieXRlWzBdLCBJZHMuT1BFTl9BQ0xfVU5TQUZFLAorICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGVNb2RlLkVQSEVNRVJBTCk7CisgICAgICBMT0cuZGVidWcoIldyb3RlIG91dCBvZiBzYWZlIG1vZGUiKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgdG8gY3JlYXRlIG91dCBvZiBzYWZlIG1vZGUgaW4gWm9vS2VlcGVyOiAiICsgZSk7CisgICAgfSBjYXRjaCAoS2VlcGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgdG8gY3JlYXRlIG91dCBvZiBzYWZlIG1vZGUgaW4gWm9vS2VlcGVyOiAiICsgZSk7CisgICAgfQorCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIAorICAvKioKKyAgICogV3JpdGUgaW4gWksgdGhpcyBSUyBzdGFydENvZGUgYW5kIGFkZHJlc3MuCisgICAqIEVuc3VyZXMgdGhhdCB0aGUgZnVsbCBwYXRoIGV4aXN0cy4KKyAgICogQHBhcmFtIGluZm8gVGhlIFJTIGluZm8KKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBsb2NhdGlvbiB3YXMgd3JpdHRlbiwgZmFsc2UgaWYgaXQgZmFpbGVkCisgICAqLworICBwdWJsaWMgYm9vbGVhbiB3cml0ZVJTTG9jYXRpb24oSFNlcnZlckluZm8gaW5mbykgeworICAgIGVuc3VyZUV4aXN0cyhyc1pOb2RlKTsKKyAgICBieXRlW10gZGF0YSA9IEJ5dGVzLnRvQnl0ZXMoaW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkuZ2V0QmluZEFkZHJlc3MoKSk7CisgICAgU3RyaW5nIHpub2RlID0gam9pblBhdGgocnNaTm9kZSwgTG9uZy50b1N0cmluZyhpbmZvLmdldFN0YXJ0Q29kZSgpKSk7CisgICAgdHJ5IHsKKyAgICAgIHpvb0tlZXBlci5jcmVhdGUoem5vZGUsIGRhdGEsIElkcy5PUEVOX0FDTF9VTlNBRkUsIENyZWF0ZU1vZGUuRVBIRU1FUkFMKTsKKyAgICAgIExPRy5kZWJ1ZygiQ3JlYXRlZCBaTm9kZSAiICsgem5vZGUKKyAgICAgICAgICArICIgd2l0aCBkYXRhICIgKyBpbmZvLmdldFNlcnZlckFkZHJlc3MoKS5nZXRCaW5kQWRkcmVzcygpKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiRmFpbGVkIHRvIGNyZWF0ZSAiICsgem5vZGUgKyAiIHpub2RlIGluIFpvb0tlZXBlcjogIiArIGUpOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgdG8gY3JlYXRlICIgKyB6bm9kZSArICIgem5vZGUgaW4gWm9vS2VlcGVyOiAiICsgZSk7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8qKgorICAgKiBVcGRhdGUgdGhlIFJTIGFkZHJlc3MgYW5kIHNldCBhIHdhdGNoZXIgb24gdGhlIHpub2RlCisgICAqIEBwYXJhbSBpbmZvIFRoZSBSUyBpbmZvCisgICAqIEBwYXJhbSB3YXRjaGVyIFRoZSB3YXRjaGVyIHRvIHB1dCBvbiB0aGUgem5vZGUKKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSB1cGRhdGUgaXMgZG9uZSwgZmFsc2UgaWYgaXQgZmFpbGVkCisgICAqLworICBwdWJsaWMgYm9vbGVhbiB1cGRhdGVSU0xvY2F0aW9uR2V0V2F0Y2goSFNlcnZlckluZm8gaW5mbywgV2F0Y2hlciB3YXRjaGVyKSB7CisgICAgYnl0ZVtdIGRhdGEgPSBCeXRlcy50b0J5dGVzKGluZm8uZ2V0U2VydmVyQWRkcmVzcygpLmdldEJpbmRBZGRyZXNzKCkpOworICAgIFN0cmluZyB6bm9kZSA9IHJzWk5vZGUgKyAiLyIgKyBpbmZvLmdldFN0YXJ0Q29kZSgpOworICAgIHRyeSB7CisgICAgICB6b29LZWVwZXIuc2V0RGF0YSh6bm9kZSwgZGF0YSwgLTEpOworICAgICAgTE9HLmRlYnVnKCJVcGRhdGVkIFpOb2RlICIgKyB6bm9kZQorICAgICAgICAgICsgIiB3aXRoIGRhdGEgIiArIGluZm8uZ2V0U2VydmVyQWRkcmVzcygpLmdldEJpbmRBZGRyZXNzKCkpOworICAgICAgem9vS2VlcGVyLmdldERhdGEoem5vZGUsIHdhdGNoZXIsIG51bGwpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfSBjYXRjaCAoS2VlcGVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy53YXJuKCJGYWlsZWQgdG8gdXBkYXRlICIgKyB6bm9kZSArICIgem5vZGUgaW4gWm9vS2VlcGVyOiAiICsgZSk7CisgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgTE9HLndhcm4oIkZhaWxlZCB0byB1cGRhdGUgIiArIHpub2RlICsgIiB6bm9kZSBpbiBab29LZWVwZXI6ICIgKyBlKTsKKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgCisgIHByaXZhdGUgYm9vbGVhbiBjaGVja0V4aXN0ZW5jZU9mKFN0cmluZyBwYXRoKSB7CisgICAgU3RhdCBzdGF0ID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgc3RhdCA9IHpvb0tlZXBlci5leGlzdHMocGF0aCwgZmFsc2UpOworICAgIH0gY2F0Y2ggKEtlZXBlckV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiY2hlY2tpbmcgZXhpc3RlbmNlIG9mICIgKyBwYXRoLCBlKTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cud2FybigiY2hlY2tpbmcgZXhpc3RlbmNlIG9mICIgKyBwYXRoLCBlKTsKKyAgICB9CisKKyAgICByZXR1cm4gc3RhdCAhPSBudWxsOworICB9CisKKyAgLyoqCisgICAqIENsb3NlIHRoaXMgWm9vS2VlcGVyIHNlc3Npb24uCisgICAqLworICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKKyAgICB0cnkgeworICAgICAgem9vS2VlcGVyLmNsb3NlKCk7CisgICAgICBMT0cuZGVidWcoIkNsb3NlZCBjb25uZWN0aW9uIHdpdGggWm9vS2VlcGVyIik7CisgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgTE9HLndhcm4oIkZhaWxlZCB0byBjbG9zZSBjb25uZWN0aW9uIHdpdGggWm9vS2VlcGVyIik7CisgICAgfQorICB9CisgIAorICBwcml2YXRlIFN0cmluZyBnZXRaTm9kZShTdHJpbmcgcGFyZW50Wk5vZGUsIFN0cmluZyB6bm9kZU5hbWUpIHsKKyAgICByZXR1cm4gem5vZGVOYW1lLmNoYXJBdCgwKSA9PSBaTk9ERV9QQVRIX1NFUEFSQVRPUiA/CisgICAgICAgIHpub2RlTmFtZSA6IGpvaW5QYXRoKHBhcmVudFpOb2RlLCB6bm9kZU5hbWUpOworICB9CisKKyAgcHJpdmF0ZSBTdHJpbmcgam9pblBhdGgoU3RyaW5nIHBhcmVudCwgU3RyaW5nIGNoaWxkKSB7CisgICAgcmV0dXJuIHBhcmVudCArIFpOT0RFX1BBVEhfU0VQQVJBVE9SICsgY2hpbGQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9qYXZhL292ZXJ2aWV3Lmh0bWwgYi9zcmMvamF2YS9vdmVydmlldy5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2NTJiYjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvamF2YS9vdmVydmlldy5odG1sCkBAIC0wLDAgKzEsMzMzIEBACis8IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIj4KKzxodG1sPgorCis8IS0tCisgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAgIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAorICAgdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLgorICAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyAgICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCisgICB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLS0+CisKKzxoZWFkPgorICAgIDx0aXRsZT5IQmFzZTwvdGl0bGU+Cis8L2hlYWQ+Cis8Ym9keSBiZ2NvbG9yPSJ3aGl0ZSI+Cis8YSBocmVmPSJodHRwOi8vaGJhc2Uub3JnIj5IQmFzZTwvYT4gaXMgYSBzY2FsYWJsZSwgZGlzdHJpYnV0ZWQgZGF0YWJhc2UgYnVpbHQgb24gPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL2NvcmUiPkhhZG9vcCBDb3JlPC9hPi4KKworPGgyPjxhIG5hbWU9InJlcXVpcmVtZW50cyI+UmVxdWlyZW1lbnRzPC9hPjwvaDI+Cis8dWw+CisgIDxsaT5KYXZhIDEuNi54LCBwcmVmZXJhYmx5IGZyb20gPGEgaHJlZj0iaHR0cDovL3d3dy5qYXZhLmNvbS9lbi9kb3dubG9hZC8iPlN1bjwvYT4uCisgIDwvbGk+CisgIDxsaT48YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9yZWxlYXNlcy5odG1sIj5IYWRvb3AgMC4xOS54PC9hPi4gIFRoaXMgdmVyc2lvbiBvZiBIQmFzZSB3aWxsIAorICBvbmx5IHJ1biBvbiB0aGlzIHZlcnNpb24gb2YgSGFkb29wLgorICA8L2xpPgorICA8bGk+CisgICAgc3NoIG11c3QgYmUgaW5zdGFsbGVkIGFuZCBzc2hkIG11c3QgYmUgcnVubmluZyB0byB1c2UgSGFkb29wJ3MKKyAgICBzY3JpcHRzIHRvIG1hbmFnZSByZW1vdGUgSGFkb29wIGRhZW1vbnMuCisgIDwvbGk+CisgIDxsaT5IQmFzZSBjdXJyZW50bHkgaXMgYSBmaWxlIGhhbmRsZSBob2cuICBUaGUgdXN1YWwgZGVmYXVsdCBvZgorICAxMDI0IG9uICpuaXggc3lzdGVtcyBpcyBpbnN1ZmZpY2llbnQgaWYgeW91IGFyZSBsb2FkaW5nIGFueSBzaWduaWZpY2FudAorICBhbW91bnQgb2YgZGF0YSBpbnRvIHJlZ2lvbnNlcnZlcnMuICBTZWUgdGhlCisgIDxhIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL0hiYXNlL0ZBUSM2Ij5GQVE6IFdoeSBkbyBJIHNlZSAiamF2YS5pby5JT0V4Y2VwdGlvbi4uLihUb28gbWFueSBvcGVuIGZpbGVzKSIgaW4gbXkgbG9ncz88L2E+CisgIGZvciBob3cgdG8gdXAgdGhlIGxpbWl0LiAgQWxzbywgYXMgb2YgMC4xOC54IGhhZG9vcCwgZGF0YW5vZGVzIGhhdmUgYW4gdXBwZXItYm91bmQKKyAgICAgIG9uIHRoZSBudW1iZXIgb2YgdGhyZWFkcyB0aGV5IHdpbGwgc3VwcG9ydCAoPGNvZGU+ZGZzLmRhdGFub2RlLm1heC54Y2lldmVyczwvY29kZT4pLgorICAgICAgRGVmYXVsdCBpcyAyNTYuICBJZiBsb2FkaW5nIGxvdHMgb2YgZGF0YSBpbnRvIGhiYXNlLCB1cCB0aGlzIGxpbWl0IG9uIHlvdXIKKyAgICAgIGhhZG9vcCBjbHVzdGVyLiAgQWxzbyBjb25zaWRlciB1cHBpbmcgdGhlIG51bWJlciBvZiBkYXRhbm9kZSBoYW5kbGVycyBmcm9tCisgICAgICB0aGUgZGVmYXVsdCBvZiAzLiBTZWUgPGNvZGU+ZGZzLmRhdGFub2RlLmhhbmRsZXIuY291bnQ8L2NvZGU+LjwvbGk+CisgICAgICA8bGk+VGhlIGNsb2NrcyBvbiBjbHVzdGVyIG1lbWJlcnMgc2hvdWxkIGJlIGluIGJhc2ljIGFsaWdubWVudHMuICBTb21lIHNrZXcgaXMgdG9sZXJhYmxlIGJ1dAorICAgICAgd2lsZCBza2V3IGNhbiBnZW5lcmF0ZSBvZGQgYmVoYXZpb3JzLiAgUnVuIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTmV0d29ya19UaW1lX1Byb3RvY29sIj5OVFA8L2E+CisgICAgICBvbiB5b3VyIGNsdXN0ZXIsIG9yIGFuIGVxdWl2YWxlbnQuPC9saT4KKzwvdWw+Cis8aDM+V2luZG93czwvaDM+CitJZiB5b3UgYXJlIHJ1bm5pbmcgSEJhc2Ugb24gV2luZG93cywgeW91IG11c3QgaW5zdGFsbCA8YSBocmVmPSJodHRwOi8vY3lnd2luLmNvbS8iPkN5Z3dpbjwvYT4uIEFkZGl0aW9uYWxseSwgaXQgaXMgPGVtcGg+c3Ryb25nbHkgcmVjb21tZW5kZWQ8L2VtcGg+IHRoYXQgeW91IGFkZCBvciBhcHBlbmQgdG8gdGhlIGZvbGxvd2luZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMuIElmIHlvdSBpbnN0YWxsIEN5Z3dpbiBpbiBhIGxvY2F0aW9uIHRoYXQgaXMgbm90IEM6XGN5Z3dpbiB5b3Ugc2hvdWxkIG1vZGlmeSB0aGUgZm9sbG93aW5nIGFwcHJvcHJpYXRlbHkuCis8cD4KKzxwcmU+CitIT01FPWM6XGN5Z3dpblxob21lXGppbQorQU5UX0hPTUU9KHdoZXJldmVyIHlvdSBpbnN0YWxsZWQgYW50KQorSkFWQV9IT01FPSh3aGVyZXZlciB5b3UgaW5zdGFsbGVkIGphdmEpIAorUEFUSD1DOlxjeWd3aW5cYmluOyVKQVZBX0hPTUUlXGJpbjslQU5UX0hPTUUlXGJpbjsgb3RoZXIgd2luZG93cyBzdHVmZiAKK1NIRUxMPS9iaW4vYmFzaAorPC9wcmU+CitGb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiwgc2VlIHRoZSA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvY29yZS9kb2NzL2N1cnJlbnQvcXVpY2tzdGFydC5odG1sIj5IYWRvb3AgUXVpY2sgU3RhcnQgR3VpZGU8L2E+Cis8L3A+Cis8aDI+PGEgbmFtZT0iZ2V0dGluZ19zdGFydGVkIiA+R2V0dGluZyBTdGFydGVkPC9hPjwvaDI+Cis8cD4KK1doYXQgZm9sbG93cyBwcmVzdW1lcyB5b3UgaGF2ZSBvYnRhaW5lZCBhIGNvcHkgb2YgSEJhc2UgYW5kIGFyZSBpbnN0YWxsaW5nCitmb3IgdGhlIGZpcnN0IHRpbWUuIElmIHVwZ3JhZGluZyB5b3VyCitIQmFzZSBpbnN0YW5jZSwgc2VlIDxhIGhyZWY9IiN1cGdyYWRpbmciPlVwZ3JhZGluZzwvYT4uCis8L3A+Cis8cD4KK0RlZmluZSA8Y29kZT4ke0hCQVNFX0hPTUV9PC9jb2RlPiB0byBiZSB0aGUgbG9jYXRpb24gb2YgdGhlIHJvb3Qgb2YgeW91ciBIQmFzZSBpbnN0YWxsYXRpb24sIGUuZy4gCis8Y29kZT4vdXNlci9sb2NhbC9oYmFzZTwvY29kZT4uICBFZGl0IDxjb2RlPiR7SEJBU0VfSE9NRX0vY29uZi9oYmFzZS1lbnYuc2g8L2NvZGU+LiAgSW4gdGhpcyBmaWxlIHlvdSBjYW4KK3NldCB0aGUgaGVhcHNpemUgZm9yIEhCYXNlLCBldGMuICBBdCBhIG1pbmltdW0sIHNldCA8Y29kZT5KQVZBX0hPTUU8L2NvZGU+IHRvIHBvaW50IGF0IHRoZSByb290IG9mCit5b3VyIEphdmEgaW5zdGFsbGF0aW9uLgorPC9wPgorPHA+CitJZiB5b3UgYXJlIHJ1bm5pbmcgYSBzdGFuZGFsb25lIG9wZXJhdGlvbiwgdGhlcmUgc2hvdWxkIGJlIG5vdGhpbmcgZnVydGhlciB0byBjb25maWd1cmU7IHByb2NlZWQgdG8KKzxhIGhyZWY9I3J1bmFuZGNvbmZpcm0+UnVubmluZyBhbmQgQ29uZmlybWluZyBZb3VyIEluc3RhbGxhdGlvbjwvYT4uICBJZiB5b3UgYXJlIHJ1bm5pbmcgYSBkaXN0cmlidXRlZCAKK29wZXJhdGlvbiwgY29udGludWUgcmVhZGluZy4KKzwvcD4KKworPGgyPjxhIG5hbWU9ImRpc3RyaWJ1dGVkIj5EaXN0cmlidXRlZCBPcGVyYXRpb248L2E+PC9oMj4KKzxwPkRpc3RyaWJ1dGVkIG1vZGUgcmVxdWlyZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIEhhZG9vcCBEaXN0cmlidXRlZCBGaWxlIFN5c3RlbSAoREZTKSBhbmQgYSBab29LZWVwZXIgY2x1c3Rlci4KK1NlZSB0aGUgSGFkb29wIDxhIGhyZWY9Imh0dHA6Ly9sdWNlbmUuYXBhY2hlLm9yZy9oYWRvb3AvYXBpL292ZXJ2aWV3LXN1bW1hcnkuaHRtbCNvdmVydmlld19kZXNjcmlwdGlvbiI+CityZXF1aXJlbWVudHMgYW5kIGluc3RydWN0aW9uczwvYT4gZm9yIGhvdyB0byBzZXQgdXAgYSBERlMuCitTZWUgdGhlIFpvb0tlZWVwZXIgPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL3pvb2tlZXBlci9kb2NzL2N1cnJlbnQvem9va2VlcGVyU3RhcnRlZC5odG1sIj5HZXR0aW5nIFN0YXJ0ZWQgR3VpZGU8L2E+Citmb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIFpvb0tlZXBlciBkaXN0cmlidXRlZCBjb29yZGluYXRpb24gc2VydmljZS4KK0lmIHlvdSBkbyBub3QgY29uZmlndXJlIGEgWm9vS2VlcGVyIGNsdXN0ZXIsIEhCYXNlIHdpbGwgbWFuYWdlIGEgc2luZ2xlIGluc3RhbmNlCitab29LZWVwZXIgc2VydmljZSBmb3IgeW91IHJ1bm5pbmcgb24gdGhlIG1hc3RlciBub2RlLgorVGhpcyBpcyBpbnRlbmRlZCBmb3IgZGV2ZWxvcG1lbnQgYW5kIGxvY2FsIHRlc3Rpbmcgb25seS4KK0l0IFNIT1VMRCBOT1QgYmUgdXNlZCBpbiBhIGZ1bGx5LWRpc3RyaWJ1dGVkIHByb2R1Y3Rpb24gb3BlcmF0aW9uLgorPC9wPgorCis8aDM+PGEgbmFtZT0icHNldWRvLWRpc3RyaWIiPlBzZXVkby1EaXN0cmlidXRlZCBPcGVyYXRpb248L2E+PC9oMz4KKzxwPkEgcHNldWRvLWRpc3RyaWJ1dGVkIG9wZXJhdGlvbiBpcyBzaW1wbHkgYSBkaXN0cmlidXRlZCBvcGVyYXRpb24gcnVuIG9uIGEgc2luZ2xlIGhvc3QuICAKK09uY2UgeW91IGhhdmUgY29uZmlybWVkIHlvdXIgREZTIHNldHVwLCBjb25maWd1cmluZyBIQmFzZSBmb3IgdXNlIG9uIG9uZSBob3N0IHJlcXVpcmVzIG1vZGlmaWNhdGlvbiBvZiAKKzxjb2RlPiR7SEJBU0VfSE9NRX0vY29uZi9oYmFzZS1zaXRlLnhtbDwvY29kZT4sIHdoaWNoIG5lZWRzIHRvIGJlIHBvaW50ZWQgYXQgdGhlIHJ1bm5pbmcgSGFkb29wIERGUyBpbnN0YW5jZS4gIAorVXNlIDxjb2RlPmhiYXNlLXNpdGUueG1sPC9jb2RlPiB0byBvdmVycmlkZSB0aGUgcHJvcGVydGllcyBkZWZpbmVkIGluIAorPGNvZGU+JHtIQkFTRV9IT01FfS9jb25mL2hiYXNlLWRlZmF1bHQueG1sPC9jb2RlPiAoPGNvZGU+aGJhc2UtZGVmYXVsdC54bWw8L2NvZGU+IGl0c2VsZiAKK3Nob3VsZCBuZXZlciBiZSBtb2RpZmllZCkuICBBdCBhIG1pbmltdW0gdGhlIDxjb2RlPmhiYXNlLnJvb3RkaXI8L2NvZGU+IHByb3BlcnR5IHNob3VsZCBiZSByZWRlZmluZWQgCitpbiA8Y29kZT5oYmFzZS1zaXRlLnhtbDwvY29kZT4gdG8gcG9pbnQgSEJhc2UgYXQgdGhlIEhhZG9vcCBmaWxlc3lzdGVtIHRvIHVzZS4gIEZvciBleGFtcGxlLCBhZGRpbmcgdGhlIHByb3BlcnR5IAorYmVsb3cgdG8geW91ciA8Y29kZT5oYmFzZS1zaXRlLnhtbDwvY29kZT4gc2F5cyB0aGF0IEhCYXNlIHNob3VsZCB1c2UgdGhlIDxjb2RlPi9oYmFzZTwvY29kZT4gZGlyZWN0b3J5IGluIHRoZSAKK0hERlMgd2hvc2UgbmFtZW5vZGUgaXMgYXQgcG9ydCA5MDAwIG9uIHlvdXIgbG9jYWwgbWFjaGluZToKKzwvcD4KKzxwcmU+CismbHQ7Y29uZmlndXJhdGlvbiZndDsKKyAgLi4uCisgICZsdDtwcm9wZXJ0eSZndDsKKyAgICAmbHQ7bmFtZSZndDtoYmFzZS5yb290ZGlyJmx0Oy9uYW1lJmd0OworICAgICZsdDt2YWx1ZSZndDtoZGZzOi8vbG9jYWxob3N0OjkwMDAvaGJhc2UmbHQ7L3ZhbHVlJmd0OworICAgICZsdDtkZXNjcmlwdGlvbiZndDtUaGUgZGlyZWN0b3J5IHNoYXJlZCBieSByZWdpb24gc2VydmVycy4KKyAgICAmbHQ7L2Rlc2NyaXB0aW9uJmd0OworICAmbHQ7L3Byb3BlcnR5Jmd0OworICAuLi4KKyZsdDsvY29uZmlndXJhdGlvbiZndDsKKzwvcHJlPgorPHA+Tm90ZTogTGV0IGhiYXNlIGNyZWF0ZSB0aGUgZGlyZWN0b3J5LiAgSWYgeW91IGRvbid0LCB5b3UnbGwgZ2V0IHdhcm5pbmcgc2F5aW5nIGhiYXNlCituZWVkcyBhIG1pZ3JhdGlvbiBydW4gYmVjYXVzZSB0aGUgZGlyZWN0b3J5IGlzIG1pc3NpbmcgZmlsZXMgZXhwZWN0ZWQgYnkgaGJhc2UgKGl0J2xsCitjcmVhdGUgdGhlbSBpZiB5b3UgbGV0IGl0KS4KKzwvcD4KKworPGgzPjxhIG5hbWU9ImZ1bGx5LWRpc3RyaWIiPkZ1bGx5LURpc3RyaWJ1dGVkIE9wZXJhdGlvbjwvYT48L2gzPgorRm9yIHJ1bm5pbmcgYSBmdWxseS1kaXN0cmlidXRlZCBvcGVyYXRpb24gb24gbW9yZSB0aGFuIG9uZSBob3N0LCB0aGUgZm9sbG93aW5nCitjb25maWd1cmF0aW9ucyBtdXN0IGJlIG1hZGUgPGk+aW4gYWRkaXRpb248L2k+IHRvIHRob3NlIGRlc2NyaWJlZCBpbiB0aGUKKzxhIGhyZWY9IiNwc2V1ZG8tZGlzdHJpYiI+cHNldWRvLWRpc3RyaWJ1dGVkIG9wZXJhdGlvbjwvYT4gc2VjdGlvbiBhYm92ZS4KK0luIDxjb2RlPmhiYXNlLXNpdGUueG1sPC9jb2RlPiwgeW91IG11c3QgYWxzbyBjb25maWd1cmUKKzxjb2RlPmhiYXNlLm1hc3Rlci5ob3N0bmFtZTwvY29kZT4gdG8gdGhlIGhvc3Qgb24gd2hpY2ggdGhlIEhCYXNlIG1hc3RlciBydW5zCisoPGEgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9sdWNlbmUtaGFkb29wL0hiYXNlL0hiYXNlQXJjaGl0ZWN0dXJlIj5yZWFkIAorYWJvdXQgdGhlIEhCYXNlIG1hc3RlciwgcmVnaW9uc2VydmVycywgZXRjPC9hPikuCitGb3IgZXhhbXBsZSwgYWRkaW5nIHRoZSBiZWxvdyB0byB5b3VyIDxjb2RlPmhiYXNlLXNpdGUueG1sPC9jb2RlPiBzYXlzIHRoZQorbWFzdGVyIGlzIHVwIG9uIHRoZSBob3N0IGV4YW1wbGUub3JnOgorPC9wPgorPHByZT4KKyZsdDtjb25maWd1cmF0aW9uJmd0OworICAuLi4KKyAgJmx0O3Byb3BlcnR5Jmd0OworICAgICZsdDtuYW1lJmd0O2hiYXNlLm1hc3Rlci5ob3N0bmFtZSZsdDsvbmFtZSZndDsKKyAgICAmbHQ7dmFsdWUmZ3Q7ZXhhbXBsZS5vcmcmbHQ7L3ZhbHVlJmd0OworICAgICZsdDtkZXNjcmlwdGlvbiZndDtUaGUgaG9zdCB0aGF0IHRoZSBIQmFzZSBtYXN0ZXIgcnVucyBhdC4KKyAgICAgIEEgdmFsdWUgb2YgJ2xvY2FsJyBydW5zIHRoZSBtYXN0ZXIgYW5kIHJlZ2lvbnNlcnZlciBpbiBhIHNpbmdsZSBwcm9jZXNzLgorICAgICZsdDsvZGVzY3JpcHRpb24mZ3Q7CisgICZsdDsvcHJvcGVydHkmZ3Q7CisgIC4uLgorJmx0Oy9jb25maWd1cmF0aW9uJmd0OworPC9wcmU+Cis8cD4KK0tlZXAgaW4gbWluZCB0aGF0IGZvciBhIGZ1bGx5LWRpc3RyaWJ1dGVkIG9wZXJhdGlvbiwgeW91IG1heSBub3Qgd2FudCB5b3VyIDxjb2RlPmhiYXNlLnJvb3RkaXI8L2NvZGU+IAordG8gcG9pbnQgdG8gbG9jYWxob3N0IChtYXliZSwgYXMgaW4gdGhlIGNvbmZpZ3VyYXRpb24gYWJvdmUsIHlvdSB3aWxsIHdhbnQgdG8gdXNlIAorPGNvZGU+ZXhhbXBsZS5vcmc8L2NvZGU+KS4gIEluIGFkZGl0aW9uIHRvIDxjb2RlPmhiYXNlLXNpdGUueG1sPC9jb2RlPiwgYSBmdWxseS1kaXN0cmlidXRlZCAKK29wZXJhdGlvbiByZXF1aXJlcyB0aGF0IHlvdSBhbHNvIG1vZGlmeSA8Y29kZT4ke0hCQVNFX0hPTUV9L2NvbmYvcmVnaW9uc2VydmVyczwvY29kZT4uICAKKzxjb2RlPnJlZ2lvbnNlcnZlcjwvY29kZT4gbGlzdHMgYWxsIHRoZSBob3N0cyBydW5uaW5nIEhSZWdpb25TZXJ2ZXJzLCBvbmUgaG9zdCBwZXIgbGluZSAgKFRoaXMgZmlsZSAKK2luIEhCYXNlIGlzIGxpa2UgdGhlIGhhZG9vcCBzbGF2ZXMgZmlsZSBhdCA8Y29kZT4ke0hBRE9PUF9IT01FfS9jb25mL3NsYXZlczwvY29kZT4pLgorPC9wPgorPHA+CitGdXJ0aGVybW9yZSwgeW91IHNob3VsZCBjb25maWd1cmUgYSBkaXN0cmlidXRlZCBab29LZWVwZXIgY2x1c3Rlci4KK1RoZSBab29LZWVwZXIgY29uZmlndXJhdGlvbiBmaWxlIGlzIHN0b3JlZCBhdCA8Y29kZT4ke0hCQVNFX0hPTUV9L2NvbmYvem9vLmNmZzwvY29kZT4uCitTZWUgdGhlIFpvb0tlZXBlciA8YSBocmVmPSJodHRwOi8vaGFkb29wLmFwYWNoZS5vcmcvem9va2VlcGVyL2RvY3MvY3VycmVudC96b29rZWVwZXJTdGFydGVkLmh0bWwiPiBHZXR0aW5nIFN0YXJ0ZWQgR3VpZGU8L2E+IGZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZm9ybWF0IGFuZCBvcHRpb25zIG9mIHRoYXQgZmlsZS4KK1NwZWNpZmljYWxseSwgbG9vayBhdCB0aGUgPGEgaHJlZj0iaHR0cDovL2hhZG9vcC5hcGFjaGUub3JnL3pvb2tlZXBlci9kb2NzL2N1cnJlbnQvem9va2VlcGVyU3RhcnRlZC5odG1sI3NjX1J1bm5pbmdSZXBsaWNhdGVkWm9vS2VlcGVyIj5SdW5uaW5nIFJlcGxpY2F0ZWQgWm9vS2VlcGVyPC9hPiBzZWN0aW9uLgorSW4gPGNvZGU+JHtIQkFTRV9IT01FfS9jb25mL2hiYXNlLWVudi5zaDwvY29kZT4sIHNldCA8Y29kZT5IQkFTRV9NQU5BR0VTX1pLPWZhbHNlPC9jb2RlPiB0byB0ZWxsIEhCYXNlIG5vdCB0byBtYW5hZ2UgaXRzIG93biBzaW5nbGUgaW5zdGFuY2UgWm9vS2VlcGVyIHNlcnZpY2UuCis8L3A+CisKKzxwPk9mIG5vdGUsIGlmIHlvdSBoYXZlIG1hZGUgPGk+SERGUyBjbGllbnQgY29uZmlndXJhdGlvbjwvaT4gb24geW91ciBoYWRvb3AgY2x1c3RlciwgaGJhc2Ugd2lsbCBub3QKK3NlZSB0aGlzIGNvbmZpZ3VyYXRpb24gdW5sZXNzIHlvdSBkbyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKzx1bD4KKyAgICA8bGk+QWRkIGEgcG9pbnRlciB0byB5b3VyIDxjb2RlPkhBRE9PUF9DT05GX0RJUjwvY29kZT4gdG8gPGNvZGU+Q0xBU1NQQVRIPC9jb2RlPiBpbiA8Y29kZT5oYmFzZS1lbnYuc2g8L2NvZGU+PC9saT4KKyAgICA8bGk+QWRkIGEgY29weSBvZiA8Y29kZT5oYWRvb3Atc2l0ZS54bWw8L2NvZGU+IHRvIDxjb2RlPiR7SEJBU0VfSE9NRX0vY29uZjwvY29kZT4sIG9yPC9saT4KKyAgICA8bGk+SWYgb25seSBhIHNtYWxsIHNldCBvZiBIREZTIGNsaWVudCBjb25maWd1cmF0aW9ucywgYWRkIHRoZW0gdG8gPGNvZGU+aGJhc2Utc2l0ZS54bWw8L2NvZGU+PC9saT4KKzwvdWw+CitBbiBleGFtcGxlIG9mIHN1Y2ggYW4gSERGUyBjbGllbnQgY29uZmlndXJhdGlvbiBpcyA8Y29kZT5kZnMucmVwbGljYXRpb248L2NvZGU+LiAgSWYgZm9yIGV4YW1wbGUsCit5b3Ugd2FudCB0byBydW4gd2l0aCBhIHJlcGxpY2F0aW9uIGZhY3RvciBvZiA1LCBoYmFzZSB3aWxsIGNyZWF0ZSBmaWxlcyB3aXRoIHRoZSBkZWZhdWx0IG9mIDMgdW5sZXNzIAoreW91IGRvIHRoZSBhYm92ZSB0byBtYWtlIHRoZSBjb25maWd1cmF0aW9uIGF2YWlsYWJsZSB0byBoYmFzZS4KKzwvcD4KKworPGgyPjxhIG5hbWU9InJ1bmFuZGNvbmZpcm0iPlJ1bm5pbmcgYW5kIENvbmZpcm1pbmcgWW91ciBJbnN0YWxsYXRpb248L2E+PC9oMj4KKzxwPklmIHlvdSBhcmUgcnVubmluZyBpbiBzdGFuZGFsb25lLCBub24tZGlzdHJpYnV0ZWQgbW9kZSwgSEJhc2UgYnkgZGVmYXVsdCB1c2VzCit0aGUgbG9jYWwgZmlsZXN5c3RlbS48L3A+CisKKzxwPklmIHlvdSBhcmUgcnVubmluZyBhIGRpc3RyaWJ1dGVkIGNsdXN0ZXIgeW91IHdpbGwgbmVlZCB0byBzdGFydCB0aGUgSGFkb29wIERGUyBkYWVtb25zIAorYmVmb3JlIHN0YXJ0aW5nIEhCYXNlIGFuZCBzdG9wIHRoZSBkYWVtb25zIGFmdGVyIEhCYXNlIGhhcyBzaHV0IGRvd24uICBTdGFydCBhbmQgCitzdG9wIHRoZSBIYWRvb3AgREZTIGRhZW1vbnMgYnkgcnVubmluZyA8Y29kZT4ke0hBRE9PUF9IT01FfS9iaW4vc3RhcnQtZGZzLnNoPC9jb2RlPi4KK1lvdSBjYW4gZW5zdXJlIGl0IHN0YXJ0ZWQgcHJvcGVybHkgYnkgdGVzdGluZyB0aGUgcHV0IGFuZCBnZXQgb2YgZmlsZXMgaW50byB0aGUgSGFkb29wIGZpbGVzeXN0ZW0uCitIQmFzZSBkb2VzIG5vdCBub3JtYWxseSB1c2UgdGhlIG1hcHJlZHVjZSBkYWVtb25zLiAgVGhlc2UgZG8gbm90IG5lZWQgdG8gYmUgc3RhcnRlZC48L3A+CisKKzxwPlN0YXJ0IEhCYXNlIHdpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kOgorPC9wPgorPHByZT4KKyR7SEJBU0VfSE9NRX0vYmluL3N0YXJ0LWhiYXNlLnNoCis8L3ByZT4KKzxwPgorT25jZSBIQmFzZSBoYXMgc3RhcnRlZCwgZW50ZXIgPGNvZGU+JHtIQkFTRV9IT01FfS9iaW4vaGJhc2Ugc2hlbGw8L2NvZGU+IHRvIG9idGFpbiBhIAorc2hlbGwgYWdhaW5zdCBIQmFzZSBmcm9tIHdoaWNoIHlvdSBjYW4gZXhlY3V0ZSBjb21tYW5kcy4gIAorVGVzdCB5b3VyIGluc3RhbGxhdGlvbiBieSBjcmVhdGluZywgdmlld2luZywgYW5kIGRyb3BwaW5nIAorVG8gc3RvcCBIQmFzZSwgZXhpdCB0aGUgSEJhc2Ugc2hlbGwgYW5kIGVudGVyOgorPC9wPgorPHByZT4KKyR7SEJBU0VfSE9NRX0vYmluL3N0b3AtaGJhc2Uuc2gKKzwvcHJlPgorPHA+CitJZiB5b3UgYXJlIHJ1bm5pbmcgYSBkaXN0cmlidXRlZCBvcGVyYXRpb24sIGJlIHN1cmUgdG8gd2FpdCB1bnRpbCBIQmFzZSBoYXMgc2h1dCBkb3duIGNvbXBsZXRlbHkgCitiZWZvcmUgc3RvcHBpbmcgdGhlIEhhZG9vcCBkYWVtb25zLgorPC9wPgorPHA+CitUaGUgZGVmYXVsdCBsb2NhdGlvbiBmb3IgbG9ncyBpcyA8Y29kZT4ke0hCQVNFX0hPTUV9L2xvZ3M8L2NvZGU+LgorPC9wPgorPHA+SEJhc2UgYWxzbyBwdXRzIHVwIGEgVUkgbGlzdGluZyB2aXRhbCBhdHRyaWJ1dGVzLiAgQnkgZGVmYXVsdCBpdHMgZGVwbG95ZWQgb24gdGhlIG1hc3RlciBob3N0CithdCBwb3J0IDYwMDEwIChIQmFzZSByZWdpb25zZXJ2ZXJzIGxpc3RlbiBvbiBwb3J0IDYwMDIwIGJ5IGRlZmF1bHQgYW5kIHB1dCB1cCBhbiBpbmZvcm1hdGlvbmFsCitodHRwIHNlcnZlciBhdCA2MDAzMCkuPC9wPgorCis8aDI+PGEgbmFtZT0idXBncmFkaW5nIiA+VXBncmFkaW5nPC9hPjwvaDI+Cis8cD5BZnRlciBpbnN0YWxsaW5nIGEgbmV3IEhCYXNlIG9uIHRvcCBvZiBkYXRhIHdyaXR0ZW4gYnkgYSBwcmV2aW91cyBIQmFzZSB2ZXJzaW9uLCBiZWZvcmUKK3N0YXJ0aW5nIHlvdXIgY2x1c3RlciwgcnVuIHRoZSA8Y29kZT4ke0hCQVNFX0RJUn0vYmluL2hiYXNlIG1pZ3JhdGU8L2NvZGU+IG1pZ3JhdGlvbiBzY3JpcHQuCitJdCB3aWxsIG1ha2UgYW55IGFkanVzdG1lbnRzIHRvIHRoZSBmaWxlc3lzdGVtIGRhdGEgdW5kZXIgPGNvZGU+aGJhc2Uucm9vdGRpcjwvY29kZT4gbmVjZXNzYXJ5IHRvIHJ1bgordGhlIEhCYXNlIHZlcnNpb24uIEl0IGRvZXMgbm90IGNoYW5nZSB5b3VyIGluc3RhbGwgdW5sZXNzIHlvdSBleHBsaWNpdGx5IGFzayBpdCB0by4KKzwvcD4KKworPGgyPjxhIG5hbWU9ImNsaWVudF9leGFtcGxlIj5FeGFtcGxlIEFQSSBVc2FnZTwvYT48L2gyPgorPHA+T25jZSB5b3UgaGF2ZSBhIHJ1bm5pbmcgSEJhc2UsIHlvdSBwcm9iYWJseSB3YW50IGEgd2F5IHRvIGhvb2sgeW91ciBhcHBsaWNhdGlvbiB1cCB0byBpdC4gCisgIElmIHlvdXIgYXBwbGljYXRpb24gaXMgaW4gSmF2YSwgdGhlbiB5b3Ugc2hvdWxkIHVzZSB0aGUgSmF2YSBBUEkuIEhlcmUncyBhbiBleGFtcGxlIG9mIHdoYXQgCisgIGEgc2ltcGxlIGNsaWVudCBtaWdodCBsb29rIGxpa2UuICBUaGlzIGV4YW1wbGUgYXNzdW1lcyB0aGF0IHlvdSd2ZSBjcmVhdGVkIGEgdGFibGUgY2FsbGVkCisgICJteVRhYmxlIiB3aXRoIGEgY29sdW1uIGZhbWlseSBjYWxsZWQgIm15Q29sdW1uRmFtaWx5Ii4KKzwvcD4KKworPGRpdiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjogI2NjY2NjYzsgcGFkZGluZzogMnB4Ij4KKzxjb2RlPjxwcmU+CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK3B1YmxpYyBjbGFzcyBNeUNsaWVudCB7CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3NbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBZb3UgbmVlZCBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvIHRlbGwgdGhlIGNsaWVudCB3aGVyZSB0byBjb25uZWN0LgorICAgIC8vIEJ1dCBkb24ndCB3b3JyeSwgdGhlIGRlZmF1bHRzIGFyZSBwdWxsZWQgZnJvbSB0aGUgbG9jYWwgY29uZmlnIGZpbGUuCisgICAgSEJhc2VDb25maWd1cmF0aW9uIGNvbmZpZyA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKworICAgIC8vIFRoaXMgaW5zdGFudGlhdGVzIGFuIEhUYWJsZSBvYmplY3QgdGhhdCBjb25uZWN0cyB5b3UgdG8gdGhlICJteVRhYmxlIgorICAgIC8vIHRhYmxlLiAKKyAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmZpZywgIm15VGFibGUiKTsKKworICAgIC8vIFRvIGRvIGFueSBzb3J0IG9mIHVwZGF0ZSBvbiBhIHJvdywgeW91IHVzZSBhbiBpbnN0YW5jZSBvZiB0aGUgQmF0Y2hVcGRhdGUKKyAgICAvLyBjbGFzcy4gQSBCYXRjaFVwZGF0ZSB0YWtlcyBhIHJvdyBhbmQgb3B0aW9uYWxseSBhIHRpbWVzdGFtcCB3aGljaCB5b3VyCisgICAgLy8gdXBkYXRlcyB3aWxsIGFmZmVjdC4gIElmIG5vIHRpbWVzdGFtcCwgdGhlIHNlcnZlciBhcHBsaWVzIGN1cnJlbnQgdGltZQorICAgIC8vIHRvIHRoZSBlZGl0cy4KKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSgibXlSb3ciKTsKKworICAgIC8vIFRoZSBCYXRjaFVwZGF0ZSNwdXQgbWV0aG9kIHRha2VzIGEgYnl0ZSBbXSAob3IgU3RyaW5nKSB0aGF0IGRlc2lnbmF0ZXMKKyAgICAvLyB3aGF0IGNlbGwgeW91IHdhbnQgdG8gcHV0IGEgdmFsdWUgaW50bywgYW5kIGEgYnl0ZSBhcnJheSB0aGF0IGlzIHRoZQorICAgIC8vIHZhbHVlIHlvdSB3YW50IHRvIHN0b3JlLiBOb3RlIHRoYXQgaWYgeW91IHdhbnQgdG8gc3RvcmUgU3RyaW5ncywgeW91CisgICAgLy8gaGF2ZSB0byBnZXRCeXRlcygpIGZyb20gdGhlIFN0cmluZyBmb3IgSEJhc2UgdG8gc3RvcmUgaXQgc2luY2UgSEJhc2UgaXMKKyAgICAvLyBhbGwgYWJvdXQgYnl0ZSBhcnJheXMuIFRoZSBzYW1lIGdvZXMgZm9yIHByaW1pdGl2ZXMgbGlrZSBpbnRzIGFuZCBsb25ncworICAgIC8vIGFuZCB1c2VyLWRlZmluZWQgY2xhc3NlcyAtIHlvdSBtdXN0IGZpbmQgYSB3YXkgdG8gcmVkdWNlIGl0IHRvIGJ5dGVzLgorICAgIC8vIFRoZSBCeXRlcyBjbGFzcyBmcm9tIHRoZSBoYmFzZSB1dGlsIHBhY2thZ2UgaGFzIHV0aWxpdHkgZm9yIGdvaW5nIGZyb20KKyAgICAvLyBTdHJpbmcgdG8gdXRmLTggYnl0ZXMgYW5kIGJhY2sgYWdhaW4gYW5kIGhlbHAgZm9yIG90aGVyIGJhc2UgdHlwZXMuCisgICAgYmF0Y2hVcGRhdGUucHV0KCJteUNvbHVtbkZhbWlseTpjb2x1bW5RdWFsaWZpZXIxIiwgCisgICAgICBCeXRlcy50b0J5dGVzKCJjb2x1bW5RdWFsaWZpZXIxIHZhbHVlISIpKTsKKworICAgIC8vIERlbGV0ZXMgYXJlIGJhdGNoIG9wZXJhdGlvbnMgaW4gSEJhc2UgYXMgd2VsbC4gCisgICAgYmF0Y2hVcGRhdGUuZGVsZXRlKCJteUNvbHVtbkZhbWlseTpjZWxsSVdhbnREZWxldGVkIik7CisKKyAgICAvLyBPbmNlIHlvdSd2ZSBkb25lIGFsbCB0aGUgcHV0cyB5b3Ugd2FudCwgeW91IG5lZWQgdG8gY29tbWl0IHRoZSByZXN1bHRzLgorICAgIC8vIFRoZSBIVGFibGUjY29tbWl0IG1ldGhvZCB0YWtlcyB0aGUgQmF0Y2hVcGRhdGUgaW5zdGFuY2UgeW91J3ZlIGJlZW4gCisgICAgLy8gYnVpbGRpbmcgYW5kIHB1c2hlcyB0aGUgYmF0Y2ggb2YgY2hhbmdlcyB5b3UgbWFkZSBpbnRvIEhCYXNlLgorICAgIHRhYmxlLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisKKyAgICAvLyBOb3csIHRvIHJldHJpZXZlIHRoZSBkYXRhIHdlIGp1c3Qgd3JvdGUuIFRoZSB2YWx1ZXMgdGhhdCBjb21lIGJhY2sgYXJlCisgICAgLy8gQ2VsbCBpbnN0YW5jZXMuIEEgQ2VsbCBpcyBhIGNvbWJpbmF0aW9uIG9mIHRoZSB2YWx1ZSBhcyBhIGJ5dGUgYXJyYXkgYW5kCisgICAgLy8gdGhlIHRpbWVzdGFtcCB0aGUgdmFsdWUgd2FzIHN0b3JlZCB3aXRoLiBJZiB5b3UgaGFwcGVuIHRvIGtub3cgdGhhdCB0aGUgCisgICAgLy8gdmFsdWUgY29udGFpbmVkIGlzIGEgc3RyaW5nIGFuZCB3YW50IGFuIGFjdHVhbCBzdHJpbmcsIHRoZW4geW91IG11c3QgCisgICAgLy8gY29udmVydCBpdCB5b3Vyc2VsZi4KKyAgICBDZWxsIGNlbGwgPSB0YWJsZS5nZXQoIm15Um93IiwgIm15Q29sdW1uRmFtaWx5OmNvbHVtblF1YWxpZmllcjEiKTsKKyAgICAvLyBUaGlzIGNvdWxkIHRocm93IGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlcmUgd2FzIG5vIHZhbHVlIGF0IHRoZSBjZWxsCisgICAgLy8gbG9jYXRpb24uCisgICAgU3RyaW5nIHZhbHVlU3RyID0gQnl0ZXMudG9TdHJpbmcoY2VsbC5nZXRWYWx1ZSgpKTsKKyAgICAKKyAgICAvLyBTb21ldGltZXMsIHlvdSB3b24ndCBrbm93IHRoZSByb3cgeW91J3JlIGxvb2tpbmcgZm9yLiBJbiB0aGlzIGNhc2UsIHlvdQorICAgIC8vIHVzZSBhIFNjYW5uZXIuIFRoaXMgd2lsbCBnaXZlIHlvdSBjdXJzb3ItbGlrZSBpbnRlcmZhY2UgdG8gdGhlIGNvbnRlbnRzCisgICAgLy8gb2YgdGhlIHRhYmxlLgorICAgIFNjYW5uZXIgc2Nhbm5lciA9IAorICAgICAgLy8gd2Ugd2FudCB0byBnZXQgYmFjayBvbmx5ICJteUNvbHVtbkZhbWlseTpjb2x1bW5RdWFsaWZpZXIxIiB3aGVuIHdlIGl0ZXJhdGUKKyAgICAgIHRhYmxlLmdldFNjYW5uZXIobmV3IFN0cmluZ1tdeyJteUNvbHVtbkZhbWlseTpjb2x1bW5RdWFsaWZpZXIxIn0pOworICAgIAorICAgIAorICAgIC8vIFNjYW5uZXJzIHJldHVybiBSb3dSZXN1bHQgaW5zdGFuY2VzLiBBIFJvd1Jlc3VsdCBpcyBsaWtlIHRoZQorICAgIC8vIHJvdyBrZXkgYW5kIHRoZSBjb2x1bW5zIGFsbCB3cmFwcGVkIHVwIGluIGEgc2luZ2xlIE9iamVjdC4gCisgICAgLy8gUm93UmVzdWx0I2dldFJvdyBnaXZlcyB5b3UgdGhlIHJvdyBrZXkuIFJvd1Jlc3VsdCBhbHNvIGltcGxlbWVudHMgCisgICAgLy8gTWFwLCBzbyB5b3UgY2FuIGdldCB0byB5b3VyIGNvbHVtbiByZXN1bHRzIGVhc2lseS4gCisgICAgCisgICAgLy8gTm93LCBmb3IgdGhlIGFjdHVhbCBpdGVyYXRpb24uIE9uZSB3YXkgaXMgdG8gdXNlIGEgd2hpbGUgbG9vcCBsaWtlIHNvOgorICAgIFJvd1Jlc3VsdCByb3dSZXN1bHQgPSBzY2FubmVyLm5leHQoKTsKKyAgICAKKyAgICB3aGlsZSAocm93UmVzdWx0ICE9IG51bGwpIHsKKyAgICAgIC8vIHByaW50IG91dCB0aGUgcm93IHdlIGZvdW5kIGFuZCB0aGUgY29sdW1ucyB3ZSB3ZXJlIGxvb2tpbmcgZm9yCisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZvdW5kIHJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKHJvd1Jlc3VsdC5nZXRSb3coKSkgKworICAgICAgICAiIHdpdGggdmFsdWU6ICIgKyByb3dSZXN1bHQuZ2V0KEJ5dGVzLnRvQnl0ZXMoIm15Q29sdW1uRmFtaWx5OmNvbHVtblF1YWxpZmllcjEiKSkpOworICAgICAgcm93UmVzdWx0ID0gc2Nhbm5lci5uZXh0KCk7CisgICAgfQorICAgIAorICAgIC8vIFRoZSBvdGhlciBhcHByb2FjaCBpcyB0byB1c2UgYSBmb3JlYWNoIGxvb3AuIFNjYW5uZXJzIGFyZSBpdGVyYWJsZSEKKyAgICBmb3IgKFJvd1Jlc3VsdCByZXN1bHQgOiBzY2FubmVyKSB7CisgICAgICAvLyBwcmludCBvdXQgdGhlIHJvdyB3ZSBmb3VuZCBhbmQgdGhlIGNvbHVtbnMgd2Ugd2VyZSBsb29raW5nIGZvcgorICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGb3VuZCByb3c6ICIgKyBCeXRlcy50b1N0cmluZyhyb3dSZXN1bHQuZ2V0Um93KCkpICsKKyAgICAgICAgIiB3aXRoIHZhbHVlOiAiICsgcm93UmVzdWx0LmdldChCeXRlcy50b0J5dGVzKCJteUNvbHVtbkZhbWlseTpjb2x1bW5RdWFsaWZpZXIxIikpKTsKKyAgICB9CisgICAgCisgICAgLy8gTWFrZSBzdXJlIHlvdSBjbG9zZSB5b3VyIHNjYW5uZXJzIHdoZW4geW91IGFyZSBkb25lIQorICAgIC8vIEl0cyBwcm9iYWJseSBiZXN0IHRvIHB1dCB0aGUgaXRlcmF0aW9uIGludG8gYSB0cnkvZmluYWxseSB3aXRoIHRoZSBiZWxvdworICAgIC8vIGluc2lkZSB0aGUgZmluYWxseSBjbGF1c2UuCisgICAgc2Nhbm5lci5jbG9zZSgpOworICB9Cit9Cis8L3ByZT48L2NvZGU+Cis8L2Rpdj4KKworPHA+VGhlcmUgYXJlIG1hbnkgb3RoZXIgbWV0aG9kcyBmb3IgcHV0dGluZyBkYXRhIGludG8gYW5kIGdldHRpbmcgZGF0YSBvdXQgb2YgCisgIEhCYXNlLCBidXQgdGhlc2UgZXhhbXBsZXMgc2hvdWxkIGdldCB5b3Ugc3RhcnRlZC4gU2VlIHRoZSBIVGFibGUgamF2YWRvYyBmb3IKKyAgbW9yZSBtZXRob2RzLiBBZGRpdGlvbmFsbHksIHRoZXJlIGFyZSBtZXRob2RzIGZvciBtYW5hZ2luZyB0YWJsZXMgaW4gdGhlIAorICBIQmFzZUFkbWluIGNsYXNzLjwvcD4KKworPHA+SWYgeW91ciBjbGllbnQgaXMgTk9UIEphdmEsIHRoZW4geW91IHNob3VsZCBjb25zaWRlciB0aGUgVGhyaWZ0IG9yIFJFU1QgCisgIGxpYnJhcmllcy48L3A+CisKKzxoMj48YSBuYW1lPSJyZWxhdGVkIiA+UmVsYXRlZCBEb2N1bWVudGF0aW9uPC9hPjwvaDI+Cis8dWw+CisgIDxsaT48YSBocmVmPSJodHRwOi8vaGJhc2Uub3JnIj5IQmFzZSBIb21lIFBhZ2U8L2E+CisgIDxsaT48YSBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2hhZG9vcC9IYmFzZSI+SEJhc2UgV2lraTwvYT4KKyAgPGxpPjxhIGhyZWY9Imh0dHA6Ly9oYWRvb3AuYXBhY2hlLm9yZy8iPkhhZG9vcCBIb21lIFBhZ2U8L2E+Cis8L3VsPgorCis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvc2F2ZVZlcnNpb24uc2ggYi9zcmMvc2F2ZVZlcnNpb24uc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uYjllMTE2OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9zYXZlVmVyc2lvbi5zaApAQCAtMCwwICsxLDU5IEBACisjIS9iaW4vc2gKKworIyBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyMgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisjIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyMgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8gWW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAKKyMgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyMgdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCisKKyMgVGhpcyBmaWxlIGlzIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGFubm90YXRpb24gb2YgcGFja2FnZSBpbmZvIHRoYXQKKyMgcmVjb3JkcyB0aGUgdXNlciwgdXJsLCByZXZpc2lvbiBhbmQgdGltZXN0YW1wLgorCisjIENvcGllZCBmcm9tIGhhZG9vcCBjb3JlIHI3NDAzODYKKwordW5zZXQgTEFORwordW5zZXQgTENfQ1RZUEUKK3ZlcnNpb249JDEKK3VzZXI9YHdob2FtaWAKK2RhdGU9YGRhdGVgCitjd2Q9YHB3ZGAKK2lmIFsgLWQgLnN2biBdOyB0aGVuCisgIHJldmlzaW9uPWBzdm4gaW5mbyB8IHNlZCAtbiAtZSAncy9MYXN0IENoYW5nZWQgUmV2OiBcKC4qXCkvXDEvcCdgCisgIHVybD1gc3ZuIGluZm8gfCBzZWQgLW4gLWUgJ3MvVVJMOiBcKC4qXCkvXDEvcCdgCisgICMgR2V0IGNhbm9uaWNhbCBicmFuY2ggKGJyYW5jaGVzL1gsIHRhZ3MvWCwgb3IgdHJ1bmspCisgIGJyYW5jaD1gZWNobyAkdXJsIHwgc2VkIC1uIC1lICdzLC4qXChicmFuY2hlcy8uKlwpJCxcMSxwJyBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1lICdzLC4qXCh0YWdzLy4qXCkkLFwxLHAnIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLWUgJ3MsLip0cnVuayQsdHJ1bmsscCdgCitlbGlmIFsgLWQgLmdpdCBdOyB0aGVuCisgIHJldmlzaW9uPWBnaXQgbG9nIC0xIC0tcHJldHR5PWZvcm1hdDoiJUgiYAorICBob3N0bmFtZT1gaG9zdG5hbWVgCisgIGJyYW5jaD1gZ2l0IGJyYW5jaCB8IHNlZCAtbiAtZSAncy9eKiAvL3AnYAorICB1cmw9ImdpdDovLyR7aG9zdG5hbWV9JHtjd2R9IgorZWxzZQorICByZXZpc2lvbj0iVW5rbm93biIKKyAgYnJhbmNoPSJVbmtub3duIgorICB1cmw9ImZpbGU6Ly8kY3dkIgorZmkKK21rZGlyIC1wIGJ1aWxkL3NyYy9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZQorY2F0IDw8IEVPRiB8IFwKKyAgc2VkIC1lICJzL1ZFUlNJT04vJHZlcnNpb24vIiAtZSAicy9VU0VSLyR1c2VyLyIgLWUgInMvREFURS8kZGF0ZS8iIFwKKyAgICAgIC1lICJzfFVSTHwkdXJsfCIgLWUgInMvUkVWLyRyZXZpc2lvbi8iIFwKKyAgICAgIC1lICJzfEJSQU5DSHwkYnJhbmNofCIgXAorICAgICAgPiBidWlsZC9zcmMvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcGFja2FnZS1pbmZvLmphdmEKKy8qCisgKiBHZW5lcmF0ZWQgYnkgc3JjL3NhdmVWZXJzaW9uLnNoCisgKi8KK0BWZXJzaW9uQW5ub3RhdGlvbih2ZXJzaW9uPSJWRVJTSU9OIiwgcmV2aXNpb249IlJFViIsIAorICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXI9IlVTRVIiLCBkYXRlPSJEQVRFIiwgdXJsPSJVUkwiKQorcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKK0VPRgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvaGJhc2Utc2l0ZS54bWwgYi9zcmMvdGVzdC9oYmFzZS1zaXRlLnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NDgyMTIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvaGJhc2Utc2l0ZS54bWwKQEAgLTAsMCArMSwxMzAgQEAKKzw/eG1sIHZlcnNpb249IjEuMCI/PgorPD94bWwtc3R5bGVzaGVldCB0eXBlPSJ0ZXh0L3hzbCIgaHJlZj0iY29uZmlndXJhdGlvbi54c2wiPz4KKzwhLS0KKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8Y29uZmlndXJhdGlvbj4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5tc2dpbnRlcnZhbDwvbmFtZT4KKyAgICA8dmFsdWU+MTAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPkludGVydmFsIGJldHdlZW4gbWVzc2FnZXMgZnJvbSB0aGUgUmVnaW9uU2VydmVyIHRvIEhNYXN0ZXIKKyAgICBpbiBtaWxsaXNlY29uZHMuICBEZWZhdWx0IGlzIDE1LiBTZXQgdGhpcyB2YWx1ZSBsb3cgaWYgeW91IHdhbnQgdW5pdAorICAgIHRlc3RzIHRvIGJlIHJlc3BvbnNpdmUuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmNsaWVudC5wYXVzZTwvbmFtZT4KKyAgICA8dmFsdWU+NTAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPkdlbmVyYWwgY2xpZW50IHBhdXNlIHZhbHVlLiAgVXNlZCBtb3N0bHkgYXMgdmFsdWUgdG8gd2FpdAorICAgIGJlZm9yZSBydW5uaW5nIGEgcmV0cnkgb2YgYSBmYWlsZWQgZ2V0LCByZWdpb24gbG9va3VwLCBldGMuPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLm1hc3Rlci5tZXRhLnRocmVhZC5yZXNjYW5mcmVxdWVuY3k8L25hbWU+CisgICAgPHZhbHVlPjEwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+SG93IGxvbmcgdGhlIEhNYXN0ZXIgc2xlZXBzIChpbiBtaWxsaXNlY29uZHMpIGJldHdlZW4gc2NhbnMgb2YKKyAgICB0aGUgcm9vdCBhbmQgbWV0YSB0YWJsZXMuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnNlcnZlci50aHJlYWQud2FrZWZyZXF1ZW5jeTwvbmFtZT4KKyAgICA8dmFsdWU+MTAwMDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPlRpbWUgdG8gc2xlZXAgaW4gYmV0d2VlbiBzZWFyY2hlcyBmb3Igd29yayAoaW4gbWlsbGlzZWNvbmRzKS4KKyAgICBVc2VkIGFzIHNsZWVwIGludGVydmFsIGJ5IHNlcnZpY2UgdGhyZWFkcyBzdWNoIGFzIE1FVEEgc2Nhbm5lciBhbmQgbG9nIHJvbGxlci4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyLmhhbmRsZXIuY291bnQ8L25hbWU+CisgICAgPHZhbHVlPjU8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5Db3VudCBvZiBSUEMgU2VydmVyIGluc3RhbmNlcyBzcHVuIHVwIG9uIFJlZ2lvblNlcnZlcnMKKyAgICBTYW1lIHByb3BlcnR5IGlzIHVzZWQgYnkgdGhlIEhNYXN0ZXIgZm9yIGNvdW50IG9mIG1hc3RlciBoYW5kbGVycy4KKyAgICBEZWZhdWx0IGlzIDEwLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5tYXN0ZXIubGVhc2UucGVyaW9kPC9uYW1lPgorICAgIDx2YWx1ZT42MDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+TGVuZ3RoIG9mIHRpbWUgdGhlIG1hc3RlciB3aWxsIHdhaXQgYmVmb3JlIHRpbWluZyBvdXQgYSByZWdpb24KKyAgICBzZXJ2ZXIgbGVhc2UuIFNpbmNlIHJlZ2lvbiBzZXJ2ZXJzIHJlcG9ydCBpbiBldmVyeSBzZWNvbmQgKHNlZSBhYm92ZSksIHRoaXMKKyAgICB2YWx1ZSBoYXMgYmVlbiByZWR1Y2VkIHNvIHRoYXQgdGhlIG1hc3RlciB3aWxsIG5vdGljZSBhIGRlYWQgcmVnaW9uIHNlcnZlcgorICAgIHNvb25lci4gVGhlIGRlZmF1bHQgaXMgMzAgc2Vjb25kcy4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UubWFzdGVyLmluZm8ucG9ydDwvbmFtZT4KKyAgICA8dmFsdWU+LTE8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgcG9ydCBmb3IgdGhlIGhiYXNlIG1hc3RlciB3ZWIgVUkKKyAgICBTZXQgdG8gLTEgaWYgeW91IGRvIG5vdCB3YW50IHRoZSBpbmZvIHNlcnZlciB0byBydW4uCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLnJlZ2lvbnNlcnZlci5pbmZvLnBvcnQ8L25hbWU+CisgICAgPHZhbHVlPi0xPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+VGhlIHBvcnQgZm9yIHRoZSBoYmFzZSByZWdpb25zZXJ2ZXIgd2ViIFVJCisgICAgU2V0IHRvIC0xIGlmIHlvdSBkbyBub3Qgd2FudCB0aGUgaW5mbyBzZXJ2ZXIgdG8gcnVuLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIuaW5mby5wb3J0LmF1dG88L25hbWU+CisgICAgPHZhbHVlPnRydWU8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5JbmZvIHNlcnZlciBhdXRvIHBvcnQgYmluZC4gRW5hYmxlcyBhdXRvbWF0aWMgcG9ydAorICAgIHNlYXJjaCBpZiBoYmFzZS5yZWdpb25zZXJ2ZXIuaW5mby5wb3J0IGlzIGFscmVhZHkgaW4gdXNlLgorICAgIEVuYWJsZWQgZm9yIHRlc3RpbmcgdG8gcnVuIG11bHRpcGxlIHRlc3RzIG9uIG9uZSBtYWNoaW5lLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5tYXN0ZXIubGVhc2UudGhyZWFkLndha2VmcmVxdWVuY3k8L25hbWU+CisgICAgPHZhbHVlPjMwMDA8L3ZhbHVlPgorICAgIDxkZXNjcmlwdGlvbj5UaGUgaW50ZXJ2YWwgYmV0d2VlbiBjaGVja3MgZm9yIGV4cGlyZWQgcmVnaW9uIHNlcnZlciBsZWFzZXMuCisgICAgVGhpcyB2YWx1ZSBoYXMgYmVlbiByZWR1Y2VkIGR1ZSB0byB0aGUgb3RoZXIgcmVkdWNlZCB2YWx1ZXMgYWJvdmUgc28gdGhhdAorICAgIHRoZSBtYXN0ZXIgd2lsbCBub3RpY2UgYSBkZWFkIHJlZ2lvbiBzZXJ2ZXIgc29vbmVyLiBUaGUgZGVmYXVsdCBpcyAxNSBzZWNvbmRzLgorICAgIDwvZGVzY3JpcHRpb24+CisgIDwvcHJvcGVydHk+CisgIDxwcm9wZXJ0eT4KKyAgICA8bmFtZT5oYmFzZS5yZWdpb25zZXJ2ZXIub3B0aW9uYWxjYWNoZWZsdXNoaW50ZXJ2YWw8L25hbWU+CisgICAgPHZhbHVlPjEwMDAwPC92YWx1ZT4KKyAgICA8ZGVzY3JpcHRpb24+CisgICAgQW1vdW50IG9mIHRpbWUgdG8gd2FpdCBzaW5jZSB0aGUgbGFzdCB0aW1lIGEgcmVnaW9uIHdhcyBmbHVzaGVkIGJlZm9yZQorICAgIGludm9raW5nIGFuIG9wdGlvbmFsIGNhY2hlIGZsdXNoLiBEZWZhdWx0IDYwLDAwMC4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGJhc2UucmVnaW9uc2VydmVyLnNhZmVtb2RlPC9uYW1lPgorICAgIDx2YWx1ZT5mYWxzZTwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPgorICAgIFR1cm4gb24vb2ZmIHNhZmUgbW9kZSBpbiByZWdpb24gc2VydmVyLiBBbHdheXMgb24gZm9yIHByb2R1Y3Rpb24sIGFsd2F5cyBvZmYKKyAgICBmb3IgdGVzdHMuCisgICAgPC9kZXNjcmlwdGlvbj4KKyAgPC9wcm9wZXJ0eT4KKyAgPHByb3BlcnR5PgorICAgIDxuYW1lPmhiYXNlLmhyZWdpb24ubWF4LmZpbGVzaXplPC9uYW1lPgorICAgIDx2YWx1ZT42NzEwODg2NDwvdmFsdWU+CisgICAgPGRlc2NyaXB0aW9uPgorICAgIE1heGltdW0gZGVzaXJlZCBmaWxlIHNpemUgZm9yIGFuIEhSZWdpb24uICBJZiBmaWxlc2l6ZSBleGNlZWRzCisgICAgdmFsdWUgKyAodmFsdWUgLyAyKSwgdGhlIEhSZWdpb24gaXMgc3BsaXQgaW4gdHdvLiAgRGVmYXVsdDogMjU2TS4KKworICAgIEtlZXAgdGhlIG1heGltdW0gZmlsZXNpemUgc21hbGwgc28gd2Ugc3BsaXQgbW9yZSBvZnRlbiBpbiB0ZXN0cy4KKyAgICA8L2Rlc2NyaXB0aW9uPgorICA8L3Byb3BlcnR5PgorICA8cHJvcGVydHk+CisgICAgPG5hbWU+aGFkb29wLmxvZy5kaXI8L25hbWU+CisgICAgPHZhbHVlPiR7dXNlci5kaXJ9Ly4uL2xvZ3M8L3ZhbHVlPgorICA8L3Byb3BlcnR5PgorPC9jb25maWd1cmF0aW9uPgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvbG9nNGoucHJvcGVydGllcyBiL3NyYy90ZXN0L2xvZzRqLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGI4ZjJjNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2xvZzRqLnByb3BlcnRpZXMKQEAgLTAsMCArMSw0NyBAQAorIyBEZWZpbmUgc29tZSBkZWZhdWx0IHZhbHVlcyB0aGF0IGNhbiBiZSBvdmVycmlkZGVuIGJ5IHN5c3RlbSBwcm9wZXJ0aWVzCitoYmFzZS5yb290LmxvZ2dlcj1JTkZPLGNvbnNvbGUKK2hiYXNlLmxvZy5kaXI9LgoraGJhc2UubG9nLmZpbGU9aGJhc2UubG9nCisKKyMgRGVmaW5lIHRoZSByb290IGxvZ2dlciB0byB0aGUgc3lzdGVtIHByb3BlcnR5ICJoYmFzZS5yb290LmxvZ2dlciIuCitsb2c0ai5yb290TG9nZ2VyPSR7aGJhc2Uucm9vdC5sb2dnZXJ9CisKKyMgTG9nZ2luZyBUaHJlc2hvbGQKK2xvZzRqLnRocmVzaGhvbGQ9QUxMCisKKyMKKyMgRGFpbHkgUm9sbGluZyBGaWxlIEFwcGVuZGVyCisjCitsb2c0ai5hcHBlbmRlci5EUkZBPW9yZy5hcGFjaGUubG9nNGouRGFpbHlSb2xsaW5nRmlsZUFwcGVuZGVyCitsb2c0ai5hcHBlbmRlci5EUkZBLkZpbGU9JHtoYmFzZS5sb2cuZGlyfS8ke2hiYXNlLmxvZy5maWxlfQorCisjIFJvbGx2ZXIgYXQgbWlkbmlnaHQKK2xvZzRqLmFwcGVuZGVyLkRSRkEuRGF0ZVBhdHRlcm49Lnl5eXktTU0tZGQKKworIyAzMC1kYXkgYmFja3VwCisjbG9nNGouYXBwZW5kZXIuRFJGQS5NYXhCYWNrdXBJbmRleD0zMAorbG9nNGouYXBwZW5kZXIuRFJGQS5sYXlvdXQ9b3JnLmFwYWNoZS5sb2c0ai5QYXR0ZXJuTGF5b3V0CisKKyMgUGF0dGVybiBmb3JtYXQ6IERhdGUgTG9nTGV2ZWwgTG9nZ2VyTmFtZSBMb2dNZXNzYWdlCisjbG9nNGouYXBwZW5kZXIuRFJGQS5sYXlvdXQuQ29udmVyc2lvblBhdHRlcm49JWR7SVNPODYwMX0gJXAgJWM6ICVtJW4KKworIyBEZWJ1Z2dpbmcgUGF0dGVybiBmb3JtYXQKK2xvZzRqLmFwcGVuZGVyLkRSRkEubGF5b3V0LkNvbnZlcnNpb25QYXR0ZXJuPSVkICUtNXAgWyV0XSAlQ3syfSglTCk6ICVtJW4KKworCisjCisjIGNvbnNvbGUKKyMgQWRkICJjb25zb2xlIiB0byByb290bG9nZ2VyIGFib3ZlIGlmIHlvdSB3YW50IHRvIHVzZSB0aGlzIAorIworbG9nNGouYXBwZW5kZXIuY29uc29sZT1vcmcuYXBhY2hlLmxvZzRqLkNvbnNvbGVBcHBlbmRlcgorbG9nNGouYXBwZW5kZXIuY29uc29sZS50YXJnZXQ9U3lzdGVtLmVycgorbG9nNGouYXBwZW5kZXIuY29uc29sZS5sYXlvdXQ9b3JnLmFwYWNoZS5sb2c0ai5QYXR0ZXJuTGF5b3V0Citsb2c0ai5hcHBlbmRlci5jb25zb2xlLmxheW91dC5Db252ZXJzaW9uUGF0dGVybj0lZCAlLTVwIFsldF0gJUN7Mn0oJUwpOiAlbSVuCisKKyMgQ3VzdG9tIExvZ2dpbmcgbGV2ZWxzCisKKyNsb2c0ai5sb2dnZXIub3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNOYW1lc3lzdGVtPURFQlVHCisKK2xvZzRqLmxvZ2dlci5vcmcuYXBhY2hlLmhhZG9vcD1XQVJOCitsb2c0ai5sb2dnZXIub3JnLmFwYWNoZS56b29rZWVwZXI9RVJST1IKK2xvZzRqLmxvZ2dlci5vcmcuYXBhY2hlLmhhZG9vcC5oYmFzZT1ERUJVRwpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvQWJzdHJhY3RNZXJnZVRlc3RCYXNlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9BYnN0cmFjdE1lcmdlVGVzdEJhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZjVjZTIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvQWJzdHJhY3RNZXJnZVRlc3RCYXNlLmphdmEKQEAgLTAsMCArMSwxNDQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5JbW11dGFibGVCeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKKy8qKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBtZXJnZSB0ZXN0cyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0TWVyZ2VUZXN0QmFzZSBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPQorICAgIExvZ0ZhY3RvcnkuZ2V0TG9nKEFic3RyYWN0TWVyZ2VUZXN0QmFzZS5jbGFzcy5nZXROYW1lKCkpOworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xVTU5fTkFNRSA9IEJ5dGVzLnRvQnl0ZXMoImNvbnRlbnRzOiIpOworICBwcm90ZWN0ZWQgZmluYWwgUmFuZG9tIHJhbmQgPSBuZXcgUmFuZG9tKCk7CisgIHByb3RlY3RlZCBIVGFibGVEZXNjcmlwdG9yIGRlc2M7CisgIHByb3RlY3RlZCBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHZhbHVlOworICBwcm90ZWN0ZWQgYm9vbGVhbiBzdGFydE1pbmlIQmFzZTsKKyAgCisgIHB1YmxpYyBBYnN0cmFjdE1lcmdlVGVzdEJhc2UoKSB7CisgICAgdGhpcyh0cnVlKTsKKyAgfQorICAKKyAgLyoqIGNvbnN0cnVjdG9yIAorICAgKiBAcGFyYW0gc3RhcnRNaW5pSEJhc2UKKyAgICovCisgIHB1YmxpYyBBYnN0cmFjdE1lcmdlVGVzdEJhc2UoYm9vbGVhbiBzdGFydE1pbmlIQmFzZSkgeworICAgIHN1cGVyKCk7CisgICAgCisgICAgdGhpcy5zdGFydE1pbmlIQmFzZSA9IHN0YXJ0TWluaUhCYXNlOworICAgIAorICAgIC8vIFdlIHdpbGwgdXNlIHRoZSBzYW1lIHZhbHVlIGZvciB0aGUgcm93cyBhcyB0aGF0IGlzIG5vdCByZWFsbHkgaW1wb3J0YW50IGhlcmUKKyAgICAKKyAgICBTdHJpbmcgcGFydGlhbFZhbHVlID0gU3RyaW5nLnZhbHVlT2YoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIFN0cmluZ0J1aWxkZXIgdmFsID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKKyAgICB3aGlsZSh2YWwubGVuZ3RoKCkgPCAxMDI0KSB7CisgICAgICB2YWwuYXBwZW5kKHBhcnRpYWxWYWx1ZSk7CisgICAgfQorIAorICAgIHRyeSB7CisgICAgICB2YWx1ZSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKAorICAgICAgICAgIHZhbC50b1N0cmluZygpLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgZmFpbCgpOworICAgIH0KKyAgICBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoQnl0ZXMudG9CeXRlcygidGVzdCIpKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoQ09MVU1OX05BTUUpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBoQmFzZUNsdXN0ZXJTZXR1cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGlmIChzdGFydE1pbmlIQmFzZSkgeworICAgICAgc3VwZXIuaEJhc2VDbHVzdGVyU2V0dXAoKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcHJlSEJhc2VDbHVzdGVyU2V0dXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjb25mLnNldExvbmcoImhiYXNlLmhyZWdpb24ubWF4LmZpbGVzaXplIiwgNjRMICogMTAyNEwgKiAxMDI0TCk7CisKKyAgICAvLyBXZSBjcmVhdGUgdGhyZWUgZGF0YSByZWdpb25zOiBUaGUgZmlyc3QgaXMgdG9vIGxhcmdlIHRvIG1lcmdlIHNpbmNlIGl0IAorICAgIC8vIHdpbGwgYmUgPiA2NCBNQiBpbiBzaXplLiBUaGUgc2Vjb25kIHR3byB3aWxsIGJlIHNtYWxsZXIgYW5kIHdpbGwgYmUgCisgICAgLy8gc2VsZWN0ZWQgZm9yIG1lcmdpbmcuCisgICAgCisgICAgLy8gVG8gZW5zdXJlIHRoYXQgdGhlIGZpcnN0IHJlZ2lvbiBpcyBsYXJnZXIgdGhhbiA2NE1CIHdlIG5lZWQgdG8gd3JpdGUgYXQKKyAgICAvLyBsZWFzdCA2NTUzNiByb3dzLiBXZSB3aWxsIG1ha2UgY2VydGFpbiBieSB3cml0aW5nIDcwMDAwCisKKyAgICBieXRlIFtdIHJvd183MDAwMSA9IEJ5dGVzLnRvQnl0ZXMoInJvd183MDAwMSIpOworICAgIGJ5dGUgW10gcm93XzgwMDAxID0gQnl0ZXMudG9CeXRlcygicm93XzgwMDAxIik7CisKKyAgICAvLyBYWFg6IE5vdGUgdGhhdCB0aGUgbnVtYmVyIG9mIHJvd3Mgd2UgcHV0IGluIGlzIGRpZmZlcmVudCBmb3IgZWFjaCByZWdpb24KKyAgICAvLyBiZWNhdXNlIGN1cnJlbnRseSB3ZSBkb24ndCBoYXZlIGEgZ29vZCBtZWNoYW5pc20gdG8gaGFuZGxlIG1lcmdpbmcgdHdvCisgICAgLy8gc3RvcmUgZmlsZXMgd2l0aCB0aGUgc2FtZSBzZXF1ZW5jZSBpZC4gV2UgY2FuJ3QganVzdCBkdW1ibHkgc3RpY2sgdGhlbQorICAgIC8vIGluIGJlY2F1c2UgaXQgd2lsbCBzY3JldyB1cCB0aGUgb3JkZXIgd2hlbiB0aGUgc3RvcmUgZmlsZXMgYXJlIGxvYWRlZCB1cC4KKyAgICAvLyBUaGUgc2VxdWVuY2UgaWRzIGFyZSB1c2VkIGZvciBhcnJhbmdpbmcgdGhlIHN0b3JlIGZpbGVzLCBzbyBpZiB0d28gZmlsZXMKKyAgICAvLyBoYXZlIHRoZSBzYW1lIGlkLCBvbmUgd2lsbCBvdmVyd3JpdGUgdGhlIG90aGVyIG9uZSBpbiBvdXIgbGlzdGluZywgd2hpY2gKKyAgICAvLyBpcyB2ZXJ5IGJhZC4gU2VlIEhCQVNFLTEyMTIgYW5kIEhCQVNFLTEyNzQuCisgICAgSFJlZ2lvbltdIHJlZ2lvbnMgPSB7CisgICAgICBjcmVhdGVBcmVnaW9uKG51bGwsIHJvd183MDAwMSwgMSwgNzAwMDApLAorICAgICAgY3JlYXRlQXJlZ2lvbihyb3dfNzAwMDEsIHJvd184MDAwMSwgNzAwMDEsIDEwMDAwKSwKKyAgICAgIGNyZWF0ZUFyZWdpb24ocm93XzgwMDAxLCBudWxsLCA4MDAwMSwgMTEwMDApCisgICAgfTsKKyAgICAKKyAgICAvLyBOb3cgY3JlYXRlIHRoZSByb290IGFuZCBtZXRhIHJlZ2lvbnMgYW5kIGluc2VydCB0aGUgZGF0YSByZWdpb25zCisgICAgLy8gY3JlYXRlZCBhYm92ZSBpbnRvIHRoZSBtZXRhCisKKyAgICBjcmVhdGVSb290QW5kTWV0YVJlZ2lvbnMoKTsKKyAgICAKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgcmVnaW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgSFJlZ2lvbi5hZGRSZWdpb25Ub01FVEEobWV0YSwgcmVnaW9uc1tpXSk7CisgICAgfQorCisgICAgY2xvc2VSb290QW5kTWV0YSgpOworICB9CisKKyAgcHJpdmF0ZSBIUmVnaW9uIGNyZWF0ZUFyZWdpb24oYnl0ZSBbXSBzdGFydEtleSwgYnl0ZSBbXSBlbmRLZXksIGludCBmaXJzdFJvdywKKyAgICAgIGludCBucm93cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oZGVzYywgc3RhcnRLZXksIGVuZEtleSk7CisgICAgCisgICAgU3lzdGVtLm91dC5wcmludGxuKCJjcmVhdGVkIHJlZ2lvbiAiICsKKyAgICAgICAgQnl0ZXMudG9TdHJpbmcocmVnaW9uLmdldFJlZ2lvbk5hbWUoKSkpOworCisgICAgSFJlZ2lvbkluY29tbW9uIHIgPSBuZXcgSFJlZ2lvbkluY29tbW9uKHJlZ2lvbik7CisgICAgZm9yKGludCBpID0gZmlyc3RSb3c7IGkgPCBmaXJzdFJvdyArIG5yb3dzOyBpKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKEJ5dGVzLnRvQnl0ZXMoInJvd18iCisgICAgICAgICAgKyBTdHJpbmcuZm9ybWF0KCIlMSQwNWQiLCBpKSkpOworCisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OX05BTUUsIHZhbHVlLmdldCgpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICBpZihpICUgMTAwMDAgPT0gMCkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZsdXNoaW5nIHdyaXRlICMiICsgaSk7CisgICAgICAgIHIuZmx1c2hjYWNoZSgpOworICAgICAgfQorICAgIH0KKyAgICByZWdpb24uY2xvc2UoKTsKKyAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICByZWdpb24uZ2V0UmVnaW9uSW5mbygpLnNldE9mZmxpbmUodHJ1ZSk7CisgICAgcmV0dXJuIHJlZ2lvbjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvREZTQWJvcnQuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0RGU0Fib3J0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzJhOWQ4NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0RGU0Fib3J0LmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RTdWl0ZTsKK2ltcG9ydCBqdW5pdC50ZXh0dWkuVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKKworLyoqCisgKiBUZXN0IGFiaWxpdHkgb2YgSEJhc2UgdG8gaGFuZGxlIERGUyBmYWlsdXJlCisgKi8KK3B1YmxpYyBjbGFzcyBERlNBYm9ydCBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBERlNBYm9ydCgpIHsKKyAgICBzdXBlcigpOworICAgIAorICAgIC8vIEZvciBsZXNzIGZyZXF1ZW50bHkgdXBkYXRlZCByZWdpb25zIGZsdXNoIGFmdGVyIGV2ZXJ5IDIgZmx1c2hlcworICAgIGNvbmYuc2V0SW50KCJoYmFzZS5ocmVnaW9uLm1lbWNhY2hlLm9wdGlvbmFsZmx1c2hjb3VudCIsIDIpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZX1NUUikpOworICAgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0REZTQWJvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgLy8gQnkgbm93IHRoZSBNaW5pIERGUyBpcyBydW5uaW5nLCBNaW5pIEhCYXNlIGlzIHJ1bm5pbmcgYW5kIHdlIGhhdmUKKyAgICAgIC8vIGNyZWF0ZWQgYSB0YWJsZS4gTm93IGxldCdzIHlhbmsgdGhlIHJ1ZyBvdXQgZnJvbSBIQmFzZQorICAgICAgZGZzQ2x1c3Rlci5zaHV0ZG93bigpOworICAgICAgdGhyZWFkRHVtcGluZ0pvaW4oKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBhcmdzIHVudXNlZAorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworICAgIFRlc3RSdW5uZXIucnVuKG5ldyBUZXN0U3VpdGUoREZTQWJvcnQuY2xhc3MpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvSEJhc2VDbHVzdGVyVGVzdENhc2UuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hCYXNlQ2x1c3RlclRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk3NGMyNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hCYXNlQ2x1c3RlclRlc3RDYXNlLmphdmEKQEAgLTAsMCArMSwyMjYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQ29ubmVjdGlvbk1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkZTVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5SZWZsZWN0aW9uVXRpbHM7CisKKy8qKgorICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgSEJhc2UgY2x1c3RlciBqdW5pdCB0ZXN0cy4gIFNwaW5zIHVwIGFuIGhiYXNlCisgKiBjbHVzdGVyIGluIHNldHVwIGFuZCB0ZWFycyBpdCBkb3duIGFnYWluIGluIHRlYXJEb3duLgorICovCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSEJhc2VDbHVzdGVyVGVzdENhc2UgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKEhCYXNlQ2x1c3RlclRlc3RDYXNlLmNsYXNzKTsKKyAgcHVibGljIE1pbmlIQmFzZUNsdXN0ZXIgY2x1c3RlcjsKKyAgcHJvdGVjdGVkIE1pbmlERlNDbHVzdGVyIGRmc0NsdXN0ZXI7CisgIHByb3RlY3RlZCBNaW5pWm9vS2VlcGVyQ2x1c3RlciB6b29LZWVwZXJDbHVzdGVyOworICBwcm90ZWN0ZWQgaW50IHJlZ2lvblNlcnZlcnM7CisgIHByb3RlY3RlZCBib29sZWFuIHN0YXJ0RGZzOworICBwcml2YXRlIGJvb2xlYW4gb3Blbk1ldGFUYWJsZSA9IHRydWU7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIEhCYXNlQ2x1c3RlclRlc3RDYXNlKCkgeworICAgIHRoaXMoMSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBTdGFydCBhIE1pbmlIQmFzZUNsdXN0ZXIgd2l0aCByZWdpb25TZXJ2ZXJzIHJlZ2lvbiBzZXJ2ZXJzIGluLXByb2Nlc3MgdG8KKyAgICogc3RhcnQgd2l0aC4gQWxzbywgc3RhcnQgYSBNaW5pRGZzQ2x1c3RlciBiZWZvcmUgc3RhcnRpbmcgdGhlIGhiYXNlIGNsdXN0ZXIuCisgICAqIFRoZSBjb25maWd1cmF0aW9uIHVzZWQgd2lsbCBiZSBlZGl0ZWQgc28gdGhhdCB0aGlzIHdvcmtzIGNvcnJlY3RseS4KKyAgICogQHBhcmFtIHJlZ2lvblNlcnZlcnMgbnVtYmVyIG9mIHJlZ2lvbiBzZXJ2ZXJzIHRvIHN0YXJ0LgorICAgKi8gIAorICBwdWJsaWMgSEJhc2VDbHVzdGVyVGVzdENhc2UoaW50IHJlZ2lvblNlcnZlcnMpIHsKKyAgICB0aGlzKHJlZ2lvblNlcnZlcnMsIHRydWUpOworICB9CisgIAorICAvKiogIGluLXByb2Nlc3MgdG8KKyAgICogc3RhcnQgd2l0aC4gT3B0aW9uYWxseSwgc3RhcnREZnMgaW5kaWNhdGVzIGlmIGEgTWluaURGU0NsdXN0ZXIgc2hvdWxkIGJlCisgICAqIHN0YXJ0ZWQuIElmIHN0YXJ0RGZzIGlzIGZhbHNlLCB0aGUgYXNzdW1wdGlvbiBpcyB0aGF0IGFuIGV4dGVybmFsIERGUyBpcworICAgKiBjb25maWd1cmVkIGluIGhiYXNlLXNpdGUueG1sIGFuZCBpcyBhbHJlYWR5IHN0YXJ0ZWQsIG9yIHlvdSBoYXZlIHN0YXJ0ZWQgYQorICAgKiBNaW5pREZTQ2x1c3RlciBvbiB5b3VyIG93biBhbmQgZWRpdGVkIHRoZSBjb25maWd1cmF0aW9uIGluIG1lbW9yeS4gKFlvdSAKKyAgICogY2FuIG1vZGlmeSB0aGUgY29uZmlnIHVzZWQgYnkgb3ZlcnJpZGluZyB0aGUgcHJlSEJhc2VDbHVzdGVyU2V0dXAgbWV0aG9kLikKKyAgICogQHBhcmFtIHJlZ2lvblNlcnZlcnMgbnVtYmVyIG9mIHJlZ2lvbiBzZXJ2ZXJzIHRvIHN0YXJ0LgorICAgKiBAcGFyYW0gc3RhcnREZnMgc2V0IHRvIHRydWUgaWYgTWluaURGUyBzaG91bGQgYmUgc3RhcnRlZAorICAgKi8KKyAgcHVibGljIEhCYXNlQ2x1c3RlclRlc3RDYXNlKGludCByZWdpb25TZXJ2ZXJzLCBib29sZWFuIHN0YXJ0RGZzKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLnN0YXJ0RGZzID0gc3RhcnREZnM7CisgICAgdGhpcy5yZWdpb25TZXJ2ZXJzID0gcmVnaW9uU2VydmVyczsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIHNldE9wZW5NZXRhVGFibGUoYm9vbGVhbiB2YWwpIHsKKyAgICBvcGVuTWV0YVRhYmxlID0gdmFsOworICB9CisKKyAgLyoqCisgICAqIFJ1biBhZnRlciBkZnMgaXMgcmVhZHkgYnV0IGJlZm9yZSBoYmFzZSBjbHVzdGVyIGlzIHN0YXJ0ZWQgdXAuCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBwcmVIQmFzZUNsdXN0ZXJTZXR1cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIGNvbnRpbnVlCisgIH0gCisKKyAgLyoqCisgICAqIEFjdHVhbGx5IHN0YXJ0IHRoZSBNaW5pSEJhc2UgaW5zdGFuY2UuCisgICAqLworICBwcm90ZWN0ZWQgdm9pZCBoQmFzZUNsdXN0ZXJTZXR1cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgdGVzdERpciA9IG5ldyBGaWxlKGdldFVuaXRUZXN0ZGlyKGdldE5hbWUoKSkudG9TdHJpbmcoKSk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyBkb25lIGJlZm9yZSB3ZSBjcmVhdGUgdGhlIE1pbmlIQmFzZUNsdXN0ZXIgYmVjYXVzZSB3ZQorICAgIC8vIG5lZWQgdG8gZWRpdCB0aGUgY29uZmlnIHRvIGFkZCB0aGUgWm9vS2VlcGVyIHNlcnZlcnMuCisgICAgdGhpcy56b29LZWVwZXJDbHVzdGVyID0gbmV3IE1pbmlab29LZWVwZXJDbHVzdGVyKCk7CisgICAgdGhpcy56b29LZWVwZXJDbHVzdGVyLnN0YXJ0dXAodGVzdERpcik7CisKKyAgICAvLyBzdGFydCB0aGUgbWluaSBjbHVzdGVyCisgICAgdGhpcy5jbHVzdGVyID0gbmV3IE1pbmlIQmFzZUNsdXN0ZXIoY29uZiwgcmVnaW9uU2VydmVycyk7CisKKyAgICBpZiAob3Blbk1ldGFUYWJsZSkgeworICAgICAgLy8gb3BlbmluZyB0aGUgTUVUQSB0YWJsZSBlbnN1cmVzIHRoYXQgY2x1c3RlciBpcyBydW5uaW5nCisgICAgICBuZXcgSFRhYmxlKGNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBSdW4gYWZ0ZXIgaGJhc2UgY2x1c3RlciBpcyBzdGFydGVkIHVwLgorICAgKi8KKyAgcHJvdGVjdGVkIHZvaWQgcG9zdEhCYXNlQ2x1c3RlclNldHVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gY29udGludWUKKyAgfSAKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgaWYgKHN0YXJ0RGZzKSB7CisgICAgICAgIC8vIHN0YXJ0IHVwIHRoZSBkZnMKKyAgICAgICAgZGZzQ2x1c3RlciA9IG5ldyBNaW5pREZTQ2x1c3Rlcihjb25mLCAyLCB0cnVlLCAoU3RyaW5nW10pbnVsbCk7CisKKyAgICAgICAgLy8gbWFuZ2xlIHRoZSBjb25mIHNvIHRoYXQgdGhlIGZzIHBhcmFtZXRlciBwb2ludHMgdG8gdGhlIG1pbmlkZnMgd2UKKyAgICAgICAgLy8ganVzdCBzdGFydGVkIHVwCisgICAgICAgIEZpbGVTeXN0ZW0gZmlsZXN5c3RlbSA9IGRmc0NsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpOworICAgICAgICBjb25mLnNldCgiZnMuZGVmYXVsdC5uYW1lIiwgZmlsZXN5c3RlbS5nZXRVcmkoKS50b1N0cmluZygpKTsgICAgICAKKyAgICAgICAgUGF0aCBwYXJlbnRkaXIgPSBmaWxlc3lzdGVtLmdldEhvbWVEaXJlY3RvcnkoKTsKKyAgICAgICAgY29uZi5zZXQoSENvbnN0YW50cy5IQkFTRV9ESVIsIHBhcmVudGRpci50b1N0cmluZygpKTsKKyAgICAgICAgZmlsZXN5c3RlbS5ta2RpcnMocGFyZW50ZGlyKTsKKyAgICAgICAgRlNVdGlscy5zZXRWZXJzaW9uKGZpbGVzeXN0ZW0sIHBhcmVudGRpcik7CisgICAgICB9CisKKyAgICAgIC8vIGRvIHRoZSBzdXBlciBzZXR1cCBub3cuIGlmIHdlIGhhZCBkb25lIGl0IGZpcnN0LCB0aGVuIHdlIHdvdWxkIGhhdmUKKyAgICAgIC8vIGdvdHRlbiBvdXIgY29uZiBhbGwgbWFuZ2xlZCBhbmQgYSBsb2NhbCBmcyBzdGFydGVkIHVwLgorICAgICAgc3VwZXIuc2V0VXAoKTsKKyAgICAKKyAgICAgIC8vIHJ1biB0aGUgcHJlLWNsdXN0ZXIgc2V0dXAKKyAgICAgIHByZUhCYXNlQ2x1c3RlclNldHVwKCk7ICAgIAorCisgICAgICAvLyBzdGFydCB0aGUgaW5zdGFuY2UKKyAgICAgIGhCYXNlQ2x1c3RlclNldHVwKCk7CisKKyAgICAgIC8vIHJ1biBwb3N0LWNsdXN0ZXIgc2V0dXAKKyAgICAgIHBvc3RIQmFzZUNsdXN0ZXJTZXR1cCgpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoIkV4Y2VwdGlvbiBpbiBzZXR1cCEiLCBlKTsKKyAgICAgIGlmIChjbHVzdGVyICE9IG51bGwpIHsKKyAgICAgICAgY2x1c3Rlci5zaHV0ZG93bigpOworICAgICAgfQorICAgICAgaWYgKHpvb0tlZXBlckNsdXN0ZXIgIT0gbnVsbCkgeworICAgICAgICB6b29LZWVwZXJDbHVzdGVyLnNodXRkb3duKCk7CisgICAgICB9CisgICAgICBpZiAoZGZzQ2x1c3RlciAhPSBudWxsKSB7CisgICAgICAgIHNodXRkb3duRGZzKGRmc0NsdXN0ZXIpOworICAgICAgfQorICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpZiAoIW9wZW5NZXRhVGFibGUpIHsKKyAgICAgIC8vIG9wZW4gdGhlIE1FVEEgdGFibGUgbm93IHRvIGVuc3VyZSBjbHVzdGVyIGlzIHJ1bm5pbmcgYmVmb3JlIHNodXRkb3duLgorICAgICAgbmV3IEhUYWJsZShjb25mLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSk7CisgICAgfQorICAgIHN1cGVyLnRlYXJEb3duKCk7CisgICAgdHJ5IHsKKyAgICAgIEhDb25uZWN0aW9uTWFuYWdlci5kZWxldGVDb25uZWN0aW9uSW5mbyhjb25mLCB0cnVlKTsKKyAgICAgIGlmICh0aGlzLmNsdXN0ZXIgIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHRoaXMuY2x1c3Rlci5zaHV0ZG93bigpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy53YXJuKCJDbG9zaW5nIG1pbmkgZGZzIiwgZSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICB0aGlzLnpvb0tlZXBlckNsdXN0ZXIuc2h1dGRvd24oKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIExPRy53YXJuKCJTaHV0dGluZyBkb3duIFpvb0tlZXBlciBjbHVzdGVyIiwgZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlmIChzdGFydERmcykgeworICAgICAgICBzaHV0ZG93bkRmcyhkZnNDbHVzdGVyKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKGUpOworICAgIH0KKyAgICAvLyBSZWZsZWN0aW9uVXRpbHMucHJpbnRUaHJlYWRJbmZvKG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0KSwKKyAgICAvLyAgIlRlbXBvcmFyeSBlbmQtb2YtdGVzdCB0aHJlYWQgZHVtcCBkZWJ1Z2dpbmcgSEFET09QLTIwNDA6ICIgKyBnZXROYW1lKCkpOworICB9CisKKyAgCisgIC8qKgorICAgKiBVc2UgdGhpcyB1dGlsaXR5IG1ldGhvZCBkZWJ1Z2dpbmcgd2h5IGNsdXN0ZXIgd29uJ3QgZ28gZG93bi4gIE9uIGEKKyAgICogcGVyaW9kIGl0IHRocm93cyBhIHRocmVhZCBkdW1wLiAgTWV0aG9kIGVuZHMgd2hlbiBhbGwgY2x1c3RlcgorICAgKiByZWdpb25zZXJ2ZXJzIGFuZCBtYXN0ZXIgdGhyZWFkcyBhcmUgbm8gbG9uZyBhbGl2ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRocmVhZER1bXBpbmdKb2luKCkgeworICAgIGlmICh0aGlzLmNsdXN0ZXIuZ2V0UmVnaW9uVGhyZWFkcygpICE9IG51bGwpIHsKKyAgICAgIGZvcihUaHJlYWQgdDogdGhpcy5jbHVzdGVyLmdldFJlZ2lvblRocmVhZHMoKSkgeworICAgICAgICB0aHJlYWREdW1waW5nSm9pbih0KTsKKyAgICAgIH0KKyAgICB9CisgICAgdGhyZWFkRHVtcGluZ0pvaW4odGhpcy5jbHVzdGVyLmdldE1hc3RlcigpKTsKKyAgfQorCisgIHByb3RlY3RlZCB2b2lkIHRocmVhZER1bXBpbmdKb2luKGZpbmFsIFRocmVhZCB0KSB7CisgICAgaWYgKHQgPT0gbnVsbCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIHdoaWxlICh0LmlzQWxpdmUoKSkgeworICAgICAgdHJ5IHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuaW5mbygiQ29udGludWluZy4uLiIsIGUpOworICAgICAgfQorICAgICAgaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lID4gNjAwMDApIHsKKyAgICAgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgIFJlZmxlY3Rpb25VdGlscy5wcmludFRocmVhZEluZm8obmV3IFByaW50V3JpdGVyKFN5c3RlbS5vdXQpLAorICAgICAgICAgICAgIkF1dG9tYXRpYyBTdGFjayBUcmFjZSBldmVyeSA2MCBzZWNvbmRzIHdhaXRpbmcgb24gIiArCisgICAgICAgICAgICB0LmdldE5hbWUoKSk7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IQmFzZVRlc3RDYXNlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IQmFzZVRlc3RDYXNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY0YjI5NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hCYXNlVGVzdENhc2UuamF2YQpAQCAtMCwwICsxLDYyNyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkludGVybmFsU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIHRlc3QgY2FzZXMuIFBlcmZvcm1zIGFsbCBzdGF0aWMgaW5pdGlhbGl6YXRpb24KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEhCYXNlVGVzdENhc2UgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhIQmFzZVRlc3RDYXNlLmNsYXNzKTsKKworICAvKiogY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgbmFtZSBmb3IgdGVzdCBkaXJlY3RvcnkgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9ESVJFQ1RPUllfS0VZID0gInRlc3QuYnVpbGQuZGF0YSI7CisKKyAgcHJvdGVjdGVkIGZpbmFsIHN0YXRpYyBieXRlIFtdIENPTEZBTUlMWV9OQU1FMSA9IEJ5dGVzLnRvQnl0ZXMoImNvbGZhbWlseTE6Iik7CisgIHByb3RlY3RlZCBmaW5hbCBzdGF0aWMgYnl0ZSBbXSBDT0xGQU1JTFlfTkFNRTIgPSBCeXRlcy50b0J5dGVzKCJjb2xmYW1pbHkyOiIpOworICBwcm90ZWN0ZWQgZmluYWwgc3RhdGljIGJ5dGUgW10gQ09MRkFNSUxZX05BTUUzID0gQnl0ZXMudG9CeXRlcygiY29sZmFtaWx5MzoiKTsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFtdW10gQ09MVU1OUyA9IHtDT0xGQU1JTFlfTkFNRTEsCisgICAgQ09MRkFNSUxZX05BTUUyLCBDT0xGQU1JTFlfTkFNRTN9OworCisgIHByaXZhdGUgYm9vbGVhbiBsb2NhbGZzID0gZmFsc2U7CisgIHByb3RlY3RlZCBQYXRoIHRlc3REaXIgPSBudWxsOworICBwcm90ZWN0ZWQgRmlsZVN5c3RlbSBmcyA9IG51bGw7CisgIHByb3RlY3RlZCBIUmVnaW9uIHJvb3QgPSBudWxsOworICBwcm90ZWN0ZWQgSFJlZ2lvbiBtZXRhID0gbnVsbDsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyIEZJUlNUX0NIQVIgPSAnYSc7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhciBMQVNUX0NIQVIgPSAneic7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFBVTkNUVUFUSU9OID0gIn5gQCMkJV4mKigpLV8rPTo7JywuPD4vP1tde318IjsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBieXRlIFtdIFNUQVJUX0tFWV9CWVRFUyA9IHtGSVJTVF9DSEFSLCBGSVJTVF9DSEFSLCBGSVJTVF9DSEFSfTsKKyAgcHJvdGVjdGVkIFN0cmluZyBTVEFSVF9LRVk7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IE1BWFZFUlNJT05TID0gMzsKKyAgCisgIHN0YXRpYyB7CisgICAgaW5pdGlhbGl6ZSgpOworICB9CisgIAorICBwdWJsaWMgdm9sYXRpbGUgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBIQmFzZVRlc3RDYXNlKCkgeworICAgIHN1cGVyKCk7CisgICAgaW5pdCgpOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIG5hbWUKKyAgICovCisgIHB1YmxpYyBIQmFzZVRlc3RDYXNlKFN0cmluZyBuYW1lKSB7CisgICAgc3VwZXIobmFtZSk7CisgICAgaW5pdCgpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgaW5pdCgpIHsKKyAgICBjb25mID0gbmV3IEhCYXNlQ29uZmlndXJhdGlvbigpOworICAgIHRyeSB7CisgICAgICBTVEFSVF9LRVkgPSBuZXcgU3RyaW5nKFNUQVJUX0tFWV9CWVRFUywgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiZXJyb3IgZHVyaW5nIGluaXRpYWxpemF0aW9uIiwgZSk7CisgICAgICBmYWlsKCk7CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGFmdGVyIHRoZSBtaW5pIGhkZnMgY2x1c3RlciBoYXMKKyAgICogc3RhcnRlZCBvciB3ZSBlbmQgdXAgd2l0aCBhIGxvY2FsIGZpbGUgc3lzdGVtLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICBsb2NhbGZzID0KKyAgICAgIChjb25mLmdldCgiZnMuZGVmYXVsdC5uYW1lIiwgImZpbGU6Ly8vIikuY29tcGFyZVRvKCJmaWxlOi8vLyIpID09IDApOworCisgICAgaWYgKGZzID09IG51bGwpIHsKKyAgICAgIHRoaXMuZnMgPSBGaWxlU3lzdGVtLmdldChjb25mKTsKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGlmIChsb2NhbGZzKSB7CisgICAgICAgIHRoaXMudGVzdERpciA9IGdldFVuaXRUZXN0ZGlyKGdldE5hbWUoKSk7CisgICAgICAgIGlmIChmcy5leGlzdHModGVzdERpcikpIHsKKyAgICAgICAgICBmcy5kZWxldGUodGVzdERpciwgdHJ1ZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRoaXMudGVzdERpciA9CisgICAgICAgICAgdGhpcy5mcy5tYWtlUXVhbGlmaWVkKG5ldyBQYXRoKGNvbmYuZ2V0KEhDb25zdGFudHMuSEJBU0VfRElSKSkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoImVycm9yIGR1cmluZyBzZXR1cCIsIGUpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBpZiAobG9jYWxmcykgeworICAgICAgICBpZiAodGhpcy5mcy5leGlzdHModGVzdERpcikpIHsKKyAgICAgICAgICB0aGlzLmZzLmRlbGV0ZSh0ZXN0RGlyLCB0cnVlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoImVycm9yIGR1cmluZyB0ZWFyIGRvd24iLCBlKTsKKyAgICB9CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgfQorCisgIHByb3RlY3RlZCBQYXRoIGdldFVuaXRUZXN0ZGlyKFN0cmluZyB0ZXN0TmFtZSkgeworICAgIHJldHVybiBuZXcgUGF0aCgKKyAgICAgICAgY29uZi5nZXQoVEVTVF9ESVJFQ1RPUllfS0VZLCAidGVzdC9idWlsZC9kYXRhIiksIHRlc3ROYW1lKTsKKyAgfQorCisgIHByb3RlY3RlZCBIUmVnaW9uIGNyZWF0ZU5ld0hSZWdpb24oSFRhYmxlRGVzY3JpcHRvciBkZXNjLCBieXRlIFtdIHN0YXJ0S2V5LAorICAgICAgYnl0ZSBbXSBlbmRLZXkpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZVN5c3RlbSBmaWxlc3lzdGVtID0gRmlsZVN5c3RlbS5nZXQoY29uZik7CisgICAgUGF0aCByb290ZGlyID0gZmlsZXN5c3RlbS5tYWtlUXVhbGlmaWVkKAorICAgICAgICBuZXcgUGF0aChjb25mLmdldChIQ29uc3RhbnRzLkhCQVNFX0RJUikpKTsKKyAgICBmaWxlc3lzdGVtLm1rZGlycyhyb290ZGlyKTsKKyAgICAKKyAgICByZXR1cm4gSFJlZ2lvbi5jcmVhdGVIUmVnaW9uKG5ldyBIUmVnaW9uSW5mbyhkZXNjLCBzdGFydEtleSwgZW5kS2V5KSwKKyAgICAgICAgcm9vdGRpciwgY29uZik7CisgIH0KKyAgCisgIHByb3RlY3RlZCBIUmVnaW9uIG9wZW5DbG9zZWRSZWdpb24oZmluYWwgSFJlZ2lvbiBjbG9zZWRSZWdpb24pCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByID0gbmV3IEhSZWdpb24oY2xvc2VkUmVnaW9uLmdldEJhc2VEaXIoKSwgY2xvc2VkUmVnaW9uLmdldExvZygpLAorICAgICAgICBjbG9zZWRSZWdpb24uZ2V0RmlsZXN5c3RlbSgpLCBjbG9zZWRSZWdpb24uZ2V0Q29uZigpLAorICAgICAgICBjbG9zZWRSZWdpb24uZ2V0UmVnaW9uSW5mbygpLCBudWxsKTsKKyAgICByLmluaXRpYWxpemUobnVsbCwgbnVsbCk7CisgICAgcmV0dXJuIHI7CisgIH0KKyAgCisgIC8qKgorICAgKiBDcmVhdGUgYSB0YWJsZSBvZiBuYW1lIDxjb2RlPm5hbWU8L2NvZGU+IHdpdGgge0BsaW5rIENPTFVNTlN9IGZvcgorICAgKiBmYW1pbGllcy4KKyAgICogQHBhcmFtIG5hbWUgTmFtZSB0byBnaXZlIHRhYmxlLgorICAgKiBAcmV0dXJuIENvbHVtbiBkZXNjcmlwdG9yLgorICAgKi8KKyAgcHJvdGVjdGVkIEhUYWJsZURlc2NyaXB0b3IgY3JlYXRlVGFibGVEZXNjcmlwdG9yKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgcmV0dXJuIGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihuYW1lLCBNQVhWRVJTSU9OUyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBDcmVhdGUgYSB0YWJsZSBvZiBuYW1lIDxjb2RlPm5hbWU8L2NvZGU+IHdpdGgge0BsaW5rIENPTFVNTlN9IGZvcgorICAgKiBmYW1pbGllcy4KKyAgICogQHBhcmFtIG5hbWUgTmFtZSB0byBnaXZlIHRhYmxlLgorICAgKiBAcGFyYW0gdmVyc2lvbnMgSG93IG1hbnkgdmVyc2lvbnMgdG8gYWxsb3cgcGVyIGNvbHVtbi4KKyAgICogQHJldHVybiBDb2x1bW4gZGVzY3JpcHRvci4KKyAgICovCisgIHByb3RlY3RlZCBIVGFibGVEZXNjcmlwdG9yIGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihmaW5hbCBTdHJpbmcgbmFtZSwKKyAgICAgIGZpbmFsIGludCB2ZXJzaW9ucykgeworICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gbmV3IEhUYWJsZURlc2NyaXB0b3IobmFtZSk7CisgICAgaHRkLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoQ09MRkFNSUxZX05BTUUxLCB2ZXJzaW9ucywKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQ09NUFJFU1NJT04sIGZhbHNlLCBmYWxzZSwKKyAgICAgIEludGVnZXIuTUFYX1ZBTFVFLCBIQ29uc3RhbnRzLkZPUkVWRVIsIGZhbHNlKSk7CisgICAgaHRkLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoQ09MRkFNSUxZX05BTUUyLCB2ZXJzaW9ucywKKyAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9DT01QUkVTU0lPTiwgZmFsc2UsIGZhbHNlLAorICAgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgSENvbnN0YW50cy5GT1JFVkVSLCBmYWxzZSkpOworICAgIGh0ZC5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTEZBTUlMWV9OQU1FMywgdmVyc2lvbnMsCisgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQ09NUFJFU1NJT04sIGZhbHNlLCBmYWxzZSwKKyAgICAgICAgSW50ZWdlci5NQVhfVkFMVUUsICBIQ29uc3RhbnRzLkZPUkVWRVIsIGZhbHNlKSk7CisgICAgcmV0dXJuIGh0ZDsKKyAgfQorICAKKyAgLyoqCisgICAqIEFkZCBjb250ZW50IHRvIHJlZ2lvbiA8Y29kZT5yPC9jb2RlPiBvbiB0aGUgcGFzc2VkIGNvbHVtbgorICAgKiA8Y29kZT5jb2x1bW48L2NvZGU+LgorICAgKiBBZGRzIGRhdGEgb2YgdGhlIGZyb20gJ2FhYScsICdhYWInLCBldGMgd2hlcmUga2V5IGFuZCB2YWx1ZSBhcmUgdGhlIHNhbWUuCisgICAqIEBwYXJhbSByCisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAcmV0dXJuIGNvdW50IG9mIHdoYXQgd2UgYWRkZWQuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGxvbmcgYWRkQ29udGVudChmaW5hbCBIUmVnaW9uIHIsIGZpbmFsIGJ5dGUgW10gY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW10gc3RhcnRLZXkgPSByLmdldFJlZ2lvbkluZm8oKS5nZXRTdGFydEtleSgpOworICAgIGJ5dGUgW10gZW5kS2V5ID0gci5nZXRSZWdpb25JbmZvKCkuZ2V0RW5kS2V5KCk7CisgICAgYnl0ZSBbXSBzdGFydEtleUJ5dGVzID0gc3RhcnRLZXk7CisgICAgaWYgKHN0YXJ0S2V5Qnl0ZXMgPT0gbnVsbCB8fCBzdGFydEtleUJ5dGVzLmxlbmd0aCA9PSAwKSB7CisgICAgICBzdGFydEtleUJ5dGVzID0gU1RBUlRfS0VZX0JZVEVTOworICAgIH0KKyAgICByZXR1cm4gYWRkQ29udGVudChuZXcgSFJlZ2lvbkluY29tbW9uKHIpLCBCeXRlcy50b1N0cmluZyhjb2x1bW4pLAorICAgICAgc3RhcnRLZXlCeXRlcywgZW5kS2V5LCAtMSk7CisgIH0KKworICAvKioKKyAgICogQWRkIGNvbnRlbnQgdG8gcmVnaW9uIDxjb2RlPnI8L2NvZGU+IG9uIHRoZSBwYXNzZWQgY29sdW1uCisgICAqIDxjb2RlPmNvbHVtbjwvY29kZT4uCisgICAqIEFkZHMgZGF0YSBvZiB0aGUgZnJvbSAnYWFhJywgJ2FhYicsIGV0YyB3aGVyZSBrZXkgYW5kIHZhbHVlIGFyZSB0aGUgc2FtZS4KKyAgICogQHBhcmFtIHVwZGF0ZXIgIEFuIGluc3RhbmNlIG9mIHtAbGluayBJbmNvbW1vbn0uCisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAcmV0dXJuIGNvdW50IG9mIHdoYXQgd2UgYWRkZWQuCisgICAqLworICBwcm90ZWN0ZWQgc3RhdGljIGxvbmcgYWRkQ29udGVudChmaW5hbCBJbmNvbW1vbiB1cGRhdGVyLCBmaW5hbCBTdHJpbmcgY29sdW1uKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBhZGRDb250ZW50KHVwZGF0ZXIsIGNvbHVtbiwgU1RBUlRfS0VZX0JZVEVTLCBudWxsKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGQgY29udGVudCB0byByZWdpb24gPGNvZGU+cjwvY29kZT4gb24gdGhlIHBhc3NlZCBjb2x1bW4KKyAgICogPGNvZGU+Y29sdW1uPC9jb2RlPi4KKyAgICogQWRkcyBkYXRhIG9mIHRoZSBmcm9tICdhYWEnLCAnYWFiJywgZXRjIHdoZXJlIGtleSBhbmQgdmFsdWUgYXJlIHRoZSBzYW1lLgorICAgKiBAcGFyYW0gdXBkYXRlciAgQW4gaW5zdGFuY2Ugb2Yge0BsaW5rIEluY29tbW9ufS4KKyAgICogQHBhcmFtIGNvbHVtbgorICAgKiBAcGFyYW0gc3RhcnRLZXlCeXRlcyBXaGVyZSB0byBzdGFydCB0aGUgcm93cyBpbnNlcnRlZAorICAgKiBAcGFyYW0gZW5kS2V5IFdoZXJlIHRvIHN0b3AgaW5zZXJ0aW5nIHJvd3MuCisgICAqIEByZXR1cm4gY291bnQgb2Ygd2hhdCB3ZSBhZGRlZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJvdGVjdGVkIHN0YXRpYyBsb25nIGFkZENvbnRlbnQoZmluYWwgSW5jb21tb24gdXBkYXRlciwgZmluYWwgU3RyaW5nIGNvbHVtbiwKKyAgICAgIGZpbmFsIGJ5dGUgW10gc3RhcnRLZXlCeXRlcywgZmluYWwgYnl0ZSBbXSBlbmRLZXkpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGFkZENvbnRlbnQodXBkYXRlciwgY29sdW1uLCBzdGFydEtleUJ5dGVzLCBlbmRLZXksIC0xKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEFkZCBjb250ZW50IHRvIHJlZ2lvbiA8Y29kZT5yPC9jb2RlPiBvbiB0aGUgcGFzc2VkIGNvbHVtbgorICAgKiA8Y29kZT5jb2x1bW48L2NvZGU+LgorICAgKiBBZGRzIGRhdGEgb2YgdGhlIGZyb20gJ2FhYScsICdhYWInLCBldGMgd2hlcmUga2V5IGFuZCB2YWx1ZSBhcmUgdGhlIHNhbWUuCisgICAqIEBwYXJhbSB1cGRhdGVyICBBbiBpbnN0YW5jZSBvZiB7QGxpbmsgSW5jb21tb259LgorICAgKiBAcGFyYW0gY29sdW1uCisgICAqIEBwYXJhbSBzdGFydEtleUJ5dGVzIFdoZXJlIHRvIHN0YXJ0IHRoZSByb3dzIGluc2VydGVkCisgICAqIEBwYXJhbSBlbmRLZXkgV2hlcmUgdG8gc3RvcCBpbnNlcnRpbmcgcm93cy4KKyAgICogQHBhcmFtIHRzIFRpbWVzdGFtcCB0byB3cml0ZSB0aGUgY29udGVudCB3aXRoLgorICAgKiBAcmV0dXJuIGNvdW50IG9mIHdoYXQgd2UgYWRkZWQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByb3RlY3RlZCBzdGF0aWMgbG9uZyBhZGRDb250ZW50KGZpbmFsIEluY29tbW9uIHVwZGF0ZXIsIGZpbmFsIFN0cmluZyBjb2x1bW4sCisgICAgICBmaW5hbCBieXRlIFtdIHN0YXJ0S2V5Qnl0ZXMsIGZpbmFsIGJ5dGUgW10gZW5kS2V5LCBmaW5hbCBsb25nIHRzKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgY291bnQgPSAwOworICAgIC8vIEFkZCByb3dzIG9mIHRocmVlIGNoYXJhY3RlcnMuICBUaGUgZmlyc3QgY2hhcmFjdGVyIHN0YXJ0cyB3aXRoIHRoZQorICAgIC8vICdhJyBjaGFyYWN0ZXIgYW5kIHJ1bnMgdXAgdG8gJ3onLiAgUGVyIGZpcnN0IGNoYXJhY3Rlciwgd2UgcnVuIHRoZQorICAgIC8vIHNlY29uZCBjaGFyYWN0ZXIgb3ZlciBzYW1lIHJhbmdlLiAgQW5kIHNhbWUgZm9yIHRoZSB0aGlyZCBzbyByb3dzCisgICAgLy8gKGFuZCB2YWx1ZXMpIGxvb2sgbGlrZSB0aGlzOiAnYWFhJywgJ2FhYicsICdhYWMnLCBldGMuCisgICAgY2hhciBzZWNvbmRDaGFyU3RhcnQgPSAoY2hhcilzdGFydEtleUJ5dGVzWzFdOworICAgIGNoYXIgdGhpcmRDaGFyU3RhcnQgPSAoY2hhcilzdGFydEtleUJ5dGVzWzJdOworICAgIEVYSVQ6IGZvciAoY2hhciBjID0gKGNoYXIpc3RhcnRLZXlCeXRlc1swXTsgYyA8PSBMQVNUX0NIQVI7IGMrKykgeworICAgICAgZm9yIChjaGFyIGQgPSBzZWNvbmRDaGFyU3RhcnQ7IGQgPD0gTEFTVF9DSEFSOyBkKyspIHsKKyAgICAgICAgZm9yIChjaGFyIGUgPSB0aGlyZENoYXJTdGFydDsgZSA8PSBMQVNUX0NIQVI7IGUrKykgeworICAgICAgICAgIGJ5dGUgW10gdCA9IG5ldyBieXRlIFtdIHsoYnl0ZSljLCAoYnl0ZSlkLCAoYnl0ZSllfTsKKyAgICAgICAgICBpZiAoZW5kS2V5ICE9IG51bGwgJiYgZW5kS2V5Lmxlbmd0aCA+IDAKKyAgICAgICAgICAgICAgJiYgQnl0ZXMuY29tcGFyZVRvKGVuZEtleSwgdCkgPD0gMCkgeworICAgICAgICAgICAgYnJlYWsgRVhJVDsKKyAgICAgICAgICB9CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gdHMgPT0gLTEgPyAKKyAgICAgICAgICAgICAgbmV3IEJhdGNoVXBkYXRlKHQpIDogbmV3IEJhdGNoVXBkYXRlKHQsIHRzKTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2x1bW4sIHQpOworICAgICAgICAgICAgICB1cGRhdGVyLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICAgIH0gCisgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gU2V0IHN0YXJ0IGNoYXJhY3RlciBiYWNrIHRvIEZJUlNUX0NIQVIgYWZ0ZXIgd2UndmUgZG9uZSBmaXJzdCBsb29wLgorICAgICAgICB0aGlyZENoYXJTdGFydCA9IEZJUlNUX0NIQVI7CisgICAgICB9CisgICAgICBzZWNvbmRDaGFyU3RhcnQgPSBGSVJTVF9DSEFSOworICAgIH0KKyAgICByZXR1cm4gY291bnQ7CisgIH0KKyAgCisgIC8qKgorICAgKiBJbXBsZW1lbnRvcnMgY2FuIGZsdXNoY2FjaGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBGbHVzaENhY2hlIHsKKyAgICAvKioKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHZvaWQgZmx1c2hjYWNoZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIEludGVyZmFjZSB1c2VkIGJ5IHRlc3RzIHNvIGNhbiBkbyBjb21tb24gb3BlcmF0aW9ucyBhZ2FpbnN0IGFuIEhUYWJsZQorICAgKiBvciBhbiBIUmVnaW9uLgorICAgKiAKKyAgICogVE9PRDogQ29tZSB1cCB3LyBhIGJldHRlciBuYW1lIGZvciB0aGlzIGludGVyZmFjZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEluY29tbW9uIHsKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqIEByZXR1cm4gdmFsdWUgZm9yIHJvdy9jb2x1bW4gcGFpcgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgQ2VsbCBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uKSB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgLyoqCisgICAgICogQHBhcmFtIHJvdworICAgICAqIEBwYXJhbSBjb2x1bW4KKyAgICAgKiBAcGFyYW0gdmVyc2lvbnMKKyAgICAgKiBAcmV0dXJuIHZhbHVlIGZvciByb3cvY29sdW1uIHBhaXIgZm9yIG51bWJlciBvZiB2ZXJzaW9ucyByZXF1ZXN0ZWQKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIENlbGxbXSBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uLCBpbnQgdmVyc2lvbnMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcm93CisgICAgICogQHBhcmFtIGNvbHVtbgorICAgICAqIEBwYXJhbSB0cworICAgICAqIEBwYXJhbSB2ZXJzaW9ucworICAgICAqIEByZXR1cm4gdmFsdWUgZm9yIHJvdy9jb2x1bW4vdGltZXN0YW1wIHR1cGxlIGZvciBudW1iZXIgb2YgdmVyc2lvbnMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIENlbGxbXSBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uLCBsb25nIHRzLCBpbnQgdmVyc2lvbnMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIC8qKgorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcGFyYW0gY29sdW1uCisgICAgICogQHBhcmFtIHRzCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChieXRlIFtdIHJvdywgYnl0ZSBbXSBjb2x1bW4sIGxvbmcgdHMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBiYXRjaFVwZGF0ZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBjb21taXQoQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBjb2x1bW5zCisgICAgICogQHBhcmFtIGZpcnN0Um93CisgICAgICogQHBhcmFtIHRzCisgICAgICogQHJldHVybiBzY2FubmVyIGZvciBzcGVjaWZpZWQgY29sdW1ucywgZmlyc3Qgcm93IGFuZCB0aW1lc3RhbXAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIFNjYW5uZXJJbmNvbW1vbiBnZXRTY2FubmVyKGJ5dGUgW10gW10gY29sdW1ucywgYnl0ZSBbXSBmaXJzdFJvdywKKyAgICAgIGxvbmcgdHMpIHRocm93cyBJT0V4Y2VwdGlvbjsKKyAgfQorICAKKyAgLyoqCisgICAqIEEgY2xhc3MgdGhhdCBtYWtlcyBhIHtAbGluayBJbmNvbW1vbn0gb3V0IG9mIGEge0BsaW5rIEhSZWdpb259CisgICAqLworICBwdWJsaWMgc3RhdGljIGNsYXNzIEhSZWdpb25JbmNvbW1vbiBpbXBsZW1lbnRzIEluY29tbW9uLCBGbHVzaENhY2hlIHsKKyAgICBmaW5hbCBIUmVnaW9uIHJlZ2lvbjsKKyAgICAKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gSFJlZ2lvbgorICAgICAqLworICAgIHB1YmxpYyBIUmVnaW9uSW5jb21tb24oZmluYWwgSFJlZ2lvbiBIUmVnaW9uKSB7CisgICAgICB0aGlzLnJlZ2lvbiA9IEhSZWdpb247CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGNvbW1pdChCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFsbChieXRlIFtdIHJvdywgYnl0ZSBbXSBjb2x1bW4sIGxvbmcgdHMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMucmVnaW9uLmRlbGV0ZUFsbChyb3csIGNvbHVtbiwgdHMsIG51bGwpOworICAgIH0KKworICAgIHB1YmxpYyBTY2FubmVySW5jb21tb24gZ2V0U2Nhbm5lcihieXRlIFtdW10gY29sdW1ucywgYnl0ZSBbXSBmaXJzdFJvdywKKyAgICAgIGxvbmcgdHMpIAorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gbmV3IAorICAgICAgICBJbnRlcm5hbFNjYW5uZXJJbmNvbW1vbihyZWdpb24uZ2V0U2Nhbm5lcihjb2x1bW5zLCBmaXJzdFJvdywgdHMsIG51bGwpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VsbCBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gVE9ETzogRml4IHByb2ZsaWdhY3kgY29udmVydGluZyBmcm9tIExpc3QgdG8gQ2VsbCBbXS4KKyAgICAgIENlbGxbXSByZXN1bHQgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheSh0aGlzLnJlZ2lvbi5nZXQocm93LCBjb2x1bW4sIC0xLCAtMSkpOworICAgICAgcmV0dXJuIChyZXN1bHQgPT0gbnVsbCk/IG51bGwgOiByZXN1bHRbMF07CisgICAgfQorCisgICAgcHVibGljIENlbGxbXSBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uLCBpbnQgdmVyc2lvbnMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIFRPRE86IEZpeCBwcm9mbGlnYWN5IGNvbnZlcnRpbmcgZnJvbSBMaXN0IHRvIENlbGwgW10uCisgICAgICByZXR1cm4gQ2VsbC5jcmVhdGVTaW5nbGVDZWxsQXJyYXkodGhpcy5yZWdpb24uZ2V0KHJvdywgY29sdW1uLCAtMSwgdmVyc2lvbnMpKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQ2VsbFtdIGdldChieXRlIFtdIHJvdywgYnl0ZSBbXSBjb2x1bW4sIGxvbmcgdHMsIGludCB2ZXJzaW9ucykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gVE9ETzogRml4IHByb2ZsaWdhY3kgY29udmVydGluZyBmcm9tIExpc3QgdG8gQ2VsbCBbXS4KKyAgICAgIHJldHVybiBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheSh0aGlzLnJlZ2lvbi5nZXQocm93LCBjb2x1bW4sIHRzLCB2ZXJzaW9ucykpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBwYXJhbSByb3cKKyAgICAgKiBAcmV0dXJuIHZhbHVlcyBmb3IgZWFjaCBjb2x1bW4gaW4gdGhlIHNwZWNpZmllZCByb3cKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIE1hcDxieXRlIFtdLCBDZWxsPiBnZXRGdWxsKGJ5dGUgW10gcm93KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgcmV0dXJuIHJlZ2lvbi5nZXRGdWxsKHJvdywgbnVsbCwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBmbHVzaGNhY2hlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRoaXMucmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQSBjbGFzcyB0aGF0IG1ha2VzIGEge0BsaW5rIEluY29tbW9ufSBvdXQgb2YgYSB7QGxpbmsgSFRhYmxlfQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBIVGFibGVJbmNvbW1vbiBpbXBsZW1lbnRzIEluY29tbW9uIHsKKyAgICBmaW5hbCBIVGFibGUgdGFibGU7CisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gdGFibGUKKyAgICAgKi8KKyAgICBwdWJsaWMgSFRhYmxlSW5jb21tb24oZmluYWwgSFRhYmxlIHRhYmxlKSB7CisgICAgICBzdXBlcigpOworICAgICAgdGhpcy50YWJsZSA9IHRhYmxlOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBjb21taXQoQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0YWJsZS5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBkZWxldGVBbGwoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uLCBsb25nIHRzKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLnRhYmxlLmRlbGV0ZUFsbChyb3csIGNvbHVtbiwgdHMpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgU2Nhbm5lckluY29tbW9uIGdldFNjYW5uZXIoYnl0ZSBbXVtdIGNvbHVtbnMsIGJ5dGUgW10gZmlyc3RSb3csIGxvbmcgdHMpIAorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gbmV3IAorICAgICAgICBDbGllbnRTY2FubmVySW5jb21tb24odGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBmaXJzdFJvdywgdHMsIG51bGwpKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIENlbGwgZ2V0KGJ5dGUgW10gcm93LCBieXRlIFtdIGNvbHVtbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlLmdldChyb3csIGNvbHVtbik7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBDZWxsW10gZ2V0KGJ5dGUgW10gcm93LCBieXRlIFtdIGNvbHVtbiwgaW50IHZlcnNpb25zKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gdGhpcy50YWJsZS5nZXQocm93LCBjb2x1bW4sIHZlcnNpb25zKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIENlbGxbXSBnZXQoYnl0ZSBbXSByb3csIGJ5dGUgW10gY29sdW1uLCBsb25nIHRzLCBpbnQgdmVyc2lvbnMpCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJldHVybiB0aGlzLnRhYmxlLmdldChyb3csIGNvbHVtbiwgdHMsIHZlcnNpb25zKTsKKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyBpbnRlcmZhY2UgU2Nhbm5lckluY29tbW9uIAorICBleHRlbmRzIEl0ZXJhYmxlPE1hcC5FbnRyeTxIU3RvcmVLZXksIFNvcnRlZE1hcDxieXRlIFtdLCBDZWxsPj4+IHsKKyAgICBwdWJsaWMgYm9vbGVhbiBuZXh0KExpc3Q8S2V5VmFsdWU+IHZhbHVlcykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb247CisgICAgCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIH0KKyAgCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ2xpZW50U2Nhbm5lckluY29tbW9uIGltcGxlbWVudHMgU2Nhbm5lckluY29tbW9uIHsKKyAgICBTY2FubmVyIHNjYW5uZXI7CisgICAgcHVibGljIENsaWVudFNjYW5uZXJJbmNvbW1vbihTY2FubmVyIHNjYW5uZXIpIHsKKyAgICAgIHRoaXMuc2Nhbm5lciA9IHNjYW5uZXI7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBib29sZWFuIG5leHQoTGlzdDxLZXlWYWx1ZT4gdmFsdWVzKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBSb3dSZXN1bHQgcmVzdWx0cyA9IHNjYW5uZXIubmV4dCgpOworICAgICAgaWYgKHJlc3VsdHMgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICB2YWx1ZXMuY2xlYXIoKTsKKyAgICAgIGZvciAoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGVudHJ5IDogcmVzdWx0cy5lbnRyeVNldCgpKSB7CisgICAgICAgIHZhbHVlcy5hZGQobmV3IEtleVZhbHVlKHJlc3VsdHMuZ2V0Um93KCksIGVudHJ5LmdldEtleSgpLAorICAgICAgICAgIGVudHJ5LmdldFZhbHVlKCkuZ2V0VGltZXN0YW1wKCksIGVudHJ5LmdldFZhbHVlKCkuZ2V0VmFsdWUoKSkpOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIAorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisgICAgCisgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCisgICAgcHVibGljIEl0ZXJhdG9yIGl0ZXJhdG9yKCkgeworICAgICAgcmV0dXJuIHNjYW5uZXIuaXRlcmF0b3IoKTsKKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW50ZXJuYWxTY2FubmVySW5jb21tb24gaW1wbGVtZW50cyBTY2FubmVySW5jb21tb24geworICAgIEludGVybmFsU2Nhbm5lciBzY2FubmVyOworICAgIAorICAgIHB1YmxpYyBJbnRlcm5hbFNjYW5uZXJJbmNvbW1vbihJbnRlcm5hbFNjYW5uZXIgc2Nhbm5lcikgeworICAgICAgdGhpcy5zY2FubmVyID0gc2Nhbm5lcjsKKyAgICB9CisgICAgCisgICAgcHVibGljIGJvb2xlYW4gbmV4dChMaXN0PEtleVZhbHVlPiByZXN1bHRzKQorICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gc2Nhbm5lci5uZXh0KHJlc3VsdHMpOworICAgIH0KKyAgICAKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzY2FubmVyLmNsb3NlKCk7CisgICAgfQorICAgIAorICAgIHB1YmxpYyBJdGVyYXRvcjxNYXAuRW50cnk8SFN0b3JlS2V5LCBTb3J0ZWRNYXA8Ynl0ZSBbXSwgQ2VsbD4+PiBpdGVyYXRvcigpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOworICAgIH0KKyAgfQorICAKKyAgcHJvdGVjdGVkIHZvaWQgYXNzZXJ0Q2VsbEVxdWFscyhmaW5hbCBIUmVnaW9uIHJlZ2lvbiwgZmluYWwgYnl0ZSBbXSByb3csCisgICAgZmluYWwgYnl0ZSBbXSBjb2x1bW4sIGZpbmFsIGxvbmcgdGltZXN0YW1wLCBmaW5hbCBTdHJpbmcgdmFsdWUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWFwPGJ5dGUgW10sIENlbGw+IHJlc3VsdCA9IHJlZ2lvbi5nZXRGdWxsKHJvdywgbnVsbCwgdGltZXN0YW1wLCAxLCBudWxsKTsKKyAgICBDZWxsIGNlbGxfdmFsdWUgPSByZXN1bHQuZ2V0KGNvbHVtbik7CisgICAgaWYgKHZhbHVlID09IG51bGwpIHsKKyAgICAgIGFzc2VydEVxdWFscyhCeXRlcy50b1N0cmluZyhjb2x1bW4pICsgIiBhdCB0aW1lc3RhbXAgIiArIHRpbWVzdGFtcCwgbnVsbCwKKyAgICAgICAgY2VsbF92YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChjZWxsX3ZhbHVlID09IG51bGwpIHsKKyAgICAgICAgZmFpbChCeXRlcy50b1N0cmluZyhjb2x1bW4pICsgIiBhdCB0aW1lc3RhbXAgIiArIHRpbWVzdGFtcCArIAorICAgICAgICAgICJcIiB3YXMgZXhwZWN0ZWQgdG8gYmUgXCIiICsgdmFsdWUgKyAiIGJ1dCB3YXMgbnVsbCIpOworICAgICAgfQorICAgICAgaWYgKGNlbGxfdmFsdWUgIT0gbnVsbCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoQnl0ZXMudG9TdHJpbmcoY29sdW1uKSArICIgYXQgdGltZXN0YW1wICIgCisgICAgICAgICAgICArIHRpbWVzdGFtcCwgdmFsdWUsIG5ldyBTdHJpbmcoY2VsbF92YWx1ZS5nZXRWYWx1ZSgpKSk7CisgICAgICB9CisgICAgfQorICB9CisgIAorICAvKioKKyAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyB1c2VkIGluIHRoZSB0ZXN0IGVudmlyb25tZW50OgorICAgKiAKKyAgICogU2V0cyB0aGUgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIgVEVTVF9ESVJFQ1RPUllfS0VZIGlmIG5vdCBhbHJlYWR5IHNldC4KKyAgICogU2V0cyB0aGUgYm9vbGVhbiBkZWJ1Z2dpbmcgaWYgIkRFQlVHR0lORyIgaXMgc2V0IGluIHRoZSBlbnZpcm9ubWVudC4KKyAgICogSWYgZGVidWdnaW5nIGlzIGVuYWJsZWQsIHJlY29uZmlndXJlcyBsb2dnaW5nIHNvIHRoYXQgdGhlIHJvb3QgbG9nIGxldmVsIGlzCisgICAqIHNldCB0byBXQVJOIGFuZCB0aGUgbG9nZ2luZyBsZXZlbCBmb3IgdGhlIHBhY2thZ2UgaXMgc2V0IHRvIERFQlVHLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGluaXRpYWxpemUoKSB7CisgICAgaWYgKFN5c3RlbS5nZXRQcm9wZXJ0eShURVNUX0RJUkVDVE9SWV9LRVkpID09IG51bGwpIHsKKyAgICAgIFN5c3RlbS5zZXRQcm9wZXJ0eShURVNUX0RJUkVDVE9SWV9LRVksIG5ldyBGaWxlKAorICAgICAgICAgICJidWlsZC9oYmFzZS90ZXN0IikuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb21tb24gbWV0aG9kIHRvIGNsb3NlIGRvd24gYSBNaW5pREZTQ2x1c3RlciBhbmQgdGhlIGFzc29jaWF0ZWQgZmlsZSBzeXN0ZW0KKyAgICogCisgICAqIEBwYXJhbSBjbHVzdGVyCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgc2h1dGRvd25EZnMoTWluaURGU0NsdXN0ZXIgY2x1c3RlcikgeworICAgIGlmIChjbHVzdGVyICE9IG51bGwpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIEZpbGVTeXN0ZW0gZnMgPSBjbHVzdGVyLmdldEZpbGVTeXN0ZW0oKTsKKyAgICAgICAgaWYgKGZzICE9IG51bGwpIHsKKyAgICAgICAgICBMT0cuaW5mbygiU2h1dHRpbmcgZG93biBGaWxlU3lzdGVtIik7CisgICAgICAgICAgZnMuY2xvc2UoKTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuZXJyb3IoImVycm9yIGNsb3NpbmcgZmlsZSBzeXN0ZW0iLCBlKTsKKyAgICAgIH0KKworICAgICAgTE9HLmluZm8oIlNodXR0aW5nIGRvd24gTWluaSBERlMgIik7CisgICAgICB0cnkgeworICAgICAgICBjbHVzdGVyLnNodXRkb3duKCk7CisgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAvLy8gQ2FuIGdldCBhIGphdmEubGFuZy5yZWZsZWN0LlVuZGVjbGFyZWRUaHJvd2FibGVFeGNlcHRpb24gdGhyb3duCisgICAgICAgIC8vIGhlcmUgYmVjYXVzZSBvZiBhbiBJbnRlcnJ1cHRlZEV4Y2VwdGlvbi4gRG9uJ3QgbGV0IGV4Y2VwdGlvbnMgaW4KKyAgICAgICAgLy8gaGVyZSBiZSBjYXVzZSBvZiB0ZXN0IGZhaWx1cmUuCisgICAgICB9CisgICAgfQorICB9CisgIAorICBwcm90ZWN0ZWQgdm9pZCBjcmVhdGVSb290QW5kTWV0YVJlZ2lvbnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJvb3QgPSBIUmVnaW9uLmNyZWF0ZUhSZWdpb24oSFJlZ2lvbkluZm8uUk9PVF9SRUdJT05JTkZPLCB0ZXN0RGlyLCBjb25mKTsKKyAgICBtZXRhID0gSFJlZ2lvbi5jcmVhdGVIUmVnaW9uKEhSZWdpb25JbmZvLkZJUlNUX01FVEFfUkVHSU9OSU5GTywgdGVzdERpciwgCisgICAgICAgIGNvbmYpOworICAgIEhSZWdpb24uYWRkUmVnaW9uVG9NRVRBKHJvb3QsIG1ldGEpOworICB9CisgIAorICBwcm90ZWN0ZWQgdm9pZCBjbG9zZVJvb3RBbmRNZXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAobWV0YSAhPSBudWxsKSB7CisgICAgICBtZXRhLmNsb3NlKCk7CisgICAgICBtZXRhLmdldExvZygpLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgfQorICAgIGlmIChyb290ICE9IG51bGwpIHsKKyAgICAgIHJvb3QuY2xvc2UoKTsKKyAgICAgIHJvb3QuZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL0hGaWxlUGVyZm9ybWFuY2VFdmFsdWF0aW9uLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0YWZiMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9IRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzY1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5tYXRoLnJhbmRvbS5SYW5kb21EYXRhOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5tYXRoLnJhbmRvbS5SYW5kb21EYXRhSW1wbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5jb25mLkNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGVTY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogPHA+CisgKiBUaGlzIGNsYXNzIHJ1bnMgcGVyZm9ybWFuY2UgYmVuY2htYXJrcyBmb3Ige0BsaW5rIEhGaWxlfS4KKyAqIDwvcD4KKyAqLworcHVibGljIGNsYXNzIEhGaWxlUGVyZm9ybWFuY2VFdmFsdWF0aW9uIHsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBST1dfTEVOR1RIID0gMTA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBST1dfQ09VTlQgPSAxMDAwMDAwOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUkZJTEVfQkxPQ0tTSVpFID0gOCAqIDEwMjQ7CisgIAorICBzdGF0aWMgZmluYWwgTG9nIExPRyA9CisgICAgTG9nRmFjdG9yeS5nZXRMb2coSEZpbGVQZXJmb3JtYW5jZUV2YWx1YXRpb24uY2xhc3MuZ2V0TmFtZSgpKTsKKyAgCisgIHN0YXRpYyBieXRlIFtdIGZvcm1hdChmaW5hbCBpbnQgaSkgeworICAgIFN0cmluZyB2ID0gSW50ZWdlci50b1N0cmluZyhpKTsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcygiMDAwMDAwMDAwMCIuc3Vic3RyaW5nKHYubGVuZ3RoKCkpICsgdik7CisgIH0KKworICBzdGF0aWMgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBmb3JtYXQoZmluYWwgaW50IGksIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgdykgeworICAgIHcuc2V0KGZvcm1hdChpKSk7CisgICAgcmV0dXJuIHc7CisgIH0KKworICBwcml2YXRlIHZvaWQgcnVuQmVuY2htYXJrcygpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbmFsIENvbmZpZ3VyYXRpb24gY29uZiA9IG5ldyBDb25maWd1cmF0aW9uKCk7CisgICAgZmluYWwgRmlsZVN5c3RlbSBmcyA9IEZpbGVTeXN0ZW0uZ2V0KGNvbmYpOworICAgIGZpbmFsIFBhdGggbWYgPSBmcy5tYWtlUXVhbGlmaWVkKG5ldyBQYXRoKCJwZXJmb3JtYW5jZWV2YWx1YXRpb24ubWFwZmlsZSIpKTsKKyAgICBpZiAoZnMuZXhpc3RzKG1mKSkgeworICAgICAgZnMuZGVsZXRlKG1mLCB0cnVlKTsKKyAgICB9CisKKyAgICBydW5CZW5jaG1hcmsobmV3IFNlcXVlbnRpYWxXcml0ZUJlbmNobWFyayhjb25mLCBmcywgbWYsIFJPV19DT1VOVCksCisgICAgICAgIFJPV19DT1VOVCk7CisgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5jb25jdXJyZW50UmVhZHMobmV3IFJ1bm5hYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJ1bkJlbmNobWFyayhuZXcgVW5pZm9ybVJhbmRvbVNtYWxsU2Nhbihjb25mLCBmcywgbWYsIFJPV19DT1VOVCksCisgICAgICAgICAgICBST1dfQ09VTlQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9KTsKKyAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmNvbmN1cnJlbnRSZWFkcyhuZXcgUnVubmFibGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcnVuQmVuY2htYXJrKG5ldyBVbmlmb3JtUmFuZG9tUmVhZEJlbmNobWFyayhjb25mLCBmcywgbWYsIFJPV19DT1VOVCksCisgICAgICAgICAgICAgIFJPV19DT1VOVCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0pOworICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuY29uY3VycmVudFJlYWRzKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBydW5CZW5jaG1hcmsobmV3IEdhdXNzaWFuUmFuZG9tUmVhZEJlbmNobWFyayhjb25mLCBmcywgbWYsIFJPV19DT1VOVCksCisgICAgICAgICAgICAgIFJPV19DT1VOVCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0pOworICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuY29uY3VycmVudFJlYWRzKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBydW5CZW5jaG1hcmsobmV3IFNlcXVlbnRpYWxSZWFkQmVuY2htYXJrKGNvbmYsIGZzLCBtZiwgUk9XX0NPVU5UKSwKKyAgICAgICAgICAgICAgUk9XX0NPVU5UKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICB9CisgICAgfSk7CisgICAgCisgIH0KKyAgCisgIHByb3RlY3RlZCB2b2lkIHJ1bkJlbmNobWFyayhSb3dPcmllbnRlZEJlbmNobWFyayBiZW5jaG1hcmssIGludCByb3dDb3VudCkKKyAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBMT0cuaW5mbygiUnVubmluZyAiICsgYmVuY2htYXJrLmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpICsgIiBmb3IgIiArCisgICAgICAgIHJvd0NvdW50ICsgIiByb3dzLiIpOworICAgIGxvbmcgZWxhcHNlZFRpbWUgPSBiZW5jaG1hcmsucnVuKCk7CisgICAgTE9HLmluZm8oIlJ1bm5pbmcgIiArIGJlbmNobWFyay5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSArICIgZm9yICIgKworICAgICAgICByb3dDb3VudCArICIgcm93cyB0b29rICIgKyBlbGFwc2VkVGltZSArICJtcy4iKTsKKyAgfQorICAKKyAgc3RhdGljIGFic3RyYWN0IGNsYXNzIFJvd09yaWVudGVkQmVuY2htYXJrIHsKKyAgICAKKyAgICBwcm90ZWN0ZWQgZmluYWwgQ29uZmlndXJhdGlvbiBjb25mOworICAgIHByb3RlY3RlZCBmaW5hbCBGaWxlU3lzdGVtIGZzOworICAgIHByb3RlY3RlZCBmaW5hbCBQYXRoIG1mOworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgdG90YWxSb3dzOworICAgIAorICAgIHB1YmxpYyBSb3dPcmllbnRlZEJlbmNobWFyayhDb25maWd1cmF0aW9uIGNvbmYsIEZpbGVTeXN0ZW0gZnMsIFBhdGggbWYsCisgICAgICAgIGludCB0b3RhbFJvd3MpIHsKKyAgICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgICB0aGlzLmZzID0gZnM7CisgICAgICB0aGlzLm1mID0gbWY7CisgICAgICB0aGlzLnRvdGFsUm93cyA9IHRvdGFsUm93czsKKyAgICB9CisgICAgCisgICAgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgLy8gZG8gbm90aGluZworICAgIH0KKyAgICAKKyAgICBhYnN0cmFjdCB2b2lkIGRvUm93KGludCBpKSB0aHJvd3MgRXhjZXB0aW9uOworICAgIAorICAgIHByb3RlY3RlZCBpbnQgZ2V0UmVwb3J0aW5nUGVyaW9kKCkgeworICAgICAgcmV0dXJuIHRoaXMudG90YWxSb3dzIC8gMTA7CisgICAgfQorICAgIAorICAgIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIC8vIGRvIG5vdGhpbmcKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogUnVuIGJlbmNobWFyaworICAgICAqIEByZXR1cm4gZWxhcHNlZCB0aW1lLgorICAgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAgICovCisgICAgbG9uZyBydW4oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIGxvbmcgZWxhcHNlZFRpbWU7CisgICAgICBzZXRVcCgpOworICAgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdG90YWxSb3dzOyBpKyspIHsKKyAgICAgICAgICBpZiAoaSA+IDAgJiYgaSAlIGdldFJlcG9ydGluZ1BlcmlvZCgpID09IDApIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJQcm9jZXNzZWQgIiArIGkgKyAiIHJvd3MuIik7CisgICAgICAgICAgfQorICAgICAgICAgIGRvUm93KGkpOworICAgICAgICB9CisgICAgICAgIGVsYXBzZWRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWU7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICB0ZWFyRG93bigpOworICAgICAgfQorICAgICAgcmV0dXJuIGVsYXBzZWRUaW1lOworICAgIH0KKyAgICAKKyAgfQorICAKKyAgc3RhdGljIGNsYXNzIFNlcXVlbnRpYWxXcml0ZUJlbmNobWFyayBleHRlbmRzIFJvd09yaWVudGVkQmVuY2htYXJrIHsKKyAgICBwcm90ZWN0ZWQgSEZpbGUuV3JpdGVyIHdyaXRlcjsKKyAgICBwcml2YXRlIFJhbmRvbSByYW5kb20gPSBuZXcgUmFuZG9tKCk7CisgICAgcHJpdmF0ZSBieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtST1dfTEVOR1RIXTsKKyAgICAKKyAgICBwdWJsaWMgU2VxdWVudGlhbFdyaXRlQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgUGF0aCBtZiwKKyAgICAgICAgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICB3cml0ZXIgPSBuZXcgSEZpbGUuV3JpdGVyKHRoaXMuZnMsIHRoaXMubWYsIFJGSUxFX0JMT0NLU0laRSwgbnVsbCwgbnVsbCk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgd3JpdGVyLmFwcGVuZChmb3JtYXQoaSksIGdlbmVyYXRlVmFsdWUoKSk7IAorICAgIH0KKyAgICAKKyAgICBwcml2YXRlIGJ5dGVbXSBnZW5lcmF0ZVZhbHVlKCkgeworICAgICAgcmFuZG9tLm5leHRCeXRlcyhieXRlcyk7CisgICAgICByZXR1cm4gYnl0ZXM7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZ2V0UmVwb3J0aW5nUGVyaW9kKCkgeworICAgICAgcmV0dXJuIHRoaXMudG90YWxSb3dzOyAvLyBkb24ndCByZXBvcnQgcHJvZ3Jlc3MKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgfQorICAgIAorICB9CisgIAorICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgUmVhZEJlbmNobWFyayBleHRlbmRzIFJvd09yaWVudGVkQmVuY2htYXJrIHsKKyAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKCk7CisgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSB2YWx1ZSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKCk7CisgICAgCisgICAgcHJvdGVjdGVkIEhGaWxlLlJlYWRlciByZWFkZXI7CisgICAgCisgICAgcHVibGljIFJlYWRCZW5jaG1hcmsoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBQYXRoIG1mLAorICAgICAgICBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHJlYWRlciA9IG5ldyBIRmlsZS5SZWFkZXIodGhpcy5mcywgdGhpcy5tZiwgbnVsbCk7CisgICAgICB0aGlzLnJlYWRlci5sb2FkRmlsZUluZm8oKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgcmVhZGVyLmNsb3NlKCk7CisgICAgfQorICAgIAorICB9CisKKyAgc3RhdGljIGNsYXNzIFNlcXVlbnRpYWxSZWFkQmVuY2htYXJrIGV4dGVuZHMgUmVhZEJlbmNobWFyayB7CisgICAgcHJpdmF0ZSBIRmlsZVNjYW5uZXIgc2Nhbm5lcjsKKyAgICAKKyAgICBwdWJsaWMgU2VxdWVudGlhbFJlYWRCZW5jaG1hcmsoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgUGF0aCBtZiwgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICBzdXBlci5zZXRVcCgpOworICAgICAgdGhpcy5zY2FubmVyID0gdGhpcy5yZWFkZXIuZ2V0U2Nhbm5lcigpOworICAgICAgdGhpcy5zY2FubmVyLnNlZWtUbygpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgaWYgKHRoaXMuc2Nhbm5lci5uZXh0KCkpIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBrID0gdGhpcy5zY2FubmVyLmdldEtleSgpOworICAgICAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmFzc2VydEtleShmb3JtYXQoaSArIDEpLCBrKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciB2ID0gc2Nhbm5lci5nZXRWYWx1ZSgpOworICAgICAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmFzc2VydFZhbHVlU2l6ZSh2LmxpbWl0KCksIFJPV19MRU5HVEgpOworICAgICAgfQorICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGdldFJlcG9ydGluZ1BlcmlvZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRvdGFsUm93czsgLy8gZG9uJ3QgcmVwb3J0IHByb2dyZXNzCisgICAgfQorICAgIAorICB9CisgIAorICBzdGF0aWMgY2xhc3MgVW5pZm9ybVJhbmRvbVJlYWRCZW5jaG1hcmsgZXh0ZW5kcyBSZWFkQmVuY2htYXJrIHsKKyAgICAKKyAgICBwcml2YXRlIFJhbmRvbSByYW5kb20gPSBuZXcgUmFuZG9tKCk7CisKKyAgICBwdWJsaWMgVW5pZm9ybVJhbmRvbVJlYWRCZW5jaG1hcmsoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgICBQYXRoIG1mLCBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCBkb1JvdyhpbnQgaSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICBIRmlsZVNjYW5uZXIgc2Nhbm5lciA9IHRoaXMucmVhZGVyLmdldFNjYW5uZXIoKTsKKyAgICAgIGJ5dGUgW10gYiA9IGdldFJhbmRvbVJvdygpOworICAgICAgc2Nhbm5lci5zZWVrVG8oYik7CisgICAgICBCeXRlQnVmZmVyIGsgPSBzY2FubmVyLmdldEtleSgpOworICAgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5hc3NlcnRLZXkoYiwgayk7CisgICAgICBCeXRlQnVmZmVyIHYgPSBzY2FubmVyLmdldFZhbHVlKCk7CisgICAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmFzc2VydFZhbHVlU2l6ZSh2LmxpbWl0KCksIFJPV19MRU5HVEgpOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIGJ5dGUgW10gZ2V0UmFuZG9tUm93KCkgeworICAgICAgcmV0dXJuIGZvcm1hdChyYW5kb20ubmV4dEludCh0b3RhbFJvd3MpKTsKKyAgICB9CisgIH0KKyAgCisgIHN0YXRpYyBjbGFzcyBVbmlmb3JtUmFuZG9tU21hbGxTY2FuIGV4dGVuZHMgUmVhZEJlbmNobWFyayB7CisgICAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgICAgcHVibGljIFVuaWZvcm1SYW5kb21TbWFsbFNjYW4oQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgICBQYXRoIG1mLCBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cy8xMCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCBkb1JvdyhpbnQgaSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICBIRmlsZVNjYW5uZXIgc2Nhbm5lciA9IHRoaXMucmVhZGVyLmdldFNjYW5uZXIoKTsKKyAgICAgIGJ5dGUgW10gYiA9IGdldFJhbmRvbVJvdygpOworICAgICAgaWYgKHNjYW5uZXIuc2Vla1RvKGIpICE9IDApIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJOb25leGlzdGVudCByb3c6ICIgKyBuZXcgU3RyaW5nKGIpKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgQnl0ZUJ1ZmZlciBrID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuYXNzZXJ0S2V5KGIsIGspOworICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJGb3VuZCByb3c6ICIgKyBuZXcgU3RyaW5nKGIpKTsKKyAgICAgIGZvciAoaW50IGlpID0gMDsgaWkgPCAzMDsgaWkrKykgeworICAgICAgICBpZiAoIXNjYW5uZXIubmV4dCgpKSB7CisgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJOT1RISU5HIEZPTExPV1MiKTsKKyAgICAgICAgfQorICAgICAgICBCeXRlQnVmZmVyIHYgPSBzY2FubmVyLmdldFZhbHVlKCk7CisgICAgICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuYXNzZXJ0VmFsdWVTaXplKHYubGltaXQoKSwgUk9XX0xFTkdUSCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHByaXZhdGUgYnl0ZSBbXSBnZXRSYW5kb21Sb3coKSB7CisgICAgICByZXR1cm4gZm9ybWF0KHJhbmRvbS5uZXh0SW50KHRvdGFsUm93cykpOworICAgIH0KKyAgfQorICAKKyAgc3RhdGljIGNsYXNzIEdhdXNzaWFuUmFuZG9tUmVhZEJlbmNobWFyayBleHRlbmRzIFJlYWRCZW5jaG1hcmsgeworICAgIAorICAgIHByaXZhdGUgUmFuZG9tRGF0YSByYW5kb21EYXRhID0gbmV3IFJhbmRvbURhdGFJbXBsKCk7CisKKyAgICBwdWJsaWMgR2F1c3NpYW5SYW5kb21SZWFkQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywKKyAgICAgICAgUGF0aCBtZiwgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSB0aGlzLnJlYWRlci5nZXRTY2FubmVyKCk7CisgICAgICBzY2FubmVyLnNlZWtUbyhnZXRHYXVzc2lhblJhbmRvbVJvd0J5dGVzKCkpOworICAgICAgZm9yIChpbnQgaWkgPSAwOyBpaSA8IDMwOyBpaSsrKSB7CisgICAgICAgIGlmICghc2Nhbm5lci5uZXh0KCkpIHsKKyAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5PVEhJTkcgRk9MTE9XUyIpOworICAgICAgICB9CisgICAgICAgIHNjYW5uZXIuZ2V0S2V5KCk7CisgICAgICAgIHNjYW5uZXIuZ2V0VmFsdWUoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcml2YXRlIGJ5dGUgW10gZ2V0R2F1c3NpYW5SYW5kb21Sb3dCeXRlcygpIHsKKyAgICAgIGludCByID0gKGludCkgcmFuZG9tRGF0YS5uZXh0R2F1c3NpYW4odG90YWxSb3dzIC8gMiwgdG90YWxSb3dzIC8gMTApOworICAgICAgcmV0dXJuIGZvcm1hdChyKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBAcGFyYW0gYXJncworICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24geworICAgIG5ldyBIRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbigpLnJ1bkJlbmNobWFya3MoKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01hcEZpbGVQZXJmb3JtYW5jZUV2YWx1YXRpb24uamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01hcEZpbGVQZXJmb3JtYW5jZUV2YWx1YXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YzgwYzZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvTWFwRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzQ4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubWF0aC5yYW5kb20uUmFuZG9tRGF0YTsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubWF0aC5yYW5kb20uUmFuZG9tRGF0YUltcGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuY29uZi5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5JbW11dGFibGVCeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLk1hcEZpbGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZUNvbXBhcmFibGU7CisKKy8qKgorICogPHA+CisgKiBUaGlzIGNsYXNzIHJ1bnMgcGVyZm9ybWFuY2UgYmVuY2htYXJrcyBmb3Ige0BsaW5rIE1hcEZpbGV9LgorICogPC9wPgorICovCitwdWJsaWMgY2xhc3MgTWFwRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbiB7CisgIHByb3RlY3RlZCBmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJPV19MRU5HVEggPSAxMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJPV19DT1VOVCA9IDEwMDAwMDsKKyAgCisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0KKyAgICBMb2dGYWN0b3J5LmdldExvZyhNYXBGaWxlUGVyZm9ybWFuY2VFdmFsdWF0aW9uLmNsYXNzLmdldE5hbWUoKSk7CisKKyAgLyoqCisgICAqIEBwYXJhbSBjCisgICAqLworICBwdWJsaWMgTWFwRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbihmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gYykgeworICAgIHN1cGVyKCk7CisgICAgdGhpcy5jb25mID0gYzsKKyAgfQorICAKKyAgc3RhdGljIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgZm9ybWF0KGZpbmFsIGludCBpLCBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHcpIHsKKyAgICBTdHJpbmcgdiA9IEludGVnZXIudG9TdHJpbmcoaSk7CisgICAgdy5zZXQoQnl0ZXMudG9CeXRlcygiMDAwMDAwMDAwMCIuc3Vic3RyaW5nKHYubGVuZ3RoKCkpICsgdikpOworICAgIHJldHVybiB3OworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJ1bkJlbmNobWFya3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBGaWxlU3lzdGVtIGZzID0gRmlsZVN5c3RlbS5nZXQodGhpcy5jb25mKTsKKyAgICBmaW5hbCBQYXRoIG1mID0gZnMubWFrZVF1YWxpZmllZChuZXcgUGF0aCgicGVyZm9ybWFuY2VldmFsdWF0aW9uLm1hcGZpbGUiKSk7CisgICAgaWYgKGZzLmV4aXN0cyhtZikpIHsKKyAgICAgIGZzLmRlbGV0ZShtZiwgdHJ1ZSk7CisgICAgfQorICAgIHJ1bkJlbmNobWFyayhuZXcgU2VxdWVudGlhbFdyaXRlQmVuY2htYXJrKGNvbmYsIGZzLCBtZiwgUk9XX0NPVU5UKSwKKyAgICAgICAgUk9XX0NPVU5UKTsKKyAgICAKKyAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmNvbmN1cnJlbnRSZWFkcyhuZXcgUnVubmFibGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcnVuQmVuY2htYXJrKG5ldyBVbmlmb3JtUmFuZG9tU21hbGxTY2FuKGNvbmYsIGZzLCBtZiwgUk9XX0NPVU5UKSwKKyAgICAgICAgICAgIFJPV19DT1VOVCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0pOworICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuY29uY3VycmVudFJlYWRzKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBydW5CZW5jaG1hcmsobmV3IFVuaWZvcm1SYW5kb21SZWFkQmVuY2htYXJrKGNvbmYsIGZzLCBtZiwgUk9XX0NPVU5UKSwKKyAgICAgICAgICAgICAgUk9XX0NPVU5UKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICB9CisgICAgfSk7CisgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5jb25jdXJyZW50UmVhZHMobmV3IFJ1bm5hYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJ1bkJlbmNobWFyayhuZXcgR2F1c3NpYW5SYW5kb21SZWFkQmVuY2htYXJrKGNvbmYsIGZzLCBtZiwgUk9XX0NPVU5UKSwKKyAgICAgICAgICAgICAgUk9XX0NPVU5UKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICB9CisgICAgfSk7CisgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5jb25jdXJyZW50UmVhZHMobmV3IFJ1bm5hYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJ1bkJlbmNobWFyayhuZXcgU2VxdWVudGlhbFJlYWRCZW5jaG1hcmsoY29uZiwgZnMsIG1mLCBST1dfQ09VTlQpLAorICAgICAgICAgICAgICBST1dfQ09VTlQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9KTsKKyAgfQorICAKKyAgcHJvdGVjdGVkIHZvaWQgcnVuQmVuY2htYXJrKFJvd09yaWVudGVkQmVuY2htYXJrIGJlbmNobWFyaywgaW50IHJvd0NvdW50KQorICAgIHRocm93cyBFeGNlcHRpb24geworICAgIExPRy5pbmZvKCJSdW5uaW5nICIgKyBiZW5jaG1hcmsuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkgKyAiIGZvciAiICsKKyAgICAgICAgcm93Q291bnQgKyAiIHJvd3MuIik7CisgICAgbG9uZyBlbGFwc2VkVGltZSA9IGJlbmNobWFyay5ydW4oKTsKKyAgICBMT0cuaW5mbygiUnVubmluZyAiICsgYmVuY2htYXJrLmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpICsgIiBmb3IgIiArCisgICAgICAgIHJvd0NvdW50ICsgIiByb3dzIHRvb2sgIiArIGVsYXBzZWRUaW1lICsgIm1zLiIpOworICB9CisgIAorICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgUm93T3JpZW50ZWRCZW5jaG1hcmsgeworICAgIAorICAgIHByb3RlY3RlZCBmaW5hbCBDb25maWd1cmF0aW9uIGNvbmY7CisgICAgcHJvdGVjdGVkIGZpbmFsIEZpbGVTeXN0ZW0gZnM7CisgICAgcHJvdGVjdGVkIGZpbmFsIFBhdGggbWY7CisgICAgcHJvdGVjdGVkIGZpbmFsIGludCB0b3RhbFJvd3M7CisgICAgCisgICAgcHVibGljIFJvd09yaWVudGVkQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgUGF0aCBtZiwKKyAgICAgICAgaW50IHRvdGFsUm93cykgeworICAgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICAgIHRoaXMuZnMgPSBmczsKKyAgICAgIHRoaXMubWYgPSBtZjsKKyAgICAgIHRoaXMudG90YWxSb3dzID0gdG90YWxSb3dzOworICAgIH0KKyAgICAKKyAgICB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAvLyBkbyBub3RoaW5nCisgICAgfQorICAgIAorICAgIGFic3RyYWN0IHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb247CisgICAgCisgICAgcHJvdGVjdGVkIGludCBnZXRSZXBvcnRpbmdQZXJpb2QoKSB7CisgICAgICByZXR1cm4gdGhpcy50b3RhbFJvd3MgLyAxMDsKKyAgICB9CisgICAgCisgICAgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgLy8gZG8gbm90aGluZworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBSdW4gYmVuY2htYXJrCisgICAgICogQHJldHVybiBlbGFwc2VkIHRpbWUuCisgICAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICAgKi8KKyAgICBsb25nIHJ1bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgbG9uZyBlbGFwc2VkVGltZTsKKyAgICAgIHNldFVwKCk7CisgICAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgdHJ5IHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbFJvd3M7IGkrKykgeworICAgICAgICAgIGlmIChpID4gMCAmJiBpICUgZ2V0UmVwb3J0aW5nUGVyaW9kKCkgPT0gMCkgeworICAgICAgICAgICAgTE9HLmluZm8oIlByb2Nlc3NlZCAiICsgaSArICIgcm93cy4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgZG9Sb3coaSk7CisgICAgICAgIH0KKyAgICAgICAgZWxhcHNlZFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHRlYXJEb3duKCk7CisgICAgICB9CisgICAgICByZXR1cm4gZWxhcHNlZFRpbWU7CisgICAgfQorICAgIAorICB9CisgIAorICBzdGF0aWMgY2xhc3MgU2VxdWVudGlhbFdyaXRlQmVuY2htYXJrIGV4dGVuZHMgUm93T3JpZW50ZWRCZW5jaG1hcmsgeworICAgIAorICAgIHByb3RlY3RlZCBNYXBGaWxlLldyaXRlciB3cml0ZXI7CisgICAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworICAgIHByaXZhdGUgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbUk9XX0xFTkdUSF07CisgICAgcHJpdmF0ZSBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSA9IG5ldyBJbW11dGFibGVCeXRlc1dyaXRhYmxlKCk7CisgICAgcHJpdmF0ZSBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHZhbHVlID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICAKKyAgICBwdWJsaWMgU2VxdWVudGlhbFdyaXRlQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywgUGF0aCBtZiwKKyAgICAgICAgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICB3cml0ZXIgPSBuZXcgTWFwRmlsZS5Xcml0ZXIoY29uZiwgZnMsIG1mLnRvU3RyaW5nKCksCisgICAgICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MsIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUuY2xhc3MpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIGRvUm93KGludCBpKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHZhbHVlLnNldChnZW5lcmF0ZVZhbHVlKCkpOworICAgICAgd3JpdGVyLmFwcGVuZChmb3JtYXQoaSwga2V5KSwgdmFsdWUpOyAKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBieXRlW10gZ2VuZXJhdGVWYWx1ZSgpIHsKKyAgICAgIHJhbmRvbS5uZXh0Qnl0ZXMoYnl0ZXMpOworICAgICAgcmV0dXJuIGJ5dGVzOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGdldFJlcG9ydGluZ1BlcmlvZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnRvdGFsUm93czsgLy8gZG9uJ3QgcmVwb3J0IHByb2dyZXNzCisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHdyaXRlci5jbG9zZSgpOworICAgIH0KKyAgICAKKyAgfQorICAKKyAgc3RhdGljIGFic3RyYWN0IGNsYXNzIFJlYWRCZW5jaG1hcmsgZXh0ZW5kcyBSb3dPcmllbnRlZEJlbmNobWFyayB7CisgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrZXkgPSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSgpOworICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgdmFsdWUgPSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSgpOworICAgIAorICAgIHByb3RlY3RlZCBNYXBGaWxlLlJlYWRlciByZWFkZXI7CisgICAgCisgICAgcHVibGljIFJlYWRCZW5jaG1hcmsoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLCBQYXRoIG1mLAorICAgICAgICBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHJlYWRlciA9IG5ldyBNYXBGaWxlLlJlYWRlcihmcywgbWYudG9TdHJpbmcoKSwgY29uZik7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHJlYWRlci5jbG9zZSgpOworICAgIH0KKyAgICAKKyAgfQorCisgIHN0YXRpYyBjbGFzcyBTZXF1ZW50aWFsUmVhZEJlbmNobWFyayBleHRlbmRzIFJlYWRCZW5jaG1hcmsgeworICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgdmVyaWZ5ID0gbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUoKTsKKyAgICAKKyAgICBwdWJsaWMgU2VxdWVudGlhbFJlYWRCZW5jaG1hcmsoQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgICBQYXRoIG1mLCBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCBkb1JvdyhpbnQgaSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICB0aGlzLnJlYWRlci5uZXh0KGtleSwgdmFsdWUpOworICAgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5hc3NlcnRLZXkodGhpcy5rZXkuZ2V0KCksCisgICAgICAgIGZvcm1hdChpLCB0aGlzLnZlcmlmeSkuZ2V0KCkpOworICAgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5hc3NlcnRWYWx1ZVNpemUoUk9XX0xFTkdUSCwgdmFsdWUuZ2V0U2l6ZSgpKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIGludCBnZXRSZXBvcnRpbmdQZXJpb2QoKSB7CisgICAgICByZXR1cm4gdGhpcy50b3RhbFJvd3M7IC8vIGRvbid0IHJlcG9ydCBwcm9ncmVzcworICAgIH0KKyAgICAKKyAgfQorICAKKyAgc3RhdGljIGNsYXNzIFVuaWZvcm1SYW5kb21SZWFkQmVuY2htYXJrIGV4dGVuZHMgUmVhZEJlbmNobWFyayB7CisgICAgCisgICAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgICAgcHVibGljIFVuaWZvcm1SYW5kb21SZWFkQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywKKyAgICAgICAgUGF0aCBtZiwgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrID0gZ2V0UmFuZG9tUm93KCk7CisgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIHIgPSAoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSlyZWFkZXIuZ2V0KGssIHZhbHVlKTsKKyAgICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuYXNzZXJ0VmFsdWVTaXplKHIuZ2V0U2l6ZSgpLCBST1dfTEVOR1RIKTsKKyAgICB9CisgICAgCisgICAgcHJpdmF0ZSBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGdldFJhbmRvbVJvdygpIHsKKyAgICAgIHJldHVybiBmb3JtYXQocmFuZG9tLm5leHRJbnQodG90YWxSb3dzKSwga2V5KTsKKyAgICB9CisgICAgCisgIH0KKyAgCisgIHN0YXRpYyBjbGFzcyBVbmlmb3JtUmFuZG9tU21hbGxTY2FuIGV4dGVuZHMgUmVhZEJlbmNobWFyayB7CisgICAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgICAgcHVibGljIFVuaWZvcm1SYW5kb21TbWFsbFNjYW4oQ29uZmlndXJhdGlvbiBjb25mLCBGaWxlU3lzdGVtIGZzLAorICAgICAgICBQYXRoIG1mLCBpbnQgdG90YWxSb3dzKSB7CisgICAgICBzdXBlcihjb25mLCBmcywgbWYsIHRvdGFsUm93cy8xMCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCBkb1JvdyhpbnQgaSkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlIGlidyA9IGdldFJhbmRvbVJvdygpOworICAgICAgV3JpdGFibGVDb21wYXJhYmxlPD8+IHdjID0gdGhpcy5yZWFkZXIuZ2V0Q2xvc2VzdChpYncsIHRoaXMudmFsdWUpOworICAgICAgaWYgKHdjID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgICB9CisgICAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmFzc2VydEtleShpYncuZ2V0KCksCisgICAgICAgICgoSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSl3YykuZ2V0KCkpOworICAgICAgLy8gVE9ETzogVmVyaWZ5IHdlJ3JlIGdldHRpbmcgcmlnaHQgdmFsdWVzLgorICAgICAgZm9yIChpbnQgaWkgPSAwOyBpaSA8IDI5OyBpaSsrKSB7CisgICAgICAgIHRoaXMucmVhZGVyLm5leHQodGhpcy5rZXksIHRoaXMudmFsdWUpOworICAgICAgICBQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmFzc2VydFZhbHVlU2l6ZSh0aGlzLnZhbHVlLmdldFNpemUoKSwgUk9XX0xFTkdUSCk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIHByaXZhdGUgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBnZXRSYW5kb21Sb3coKSB7CisgICAgICByZXR1cm4gZm9ybWF0KHJhbmRvbS5uZXh0SW50KHRvdGFsUm93cyksIGtleSk7CisgICAgfQorICB9CisKKyAgc3RhdGljIGNsYXNzIEdhdXNzaWFuUmFuZG9tUmVhZEJlbmNobWFyayBleHRlbmRzIFJlYWRCZW5jaG1hcmsgeworICAgIHByaXZhdGUgUmFuZG9tRGF0YSByYW5kb21EYXRhID0gbmV3IFJhbmRvbURhdGFJbXBsKCk7CisKKyAgICBwdWJsaWMgR2F1c3NpYW5SYW5kb21SZWFkQmVuY2htYXJrKENvbmZpZ3VyYXRpb24gY29uZiwgRmlsZVN5c3RlbSBmcywKKyAgICAgICAgUGF0aCBtZiwgaW50IHRvdGFsUm93cykgeworICAgICAgc3VwZXIoY29uZiwgZnMsIG1mLCB0b3RhbFJvd3MpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHZvaWQgZG9Sb3coaW50IGkpIHRocm93cyBFeGNlcHRpb24geworICAgICAgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZSBrID0gZ2V0R2F1c3NpYW5SYW5kb21Sb3coKTsKKyAgICAgIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgciA9IChJbW11dGFibGVCeXRlc1dyaXRhYmxlKXJlYWRlci5nZXQoaywgdmFsdWUpOworICAgICAgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucy5hc3NlcnRWYWx1ZVNpemUoci5nZXRTaXplKCksIFJPV19MRU5HVEgpOworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIEltbXV0YWJsZUJ5dGVzV3JpdGFibGUgZ2V0R2F1c3NpYW5SYW5kb21Sb3coKSB7CisgICAgICBpbnQgciA9IChpbnQpIHJhbmRvbURhdGEubmV4dEdhdXNzaWFuKHRvdGFsUm93cyAvIDIsIHRvdGFsUm93cyAvIDEwKTsKKyAgICAgIHJldHVybiBmb3JtYXQociwga2V5KTsKKyAgICB9CisgICAgCisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGFyZ3MKKyAgICogQHRocm93cyBFeGNlcHRpb24gCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBuZXcgTWFwRmlsZVBlcmZvcm1hbmNlRXZhbHVhdGlvbihuZXcgSEJhc2VDb25maWd1cmF0aW9uKCkpLgorICAgICAgcnVuQmVuY2htYXJrcygpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9NaW5pSEJhc2VDbHVzdGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9NaW5pSEJhc2VDbHVzdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGNjYjZhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01pbmlIQmFzZUNsdXN0ZXIuamF2YQpAQCAtMCwwICsxLDIwNSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5CaW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXIuSE1hc3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvblNlcnZlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKKworLyoqCisgKiBUaGlzIGNsYXNzIGNyZWF0ZXMgYSBzaW5nbGUgcHJvY2VzcyBIQmFzZSBjbHVzdGVyLiBPbmUgdGhyZWFkIGlzIGNyZWF0ZWQgZm9yCisgKiBlYWNoIHNlcnZlci4KKyAqLworcHVibGljIGNsYXNzIE1pbmlIQmFzZUNsdXN0ZXIgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhNaW5pSEJhc2VDbHVzdGVyLmNsYXNzLmdldE5hbWUoKSk7CisgIAorICBwcml2YXRlIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mOworICBwcml2YXRlIExvY2FsSEJhc2VDbHVzdGVyIGhiYXNlQ2x1c3RlcjsKKworICAvKioKKyAgICogU3RhcnQgYSBNaW5pSEJhc2VDbHVzdGVyLiAKKyAgICogQHBhcmFtIGNvbmYgSEJhc2VDb25maWd1cmF0aW9uIHRvIGJlIHVzZWQgZm9yIGNsdXN0ZXIKKyAgICogQHBhcmFtIG51bVJlZ2lvblNlcnZlcnMgaW5pdGlhbCBudW1iZXIgb2YgcmVnaW9uIHNlcnZlcnMgdG8gc3RhcnQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBNaW5pSEJhc2VDbHVzdGVyKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBpbnQgbnVtUmVnaW9uU2VydmVycykgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhpcy5jb25mID0gY29uZjsKKyAgICBpbml0KG51bVJlZ2lvblNlcnZlcnMpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGluaXQoZmluYWwgaW50IG5SZWdpb25Ob2RlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgLy8gc3RhcnQgdXAgYSBMb2NhbEhCYXNlQ2x1c3RlcgorICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBoYmFzZUNsdXN0ZXIgPSBuZXcgTG9jYWxIQmFzZUNsdXN0ZXIoY29uZiwgblJlZ2lvbk5vZGVzKTsKKyAgICAgICAgICBoYmFzZUNsdXN0ZXIuc3RhcnR1cCgpOworICAgICAgICB9IGNhdGNoIChCaW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvL3RoaXMgcG9ydCBpcyBhbHJlYWR5IGluIHVzZS4gdHJ5IHRvIHVzZSBhbm90aGVyIChmb3IgbXVsdGlwbGUgdGVzdGluZykKKyAgICAgICAgICBpbnQgcG9ydCA9IGNvbmYuZ2V0SW50KCJoYmFzZS5tYXN0ZXIucG9ydCIsIERFRkFVTFRfTUFTVEVSX1BPUlQpOworICAgICAgICAgIExPRy5pbmZvKCJNaW5pSEJhc2VDbHVzdGVyOiBGYWlsZWQgYmluZGluZyBNYXN0ZXIgdG8gcG9ydDogIiArIHBvcnQpOworICAgICAgICAgIHBvcnQrKzsKKyAgICAgICAgICBjb25mLnNldEludCgiaGJhc2UubWFzdGVyLnBvcnQiLCBwb3J0KTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHNodXRkb3duKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBTdGFydHMgYSByZWdpb24gc2VydmVyIHRocmVhZCBydW5uaW5nCisgICAqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHJldHVybiBOYW1lIG9mIHJlZ2lvbnNlcnZlciBzdGFydGVkLgorICAgKi8KKyAgcHVibGljIFN0cmluZyBzdGFydFJlZ2lvblNlcnZlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTG9jYWxIQmFzZUNsdXN0ZXIuUmVnaW9uU2VydmVyVGhyZWFkIHQgPQorICAgICAgdGhpcy5oYmFzZUNsdXN0ZXIuYWRkUmVnaW9uU2VydmVyKCk7CisgICAgdC5zdGFydCgpOworICAgIHQud2FpdEZvclNlcnZlck9ubGluZSgpOworICAgIHJldHVybiB0LmdldE5hbWUoKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIFJldHVybnMgdGhlIHJwYyBhZGRyZXNzIGFjdHVhbGx5IHVzZWQgYnkgdGhlIG1hc3RlciBzZXJ2ZXIsIGJlY2F1c2UKKyAgICogdGhlIHN1cHBsaWVkIHBvcnQgaXMgbm90IG5lY2Vzc2FyaWx5IHRoZSBhY3R1YWwgcG9ydCB1c2VkLgorICAgKi8KKyAgcHVibGljIEhTZXJ2ZXJBZGRyZXNzIGdldEhNYXN0ZXJBZGRyZXNzKCkgeworICAgIHJldHVybiB0aGlzLmhiYXNlQ2x1c3Rlci5nZXRNYXN0ZXIoKS5nZXRNYXN0ZXJBZGRyZXNzKCk7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgSE1hc3RlcgorICAgKi8KKyAgcHVibGljIEhNYXN0ZXIgZ2V0TWFzdGVyKCkgeworICAgIHJldHVybiB0aGlzLmhiYXNlQ2x1c3Rlci5nZXRNYXN0ZXIoKTsKKyAgfQorICAKKyAgLyoqCisgICAqIENhdXNlIGEgcmVnaW9uIHNlcnZlciB0byBleGl0IHdpdGhvdXQgY2xlYW5pbmcgdXAKKyAgICoKKyAgICogQHBhcmFtIHNlcnZlck51bWJlciAgVXNlZCBhcyBpbmRleCBpbnRvIGEgbGlzdC4KKyAgICovCisgIHB1YmxpYyB2b2lkIGFib3J0UmVnaW9uU2VydmVyKGludCBzZXJ2ZXJOdW1iZXIpIHsKKyAgICBIUmVnaW9uU2VydmVyIHNlcnZlciA9IGdldFJlZ2lvblNlcnZlcihzZXJ2ZXJOdW1iZXIpOworICAgIExPRy5pbmZvKCJBYm9ydGluZyAiICsgc2VydmVyLmdldFNlcnZlckluZm8oKS50b1N0cmluZygpKTsKKyAgICBzZXJ2ZXIuYWJvcnQoKTsKKyAgfQorCisgIC8qKgorICAgKiBTaHV0IGRvd24gdGhlIHNwZWNpZmllZCByZWdpb24gc2VydmVyIGNsZWFubHkKKyAgICoKKyAgICogQHBhcmFtIHNlcnZlck51bWJlciAgVXNlZCBhcyBpbmRleCBpbnRvIGEgbGlzdC4KKyAgICogQHJldHVybiB0aGUgcmVnaW9uIHNlcnZlciB0aGF0IHdhcyBzdG9wcGVkCisgICAqLworICBwdWJsaWMgTG9jYWxIQmFzZUNsdXN0ZXIuUmVnaW9uU2VydmVyVGhyZWFkIHN0b3BSZWdpb25TZXJ2ZXIoaW50IHNlcnZlck51bWJlcikgeworICAgIHJldHVybiBzdG9wUmVnaW9uU2VydmVyKHNlcnZlck51bWJlciwgdHJ1ZSk7CisgIH0KKworICAvKioKKyAgICogU2h1dCBkb3duIHRoZSBzcGVjaWZpZWQgcmVnaW9uIHNlcnZlciBjbGVhbmx5CisgICAqCisgICAqIEBwYXJhbSBzZXJ2ZXJOdW1iZXIgIFVzZWQgYXMgaW5kZXggaW50byBhIGxpc3QuCisgICAqIEBwYXJhbSBzaHV0ZG93bkZTIFRydWUgaXMgd2UgYXJlIHRvIHNodXRkb3duIHRoZSBmaWxlc3lzdGVtIGFzIHBhcnQgb2YgdGhpcworICAgKiByZWdpb25zZXJ2ZXIncyBzaHV0ZG93bi4gIFVzdWFsbHkgd2UgZG8gYnV0IHlvdSBkbyBub3Qgd2FudCB0byBkbyB0aGlzIGlmCisgICAqIHlvdSBhcmUgcnVubmluZyBtdWx0aXBsZSByZWdpb25zZXJ2ZXJzIGluIGEgdGVzdCBhbmQgeW91IHNodXQgZG93biBvbmUKKyAgICogYmVmb3JlIGVuZCBvZiB0aGUgdGVzdC4KKyAgICogQHJldHVybiB0aGUgcmVnaW9uIHNlcnZlciB0aGF0IHdhcyBzdG9wcGVkCisgICAqLworICBwdWJsaWMgTG9jYWxIQmFzZUNsdXN0ZXIuUmVnaW9uU2VydmVyVGhyZWFkIHN0b3BSZWdpb25TZXJ2ZXIoaW50IHNlcnZlck51bWJlciwKKyAgICAgIGZpbmFsIGJvb2xlYW4gc2h1dGRvd25GUykgeworICAgIExvY2FsSEJhc2VDbHVzdGVyLlJlZ2lvblNlcnZlclRocmVhZCBzZXJ2ZXIgPQorICAgICAgaGJhc2VDbHVzdGVyLmdldFJlZ2lvblNlcnZlcnMoKS5nZXQoc2VydmVyTnVtYmVyKTsKKyAgICBMT0cuaW5mbygiU3RvcHBpbmcgIiArIHNlcnZlci50b1N0cmluZygpKTsKKyAgICBpZiAoIXNodXRkb3duRlMpIHsKKyAgICAgIC8vIFN0b3AgdGhlIHJ1bm5pbmcgb2YgdGhlIGhkZnMgc2h1dGRvd24gdGhyZWFkIGluIHRlc3RzLgorICAgICAgc2VydmVyLmdldFJlZ2lvblNlcnZlcigpLnNldEhERlNTaHV0ZG93blRocmVhZE9uRXhpdChudWxsKTsKKyAgICB9CisgICAgc2VydmVyLmdldFJlZ2lvblNlcnZlcigpLnN0b3AoKTsKKyAgICByZXR1cm4gc2VydmVyOworICB9CisKKyAgLyoqCisgICAqIFdhaXQgZm9yIHRoZSBzcGVjaWZpZWQgcmVnaW9uIHNlcnZlciB0byBzdG9wCisgICAqIFJlbW92ZXMgdGhpcyB0aHJlYWQgZnJvbSBsaXN0IG9mIHJ1bm5pbmcgdGhyZWFkcy4KKyAgICogQHBhcmFtIHNlcnZlck51bWJlcgorICAgKiBAcmV0dXJuIE5hbWUgb2YgcmVnaW9uIHNlcnZlciB0aGF0IGp1c3Qgd2VudCBkb3duLgorICAgKi8KKyAgcHVibGljIFN0cmluZyB3YWl0T25SZWdpb25TZXJ2ZXIoZmluYWwgaW50IHNlcnZlck51bWJlcikgeworICAgIHJldHVybiB0aGlzLmhiYXNlQ2x1c3Rlci53YWl0T25SZWdpb25TZXJ2ZXIoc2VydmVyTnVtYmVyKTsKKyAgfQorCisgIC8qKgorICAgKiBXYWl0IGZvciBNaW5pIEhCYXNlIENsdXN0ZXIgdG8gc2h1dCBkb3duLgorICAgKi8KKyAgcHVibGljIHZvaWQgam9pbigpIHsKKyAgICB0aGlzLmhiYXNlQ2x1c3Rlci5qb2luKCk7CisgIH0KKworICAvKioKKyAgICogU2h1dCBkb3duIHRoZSBtaW5pIEhCYXNlIGNsdXN0ZXIKKyAgICovCisgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgeworICAgIGlmICh0aGlzLmhiYXNlQ2x1c3RlciAhPSBudWxsKSB7CisgICAgICB0aGlzLmhiYXNlQ2x1c3Rlci5zaHV0ZG93bigpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDYWxsIGZsdXNoQ2FjaGUgb24gYWxsIHJlZ2lvbnMgb24gYWxsIHBhcnRpY2lwYXRpbmcgcmVnaW9uc2VydmVycy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZmx1c2hjYWNoZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZm9yIChMb2NhbEhCYXNlQ2x1c3Rlci5SZWdpb25TZXJ2ZXJUaHJlYWQgdDoKKyAgICAgICAgdGhpcy5oYmFzZUNsdXN0ZXIuZ2V0UmVnaW9uU2VydmVycygpKSB7CisgICAgICBmb3IoSFJlZ2lvbiByOiB0LmdldFJlZ2lvblNlcnZlcigpLmdldE9ubGluZVJlZ2lvbnMoKSkgeworICAgICAgICByLmZsdXNoY2FjaGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBMaXN0IG9mIHJlZ2lvbiBzZXJ2ZXIgdGhyZWFkcy4KKyAgICovCisgIHB1YmxpYyBMaXN0PExvY2FsSEJhc2VDbHVzdGVyLlJlZ2lvblNlcnZlclRocmVhZD4gZ2V0UmVnaW9uVGhyZWFkcygpIHsKKyAgICByZXR1cm4gdGhpcy5oYmFzZUNsdXN0ZXIuZ2V0UmVnaW9uU2VydmVycygpOworICB9CisgIAorICAvKioKKyAgICogR3JhYiBhIG51bWJlcmVkIHJlZ2lvbiBzZXJ2ZXIgb2YgeW91ciBjaG9pY2UuCisgICAqIEBwYXJhbSBzZXJ2ZXJOdW1iZXIKKyAgICogQHJldHVybiByZWdpb24gc2VydmVyCisgICAqLworICBwdWJsaWMgSFJlZ2lvblNlcnZlciBnZXRSZWdpb25TZXJ2ZXIoaW50IHNlcnZlck51bWJlcikgeworICAgIHJldHVybiBoYmFzZUNsdXN0ZXIuZ2V0UmVnaW9uU2VydmVyKHNlcnZlck51bWJlcik7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL01pbmlab29LZWVwZXJDbHVzdGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9NaW5pWm9vS2VlcGVyQ2x1c3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4MjYwMWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9NaW5pWm9vS2VlcGVyQ2x1c3Rlci5qYXZhCkBAIC0wLDAgKzEsMjA1IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5SZWFkZXI7CitpbXBvcnQgamF2YS5uZXQuQmluZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlVXRpbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS56b29rZWVwZXIuWm9vS2VlcGVyV3JhcHBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5zZXJ2ZXIuTklPU2VydmVyQ254bjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5zZXJ2ZXIuWm9vS2VlcGVyU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLnNlcnZlci5wZXJzaXN0ZW5jZS5GaWxlVHhuTG9nOworCisvKioKKyAqIFRPRE86IE1vc3Qgb2YgdGhlIGNvZGUgaW4gdGhpcyBjbGFzcyBpcyByaXBwZWQgZnJvbSBab29LZWVwZXIgdGVzdHMuIEluc3RlYWQKKyAqIG9mIHJlZG9pbmcgaXQsIHdlIHNob3VsZCBjb250cmlidXRlIHVwZGF0ZXMgdG8gdGhlaXIgY29kZSB3aGljaCBsZXQgdXMgbW9yZQorICogZWFzaWx5IGFjY2VzcyB0ZXN0aW5nIGhlbHBlciBvYmplY3RzLgorICovCitwdWJsaWMgY2xhc3MgTWluaVpvb0tlZXBlckNsdXN0ZXIgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWluaVpvb0tlZXBlckNsdXN0ZXIuY2xhc3MpOworCisgIC8vIFRPRE86IG1ha2UgdGhpcyBtb3JlIGNvbmZpZ3VyYWJsZT8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRJQ0tfVElNRSA9IDIwMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT05ORUNUSU9OX1RJTUVPVVQgPSAzMDAwMDsKKworICBwcml2YXRlIGJvb2xlYW4gc3RhcnRlZDsKKyAgcHJpdmF0ZSBpbnQgY2xpZW50UG9ydCA9IDIxODEwOyAvLyB1c2Ugbm9uLXN0YW5kYXJkIHBvcnQKKworICBwcml2YXRlIE5JT1NlcnZlckNueG4uRmFjdG9yeSBzdGFuZGFsb25lU2VydmVyRmFjdG9yeTsKKworICAvKiogQ3JlYXRlIG1pbmkgWm9vS2VlcGVyIGNsdXN0ZXIuICovCisgIHB1YmxpYyBNaW5pWm9vS2VlcGVyQ2x1c3RlcigpIHsKKyAgICB0aGlzLnN0YXJ0ZWQgPSBmYWxzZTsKKyAgfQorCisgIC8vIC8gWFhYOiBGcm9tIG8uYS56ay50LkNsaWVudEJhc2UKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXR1cFRlc3RFbnYoKSB7CisgICAgLy8gZHVyaW5nIHRoZSB0ZXN0cyB3ZSBydW4gd2l0aCAxMDBLIHByZWFsbG9jIGluIHRoZSBsb2dzLgorICAgIC8vIG9uIHdpbmRvd3Mgc3lzdGVtcyBwcmVhbGxvYyBvZiA2NE0gd2FzIHNlZW4gdG8gdGFrZSB+MTVzZWNvbmRzCisgICAgLy8gcmVzdWx0aW5nIGluIHRlc3QgZmFpbHVyZSAoY2xpZW50IHRpbWVvdXQgb24gZmlyc3Qgc2Vzc2lvbikuCisgICAgLy8gc2V0IGVudiBhbmQgZGlyZWN0bHkgaW4gb3JkZXIgdG8gaGFuZGxlIHN0YXRpYyBpbml0L2djIGlzc3VlcworICAgIFN5c3RlbS5zZXRQcm9wZXJ0eSgiem9va2VlcGVyLnByZUFsbG9jU2l6ZSIsICIxMDAiKTsKKyAgICBGaWxlVHhuTG9nLnNldFByZWFsbG9jU2l6ZSgxMDApOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBiYXNlRGlyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc3RhcnR1cChGaWxlIGJhc2VEaXIpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBzZXR1cFRlc3RFbnYoKTsKKworICAgIHNodXRkb3duKCk7CisKKyAgICBGaWxlIGRpciA9IG5ldyBGaWxlKGJhc2VEaXIsICJ6b29rZWVwZXIiKS5nZXRBYnNvbHV0ZUZpbGUoKTsKKyAgICByZWNyZWF0ZURpcihkaXIpOworCisgICAgWm9vS2VlcGVyU2VydmVyIHNlcnZlciA9IG5ldyBab29LZWVwZXJTZXJ2ZXIoZGlyLCBkaXIsIFRJQ0tfVElNRSk7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHN0YW5kYWxvbmVTZXJ2ZXJGYWN0b3J5ID0gbmV3IE5JT1NlcnZlckNueG4uRmFjdG9yeShjbGllbnRQb3J0KTsKKyAgICAgIH0gY2F0Y2ggKEJpbmRFeGNlcHRpb24gZSkgeworICAgICAgICBMT0cuaW5mbygiRmFpbGQgYmluZGluZyBaSyBTZXJ2ZXIgdG8gY2xpZW50IHBvcnQ6ICIgKyBjbGllbnRQb3J0KTsKKyAgICAgICAgLy90aGlzIHBvcnQgaXMgYWxyZWFkeSBpbiB1c2UuIHRyeSB0byB1c2UgYW5vdGhlcgorICAgICAgICBjbGllbnRQb3J0Kys7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIHN0YW5kYWxvbmVTZXJ2ZXJGYWN0b3J5LnN0YXJ0dXAoc2VydmVyKTsKKworICAgIFN0cmluZyBxdW9ydW1TZXJ2ZXJzID0gImxvY2FsaG9zdDoiICsgY2xpZW50UG9ydDsKKyAgICBab29LZWVwZXJXcmFwcGVyLnNldFF1b3J1bVNlcnZlcnMocXVvcnVtU2VydmVycyk7CisKKyAgICBpZiAoIXdhaXRGb3JTZXJ2ZXJVcChjbGllbnRQb3J0LCBDT05ORUNUSU9OX1RJTUVPVVQpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIldhaXRpbmcgZm9yIHN0YXJ0dXAgb2Ygc3RhbmRhbG9uZSBzZXJ2ZXIiKTsKKyAgICB9CisKKyAgICBzdGFydGVkID0gdHJ1ZTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWNyZWF0ZURpcihGaWxlIGRpcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoZGlyLmV4aXN0cygpKSB7CisgICAgICBGaWxlVXRpbC5mdWxseURlbGV0ZShkaXIpOworICAgIH0KKyAgICB0cnkgeworICAgICAgZGlyLm1rZGlycygpOworICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiY3JlYXRpbmcgZGlyOiAiICsgZGlyLCBlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghc3RhcnRlZCkgeworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHN0YW5kYWxvbmVTZXJ2ZXJGYWN0b3J5LnNodXRkb3duKCk7CisgICAgaWYgKCF3YWl0Rm9yU2VydmVyRG93bihjbGllbnRQb3J0LCBDT05ORUNUSU9OX1RJTUVPVVQpKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIldhaXRpbmcgZm9yIHNodXRkb3duIG9mIHN0YW5kYWxvbmUgc2VydmVyIik7CisgICAgfQorCisgICAgc3RhcnRlZCA9IGZhbHNlOworICB9CisKKyAgLy8gWFhYOiBGcm9tIG8uYS56ay50LkNsaWVudEJhc2UKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB3YWl0Rm9yU2VydmVyRG93bihpbnQgcG9ydCwgbG9uZyB0aW1lb3V0KSB7CisgICAgbG9uZyBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICB0cnkgeworICAgICAgICBTb2NrZXQgc29jayA9IG5ldyBTb2NrZXQoImxvY2FsaG9zdCIsIHBvcnQpOworICAgICAgICB0cnkgeworICAgICAgICAgIE91dHB1dFN0cmVhbSBvdXRzdHJlYW0gPSBzb2NrLmdldE91dHB1dFN0cmVhbSgpOworICAgICAgICAgIG91dHN0cmVhbS53cml0ZSgic3RhdCIuZ2V0Qnl0ZXMoKSk7CisgICAgICAgICAgb3V0c3RyZWFtLmZsdXNoKCk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgc29jay5jbG9zZSgpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorCisgICAgICBpZiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgPiBzdGFydCArIHRpbWVvdXQpIHsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoMjUwKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gaWdub3JlCisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIFhYWDogRnJvbSBvLmEuemsudC5DbGllbnRCYXNlCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gd2FpdEZvclNlcnZlclVwKGludCBwb3J0LCBsb25nIHRpbWVvdXQpIHsKKyAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIFNvY2tldCBzb2NrID0gbmV3IFNvY2tldCgibG9jYWxob3N0IiwgcG9ydCk7CisgICAgICAgIEJ1ZmZlcmVkUmVhZGVyIHJlYWRlciA9IG51bGw7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgT3V0cHV0U3RyZWFtIG91dHN0cmVhbSA9IHNvY2suZ2V0T3V0cHV0U3RyZWFtKCk7CisgICAgICAgICAgb3V0c3RyZWFtLndyaXRlKCJzdGF0Ii5nZXRCeXRlcygpKTsKKyAgICAgICAgICBvdXRzdHJlYW0uZmx1c2goKTsKKworICAgICAgICAgIFJlYWRlciBpc3IgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoc29jay5nZXRJbnB1dFN0cmVhbSgpKTsKKyAgICAgICAgICByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoaXNyKTsKKyAgICAgICAgICBTdHJpbmcgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpOworICAgICAgICAgIGlmIChsaW5lICE9IG51bGwgJiYgbGluZS5zdGFydHNXaXRoKCJab29rZWVwZXIgdmVyc2lvbjoiKSkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgIHNvY2suY2xvc2UoKTsKKyAgICAgICAgICBpZiAocmVhZGVyICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJlYWRlci5jbG9zZSgpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAvLyBpZ25vcmUgYXMgdGhpcyBpcyBleHBlY3RlZAorICAgICAgICBMT0cuaW5mbygic2VydmVyIGxvY2FsaG9zdDoiICsgcG9ydCArICIgbm90IHVwICIgKyBlKTsKKyAgICAgIH0KKworICAgICAgaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpID4gc3RhcnQgKyB0aW1lb3V0KSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgdHJ5IHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDI1MCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGlnbm9yZQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL011bHRpUmVnaW9uVGFibGUuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL011bHRpUmVnaW9uVGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xN2Q0OGRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvTXVsdGlSZWdpb25UYWJsZS5qYXZhCkBAIC0wLDAgKzEsMTEzIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBVdGlsaXR5IGNsYXNzIHRvIGJ1aWxkIGEgdGFibGUgb2YgbXVsdGlwbGUgcmVnaW9ucy4KKyAqLworcHVibGljIGNsYXNzIE11bHRpUmVnaW9uVGFibGUgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW11bXSBLRVlTID0geworICAgIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwKKyAgICBCeXRlcy50b0J5dGVzKCJiYmIiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJjY2MiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJkZGQiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJlZWUiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJmZmYiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJnZ2ciKSwKKyAgICBCeXRlcy50b0J5dGVzKCJoaGgiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJpaWkiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJqamoiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJra2siKSwKKyAgICBCeXRlcy50b0J5dGVzKCJsbGwiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJtbW0iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJubm4iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJvb28iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJwcHAiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJxcXEiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJycnIiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJzc3MiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ0dHQiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ1dXUiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ2dnYiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ3d3ciKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ4eHgiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ5eXkiKQorICB9OworICAKKyAgcHJvdGVjdGVkIGZpbmFsIGJ5dGUgW10gY29sdW1uTmFtZTsKKyAgcHJvdGVjdGVkIEhUYWJsZURlc2NyaXB0b3IgZGVzYzsKKworICAvKioKKyAgICogQHBhcmFtIGNvbHVtbk5hbWUgdGhlIGNvbHVtbiB0byBwb3B1bGF0ZS4KKyAgICovCisgIHB1YmxpYyBNdWx0aVJlZ2lvblRhYmxlKGZpbmFsIFN0cmluZyBjb2x1bW5OYW1lKSB7CisgICAgc3VwZXIoKTsKKyAgICB0aGlzLmNvbHVtbk5hbWUgPSBCeXRlcy50b0J5dGVzKGNvbHVtbk5hbWUpOworICAgIC8vIFRoZXNlIGFyZSBuZWVkZWQgZm9yIHRoZSBuZXcgYW5kIGltcHJvdmVkIE1hcC9SZWR1Y2UgZnJhbWV3b3JrCisgICAgU3lzdGVtLnNldFByb3BlcnR5KCJoYWRvb3AubG9nLmRpciIsIGNvbmYuZ2V0KCJoYWRvb3AubG9nLmRpciIpKTsKKyAgICBjb25mLnNldCgibWFwcmVkLm91dHB1dC5kaXIiLCBjb25mLmdldCgiaGFkb29wLnRtcC5kaXIiKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBSdW4gYWZ0ZXIgZGZzIGlzIHJlYWR5IGJ1dCBiZWZvcmUgaGJhc2UgY2x1c3RlciBpcyBzdGFydGVkIHVwLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHByZUhCYXNlQ2x1c3RlclNldHVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIC8vIENyZWF0ZSBhIGJ1bmNoIG9mIHJlZ2lvbnMKKyAgICAgIEhSZWdpb25bXSByZWdpb25zID0gbmV3IEhSZWdpb25bS0VZUy5sZW5ndGhdOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWdpb25zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGludCBqID0gKGkgKyAxKSAlIHJlZ2lvbnMubGVuZ3RoOworICAgICAgICByZWdpb25zW2ldID0gY3JlYXRlQVJlZ2lvbihLRVlTW2ldLCBLRVlTW2pdKTsKKyAgICAgIH0KKworICAgICAgLy8gTm93IGNyZWF0ZSB0aGUgcm9vdCBhbmQgbWV0YSByZWdpb25zIGFuZCBpbnNlcnQgdGhlIGRhdGEgcmVnaW9ucworICAgICAgLy8gY3JlYXRlZCBhYm92ZSBpbnRvIHRoZSBtZXRhCisKKyAgICAgIGNyZWF0ZVJvb3RBbmRNZXRhUmVnaW9ucygpOworCisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgcmVnaW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgICBIUmVnaW9uLmFkZFJlZ2lvblRvTUVUQShtZXRhLCByZWdpb25zW2ldKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgY2xvc2VSb290QW5kTWV0YSgpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBzaHV0ZG93bkRmcyhkZnNDbHVzdGVyKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9IAorCisgIHByaXZhdGUgSFJlZ2lvbiBjcmVhdGVBUmVnaW9uKGJ5dGUgW10gc3RhcnRLZXksIGJ5dGUgW10gZW5kS2V5KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihkZXNjLCBzdGFydEtleSwgZW5kS2V5KTsKKyAgICBhZGRDb250ZW50KHJlZ2lvbiwgdGhpcy5jb2x1bW5OYW1lKTsKKyAgICBjbG9zZVJlZ2lvbkFuZERlbGV0ZUxvZyhyZWdpb24pOworICAgIHJldHVybiByZWdpb247CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBjbG9zZVJlZ2lvbkFuZERlbGV0ZUxvZyhIUmVnaW9uIHJlZ2lvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZWdpb24uY2xvc2UoKTsKKyAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1BlcmZvcm1hbmNlRXZhbHVhdGlvbi5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvUGVyZm9ybWFuY2VFdmFsdWF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDcyYjNlMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1BlcmZvcm1hbmNlRXZhbHVhdGlvbi5qYXZhCkBAIC0wLDAgKzEsODE5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlBhZ2VSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLldoaWxlTWF0Y2hSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5GU1V0aWxzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuSGFzaDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLk11cm11ckhhc2g7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uTG9uZ1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkZpbGVJbnB1dEZvcm1hdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuRmlsZU91dHB1dEZvcm1hdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ2xpZW50OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDb25mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NYXBSZWR1Y2VCYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NYXBwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk91dHB1dENvbGxlY3RvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuUmVwb3J0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlRleHRJbnB1dEZvcm1hdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuVGV4dE91dHB1dEZvcm1hdDsKKworCisvKioKKyAqIFNjcmlwdCB1c2VkIGV2YWx1YXRpbmcgSEJhc2UgcGVyZm9ybWFuY2UgYW5kIHNjYWxhYmlsaXR5LiAgUnVucyBhIEhCYXNlCisgKiBjbGllbnQgdGhhdCBzdGVwcyB0aHJvdWdoIG9uZSBvZiBhIHNldCBvZiBoYXJkY29kZWQgdGVzdHMgb3IgJ2V4cGVyaW1lbnRzJworICogKGUuZy4gYSByYW5kb20gcmVhZHMgdGVzdCwgYSByYW5kb20gd3JpdGVzIHRlc3QsIGV0Yy4pLiBQYXNzIG9uIHRoZQorICogY29tbWFuZC1saW5lIHdoaWNoIHRlc3QgdG8gcnVuIGFuZCBob3cgbWFueSBjbGllbnRzIGFyZSBwYXJ0aWNpcGF0aW5nIGluCisgKiB0aGlzIGV4cGVyaW1lbnQuIFJ1biA8Y29kZT5qYXZhIFBlcmZvcm1hbmNlRXZhbHVhdGlvbiAtLWhlbHA8L2NvZGU+IHRvCisgKiBvYnRhaW4gdXNhZ2UuCisgKiAKKyAqIDxwPlRoaXMgY2xhc3Mgc2V0cyB1cCBhbmQgcnVucyB0aGUgZXZhbHVhdGlvbiBwcm9ncmFtcyBkZXNjcmliZWQgaW4KKyAqIFNlY3Rpb24gNywgPGk+UGVyZm9ybWFuY2UgRXZhbHVhdGlvbjwvaT4sIG9mIHRoZSA8YQorICogaHJlZj0iaHR0cDovL2xhYnMuZ29vZ2xlLmNvbS9wYXBlcnMvYmlndGFibGUuaHRtbCI+QmlndGFibGU8L2E+CisgKiBwYXBlciwgcGFnZXMgOC0xMC4KKyAqIAorICogPHA+SWYgbnVtYmVyIG9mIGNsaWVudHMgPiAxLCB3ZSBzdGFydCB1cCBhIE1hcFJlZHVjZSBqb2IuIEVhY2ggbWFwIHRhc2sKKyAqIHJ1bnMgYW4gaW5kaXZpZHVhbCBjbGllbnQuIEVhY2ggY2xpZW50IGRvZXMgYWJvdXQgMUdCIG9mIGRhdGEuCisgKi8KK3B1YmxpYyBjbGFzcyBQZXJmb3JtYW5jZUV2YWx1YXRpb24gaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coUGVyZm9ybWFuY2VFdmFsdWF0aW9uLmNsYXNzLmdldE5hbWUoKSk7CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUk9XX0xFTkdUSCA9IDEwMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBPTkVfR0IgPSAxMDI0ICogMTAyNCAqIDEwMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBST1dTX1BFUl9HQiA9IE9ORV9HQiAvIFJPV19MRU5HVEg7CisgIAorICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xVTU5fTkFNRSA9IEJ5dGVzLnRvQnl0ZXMoQ09MVU1OX0ZBTUlMWV9TVFIgKyAiZGF0YSIpOworICAKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBIVGFibGVEZXNjcmlwdG9yIFRBQkxFX0RFU0NSSVBUT1I7CisgIHN0YXRpYyB7CisgICAgVEFCTEVfREVTQ1JJUFRPUiA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKCJUZXN0VGFibGUiKTsKKyAgICBUQUJMRV9ERVNDUklQVE9SLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoQ09MVU1OX0ZBTUlMWSkpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkFORE9NX1JFQUQgPSAicmFuZG9tUmVhZCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSQU5ET01fU0VFS19TQ0FOID0gInJhbmRvbVNlZWtTY2FuIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJBTkRPTV9SRUFEX01FTSA9ICJyYW5kb21SZWFkTWVtIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJBTkRPTV9XUklURSA9ICJyYW5kb21Xcml0ZSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVFVRU5USUFMX1JFQUQgPSAic2VxdWVudGlhbFJlYWQiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VRVUVOVElBTF9XUklURSA9ICJzZXF1ZW50aWFsV3JpdGUiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NBTiA9ICJzY2FuIjsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8U3RyaW5nPiBDT01NQU5EUyA9CisgICAgQXJyYXlzLmFzTGlzdChuZXcgU3RyaW5nIFtdIHtSQU5ET01fUkVBRCwKKyAgICAgIFJBTkRPTV9TRUVLX1NDQU4sCisgICAgICBSQU5ET01fUkVBRF9NRU0sCisgICAgICBSQU5ET01fV1JJVEUsCisgICAgICBTRVFVRU5USUFMX1JFQUQsCisgICAgICBTRVFVRU5USUFMX1dSSVRFLAorICAgICAgU0NBTn0pOworICAKKyAgdm9sYXRpbGUgSEJhc2VDb25maWd1cmF0aW9uIGNvbmY7CisgIHByaXZhdGUgYm9vbGVhbiBtaW5pQ2x1c3RlciA9IGZhbHNlOworICBwcml2YXRlIGJvb2xlYW4gbm9tYXByZWQgPSBmYWxzZTsKKyAgcHJpdmF0ZSBpbnQgTiA9IDE7CisgIHByaXZhdGUgaW50IFIgPSBST1dTX1BFUl9HQjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0aCBQRVJGX0VWQUxfRElSID0gbmV3IFBhdGgoInBlcmZvcm1hbmNlX2V2YWx1YXRpb24iKTsKKyAgCisgIC8qKgorICAgKiBSZWdleCB0byBwYXJzZSBsaW5lcyBpbiBpbnB1dCBmaWxlIHBhc3NlZCB0byBtYXByZWR1Y2UgdGFzay4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgUGF0dGVybiBMSU5FX1BBVFRFUk4gPQorICAgIFBhdHRlcm4uY29tcGlsZSgic3RhcnRSb3c9KFxcZCspLFxccysiICsKKyAgICAicGVyQ2xpZW50UnVuUm93cz0oXFxkKyksXFxzK3RvdGFsUm93cz0oXFxkKyksXFxzK2NsaWVudHM9KFxcZCspIik7CisgIAorICAvKioKKyAgICogRW51bSBmb3IgbWFwIG1ldHJpY3MuICBLZWVwIGl0IG91dCBoZXJlIHJhdGhlciB0aGFuIGluc2lkZSBpbiB0aGUgTWFwCisgICAqIGlubmVyLWNsYXNzIHNvIHdlIGNhbiBmaW5kIGFzc29jaWF0ZWQgcHJvcGVydGllcy4KKyAgICovCisgIHByb3RlY3RlZCBzdGF0aWMgZW51bSBDb3VudGVyIHsKKyAgICAvKiogZWxhcHNlZCB0aW1lICovCisgICAgRUxBUFNFRF9USU1FLAorICAgIC8qKiBudW1iZXIgb2Ygcm93cyAqLworICAgIFJPV1N9CisgIAorICAKKyAgLyoqCisgICAqIENvbnN0cnVjdG9yCisgICAqIEBwYXJhbSBjIENvbmZpZ3VyYXRpb24gb2JqZWN0CisgICAqLworICBwdWJsaWMgUGVyZm9ybWFuY2VFdmFsdWF0aW9uKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjKSB7CisgICAgdGhpcy5jb25mID0gYzsKKyAgfQorICAKKyAgLyoqCisgICAqIEltcGxlbWVudGF0aW9ucyBjYW4gaGF2ZSB0aGVpciBzdGF0dXMgc2V0LgorICAgKi8KKyAgc3RhdGljIGludGVyZmFjZSBTdGF0dXMgeworICAgIC8qKgorICAgICAqIFNldHMgc3RhdHVzCisgICAgICogQHBhcmFtIG1zZyBzdGF0dXMgbWVzc2FnZQorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICB2b2lkIHNldFN0YXR1cyhmaW5hbCBTdHJpbmcgbXNnKSB0aHJvd3MgSU9FeGNlcHRpb247CisgIH0KKyAgCisgIC8qKgorICAgKiBNYXBSZWR1Y2Ugam9iIHRoYXQgcnVucyBhIHBlcmZvcm1hbmNlIGV2YWx1YXRpb24gY2xpZW50IGluIGVhY2ggbWFwIHRhc2suCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBFdmFsdWF0aW9uTWFwVGFzayBleHRlbmRzIE1hcFJlZHVjZUJhc2UKKyAgaW1wbGVtZW50cyBNYXBwZXIgeworICAgIC8qKiBjb25maWd1cmF0aW9uIHBhcmFtZXRlciBuYW1lIHRoYXQgY29udGFpbnMgdGhlIGNvbW1hbmQgKi8KKyAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBDTURfS0VZID0gIkV2YWx1YXRpb25NYXBUYXNrLmNvbW1hbmQiOworICAgIHByaXZhdGUgU3RyaW5nIGNtZDsKKyAgICBwcml2YXRlIFBlcmZvcm1hbmNlRXZhbHVhdGlvbiBwZTsKKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjb25maWd1cmUoSm9iQ29uZiBqKSB7CisgICAgICB0aGlzLmNtZCA9IGouZ2V0KENNRF9LRVkpOworCisgICAgICB0aGlzLnBlID0gbmV3IFBlcmZvcm1hbmNlRXZhbHVhdGlvbihuZXcgSEJhc2VDb25maWd1cmF0aW9uKGopKTsKKyAgICB9CisgICAgCisgICAgcHVibGljIHZvaWQgbWFwKGZpbmFsIE9iamVjdCBrZXksCisgICAgICBmaW5hbCBPYmplY3QgdmFsdWUsIGZpbmFsIE91dHB1dENvbGxlY3RvciBvdXRwdXQsCisgICAgICBmaW5hbCBSZXBvcnRlciByZXBvcnRlcikKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgTWF0Y2hlciBtID0gTElORV9QQVRURVJOLm1hdGNoZXIoKChUZXh0KXZhbHVlKS50b1N0cmluZygpKTsKKyAgICAgIGlmIChtICE9IG51bGwgJiYgbS5tYXRjaGVzKCkpIHsKKyAgICAgICAgaW50IHN0YXJ0Um93ID0gSW50ZWdlci5wYXJzZUludChtLmdyb3VwKDEpKTsKKyAgICAgICAgaW50IHBlckNsaWVudFJ1blJvd3MgPSBJbnRlZ2VyLnBhcnNlSW50KG0uZ3JvdXAoMikpOworICAgICAgICBpbnQgdG90YWxSb3dzID0gSW50ZWdlci5wYXJzZUludChtLmdyb3VwKDMpKTsKKyAgICAgICAgU3RhdHVzIHN0YXR1cyA9IG5ldyBTdGF0dXMoKSB7CisgICAgICAgICAgcHVibGljIHZvaWQgc2V0U3RhdHVzKFN0cmluZyBtc2cpIHsKKyAgICAgICAgICAgIHJlcG9ydGVyLnNldFN0YXR1cyhtc2cpOworICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICAgICAgbG9uZyBlbGFwc2VkVGltZSA9ICB0aGlzLnBlLnJ1bk9uZUNsaWVudCh0aGlzLmNtZCwgc3RhcnRSb3csCisgICAgICAgICAgcGVyQ2xpZW50UnVuUm93cywgdG90YWxSb3dzLCBzdGF0dXMpOworICAgICAgICAvLyBDb2xsZWN0IGhvdyBtdWNoIHRpbWUgdGhlIHRoaW5nIHRvb2suICBSZXBvcnQgYXMgbWFwIG91dHB1dCBhbmQKKyAgICAgICAgLy8gdG8gdGhlIEVMQVBTRURfVElNRSBjb3VudGVyLgorICAgICAgICByZXBvcnRlci5pbmNyQ291bnRlcihDb3VudGVyLkVMQVBTRURfVElNRSwgZWxhcHNlZFRpbWUpOworICAgICAgICByZXBvcnRlci5pbmNyQ291bnRlcihDb3VudGVyLlJPV1MsIHBlckNsaWVudFJ1blJvd3MpOworICAgICAgICBvdXRwdXQuY29sbGVjdChuZXcgTG9uZ1dyaXRhYmxlKHN0YXJ0Um93KSwKKyAgICAgICAgICBuZXcgVGV4dChMb25nLnRvU3RyaW5nKGVsYXBzZWRUaW1lKSkpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoKKyAgICogSWYgdGFibGUgZG9lcyBub3QgYWxyZWFkeSBleGlzdCwgY3JlYXRlLgorICAgKiBAcGFyYW0gYyBDbGllbnQgdG8gdXNlIGNoZWNraW5nLgorICAgKiBAcmV0dXJuIFRydWUgaWYgd2UgY3JlYXRlZCB0aGUgdGFibGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiBjaGVja1RhYmxlKEhCYXNlQWRtaW4gYWRtaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiB0YWJsZUV4aXN0cyA9IGFkbWluLnRhYmxlRXhpc3RzKFRBQkxFX0RFU0NSSVBUT1IuZ2V0TmFtZSgpKTsKKyAgICBpZiAoIXRhYmxlRXhpc3RzKSB7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZShUQUJMRV9ERVNDUklQVE9SKTsKKyAgICAgIExPRy5pbmZvKCJUYWJsZSAiICsgVEFCTEVfREVTQ1JJUFRPUiArICIgY3JlYXRlZCIpOworICAgIH0KKyAgICByZXR1cm4gIXRhYmxlRXhpc3RzOworICB9CisgCisgIC8qCisgICAqIFdlJ3JlIHRvIHJ1biBtdWx0aXBsZSBjbGllbnRzIGNvbmN1cnJlbnRseS4gIFNldHVwIGEgbWFwcmVkdWNlIGpvYi4gIFJ1bgorICAgKiBvbmUgbWFwIHBlciBjbGllbnQuICBUaGVuIHJ1biBhIHNpbmdsZSByZWR1Y2UgdG8gc3VtIHRoZSBlbGFwc2VkIHRpbWVzLgorICAgKiBAcGFyYW0gY21kIENvbW1hbmQgdG8gcnVuLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgcnVuTklzTW9yZVRoYW5PbmUoZmluYWwgU3RyaW5nIGNtZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBjaGVja1RhYmxlKG5ldyBIQmFzZUFkbWluKGNvbmYpKTsKKyAgICBpZiAodGhpcy5ub21hcHJlZCkgeworICAgICAgZG9NdWx0aXBsZUNsaWVudHMoY21kKTsKKyAgICB9IGVsc2UgeworICAgICAgZG9NYXBSZWR1Y2UoY21kKTsKKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIFJ1biBhbGwgY2xpZW50cyBpbiB0aGlzIHZtIGVhY2ggdG8gaXRzIG93biB0aHJlYWQuCisgICAqIEBwYXJhbSBjbWQgQ29tbWFuZCB0byBydW4uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKQorICBwcml2YXRlIHZvaWQgZG9NdWx0aXBsZUNsaWVudHMoZmluYWwgU3RyaW5nIGNtZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBMaXN0PFRocmVhZD4gdGhyZWFkcyA9IG5ldyBBcnJheUxpc3Q8VGhyZWFkPih0aGlzLk4pOworICAgIGZpbmFsIGludCBwZXJDbGllbnRSb3dzID0gUi9OOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy5OOyBpKyspIHsKKyAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZCAoSW50ZWdlci50b1N0cmluZyhpKSkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgIHN1cGVyLnJ1bigpOworICAgICAgICAgIFBlcmZvcm1hbmNlRXZhbHVhdGlvbiBwZSA9IG5ldyBQZXJmb3JtYW5jZUV2YWx1YXRpb24oY29uZik7CisgICAgICAgICAgaW50IGluZGV4ID0gSW50ZWdlci5wYXJzZUludChnZXROYW1lKCkpOworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBsb25nIGVsYXBzZWRUaW1lID0gcGUucnVuT25lQ2xpZW50KGNtZCwgaW5kZXggKiBwZXJDbGllbnRSb3dzLAorICAgICAgICAgICAgICAgcGVyQ2xpZW50Um93cywgcGVyQ2xpZW50Um93cywKKyAgICAgICAgICAgICAgIG5ldyBTdGF0dXMoKSB7CisgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzZXRTdGF0dXMoZmluYWwgU3RyaW5nIG1zZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgTE9HLmluZm8oImNsaWVudC0iICsgZ2V0TmFtZSgpICsgIiAiICsgbXNnKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIExPRy5pbmZvKCJGaW5pc2hlZCAiICsgZ2V0TmFtZSgpICsgIiBpbiAiICsgZWxhcHNlZFRpbWUgKworICAgICAgICAgICAgICAibXMgd3JpdGluZyAiICsgcGVyQ2xpZW50Um93cyArICIgcm93cyIpOworICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfTsKKyAgICAgIHRocmVhZHMuYWRkKHQpOworICAgIH0KKyAgICBmb3IgKFRocmVhZCB0OiB0aHJlYWRzKSB7CisgICAgICB0LnN0YXJ0KCk7CisgICAgfQorICAgIGZvciAoVGhyZWFkIHQ6IHRocmVhZHMpIHsKKyAgICAgIHdoaWxlKHQuaXNBbGl2ZSgpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgdC5qb2luKCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZGVidWcoIkludGVycnVwdGVkLCBjb250aW51aW5nIiArIGUudG9TdHJpbmcoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIFJ1biBhIG1hcHJlZHVjZSBqb2IuICBSdW4gYXMgbWFueSBtYXBzIGFzIGFza2VkLWZvciBjbGllbnRzLgorICAgKiBCZWZvcmUgd2Ugc3RhcnQgdXAgdGhlIGpvYiwgd3JpdGUgb3V0IGFuIGlucHV0IGZpbGUgd2l0aCBpbnN0cnVjdGlvbgorICAgKiBwZXIgY2xpZW50IHJlZ2FyZHMgd2hpY2ggcm93IHRoZXkgYXJlIHRvIHN0YXJ0IG9uLgorICAgKiBAcGFyYW0gY21kIENvbW1hbmQgdG8gcnVuLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgZG9NYXBSZWR1Y2UoZmluYWwgU3RyaW5nIGNtZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQYXRoIGlucHV0RGlyID0gd3JpdGVJbnB1dEZpbGUodGhpcy5jb25mKTsKKyAgICB0aGlzLmNvbmYuc2V0KEV2YWx1YXRpb25NYXBUYXNrLkNNRF9LRVksIGNtZCk7CisgICAgSm9iQ29uZiBqb2IgPSBuZXcgSm9iQ29uZih0aGlzLmNvbmYsIHRoaXMuZ2V0Q2xhc3MoKSk7CisgICAgRmlsZUlucHV0Rm9ybWF0LnNldElucHV0UGF0aHMoam9iLCBpbnB1dERpcik7CisgICAgam9iLnNldElucHV0Rm9ybWF0KFRleHRJbnB1dEZvcm1hdC5jbGFzcyk7CisgICAgam9iLnNldEpvYk5hbWUoIkhCYXNlIFBlcmZvcm1hbmNlIEV2YWx1YXRpb24iKTsKKyAgICBqb2Iuc2V0TWFwcGVyQ2xhc3MoRXZhbHVhdGlvbk1hcFRhc2suY2xhc3MpOworICAgIGpvYi5zZXRNYXhNYXBBdHRlbXB0cygxKTsKKyAgICBqb2Iuc2V0TWF4UmVkdWNlQXR0ZW1wdHMoMSk7CisgICAgam9iLnNldE51bU1hcFRhc2tzKHRoaXMuTiAqIDEwKTsgLy8gVGVuIG1hcHMgcGVyIGNsaWVudC4KKyAgICBqb2Iuc2V0TnVtUmVkdWNlVGFza3MoMSk7CisgICAgam9iLnNldE91dHB1dEZvcm1hdChUZXh0T3V0cHV0Rm9ybWF0LmNsYXNzKTsKKyAgICBGaWxlT3V0cHV0Rm9ybWF0LnNldE91dHB1dFBhdGgoam9iLCBuZXcgUGF0aChpbnB1dERpciwgIm91dHB1dHMiKSk7CisgICAgSm9iQ2xpZW50LnJ1bkpvYihqb2IpOworICB9CisgIAorICAvKgorICAgKiBXcml0ZSBpbnB1dCBmaWxlIG9mIG9mZnNldHMtcGVyLWNsaWVudCBmb3IgdGhlIG1hcHJlZHVjZSBqb2IuCisgICAqIEBwYXJhbSBjIENvbmZpZ3VyYXRpb24KKyAgICogQHJldHVybiBEaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlIHdyaXR0ZW4uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgUGF0aCB3cml0ZUlucHV0RmlsZShmaW5hbCBDb25maWd1cmF0aW9uIGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZVN5c3RlbSBmcyA9IEZpbGVTeXN0ZW0uZ2V0KGMpOworICAgIGlmICghZnMuZXhpc3RzKFBFUkZfRVZBTF9ESVIpKSB7CisgICAgICBmcy5ta2RpcnMoUEVSRl9FVkFMX0RJUik7CisgICAgfQorICAgIFNpbXBsZURhdGVGb3JtYXQgZm9ybWF0dGVyID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXlNTWRkSEhtbXNzIik7CisgICAgUGF0aCBzdWJkaXIgPSBuZXcgUGF0aChQRVJGX0VWQUxfRElSLCBmb3JtYXR0ZXIuZm9ybWF0KG5ldyBEYXRlKCkpKTsKKyAgICBmcy5ta2RpcnMoc3ViZGlyKTsKKyAgICBQYXRoIGlucHV0RmlsZSA9IG5ldyBQYXRoKHN1YmRpciwgImlucHV0LnR4dCIpOworICAgIFByaW50U3RyZWFtIG91dCA9IG5ldyBQcmludFN0cmVhbShmcy5jcmVhdGUoaW5wdXRGaWxlKSk7CisgICAgLy8gTWFrZSBpbnB1dCByYW5kb20uCisgICAgTWFwPEludGVnZXIsIFN0cmluZz4gbSA9IG5ldyBUcmVlTWFwPEludGVnZXIsIFN0cmluZz4oKTsKKyAgICBIYXNoIGggPSBNdXJtdXJIYXNoLmdldEluc3RhbmNlKCk7CisgICAgaW50IHBlckNsaWVudFJvd3MgPSAodGhpcy5SIC8gdGhpcy5OKTsKKyAgICB0cnkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgTjsgaisrKSB7CisgICAgICAgICAgU3RyaW5nIHMgPSAic3RhcnRSb3c9IiArICgoaiAqIHBlckNsaWVudFJvd3MpICsgKGkgKiAocGVyQ2xpZW50Um93cy8xMCkpKSArCisgICAgICAgICAgIiwgcGVyQ2xpZW50UnVuUm93cz0iICsgKHBlckNsaWVudFJvd3MgLyAxMCkgKworICAgICAgICAgICIsIHRvdGFsUm93cz0iICsgdGhpcy5SICsKKyAgICAgICAgICAiLCBjbGllbnRzPSIgKyB0aGlzLk47CisgICAgICAgICAgaW50IGhhc2ggPSBoLmhhc2goQnl0ZXMudG9CeXRlcyhzKSk7CisgICAgICAgICAgbS5wdXQoaGFzaCwgcyk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGZvciAoTWFwLkVudHJ5PEludGVnZXIsIFN0cmluZz4gZTogbS5lbnRyeVNldCgpKSB7CisgICAgICAgIG91dC5wcmludGxuKGUuZ2V0VmFsdWUoKSk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG91dC5jbG9zZSgpOworICAgIH0KKyAgICByZXR1cm4gc3ViZGlyOworICB9CisKKyAgLyoKKyAgICogQSB0ZXN0LgorICAgKiBTdWJjbGFzcyB0byBwYXJ0aWN1bGFyaXplIHdoYXQgaGFwcGVucyBwZXIgcm93LgorICAgKi8KKyAgc3RhdGljIGFic3RyYWN0IGNsYXNzIFRlc3QgeworICAgIHByb3RlY3RlZCBmaW5hbCBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgc3RhcnRSb3c7CisgICAgcHJvdGVjdGVkIGZpbmFsIGludCBwZXJDbGllbnRSdW5Sb3dzOworICAgIHByb3RlY3RlZCBmaW5hbCBpbnQgdG90YWxSb3dzOworICAgIHByaXZhdGUgZmluYWwgU3RhdHVzIHN0YXR1czsKKyAgICBwcm90ZWN0ZWQgSEJhc2VBZG1pbiBhZG1pbjsKKyAgICBwcm90ZWN0ZWQgSFRhYmxlIHRhYmxlOworICAgIHByb3RlY3RlZCB2b2xhdGlsZSBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZjsKKyAgICAKKyAgICBUZXN0KGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBpbnQgc3RhcnRSb3csCisgICAgICAgIGZpbmFsIGludCBwZXJDbGllbnRSdW5Sb3dzLCBmaW5hbCBpbnQgdG90YWxSb3dzLCBmaW5hbCBTdGF0dXMgc3RhdHVzKSB7CisgICAgICBzdXBlcigpOworICAgICAgdGhpcy5zdGFydFJvdyA9IHN0YXJ0Um93OworICAgICAgdGhpcy5wZXJDbGllbnRSdW5Sb3dzID0gcGVyQ2xpZW50UnVuUm93czsKKyAgICAgIHRoaXMudG90YWxSb3dzID0gdG90YWxSb3dzOworICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7CisgICAgICB0aGlzLnRhYmxlID0gbnVsbDsKKyAgICAgIHRoaXMuY29uZiA9IGNvbmY7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgU3RyaW5nIGdlbmVyYXRlU3RhdHVzKGZpbmFsIGludCBzciwgZmluYWwgaW50IGksIGZpbmFsIGludCBscikgeworICAgICAgcmV0dXJuIHNyICsgIi8iICsgaSArICIvIiArIGxyOworICAgIH0KKyAgICAKKyAgICBwcm90ZWN0ZWQgaW50IGdldFJlcG9ydGluZ1BlcmlvZCgpIHsKKyAgICAgIHJldHVybiB0aGlzLnBlckNsaWVudFJ1blJvd3MgLyAxMDsKKyAgICB9CisgICAgCisgICAgdm9pZCB0ZXN0U2V0dXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy5hZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgICAgdGhpcy50YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgVEFCTEVfREVTQ1JJUFRPUi5nZXROYW1lKCkpOworICAgICAgdGhpcy50YWJsZS5zZXRBdXRvRmx1c2goZmFsc2UpOworICAgICAgdGhpcy50YWJsZS5zZXRXcml0ZUJ1ZmZlclNpemUoMTAyNCoxMDI0KjEyKTsKKyAgICB9CisKKyAgICB2b2lkIHRlc3RUYWtlZG93bigpICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy50YWJsZS5mbHVzaENvbW1pdHMoKTsKKyAgICB9CisgICAgCisgICAgLyoKKyAgICAgKiBSdW4gdGVzdAorICAgICAqIEByZXR1cm4gRWxhcHNlZCB0aW1lLgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBsb25nIHRlc3QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgbG9uZyBlbGFwc2VkVGltZTsKKyAgICAgIHRlc3RTZXR1cCgpOworICAgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGludCBsYXN0Um93ID0gdGhpcy5zdGFydFJvdyArIHRoaXMucGVyQ2xpZW50UnVuUm93czsKKyAgICAgICAgLy8gUmVwb3J0IG9uIGNvbXBsZXRpb24gb2YgMS8xMHRoIG9mIHRvdGFsLgorICAgICAgICBmb3IgKGludCBpID0gdGhpcy5zdGFydFJvdzsgaSA8IGxhc3RSb3c7IGkrKykgeworICAgICAgICAgIHRlc3RSb3coaSk7CisgICAgICAgICAgaWYgKHN0YXR1cyAhPSBudWxsICYmIGkgPiAwICYmIChpICUgZ2V0UmVwb3J0aW5nUGVyaW9kKCkpID09IDApIHsKKyAgICAgICAgICAgIHN0YXR1cy5zZXRTdGF0dXMoZ2VuZXJhdGVTdGF0dXModGhpcy5zdGFydFJvdywgaSwgbGFzdFJvdykpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbGFwc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lOworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgdGVzdFRha2Vkb3duKCk7CisgICAgICB9CisgICAgICByZXR1cm4gZWxhcHNlZFRpbWU7CisgICAgfQorICAgIAorICAgIC8qCisgICAgICogVGVzdCBmb3IgaW5kaXZpZHVhbCByb3cuCisgICAgICogQHBhcmFtIGkgUm93IGluZGV4LgorICAgICAqLworICAgIGFic3RyYWN0IHZvaWQgdGVzdFJvdyhmaW5hbCBpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uOworICAgIAorICAgIC8qCisgICAgICogQHJldHVybiBUZXN0IG5hbWUuCisgICAgICovCisgICAgYWJzdHJhY3QgU3RyaW5nIGdldFRlc3ROYW1lKCk7CisgIH0KKworICBjbGFzcyBSYW5kb21TZWVrU2NhblRlc3QgZXh0ZW5kcyBUZXN0IHsKKyAgICBSYW5kb21TZWVrU2NhblRlc3QoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIGZpbmFsIGludCBzdGFydFJvdywKKyAgICAgICAgZmluYWwgaW50IHBlckNsaWVudFJ1blJvd3MsIGZpbmFsIGludCB0b3RhbFJvd3MsIGZpbmFsIFN0YXR1cyBzdGF0dXMpIHsKKyAgICAgIHN1cGVyKGNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLCB0b3RhbFJvd3MsIHN0YXR1cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgdGVzdFJvdyhmaW5hbCBpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIFNjYW5uZXIgcyA9IHRoaXMudGFibGUuZ2V0U2Nhbm5lcihuZXcgYnl0ZSBbXVtdIHtDT0xVTU5fTkFNRX0sCisgICAgICAgIGdldFJhbmRvbVJvdyh0aGlzLnJhbmQsIHRoaXMudG90YWxSb3dzKSwKKyAgICAgICAgbmV3IFdoaWxlTWF0Y2hSb3dGaWx0ZXIobmV3IFBhZ2VSb3dGaWx0ZXIoMTIwKSkpOworICAgICAgLy9pbnQgY291bnQgPSAwOworICAgICAgZm9yIChSb3dSZXN1bHQgcnIgPSBudWxsOyAocnIgPSBzLm5leHQoKSkgIT0gbnVsbDspIHsKKyAgICAgICAgLy8gTE9HLmluZm8oIiIgKyBjb3VudCsrICsgIiAiICsgcnIudG9TdHJpbmcoKSk7CisgICAgICB9CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorIAorICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCBpbnQgZ2V0UmVwb3J0aW5nUGVyaW9kKCkgeworICAgICAgLy8gCisgICAgICByZXR1cm4gdGhpcy5wZXJDbGllbnRSdW5Sb3dzIC8gMTAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIFN0cmluZyBnZXRUZXN0TmFtZSgpIHsKKyAgICAgIHJldHVybiAicmFuZG9tU2Vla1NjYW5UZXN0IjsKKyAgICB9CisgIH0KKworICBjbGFzcyBSYW5kb21SZWFkVGVzdCBleHRlbmRzIFRlc3QgeworICAgIFJhbmRvbVJlYWRUZXN0KGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBpbnQgc3RhcnRSb3csCisgICAgICAgIGZpbmFsIGludCBwZXJDbGllbnRSdW5Sb3dzLCBmaW5hbCBpbnQgdG90YWxSb3dzLCBmaW5hbCBTdGF0dXMgc3RhdHVzKSB7CisgICAgICBzdXBlcihjb25mLCBzdGFydFJvdywgcGVyQ2xpZW50UnVuUm93cywgdG90YWxSb3dzLCBzdGF0dXMpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHRlc3RSb3coZmluYWwgaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0aGlzLnRhYmxlLmdldChnZXRSYW5kb21Sb3codGhpcy5yYW5kLCB0aGlzLnRvdGFsUm93cyksIENPTFVNTl9OQU1FKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgaW50IGdldFJlcG9ydGluZ1BlcmlvZCgpIHsKKyAgICAgIC8vIAorICAgICAgcmV0dXJuIHRoaXMucGVyQ2xpZW50UnVuUm93cyAvIDEwMDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBTdHJpbmcgZ2V0VGVzdE5hbWUoKSB7CisgICAgICByZXR1cm4gInJhbmRvbVJlYWQiOworICAgIH0KKyAgfQorICAKKyAgY2xhc3MgUmFuZG9tV3JpdGVUZXN0IGV4dGVuZHMgVGVzdCB7CisgICAgUmFuZG9tV3JpdGVUZXN0KGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBpbnQgc3RhcnRSb3csCisgICAgICAgIGZpbmFsIGludCBwZXJDbGllbnRSdW5Sb3dzLCBmaW5hbCBpbnQgdG90YWxSb3dzLCBmaW5hbCBTdGF0dXMgc3RhdHVzKSB7CisgICAgICBzdXBlcihjb25mLCBzdGFydFJvdywgcGVyQ2xpZW50UnVuUm93cywgdG90YWxSb3dzLCBzdGF0dXMpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHRlc3RSb3coZmluYWwgaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBieXRlIFtdIHJvdyA9IGdldFJhbmRvbVJvdyh0aGlzLnJhbmQsIHRoaXMudG90YWxSb3dzKTsKKyAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgIGIucHV0KENPTFVNTl9OQU1FLCBnZW5lcmF0ZVZhbHVlKHRoaXMucmFuZCkpOworICAgICAgdGFibGUuY29tbWl0KGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIFN0cmluZyBnZXRUZXN0TmFtZSgpIHsKKyAgICAgIHJldHVybiAicmFuZG9tV3JpdGUiOworICAgIH0KKyAgfQorICAKKyAgY2xhc3MgU2NhblRlc3QgZXh0ZW5kcyBUZXN0IHsKKyAgICBwcml2YXRlIFNjYW5uZXIgdGVzdFNjYW5uZXI7CisgICAgCisgICAgU2NhblRlc3QoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIGZpbmFsIGludCBzdGFydFJvdywKKyAgICAgICAgZmluYWwgaW50IHBlckNsaWVudFJ1blJvd3MsIGZpbmFsIGludCB0b3RhbFJvd3MsIGZpbmFsIFN0YXR1cyBzdGF0dXMpIHsKKyAgICAgIHN1cGVyKGNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLCB0b3RhbFJvd3MsIHN0YXR1cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgdGVzdFNldHVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN1cGVyLnRlc3RTZXR1cCgpOworICAgICAgdGhpcy50ZXN0U2Nhbm5lciA9IHRhYmxlLmdldFNjYW5uZXIobmV3IGJ5dGUgW11bXSB7Q09MVU1OX05BTUV9LAorICAgICAgICBmb3JtYXQodGhpcy5zdGFydFJvdykpOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHRlc3RUYWtlZG93bigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAodGhpcy50ZXN0U2Nhbm5lciAhPSBudWxsKSB7CisgICAgICAgIHRoaXMudGVzdFNjYW5uZXIuY2xvc2UoKTsKKyAgICAgIH0KKyAgICAgIHN1cGVyLnRlc3RUYWtlZG93bigpOworICAgIH0KKyAgICAKKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICB2b2lkIHRlc3RSb3coZmluYWwgaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICB0ZXN0U2Nhbm5lci5uZXh0KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgU3RyaW5nIGdldFRlc3ROYW1lKCkgeworICAgICAgcmV0dXJuICJzY2FuIjsKKyAgICB9CisgIH0KKyAgCisgIGNsYXNzIFNlcXVlbnRpYWxSZWFkVGVzdCBleHRlbmRzIFRlc3QgeworICAgIFNlcXVlbnRpYWxSZWFkVGVzdChmaW5hbCBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiwgZmluYWwgaW50IHN0YXJ0Um93LAorICAgICAgICBmaW5hbCBpbnQgcGVyQ2xpZW50UnVuUm93cywgZmluYWwgaW50IHRvdGFsUm93cywgZmluYWwgU3RhdHVzIHN0YXR1cykgeworICAgICAgc3VwZXIoY29uZiwgc3RhcnRSb3csIHBlckNsaWVudFJ1blJvd3MsIHRvdGFsUm93cywgc3RhdHVzKTsKKyAgICB9CisgICAgCisgICAgQE92ZXJyaWRlCisgICAgdm9pZCB0ZXN0Um93KGZpbmFsIGludCBpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGFibGUuZ2V0KGZvcm1hdChpKSwgQ09MVU1OX05BTUUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIFN0cmluZyBnZXRUZXN0TmFtZSgpIHsKKyAgICAgIHJldHVybiAic2VxdWVudGlhbFJlYWQiOworICAgIH0KKyAgfQorICAKKyAgY2xhc3MgU2VxdWVudGlhbFdyaXRlVGVzdCBleHRlbmRzIFRlc3QgeworICAgIFNlcXVlbnRpYWxXcml0ZVRlc3QoZmluYWwgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYsIGZpbmFsIGludCBzdGFydFJvdywKKyAgICAgICAgZmluYWwgaW50IHBlckNsaWVudFJ1blJvd3MsIGZpbmFsIGludCB0b3RhbFJvd3MsIGZpbmFsIFN0YXR1cyBzdGF0dXMpIHsKKyAgICAgIHN1cGVyKGNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLCB0b3RhbFJvd3MsIHN0YXR1cyk7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHZvaWQgdGVzdFJvdyhmaW5hbCBpbnQgaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUoZm9ybWF0KGkpKTsKKyAgICAgIGIucHV0KENPTFVNTl9OQU1FLCBnZW5lcmF0ZVZhbHVlKHRoaXMucmFuZCkpOworICAgICAgdGFibGUuY29tbWl0KGIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIFN0cmluZyBnZXRUZXN0TmFtZSgpIHsKKyAgICAgIHJldHVybiAic2VxdWVudGlhbFdyaXRlIjsKKyAgICB9CisgIH0KKyAgCisgIC8qCisgICAqIEZvcm1hdCBwYXNzZWQgaW50ZWdlci4KKyAgICogQHBhcmFtIG51bWJlcgorICAgKiBAcmV0dXJuIFJldHVybnMgemVyby1wcmVmaXhlZCAxMC1ieXRlIHdpZGUgZGVjaW1hbCB2ZXJzaW9uIG9mIHBhc3NlZAorICAgKiBudW1iZXIgKERvZXMgYWJzb2x1dGUgaW4gY2FzZSBudW1iZXIgaXMgbmVnYXRpdmUpLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlIFtdIGZvcm1hdChmaW5hbCBpbnQgbnVtYmVyKSB7CisgICAgYnl0ZSBbXSBiID0gbmV3IGJ5dGVbMTBdOworICAgIGludCBkID0gTWF0aC5hYnMobnVtYmVyKTsKKyAgICBmb3IgKGludCBpID0gYi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgeworICAgICAgYltpXSA9IChieXRlKSgoZCAlIDEwKSArICcwJyk7CisgICAgICBkIC89IDEwOworICAgIH0KKyAgICByZXR1cm4gYjsKKyAgfQorICAKKyAgLyoKKyAgICogVGhpcyBtZXRob2QgdGFrZXMgc29tZSB0aW1lIGFuZCBpcyBkb25lIGlubGluZSB1cGxvYWRpbmcgZGF0YS4gIEZvcgorICAgKiBleGFtcGxlLCBkb2luZyB0aGUgbWFwZmlsZSB0ZXN0LCBnZW5lcmF0aW9uIG9mIHRoZSBrZXkgYW5kIHZhbHVlCisgICAqIGNvbnN1bWVzIGFib3V0IDMwJSBvZiBDUFUgdGltZS4KKyAgICogQHJldHVybiBHZW5lcmF0ZWQgcmFuZG9tIHZhbHVlIHRvIGluc2VydCBpbnRvIGEgdGFibGUgY2VsbC4KKyAgICovCisgIHN0YXRpYyBieXRlW10gZ2VuZXJhdGVWYWx1ZShmaW5hbCBSYW5kb20gcikgeworICAgIGJ5dGUgW10gYiA9IG5ldyBieXRlIFtST1dfTEVOR1RIXTsKKyAgICByLm5leHRCeXRlcyhiKTsKKyAgICByZXR1cm4gYjsKKyAgfQorICAKKyAgc3RhdGljIGJ5dGUgW10gZ2V0UmFuZG9tUm93KGZpbmFsIFJhbmRvbSByYW5kb20sIGZpbmFsIGludCB0b3RhbFJvd3MpIHsKKyAgICByZXR1cm4gZm9ybWF0KHJhbmRvbS5uZXh0SW50KEludGVnZXIuTUFYX1ZBTFVFKSAlIHRvdGFsUm93cyk7CisgIH0KKyAgCisgIGxvbmcgcnVuT25lQ2xpZW50KGZpbmFsIFN0cmluZyBjbWQsIGZpbmFsIGludCBzdGFydFJvdywKKyAgICBmaW5hbCBpbnQgcGVyQ2xpZW50UnVuUm93cywgZmluYWwgaW50IHRvdGFsUm93cywgZmluYWwgU3RhdHVzIHN0YXR1cykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdGF0dXMuc2V0U3RhdHVzKCJTdGFydCAiICsgY21kICsgIiBhdCBvZmZzZXQgIiArIHN0YXJ0Um93ICsgIiBmb3IgIiArCisgICAgICBwZXJDbGllbnRSdW5Sb3dzICsgIiByb3dzIik7CisgICAgbG9uZyB0b3RhbEVsYXBzZWRUaW1lID0gMDsKKyAgICBpZiAoY21kLmVxdWFscyhSQU5ET01fUkVBRCkpIHsKKyAgICAgIFRlc3QgdCA9IG5ldyBSYW5kb21SZWFkVGVzdCh0aGlzLmNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLAorICAgICAgICB0b3RhbFJvd3MsIHN0YXR1cyk7CisgICAgICB0b3RhbEVsYXBzZWRUaW1lID0gdC50ZXN0KCk7CisgICAgfSBlbHNlIGlmIChjbWQuZXF1YWxzKFJBTkRPTV9SRUFEX01FTSkpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IHlldCBpbXBsZW1lbnRlZCIpOworICAgIH0gZWxzZSBpZiAoY21kLmVxdWFscyhSQU5ET01fV1JJVEUpKSB7CisgICAgICBUZXN0IHQgPSBuZXcgUmFuZG9tV3JpdGVUZXN0KHRoaXMuY29uZiwgc3RhcnRSb3csIHBlckNsaWVudFJ1blJvd3MsCisgICAgICAgIHRvdGFsUm93cywgc3RhdHVzKTsKKyAgICAgIHRvdGFsRWxhcHNlZFRpbWUgPSB0LnRlc3QoKTsKKyAgICB9IGVsc2UgaWYgKGNtZC5lcXVhbHMoU0NBTikpIHsKKyAgICAgIFRlc3QgdCA9IG5ldyBTY2FuVGVzdCh0aGlzLmNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLAorICAgICAgICB0b3RhbFJvd3MsIHN0YXR1cyk7CisgICAgICB0b3RhbEVsYXBzZWRUaW1lID0gdC50ZXN0KCk7CisgICAgfSBlbHNlIGlmIChjbWQuZXF1YWxzKFNFUVVFTlRJQUxfUkVBRCkpIHsKKyAgICAgIFRlc3QgdCA9IG5ldyBTZXF1ZW50aWFsUmVhZFRlc3QodGhpcy5jb25mLCBzdGFydFJvdywgcGVyQ2xpZW50UnVuUm93cywKKyAgICAgICAgdG90YWxSb3dzLCBzdGF0dXMpOworICAgICAgdG90YWxFbGFwc2VkVGltZSA9IHQudGVzdCgpOworICAgIH0gZWxzZSBpZiAoY21kLmVxdWFscyhTRVFVRU5USUFMX1dSSVRFKSkgeworICAgICAgVGVzdCB0ID0gbmV3IFNlcXVlbnRpYWxXcml0ZVRlc3QodGhpcy5jb25mLCBzdGFydFJvdywgcGVyQ2xpZW50UnVuUm93cywKKyAgICAgICAgdG90YWxSb3dzLCBzdGF0dXMpOworICAgICAgdG90YWxFbGFwc2VkVGltZSA9IHQudGVzdCgpOworICAgIH0gZWxzZSBpZiAoY21kLmVxdWFscyhSQU5ET01fU0VFS19TQ0FOKSkgeworICAgICAgVGVzdCB0ID0gbmV3IFJhbmRvbVNlZWtTY2FuVGVzdCh0aGlzLmNvbmYsIHN0YXJ0Um93LCBwZXJDbGllbnRSdW5Sb3dzLAorICAgICAgICAgIHRvdGFsUm93cywgc3RhdHVzKTsKKyAgICAgICAgdG90YWxFbGFwc2VkVGltZSA9IHQudGVzdCgpOworICAgIH0gZWxzZSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGNvbW1hbmQgdmFsdWU6ICIgKyBjbWQpOworICAgIH0KKyAgICBzdGF0dXMuc2V0U3RhdHVzKCJGaW5pc2hlZCAiICsgY21kICsgIiBpbiAiICsgdG90YWxFbGFwc2VkVGltZSArCisgICAgICAibXMgYXQgb2Zmc2V0ICIgKyBzdGFydFJvdyArICIgZm9yICIgKyBwZXJDbGllbnRSdW5Sb3dzICsgIiByb3dzIik7CisgICAgcmV0dXJuIHRvdGFsRWxhcHNlZFRpbWU7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBydW5OSXNPbmUoZmluYWwgU3RyaW5nIGNtZCkgeworICAgIFN0YXR1cyBzdGF0dXMgPSBuZXcgU3RhdHVzKCkgeworICAgICAgcHVibGljIHZvaWQgc2V0U3RhdHVzKFN0cmluZyBtc2cpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIExPRy5pbmZvKG1zZyk7CisgICAgICB9CisgICAgfTsKKworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBudWxsOworICAgIHRyeSB7CisgICAgICBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKHRoaXMuY29uZik7CisgICAgICBjaGVja1RhYmxlKGFkbWluKTsKKyAgICAgIHJ1bk9uZUNsaWVudChjbWQsIDAsIHRoaXMuUiwgdGhpcy5SLCBzdGF0dXMpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZXJyb3IoIkZhaWxlZCIsIGUpOworICAgIH0gCisgIH0KKworICBwcml2YXRlIHZvaWQgcnVuVGVzdChmaW5hbCBTdHJpbmcgY21kKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChjbWQuZXF1YWxzKFJBTkRPTV9SRUFEX01FTSkpIHsKKyAgICAgIC8vIEZvciB0aGlzIG9uZSB0ZXN0LCBzbyBhbGwgZml0cyBpbiBtZW1vcnksIG1ha2UgUiBzbWFsbGVyIChTZWUKKyAgICAgIC8vIHBnLiA5IG9mIEJpZ1RhYmxlIHBhcGVyKS4KKyAgICAgIFIgPSAodGhpcy5SIC8gMTApICogTjsKKyAgICB9CisgICAgCisgICAgTWluaUhCYXNlQ2x1c3RlciBoYmFzZU1pbmlDbHVzdGVyID0gbnVsbDsKKyAgICBNaW5pREZTQ2x1c3RlciBkZnNDbHVzdGVyID0gbnVsbDsKKyAgICBpZiAodGhpcy5taW5pQ2x1c3RlcikgeworICAgICAgZGZzQ2x1c3RlciA9IG5ldyBNaW5pREZTQ2x1c3Rlcihjb25mLCAyLCB0cnVlLCAoU3RyaW5nW10pbnVsbCk7CisgICAgICAvLyBtYW5nbGUgdGhlIGNvbmYgc28gdGhhdCB0aGUgZnMgcGFyYW1ldGVyIHBvaW50cyB0byB0aGUgbWluaWRmcyB3ZQorICAgICAgLy8ganVzdCBzdGFydGVkIHVwCisgICAgICBGaWxlU3lzdGVtIGZzID0gZGZzQ2x1c3Rlci5nZXRGaWxlU3lzdGVtKCk7CisgICAgICBjb25mLnNldCgiZnMuZGVmYXVsdC5uYW1lIiwgZnMuZ2V0VXJpKCkudG9TdHJpbmcoKSk7ICAgICAgCisgICAgICBQYXRoIHBhcmVudGRpciA9IGZzLmdldEhvbWVEaXJlY3RvcnkoKTsKKyAgICAgIGNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLCBwYXJlbnRkaXIudG9TdHJpbmcoKSk7CisgICAgICBmcy5ta2RpcnMocGFyZW50ZGlyKTsKKyAgICAgIEZTVXRpbHMuc2V0VmVyc2lvbihmcywgcGFyZW50ZGlyKTsKKyAgICAgIGhiYXNlTWluaUNsdXN0ZXIgPSBuZXcgTWluaUhCYXNlQ2x1c3Rlcih0aGlzLmNvbmYsIE4pOworICAgIH0KKyAgICAKKyAgICB0cnkgeworICAgICAgaWYgKE4gPT0gMSkgeworICAgICAgICAvLyBJZiB0aGVyZSBpcyBvbmx5IG9uZSBjbGllbnQgYW5kIG9uZSBIUmVnaW9uU2VydmVyLCB3ZSBhc3N1bWUgbm90aGluZworICAgICAgICAvLyBoYXMgYmVlbiBzZXQgdXAgYXQgYWxsLgorICAgICAgICBydW5OSXNPbmUoY21kKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIEVsc2UsIHJ1biAKKyAgICAgICAgcnVuTklzTW9yZVRoYW5PbmUoY21kKTsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYodGhpcy5taW5pQ2x1c3RlciAmJiBoYmFzZU1pbmlDbHVzdGVyICE9IG51bGwpIHsKKyAgICAgICAgaGJhc2VNaW5pQ2x1c3Rlci5zaHV0ZG93bigpOworICAgICAgICBIQmFzZVRlc3RDYXNlLnNodXRkb3duRGZzKGRmc0NsdXN0ZXIpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHByaW50VXNhZ2UoKSB7CisgICAgcHJpbnRVc2FnZShudWxsKTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHByaW50VXNhZ2UoZmluYWwgU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBpZiAobWVzc2FnZSAhPSBudWxsICYmIG1lc3NhZ2UubGVuZ3RoKCkgPiAwKSB7CisgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obWVzc2FnZSk7CisgICAgfQorICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IGphdmEgIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKworICAgICAgICAiIFstLW1hc3Rlcj1IT1NUOlBPUlRdIFxcIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgIFstLW1pbmlDbHVzdGVyXSBbLS1ub21hcHJlZF0gWy0tcm93cz1ST1dTXSA8Y29tbWFuZD4gPG5jbGllbnRzPiIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiT3B0aW9uczoiKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiBtYXN0ZXIgICAgICAgICAgU3BlY2lmeSBob3N0IGFuZCBwb3J0IG9mIEhCYXNlICIgKworICAgICAgICAiY2x1c3RlciBtYXN0ZXIuIElmIG5vdCBwcmVzZW50LCIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICAgICAgICAgICAgICAgICBhZGRyZXNzIGlzIHJlYWQgZnJvbSBjb25maWd1cmF0aW9uIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgbWluaUNsdXN0ZXIgICAgIFJ1biB0aGUgdGVzdCBvbiBhbiBIQmFzZU1pbmlDbHVzdGVyIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgbm9tYXByZWQgICAgICAgIFJ1biBtdWx0aXBsZSBjbGllbnRzIHVzaW5nIHRocmVhZHMgIiArCisgICAgICAiKHJhdGhlciB0aGFuIHVzZSBtYXByZWR1Y2UpIik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgcm93cyAgICAgICAgICAgIFJvd3MgZWFjaCBjbGllbnQgcnVucy4gRGVmYXVsdDogT25lIG1pbGxpb24iKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNvbW1hbmQ6Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgcmFuZG9tUmVhZCAgICAgIFJ1biByYW5kb20gcmVhZCB0ZXN0Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgcmFuZG9tUmVhZE1lbSAgIFJ1biByYW5kb20gcmVhZCB0ZXN0IHdoZXJlIHRhYmxlICIgKworICAgICAgImlzIGluIG1lbW9yeSIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiIHJhbmRvbVNlZWtTY2FuICBSdW4gcmFuZG9tIHNlZWsgYW5kIHNjYW4gMTAwIHRlc3QiKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiByYW5kb21Xcml0ZSAgICAgUnVuIHJhbmRvbSB3cml0ZSB0ZXN0Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgc2VxdWVudGlhbFJlYWQgIFJ1biBzZXF1ZW50aWFsIHJlYWQgdGVzdCIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiIHNlcXVlbnRpYWxXcml0ZSBSdW4gc2VxdWVudGlhbCB3cml0ZSB0ZXN0Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgc2NhbiAgICAgICAgICAgIFJ1biBzY2FuIHRlc3QiKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oKTsKKyAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkFyZ3M6Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgbmNsaWVudHMgICAgICAgIEludGVnZXIuIFJlcXVpcmVkLiBUb3RhbCBudW1iZXIgb2YgIiArCisgICAgICAiY2xpZW50cyAoYW5kIEhSZWdpb25TZXJ2ZXJzKSIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICAgICAgICAgICAgICAgICBydW5uaW5nOiAxIDw9IHZhbHVlIDw9IDUwMCIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRXhhbXBsZXM6Iik7CisgICAgU3lzdGVtLmVyci5wcmludGxuKCIgVG8gcnVuIGEgc2luZ2xlIGV2YWx1YXRpb24gY2xpZW50OiIpOworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiICQgYmluL2hiYXNlICIgKworICAgICAgIm9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlBlcmZvcm1hbmNlRXZhbHVhdGlvbiBzZXF1ZW50aWFsV3JpdGUgMSIpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGdldEFyZ3MoZmluYWwgaW50IHN0YXJ0LCBmaW5hbCBTdHJpbmdbXSBhcmdzKSB7CisgICAgaWYoc3RhcnQgKyAxID4gYXJncy5sZW5ndGgpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm11c3Qgc3VwcGx5IHRoZSBudW1iZXIgb2YgY2xpZW50cyIpOworICAgIH0KKyAgICAKKyAgICBOID0gSW50ZWdlci5wYXJzZUludChhcmdzW3N0YXJ0XSk7CisgICAgaWYgKE4gPCAxKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOdW1iZXIgb2YgY2xpZW50cyBtdXN0IGJlID4gMSIpOworICAgIH0KKyAgIAorICAgIC8vIFNldCB0b3RhbCBudW1iZXIgb2Ygcm93cyB0byB3cml0ZS4KKyAgICB0aGlzLlIgPSB0aGlzLlIgKiBOOworICB9CisgIAorICBwcml2YXRlIGludCBkb0NvbW1hbmRMaW5lKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICAvLyBQcm9jZXNzIGNvbW1hbmQtbGluZSBhcmdzLiBUT0RPOiBCZXR0ZXIgY21kLWxpbmUgcHJvY2Vzc2luZworICAgIC8vIChidXQgaG9wZWZ1bGx5IHNvbWV0aGluZyBub3QgYXMgcGFpbmZ1bCBhcyBjbGkgb3B0aW9ucykuICAgIAorICAgIGludCBlcnJDb2RlID0gLTE7CisgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgeworICAgICAgcHJpbnRVc2FnZSgpOworICAgICAgcmV0dXJuIGVyckNvZGU7CisgICAgfQorICAgIAorICAgIHRyeSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgU3RyaW5nIGNtZCA9IGFyZ3NbaV07CisgICAgICAgIGlmIChjbWQuZXF1YWxzKCItaCIpIHx8IGNtZC5zdGFydHNXaXRoKCItLWgiKSkgeworICAgICAgICAgIHByaW50VXNhZ2UoKTsKKyAgICAgICAgICBlcnJDb2RlID0gMDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgZmluYWwgU3RyaW5nIG1hc3RlckFyZ0tleSA9ICItLW1hc3Rlcj0iOworICAgICAgICBpZiAoY21kLnN0YXJ0c1dpdGgobWFzdGVyQXJnS2V5KSkgeworICAgICAgICAgIHRoaXMuY29uZi5zZXQoTUFTVEVSX0FERFJFU1MsIGNtZC5zdWJzdHJpbmcobWFzdGVyQXJnS2V5Lmxlbmd0aCgpKSk7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAKKyAgICAgICAgZmluYWwgU3RyaW5nIG1pbmlDbHVzdGVyQXJnS2V5ID0gIi0tbWluaUNsdXN0ZXIiOworICAgICAgICBpZiAoY21kLnN0YXJ0c1dpdGgobWluaUNsdXN0ZXJBcmdLZXkpKSB7CisgICAgICAgICAgdGhpcy5taW5pQ2x1c3RlciA9IHRydWU7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGZpbmFsIFN0cmluZyBubXIgPSAiLS1ub21hcHJlZCI7CisgICAgICAgIGlmIChjbWQuc3RhcnRzV2l0aChubXIpKSB7CisgICAgICAgICAgdGhpcy5ub21hcHJlZCA9IHRydWU7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIGZpbmFsIFN0cmluZyByb3dzID0gIi0tcm93cz0iOworICAgICAgICBpZiAoY21kLnN0YXJ0c1dpdGgocm93cykpIHsKKyAgICAgICAgICB0aGlzLlIgPSBJbnRlZ2VyLnBhcnNlSW50KGNtZC5zdWJzdHJpbmcocm93cy5sZW5ndGgoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgCisgICAgICAgIGlmIChDT01NQU5EUy5jb250YWlucyhjbWQpKSB7CisgICAgICAgICAgZ2V0QXJncyhpICsgMSwgYXJncyk7CisgICAgICAgICAgcnVuVGVzdChjbWQpOworICAgICAgICAgIGVyckNvZGUgPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgCisgICAgICAgIHByaW50VXNhZ2UoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgfQorICAgIAorICAgIHJldHVybiBlcnJDb2RlOworICB9CisgIAorICAvKioKKyAgICogQHBhcmFtIGFyZ3MKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKGZpbmFsIFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBIQmFzZUNvbmZpZ3VyYXRpb24gYyA9IG5ldyBIQmFzZUNvbmZpZ3VyYXRpb24oKTsKKyAgICBTeXN0ZW0uZXhpdChuZXcgUGVyZm9ybWFuY2VFdmFsdWF0aW9uKGMpLmRvQ29tbWFuZExpbmUoYXJncykpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9QZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9QZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhkOTg0YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1BlcmZvcm1hbmNlRXZhbHVhdGlvbkNvbW1vbnMuamF2YQpAQCAtMCwwICsxLDc4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKKworCisvKioKKyAqIENvZGUgc2hhcmVkIGJ5IFBFIHRlc3RzLgorICovCitwdWJsaWMgY2xhc3MgUGVyZm9ybWFuY2VFdmFsdWF0aW9uQ29tbW9ucyB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0KKyAgICBMb2dGYWN0b3J5LmdldExvZyhQZXJmb3JtYW5jZUV2YWx1YXRpb25Db21tb25zLmNsYXNzLmdldE5hbWUoKSk7CisgIAorICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0VmFsdWVTaXplKGZpbmFsIGludCBleHBlY3RlZFNpemUsIGZpbmFsIGludCBnb3QpIHsKKyAgICBpZiAoZ290ICE9IGV4cGVjdGVkU2l6ZSkgeworICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJFeHBlY3RlZCAiICsgZXhwZWN0ZWRTaXplICsgIiBidXQgZ290ICIgKyBnb3QpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEtleShmaW5hbCBieXRlIFtdIGV4cGVjdGVkLCBmaW5hbCBCeXRlQnVmZmVyIGdvdCkgeworICAgIGJ5dGUgW10gYiA9IG5ldyBieXRlW2dvdC5saW1pdCgpXTsKKyAgICBnb3QuZ2V0KGIsIDAsIGdvdC5saW1pdCgpKTsKKyAgICBhc3NlcnRLZXkoZXhwZWN0ZWQsIGIpOworICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIGFzc2VydEtleShmaW5hbCBieXRlIFtdIGV4cGVjdGVkLCBmaW5hbCBieXRlIFtdIGdvdCkgeworICAgIGlmICghb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlcy5lcXVhbHMoZXhwZWN0ZWQsIGdvdCkpIHsKKyAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiRXhwZWN0ZWQgIiArCisgICAgICAgIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXMudG9TdHJpbmcoZXhwZWN0ZWQpICsKKyAgICAgICAgIiBidXQgZ290ICIgKyBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzLnRvU3RyaW5nKGdvdCkpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHN0YXRpYyB2b2lkIGNvbmN1cnJlbnRSZWFkcyhmaW5hbCBSdW5uYWJsZSByKSB7CisgICAgZmluYWwgaW50IGNvdW50ID0gMTsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIExpc3Q8VGhyZWFkPiB0aHJlYWRzID0gbmV3IEFycmF5TGlzdDxUaHJlYWQ+KGNvdW50KTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIFRocmVhZCB0ID0gbmV3IFRocmVhZChyKTsKKyAgICAgIHQuc2V0TmFtZSgiIiArIGkpOworICAgICAgdGhyZWFkcy5hZGQodCk7CisgICAgfQorICAgIGZvciAoVGhyZWFkIHQ6IHRocmVhZHMpIHsKKyAgICAgIHQuc3RhcnQoKTsKKyAgICB9CisgICAgZm9yIChUaHJlYWQgdDogdGhyZWFkcykgeworICAgICAgdHJ5IHsKKyAgICAgICAgdC5qb2luKCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICB9CisgICAgfQorICAgIExPRy5pbmZvKCJUZXN0IHRvb2sgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIG5vdykpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvUGVyZm9ybWFuY2VFdmFsdWF0aW9uX0NvdW50ZXIucHJvcGVydGllcyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1BlcmZvcm1hbmNlRXZhbHVhdGlvbl9Db3VudGVyLnByb3BlcnRpZXMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg0OTNmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1BlcmZvcm1hbmNlRXZhbHVhdGlvbl9Db3VudGVyLnByb3BlcnRpZXMKQEAgLTAsMCArMSwzMCBAQAorIyBSZXNvdXJjZUJ1bmRsZSBwcm9wZXJ0aWVzIGZpbGUgZm9yIE1hcC1SZWR1Y2UgY291bnRlcnMKKworIy8qKgorIyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorIyAqCisjICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorIyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisjICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorIyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisjICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIyAqCisjICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIyAqCisjICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIyAqLworCitDb3VudGVyR3JvdXBOYW1lPSAgICAgICAgICAgICAgSEJhc2UgUGVyZm9ybWFuY2UgRXZhbHVhdGlvbgorRUxBUFNFRF9USU1FLm5hbWU9ICAgICAgICAgICAgIEVsYXBzZWQgdGltZSBpbiBtaWxsaXNlY29uZHMKK1JPV1MubmFtZT0JCQkJCQkJCQkgIFJvdyBjb3VudAorIyBSZXNvdXJjZUJ1bmRsZSBwcm9wZXJ0aWVzIGZpbGUgZm9yIE1hcC1SZWR1Y2UgY291bnRlcnMKKworQ291bnRlckdyb3VwTmFtZT0gICAgICAgICAgICAgIEhCYXNlIFBlcmZvcm1hbmNlIEV2YWx1YXRpb24KK0VMQVBTRURfVElNRS5uYW1lPSAgICAgICAgICAgICBFbGFwc2VkIHRpbWUgaW4gbWlsbGlzZWNvbmRzCitST1dTLm5hbWU9CQkJCQkJCQkJICBSb3cgY291bnQKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RDbGFzc01pZ3JhdGlvbi5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdENsYXNzTWlncmF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmI3ZjQ1YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RDbGFzc01pZ3JhdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjYxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA4IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dDsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uV3JpdGFibGVDb21wYXJhYmxlOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3QgdGhhdCBpbmRpdmlkdWFsIGNsYXNzZXMgY2FuIG1pZ3JhdGUgdGhlbXNlbHZlcy4KKyAqLworcHVibGljIGNsYXNzIFRlc3RDbGFzc01pZ3JhdGlvbiBleHRlbmRzIFRlc3RDYXNlIHsKKyAgCisgIC8qKgorICAgKiBUZXN0IHdlIGNhbiBtaWdyYXRlIGEgMC4xIHZlcnNpb24gb2YgSFNLLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE1pZ3JhdGVIU3RvcmVLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGJ5dGUgW10gbmFtZUJ5dGVzID0gQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpOworICAgIFRleHQgbmFtZVRleHQgPSBuZXcgVGV4dChuYW1lQnl0ZXMpOworICAgIEhTdG9yZUtleTAxQnJhbmNoICBoc2sgPSBuZXcgSFN0b3JlS2V5MDFCcmFuY2gobmFtZVRleHQsIG5hbWVUZXh0LCBub3cpOworICAgIGJ5dGUgW10gYiA9IFdyaXRhYmxlcy5nZXRCeXRlcyhoc2spOworICAgIEhTdG9yZUtleSBkZXNlcmlhbGl6ZWRIc2sgPQorICAgICAgKEhTdG9yZUtleSlXcml0YWJsZXMuZ2V0V3JpdGFibGUoYiwgbmV3IEhTdG9yZUtleSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoZGVzZXJpYWxpemVkSHNrLmdldFRpbWVzdGFtcCgpLCBoc2suZ2V0VGltZXN0YW1wKCkpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKG5hbWVCeXRlcywgZGVzZXJpYWxpemVkSHNrLmdldENvbHVtbigpKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMobmFtZUJ5dGVzLCBkZXNlcmlhbGl6ZWRIc2suZ2V0Um93KCkpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEhCYXNlIDAuMSBicmFuY2ggSFN0b3JlS2V5LiAgU2FtZSBpbiBhbGwgcmVnYXJkcyBleGNlcHQgdGhlIHV0aWxpdHkKKyAgICogbWV0aG9kcyBoYXZlIGJlZW4gcmVtb3ZlZC4KKyAgICogVXNlZCBpbiB0ZXN0IG9mIEhTSyBtaWdyYXRpb24gdGVzdC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEhTdG9yZUtleTAxQnJhbmNoIGltcGxlbWVudHMgV3JpdGFibGVDb21wYXJhYmxlIHsKKyAgICAvKioKKyAgICAgKiBDb2xvbiBjaGFyYWN0ZXIgaW4gVVRGLTgKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVIgPSAnOic7CisgICAgCisgICAgcHJpdmF0ZSBUZXh0IHJvdzsKKyAgICBwcml2YXRlIFRleHQgY29sdW1uOworICAgIHByaXZhdGUgbG9uZyB0aW1lc3RhbXA7CisKKworICAgIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBXcml0YWJsZSBpbnRlcmZhY2UgKi8KKyAgICBwdWJsaWMgSFN0b3JlS2V5MDFCcmFuY2goKSB7CisgICAgICB0aGlzKG5ldyBUZXh0KCkpOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSFN0b3JlS2V5IHNwZWNpZnlpbmcgb25seSB0aGUgcm93CisgICAgICogVGhlIGNvbHVtbiBkZWZhdWx0cyB0byB0aGUgZW1wdHkgc3RyaW5nIGFuZCB0aGUgdGltZSBzdGFtcCBkZWZhdWx0cyB0bworICAgICAqIExvbmcuTUFYX1ZBTFVFCisgICAgICogCisgICAgICogQHBhcmFtIHJvdyAtIHJvdyBrZXkKKyAgICAgKi8KKyAgICBwdWJsaWMgSFN0b3JlS2V5MDFCcmFuY2goVGV4dCByb3cpIHsKKyAgICAgIHRoaXMocm93LCBMb25nLk1BWF9WQUxVRSk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyB0aGUgcm93IGFuZCB0aW1lc3RhbXAKKyAgICAgKiBUaGUgY29sdW1uIG5hbWUgZGVmYXVsdHMgdG8gdGhlIGVtcHR5IHN0cmluZworICAgICAqIAorICAgICAqIEBwYXJhbSByb3cgcm93IGtleQorICAgICAqIEBwYXJhbSB0aW1lc3RhbXAgdGltZXN0YW1wIHZhbHVlCisgICAgICovCisgICAgcHVibGljIEhTdG9yZUtleTAxQnJhbmNoKFRleHQgcm93LCBsb25nIHRpbWVzdGFtcCkgeworICAgICAgdGhpcyhyb3csIG5ldyBUZXh0KCksIHRpbWVzdGFtcCk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIENyZWF0ZSBhbiBIU3RvcmVLZXkgc3BlY2lmeWluZyB0aGUgcm93IGFuZCBjb2x1bW4gbmFtZXMKKyAgICAgKiBUaGUgdGltZXN0YW1wIGRlZmF1bHRzIHRvIExBVEVTVF9USU1FU1RBTVAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBrZXkKKyAgICAgKi8KKyAgICBwdWJsaWMgSFN0b3JlS2V5MDFCcmFuY2goVGV4dCByb3csIFRleHQgY29sdW1uKSB7CisgICAgICB0aGlzKHJvdywgY29sdW1uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYW4gSFN0b3JlS2V5IHNwZWNpZnlpbmcgYWxsIHRoZSBmaWVsZHMKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcm93IHJvdyBrZXkKKyAgICAgKiBAcGFyYW0gY29sdW1uIGNvbHVtbiBrZXkKKyAgICAgKiBAcGFyYW0gdGltZXN0YW1wIHRpbWVzdGFtcCB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyBIU3RvcmVLZXkwMUJyYW5jaChUZXh0IHJvdywgVGV4dCBjb2x1bW4sIGxvbmcgdGltZXN0YW1wKSB7CisgICAgICAvLyBNYWtlIGNvcGllcyBieSBkb2luZyAnbmV3IFRleHQoYXJnKScuCisgICAgICB0aGlzLnJvdyA9IG5ldyBUZXh0KHJvdyk7CisgICAgICB0aGlzLmNvbHVtbiA9IG5ldyBUZXh0KGNvbHVtbik7CisgICAgICB0aGlzLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKKyAgICB9CisgICAgCisgICAgLyoqIEByZXR1cm4gQXBwcm94aW1hdGUgc2l6ZSBpbiBieXRlcyBvZiB0aGlzIGtleS4gKi8KKyAgICBwdWJsaWMgbG9uZyBnZXRTaXplKCkgeworICAgICAgcmV0dXJuIHRoaXMucm93LmdldExlbmd0aCgpICsgdGhpcy5jb2x1bW4uZ2V0TGVuZ3RoKCkgKworICAgICAgICA4IC8qIFRoZXJlIGlzIG5vIHNpemVvZiBpbiBqYXZhLiBQcmVzdW1lIGxvbmcgaXMgOCAoNjRiaXQgbWFjaGluZSkqLzsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQ29uc3RydWN0cyBhIG5ldyBIU3RvcmVLZXkgZnJvbSBhbm90aGVyCisgICAgICogCisgICAgICogQHBhcmFtIG90aGVyIHRoZSBzb3VyY2Uga2V5CisgICAgICovCisgICAgcHVibGljIEhTdG9yZUtleTAxQnJhbmNoKEhTdG9yZUtleTAxQnJhbmNoIG90aGVyKSB7CisgICAgICB0aGlzKG90aGVyLnJvdywgb3RoZXIuY29sdW1uLCBvdGhlci50aW1lc3RhbXApOworICAgIH0KKyAgICAKKyAgICAvKioKKyAgICAgKiBDaGFuZ2UgdGhlIHZhbHVlIG9mIHRoZSByb3cga2V5CisgICAgICogCisgICAgICogQHBhcmFtIG5ld3JvdyBuZXcgcm93IGtleSB2YWx1ZQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldFJvdyhUZXh0IG5ld3JvdykgeworICAgICAgdGhpcy5yb3cuc2V0KG5ld3Jvdyk7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIENoYW5nZSB0aGUgdmFsdWUgb2YgdGhlIGNvbHVtbiBrZXkKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gbmV3Y29sIG5ldyBjb2x1bW4ga2V5IHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0Q29sdW1uKFRleHQgbmV3Y29sKSB7CisgICAgICB0aGlzLmNvbHVtbi5zZXQobmV3Y29sKTsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQ2hhbmdlIHRoZSB2YWx1ZSBvZiB0aGUgdGltZXN0YW1wIGZpZWxkCisgICAgICogCisgICAgICogQHBhcmFtIHRpbWVzdGFtcCBuZXcgdGltZXN0YW1wIHZhbHVlCisgICAgICovCisgICAgcHVibGljIHZvaWQgc2V0VmVyc2lvbihsb25nIHRpbWVzdGFtcCkgeworICAgICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7CisgICAgfQorICAgIAorICAgIC8qKgorICAgICAqIFNldCB0aGUgdmFsdWUgb2YgdGhpcyBIU3RvcmVLZXkgZnJvbSB0aGUgc3VwcGxpZWQga2V5CisgICAgICogCisgICAgICogQHBhcmFtIGsga2V5IHZhbHVlIHRvIGNvcHkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzZXQoSFN0b3JlS2V5MDFCcmFuY2ggaykgeworICAgICAgdGhpcy5yb3cgPSBrLmdldFJvdygpOworICAgICAgdGhpcy5jb2x1bW4gPSBrLmdldENvbHVtbigpOworICAgICAgdGhpcy50aW1lc3RhbXAgPSBrLmdldFRpbWVzdGFtcCgpOworICAgIH0KKyAgICAKKyAgICAvKiogQHJldHVybiB2YWx1ZSBvZiByb3cga2V5ICovCisgICAgcHVibGljIFRleHQgZ2V0Um93KCkgeworICAgICAgcmV0dXJuIHJvdzsKKyAgICB9CisgICAgCisgICAgLyoqIEByZXR1cm4gdmFsdWUgb2YgY29sdW1uIGtleSAqLworICAgIHB1YmxpYyBUZXh0IGdldENvbHVtbigpIHsKKyAgICAgIHJldHVybiBjb2x1bW47CisgICAgfQorICAgIAorICAgIC8qKiBAcmV0dXJuIHZhbHVlIG9mIHRpbWVzdGFtcCAqLworICAgIHB1YmxpYyBsb25nIGdldFRpbWVzdGFtcCgpIHsKKyAgICAgIHJldHVybiB0aW1lc3RhbXA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIHJldHVybiByb3cudG9TdHJpbmcoKSArICIvIiArIGNvbHVtbi50b1N0cmluZygpICsgIi8iICsgdGltZXN0YW1wOworICAgIH0KKyAgICAKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgeworICAgICAgcmV0dXJuIGNvbXBhcmVUbyhvYmopID09IDA7CisgICAgfQorICAgIAorICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICBpbnQgcmVzdWx0ID0gdGhpcy5yb3cuaGFzaENvZGUoKTsKKyAgICAgIHJlc3VsdCBePSB0aGlzLmNvbHVtbi5oYXNoQ29kZSgpOworICAgICAgcmVzdWx0IF49IHRoaXMudGltZXN0YW1wOworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICAvLyBDb21wYXJhYmxlCisKKyAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhPYmplY3QgbykgeworICAgICAgSFN0b3JlS2V5MDFCcmFuY2ggb3RoZXIgPSAoSFN0b3JlS2V5MDFCcmFuY2gpbzsKKyAgICAgIGludCByZXN1bHQgPSB0aGlzLnJvdy5jb21wYXJlVG8ob3RoZXIucm93KTsKKyAgICAgIGlmIChyZXN1bHQgIT0gMCkgeworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgfQorICAgICAgcmVzdWx0ID0gdGhpcy5jb2x1bW4uY29tcGFyZVRvKG90aGVyLmNvbHVtbik7CisgICAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIH0KKyAgICAgIC8vIFRoZSBiZWxvdyBvbGRlciB0aW1lc3RhbXBzIHNvcnRpbmcgYWhlYWQgb2YgbmV3ZXIgdGltZXN0YW1wcyBsb29rcworICAgICAgLy8gd3JvbmcgYnV0IGl0IGlzIGludGVudGlvbmFsLiBUaGlzIHdheSwgbmV3ZXIgdGltZXN0YW1wcyBhcmUgZmlyc3QKKyAgICAgIC8vIGZvdW5kIHdoZW4gd2UgaXRlcmF0ZSBvdmVyIGEgbWVtY2FjaGUgYW5kIG5ld2VyIHZlcnNpb25zIGFyZSB0aGUKKyAgICAgIC8vIGZpcnN0IHdlIHRyaXAgb3ZlciB3aGVuIHJlYWRpbmcgZnJvbSBhIHN0b3JlIGZpbGUuCisgICAgICBpZiAodGhpcy50aW1lc3RhbXAgPCBvdGhlci50aW1lc3RhbXApIHsKKyAgICAgICAgcmVzdWx0ID0gMTsKKyAgICAgIH0gZWxzZSBpZiAodGhpcy50aW1lc3RhbXAgPiBvdGhlci50aW1lc3RhbXApIHsKKyAgICAgICAgcmVzdWx0ID0gLTE7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIC8vIFdyaXRhYmxlCisKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShEYXRhT3V0cHV0IG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJvdy53cml0ZShvdXQpOworICAgICAgY29sdW1uLndyaXRlKG91dCk7CisgICAgICBvdXQud3JpdGVMb25nKHRpbWVzdGFtcCk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcmVhZEZpZWxkcyhEYXRhSW5wdXQgaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByb3cucmVhZEZpZWxkcyhpbik7CisgICAgICBjb2x1bW4ucmVhZEZpZWxkcyhpbik7CisgICAgICB0aW1lc3RhbXAgPSBpbi5yZWFkTG9uZygpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybnMgcm93IGFuZCBjb2x1bW4gYnl0ZXMgb3V0IG9mIGFuIEhTdG9yZUtleS4KKyAgICAgKiBAcGFyYW0gaHNrIFN0b3JlIGtleS4KKyAgICAgKiBAcmV0dXJuIGJ5dGUgYXJyYXkgZW5jb2Rpbmcgb2YgSFN0b3JlS2V5CisgICAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBieXRlW10gZ2V0Qnl0ZXMoZmluYWwgSFN0b3JlS2V5IGhzaykKKyAgICB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiB7CisgICAgICBTdHJpbmdCdWlsZGVyIHMgPSBuZXcgU3RyaW5nQnVpbGRlcihCeXRlcy50b1N0cmluZyhoc2suZ2V0Um93KCkpKTsKKyAgICAgIHMuYXBwZW5kKEJ5dGVzLnRvU3RyaW5nKGhzay5nZXRDb2x1bW4oKSkpOworICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RDb21wYXJlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0Q29tcGFyZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE4MjVhNGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0Q29tcGFyZS5qYXZhCkBAIC0wLDAgKzEsMTI1IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdCBjb21wYXJpbmcgSEJhc2Ugb2JqZWN0cy4KKyAqLworcHVibGljIGNsYXNzIFRlc3RDb21wYXJlIGV4dGVuZHMgVGVzdENhc2UgeworICAKKyAgLyoqCisgICAqIEhTdG9yZUtleSBzb3J0cyBhcyB5b3Ugd291bGQgZXhwZWN0IGluIHRoZSByb3cgYW5kIGNvbHVtbiBwb3J0aW9ucyBidXQKKyAgICogZm9yIHRoZSB0aW1lc3RhbXBzLCBpdCBzb3J0cyBpbiByZXZlcnNlIHdpdGggdGhlIG5ld2VzdCBzb3J0aW5nIGJlZm9yZQorICAgKiB0aGUgb2xkZXN0IChUaGlzIGlzIGludGVudGlvbmFsIHNvIHdlIHRyaXAgb3ZlciB0aGUgbGF0ZXN0IGZpcnN0IHdoZW4KKyAgICogaXRlcmF0aW5nIG9yIGxvb2tpbmcgaW4gc3RvcmUgZmlsZXMpLgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEhTdG9yZUtleSgpIHsKKyAgICBsb25nIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGJ5dGUgW10gYSA9IEJ5dGVzLnRvQnl0ZXMoImEiKTsKKyAgICBIU3RvcmVLZXkgcGFzdCA9IG5ldyBIU3RvcmVLZXkoYSwgYSwgdGltZXN0YW1wIC0gMTApOworICAgIEhTdG9yZUtleSBub3cgPSBuZXcgSFN0b3JlS2V5KGEsIGEsIHRpbWVzdGFtcCk7CisgICAgSFN0b3JlS2V5IGZ1dHVyZSA9IG5ldyBIU3RvcmVLZXkoYSwgYSwgdGltZXN0YW1wICsgMTApOworICAgIGFzc2VydFRydWUocGFzdC5jb21wYXJlVG8obm93KSA+IDApOworICAgIGFzc2VydFRydWUobm93LmNvbXBhcmVUbyhub3cpID09IDApOworICAgIGFzc2VydFRydWUoZnV0dXJlLmNvbXBhcmVUbyhub3cpIDwgMCk7CisgICAgLy8gQ2hlY2sgdGhhdCBlbXB0eSBjb2x1bW4gY29tZXMgYmVmb3JlIG9uZSB3aXRoIGEgY29sdW1uCisgICAgSFN0b3JlS2V5IG5vY29sdW1uID0gbmV3IEhTdG9yZUtleShhLCB0aW1lc3RhbXApOworICAgIEhTdG9yZUtleSB3aXRoY29sdW1uID0gbmV3IEhTdG9yZUtleShhLCBhLCB0aW1lc3RhbXApOworICAgIGFzc2VydFRydWUobm9jb2x1bW4uY29tcGFyZVRvKHdpdGhjb2x1bW4pIDwgMCk7CisgICAgLy8gQ2hlY2sgdGhhdCBlbXB0eSBjb2x1bW4gY29tZXMgYW5kIExBVEVTVCBjb21lcyBiZWZvcmUgb25lIHdpdGggYSBjb2x1bW4KKyAgICAvLyBhbmQgb2xkIHRpbWVzdGFtcC4KKyAgICBub2NvbHVtbiA9IG5ldyBIU3RvcmVLZXkoYSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICB3aXRoY29sdW1uID0gbmV3IEhTdG9yZUtleShhLCBhLCB0aW1lc3RhbXApOworICAgIGFzc2VydFRydWUobm9jb2x1bW4uY29tcGFyZVRvKHdpdGhjb2x1bW4pIDwgMCk7CisgICAgLy8gVGVzdCBudWxsIGtleXMuCisgICAgSFN0b3JlS2V5IG5vcm1hbCA9IG5ldyBIU3RvcmVLZXkoImEiLCAiYiIpOworICAgIGFzc2VydFRydWUobm9ybWFsLmNvbXBhcmVUbyhudWxsKSA+IDApOworICAgIGFzc2VydFRydWUoSFN0b3JlS2V5LmNvbXBhcmVUbyhudWxsLCBudWxsKSA9PSAwKTsKKyAgICBhc3NlcnRUcnVlKEhTdG9yZUtleS5jb21wYXJlVG8obnVsbCwgbm9ybWFsKSA8IDApOworICB9CisgIAorICAvKioKKyAgICogVGVzdHMgY2FzZXMgd2hlcmUgcm93cyBrZXlzIGhhdmUgY2hhcmFjdGVycyBiZWxvdyB0aGUgJywnLgorICAgKiBTZWUgSEJBU0UtODMyCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SFN0b3JlS2V5Qm9yZGVyQ2FzZXMoKSB7CisgICAgLyoqIFRPRE8hISEhCisgICAgSFJlZ2lvbkluZm8gaW5mbyA9IG5ldyBIUmVnaW9uSW5mbyhuZXcgSFRhYmxlRGVzY3JpcHRvcigidGVzdHRhYmxlIiksCisgICAgICAgIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwgSENvbnN0YW50cy5FTVBUWV9CWVRFX0FSUkFZKTsKKyAgICBIU3RvcmVLZXkgcm93QSA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSx3d3cuaGJhc2Uub3JnLywxMjM0IiwKKyAgICAgICAgIiIsIExvbmcuTUFYX1ZBTFVFLCBpbmZvKTsKKyAgICBIU3RvcmVLZXkgcm93QiA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSx3d3cuaGJhc2Uub3JnLyUyMCw5OTk5OSIsCisgICAgICAgICIiLCBMb25nLk1BWF9WQUxVRSwgaW5mbyk7CisKKyAgICBhc3NlcnRUcnVlKHJvd0EuY29tcGFyZVRvKHJvd0IpID4gMCk7CisKKyAgICByb3dBID0gbmV3IEhTdG9yZUtleSgidGVzdHRhYmxlLHd3dy5oYmFzZS5vcmcvLDEyMzQiLAorICAgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUsIEhSZWdpb25JbmZvLkZJUlNUX01FVEFfUkVHSU9OSU5GTyk7CisgICAgcm93QiA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSx3d3cuaGJhc2Uub3JnLyUyMCw5OTk5OSIsCisgICAgICAgICIiLCBMb25nLk1BWF9WQUxVRSwgSFJlZ2lvbkluZm8uRklSU1RfTUVUQV9SRUdJT05JTkZPKTsKKworICAgIGFzc2VydFRydWUocm93QS5jb21wYXJlVG8ocm93QikgPCAwKTsKKworICAgIHJvd0EgPSBuZXcgSFN0b3JlS2V5KCJ0ZXN0dGFibGUsLDEyMzQiLAorICAgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUsIEhSZWdpb25JbmZvLkZJUlNUX01FVEFfUkVHSU9OSU5GTyk7CisgICAgcm93QiA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSwkd3d3LmhiYXNlLm9yZy8sOTk5OTkiLAorICAgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUsIEhSZWdpb25JbmZvLkZJUlNUX01FVEFfUkVHSU9OSU5GTyk7CisKKyAgICBhc3NlcnRUcnVlKHJvd0EuY29tcGFyZVRvKHJvd0IpIDwgMCk7CisKKyAgICByb3dBID0gbmV3IEhTdG9yZUtleSgiLk1FVEEuLHRlc3R0YWJsZSx3d3cuaGJhc2Uub3JnLywxMjM0LDQzMjEiLAorICAgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUsIEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTyk7CisgICAgcm93QiA9IG5ldyBIU3RvcmVLZXkoIi5NRVRBLix0ZXN0dGFibGUsd3d3LmhiYXNlLm9yZy8lMjAsOTk5OTksOTk5OTkiLAorICAgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUsIEhSZWdpb25JbmZvLlJPT1RfUkVHSU9OSU5GTyk7CisKKyAgICBhc3NlcnRUcnVlKHJvd0EuY29tcGFyZVRvKHJvd0IpID4gMCk7CisgICAgKi8KKyAgfQorCisgIAorICAvKioKKyAgICogU29ydCBvZiBIUmVnaW9uSW5mby4KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RIUmVnaW9uSW5mbygpIHsKKyAgICBIUmVnaW9uSW5mbyBhID0gbmV3IEhSZWdpb25JbmZvKG5ldyBIVGFibGVEZXNjcmlwdG9yKCJhIiksIG51bGwsIG51bGwpOworICAgIEhSZWdpb25JbmZvIGIgPSBuZXcgSFJlZ2lvbkluZm8obmV3IEhUYWJsZURlc2NyaXB0b3IoImIiKSwgbnVsbCwgbnVsbCk7CisgICAgYXNzZXJ0VHJ1ZShhLmNvbXBhcmVUbyhiKSAhPSAwKTsKKyAgICBIVGFibGVEZXNjcmlwdG9yIHQgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcigidCIpOworICAgIGJ5dGUgW10gbWlkd2F5ID0gQnl0ZXMudG9CeXRlcygibWlkd2F5Iik7CisgICAgYSA9IG5ldyBIUmVnaW9uSW5mbyh0LCBudWxsLCBtaWR3YXkpOworICAgIGIgPSBuZXcgSFJlZ2lvbkluZm8odCwgbWlkd2F5LCBudWxsKTsKKyAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRvKGIpIDwgMCk7CisgICAgYXNzZXJ0VHJ1ZShiLmNvbXBhcmVUbyhhKSA+IDApOworICAgIGFzc2VydEVxdWFscyhhLCBhKTsKKyAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRvKGEpID09IDApOworICAgIGEgPSBuZXcgSFJlZ2lvbkluZm8odCwgQnl0ZXMudG9CeXRlcygiYSIpLCBCeXRlcy50b0J5dGVzKCJkIikpOworICAgIGIgPSBuZXcgSFJlZ2lvbkluZm8odCwgQnl0ZXMudG9CeXRlcygiZSIpLCBCeXRlcy50b0J5dGVzKCJnIikpOworICAgIGFzc2VydFRydWUoYS5jb21wYXJlVG8oYikgPCAwKTsKKyAgICBhID0gbmV3IEhSZWdpb25JbmZvKHQsIEJ5dGVzLnRvQnl0ZXMoImFhYWEiKSwgQnl0ZXMudG9CeXRlcygiZGRkZCIpKTsKKyAgICBiID0gbmV3IEhSZWdpb25JbmZvKHQsIEJ5dGVzLnRvQnl0ZXMoImUiKSwgQnl0ZXMudG9CeXRlcygiZyIpKTsKKyAgICBhc3NlcnRUcnVlKGEuY29tcGFyZVRvKGIpIDwgMCk7CisgICAgYSA9IG5ldyBIUmVnaW9uSW5mbyh0LCBCeXRlcy50b0J5dGVzKCJhYWFhIiksIEJ5dGVzLnRvQnl0ZXMoImRkZGQiKSk7CisgICAgYiA9IG5ldyBIUmVnaW9uSW5mbyh0LCBCeXRlcy50b0J5dGVzKCJhYWFhIiksIEJ5dGVzLnRvQnl0ZXMoImVlZWUiKSk7CisgICAgYXNzZXJ0VHJ1ZShhLmNvbXBhcmVUbyhiKSA8IDApOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdEVtcHR5TWV0YUluZm8uamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RFbXB0eU1ldGFJbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTIyZDI3OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RFbXB0eU1ldGFJbmZvLmphdmEKQEAgLTAsMCArMSw3NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0cyBtYXN0ZXIgY2xlYW51cCBvZiByb3dzIGluIG1ldGEgdGFibGUgd2hlcmUgdGhlcmUgaXMgbm8gSFJlZ2lvbkluZm8KKyAqLworcHVibGljIGNsYXNzIFRlc3RFbXB0eU1ldGFJbmZvIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICAvKioKKyAgICogSW5zZXJ0IHNvbWUgYm9ndXMgcm93cyBpbiBtZXRhLiBNYXN0ZXIgc2hvdWxkIGNsZWFuIHRoZW0gdXAuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RFbXB0eU1ldGFJbmZvKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGUgdCA9IG5ldyBIVGFibGUoY29uZiwgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpOworICAgIGZpbmFsIGludCBDT1VOVCA9IDU7CisgICAgZmluYWwgYnl0ZSBbXSB0YWJsZU5hbWUgPSBCeXRlcy50b0J5dGVzKGdldE5hbWUoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDT1VOVDsgaSsrKSB7CisgICAgICBieXRlIFtdIHJlZ2lvbk5hbWUgPSBIUmVnaW9uSW5mby5jcmVhdGVSZWdpb25OYW1lKHRhYmxlTmFtZSwKKyAgICAgICAgQnl0ZXMudG9CeXRlcyhpID09IDA/ICIiOiBJbnRlZ2VyLnRvU3RyaW5nKGkpKSwKKyAgICAgICAgTG9uZy50b1N0cmluZyhTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpOworICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShyZWdpb25OYW1lKTsKKyAgICAgIGIucHV0KEhDb25zdGFudHMuQ09MX1NFUlZFUiwgQnl0ZXMudG9CeXRlcygibG9jYWxob3N0OjEyMzQiKSk7CisgICAgICB0LmNvbW1pdChiKTsKKyAgICB9CisgICAgbG9uZyBzbGVlcFRpbWUgPQorICAgICAgY29uZi5nZXRMb25nKCJoYmFzZS5tYXN0ZXIubWV0YS50aHJlYWQucmVzY2FuZnJlcXVlbmN5IiwgMTAwMDApOworICAgIGludCB0cmllcyA9IGNvbmYuZ2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCA1KTsKKyAgICBpbnQgY291bnQgPSAwOworICAgIGRvIHsKKyAgICAgIHRyaWVzIC09IDE7CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoc2xlZXBUaW1lKTsKKyAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gaWdub3JlCisgICAgICB9CisgICAgICBTY2FubmVyIHNjYW5uZXIgPSB0LmdldFNjYW5uZXIoSENvbnN0YW50cy5BTExfTUVUQV9DT0xVTU5TLCB0YWJsZU5hbWUpOworICAgICAgdHJ5IHsKKyAgICAgICAgY291bnQgPSAwOworICAgICAgICBmb3IgKFJvd1Jlc3VsdCByOiBzY2FubmVyKSB7CisgICAgICAgICAgaWYgKHIuc2l6ZSgpID4gMCkgeworICAgICAgICAgICAgY291bnQgKz0gMTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9IHdoaWxlIChjb3VudCAhPSAwICYmIHRyaWVzID49IDApOworICAgIGFzc2VydFRydWUodHJpZXMgPj0gMCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGNvdW50KTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RIQmFzZUNsdXN0ZXIuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RIQmFzZUNsdXN0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzQ2NjE5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdEhCYXNlQ2x1c3Rlci5qYXZhCkBAIC0wLDAgKzEsMjA3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGVzdCBIQmFzZSBNYXN0ZXIgYW5kIFJlZ2lvbiBzZXJ2ZXJzLCBjbGllbnQgQVBJIAorICovCitwdWJsaWMgY2xhc3MgVGVzdEhCYXNlQ2x1c3RlciBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRlc3RIQmFzZUNsdXN0ZXIuY2xhc3MpOworCisgIHByaXZhdGUgSFRhYmxlRGVzY3JpcHRvciBkZXNjOworICBwcml2YXRlIEhCYXNlQWRtaW4gYWRtaW47CisgIHByaXZhdGUgSFRhYmxlIHRhYmxlOworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVGVzdEhCYXNlQ2x1c3RlcigpIHsKKyAgICBzdXBlcigpOworICAgIHRoaXMuZGVzYyA9IG51bGw7CisgICAgdGhpcy5hZG1pbiA9IG51bGw7CisgICAgdGhpcy50YWJsZSA9IG51bGw7CisKKyAgICAvLyBNYWtlIHRoZSB0aHJlYWQgd2FrZSBmcmVxdWVuY3kgYSBsaXR0bGUgc2xvd2VyIHNvIG90aGVyIHRocmVhZHMKKyAgICAvLyBjYW4gcnVuCisgICAgY29uZi5zZXRJbnQoImhiYXNlLnNlcnZlci50aHJlYWQud2FrZWZyZXF1ZW5jeSIsIDIwMDApOworICAgIAorICAgIC8vIE1ha2UgbGVhc2UgdGltZW91dCBsb25nZXIsIGxlYXNlIGNoZWNrcyBsZXNzIGZyZXF1ZW50CisgICAgY29uZi5zZXRJbnQoImhiYXNlLm1hc3Rlci5sZWFzZS5wZXJpb2QiLCAxMCAqIDEwMDApOworICAgIAorICAgIC8vIEluY3JlYXNlIHRoZSBhbW91bnQgb2YgdGltZSBiZXR3ZWVuIGNsaWVudCByZXRyaWVzCisgICAgY29uZi5zZXRMb25nKCJoYmFzZS5jbGllbnQucGF1c2UiLCAxNSAqIDEwMDApOworICB9CisKKyAgLyoqCisgICAqIFNpbmNlIGFsbCB0aGUgInRlc3RzIiBkZXBlbmQgb24gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRlc3QsIHRoZXkgYXJlCisgICAqIG5vdCBKdW5pdCB0ZXN0cyB0aGF0IGNhbiBzdGFuZCBhbG9uZS4gQ29uc2VxdWVudGx5IHdlIGhhdmUgYSBzaW5nbGUgSnVuaXQKKyAgICogdGVzdCB0aGF0IHJ1bnMgdGhlICJzdWItdGVzdHMiIGFzIHByaXZhdGUgbWV0aG9kcy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RIQmFzZUNsdXN0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHNldHVwKCk7CisgICAgYmFzaWMoKTsKKyAgICBzY2FubmVyKCk7CisgICAgbGlzdFRhYmxlcygpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZJUlNUX1JPVyA9IDE7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fVkFMUyA9IDEwMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gQ09OVEVOVFMgPSBCeXRlcy50b0J5dGVzKCJjb250ZW50czoiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFTlRTX0JBU0lDX1NUUiA9ICJjb250ZW50czpiYXNpYyI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gQ09OVEVOVFNfQkFTSUMgPSBCeXRlcy50b0J5dGVzKENPTlRFTlRTX0JBU0lDX1NUUik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05URU5UU1RSID0gImNvbnRlbnRzdHIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIEFOQ0hPUiA9IEJ5dGVzLnRvQnl0ZXMoImFuY2hvcjoiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFOQ0hPUk5VTSA9ICJhbmNob3I6YW5jaG9ybnVtLSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTkNIT1JTVFIgPSAiYW5jaG9yc3RyIjsKKworICBwcml2YXRlIHZvaWQgc2V0dXAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcigidGVzdCIpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT05URU5UUykpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihBTkNIT1IpKTsKKyAgICBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBkZXNjLmdldE5hbWUoKSk7CisgIH0KKyAgICAgIAorICAvLyBUZXN0IGJhc2ljIGZ1bmN0aW9uYWxpdHkuIFdyaXRlcyB0byBjb250ZW50czpiYXNpYyBhbmQgYW5jaG9yOmFuY2hvcm51bS0qCisKKyAgcHJpdmF0ZSB2b2lkIGJhc2ljKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworCisgICAgLy8gV3JpdGUgb3V0IGEgYnVuY2ggb2YgdmFsdWVzCisKKyAgICBmb3IgKGludCBrID0gRklSU1RfUk9XOyBrIDw9IE5VTV9WQUxTOyBrKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUoInJvd18iICsgayk7CisgICAgICBiLnB1dChDT05URU5UU19CQVNJQywgQnl0ZXMudG9CeXRlcyhDT05URU5UU1RSICsgaykpOworICAgICAgYi5wdXQoQU5DSE9STlVNICsgaywgQnl0ZXMudG9CeXRlcyhBTkNIT1JTVFIgKyBrKSk7CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfQorICAgIExPRy5pbmZvKCJXcml0ZSAiICsgTlVNX1ZBTFMgKyAiIHJvd3MuIEVsYXBzZWQgdGltZTogIgorICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisKKyAgICAvLyBSZWFkIHRoZW0gYmFjayBpbgorCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICBieXRlIFtdIGNvbGxhYmVsID0gbnVsbDsKKyAgICBmb3IgKGludCBrID0gRklSU1RfUk9XOyBrIDw9IE5VTV9WQUxTOyBrKyspIHsKKyAgICAgIFN0cmluZyByb3dsYWJlbFN0ciA9ICJyb3dfIiArIGs7CisgICAgICBieXRlIFtdIHJvd2xhYmVsID0gQnl0ZXMudG9CeXRlcyhyb3dsYWJlbFN0cik7CisKKyAgICAgIGJ5dGUgYm9keWRhdGFbXSA9IHRhYmxlLmdldChyb3dsYWJlbCwgQ09OVEVOVFNfQkFTSUMpLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJubyBkYXRhIGZvciByb3cgIiArIHJvd2xhYmVsU3RyICsgIi8iICsgQ09OVEVOVFNfQkFTSUNfU1RSLAorICAgICAgICAgIGJvZHlkYXRhKTsKKyAgICAgIFN0cmluZyBib2R5c3RyID0gbmV3IFN0cmluZyhib2R5ZGF0YSwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICAgIFN0cmluZyB0ZXN0c3RyID0gQ09OVEVOVFNUUiArIGs7CisgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdmFsdWUgZm9yIGtleTogKCIgKyByb3dsYWJlbFN0ciArICIvIiArCisgICAgICAgICAgQ09OVEVOVFNfQkFTSUNfU1RSICsgIiksIGV4cGVjdGVkOiAnIiArIHRlc3RzdHIgKyAiJyBnb3Q6ICciICsKKyAgICAgICAgICBib2R5c3RyICsgIiciLCB0ZXN0c3RyLmNvbXBhcmVUbyhib2R5c3RyKSA9PSAwKTsKKyAgICAgIAorICAgICAgU3RyaW5nIGNvbGxhYmVsU3RyID0gQU5DSE9STlVNICsgazsKKyAgICAgIGNvbGxhYmVsID0gQnl0ZXMudG9CeXRlcyhjb2xsYWJlbFN0cik7CisgICAgICBib2R5ZGF0YSA9IHRhYmxlLmdldChyb3dsYWJlbCwgY29sbGFiZWwpLmdldFZhbHVlKCk7CisgICAgICBhc3NlcnROb3ROdWxsKCJubyBkYXRhIGZvciByb3cgIiArIHJvd2xhYmVsU3RyICsgIi8iICsgY29sbGFiZWxTdHIsIGJvZHlkYXRhKTsKKyAgICAgIGJvZHlzdHIgPSBuZXcgU3RyaW5nKGJvZHlkYXRhLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgICAgdGVzdHN0ciA9IEFOQ0hPUlNUUiArIGs7CisgICAgICBhc3NlcnRUcnVlKCJJbmNvcnJlY3QgdmFsdWUgZm9yIGtleTogKCIgKyByb3dsYWJlbFN0ciArICIvIiArIGNvbGxhYmVsU3RyICsKKyAgICAgICAgICAiKSwgZXhwZWN0ZWQ6ICciICsgdGVzdHN0ciArICInIGdvdDogJyIgKyBib2R5c3RyICsgIiciLAorICAgICAgICAgIHRlc3RzdHIuY29tcGFyZVRvKGJvZHlzdHIpID09IDApOworICAgIH0KKworICAgIExPRy5pbmZvKCJSZWFkICIgKyBOVU1fVkFMUyArICIgcm93cy4gRWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHNjYW5uZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW11bXSBjb2xzID0gbmV3IGJ5dGUgW11bXSB7Qnl0ZXMudG9CeXRlcyhBTkNIT1JOVU0gKyAiWzAtOV0rIiksCisgICAgICBDT05URU5UU19CQVNJQ307CisgICAgCisgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAKKyAgICBTY2FubmVyIHMgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHMsIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSk7CisgICAgdHJ5IHsKKworICAgICAgaW50IGNvbnRlbnRzRmV0Y2hlZCA9IDA7CisgICAgICBpbnQgYW5jaG9yRmV0Y2hlZCA9IDA7CisgICAgICBpbnQgayA9IDA7CisgICAgICBmb3IgKFJvd1Jlc3VsdCBjdXJWYWxzIDogcykgeworICAgICAgICBmb3IgKEl0ZXJhdG9yPGJ5dGUgW10+IGl0ID0gY3VyVmFscy5rZXlTZXQoKS5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7ICkgeworICAgICAgICAgIGJ5dGUgW10gY29sID0gaXQubmV4dCgpOworICAgICAgICAgIGJ5dGUgdmFsW10gPSBjdXJWYWxzLmdldChjb2wpLmdldFZhbHVlKCk7CisgICAgICAgICAgU3RyaW5nIGN1cnZhbCA9IEJ5dGVzLnRvU3RyaW5nKHZhbCk7CisgICAgICAgICAgaWYgKEJ5dGVzLmNvbXBhcmVUbyhjb2wsIENPTlRFTlRTX0JBU0lDKSA9PSAwKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJFcnJvciBhdDoiICsgQnl0ZXMudG9TdHJpbmcoY3VyVmFscy5nZXRSb3coKSkgCisgICAgICAgICAgICAgICAgKyAiLCBWYWx1ZSBmb3IgIiArIEJ5dGVzLnRvU3RyaW5nKGNvbCkgKyAiIHNob3VsZCBzdGFydCB3aXRoOiAiICsgQ09OVEVOVFNUUgorICAgICAgICAgICAgICAgICsgIiwgYnV0IHdhcyBmZXRjaGVkIGFzOiAiICsgY3VydmFsLAorICAgICAgICAgICAgICAgIGN1cnZhbC5zdGFydHNXaXRoKENPTlRFTlRTVFIpKTsKKyAgICAgICAgICAgIGNvbnRlbnRzRmV0Y2hlZCsrOworICAgICAgICAgICAgCisgICAgICAgICAgfSBlbHNlIGlmIChCeXRlcy50b1N0cmluZyhjb2wpLnN0YXJ0c1dpdGgoQU5DSE9STlVNKSkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRXJyb3IgYXQ6IiArIEJ5dGVzLnRvU3RyaW5nKGN1clZhbHMuZ2V0Um93KCkpCisgICAgICAgICAgICAgICAgKyAiLCBWYWx1ZSBmb3IgIiArIEJ5dGVzLnRvU3RyaW5nKGNvbCkgKyAiIHNob3VsZCBzdGFydCB3aXRoOiAiICsgQU5DSE9SU1RSCisgICAgICAgICAgICAgICAgKyAiLCBidXQgd2FzIGZldGNoZWQgYXM6ICIgKyBjdXJ2YWwsCisgICAgICAgICAgICAgICAgY3VydmFsLnN0YXJ0c1dpdGgoQU5DSE9SU1RSKSk7CisgICAgICAgICAgICBhbmNob3JGZXRjaGVkKys7CisgICAgICAgICAgICAKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTE9HLmluZm8oQnl0ZXMudG9TdHJpbmcoY29sKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGsrKzsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiRXhwZWN0ZWQgIiArIE5VTV9WQUxTICsgIiAiICsKKyAgICAgICAgQnl0ZXMudG9TdHJpbmcoQ09OVEVOVFNfQkFTSUMpICsgIiB2YWx1ZXMsIGJ1dCBmZXRjaGVkICIgKworICAgICAgICBjb250ZW50c0ZldGNoZWQsCisgICAgICAgIE5VTV9WQUxTLCBjb250ZW50c0ZldGNoZWQpOworICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCAiICsgTlVNX1ZBTFMgKyAiICIgKyBBTkNIT1JOVU0gKworICAgICAgICAiIHZhbHVlcywgYnV0IGZldGNoZWQgIiArIGFuY2hvckZldGNoZWQsCisgICAgICAgIE5VTV9WQUxTLCBhbmNob3JGZXRjaGVkKTsKKworICAgICAgTE9HLmluZm8oIlNjYW5uZWQgIiArIE5VTV9WQUxTCisgICAgICAgICAgKyAiIHJvd3MuIEVsYXBzZWQgdGltZTogIgorICAgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKworICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGxpc3RUYWJsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZURlc2NyaXB0b3JbXSB0YWJsZXMgPSBhZG1pbi5saXN0VGFibGVzKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHRhYmxlcy5sZW5ndGgpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKGRlc2MuZ2V0TmFtZSgpLCB0YWJsZXNbMF0uZ2V0TmFtZSgpKSk7CisgICAgQ29sbGVjdGlvbjxIQ29sdW1uRGVzY3JpcHRvcj4gZmFtaWxpZXMgPSB0YWJsZXNbMF0uZ2V0RmFtaWxpZXMoKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgZmFtaWxpZXMuc2l6ZSgpKTsKKyAgICBhc3NlcnRUcnVlKHRhYmxlc1swXS5oYXNGYW1pbHkoQ09OVEVOVFMpKTsKKyAgICBhc3NlcnRUcnVlKHRhYmxlc1swXS5oYXNGYW1pbHkoQU5DSE9SKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0SFN0b3JlS2V5LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0SFN0b3JlS2V5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTBmNzY1YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RIU3RvcmVLZXkuamF2YQpAQCAtMCwwICsxLDI3MCBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuV3JpdGFibGVzOworCisvKioKKyAqIFRlc3RzIGZvciB0aGUgSFN0b3JlS2V5IFBsYWluIGFuZCBNZXRhIFJhd0NvbXBhcmF0b3JzLgorICovCitwdWJsaWMgY2xhc3MgVGVzdEhTdG9yZUtleSBleHRlbmRzIFRlc3RDYXNlIHsKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnRlYXJEb3duKCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0TW9yZUNvbXBhcmlzb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gUm9vdCBjb21wYXJlcworICAgIEhTdG9yZUtleSBhID0gbmV3IEhTdG9yZUtleSgiLk1FVEEuLCw5OTk5OTk5OTk5OTk5OSIpOworICAgIEhTdG9yZUtleSBiID0gbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwxIik7CisgICAgSFN0b3JlS2V5LlN0b3JlS2V5Q29tcGFyYXRvciBjID0gbmV3IEhTdG9yZUtleS5Sb290U3RvcmVLZXlDb21wYXJhdG9yKCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUoYi5nZXRCeXRlcygpLCBhLmdldEJ5dGVzKCkpIDwgMCk7CisgICAgSFN0b3JlS2V5IGFhID0gbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwxIik7CisgICAgSFN0b3JlS2V5IGJiID0gbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwxIiwgImluZm86cmVnaW9uaW5mbyIsIDEyMzU5NDM0NTQ2MDJMKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShhYS5nZXRCeXRlcygpLCBiYi5nZXRCeXRlcygpKSA8IDApOworICAgIAorICAgIC8vIE1ldGEgY29tcGFyZXMKKyAgICBIU3RvcmVLZXkgYWFhID0gbmV3IEhTdG9yZUtleSgiVGVzdFNjYW5NdWx0aXBsZVZlcnNpb25zLHJvd18wNTAwLDEyMzYwMjAxNDU1MDIiKTsKKyAgICBIU3RvcmVLZXkgYmJiID0gbmV3IEhTdG9yZUtleSgiVGVzdFNjYW5NdWx0aXBsZVZlcnNpb25zLCw5OTk5OTk5OTk5OTk5OSIpOworICAgIGMgPSBuZXcgSFN0b3JlS2V5Lk1ldGFTdG9yZUtleUNvbXBhcmF0b3IoKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShiYmIuZ2V0Qnl0ZXMoKSwgYWFhLmdldEJ5dGVzKCkpIDwgMCk7CisgICAgCisgICAgSFN0b3JlS2V5IGFhYWEgPSBuZXcgSFN0b3JlS2V5KCJUZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMsLDEyMzYwMjM5OTY2NTYiLAorICAgICAgImluZm86cmVnaW9uaW5mbyIsIDEyMzYwMjQzOTYyNzFMKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShhYWFhLmdldEJ5dGVzKCksIGJiYi5nZXRCeXRlcygpKSA8IDApOworICAgIAorICAgIEhTdG9yZUtleSB4ID0gbmV3IEhTdG9yZUtleSgiVGVzdFNjYW5NdWx0aXBsZVZlcnNpb25zLHJvd18wNTAwLDEyMzYwMzQ1NzQxNjIiLAorICAgICAgIiIsIDkyMjMzNzIwMzY4NTQ3NzU4MDdMKTsKKyAgICBIU3RvcmVLZXkgeSA9IG5ldyBIU3RvcmVLZXkoIlRlc3RTY2FuTXVsdGlwbGVWZXJzaW9ucyxyb3dfMDUwMCwxMjM2MDM0NTc0MTYyIiwKKyAgICAgICJpbmZvOnJlZ2lvbmluZm8iLCAxMjM2MDM0NTc0OTEyTCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUoeC5nZXRCeXRlcygpLCB5LmdldEJ5dGVzKCkpIDwgMCk7CisgICAgCisgICAgY29tcGFyaXNvbnMobmV3IEhTdG9yZUtleS5IU3RvcmVLZXlSb290Q29tcGFyYXRvcigpKTsKKyAgICBjb21wYXJpc29ucyhuZXcgSFN0b3JlS2V5LkhTdG9yZUtleU1ldGFDb21wYXJhdG9yKCkpOworICAgIGNvbXBhcmlzb25zKG5ldyBIU3RvcmVLZXkuSFN0b3JlS2V5Q29tcGFyYXRvcigpKTsKKyAgICBtZXRhY29tcGFyaXNvbnMobmV3IEhTdG9yZUtleS5IU3RvcmVLZXlSb290Q29tcGFyYXRvcigpKTsKKyAgICBtZXRhY29tcGFyaXNvbnMobmV3IEhTdG9yZUtleS5IU3RvcmVLZXlNZXRhQ29tcGFyYXRvcigpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBjYXNlcyB3aGVyZSByb3dzIGtleXMgaGF2ZSBjaGFyYWN0ZXJzIGJlbG93IHRoZSAnLCcuCisgICAqIFNlZSBIQkFTRS04MzIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RIU3RvcmVLZXlCb3JkZXJDYXNlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFN0b3JlS2V5IHJvd0EgPSBuZXcgSFN0b3JlS2V5KCJ0ZXN0dGFibGUsd3d3LmhiYXNlLm9yZy8sMTIzNCIsCisgICAgICAiIiwgTG9uZy5NQVhfVkFMVUUpOworICAgIGJ5dGUgW10gcm93QUJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKHJvd0EpOworICAgIEhTdG9yZUtleSByb3dCID0gbmV3IEhTdG9yZUtleSgidGVzdHRhYmxlLHd3dy5oYmFzZS5vcmcvJTIwLDk5OTk5IiwKKyAgICAgICIiLCBMb25nLk1BWF9WQUxVRSk7CisgICAgYnl0ZSBbXSByb3dCQnl0ZXMgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMocm93Qik7CisgICAgLy8gVGhpcyBpcyBhIHBsYWluIGNvbXBhcmUgb24gdGhlIHJvdy4gSXQgZ2l2ZXMgd3JvbmcgYW5zd2VyIGZvciBtZXRhIHRhYmxlCisgICAgLy8gcm93IGVudHJ5LgorICAgIGFzc2VydFRydWUocm93QS5jb21wYXJlVG8ocm93QikgPiAwKTsKKyAgICBIU3RvcmVLZXkuTWV0YVN0b3JlS2V5Q29tcGFyYXRvciBjID0KKyAgICAgIG5ldyBIU3RvcmVLZXkuTWV0YVN0b3JlS2V5Q29tcGFyYXRvcigpOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKHJvd0FCeXRlcywgcm93QkJ5dGVzKSA8IDApOworCisgICAgcm93QSA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSwsMTIzNCIsICIiLCBMb25nLk1BWF9WQUxVRSk7CisgICAgcm93QiA9IG5ldyBIU3RvcmVLZXkoInRlc3R0YWJsZSwkd3d3LmhiYXNlLm9yZy8sOTk5OTkiLCAiIiwgTG9uZy5NQVhfVkFMVUUpOworICAgIGFzc2VydFRydWUocm93QS5jb21wYXJlVG8ocm93QikgPiAwKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZSggV3JpdGFibGVzLmdldEJ5dGVzKHJvd0EpLCAgV3JpdGFibGVzLmdldEJ5dGVzKHJvd0IpKSA8IDApOworCisgICAgcm93QSA9IG5ldyBIU3RvcmVLZXkoIi5NRVRBLix0ZXN0dGFibGUsd3d3LmhiYXNlLm9yZy8sMTIzNCw0MzIxIiwgIiIsCisgICAgICBMb25nLk1BWF9WQUxVRSk7CisgICAgcm93QiA9IG5ldyBIU3RvcmVLZXkoIi5NRVRBLix0ZXN0dGFibGUsd3d3LmhiYXNlLm9yZy8lMjAsOTk5OTksOTk5OTkiLCAiIiwKKyAgICAgIExvbmcuTUFYX1ZBTFVFKTsKKyAgICBhc3NlcnRUcnVlKHJvd0EuY29tcGFyZVRvKHJvd0IpID4gMCk7CisgICAgSFN0b3JlS2V5LlJvb3RTdG9yZUtleUNvbXBhcmF0b3Igcm9vdENvbXBhcmF0b3IgPQorICAgICAgbmV3IEhTdG9yZUtleS5Sb290U3RvcmVLZXlDb21wYXJhdG9yKCk7CisgICAgYXNzZXJ0VHJ1ZShyb290Q29tcGFyYXRvci5jb21wYXJlKCBXcml0YWJsZXMuZ2V0Qnl0ZXMocm93QSksCisgICAgICBXcml0YWJsZXMuZ2V0Qnl0ZXMocm93QikpIDwgMCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgbWV0YWNvbXBhcmlzb25zKGZpbmFsIEhTdG9yZUtleS5IU3RvcmVLZXlDb21wYXJhdG9yIGMpIHsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShuZXcgSFN0b3JlS2V5KCIuTUVUQS4sYSwsMCwxIiksCisgICAgICBuZXcgSFN0b3JlS2V5KCIuTUVUQS4sYSwsMCwxIikpID09IDApOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBIU3RvcmVLZXkoIi5NRVRBLixhLCwwLDEiKSwKKyAgICAgIG5ldyBIU3RvcmVLZXkoIi5NRVRBLixhLCwwLDIiKSkgPCAwKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShuZXcgSFN0b3JlS2V5KCIuTUVUQS4sYSwsMCwyIiksCisgICAgICBuZXcgSFN0b3JlS2V5KCIuTUVUQS4sYSwsMCwxIikpID4gMCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgY29tcGFyaXNvbnMoZmluYWwgSFN0b3JlS2V5LkhTdG9yZUtleUNvbXBhcmF0b3IgYykgeworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBIU3RvcmVLZXkoIi5NRVRBLiwsMSIpLAorICAgICAgbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwxIikpID09IDApOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBIU3RvcmVLZXkoIi5NRVRBLiwsMSIpLAorICAgICAgbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwyIikpIDwgMCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUobmV3IEhTdG9yZUtleSgiLk1FVEEuLCwyIiksCisgICAgICBuZXcgSFN0b3JlS2V5KCIuTUVUQS4sLDEiKSkgPiAwKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgdm9pZCB0ZXN0QmluYXJ5S2V5cygpIHRocm93cyBFeGNlcHRpb24geworCVNldDxIU3RvcmVLZXk+IHNldCA9IG5ldyBUcmVlU2V0PEhTdG9yZUtleT4obmV3IEhTdG9yZUtleS5IU3RvcmVLZXlDb21wYXJhdG9yKCkpOworCUhTdG9yZUtleSBbXSBrZXlzID0ge25ldyBIU3RvcmVLZXkoImFhYWFhLFx1MDAwMFx1MDAwMCwyIiwgZ2V0TmFtZSgpLCAyKSwKKwkgIG5ldyBIU3RvcmVLZXkoImFhYWFhLFx1MDAwMSwzIiwgZ2V0TmFtZSgpLCAzKSwKKwkgIG5ldyBIU3RvcmVLZXkoImFhYWFhLCwxIiwgZ2V0TmFtZSgpLCAxKSwKKwkgIG5ldyBIU3RvcmVLZXkoImFhYWFhLFx1MTAwMCw1IiwgZ2V0TmFtZSgpLCA1KSwKKwkgIG5ldyBIU3RvcmVLZXkoImFhYWFhLGEsNCIsIGdldE5hbWUoKSwgNCksCisgICAgbmV3IEhTdG9yZUtleSgiYSxhLDAiLCBnZXROYW1lKCksIDApLAorCX07CisJLy8gQWRkIHRvIHNldCB3aXRoIGJhZCBjb21wYXJhdG9yCisJZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisJICBzZXQuYWRkKGtleXNbaV0pOworCX0KKwkvLyBUaGlzIHdpbGwgb3V0cHV0IHRoZSBrZXlzIGluY29ycmVjdGx5LgorCWJvb2xlYW4gYXNzZXJ0aW9uID0gZmFsc2U7CisJaW50IGNvdW50ID0gMDsKKwl0cnkgeworICAgICAgZm9yIChIU3RvcmVLZXkgazogc2V0KSB7CisgICAgICAgIGFzc2VydFRydWUoY291bnQrKyA9PSBrLmdldFRpbWVzdGFtcCgpKTsKKyAgICAgIH0KKwl9IGNhdGNoIChqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3IgZSkgeworCSAgLy8gRXhwZWN0ZWQKKwkgIGFzc2VydGlvbiA9IHRydWU7CisJfQorCWFzc2VydFRydWUoYXNzZXJ0aW9uKTsKKwkvLyBNYWtlIHNldCB3aXRoIGdvb2QgY29tcGFyYXRvcgorCXNldCA9IG5ldyBUcmVlU2V0PEhTdG9yZUtleT4obmV3IEhTdG9yZUtleS5IU3RvcmVLZXlNZXRhQ29tcGFyYXRvcigpKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHNldC5hZGQoa2V5c1tpXSk7CisgICAgfQorICAgIGNvdW50ID0gMDsKKyAgICBmb3IgKEhTdG9yZUtleSBrOiBzZXQpIHsKKyAgICAgIGFzc2VydFRydWUoY291bnQrKyA9PSBrLmdldFRpbWVzdGFtcCgpKTsKKyAgICB9CisgICAgLy8gTWFrZSB1cCAtUk9PVC0gdGFibGUga2V5cy4KKyAgICBIU3RvcmVLZXkgW10gcm9vdEtleXMgPSB7CisgICAgICAgIG5ldyBIU3RvcmVLZXkoIi5NRVRBLixhYWFhYSxcdTAwMDBcdTAwMDAsMCwyIiwgZ2V0TmFtZSgpLCAyKSwKKyAgICAgICAgbmV3IEhTdG9yZUtleSgiLk1FVEEuLGFhYWFhLFx1MDAwMSwwLDMiLCBnZXROYW1lKCksIDMpLAorICAgICAgICBuZXcgSFN0b3JlS2V5KCIuTUVUQS4sYWFhYWEsLDAsMSIsIGdldE5hbWUoKSwgMSksCisgICAgICAgIG5ldyBIU3RvcmVLZXkoIi5NRVRBLixhYWFhYSxcdTEwMDAsMCw1IiwgZ2V0TmFtZSgpLCA1KSwKKyAgICAgICAgbmV3IEhTdG9yZUtleSgiLk1FVEEuLGFhYWFhLGEsMCw0IiwgZ2V0TmFtZSgpLCA0KSwKKyAgICAgICAgbmV3IEhTdG9yZUtleSgiLk1FVEEuLCwwIiwgZ2V0TmFtZSgpLCAwKSwKKyAgICAgIH07CisgICAgLy8gVGhpcyB3aWxsIG91dHB1dCB0aGUga2V5cyBpbmNvcnJlY3RseS4KKyAgICBzZXQgPSBuZXcgVHJlZVNldDxIU3RvcmVLZXk+KG5ldyBIU3RvcmVLZXkuSFN0b3JlS2V5TWV0YUNvbXBhcmF0b3IoKSk7CisgICAgLy8gQWRkIHRvIHNldCB3aXRoIGJhZCBjb21wYXJhdG9yCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICBzZXQuYWRkKHJvb3RLZXlzW2ldKTsKKyAgICB9CisgICAgYXNzZXJ0aW9uID0gZmFsc2U7CisgICAgY291bnQgPSAwOworICAgIHRyeSB7CisgICAgICBmb3IgKEhTdG9yZUtleSBrOiBzZXQpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb3VudCsrID09IGsuZ2V0VGltZXN0YW1wKCkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvciBlKSB7CisgICAgICAvLyBFeHBlY3RlZAorICAgICAgYXNzZXJ0aW9uID0gdHJ1ZTsKKyAgICB9CisgICAgLy8gTm93IHdpdGggcmlnaHQgY29tcGFyYXRvcgorICAgIHNldCA9IG5ldyBUcmVlU2V0PEhTdG9yZUtleT4obmV3IEhTdG9yZUtleS5IU3RvcmVLZXlSb290Q29tcGFyYXRvcigpKTsKKyAgICAvLyBBZGQgdG8gc2V0IHdpdGggYmFkIGNvbXBhcmF0b3IKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHNldC5hZGQocm9vdEtleXNbaV0pOworICAgIH0KKyAgICBjb3VudCA9IDA7CisgICAgZm9yIChIU3RvcmVLZXkgazogc2V0KSB7CisgICAgICBhc3NlcnRUcnVlKGNvdW50KysgPT0gay5nZXRUaW1lc3RhbXAoKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhTdG9yZUtleSBoc2sgPSBuZXcgSFN0b3JlS2V5KGdldE5hbWUoKSwgZ2V0TmFtZSgpLCAxMjMpOworICAgIGJ5dGUgW10gYiA9IGhzay5nZXRCeXRlcygpOworICAgIEhTdG9yZUtleSBoc2syID0gSFN0b3JlS2V5LmNyZWF0ZShiKTsKKyAgICBhc3NlcnRUcnVlKGhzay5lcXVhbHMoaHNrMikpOworICAgIC8vIFRlc3QgZ2V0Qnl0ZXMgd2l0aCBlbXB0eSBjb2x1bW4KKyAgICBoc2sgPSBuZXcgSFN0b3JlS2V5KGdldE5hbWUoKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoaHNrLmdldEJ5dGVzKCksCisgICAgICBIU3RvcmVLZXkuZ2V0Qnl0ZXMoQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpLCBudWxsLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEdldEJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIEhTdG9yZUtleSBoc2sgPSBuZXcgSFN0b3JlS2V5KCJvbmUiLCAidHdvIiwgbm93KTsKKyAgICBieXRlIFtdIHdyaXRhYmxlc0J5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKGhzayk7CisgICAgYnl0ZSBbXSBzZWxmU2VyaWFsaXphdGlvbkJ5dGVzID0gaHNrLmdldEJ5dGVzKCk7CisgICAgQnl0ZXMuZXF1YWxzKHdyaXRhYmxlc0J5dGVzLCBzZWxmU2VyaWFsaXphdGlvbkJ5dGVzKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RCeXRlQnVmZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgbG9uZyB0cyA9IDEyMzsKKyAgICBmaW5hbCBieXRlIFtdIHJvdyA9IEJ5dGVzLnRvQnl0ZXMoInJvdyIpOworICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uID0gQnl0ZXMudG9CeXRlcygiY29sdW1uIik7CisgICAgSFN0b3JlS2V5IGhzayA9IG5ldyBIU3RvcmVLZXkocm93LCBjb2x1bW4sIHRzKTsKKyAgICBCeXRlQnVmZmVyIGJiID0gQnl0ZUJ1ZmZlci53cmFwKGhzay5nZXRCeXRlcygpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3csIEhTdG9yZUtleS5nZXRSb3coYmIpKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoY29sdW1uLCBIU3RvcmVLZXkuZ2V0Q29sdW1uKGJiKSkpOworICAgIGFzc2VydEVxdWFscyh0cywgSFN0b3JlS2V5LmdldFRpbWVzdGFtcChiYikpOworICB9CisKKyAgLyoqCisgICAqIFRlc3QgdGhlIGJ5dGUgY29tcGFyYXRvciB3b3JrcyBzYW1lIGFzIHRoZSBvYmplY3QgY29tcGFyYXRvci4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RSYXdDb21wYXJhdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGJ5dGUgW10gYSA9IEJ5dGVzLnRvQnl0ZXMoImEiKTsKKyAgICBIU3RvcmVLZXkgcGFzdCA9IG5ldyBIU3RvcmVLZXkoYSwgYSwgdGltZXN0YW1wIC0gMTApOworICAgIGJ5dGUgW10gcGFzdEJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKHBhc3QpOworICAgIEhTdG9yZUtleSBub3cgPSBuZXcgSFN0b3JlS2V5KGEsIGEsIHRpbWVzdGFtcCk7CisgICAgYnl0ZSBbXSBub3dCeXRlcyA9IFdyaXRhYmxlcy5nZXRCeXRlcyhub3cpOworICAgIEhTdG9yZUtleSBmdXR1cmUgPSBuZXcgSFN0b3JlS2V5KGEsIGEsIHRpbWVzdGFtcCArIDEwKTsKKyAgICBieXRlIFtdIGZ1dHVyZUJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKGZ1dHVyZSk7CisgICAgSFN0b3JlS2V5LlN0b3JlS2V5Q29tcGFyYXRvciBjb21wYXJhdG9yID0KKyAgICAgIG5ldyBIU3RvcmVLZXkuU3RvcmVLZXlDb21wYXJhdG9yKCk7CisgICAgYXNzZXJ0VHJ1ZShwYXN0LmNvbXBhcmVUbyhub3cpID4gMCk7CisgICAgYXNzZXJ0VHJ1ZShjb21wYXJhdG9yLmNvbXBhcmUocGFzdEJ5dGVzLCBub3dCeXRlcykgPiAwKTsKKyAgICBhc3NlcnRUcnVlKG5vdy5jb21wYXJlVG8obm93KSA9PSAwKTsKKyAgICBhc3NlcnRUcnVlKGNvbXBhcmF0b3IuY29tcGFyZShub3dCeXRlcywgbm93Qnl0ZXMpID09IDApOworICAgIGFzc2VydFRydWUoZnV0dXJlLmNvbXBhcmVUbyhub3cpIDwgMCk7CisgICAgYXNzZXJ0VHJ1ZShjb21wYXJhdG9yLmNvbXBhcmUoZnV0dXJlQnl0ZXMsIG5vd0J5dGVzKSA8IDApOworICAgIC8vIENoZWNrIHRoYXQgZW1wdHkgY29sdW1uIGNvbWVzIGJlZm9yZSBvbmUgd2l0aCBhIGNvbHVtbgorICAgIEhTdG9yZUtleSBub2NvbHVtbiA9IG5ldyBIU3RvcmVLZXkoYSwgdGltZXN0YW1wKTsKKyAgICBieXRlIFtdIG5vY29sdW1uQnl0ZXMgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMobm9jb2x1bW4pOworICAgIEhTdG9yZUtleSB3aXRoY29sdW1uID0gbmV3IEhTdG9yZUtleShhLCBhLCB0aW1lc3RhbXApOworICAgIGJ5dGUgW10gd2l0aGNvbHVtbkJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKHdpdGhjb2x1bW4pOworICAgIGFzc2VydFRydWUobm9jb2x1bW4uY29tcGFyZVRvKHdpdGhjb2x1bW4pIDwgMCk7CisgICAgYXNzZXJ0VHJ1ZShjb21wYXJhdG9yLmNvbXBhcmUobm9jb2x1bW5CeXRlcywgd2l0aGNvbHVtbkJ5dGVzKSA8IDApOworICAgIC8vIENoZWNrIHRoYXQgZW1wdHkgY29sdW1uIGNvbWVzIGFuZCBMQVRFU1QgY29tZXMgYmVmb3JlIG9uZSB3aXRoIGEgY29sdW1uCisgICAgLy8gYW5kIG9sZCB0aW1lc3RhbXAuCisgICAgbm9jb2x1bW4gPSBuZXcgSFN0b3JlS2V5KGEsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCk7CisgICAgbm9jb2x1bW5CeXRlcyA9IFdyaXRhYmxlcy5nZXRCeXRlcyhub2NvbHVtbik7CisgICAgd2l0aGNvbHVtbiA9IG5ldyBIU3RvcmVLZXkoYSwgYSwgdGltZXN0YW1wKTsKKyAgICB3aXRoY29sdW1uQnl0ZXMgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMod2l0aGNvbHVtbik7CisgICAgYXNzZXJ0VHJ1ZShub2NvbHVtbi5jb21wYXJlVG8od2l0aGNvbHVtbikgPCAwKTsKKyAgICBhc3NlcnRUcnVlKGNvbXBhcmF0b3IuY29tcGFyZShub2NvbHVtbkJ5dGVzLCB3aXRoY29sdW1uQnl0ZXMpIDwgMCk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0SW5mb1NlcnZlcnMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RJbmZvU2VydmVycy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxMWFjNDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0SW5mb1NlcnZlcnMuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworCisvKioKKyAqIFRlc3RpbmcsIGluZm8gc2VydmVycyBhcmUgZGlzYWJsZWQuICBUaGlzIHRlc3QgZW5hYmxlcyB0aGVuIGFuZCBjaGVja3MgdGhhdAorICogdGhleSBzZXJ2ZSBwYWdlcy4KKyAqLworcHVibGljIGNsYXNzIFRlc3RJbmZvU2VydmVycyBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0SW5mb1NlcnZlcnMuY2xhc3MpOworICAKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHByZUhCYXNlQ2x1c3RlclNldHVwKCkgeworICAgIC8vIEJyaW5nIHVwIGluZm8gc2VydmVycyBvbiAnb2RkJyBwb3J0IG51bWJlcnMgaW4gY2FzZSB0aGUgdGVzdCBpcyBub3QKKyAgICAvLyBzb3VyY2luZyB0aGUgc3JjL3Rlc3QvaGJhc2UtZGVmYXVsdC54bWwuCisgICAgY29uZi5zZXRJbnQoImhiYXNlLm1hc3Rlci5pbmZvLnBvcnQiLCA2MDAxMSk7CisgICAgY29uZi5zZXRJbnQoImhiYXNlLnJlZ2lvbnNlcnZlci5pbmZvLnBvcnQiLCA2MDAzMSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEluZm9TZXJ2ZXJzQXJlVXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBnaXZlIHRoZSBjbHVzdGVyIHRpbWUgdG8gc3RhcnQgdXAKKyAgICBuZXcgSFRhYmxlKGNvbmYsICIuTUVUQS4iKTsKKyAgICBpbnQgcG9ydCA9IGNsdXN0ZXIuZ2V0TWFzdGVyKCkuZ2V0SW5mb1NlcnZlcigpLmdldFBvcnQoKTsKKyAgICBhc3NlcnRIYXNFeHBlY3RlZENvbnRlbnQobmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdDoiICsgcG9ydCArCisgICAgICAiL2luZGV4Lmh0bWwiKSwgIm1hc3RlciIpOworICAgIHBvcnQgPSBjbHVzdGVyLmdldFJlZ2lvblRocmVhZHMoKS5nZXQoMCkuZ2V0UmVnaW9uU2VydmVyKCkuCisgICAgICBnZXRJbmZvU2VydmVyKCkuZ2V0UG9ydCgpOworICAgIGFzc2VydEhhc0V4cGVjdGVkQ29udGVudChuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0OiIgKyBwb3J0ICsKKyAgICAgICIvaW5kZXguaHRtbCIpLCAicmVnaW9uc2VydmVyIik7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBhc3NlcnRIYXNFeHBlY3RlZENvbnRlbnQoZmluYWwgVVJMIHUsIGZpbmFsIFN0cmluZyBleHBlY3RlZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMT0cuaW5mbygiVGVzdGluZyAiICsgdS50b1N0cmluZygpICsgIiBoYXMgIiArIGV4cGVjdGVkKTsKKyAgICBqYXZhLm5ldC5VUkxDb25uZWN0aW9uIGMgPSB1Lm9wZW5Db25uZWN0aW9uKCk7CisgICAgYy5jb25uZWN0KCk7CisgICAgYXNzZXJ0VHJ1ZShjLmdldENvbnRlbnRMZW5ndGgoKSA+IDApOworICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcihjLmdldENvbnRlbnRMZW5ndGgoKSk7CisgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBiaXMgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShjLmdldElucHV0U3RyZWFtKCkpOworICAgIGJ5dGUgW10gYnl0ZXMgPSBuZXcgYnl0ZVsxMDI0XTsKKyAgICBmb3IgKGludCByZWFkID0gLTE7IChyZWFkID0gYmlzLnJlYWQoYnl0ZXMpKSAhPSAtMTspIHsKKyAgICAgIHNiLmFwcGVuZChuZXcgU3RyaW5nKGJ5dGVzLCAwLCByZWFkKSk7CisgICAgfQorICAgIGJpcy5jbG9zZSgpOworICAgIFN0cmluZyBjb250ZW50ID0gc2IudG9TdHJpbmcoKTsKKyAgICBhc3NlcnRUcnVlKGNvbnRlbnQuY29udGFpbnMoZXhwZWN0ZWQpKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RLZXlWYWx1ZS5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdEtleVZhbHVlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYxZjRmNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RLZXlWYWx1ZS5qYXZhCkBAIC0wLDAgKzEsMjYzIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlLktWQ29tcGFyYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgVGVzdEtleVZhbHVlIGV4dGVuZHMgVGVzdENhc2UgeworICBwcml2YXRlIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKworICBwdWJsaWMgdm9pZCB0ZXN0Q29sdW1uQ29tcGFyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbmFsIGJ5dGUgW10gYSA9IEJ5dGVzLnRvQnl0ZXMoImFhYSIpOworICAgIGJ5dGUgW10gY29sdW1uMSA9IEJ5dGVzLnRvQnl0ZXMoImFiYzpkZWYiKTsKKyAgICBieXRlIFtdIGNvbHVtbjIgPSBCeXRlcy50b0J5dGVzKCJhYmNkOmVmIik7CisgICAgS2V5VmFsdWUgYWFhID0gbmV3IEtleVZhbHVlKGEsIGNvbHVtbjEsIGEpOworICAgIGFzc2VydEZhbHNlKEtleVZhbHVlLkNPTVBBUkFUT1IuCisgICAgICBjb21wYXJlQ29sdW1ucyhhYWEsIGNvbHVtbjIsIDAsIGNvbHVtbjIubGVuZ3RoLCA0KSA9PSAwKTsKKyAgICBjb2x1bW4xID0gQnl0ZXMudG9CeXRlcygiYWJjZDoiKTsKKyAgICBhYWEgPSBuZXcgS2V5VmFsdWUoYSwgY29sdW1uMSwgYSk7CisgICAgYXNzZXJ0RmFsc2UoS2V5VmFsdWUuQ09NUEFSQVRPUi4KKyAgICAgIGNvbXBhcmVDb2x1bW5zKGFhYSwgY29sdW1uMSwgMCwgY29sdW1uMS5sZW5ndGgsIDQpID09IDApOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJhc2ljcygpIHRocm93cyBFeGNlcHRpb24geworICAgIExPRy5pbmZvKCJMT1dLRVk6ICIgKyBLZXlWYWx1ZS5MT1dFU1RLRVkudG9TdHJpbmcoKSk7CisgICAgY2hlY2soQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpLAorICAgICAgQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkgKyAiOiIgKyBnZXROYW1lKCkpLCAxLAorICAgICAgQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpKTsKKyAgICAvLyBUZXN0IGVtcHR5IHZhbHVlIGFuZCBlbXB0eSBjb2x1bW4gLS0gYm90aCBzaG91bGQgd29yay4KKyAgICBjaGVjayhCeXRlcy50b0J5dGVzKGdldE5hbWUoKSksIG51bGwsIDEsIG51bGwpOworICAgIGNoZWNrKEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwgbnVsbCwgMSwgbnVsbCk7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBjaGVjayhmaW5hbCBieXRlIFtdIHJvdywgZmluYWwgYnl0ZSBbXSBjb2x1bW4sCisgICAgZmluYWwgbG9uZyB0aW1lc3RhbXAsIGZpbmFsIGJ5dGUgW10gdmFsdWUpIHsKKyAgICBLZXlWYWx1ZSBrdiA9IG5ldyBLZXlWYWx1ZShyb3csIGNvbHVtbiwgdGltZXN0YW1wLCB2YWx1ZSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5jb21wYXJlVG8oa3YuZ2V0Um93KCksIHJvdykgPT0gMCk7CisgICAgaWYgKGNvbHVtbiAhPSBudWxsICYmIGNvbHVtbi5sZW5ndGggPiAwKSB7CisgICAgICBpbnQgaW5kZXggPSBLZXlWYWx1ZS5nZXRGYW1pbHlEZWxpbWl0ZXJJbmRleChjb2x1bW4sIDAsIGNvbHVtbi5sZW5ndGgpOworICAgICAgYnl0ZSBbXSBmYW1pbHkgPSBuZXcgYnl0ZSBbaW5kZXhdOworICAgICAgU3lzdGVtLmFycmF5Y29weShjb2x1bW4sIDAsIGZhbWlseSwgMCwgZmFtaWx5Lmxlbmd0aCk7CisgICAgICBhc3NlcnRUcnVlKGt2Lm1hdGNoaW5nRmFtaWx5KGZhbWlseSkpOworICAgIH0KKyAgICAvLyBDYWxsIHRvU3RyaW5nIHRvIG1ha2Ugc3VyZSBpdCB3b3Jrcy4KKyAgICBMT0cuaW5mbyhrdi50b1N0cmluZygpKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFBsYWluQ29tcGFyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbmFsIGJ5dGUgW10gYSA9IEJ5dGVzLnRvQnl0ZXMoImFhYSIpOworICAgIGZpbmFsIGJ5dGUgW10gYiA9IEJ5dGVzLnRvQnl0ZXMoImJiYiIpOworICAgIGZpbmFsIGJ5dGUgW10gY29sdW1uID0gQnl0ZXMudG9CeXRlcygiY29sOnVtbiIpOworICAgIEtleVZhbHVlIGFhYSA9IG5ldyBLZXlWYWx1ZShhLCBjb2x1bW4sIGEpOworICAgIEtleVZhbHVlIGJiYiA9IG5ldyBLZXlWYWx1ZShiLCBjb2x1bW4sIGIpOworICAgIGJ5dGUgW10ga2V5YWJiID0gYWFhLmdldEtleSgpOworICAgIGJ5dGUgW10ga2V5YmJiID0gYmJiLmdldEtleSgpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGFhYSwgYmJiKSA8IDApOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuS0VZX0NPTVBBUkFUT1IuY29tcGFyZShrZXlhYmIsIDAsIGtleWFiYi5sZW5ndGgsIGtleWJiYiwKKyAgICAgIDAsIGtleWJiYi5sZW5ndGgpIDwgMCk7CisgICAgYXNzZXJ0VHJ1ZShLZXlWYWx1ZS5DT01QQVJBVE9SLmNvbXBhcmUoYmJiLCBhYWEpID4gMCk7CisgICAgYXNzZXJ0VHJ1ZShLZXlWYWx1ZS5LRVlfQ09NUEFSQVRPUi5jb21wYXJlKGtleWJiYiwgMCwga2V5YmJiLmxlbmd0aCwga2V5YWJiLAorICAgICAgMCwga2V5YWJiLmxlbmd0aCkgPiAwKTsKKyAgICAvLyBDb21wYXJlIGJyZWFrcyBpZiBwYXNzZWQgc2FtZSBCeXRlQnVmZmVyIGFzIGJvdGggbGVmdCBhbmQgcmlnaHQgYXJndW1lbnRzLgorICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGJiYiwgYmJiKSA9PSAwKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLktFWV9DT01QQVJBVE9SLmNvbXBhcmUoa2V5YmJiLCAwLCBrZXliYmIubGVuZ3RoLCBrZXliYmIsCisgICAgICAwLCBrZXliYmIubGVuZ3RoKSA9PSAwKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLkNPTVBBUkFUT1IuY29tcGFyZShhYWEsIGFhYSkgPT0gMCk7CisgICAgYXNzZXJ0VHJ1ZShLZXlWYWx1ZS5LRVlfQ09NUEFSQVRPUi5jb21wYXJlKGtleWFiYiwgMCwga2V5YWJiLmxlbmd0aCwga2V5YWJiLAorICAgICAgMCwga2V5YWJiLmxlbmd0aCkgPT0gMCk7CisgICAgLy8gRG8gY29tcGFyZSB3aXRoIGRpZmZlcmVudCB0aW1lc3RhbXBzLgorICAgIGFhYSA9IG5ldyBLZXlWYWx1ZShhLCBjb2x1bW4sIDEsIGEpOworICAgIGJiYiA9IG5ldyBLZXlWYWx1ZShhLCBjb2x1bW4sIDIsIGEpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGFhYSwgYmJiKSA+IDApOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGJiYiwgYWFhKSA8IDApOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGFhYSwgYWFhKSA9PSAwKTsKKyAgICAvLyBEbyBjb21wYXJlIHdpdGggZGlmZmVyZW50IHR5cGVzLiAgSGlnaGVyIG51bWJlcmVkIHR5cGVzIC0tIERlbGV0ZQorICAgIC8vIHNob3VsZCBzb3J0IGFoZWFkIG9mIGxvd2VyIG51bWJlcnM7IGkuZS4gUHV0CisgICAgYWFhID0gbmV3IEtleVZhbHVlKGEsIGNvbHVtbiwgMSwgS2V5VmFsdWUuVHlwZS5EZWxldGUsIGEpOworICAgIGJiYiA9IG5ldyBLZXlWYWx1ZShhLCBjb2x1bW4sIDEsIGEpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGFhYSwgYmJiKSA8IDApOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGJiYiwgYWFhKSA+IDApOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlKGFhYSwgYWFhKSA9PSAwKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNb3JlQ29tcGFyaXNvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBSb290IGNvbXBhcmVzCisgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBLZXlWYWx1ZSBhID0gbmV3IEtleVZhbHVlKCIuTUVUQS4sLDk5OTk5OTk5OTk5OTk5Iiwgbm93KTsKKyAgICBLZXlWYWx1ZSBiID0gbmV3IEtleVZhbHVlKCIuTUVUQS4sLDEiLCBub3cpOworICAgIEtWQ29tcGFyYXRvciBjID0gbmV3IEtleVZhbHVlLlJvb3RDb21wYXJhdG9yKCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUoYiwgYSkgPCAwKTsKKyAgICBLZXlWYWx1ZSBhYSA9IG5ldyBLZXlWYWx1ZSgiLk1FVEEuLCwxIiwgbm93KTsKKyAgICBLZXlWYWx1ZSBiYiA9IG5ldyBLZXlWYWx1ZSgiLk1FVEEuLCwxIiwgImluZm86cmVnaW9uaW5mbyIsCisgICAgICAxMjM1OTQzNDU0NjAyTCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUoYWEsIGJiKSA8IDApOworICAgIAorICAgIC8vIE1ldGEgY29tcGFyZXMKKyAgICBLZXlWYWx1ZSBhYWEgPQorICAgICAgbmV3IEtleVZhbHVlKCJUZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMscm93XzA1MDAsMTIzNjAyMDE0NTUwMiIsIG5vdyk7CisgICAgS2V5VmFsdWUgYmJiID0gbmV3IEtleVZhbHVlKCJUZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMsLDk5OTk5OTk5OTk5OTk5IiwKKyAgICAgIG5vdyk7CisgICAgYyA9IG5ldyBLZXlWYWx1ZS5NZXRhQ29tcGFyYXRvcigpOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKGJiYiwgYWFhKSA8IDApOworICAgIAorICAgIEtleVZhbHVlIGFhYWEgPSBuZXcgS2V5VmFsdWUoIlRlc3RTY2FuTXVsdGlwbGVWZXJzaW9ucywsMTIzNjAyMzk5NjY1NiIsCisgICAgICAiaW5mbzpyZWdpb25pbmZvIiwgMTIzNjAyNDM5NjI3MUwpOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKGFhYWEsIGJiYikgPCAwKTsKKyAgICAKKyAgICBLZXlWYWx1ZSB4ID0gbmV3IEtleVZhbHVlKCJUZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMscm93XzA1MDAsMTIzNjAzNDU3NDE2MiIsCisgICAgICAiIiwgOTIyMzM3MjAzNjg1NDc3NTgwN0wpOworICAgIEtleVZhbHVlIHkgPSBuZXcgS2V5VmFsdWUoIlRlc3RTY2FuTXVsdGlwbGVWZXJzaW9ucyxyb3dfMDUwMCwxMjM2MDM0NTc0MTYyIiwKKyAgICAgICJpbmZvOnJlZ2lvbmluZm8iLCAxMjM2MDM0NTc0OTEyTCk7CisgICAgYXNzZXJ0VHJ1ZShjLmNvbXBhcmUoeCwgeSkgPCAwKTsKKyAgICBjb21wYXJpc29ucyhuZXcgS2V5VmFsdWUuTWV0YUNvbXBhcmF0b3IoKSk7CisgICAgY29tcGFyaXNvbnMobmV3IEtleVZhbHVlLktWQ29tcGFyYXRvcigpKTsKKyAgICBtZXRhY29tcGFyaXNvbnMobmV3IEtleVZhbHVlLlJvb3RDb21wYXJhdG9yKCkpOworICAgIG1ldGFjb21wYXJpc29ucyhuZXcgS2V5VmFsdWUuTWV0YUNvbXBhcmF0b3IoKSk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgY2FzZXMgd2hlcmUgcm93cyBrZXlzIGhhdmUgY2hhcmFjdGVycyBiZWxvdyB0aGUgJywnLgorICAgKiBTZWUgSEJBU0UtODMyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0S2V5VmFsdWVCb3JkZXJDYXNlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gJSBzb3J0cyBiZWZvcmUgLCBzbyBpZiB3ZSBkb24ndCBkbyBzcGVjaWFsIGNvbXBhcmF0b3IsIHJvd0Igd291bGQKKyAgICAvLyBjb21lIGJlZm9yZSByb3dBLgorICAgIEtleVZhbHVlIHJvd0EgPSBuZXcgS2V5VmFsdWUoInRlc3R0YWJsZSx3d3cuaGJhc2Uub3JnLywxMjM0IiwKKyAgICAgICIiLCBMb25nLk1BWF9WQUxVRSk7CisgICAgS2V5VmFsdWUgcm93QiA9IG5ldyBLZXlWYWx1ZSgidGVzdHRhYmxlLHd3dy5oYmFzZS5vcmcvJTIwLDk5OTk5IiwKKyAgICAgICIiLCBMb25nLk1BWF9WQUxVRSk7CisgICAgYXNzZXJ0VHJ1ZShLZXlWYWx1ZS5NRVRBX0NPTVBBUkFUT1IuY29tcGFyZShyb3dBLCByb3dCKSA8IDApOworCisgICAgcm93QSA9IG5ldyBLZXlWYWx1ZSgidGVzdHRhYmxlLCwxMjM0IiwgIiIsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICByb3dCID0gbmV3IEtleVZhbHVlKCJ0ZXN0dGFibGUsJHd3dy5oYmFzZS5vcmcvLDk5OTk5IiwgIiIsIExvbmcuTUFYX1ZBTFVFKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLk1FVEFfQ09NUEFSQVRPUi5jb21wYXJlKHJvd0EsIHJvd0IpIDwgMCk7CisKKyAgICByb3dBID0gbmV3IEtleVZhbHVlKCIuTUVUQS4sdGVzdHRhYmxlLHd3dy5oYmFzZS5vcmcvLDEyMzQsNDMyMSIsICIiLAorICAgICAgTG9uZy5NQVhfVkFMVUUpOworICAgIHJvd0IgPSBuZXcgS2V5VmFsdWUoIi5NRVRBLix0ZXN0dGFibGUsd3d3LmhiYXNlLm9yZy8lMjAsOTk5OTksOTk5OTkiLCAiIiwKKyAgICAgIExvbmcuTUFYX1ZBTFVFKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLlJPT1RfQ09NUEFSQVRPUi5jb21wYXJlKHJvd0EsIHJvd0IpIDwgMCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgbWV0YWNvbXBhcmlzb25zKGZpbmFsIEtleVZhbHVlLk1ldGFDb21wYXJhdG9yIGMpIHsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBLZXlWYWx1ZSgiLk1FVEEuLGEsLDAsMSIsIG5vdyksCisgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLixhLCwwLDEiLCBub3cpKSA9PSAwKTsKKyAgICBLZXlWYWx1ZSBhID0gbmV3IEtleVZhbHVlKCIuTUVUQS4sYSwsMCwxIiwgbm93KTsKKyAgICBLZXlWYWx1ZSBiID0gbmV3IEtleVZhbHVlKCIuTUVUQS4sYSwsMCwyIiwgbm93KTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShhLCBiKSA8IDApOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBLZXlWYWx1ZSgiLk1FVEEuLGEsLDAsMiIsIG5vdyksCisgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLixhLCwwLDEiLCBub3cpKSA+IDApOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNvbXBhcmlzb25zKGZpbmFsIEtleVZhbHVlLktWQ29tcGFyYXRvciBjKSB7CisgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShuZXcgS2V5VmFsdWUoIi5NRVRBLiwsMSIsIG5vdyksCisgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLiwsMSIsIG5vdykpID09IDApOworICAgIGFzc2VydFRydWUoYy5jb21wYXJlKG5ldyBLZXlWYWx1ZSgiLk1FVEEuLCwxIiwgbm93KSwKKyAgICAgIG5ldyBLZXlWYWx1ZSgiLk1FVEEuLCwyIiwgbm93KSkgPCAwKTsKKyAgICBhc3NlcnRUcnVlKGMuY29tcGFyZShuZXcgS2V5VmFsdWUoIi5NRVRBLiwsMiIsIG5vdyksCisgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLiwsMSIsIG5vdykpID4gMCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QmluYXJ5S2V5cygpIHRocm93cyBFeGNlcHRpb24geworICAgIFNldDxLZXlWYWx1ZT4gc2V0ID0gbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KEtleVZhbHVlLkNPTVBBUkFUT1IpOworICAgIFN0cmluZyBjb2x1bW4gPSAiY29sOnVtbiI7CisgICAgS2V5VmFsdWUgW10ga2V5cyA9IHtuZXcgS2V5VmFsdWUoImFhYWFhLFx1MDAwMFx1MDAwMCwyIiwgY29sdW1uLCAyKSwKKyAgICAgIG5ldyBLZXlWYWx1ZSgiYWFhYWEsXHUwMDAxLDMiLCBjb2x1bW4sIDMpLAorICAgICAgbmV3IEtleVZhbHVlKCJhYWFhYSwsMSIsIGNvbHVtbiwgMSksCisgICAgICBuZXcgS2V5VmFsdWUoImFhYWFhLFx1MTAwMCw1IiwgY29sdW1uLCA1KSwKKyAgICAgIG5ldyBLZXlWYWx1ZSgiYWFhYWEsYSw0IiwgY29sdW1uLCA0KSwKKyAgICAgIG5ldyBLZXlWYWx1ZSgiYSxhLDAiLCBjb2x1bW4sIDApLAorICAgIH07CisgICAgLy8gQWRkIHRvIHNldCB3aXRoIGJhZCBjb21wYXJhdG9yCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICBzZXQuYWRkKGtleXNbaV0pOworICAgIH0KKyAgICAvLyBUaGlzIHdpbGwgb3V0cHV0IHRoZSBrZXlzIGluY29ycmVjdGx5LgorICAgIGJvb2xlYW4gYXNzZXJ0aW9uID0gZmFsc2U7CisgICAgaW50IGNvdW50ID0gMDsKKyAgICB0cnkgeworICAgICAgZm9yIChLZXlWYWx1ZSBrOiBzZXQpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjb3VudCsrID09IGsuZ2V0VGltZXN0YW1wKCkpOworICAgICAgfQorICAgIH0gY2F0Y2ggKGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvciBlKSB7CisgICAgICAvLyBFeHBlY3RlZAorICAgICAgYXNzZXJ0aW9uID0gdHJ1ZTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShhc3NlcnRpb24pOworICAgIC8vIE1ha2Ugc2V0IHdpdGggZ29vZCBjb21wYXJhdG9yCisgICAgc2V0ID0gbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KG5ldyBLZXlWYWx1ZS5NZXRhQ29tcGFyYXRvcigpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHNldC5hZGQoa2V5c1tpXSk7CisgICAgfQorICAgIGNvdW50ID0gMDsKKyAgICBmb3IgKEtleVZhbHVlIGs6IHNldCkgeworICAgICAgYXNzZXJ0VHJ1ZShjb3VudCsrID09IGsuZ2V0VGltZXN0YW1wKCkpOworICAgIH0KKyAgICAvLyBNYWtlIHVwIC1ST09ULSB0YWJsZSBrZXlzLgorICAgIEtleVZhbHVlIFtdIHJvb3RLZXlzID0geworICAgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLixhYWFhYSxcdTAwMDBcdTAwMDAsMCwyIiwgY29sdW1uLCAyKSwKKyAgICAgICAgbmV3IEtleVZhbHVlKCIuTUVUQS4sYWFhYWEsXHUwMDAxLDAsMyIsIGNvbHVtbiwgMyksCisgICAgICAgIG5ldyBLZXlWYWx1ZSgiLk1FVEEuLGFhYWFhLCwwLDEiLCBjb2x1bW4sIDEpLAorICAgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLixhYWFhYSxcdTEwMDAsMCw1IiwgY29sdW1uLCA1KSwKKyAgICAgICAgbmV3IEtleVZhbHVlKCIuTUVUQS4sYWFhYWEsYSwwLDQiLCBjb2x1bW4sIDQpLAorICAgICAgICBuZXcgS2V5VmFsdWUoIi5NRVRBLiwsMCIsIGNvbHVtbiwgMCksCisgICAgICB9OworICAgIC8vIFRoaXMgd2lsbCBvdXRwdXQgdGhlIGtleXMgaW5jb3JyZWN0bHkuCisgICAgc2V0ID0gbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KG5ldyBLZXlWYWx1ZS5NZXRhQ29tcGFyYXRvcigpKTsKKyAgICAvLyBBZGQgdG8gc2V0IHdpdGggYmFkIGNvbXBhcmF0b3IKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHNldC5hZGQocm9vdEtleXNbaV0pOworICAgIH0KKyAgICBhc3NlcnRpb24gPSBmYWxzZTsKKyAgICBjb3VudCA9IDA7CisgICAgdHJ5IHsKKyAgICAgIGZvciAoS2V5VmFsdWUgazogc2V0KSB7CisgICAgICAgIGFzc2VydFRydWUoY291bnQrKyA9PSBrLmdldFRpbWVzdGFtcCgpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3IgZSkgeworICAgICAgLy8gRXhwZWN0ZWQKKyAgICAgIGFzc2VydGlvbiA9IHRydWU7CisgICAgfQorICAgIC8vIE5vdyB3aXRoIHJpZ2h0IGNvbXBhcmF0b3IKKyAgICBzZXQgPSBuZXcgVHJlZVNldDxLZXlWYWx1ZT4obmV3IEtleVZhbHVlLlJvb3RDb21wYXJhdG9yKCkpOworICAgIC8vIEFkZCB0byBzZXQgd2l0aCBiYWQgY29tcGFyYXRvcgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgeworICAgICAgc2V0LmFkZChyb290S2V5c1tpXSk7CisgICAgfQorICAgIGNvdW50ID0gMDsKKyAgICBmb3IgKEtleVZhbHVlIGs6IHNldCkgeworICAgICAgYXNzZXJ0VHJ1ZShjb3VudCsrID09IGsuZ2V0VGltZXN0YW1wKCkpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNYXN0ZXJBZG1pbi5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdE1hc3RlckFkbWluLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTlhNmU2ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNYXN0ZXJBZG1pbi5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIHRlc3RzIGFkbWluaXN0cmF0aXZlIGZ1bmN0aW9ucyAqLworcHVibGljIGNsYXNzIFRlc3RNYXN0ZXJBZG1pbiBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTFVNTl9OQU1FID0gQnl0ZXMudG9CeXRlcygiY29sMToiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgSFRhYmxlRGVzY3JpcHRvciB0ZXN0RGVzYzsKKyAgc3RhdGljIHsKKyAgICB0ZXN0RGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0ZXN0YWRtaW4xIik7CisgICAgdGVzdERlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT0xVTU5fTkFNRSkpOworICB9CisgIAorICBwcml2YXRlIEhCYXNlQWRtaW4gYWRtaW47CisKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBUZXN0TWFzdGVyQWRtaW4oKSB7CisgICAgc3VwZXIoKTsKKyAgICBhZG1pbiA9IG51bGw7CisKKyAgICAvLyBNYWtlIHRoZSB0aHJlYWQgd2FrZSBmcmVxdWVuY3kgYSBsaXR0bGUgc2xvd2VyIHNvIG90aGVyIHRocmVhZHMKKyAgICAvLyBjYW4gcnVuCisgICAgY29uZi5zZXRJbnQoImhiYXNlLnNlcnZlci50aHJlYWQud2FrZWZyZXF1ZW5jeSIsIDIwMDApOworICB9CisgIAorICAvKiogQHRocm93cyBFeGNlcHRpb24gKi8KKyAgcHVibGljIHZvaWQgdGVzdE1hc3RlckFkbWluKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICAvLyBBZGQgdGVzdCB0aGF0IGV4Y2VwdGlvbiBpcyB0aHJvd24gaWYgZGVzY3JpcHRvciBpcyB3aXRob3V0IGEgdGFibGUgbmFtZS4KKyAgICAvLyBIQURPT1AtMjE1Ni4KKyAgICBib29sZWFuIGV4Y2VwdGlvbiA9IGZhbHNlOworICAgIHRyeSB7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZShuZXcgSFRhYmxlRGVzY3JpcHRvcigpKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShleGNlcHRpb24pOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKHRlc3REZXNjKTsKKyAgICBMT0cuaW5mbygiVGFibGUgIiArIHRlc3REZXNjLmdldE5hbWVBc1N0cmluZygpICsgIiBjcmVhdGVkIik7CisgICAgYWRtaW4uZGlzYWJsZVRhYmxlKHRlc3REZXNjLmdldE5hbWUoKSk7CisgICAgTE9HLmluZm8oIlRhYmxlICIgKyB0ZXN0RGVzYy5nZXROYW1lQXNTdHJpbmcoKSArICIgZGlzYWJsZWQiKTsKKyAgICB0cnkgeworICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpCisgICAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRlc3REZXNjLmdldE5hbWUoKSk7CisgICAgfSBjYXRjaCAob3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlJlZ2lvbk9mZmxpbmVFeGNlcHRpb24gZSkgeworICAgICAgLy8gRXhwZWN0ZWQKKyAgICB9CisKKyAgICBhZG1pbi5hZGRDb2x1bW4odGVzdERlc2MuZ2V0TmFtZSgpLCBuZXcgSENvbHVtbkRlc2NyaXB0b3IoImNvbDI6IikpOworICAgIGFkbWluLmVuYWJsZVRhYmxlKHRlc3REZXNjLmdldE5hbWUoKSk7CisgICAgdHJ5IHsKKyAgICAgIGFkbWluLmRlbGV0ZUNvbHVtbih0ZXN0RGVzYy5nZXROYW1lKCksIEJ5dGVzLnRvQnl0ZXMoImNvbDI6IikpOworICAgIH0gY2F0Y2goVGFibGVOb3REaXNhYmxlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBFeHBlY3RlZAorICAgIH0KKworICAgIGFkbWluLmRpc2FibGVUYWJsZSh0ZXN0RGVzYy5nZXROYW1lKCkpOworICAgIGFkbWluLmRlbGV0ZUNvbHVtbih0ZXN0RGVzYy5nZXROYW1lKCksIEJ5dGVzLnRvQnl0ZXMoImNvbDI6IikpOworICAgIGFkbWluLmRlbGV0ZVRhYmxlKHRlc3REZXNjLmdldE5hbWUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNZXJnZU1ldGEuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNZXJnZU1ldGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZWUyMTFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdE1lcmdlTWV0YS5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBUZXN0cyByZWdpb24gbWVyZ2luZyAqLworcHVibGljIGNsYXNzIFRlc3RNZXJnZU1ldGEgZXh0ZW5kcyBBYnN0cmFjdE1lcmdlVGVzdEJhc2UgeworCisgIC8qKiBjb25zdHJ1Y3RvciAKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBUZXN0TWVyZ2VNZXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIoZmFsc2UpOworICAgIGNvbmYuc2V0TG9uZygiaGJhc2UuY2xpZW50LnBhdXNlIiwgMSAqIDEwMDApOworICAgIGNvbmYuc2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCAyKTsKKyAgfQorICAKKyAgLyoqCisgICAqIHRlc3QgY2FzZQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VNZXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhc3NlcnROb3ROdWxsKGRmc0NsdXN0ZXIpOworICAgIEhNZXJnZS5tZXJnZShjb25mLCBkZnNDbHVzdGVyLmdldEZpbGVTeXN0ZW0oKSwgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdE1lcmdlVGFibGUuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNZXJnZVRhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWMzN2Y5YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RNZXJnZVRhYmxlLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBUZXN0cyBtZXJnaW5nIGEgbm9ybWFsIHRhYmxlJ3MgcmVnaW9ucworICovCitwdWJsaWMgY2xhc3MgVGVzdE1lcmdlVGFibGUgZXh0ZW5kcyBBYnN0cmFjdE1lcmdlVGVzdEJhc2UgeworCisgIC8qKgorICAgKiBUZXN0IGNhc2UKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE1lcmdlVGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFzc2VydE5vdE51bGwoZGZzQ2x1c3Rlcik7CisgICAgSE1lcmdlLm1lcmdlKGNvbmYsIGRmc0NsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpLCBkZXNjLmdldE5hbWUoKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0UmVnaW9uUmViYWxhbmNpbmcuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RSZWdpb25SZWJhbGFuY2luZy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhYWJkYTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0UmVnaW9uUmViYWxhbmNpbmcuamF2YQpAQCAtMCwwICsxLDIxOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb25TZXJ2ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IHdoZXRoZXIgcmVnaW9uIHJlYmFsYW5jaW5nIHdvcmtzLiAoSEJBU0UtNzEpCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0UmVnaW9uUmViYWxhbmNpbmcgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyh0aGlzLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKKyAgSFRhYmxlIHRhYmxlOworCisgIEhUYWJsZURlc2NyaXB0b3IgZGVzYzsKKyAgCisgIGZpbmFsIGJ5dGVbXSBGSVZFX0hVTkRSRURfS0JZVEVTOworICAKKyAgZmluYWwgYnl0ZSBbXSBDT0xVTU5fTkFNRSA9IEJ5dGVzLnRvQnl0ZXMoImNvbDoiKTsKKyAgCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVGVzdFJlZ2lvblJlYmFsYW5jaW5nKCkgeworICAgIHN1cGVyKDEpOworICAgIEZJVkVfSFVORFJFRF9LQllURVMgPSBuZXcgYnl0ZVs1MDAgKiAxMDI0XTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDUwMCAqIDEwMjQ7IGkrKykgeworICAgICAgRklWRV9IVU5EUkVEX0tCWVRFU1tpXSA9ICd4JzsKKyAgICB9CisgICAgCisgICAgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0ZXN0Iik7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTFVNTl9OQU1FKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBCZWZvcmUgdGhlIGhiYXNlIGNsdXN0ZXIgc3RhcnRzIHVwLCBjcmVhdGUgc29tZSBkdW1teSByZWdpb25zLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHByZUhCYXNlQ2x1c3RlclNldHVwKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBjcmVhdGUgYSAyMC1yZWdpb24gdGFibGUgYnkgd3JpdGluZyBkaXJlY3RseSB0byBkaXNrCisgICAgTGlzdDxieXRlIFtdPiBzdGFydEtleXMgPSBuZXcgQXJyYXlMaXN0PGJ5dGUgW10+KCk7CisgICAgc3RhcnRLZXlzLmFkZChudWxsKTsKKyAgICBmb3IgKGludCBpID0gMTA7IGkgPCAyOTsgaSsrKSB7CisgICAgICBzdGFydEtleXMuYWRkKEJ5dGVzLnRvQnl0ZXMoInJvd18iICsgaSkpOworICAgIH0KKyAgICBzdGFydEtleXMuYWRkKG51bGwpOworICAgIExPRy5pbmZvKHN0YXJ0S2V5cy5zaXplKCkgKyAiIHN0YXJ0IGtleXMgZ2VuZXJhdGVkIik7CisgICAgICAgIAorICAgIExpc3Q8SFJlZ2lvbj4gcmVnaW9ucyA9IG5ldyBBcnJheUxpc3Q8SFJlZ2lvbj4oKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDIwOyBpKyspIHsKKyAgICAgIHJlZ2lvbnMuYWRkKGNyZWF0ZUFyZWdpb24oc3RhcnRLZXlzLmdldChpKSwgc3RhcnRLZXlzLmdldChpKzEpKSk7CisgICAgfQorICAgIAorICAgIC8vIE5vdyBjcmVhdGUgdGhlIHJvb3QgYW5kIG1ldGEgcmVnaW9ucyBhbmQgaW5zZXJ0IHRoZSBkYXRhIHJlZ2lvbnMKKyAgICAvLyBjcmVhdGVkIGFib3ZlIGludG8gdGhlIG1ldGEKKyAgICAKKyAgICBjcmVhdGVSb290QW5kTWV0YVJlZ2lvbnMoKTsKKyAgICBmb3IgKEhSZWdpb24gcmVnaW9uIDogcmVnaW9ucykgeworICAgICAgSFJlZ2lvbi5hZGRSZWdpb25Ub01FVEEobWV0YSwgcmVnaW9uKTsKKyAgICB9CisgICAgY2xvc2VSb290QW5kTWV0YSgpOworICB9CisgIAorICAvKioKKyAgICogRm9yIEhCQVNFLTcxLiBUcnkgYSBmZXcgZGlmZmVyZW50IGNvbmZpZ3VyYXRpb25zIG9mIHN0YXJ0aW5nIGFuZCBzdG9wcGluZworICAgKiByZWdpb24gc2VydmVycyB0byBzZWUgaWYgdGhlIGFzc2lnbm1lbnQgb3IgcmVnaW9ucyBpcyBwcmV0dHkgYmFsYW5jZWQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmViYWxhbmNpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCAidGVzdCIpOworICAgIGFzc2VydEVxdWFscygiVGVzdCB0YWJsZSBzaG91bGQgaGF2ZSAyMCByZWdpb25zIiwgCisgICAgICAyMCwgdGFibGUuZ2V0U3RhcnRLZXlzKCkubGVuZ3RoKTsKKyAgICAKKyAgICAvLyB2ZXJpZnkgdGhhdCB0aGUgcmVnaW9uIGFzc2lnbm1lbnRzIGFyZSBiYWxhbmNlZCB0byBzdGFydCBvdXQKKyAgICBhc3NlcnRSZWdpb25zQXJlQmFsYW5jZWQoKTsKKworICAgIExPRy5kZWJ1ZygiQWRkaW5nIDJuZCByZWdpb24gc2VydmVyLiIpOworICAgIC8vIGFkZCBhIHJlZ2lvbiBzZXJ2ZXIgLSB0b3RhbCBvZiAyCisgICAgY2x1c3Rlci5zdGFydFJlZ2lvblNlcnZlcigpOworICAgIGFzc2VydFJlZ2lvbnNBcmVCYWxhbmNlZCgpOworICAKKyAgICAvLyBhZGQgYSByZWdpb24gc2VydmVyIC0gdG90YWwgb2YgMworICAgIExPRy5kZWJ1ZygiQWRkaW5nIDNyZCByZWdpb24gc2VydmVyLiIpOyAgICAKKyAgICBjbHVzdGVyLnN0YXJ0UmVnaW9uU2VydmVyKCk7CisgICAgYXNzZXJ0UmVnaW9uc0FyZUJhbGFuY2VkKCk7CisgICAgCisgICAgLy8ga2lsbCBhIHJlZ2lvbiBzZXJ2ZXIgLSB0b3RhbCBvZiAyCisgICAgTE9HLmRlYnVnKCJLaWxsaW5nIHRoZSAzcmQgcmVnaW9uIHNlcnZlci4iKTsKKyAgICBjbHVzdGVyLnN0b3BSZWdpb25TZXJ2ZXIoMiwgZmFsc2UpOworICAgIGNsdXN0ZXIud2FpdE9uUmVnaW9uU2VydmVyKDIpOworICAgIGFzc2VydFJlZ2lvbnNBcmVCYWxhbmNlZCgpOworICAgIAorICAgIC8vIHN0YXJ0IHR3byBtb3JlIHJlZ2lvbiBzZXJ2ZXJzIC0gdG90YWwgb2YgNAorICAgIExPRy5kZWJ1ZygiQWRkaW5nIDNyZCByZWdpb24gc2VydmVyIik7CisgICAgY2x1c3Rlci5zdGFydFJlZ2lvblNlcnZlcigpOworICAgIExPRy5kZWJ1ZygiQWRkaW5nIDR0aCByZWdpb24gc2VydmVyIik7ICAgIAorICAgIGNsdXN0ZXIuc3RhcnRSZWdpb25TZXJ2ZXIoKTsgICAgCisgICAgYXNzZXJ0UmVnaW9uc0FyZUJhbGFuY2VkKCk7CisgIH0KKyAgICAKKyAgLyoqIGZpZ3VyZSBvdXQgaG93IG1hbnkgcmVnaW9ucyBhcmUgY3VycmVudGx5IGJlaW5nIHNlcnZlZC4gKi8KKyAgcHJpdmF0ZSBpbnQgZ2V0UmVnaW9uQ291bnQoKSB7CisgICAgaW50IHRvdGFsID0gMDsKKyAgICBmb3IgKEhSZWdpb25TZXJ2ZXIgc2VydmVyIDogZ2V0T25saW5lUmVnaW9uU2VydmVycygpKSB7CisgICAgICB0b3RhbCArPSBzZXJ2ZXIuZ2V0T25saW5lUmVnaW9ucygpLnNpemUoKTsKKyAgICB9CisgICAgcmV0dXJuIHRvdGFsOworICB9CisgIAorICAvKioKKyAgICogRGV0ZXJtaW5lIGlmIHJlZ2lvbnMgYXJlIGJhbGFuY2VkLiBGaWd1cmUgb3V0IHRoZSB0b3RhbCwgZGl2aWRlIGJ5IHRoZQorICAgKiBudW1iZXIgb2Ygb25saW5lIHNlcnZlcnMsIHRoZW4gdGVzdCBpZiBlYWNoIHNlcnZlciBpcyArLy0gMSBvZiBhdmVyYWdlCisgICAqIHJvdW5kZWQgdXAuCisgICAqLworICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVnaW9uc0FyZUJhbGFuY2VkKCkgeworICAgIGJvb2xlYW4gc3VjY2VzcyA9IGZhbHNlOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsKKyAgICAgIHN1Y2Nlc3MgPSB0cnVlOworICAgICAgLy8gbWFrZSBzdXJlIGFsbCB0aGUgcmVnaW9ucyBhcmUgcmVhc3NpZ25lZCBiZWZvcmUgd2UgdGVzdCBiYWxhbmNlCisgICAgICB3YWl0Rm9yQWxsUmVnaW9uc0Fzc2lnbmVkKCk7CisKKyAgICAgIGludCByZWdpb25Db3VudCA9IGdldFJlZ2lvbkNvdW50KCk7CisgICAgICBMaXN0PEhSZWdpb25TZXJ2ZXI+IHNlcnZlcnMgPSBnZXRPbmxpbmVSZWdpb25TZXJ2ZXJzKCk7CisgICAgICBkb3VibGUgYXZnID0gTWF0aC5jZWlsKChkb3VibGUpcmVnaW9uQ291bnQgLyAoZG91YmxlKXNlcnZlcnMuc2l6ZSgpKTsKKyAgICAgIExPRy5kZWJ1ZygiVGhlcmUgYXJlICIgKyBzZXJ2ZXJzLnNpemUoKSArICIgc2VydmVycyBhbmQgIiArIHJlZ2lvbkNvdW50IAorICAgICAgICArICIgcmVnaW9ucy4gTG9hZCBBdmVyYWdlOiAiICsgYXZnKTsKKworICAgICAgZm9yIChIUmVnaW9uU2VydmVyIHNlcnZlciA6IHNlcnZlcnMpIHsKKyAgICAgICAgaW50IHNlcnZlckxvYWQgPSBzZXJ2ZXIuZ2V0T25saW5lUmVnaW9ucygpLnNpemUoKTsKKyAgICAgICAgTE9HLmRlYnVnKHNlcnZlci5oYXNoQ29kZSgpICsgIiBBdmc6ICIgKyBhdmcgKyAiIGFjdHVhbDogIiArIHNlcnZlckxvYWQpOworICAgICAgICBpZiAoIShzZXJ2ZXJMb2FkIDw9IGF2ZyArIDIgJiYgc2VydmVyTG9hZCA+PSBhdmcgLSAyKSkgeworICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgCisgICAgICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICAgICAgLy8gb25lIG9yIG1vcmUgc2VydmVycyBhcmUgbm90IGJhbGFuY2VkLiBzbGVlcCBhIGxpdHRsZSB0byBnaXZlIGl0IGEgCisgICAgICAgIC8vIGNoYW5jZSB0byBjYXRjaCB1cC4gdGhlbiwgZ28gYmFjayB0byB0aGUgcmV0cnkgbG9vcC4KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMDApOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7fQorICAgICAgICAKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIGlmIHdlIGdldCBoZXJlLCBhbGwgc2VydmVycyB3ZXJlIGJhbGFuY2VkLCBzbyB3ZSBzaG91bGQganVzdCByZXR1cm4uCisgICAgICByZXR1cm47CisgICAgfQorICAgIC8vIGlmIHdlIGdldCBoZXJlLCB3ZSB0cmllZCA1IHRpbWVzIGFuZCBuZXZlciBnb3QgdG8gc2hvcnQgY2lyY3VpdCBvdXQgb2YgCisgICAgLy8gdGhlIHJldHJ5IGxvb3AsIHNvIHRoaXMgaXMgYSBmYWlsdXJlLgorICAgIGZhaWwoIkFmdGVyIDUgYXR0ZW1wdHMsIHJlZ2lvbiBhc3NpZ25tZW50cyB3ZXJlIG5vdCBiYWxhbmNlZC4iKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBMaXN0PEhSZWdpb25TZXJ2ZXI+IGdldE9ubGluZVJlZ2lvblNlcnZlcnMoKSB7CisgICAgTGlzdDxIUmVnaW9uU2VydmVyPiBsaXN0ID0gbmV3IEFycmF5TGlzdDxIUmVnaW9uU2VydmVyPigpOworICAgIGZvciAoTG9jYWxIQmFzZUNsdXN0ZXIuUmVnaW9uU2VydmVyVGhyZWFkIHJzdCA6IGNsdXN0ZXIuZ2V0UmVnaW9uVGhyZWFkcygpKSB7CisgICAgICBpZiAocnN0LmdldFJlZ2lvblNlcnZlcigpLmlzT25saW5lKCkpIHsKKyAgICAgICAgbGlzdC5hZGQocnN0LmdldFJlZ2lvblNlcnZlcigpKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGxpc3Q7CisgIH0KKworICAvKioKKyAgICogV2FpdCB1bnRpbCBhbGwgdGhlIHJlZ2lvbnMgYXJlIGFzc2lnbmVkLiAKKyAgICovCisgIHByaXZhdGUgdm9pZCB3YWl0Rm9yQWxsUmVnaW9uc0Fzc2lnbmVkKCkgeworICAgIHdoaWxlIChnZXRSZWdpb25Db3VudCgpIDwgMjIpIHsKKyAgICAvLyB3aGlsZSAoIWNsdXN0ZXIuZ2V0TWFzdGVyKCkuYWxsUmVnaW9uc0Fzc2lnbmVkKCkpIHsKKyAgICAgIExPRy5kZWJ1ZygiV2FpdGluZyBmb3IgdGhlcmUgdG8gYmUgMjIgcmVnaW9ucywgYnV0IHRoZXJlIGFyZSAiICsgZ2V0UmVnaW9uQ291bnQoKSArICIgcmlnaHQgbm93LiIpOworICAgICAgdHJ5IHsKKyAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkge30KKyAgICB9CisgIH0KKworICAvKioKKyAgICogY3JlYXRlIGEgcmVnaW9uIHdpdGggdGhlIHNwZWNpZmllZCBzdGFydCBhbmQgZW5kIGtleSBhbmQgZXhhY3RseSBvbmUgcm93CisgICAqIGluc2lkZS4gCisgICAqLworICBwcml2YXRlIEhSZWdpb24gY3JlYXRlQXJlZ2lvbihieXRlIFtdIHN0YXJ0S2V5LCBieXRlIFtdIGVuZEtleSkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByZWdpb24gPSBjcmVhdGVOZXdIUmVnaW9uKGRlc2MsIHN0YXJ0S2V5LCBlbmRLZXkpOworICAgIGJ5dGUgW10ga2V5VG9Xcml0ZSA9IHN0YXJ0S2V5ID09IG51bGwgPyBCeXRlcy50b0J5dGVzKCJyb3dfMDAwIikgOiBzdGFydEtleTsKKyAgICBCYXRjaFVwZGF0ZSBidSA9IG5ldyBCYXRjaFVwZGF0ZShrZXlUb1dyaXRlKTsKKyAgICBidS5wdXQoQ09MVU1OX05BTUUsICJ0ZXN0Ii5nZXRCeXRlcygpKTsKKyAgICByZWdpb24uYmF0Y2hVcGRhdGUoYnUsIG51bGwpOworICAgIHJlZ2lvbi5jbG9zZSgpOworICAgIHJlZ2lvbi5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgIHJldHVybiByZWdpb247CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RTY2FuTXVsdGlwbGVWZXJzaW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM3YTg5Y2UKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0U2Nhbk11bHRpcGxlVmVyc2lvbnMuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBSZWdyZXNzaW9uIHRlc3QgZm9yIEhCQVNFLTYxMworICovCitwdWJsaWMgY2xhc3MgVGVzdFNjYW5NdWx0aXBsZVZlcnNpb25zIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBwcml2YXRlIGZpbmFsIGJ5dGVbXSBUQUJMRV9OQU1FID0gQnl0ZXMudG9CeXRlcygiVGVzdFNjYW5NdWx0aXBsZVZlcnNpb25zIik7CisgIHByaXZhdGUgZmluYWwgSFJlZ2lvbkluZm9bXSBJTkZPUyA9IG5ldyBIUmVnaW9uSW5mb1syXTsKKyAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uW10gUkVHSU9OUyA9IG5ldyBIUmVnaW9uWzJdOworICBwcml2YXRlIGZpbmFsIGJ5dGVbXVtdIFJPV1MgPSBuZXcgYnl0ZVtdW10geworICAgICAgQnl0ZXMudG9CeXRlcygicm93XzAyMDAiKSwKKyAgICAgIEJ5dGVzLnRvQnl0ZXMoInJvd18wODAwIikKKyAgfTsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nW10gVElNRVNUQU1QUyA9IG5ldyBsb25nW10geworICAgICAgMTAwTCwKKyAgICAgIDEwMDBMCisgIH07CisgIHByaXZhdGUgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbnVsbDsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgcHJlSEJhc2VDbHVzdGVyU2V0dXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0ZXN0RGlyID0gbmV3IFBhdGgoY29uZi5nZXQoSENvbnN0YW50cy5IQkFTRV9ESVIpKTsKKyAgICAKKyAgICAvLyBDcmVhdGUgdGFibGUgZGVzY3JpcHRpb24KKyAgICAKKyAgICB0aGlzLmRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihUQUJMRV9OQU1FKTsKKyAgICB0aGlzLmRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkpKTsKKworICAgIC8vIFJlZ2lvbiAwIHdpbGwgY29udGFpbiB0aGUga2V5IHJhbmdlIFsscm93XzA1MDApCisgICAgSU5GT1NbMF0gPSBuZXcgSFJlZ2lvbkluZm8odGhpcy5kZXNjLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywKKyAgICAgICAgQnl0ZXMudG9CeXRlcygicm93XzA1MDAiKSk7CisgICAgLy8gUmVnaW9uIDEgd2lsbCBjb250YWluIHRoZSBrZXkgcmFuZ2UgW3Jvd18wNTAwLCkKKyAgICBJTkZPU1sxXSA9IG5ldyBIUmVnaW9uSW5mbyh0aGlzLmRlc2MsIEJ5dGVzLnRvQnl0ZXMoInJvd18wNTAwIiksCisgICAgICAgIEhDb25zdGFudHMuRU1QVFlfRU5EX1JPVyk7CisKKyAgICAvLyBDcmVhdGUgcm9vdCBhbmQgbWV0YSByZWdpb25zCisgICAgY3JlYXRlUm9vdEFuZE1ldGFSZWdpb25zKCk7CisgICAgLy8gQ3JlYXRlIHRoZSByZWdpb25zCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBSRUdJT05TLmxlbmd0aDsgaSsrKSB7CisgICAgICBSRUdJT05TW2ldID0KKyAgICAgICAgSFJlZ2lvbi5jcmVhdGVIUmVnaW9uKHRoaXMuSU5GT1NbaV0sIHRoaXMudGVzdERpciwgdGhpcy5jb25mKTsKKyAgICAgIC8vIEluc2VydCBkYXRhCisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFRJTUVTVEFNUFMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShST1dTW2ldLCBUSU1FU1RBTVBTW2pdKTsKKyAgICAgICAgYi5wdXQoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZLCBCeXRlcy50b0J5dGVzKFRJTUVTVEFNUFNbal0pKTsKKyAgICAgICAgUkVHSU9OU1tpXS5iYXRjaFVwZGF0ZShiLCBudWxsKTsKKyAgICAgIH0KKyAgICAgIC8vIEluc2VydCB0aGUgcmVnaW9uIHdlIGNyZWF0ZWQgaW50byB0aGUgbWV0YQorICAgICAgSFJlZ2lvbi5hZGRSZWdpb25Ub01FVEEobWV0YSwgUkVHSU9OU1tpXSk7CisgICAgICAvLyBDbG9zZSByZWdpb24KKyAgICAgIFJFR0lPTlNbaV0uY2xvc2UoKTsKKyAgICAgIFJFR0lPTlNbaV0uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICB9CisgICAgLy8gQ2xvc2Ugcm9vdCBhbmQgbWV0YSByZWdpb25zCisgICAgY2xvc2VSb290QW5kTWV0YSgpOworICB9CisgIAorICAvKioKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTY2FuTXVsdGlwbGVWZXJzaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSBjcmVhdGVkIG11bHRpcGxlIHJlZ2lvbnMgYW5kIGJvdGggSERGUyBhbmQgSEJhc2UKKyAgICAvLyBhcmUgcnVubmluZy4gVGhlcmUgYXJlIDUgY2FzZXMgd2UgaGF2ZSB0byB0ZXN0LiBFYWNoIGlzIGRlc2NyaWJlZCBiZWxvdy4KKyAgICBIVGFibGUgdCA9IG5ldyBIVGFibGUoY29uZiwgVEFCTEVfTkFNRSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBST1dTLmxlbmd0aDsgaSsrKSB7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFRJTUVTVEFNUFMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgQ2VsbCBbXSBjZWxscyA9CisgICAgICAgICAgdC5nZXQoUk9XU1tpXSwgSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZLCBUSU1FU1RBTVBTW2pdLCAxKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShjZWxscyAhPSBudWxsICYmIGNlbGxzLmxlbmd0aCA9PSAxKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJSb3c9IiArIEJ5dGVzLnRvU3RyaW5nKFJPV1NbaV0pICsgIiwgY2VsbD0iICsKKyAgICAgICAgICBjZWxsc1swXSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8vIENhc2UgMTogc2NhbiB3aXRoIExBVEVTVF9USU1FU1RBTVAuIFNob3VsZCBnZXQgdHdvIHJvd3MKKyAgICBpbnQgY291bnQgPSAwOworICAgIFNjYW5uZXIgcyA9IHQuZ2V0U2Nhbm5lcihIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFlfQVJSQVkpOworICAgIHRyeSB7CisgICAgICBmb3IgKFJvd1Jlc3VsdCByciA9IG51bGw7IChyciA9IHMubmV4dCgpKSAhPSBudWxsOykgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocnIudG9TdHJpbmcoKSk7CisgICAgICAgIGNvdW50ICs9IDE7CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoIk51bWJlciBvZiByb3dzIHNob3VsZCBiZSAyIiwgMiwgY291bnQpOworICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorCisgICAgLy8gQ2FzZSAyOiBTY2FuIHdpdGggYSB0aW1lc3RhbXAgZ3JlYXRlciB0aGFuIG1vc3QgcmVjZW50IHRpbWVzdGFtcAorICAgIC8vIChpbiB0aGlzIGNhc2UgPiAxMDAwIGFuZCA8IExBVEVTVF9USU1FU1RBTVAuIFNob3VsZCBnZXQgMiByb3dzLgorICAgIAorICAgIGNvdW50ID0gMDsKKyAgICBzID0gdC5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csCisgICAgICAgIDEwMDAwTCk7CisgICAgdHJ5IHsKKyAgICAgIHdoaWxlIChzLm5leHQoKSAhPSBudWxsKSB7CisgICAgICAgIGNvdW50ICs9IDE7CisgICAgICB9CisgICAgICBhc3NlcnRFcXVhbHMoIk51bWJlciBvZiByb3dzIHNob3VsZCBiZSAyIiwgMiwgY291bnQpOworICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICAgIAorICAgIC8vIENhc2UgMzogc2NhbiB3aXRoIHRpbWVzdGFtcCBlcXVhbCB0byBtb3N0IHJlY2VudCB0aW1lc3RhbXAKKyAgICAvLyAoaW4gdGhpcyBjYXNlID09IDEwMDAuIFNob3VsZCBnZXQgMiByb3dzLgorICAgIAorICAgIGNvdW50ID0gMDsKKyAgICBzID0gdC5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csCisgICAgICAgIDEwMDBMKTsKKyAgICB0cnkgeworICAgICAgd2hpbGUgKHMubmV4dCgpICE9IG51bGwpIHsKKyAgICAgICAgY291bnQgKz0gMTsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiTnVtYmVyIG9mIHJvd3Mgc2hvdWxkIGJlIDIiLCAyLCBjb3VudCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgICAgCisgICAgLy8gQ2FzZSA0OiBzY2FuIHdpdGggdGltZXN0YW1wIGdyZWF0ZXIgdGhhbiBmaXJzdCB0aW1lc3RhbXAgYnV0IGxlc3MgdGhhbgorICAgIC8vIHNlY29uZCB0aW1lc3RhbXAgKDEwMCA8IHRpbWVzdGFtcCA8IDEwMDApLiBTaG91bGQgZ2V0IDIgcm93cy4KKyAgICAKKyAgICBjb3VudCA9IDA7CisgICAgcyA9IHQuZ2V0U2Nhbm5lcihIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFlfQVJSQVksIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgICA1MDBMKTsKKyAgICB0cnkgeworICAgICAgd2hpbGUgKHMubmV4dCgpICE9IG51bGwpIHsKKyAgICAgICAgY291bnQgKz0gMTsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiTnVtYmVyIG9mIHJvd3Mgc2hvdWxkIGJlIDIiLCAyLCBjb3VudCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgICAgCisgICAgLy8gQ2FzZSA1OiBzY2FuIHdpdGggdGltZXN0YW1wIGVxdWFsIHRvIGZpcnN0IHRpbWVzdGFtcCAoMTAwKQorICAgIC8vIFNob3VsZCBnZXQgMiByb3dzLgorICAgIAorICAgIGNvdW50ID0gMDsKKyAgICBzID0gdC5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csCisgICAgICAgIDEwMEwpOworICAgIHRyeSB7CisgICAgICB3aGlsZSAocy5uZXh0KCkgIT0gbnVsbCkgeworICAgICAgICBjb3VudCArPSAxOworICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJOdW1iZXIgb2Ygcm93cyBzaG91bGQgYmUgMiIsIDIsIGNvdW50KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdFNjYW5uZXJBUEkuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RTY2FubmVyQVBJLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODU5NzJhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RTY2FubmVyQVBJLmphdmEKQEAgLTAsMCArMSwxNjYgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkTWFwOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKiogdGVzdCB0aGUgc2Nhbm5lciBBUEkgYXQgYWxsIGxldmVscyAqLworcHVibGljIGNsYXNzIFRlc3RTY2FubmVyQVBJIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBwcml2YXRlIGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zID0gQnl0ZXMudG9CeXRlQXJyYXlzKG5ldyBTdHJpbmdbXSB7CisgICAgImE6IiwgImI6IgorICB9KTsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlIFtdIHN0YXJ0Um93ID0gQnl0ZXMudG9CeXRlcygiMCIpOworCisgIHByaXZhdGUgZmluYWwgVHJlZU1hcDxieXRlIFtdLCBTb3J0ZWRNYXA8Ynl0ZSBbXSwgQ2VsbD4+IHZhbHVlcyA9CisgICAgbmV3IFRyZWVNYXA8Ynl0ZSBbXSwgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+PihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgCisgIC8qKgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFRlc3RTY2FubmVyQVBJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIoKTsKKyAgICB0cnkgeworICAgICAgVHJlZU1hcDxieXRlIFtdLCBDZWxsPiBjb2x1bW5zID0KKyAgICAgICAgbmV3IFRyZWVNYXA8Ynl0ZSBbXSwgQ2VsbD4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgICBjb2x1bW5zLnB1dChCeXRlcy50b0J5dGVzKCJhOjEiKSwKKyAgICAgICAgICBuZXcgQ2VsbChCeXRlcy50b0J5dGVzKCIxIiksIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkpOworICAgICAgdmFsdWVzLnB1dChCeXRlcy50b0J5dGVzKCIxIiksIGNvbHVtbnMpOworICAgICAgY29sdW1ucyA9IG5ldyBUcmVlTWFwPGJ5dGUgW10sIENlbGw+KEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpOworICAgICAgY29sdW1ucy5wdXQoQnl0ZXMudG9CeXRlcygiYToyIiksCisgICAgICAgICAgbmV3IENlbGwoQnl0ZXMudG9CeXRlcygiMiIpLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApKTsKKyAgICAgIGNvbHVtbnMucHV0KEJ5dGVzLnRvQnl0ZXMoImI6MiIpLAorICAgICAgICAgIG5ldyBDZWxsKEJ5dGVzLnRvQnl0ZXMoIjIiKSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKSk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RBcGkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIFN0cmluZyB0YWJsZU5hbWUgPSBnZXROYW1lKCk7CisKKyAgICAvLyBDcmVhdGUgdGFibGUKKyAgICAKKyAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgSFRhYmxlRGVzY3JpcHRvciB0YWJsZURlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcih0YWJsZU5hbWUpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29sdW1ucy5sZW5ndGg7IGkrKykgeworICAgICAgdGFibGVEZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoY29sdW1uc1tpXSkpOworICAgIH0KKyAgICBhZG1pbi5jcmVhdGVUYWJsZSh0YWJsZURlc2MpOworCisgICAgLy8gSW5zZXJ0IHZhbHVlcworICAgIAorICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgZ2V0TmFtZSgpKTsKKworICAgIGZvciAoTWFwLkVudHJ5PGJ5dGUgW10sIFNvcnRlZE1hcDxieXRlIFtdLCBDZWxsPj4gcm93OiB2YWx1ZXMuZW50cnlTZXQoKSkgeworICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShyb3cuZ2V0S2V5KCkpOworICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4gdmFsOiByb3cuZ2V0VmFsdWUoKS5lbnRyeVNldCgpKSB7CisgICAgICAgIGIucHV0KHZhbC5nZXRLZXkoKSwgdmFsLmdldFZhbHVlKCkuZ2V0VmFsdWUoKSk7CisgICAgICB9CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfQorCisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworICAgIHRyeSB7CisgICAgICBDb2xsZWN0aW9uPEhSZWdpb24+IHJlZ2lvbnMgPQorICAgICAgICBjbHVzdGVyLmdldFJlZ2lvblRocmVhZHMoKS5nZXQoMCkuZ2V0UmVnaW9uU2VydmVyKCkuZ2V0T25saW5lUmVnaW9ucygpOworICAgICAgZm9yIChIUmVnaW9uIHI6IHJlZ2lvbnMpIHsKKyAgICAgICAgaWYgKCFyLmdldFJlZ2lvbkluZm8oKS5pc01ldGFSZWdpb24oKSkgeworICAgICAgICAgIHJlZ2lvbiA9IHI7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIElPRXhjZXB0aW9uIGlveCA9IG5ldyBJT0V4Y2VwdGlvbigiZXJyb3IgZmluZGluZyByZWdpb24iKTsKKyAgICAgIGlveC5pbml0Q2F1c2UoZSk7CisgICAgICB0aHJvdyBpb3g7CisgICAgfQorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJudWxsIikKKyAgICBTY2FubmVySW5jb21tb24gc2Nhbm5lciA9IG5ldyBJbnRlcm5hbFNjYW5uZXJJbmNvbW1vbigKKyAgICAgIHJlZ2lvbi5nZXRTY2FubmVyKGNvbHVtbnMsIHN0YXJ0Um93LCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwgbnVsbCkpOworICAgIHRyeSB7CisgICAgICB2ZXJpZnkoc2Nhbm5lcik7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisgICAgCisgICAgc2Nhbm5lciA9IG5ldyBDbGllbnRTY2FubmVySW5jb21tb24odGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBzdGFydFJvdykpOworICAgIHRyeSB7CisgICAgICB2ZXJpZnkoc2Nhbm5lcik7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisgICAgU2Nhbm5lciBzY2FubmVyMiA9IHRhYmxlLmdldFNjYW5uZXIoY29sdW1ucywgc3RhcnRSb3cpOworICAgIHRyeSB7CisgICAgICBmb3IgKFJvd1Jlc3VsdCByIDogc2Nhbm5lcjIpIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgicm93IGtleSIsIHZhbHVlcy5jb250YWluc0tleShyLmdldFJvdygpKSk7CisKKyAgICAgICAgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+IGNvbHVtblZhbHVlcyA9IHZhbHVlcy5nZXQoci5nZXRSb3coKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhjb2x1bW5WYWx1ZXMuc2l6ZSgpLCByLnNpemUoKSk7CisgICAgICAgIGZvciAoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGU6IGNvbHVtblZhbHVlcy5lbnRyeVNldCgpKSB7CisgICAgICAgICAgYnl0ZSBbXSBjb2x1bW4gPSBlLmdldEtleSgpOworICAgICAgICAgIGFzc2VydFRydWUoImNvbHVtbiIsIHIuY29udGFpbnNLZXkoY29sdW1uKSk7CisgICAgICAgICAgYXNzZXJ0VHJ1ZSgidmFsdWUiLCBBcnJheXMuZXF1YWxzKGNvbHVtblZhbHVlcy5nZXQoY29sdW1uKS5nZXRWYWx1ZSgpLAorICAgICAgICAgICAgci5nZXQoY29sdW1uKS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIH0KKyAgICAgIH0gICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgc2Nhbm5lci5jbG9zZSgpOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHZlcmlmeShTY2FubmVySW5jb21tb24gc2Nhbm5lcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICB3aGlsZSAoc2Nhbm5lci5uZXh0KHJlc3VsdHMpKSB7CisgICAgICBhc3NlcnRUcnVlKCJyb3cga2V5IiwgdmFsdWVzLmNvbnRhaW5zS2V5KHJlc3VsdHMuZ2V0KDApLmdldFJvdygpKSk7CisgICAgICAvLyBUT0RPIEZJWC4KKy8vICAgICAgU29ydGVkTWFwPGJ5dGUgW10sIENlbGw+IGNvbHVtblZhbHVlcyA9IHZhbHVlcy5nZXQocm93KTsKKy8vICAgICAgYXNzZXJ0RXF1YWxzKGNvbHVtblZhbHVlcy5zaXplKCksIHJlc3VsdHMuc2l6ZSgpKTsKKy8vICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4gZTogY29sdW1uVmFsdWVzLmVudHJ5U2V0KCkpIHsKKy8vICAgICAgICBieXRlIFtdIGNvbHVtbiA9IGUuZ2V0S2V5KCk7CisvLyAgICAgICAgYXNzZXJ0VHJ1ZSgiY29sdW1uIiwgcmVzdWx0cy5jb250YWluc0tleShjb2x1bW4pKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKCJ2YWx1ZSIsIEFycmF5cy5lcXVhbHMoY29sdW1uVmFsdWVzLmdldChjb2x1bW4pLmdldFZhbHVlKCksCisvLyAgICAgICAgICAgIHJlc3VsdHMuZ2V0KGNvbHVtbikuZ2V0VmFsdWUoKSkpOworLy8gICAgICB9CisvLyAgICAgIAorICAgICAgcmVzdWx0cy5jbGVhcigpOworICAgIH0KKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3RTZXJpYWxpemF0aW9uLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0U2VyaWFsaXphdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkNjZiNDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0U2VyaWFsaXphdGlvbi5qYXZhCkBAIC0wLDAgKzEsMTc0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoT3BlcmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSGJhc2VNYXBXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLldyaXRhYmxlczsKKworLyoqCisgKiBUZXN0IEhCYXNlIFdyaXRhYmxlcyBzZXJpYWxpemF0aW9ucworICovCitwdWJsaWMgY2xhc3MgVGVzdFNlcmlhbGl6YXRpb24gZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RLZXlWYWx1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpOworICAgIGJ5dGUgW10gY29sdW1uID0gQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkgKyAiOiIgKyBnZXROYW1lKCkpOworICAgIEtleVZhbHVlIG9yaWdpbmFsID0gbmV3IEtleVZhbHVlKHJvdywgY29sdW1uKTsKKyAgICBieXRlIFtdIGJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKG9yaWdpbmFsKTsKKyAgICBLZXlWYWx1ZSBuZXdvbmUgPSAoS2V5VmFsdWUpV3JpdGFibGVzLmdldFdyaXRhYmxlKGJ5dGVzLCBuZXcgS2V5VmFsdWUoKSk7CisgICAgYXNzZXJ0VHJ1ZShLZXlWYWx1ZS5DT01QQVJBVE9SLmNvbXBhcmUob3JpZ2luYWwsIG5ld29uZSkgPT0gMCk7CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0SGJhc2VNYXBXcml0YWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgYnl0ZSBbXT4gaG13ID0KKyAgICAgIG5ldyBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSwgYnl0ZVtdPigpOworICAgIGhtdy5wdXQoImtleSIuZ2V0Qnl0ZXMoKSwgInZhbHVlIi5nZXRCeXRlcygpKTsKKyAgICBieXRlIFtdIGJ5dGVzID0gV3JpdGFibGVzLmdldEJ5dGVzKGhtdyk7CisgICAgaG13ID0gKEhiYXNlTWFwV3JpdGFibGU8Ynl0ZVtdLCBieXRlW10+KQorICAgICAgV3JpdGFibGVzLmdldFdyaXRhYmxlKGJ5dGVzLCBuZXcgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBieXRlIFtdPigpKTsKKyAgICBhc3NlcnRUcnVlKGhtdy5zaXplKCkgPT0gMSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoInZhbHVlIi5nZXRCeXRlcygpLCBobXcuZ2V0KCJrZXkiLmdldEJ5dGVzKCkpKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RITXNnKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSE1zZyAgbSA9IG5ldyBITXNnKEhNc2cuVHlwZS5NU0dfUkVHSU9OU0VSVkVSX1FVSUVTQ0UpOworICAgIGJ5dGUgW10gbWIgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMobSk7CisgICAgSE1zZyBkZXNlcmlhbGl6ZWRITXNnID0gKEhNc2cpV3JpdGFibGVzLmdldFdyaXRhYmxlKG1iLCBuZXcgSE1zZygpKTsKKyAgICBhc3NlcnRUcnVlKG0uZXF1YWxzKGRlc2VyaWFsaXplZEhNc2cpKTsKKyAgICBtID0gbmV3IEhNc2coSE1zZy5UeXBlLk1TR19SRUdJT05TRVJWRVJfUVVJRVNDRSwKKyAgICAgIG5ldyBIUmVnaW9uSW5mbyhuZXcgSFRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpLAorICAgICAgICBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVksIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSksCisgICAgICAgICJTb21lIG1lc3NhZ2UiLmdldEJ5dGVzKCkpOworICAgIG1iID0gV3JpdGFibGVzLmdldEJ5dGVzKG0pOworICAgIGRlc2VyaWFsaXplZEhNc2cgPSAoSE1zZylXcml0YWJsZXMuZ2V0V3JpdGFibGUobWIsIG5ldyBITXNnKCkpOworICAgIGFzc2VydFRydWUobS5lcXVhbHMoZGVzZXJpYWxpemVkSE1zZykpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0VGFibGVEZXNjcmlwdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICBieXRlIFtdIG1iID0gV3JpdGFibGVzLmdldEJ5dGVzKGh0ZCk7CisgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNlcmlhbGl6ZWRIdGQgPQorICAgICAgKEhUYWJsZURlc2NyaXB0b3IpV3JpdGFibGVzLmdldFdyaXRhYmxlKG1iLCBuZXcgSFRhYmxlRGVzY3JpcHRvcigpKTsKKyAgICBhc3NlcnRFcXVhbHMoaHRkLmdldE5hbWVBc1N0cmluZygpLCBkZXNlcmlhbGl6ZWRIdGQuZ2V0TmFtZUFzU3RyaW5nKCkpOworICB9CisKKyAgLyoqCisgICAqIFRlc3QgUmVnaW9uSW5mbyBzZXJpYWxpemF0aW9uCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Um93UmVzdWx0KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSGJhc2VNYXBXcml0YWJsZTxieXRlIFtdLCBDZWxsPiBtID0gbmV3IEhiYXNlTWFwV3JpdGFibGU8Ynl0ZSBbXSwgQ2VsbD4oKTsKKyAgICBieXRlIFtdIGIgPSBCeXRlcy50b0J5dGVzKGdldE5hbWUoKSk7CisgICAgbS5wdXQoYiwgbmV3IENlbGwoYiwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpKTsKKyAgICBSb3dSZXN1bHQgcnIgPSBuZXcgUm93UmVzdWx0KGIsIG0pOworICAgIGJ5dGUgW10gbWIgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMocnIpOworICAgIFJvd1Jlc3VsdCBkZXNlcmlhbGl6ZWRSciA9CisgICAgICAoUm93UmVzdWx0KVdyaXRhYmxlcy5nZXRXcml0YWJsZShtYiwgbmV3IFJvd1Jlc3VsdCgpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyci5nZXRSb3coKSwgZGVzZXJpYWxpemVkUnIuZ2V0Um93KCkpKTsKKyAgICBieXRlIFtdIG9uZSA9IHJyLmdldChiKS5nZXRWYWx1ZSgpOworICAgIGJ5dGUgW10gdHdvID0gZGVzZXJpYWxpemVkUnIuZ2V0KGIpLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMob25lLCB0d28pKTsKKyAgICBXcml0YWJsZXMuY29weVdyaXRhYmxlKHJyLCBkZXNlcmlhbGl6ZWRScik7CisgICAgb25lID0gcnIuZ2V0KGIpLmdldFZhbHVlKCk7CisgICAgdHdvID0gZGVzZXJpYWxpemVkUnIuZ2V0KGIpLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMob25lLCB0d28pKTsKKyAgICAKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IFJlZ2lvbkluZm8gc2VyaWFsaXphdGlvbgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFJlZ2lvbkluZm8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgU3RyaW5nIFtdIGZhbWlsaWVzID0gbmV3IFN0cmluZyBbXSB7ImluZm86IiwgImFuY2hvcjoifTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZhbWlsaWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBodGQuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihmYW1pbGllc1tpXSkpOworICAgIH0KKyAgICBIUmVnaW9uSW5mbyBocmkgPSBuZXcgSFJlZ2lvbkluZm8oaHRkLAorICAgICAgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csIEhDb25zdGFudHMuRU1QVFlfRU5EX1JPVyk7CisgICAgYnl0ZSBbXSBocmliID0gV3JpdGFibGVzLmdldEJ5dGVzKGhyaSk7CisgICAgSFJlZ2lvbkluZm8gZGVzZXJpYWxpemVkSHJpID0KKyAgICAgIChIUmVnaW9uSW5mbylXcml0YWJsZXMuZ2V0V3JpdGFibGUoaHJpYiwgbmV3IEhSZWdpb25JbmZvKCkpOworICAgIGFzc2VydEVxdWFscyhocmkuZ2V0RW5jb2RlZE5hbWUoKSwgZGVzZXJpYWxpemVkSHJpLmdldEVuY29kZWROYW1lKCkpOworICAgIGFzc2VydEVxdWFscyhocmkuZ2V0VGFibGVEZXNjKCkuZ2V0RmFtaWxpZXMoKS5zaXplKCksCisgICAgICBkZXNlcmlhbGl6ZWRIcmkuZ2V0VGFibGVEZXNjKCkuZ2V0RmFtaWxpZXMoKS5zaXplKCkpOworICB9CisgIAorICAvKioKKyAgICogVGVzdCBTZXJ2ZXJJbmZvIHNlcmlhbGl6YXRpb24KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJ2ZXJJbmZvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSFNlcnZlckluZm8gaHNpID0gbmV3IEhTZXJ2ZXJJbmZvKG5ldyBIU2VydmVyQWRkcmVzcygiMC4wLjAuMDoxMjMiKSwgLTEsCisgICAgICAxMjQ1LCAiZGVmYXVsdCBuYW1lIik7CisgICAgYnl0ZSBbXSBiID0gV3JpdGFibGVzLmdldEJ5dGVzKGhzaSk7CisgICAgSFNlcnZlckluZm8gZGVzZXJpYWxpemVkSHNpID0KKyAgICAgIChIU2VydmVySW5mbylXcml0YWJsZXMuZ2V0V3JpdGFibGUoYiwgbmV3IEhTZXJ2ZXJJbmZvKCkpOworICAgIGFzc2VydFRydWUoaHNpLmVxdWFscyhkZXNlcmlhbGl6ZWRIc2kpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3QgQmF0Y2hVcGRhdGUgc2VyaWFsaXphdGlvbgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEJhdGNoVXBkYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQWRkIHJvdyBuYW1lZCAndGVzdE5hbWUnLgorICAgIEJhdGNoVXBkYXRlIGJ1ID0gbmV3IEJhdGNoVXBkYXRlKGdldE5hbWUoKSk7CisgICAgLy8gQWRkIGEgY29sdW1uIG5hbWVkIHNhbWUgYXMgcm93LgorICAgIGJ1LnB1dChnZXROYW1lKCksIGdldE5hbWUoKS5nZXRCeXRlcygpKTsKKyAgICBieXRlIFtdIGIgPSBXcml0YWJsZXMuZ2V0Qnl0ZXMoYnUpOworICAgIEJhdGNoVXBkYXRlIGJ1YnUgPQorICAgICAgKEJhdGNoVXBkYXRlKVdyaXRhYmxlcy5nZXRXcml0YWJsZShiLCBuZXcgQmF0Y2hVcGRhdGUoKSk7CisgICAgLy8gQXNzZXJ0IHJvd3MgYXJlIHNhbWUuCisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoYnUuZ2V0Um93KCksIGJ1YnUuZ2V0Um93KCkpKTsKKyAgICAvLyBBc3NlcnQgaGFzIHNhbWUgbnVtYmVyIG9mIEJhdGNoT3BlcmF0aW9ucy4KKyAgICBpbnQgZmlyc3RDb3VudCA9IDA7CisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBibzogYnVidSkgeworICAgICAgZmlyc3RDb3VudCsrOworICAgIH0KKyAgICAvLyBOb3cgZGVzZXJpYWxpemUgYWdhaW4gaW50byBzYW1lIGluc3RhbmNlIHRvIGVuc3VyZSB3ZSdyZSBub3QKKyAgICAvLyBhY2N1bXVsYXRpbmcgQmF0Y2hPcGVyYXRpb25zIG9uIGVhY2ggZGVzZXJpYWxpemF0aW9uLgorICAgIEJhdGNoVXBkYXRlIGJ1YnVidSA9IChCYXRjaFVwZGF0ZSlXcml0YWJsZXMuZ2V0V3JpdGFibGUoYiwgYnVidSk7CisgICAgLy8gQXNzZXJ0IHJvd3MgYXJlIHNhbWUgYWdhaW4uCisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoYnUuZ2V0Um93KCksIGJ1YnVidS5nZXRSb3coKSkpOworICAgIGludCBzZWNvbmRDb3VudCA9IDA7CisgICAgZm9yIChCYXRjaE9wZXJhdGlvbiBibzogYnVidWJ1KSB7CisgICAgICBzZWNvbmRDb3VudCsrOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoZmlyc3RDb3VudCwgc2Vjb25kQ291bnQpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdFRhYmxlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0VGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTZjMDY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGVzdFRhYmxlLmphdmEKQEAgLTAsMCArMSwxODAgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKiogVGVzdHMgdGFibGUgY3JlYXRpb24gcmVzdHJpY3Rpb25zKi8KK3B1YmxpYyBjbGFzcyBUZXN0VGFibGUgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIC8qKgorICAgKiB0aGUgdGVzdAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q3JlYXRlVGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICBTdHJpbmcgbXNnID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgYWRtaW4uY3JlYXRlVGFibGUoSFRhYmxlRGVzY3JpcHRvci5ST09UX1RBQkxFREVTQyk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIG1zZyA9IGUudG9TdHJpbmcoKTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZSgiVW5leGNlcHRlZCBleGNlcHRpb24gbWVzc2FnZSAiICsgbXNnLCBtc2cgIT0gbnVsbCAmJgorICAgICAgbXNnLnN0YXJ0c1dpdGgoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLmdldE5hbWUoKSkgJiYKKyAgICAgIG1zZy5jb250YWlucyhIVGFibGVEZXNjcmlwdG9yLlJPT1RfVEFCTEVERVNDLmdldE5hbWVBc1N0cmluZygpKSk7CisgICAgCisgICAgbXNnID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgYWRtaW4uY3JlYXRlVGFibGUoSFRhYmxlRGVzY3JpcHRvci5NRVRBX1RBQkxFREVTQyk7CisgICAgfSBjYXRjaChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgbXNnID0gZS50b1N0cmluZygpOworICAgIH0KKyAgICBhc3NlcnRUcnVlKCJVbmV4Y2VwdGVkIGV4Y2VwdGlvbiBtZXNzYWdlICIgKyBtc2csIG1zZyAhPSBudWxsICYmCisgICAgICBtc2cuc3RhcnRzV2l0aChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MuZ2V0TmFtZSgpKSAmJgorICAgICAgbXNnLmNvbnRhaW5zKEhUYWJsZURlc2NyaXB0b3IuTUVUQV9UQUJMRURFU0MuZ2V0TmFtZUFzU3RyaW5nKCkpKTsKKyAgICAKKyAgICAvLyBUcnkgZG9pbmcgYSBkdXBsaWNhdGUgZGF0YWJhc2UgY3JlYXRlLgorICAgIG1zZyA9IG51bGw7CisgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKSk7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgYXNzZXJ0VHJ1ZSgiRmlyc3QgdGFibGUgY3JlYXRpb24gY29tcGxldGVkIiwgYWRtaW4ubGlzdFRhYmxlcygpLmxlbmd0aCA9PSAxKTsKKyAgICBib29sZWFuIGdvdEV4Y2VwdGlvbiA9IGZhbHNlOworICAgIHRyeSB7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICB9IGNhdGNoIChUYWJsZUV4aXN0c0V4Y2VwdGlvbiBlKSB7CisgICAgICBnb3RFeGNlcHRpb24gPSB0cnVlOworICAgICAgbXNnID0gZS5nZXRNZXNzYWdlKCk7CisgICAgfQorICAgIGFzc2VydFRydWUoIkRpZG4ndCBnZXQgYSBUYWJsZUV4aXN0c0V4Y2VwdGlvbiEiLCBnb3RFeGNlcHRpb24pOworICAgIGFzc2VydFRydWUoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIG1lc3NhZ2UgIiArIG1zZywgbXNnICE9IG51bGwgJiYKKyAgICAgIG1zZy5jb250YWlucyhnZXROYW1lKCkpKTsKKyAgICAKKyAgICAvLyBOb3cgdHJ5IGFuZCBkbyBjb25jdXJyZW50IGNyZWF0aW9uIHdpdGggYSBidW5jaCBvZiB0aHJlYWRzLgorICAgIGZpbmFsIEhUYWJsZURlc2NyaXB0b3IgdGhyZWFkRGVzYyA9CisgICAgICBuZXcgSFRhYmxlRGVzY3JpcHRvcigidGhyZWFkZWRfIiArIGdldE5hbWUoKSk7CisgICAgdGhyZWFkRGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSkpOworICAgIGludCBjb3VudCA9IDEwOworICAgIFRocmVhZCBbXSB0aHJlYWRzID0gbmV3IFRocmVhZCBbY291bnRdOworICAgIGZpbmFsIEF0b21pY0ludGVnZXIgc3VjY2Vzc2VzID0gbmV3IEF0b21pY0ludGVnZXIoMCk7CisgICAgZmluYWwgQXRvbWljSW50ZWdlciBmYWlsdXJlcyA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgICAgdGhyZWFkc1tpXSA9IG5ldyBUaHJlYWQoSW50ZWdlci50b1N0cmluZyhpKSkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBhZG1pbi5jcmVhdGVUYWJsZSh0aHJlYWREZXNjKTsKKyAgICAgICAgICAgIHN1Y2Nlc3Nlcy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgICB9IGNhdGNoIChUYWJsZUV4aXN0c0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBmYWlsdXJlcy5pbmNyZW1lbnRBbmRHZXQoKTsKKyAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkdvdCBhbiBJT0V4Y2VwdGlvbi4uLiAiICsgZSk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9OworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKyAgICAgIHRocmVhZHNbaV0uc3RhcnQoKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisgICAgICB3aGlsZSh0aHJlYWRzW2ldLmlzQWxpdmUoKSkgeworICAgICAgICB0cnkgeworICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgLy8gQWxsIHRocmVhZHMgYXJlIG5vdyBkZWFkLiAgQ291bnQgdXAgaG93IG1hbnkgdGFibGVzIHdlcmUgY3JlYXRlZCBhbmQKKyAgICAvLyBob3cgbWFueSBmYWlsZWQgdy8gYXBwcm9wcmlhdGUgZXhjZXB0aW9uLgorICAgIGFzc2VydFRydWUoc3VjY2Vzc2VzLmdldCgpID09IDEpOworICAgIGFzc2VydFRydWUoZmFpbHVyZXMuZ2V0KCkgPT0gKGNvdW50IC0gMSkpOworICB9CisgIAorICAvKioKKyAgICogVGVzdCBmb3IgaGFkb29wLTE1ODEgJ0hCQVNFOiBVbm9wZW5hYmxlIHRhYmxlbmFtZSBidWcnLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFRhYmxlTmFtZUNsYXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSArICJTT01FVVBQRVJDQVNFIikpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSkpOworICAgIC8vIEJlZm9yZSBmaXgsIGJlbG93IHdvdWxkIGZhaWwgdGhyb3dpbmcgYSBOb1NlcnZlckZvclJlZ2lvbkV4Y2VwdGlvbi4KKyAgICBAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikKKyAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIGdldE5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogVGVzdCByZWFkIG9ubHkgdGFibGVzCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmVhZE9ubHlUYWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgIGJ5dGVbXSBjb2xOYW1lID0gQnl0ZXMudG9CeXRlcygidGVzdDoiKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoY29sTmFtZSkpOworICAgIGRlc2Muc2V0UmVhZE9ubHkodHJ1ZSk7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBnZXROYW1lKCkpOworICAgIHRyeSB7CisgICAgICBieXRlW10gdmFsdWUgPSBCeXRlcy50b0J5dGVzKCJzb21lZGF0YSIpOworICAgICAgQmF0Y2hVcGRhdGUgdXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKCk7CisgICAgICB1cGRhdGUucHV0KGNvbE5hbWUsIHZhbHVlKTsKKyAgICAgIHRhYmxlLmNvbW1pdCh1cGRhdGUpOworICAgICAgZmFpbCgiQmF0Y2hVcGRhdGUgb24gcmVhZCBvbmx5IHRhYmxlIHN1Y2NlZWRlZCIpOyAgCisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGV4cGVjdGVkCisgICAgfQorICB9CisgIAorICAvKioKKyAgICogVGVzdCB0aGF0IHVzZXIgdGFibGUgbmFtZXMgY2FuIGNvbnRhaW4gJy0nIGFuZCAnLicgc28gbG9uZyBhcyB0aGV5IGRvIG5vdAorICAgKiBzdGFydCB3aXRoIHNhbWUuIEhCQVNFLTc3MQorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFRhYmxlTmFtZXMoKSB7CisgICAgYnl0ZVtdW10gaWxsZWdhbE5hbWVzID0gbmV3IGJ5dGVbXVtdIHsKKyAgICAgICAgQnl0ZXMudG9CeXRlcygiLWJhZCIpLAorICAgICAgICBCeXRlcy50b0J5dGVzKCIuYmFkIiksCisgICAgICAgIEhDb25zdGFudHMuUk9PVF9UQUJMRV9OQU1FLAorICAgICAgICBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRQorICAgIH07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbGxlZ2FsTmFtZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIHRyeSB7CisgICAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKGlsbGVnYWxOYW1lc1tpXSk7CisgICAgICAgIGZhaWwoIkRpZCBub3QgZGV0ZWN0ICciICsgQnl0ZXMudG9TdHJpbmcoaWxsZWdhbE5hbWVzW2ldKSArCisgICAgICAgICAgICAiJyBhcyBhbiBpbGxlZ2FsIHVzZXIgdGFibGUgbmFtZSIpOworICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gZXhwZWN0ZWQKKyAgICAgIH0KKyAgICB9CisgICAgYnl0ZVtdIGxlZ2FsTmFtZSA9IEJ5dGVzLnRvQnl0ZXMoImctb28uZCIpOworICAgIHRyeSB7CisgICAgICBuZXcgSFRhYmxlRGVzY3JpcHRvcihsZWdhbE5hbWUpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICBmYWlsKCJMZWdhbCB1c2VyIHRhYmxlIG5hbWU6ICciICsgQnl0ZXMudG9TdHJpbmcobGVnYWxOYW1lKSArCisgICAgICAgICAgIicgY2F1c2VkIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0Wm9vS2VlcGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UZXN0Wm9vS2VlcGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGE0OWViZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL1Rlc3Rab29LZWVwZXIuamF2YQpAQCAtMCwwICsxLDE1MiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQ29ubmVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSENvbm5lY3Rpb25NYW5hZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyLkhNYXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb25TZXJ2ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS56b29rZWVwZXIuWm9vS2VlcGVyV3JhcHBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5XYXRjaGVkRXZlbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuV2F0Y2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnpvb2tlZXBlci5ab29LZWVwZXI7CisKKy8qKgorICoKKyAqLworcHVibGljIGNsYXNzIFRlc3Rab29LZWVwZXIgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVtcHR5V2F0Y2hlciBpbXBsZW1lbnRzIFdhdGNoZXIgeworICAgIHB1YmxpYyBFbXB0eVdhdGNoZXIoKSB7fQorICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoV2F0Y2hlZEV2ZW50IGV2ZW50KSB7fQorICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0T3Blbk1ldGFUYWJsZShmYWxzZSk7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgfQorCisgIC8qKiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFdyaXRlc1Jvb3RSZWdpb25Mb2NhdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgWm9vS2VlcGVyV3JhcHBlciB6b29LZWVwZXIgPSBuZXcgWm9vS2VlcGVyV3JhcHBlcihjb25mKTsKKworICAgIGJvb2xlYW4gb3V0T2ZTYWZlTW9kZSA9IHpvb0tlZXBlci5jaGVja091dE9mU2FmZU1vZGUoKTsKKyAgICBhc3NlcnRGYWxzZShvdXRPZlNhZmVNb2RlKTsKKworICAgIEhTZXJ2ZXJBZGRyZXNzIHpvb0tlZXBlclJvb3RBZGRyZXNzID0gem9vS2VlcGVyLnJlYWRSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICBhc3NlcnROdWxsKHpvb0tlZXBlclJvb3RBZGRyZXNzKTsKKworICAgIEhNYXN0ZXIgbWFzdGVyID0gY2x1c3Rlci5nZXRNYXN0ZXIoKTsKKyAgICBIU2VydmVyQWRkcmVzcyBtYXN0ZXJSb290QWRkcmVzcyA9IG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKTsKKyAgICBhc3NlcnROdWxsKG1hc3RlclJvb3RBZGRyZXNzKTsKKworICAgIG5ldyBIVGFibGUoY29uZiwgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpOworCisgICAgb3V0T2ZTYWZlTW9kZSA9IHpvb0tlZXBlci5jaGVja091dE9mU2FmZU1vZGUoKTsKKyAgICBhc3NlcnRUcnVlKG91dE9mU2FmZU1vZGUpOworCisgICAgem9vS2VlcGVyUm9vdEFkZHJlc3MgPSB6b29LZWVwZXIucmVhZFJvb3RSZWdpb25Mb2NhdGlvbigpOworICAgIGFzc2VydE5vdE51bGwoem9vS2VlcGVyUm9vdEFkZHJlc3MpOworCisgICAgbWFzdGVyUm9vdEFkZHJlc3MgPSBtYXN0ZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCk7CisgICAgYXNzZXJ0RXF1YWxzKG1hc3RlclJvb3RBZGRyZXNzLCB6b29LZWVwZXJSb290QWRkcmVzcyk7CisgIH0KKworICAvKioKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFBhcmVudEV4aXN0cygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29uZi5zZXQoInpvb2tlZXBlci56bm9kZS5zYWZlbW9kZSIsICIvYS9iL2MvZC9lIik7CisgICAgWm9vS2VlcGVyV3JhcHBlciB6b29LZWVwZXIgPSBuZXcgWm9vS2VlcGVyV3JhcHBlcihjb25mKTsKKyAgICBhc3NlcnRUcnVlKHpvb0tlZXBlci53cml0ZU91dE9mU2FmZU1vZGUoKSk7CisgIH0KKworICAvKioKKyAgICogU2VlIEhCQVNFLTEyMzIgYW5kIGh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvaGFkb29wL1pvb0tlZXBlci9GQVEjNC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q2xpZW50U2Vzc2lvbkV4cGlyZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBuZXcgSFRhYmxlKGNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKworICAgIFN0cmluZyBxdW9ydW1TZXJ2ZXJzID0gWm9vS2VlcGVyV3JhcHBlci5nZXRRdW9ydW1TZXJ2ZXJzKCk7CisgICAgaW50IHNlc3Npb25UaW1lb3V0ID0gY29uZi5nZXRJbnQoInpvb2tlZXBlci5zZXNzaW9uLnRpbWVvdXQiLCAyICogMTAwMCk7CisgICAgV2F0Y2hlciB3YXRjaGVyID0gbmV3IEVtcHR5V2F0Y2hlcigpOworICAgIEhDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSBIQ29ubmVjdGlvbk1hbmFnZXIuZ2V0Q29ubmVjdGlvbihjb25mKTsKKyAgICBab29LZWVwZXJXcmFwcGVyIGNvbm5lY3Rpb25aSyA9IGNvbm5lY3Rpb24uZ2V0Wm9vS2VlcGVyV3JhcHBlcigpOworICAgIGxvbmcgc2Vzc2lvbklEID0gY29ubmVjdGlvblpLLmdldFNlc3Npb25JRCgpOworICAgIGJ5dGVbXSBwYXNzd29yZCA9IGNvbm5lY3Rpb25aSy5nZXRTZXNzaW9uUGFzc3dvcmQoKTsKKworICAgIFpvb0tlZXBlciB6ayA9IG5ldyBab29LZWVwZXIocXVvcnVtU2VydmVycywgc2Vzc2lvblRpbWVvdXQsIHdhdGNoZXIsIHNlc3Npb25JRCwgcGFzc3dvcmQpOworICAgIHprLmNsb3NlKCk7CisKKyAgICBUaHJlYWQuc2xlZXAoc2Vzc2lvblRpbWVvdXQgKiAzKTsKKworICAgIFN5c3RlbS5lcnIucHJpbnRsbigiWm9vS2VlcGVyIHNob3VsZCBoYXZlIHRpbWVkIG91dCIpOworICAgIGNvbm5lY3Rpb24ucmVsb2NhdGVSZWdpb24oSENvbnN0YW50cy5ST09UX1RBQkxFX05BTUUsIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSk7CisgIH0KKworICAvKioKKyAgICoKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RSZWdpb25TZXJ2ZXJTZXNzaW9uRXhwaXJlZCgpIHsKKyAgICB0cnkgeworICAgICAgbmV3IEhUYWJsZShjb25mLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSk7CisgIAorICAgICAgU3RyaW5nIHF1b3J1bVNlcnZlcnMgPSBab29LZWVwZXJXcmFwcGVyLmdldFF1b3J1bVNlcnZlcnMoKTsKKyAgICAgIGludCBzZXNzaW9uVGltZW91dCA9IGNvbmYuZ2V0SW50KCJ6b29rZWVwZXIuc2Vzc2lvbi50aW1lb3V0IiwgMiAqIDEwMDApOworICAKKyAgICAgIFdhdGNoZXIgd2F0Y2hlciA9IG5ldyBFbXB0eVdhdGNoZXIoKTsKKyAgICAgIEhSZWdpb25TZXJ2ZXIgcnMgPSBjbHVzdGVyLmdldFJlZ2lvblNlcnZlcigwKTsKKyAgICAgIFpvb0tlZXBlcldyYXBwZXIgcnNaSyA9IHJzLmdldFpvb0tlZXBlcldyYXBwZXIoKTsKKyAgICAgIGxvbmcgc2Vzc2lvbklEID0gcnNaSy5nZXRTZXNzaW9uSUQoKTsKKyAgICAgIGJ5dGVbXSBwYXNzd29yZCA9IHJzWksuZ2V0U2Vzc2lvblBhc3N3b3JkKCk7CisgIAorICAgICAgWm9vS2VlcGVyIHprID0gbmV3IFpvb0tlZXBlcihxdW9ydW1TZXJ2ZXJzLCBzZXNzaW9uVGltZW91dCwgd2F0Y2hlciwgc2Vzc2lvbklELCBwYXNzd29yZCk7CisgICAgICB6ay5jbG9zZSgpOworCisgICAgICBUaHJlYWQuc2xlZXAoc2Vzc2lvblRpbWVvdXQgKiAzKTsKKworICAgICAgbmV3IEhUYWJsZShjb25mLCBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSk7CisgIAorICAgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoInRlc3QiKTsKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yIGZhbWlseSA9IG5ldyBIQ29sdW1uRGVzY3JpcHRvcigiZmFtOiIpOworICAgICAgZGVzYy5hZGRGYW1pbHkoZmFtaWx5KTsKKyAgICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworICAKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoInRlc3QiKTsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKCJ0ZXN0cm93Iik7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoImZhbTpjb2wiLCBCeXRlcy50b0J5dGVzKCJ0ZXN0ZGF0YSIpKTsKKyAgICAgIHRhYmxlLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICBmYWlsKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9UaW1lc3RhbXBUZXN0QmFzZS5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGltZXN0YW1wVGVzdEJhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2VjYTA5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvVGltZXN0YW1wVGVzdEJhc2UuamF2YQpAQCAtMCwwICsxLDIzMCBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRlc3RzIHVzZXIgc3BlY2lmaWFibGUgdGltZSBzdGFtcHMgcHV0dGluZywgZ2V0dGluZyBhbmQgc2Nhbm5pbmcuICBBbHNvCisgKiB0ZXN0cyBzYW1lIGluIHByZXNlbmNlIG9mIGRlbGV0ZXMuICBUZXN0IGNvcmVzIGFyZSB3cml0dGVuIHNvIGNhbiBiZQorICogcnVuIGFnYWluc3QgYW4gSFJlZ2lvbiBhbmQgYWdhaW5zdCBhbiBIVGFibGU6IGkuZS4gYm90aCBsb2NhbCBhbmQgcmVtb3RlLgorICovCitwdWJsaWMgY2xhc3MgVGltZXN0YW1wVGVzdEJhc2UgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUMCA9IDEwTDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUMSA9IDEwMEw7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgVDIgPSAyMDBMOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTl9OQU1FID0gImNvbnRlbnRzOiI7CisgIAorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTFVNTiA9IEJ5dGVzLnRvQnl0ZXMoQ09MVU1OX05BTUUpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIFJPVyA9IEJ5dGVzLnRvQnl0ZXMoInJvdyIpOworCisgICAgLyoKKyAgICogUnVuIHRlc3QgdGhhdCBkZWxldGUgd29ya3MgYWNjb3JkaW5nIHRvIGRlc2NyaXB0aW9uIGluIDxhCisgICAqIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEFET09QLTE3ODQiPmhhZG9vcC0xNzg0PC9hPi4KKyAgICogQHBhcmFtIGluY29tbW9uCisgICAqIEBwYXJhbSBmbHVzaGVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBkb1Rlc3REZWxldGUoZmluYWwgSW5jb21tb24gaW5jb21tb24sIEZsdXNoQ2FjaGUgZmx1c2hlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBBZGQgdmFsdWVzIGF0IHZhcmlvdXMgdGltZXN0YW1wcyAoVmFsdWVzIGFyZSB0aW1lc3RhbXBlcyBhcyBieXRlcykuCisgICAgcHV0KGluY29tbW9uLCBUMCk7CisgICAgcHV0KGluY29tbW9uLCBUMSk7CisgICAgcHV0KGluY29tbW9uLCBUMik7CisgICAgcHV0KGluY29tbW9uKTsKKyAgICAvLyBWZXJpZnkgdGhhdCByZXR1cm5lZCB2ZXJzaW9ucyBtYXRjaCBwYXNzZWQgdGltZXN0YW1wcy4KKyAgICBhc3NlcnRWZXJzaW9ucyhpbmNvbW1vbiwgbmV3IGxvbmcgW10ge0hDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgVDIsIFQxfSk7CisgICAgLy8gSWYgSSBkZWxldGUgdy9vIHNwZWNpZnlpbmcgYSB0aW1lc3RhbXAsIHRoaXMgbWVhbnMgSSdtIGRlbGV0aW5nIHRoZQorICAgIC8vIGxhdGVzdC4KKyAgICBkZWxldGUoaW5jb21tb24pOworICAgIC8vIFZlcmlmeSB0aGF0IEkgZ2V0IGJhY2sgVDIgdGhyb3VnaCBUMSAtLSB0aGF0IHRoZSBsYXRlc3QgdmVyc2lvbiBoYXMKKyAgICAvLyBiZWVuIGRlbGV0ZWQuCisgICAgYXNzZXJ0VmVyc2lvbnMoaW5jb21tb24sIG5ldyBsb25nIFtdIHtUMiwgVDEsIFQwfSk7CisgICAgCisgICAgLy8gRmx1c2ggZXZlcnl0aGluZyBvdXQgdG8gZGlzayBhbmQgdGhlbiByZXRyeQorICAgIGZsdXNoZXIuZmx1c2hjYWNoZSgpOworICAgIGFzc2VydFZlcnNpb25zKGluY29tbW9uLCBuZXcgbG9uZyBbXSB7VDIsIFQxLCBUMH0pOworICAgIAorICAgIC8vIE5vdyBhZGQsIGJhY2sgYSBsYXRlc3Qgc28gSSBjYW4gdGVzdCByZW1vdmUgb3RoZXIgdGhhbiB0aGUgbGF0ZXN0LgorICAgIHB1dChpbmNvbW1vbik7CisgICAgYXNzZXJ0VmVyc2lvbnMoaW5jb21tb24sIG5ldyBsb25nIFtdIHtIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIFQyLCBUMX0pOworICAgIGRlbGV0ZShpbmNvbW1vbiwgVDIpOworICAgIGFzc2VydFZlcnNpb25zKGluY29tbW9uLCBuZXcgbG9uZyBbXSB7SENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBUMSwgVDB9KTsKKyAgICAvLyBGbHVzaCBldmVyeXRoaW5nIG91dCB0byBkaXNrIGFuZCB0aGVuIHJldHJ5CisgICAgZmx1c2hlci5mbHVzaGNhY2hlKCk7CisgICAgYXNzZXJ0VmVyc2lvbnMoaW5jb21tb24sIG5ldyBsb25nIFtdIHtIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIFQxLCBUMH0pOworICAgIAorICAgIC8vIE5vdyB0cnkgZGVsZXRpbmcgYWxsIGZyb20gVDIgYmFjayBpbmNsdXNpdmUgKFdlIGZpcnN0IG5lZWQgdG8gYWRkIFQyCisgICAgLy8gYmFjayBpbnRvIHRoZSBtaXggYW5kIHRvIG1ha2UgdGhpbmdzIGEgbGl0dGxlIGludGVyZXN0aW5nLCBkZWxldGUgYW5kCisgICAgLy8gdGhlbiByZWFkZCBUMS4KKyAgICBwdXQoaW5jb21tb24sIFQyKTsKKyAgICBkZWxldGUoaW5jb21tb24sIFQxKTsKKyAgICBwdXQoaW5jb21tb24sIFQxKTsKKyAgICBpbmNvbW1vbi5kZWxldGVBbGwoUk9XLCBDT0xVTU4sIFQyKTsKKyAgICAvLyBTaG91bGQgb25seSBiZSBjdXJyZW50IHZhbHVlIGluIHNldC4gIEFzc2VydCB0aGlzIGlzIHNvCisgICAgYXNzZXJ0T25seUxhdGVzdChpbmNvbW1vbiwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKTsKKyAgICAKKyAgICAvLyBGbHVzaCBldmVyeXRoaW5nIG91dCB0byBkaXNrIGFuZCB0aGVuIHJlZG8gYWJvdmUgdGVzdHMKKyAgICBmbHVzaGVyLmZsdXNoY2FjaGUoKTsKKyAgICBhc3NlcnRPbmx5TGF0ZXN0KGluY29tbW9uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydE9ubHlMYXRlc3QoZmluYWwgSW5jb21tb24gaW5jb21tb24sCisgICAgZmluYWwgbG9uZyBjdXJyZW50VGltZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDZWxsIFtdIGNlbGxWYWx1ZXMgPSBpbmNvbW1vbi5nZXQoUk9XLCBDT0xVTU4sIDMvKkFzayBmb3IgdG9vIG11Y2gqLyk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGNlbGxWYWx1ZXMubGVuZ3RoKTsKKyAgICBsb25nIHRpbWUgPSBCeXRlcy50b0xvbmcoY2VsbFZhbHVlc1swXS5nZXRWYWx1ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHModGltZSwgY3VycmVudFRpbWUpOworICAgIGFzc2VydE51bGwoaW5jb21tb24uZ2V0KFJPVywgQ09MVU1OLCBUMSwgMyAvKlRvbyBtYW55Ki8pKTsKKyAgICBhc3NlcnRUcnVlKGFzc2VydFNjYW5Db250ZW50VGltZXN0YW1wKGluY29tbW9uLCBUMSkgPT0gMCk7CisgIH0KKyAgCisgIC8qCisgICAqIEFzc2VydCB0aGF0IHJldHVybmVkIHZlcnNpb25zIG1hdGNoIHBhc3NlZCBpbiB0aW1lc3RhbXBzIGFuZCB0aGF0IHJlc3VsdHMKKyAgICogYXJlIHJldHVybmVkIGluIHRoZSByaWdodCBvcmRlci4gIEFzc2VydCB0aGF0IHZhbHVlcyB3aGVuIGNvbnZlcnRlZCB0bworICAgKiBsb25ncyBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBwYXNzZWQgdGltZXN0YW1wLgorICAgKiBAcGFyYW0gcgorICAgKiBAcGFyYW0gdHNzCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBhc3NlcnRWZXJzaW9ucyhmaW5hbCBJbmNvbW1vbiBpbmNvbW1vbiwgZmluYWwgbG9uZyBbXSB0c3MpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQXNzZXJ0IHRoYXQgJ2xhdGVzdCcgaXMgd2hhdCB3ZSBleHBlY3QuCisgICAgYnl0ZSBbXSBieXRlcyA9IGluY29tbW9uLmdldChST1csIENPTFVNTikuZ2V0VmFsdWUoKTsKKyAgICBhc3NlcnRFcXVhbHMoQnl0ZXMudG9Mb25nKGJ5dGVzKSwgdHNzWzBdKTsKKyAgICAvLyBOb3cgYXNzZXJ0IHRoYXQgaWYgd2UgYXNrIGZvciBtdWx0aXBsZSB2ZXJzaW9ucywgdGhhdCB0aGV5IGNvbWUgb3V0IGluCisgICAgLy8gb3JkZXIuCisgICAgQ2VsbFtdIGNlbGxWYWx1ZXMgPSBpbmNvbW1vbi5nZXQoUk9XLCBDT0xVTU4sIHRzcy5sZW5ndGgpOworICAgIGFzc2VydEVxdWFscyh0c3MubGVuZ3RoLCBjZWxsVmFsdWVzLmxlbmd0aCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjZWxsVmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBsb25nIHRzID0gQnl0ZXMudG9Mb25nKGNlbGxWYWx1ZXNbaV0uZ2V0VmFsdWUoKSk7CisgICAgICBhc3NlcnRFcXVhbHModHMsIHRzc1tpXSk7CisgICAgfQorICAgIC8vIFNwZWNpZnkgYSB0aW1lc3RhbXAgZ2V0IG11bHRpcGxlIHZlcnNpb25zLgorICAgIGNlbGxWYWx1ZXMgPSBpbmNvbW1vbi5nZXQoUk9XLCBDT0xVTU4sIHRzc1swXSwgY2VsbFZhbHVlcy5sZW5ndGggLSAxKTsKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IGNlbGxWYWx1ZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIGxvbmcgdHMgPSBCeXRlcy50b0xvbmcoY2VsbFZhbHVlc1tpXS5nZXRWYWx1ZSgpKTsKKyAgICAgIGFzc2VydEVxdWFscyh0cywgdHNzW2ldKTsKKyAgICB9CisgICAgLy8gVGVzdCBzY2FubmVyIHJldHVybnMgZXhwZWN0ZWQgdmVyc2lvbgorICAgIGFzc2VydFNjYW5Db250ZW50VGltZXN0YW1wKGluY29tbW9uLCB0c3NbMF0pOworICB9CisgIAorICAvKgorICAgKiBSdW4gdGVzdCBzY2FubmluZyBkaWZmZXJlbnQgdGltZXN0YW1wcy4KKyAgICogQHBhcmFtIGluY29tbW9uCisgICAqIEBwYXJhbSBmbHVzaGVyCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBkb1Rlc3RUaW1lc3RhbXBTY2FubmluZyhmaW5hbCBJbmNvbW1vbiBpbmNvbW1vbiwKKyAgICBmaW5hbCBGbHVzaENhY2hlIGZsdXNoZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQWRkIGEgY291cGxlIG9mIHZhbHVlcyBmb3IgdGhyZWUgZGlmZmVyZW50IHRpbWVzdGFtcHMuCisgICAgcHV0KGluY29tbW9uLCBUMCk7CisgICAgcHV0KGluY29tbW9uLCBUMSk7CisgICAgcHV0KGluY29tbW9uLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgIC8vIEdldCBjb3VudCBvZiBsYXRlc3QgaXRlbXMuCisgICAgaW50IGNvdW50ID0gYXNzZXJ0U2NhbkNvbnRlbnRUaW1lc3RhbXAoaW5jb21tb24sCisgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgIC8vIEFzc2VydCBJIGdldCBzYW1lIGNvdW50IHdoZW4gSSBzY2FuIGF0IGVhY2ggdGltZXN0YW1wLgorICAgIGFzc2VydEVxdWFscyhjb3VudCwgYXNzZXJ0U2NhbkNvbnRlbnRUaW1lc3RhbXAoaW5jb21tb24sIFQwKSk7CisgICAgYXNzZXJ0RXF1YWxzKGNvdW50LCBhc3NlcnRTY2FuQ29udGVudFRpbWVzdGFtcChpbmNvbW1vbiwgVDEpKTsKKyAgICAvLyBGbHVzaCBldmVyeXRoaW5nIG91dCB0byBkaXNrIGFuZCB0aGVuIHJldHJ5CisgICAgZmx1c2hlci5mbHVzaGNhY2hlKCk7CisgICAgYXNzZXJ0RXF1YWxzKGNvdW50LCBhc3NlcnRTY2FuQ29udGVudFRpbWVzdGFtcChpbmNvbW1vbiwgVDApKTsKKyAgICBhc3NlcnRFcXVhbHMoY291bnQsIGFzc2VydFNjYW5Db250ZW50VGltZXN0YW1wKGluY29tbW9uLCBUMSkpOworICB9CisgIAorICAvKgorICAgKiBBc3NlcnQgdGhhdCB0aGUgc2NhbiByZXR1cm5zIG9ubHkgdmFsdWVzIDwgdGltZXN0YW1wLiAKKyAgICogQHBhcmFtIHIKKyAgICogQHBhcmFtIHRzCisgICAqIEByZXR1cm4gQ291bnQgb2YgaXRlbXMgc2Nhbm5lZC4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgYXNzZXJ0U2NhbkNvbnRlbnRUaW1lc3RhbXAoZmluYWwgSW5jb21tb24gaW4sIGZpbmFsIGxvbmcgdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU2Nhbm5lckluY29tbW9uIHNjYW5uZXIgPQorICAgICAgaW4uZ2V0U2Nhbm5lcihDT0xVTU5TLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywgdHMpOworICAgIGludCBjb3VudCA9IDA7CisgICAgdHJ5IHsKKyAgICAgIC8vIFRPRE8gRklYCisvLyAgICAgIEhTdG9yZUtleSBrZXkgPSBuZXcgSFN0b3JlS2V5KCk7CisvLyAgICAgIFRyZWVNYXA8Ynl0ZSBbXSwgQ2VsbD52YWx1ZSA9CisvLyAgICAgICAgbmV3IFRyZWVNYXA8Ynl0ZSBbXSwgQ2VsbD4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisvLyAgICAgIHdoaWxlIChzY2FubmVyLm5leHQoa2V5LCB2YWx1ZSkpIHsKKy8vICAgICAgICBhc3NlcnRUcnVlKGtleS5nZXRUaW1lc3RhbXAoKSA8PSB0cyk7CisvLyAgICAgICAgLy8gQ29udGVudCBtYXRjaGVzIHRoZSBrZXkgb3IgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLgorLy8gICAgICAgIC8vIChLZXkgZG9lcyBub3QgbWF0Y2ggY29udGVudCBpZiB3ZSAncHV0JyB3aXRoIExBVEVTVF9USU1FU1RBTVApLgorLy8gICAgICAgIGxvbmcgbCA9IEJ5dGVzLnRvTG9uZyh2YWx1ZS5nZXQoQ09MVU1OKS5nZXRWYWx1ZSgpKTsKKy8vICAgICAgICBhc3NlcnRUcnVlKGtleS5nZXRUaW1lc3RhbXAoKSA9PSBsIHx8CisvLyAgICAgICAgICBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAgPT0gbCk7CisvLyAgICAgICAgY291bnQrKzsKKy8vICAgICAgICB2YWx1ZS5jbGVhcigpOworLy8gICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsgCisgICAgfQorICAgIHJldHVybiBjb3VudDsKKyAgfQorICAKKyAgcHVibGljIHN0YXRpYyB2b2lkIHB1dChmaW5hbCBJbmNvbW1vbiBsb2FkZXIsIGZpbmFsIGxvbmcgdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcHV0KGxvYWRlciwgQnl0ZXMudG9CeXRlcyh0cyksIHRzKTsKKyAgfQorICAKKyAgcHVibGljIHN0YXRpYyB2b2lkIHB1dChmaW5hbCBJbmNvbW1vbiBsb2FkZXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbG9uZyB0cyA9IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUDsKKyAgICBwdXQobG9hZGVyLCBCeXRlcy50b0J5dGVzKHRzKSwgdHMpOworICB9CisgIAorICAvKgorICAgKiBQdXQgdmFsdWVzLgorICAgKiBAcGFyYW0gbG9hZGVyCisgICAqIEBwYXJhbSBieXRlcworICAgKiBAcGFyYW0gdHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHB1dChmaW5hbCBJbmNvbW1vbiBsb2FkZXIsIGZpbmFsIGJ5dGUgW10gYnl0ZXMsCisgICAgZmluYWwgbG9uZyB0cykKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IHRzID09IEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCA/IAorICAgICAgbmV3IEJhdGNoVXBkYXRlKFJPVykgOiBuZXcgQmF0Y2hVcGRhdGUoUk9XLCB0cyk7CisgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTiwgYnl0ZXMpOworICAgIGxvYWRlci5jb21taXQoYmF0Y2hVcGRhdGUpOworICB9CisgIAorICBwdWJsaWMgc3RhdGljIHZvaWQgZGVsZXRlKGZpbmFsIEluY29tbW9uIGxvYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxldGUobG9hZGVyLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIGRlbGV0ZShmaW5hbCBJbmNvbW1vbiBsb2FkZXIsIGZpbmFsIGxvbmcgdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSB0cyA9PSBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAgPyAKKyAgICAgIG5ldyBCYXRjaFVwZGF0ZShST1cpIDogbmV3IEJhdGNoVXBkYXRlKFJPVywgdHMpOworICAgIGJhdGNoVXBkYXRlLmRlbGV0ZShDT0xVTU4pOworICAgIGxvYWRlci5jb21taXQoYmF0Y2hVcGRhdGUpOyAgCisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0QmF0Y2hVcGRhdGUuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0QmF0Y2hVcGRhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NjFiZGMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RCYXRjaFVwZGF0ZS5qYXZhCkBAIC0wLDAgKzEsMjE0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IGJhdGNoIHVwZGF0ZXMKKyAqLworcHVibGljIGNsYXNzIFRlc3RCYXRjaFVwZGF0ZSBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFTlRTX1NUUiA9ICJjb250ZW50czoiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTlRFTlRTID0gQnl0ZXMudG9CeXRlcyhDT05URU5UU19TVFIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU01BTExGQU1fU1RSID0gInNtYWxsZmFtOiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gU01BTExGQU0gPSBCeXRlcy50b0J5dGVzKFNNQUxMRkFNX1NUUik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTTUFMTF9MRU5HVEggPSAxOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTkJfQkFUQ0hfUk9XUyA9IDEwOworICBwcml2YXRlIGJ5dGVbXSB2YWx1ZTsKKyAgcHJpdmF0ZSBieXRlW10gc21hbGxWYWx1ZTsKKworICBwcml2YXRlIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG51bGw7CisgIHByaXZhdGUgSFRhYmxlIHRhYmxlID0gbnVsbDsKKworICAvKioKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgVGVzdEJhdGNoVXBkYXRlKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIHN1cGVyKCk7CisgICAgdmFsdWUgPSBCeXRlcy50b0J5dGVzKCJhYmNkIik7CisgICAgc21hbGxWYWx1ZSA9IEJ5dGVzLnRvQnl0ZXMoImEiKTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB0aGlzLmRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcigidGVzdCIpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT05URU5UU19TVFIpKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoU01BTExGQU0sIAorICAgICAgICBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX1ZFUlNJT05TLCAKKyAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9DT01QUkVTU0lPTiwKKyAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9JTl9NRU1PUlksIAorICAgICAgICBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0JMT0NLQ0FDSEUsIFNNQUxMX0xFTkdUSCwgCisgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfVFRMLCBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0JMT09NRklMVEVSKSk7CisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBkZXNjLmdldE5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEJhdGNoVXBkYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCYXRjaFVwZGF0ZSBidSA9IG5ldyBCYXRjaFVwZGF0ZSgicm93MSIpOworICAgIGJ1LnB1dChDT05URU5UUywgdmFsdWUpOworICAgIGJ1LmRlbGV0ZShDT05URU5UUyk7CisgICAgdGFibGUuY29tbWl0KGJ1KTsKKworICAgIGJ1ID0gbmV3IEJhdGNoVXBkYXRlKCJyb3cyIik7CisgICAgYnUucHV0KENPTlRFTlRTLCB2YWx1ZSk7CisgICAgYnl0ZVtdW10gZ2V0Q29sdW1ucyA9IGJ1LmdldENvbHVtbnMoKTsKKyAgICBhc3NlcnRFcXVhbHMoZ2V0Q29sdW1ucy5sZW5ndGgsIDEpOworICAgIGFzc2VydFRydWUoQXJyYXlzLmVxdWFscyhnZXRDb2x1bW5zWzBdLCBDT05URU5UUykpOworICAgIGFzc2VydFRydWUoYnUuaGFzQ29sdW1uKENPTlRFTlRTKSk7CisgICAgYXNzZXJ0RmFsc2UoYnUuaGFzQ29sdW1uKG5ldyBieXRlW10ge30pKTsKKyAgICBieXRlW10gZ2V0VmFsdWUgPSBidS5nZXQoZ2V0Q29sdW1uc1swXSk7CisgICAgYXNzZXJ0VHJ1ZShBcnJheXMuZXF1YWxzKGdldFZhbHVlLCB2YWx1ZSkpOworICAgIHRhYmxlLmNvbW1pdChidSk7CisKKyAgICBieXRlIFtdW10gY29sdW1ucyA9IHsgQ09OVEVOVFMgfTsKKyAgICBTY2FubmVyIHNjYW5uZXIgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICBmb3IgKFJvd1Jlc3VsdCByIDogc2Nhbm5lcikgeworICAgICAgZm9yKE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPiBlOiByLmVudHJ5U2V0KCkpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKEJ5dGVzLnRvU3RyaW5nKHIuZ2V0Um93KCkpICsgIjogcm93OiAiICsgZS5nZXRLZXkoKSArICIgdmFsdWU6ICIgKyAKKyAgICAgICAgICAgIG5ldyBTdHJpbmcoZS5nZXRWYWx1ZSgpLmdldFZhbHVlKCksIEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdEJhdGNoVXBkYXRlTWF4TGVuZ3RoKCkgeworICAgIC8vIFRlc3QgZm9yIGEgc2luZ2xlIGdvb2QgdmFsdWUKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSgicm93MSIpOworICAgIGJhdGNoVXBkYXRlLnB1dChTTUFMTEZBTSwgdmFsdWUpOworICAgIHRyeSB7CisgICAgICB0YWJsZS5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgICAgZmFpbCgiVmFsdWUgaXMgdG9vIGxvbmcsIHNob3VsZCB0aHJvdyBleGNlcHRpb24iKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUaGlzIGlzIGV4cGVjdGVkCisgICAgfQorICAgIC8vIFRyeSB0byBzZWUgaWYgaXQncyBzdGlsbCBpbnNlcnRlZAorICAgIHRyeSB7CisgICAgICBDZWxsIGNlbGwgPSB0YWJsZS5nZXQoInJvdzEiLCBTTUFMTEZBTV9TVFIpOworICAgICAgYXNzZXJ0TnVsbChjZWxsKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgZmFpbCgiVGhpcyBpcyB1bmV4cGVjdGVkIik7CisgICAgfQorICAgIC8vIFRyeSB0byBwdXQgYSBnb29kIHZhbHVlCisgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoInJvdzEiKTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoU01BTExGQU0sIHNtYWxsVmFsdWUpOworICAgIHRyeSB7CisgICAgICB0YWJsZS5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGZhaWwoIlZhbHVlIGlzIGxvbmcgZW5vdWdoLCBzaG91bGQgbm90IHRocm93IGV4Y2VwdGlvbiIpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFJvd3NCYXRjaFVwZGF0ZSgpIHsKKyAgICBBcnJheUxpc3Q8QmF0Y2hVcGRhdGU+IHJvd3NVcGRhdGUgPSBuZXcgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPigpOworICAgIGZvcihpbnQgaSA9IDA7IGkgPCBOQl9CQVRDSF9ST1dTOyBpKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKCJyb3ciK2kpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTlRFTlRTLCB2YWx1ZSk7CisgICAgICByb3dzVXBkYXRlLmFkZChiYXRjaFVwZGF0ZSk7CisgICAgfQorICAgIHRyeSB7CisgICAgICB0YWJsZS5jb21taXQocm93c1VwZGF0ZSk7ICAKKyAgICAKKyAgICAgIGJ5dGUgW11bXSBjb2x1bW5zID0geyBDT05URU5UUyB9OworICAgICAgU2Nhbm5lciBzY2FubmVyID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgICBpbnQgbmJSb3dzID0gMDsKKyAgICAgIGZvcihAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikgUm93UmVzdWx0IHJvdyA6IHNjYW5uZXIpCisgICAgICAgIG5iUm93cysrOworICAgICAgYXNzZXJ0RXF1YWxzKE5CX0JBVENIX1JPV1MsIG5iUm93cyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgZmFpbCgiVGhpcyBpcyB1bmV4cGVjdGVkIDogIiArIGUpOworICAgIH0KKyAgfQorICAKKyAgcHVibGljIHZvaWQgdGVzdFJvd3NCYXRjaFVwZGF0ZUJ1ZmZlcmVkT25lRmx1c2goKSB7CisgICAgdGFibGUuc2V0QXV0b0ZsdXNoKGZhbHNlKTsKKyAgICBBcnJheUxpc3Q8QmF0Y2hVcGRhdGU+IHJvd3NVcGRhdGUgPSBuZXcgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPigpOworICAgIGZvcihpbnQgaSA9IDA7IGkgPCBOQl9CQVRDSF9ST1dTKjEwOyBpKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKCJyb3ciK2kpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTlRFTlRTLCB2YWx1ZSk7CisgICAgICByb3dzVXBkYXRlLmFkZChiYXRjaFVwZGF0ZSk7CisgICAgfQorICAgIHRyeSB7CisgICAgICB0YWJsZS5jb21taXQocm93c1VwZGF0ZSk7ICAKKyAgICAKKyAgICAgIGJ5dGUgW11bXSBjb2x1bW5zID0geyBDT05URU5UUyB9OworICAgICAgU2Nhbm5lciBzY2FubmVyID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgICBpbnQgbmJSb3dzID0gMDsKKyAgICAgIGZvcihAU3VwcHJlc3NXYXJuaW5ncygidW51c2VkIikgUm93UmVzdWx0IHJvdyA6IHNjYW5uZXIpCisgICAgICAgIG5iUm93cysrOworICAgICAgYXNzZXJ0RXF1YWxzKDAsIG5iUm93cyk7ICAKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICAgIAorICAgICAgdGFibGUuZmx1c2hDb21taXRzKCk7CisgICAgICAKKyAgICAgIHNjYW5uZXIgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICAgIG5iUm93cyA9IDA7CisgICAgICBmb3IoQFN1cHByZXNzV2FybmluZ3MoInVudXNlZCIpIFJvd1Jlc3VsdCByb3cgOiBzY2FubmVyKQorICAgICAgICBuYlJvd3MrKzsKKyAgICAgIGFzc2VydEVxdWFscyhOQl9CQVRDSF9ST1dTKjEwLCBuYlJvd3MpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGZhaWwoIlRoaXMgaXMgdW5leHBlY3RlZCA6ICIgKyBlKTsKKyAgICB9CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RSb3dzQmF0Y2hVcGRhdGVCdWZmZXJlZE1hbnlNYW55Rmx1c2hlcygpIHsKKyAgICB0YWJsZS5zZXRBdXRvRmx1c2goZmFsc2UpOworICAgIHRhYmxlLnNldFdyaXRlQnVmZmVyU2l6ZSgxMCk7CisgICAgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPiByb3dzVXBkYXRlID0gbmV3IEFycmF5TGlzdDxCYXRjaFVwZGF0ZT4oKTsKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgTkJfQkFUQ0hfUk9XUyoxMDsgaSsrKSB7CisgICAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSgicm93IitpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT05URU5UUywgdmFsdWUpOworICAgICAgcm93c1VwZGF0ZS5hZGQoYmF0Y2hVcGRhdGUpOworICAgIH0KKyAgICB0cnkgeworICAgICAgdGFibGUuY29tbWl0KHJvd3NVcGRhdGUpOworICAgICAgCisgICAgICB0YWJsZS5mbHVzaENvbW1pdHMoKTsKKyAgICAgIAorICAgICAgYnl0ZSBbXVtdIGNvbHVtbnMgPSB7IENPTlRFTlRTIH07CisgICAgICBTY2FubmVyIHNjYW5uZXIgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICAgIGludCBuYlJvd3MgPSAwOworICAgICAgZm9yKEBTdXBwcmVzc1dhcm5pbmdzKCJ1bnVzZWQiKSBSb3dSZXN1bHQgcm93IDogc2Nhbm5lcikKKyAgICAgICAgbmJSb3dzKys7CisgICAgICBhc3NlcnRFcXVhbHMoTkJfQkFUQ0hfUk9XUyoxMCwgbmJSb3dzKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBmYWlsKCJUaGlzIGlzIHVuZXhwZWN0ZWQgOiAiICsgZSk7CisgICAgfQorICB9CisgIAorICAKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0Rm9yY2VTcGxpdC5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RGb3JjZVNwbGl0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjhkOTE1ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0Rm9yY2VTcGxpdC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGVzdHMgZm9yY2VkIHNwbGl0dGluZyBvZiBIVGFibGUKKyAqLworcHVibGljIGNsYXNzIFRlc3RGb3JjZVNwbGl0IGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gdGFibGVOYW1lID0gQnl0ZXMudG9CeXRlcygidGVzdCIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gY29sdW1uTmFtZSA9IEJ5dGVzLnRvQnl0ZXMoImE6Iik7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB0aGlzLmNvbmYuc2V0SW50KCJoYmFzZS5pby5pbmRleC5pbnRlcnZhbCIsIDMyKTsKKyAgfQorCisgIC8qKgorICAgKiB0aGUgdGVzdAorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiAKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEZvcmNlU3BsaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBjcmVhdGUgdGhlIHRlc3QgdGFibGUKKyAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlTmFtZSk7CisgICAgaHRkLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoY29sdW1uTmFtZSkpOworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICBhZG1pbi5jcmVhdGVUYWJsZShodGQpOworICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVOYW1lKTsKKyAgICBieXRlW10gayA9IG5ldyBieXRlWzNdOworICAgIGZvciAoYnl0ZSBiMSA9ICdhJzsgYjEgPCAneic7IGIxKyspIHsKKyAgICAgIGZvciAoYnl0ZSBiMiA9ICdhJzsgYjIgPCAneic7IGIyKyspIHsKKyAgICAgICAgZm9yIChieXRlIGIzID0gJ2EnOyBiMyA8ICd6JzsgYjMrKykgeworICAgICAgICAgIGtbMF0gPSBiMTsKKyAgICAgICAgICBrWzFdID0gYjI7CisgICAgICAgICAga1syXSA9IGIzOworICAgICAgICAgIEJhdGNoVXBkYXRlIHVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShrKTsKKyAgICAgICAgICB1cGRhdGUucHV0KGNvbHVtbk5hbWUsIGspOworICAgICAgICAgIHRhYmxlLmNvbW1pdCh1cGRhdGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gZ2V0IHRoZSBpbml0aWFsIGxheW91dCAoc2hvdWxkIGp1c3QgYmUgb25lIHJlZ2lvbikKKyAgICBNYXA8SFJlZ2lvbkluZm8sSFNlcnZlckFkZHJlc3M+IG0gPSB0YWJsZS5nZXRSZWdpb25zSW5mbygpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW5pdGlhbCByZWdpb25zICgiICsgbS5zaXplKCkgKyAiKTogIiArIG0pOworICAgIGFzc2VydFRydWUobS5zaXplKCkgPT0gMSk7CisKKyAgICAvLyB0ZWxsIHRoZSBtYXN0ZXIgdG8gc3BsaXQgdGhlIHRhYmxlCisgICAgYWRtaW4uc3BsaXQoQnl0ZXMudG9TdHJpbmcodGFibGVOYW1lKSk7CisKKyAgICAvLyBnaXZlIHNvbWUgdGltZSBmb3IgdGhlIHNwbGl0IHRvIGhhcHBlbgorICAgIFRocmVhZC5zbGVlcCgxNSAqIDEwMDApOworCisgICAgLy8gY2hlY2sgYWdhaW4gICAgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRhYmxlTmFtZSk7CisgICAgbSA9IHRhYmxlLmdldFJlZ2lvbnNJbmZvKCk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJSZWdpb25zIGFmdGVyIHNwbGl0ICgiICsgbS5zaXplKCkgKyAiKTogIiArIG0pOworICAgIC8vIHNob3VsZCBoYXZlIHR3byByZWdpb25zIG5vdworICAgIGFzc2VydFRydWUobS5zaXplKCkgPT0gMik7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0R2V0Um93VmVyc2lvbnMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0R2V0Um93VmVyc2lvbnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjQ4YmIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RHZXRSb3dWZXJzaW9ucy5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIAorICovCitwdWJsaWMgY2xhc3MgVGVzdEdldFJvd1ZlcnNpb25zIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdEdldFJvd1ZlcnNpb25zLmNsYXNzKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBQkxFX05BTUUgPSAidGVzdCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05URU5UU19TVFIgPSAiY29udGVudHM6IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJPVyA9ICJyb3ciOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09MVU1OID0gImNvbnRlbnRzOmNvbnRlbnRzIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUSU1FU1RBTVAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZBTFVFMSA9ICJ2YWx1ZTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFMVUUyID0gInZhbHVlMiI7CisgIHByaXZhdGUgSEJhc2VBZG1pbiBhZG1pbiA9IG51bGw7CisgIHByaXZhdGUgSFRhYmxlIHRhYmxlID0gbnVsbDsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKFRBQkxFX05BTUUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT05URU5UU19TVFIpKTsKKyAgICB0aGlzLmFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgdGhpcy5hZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICB0aGlzLnRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBUQUJMRV9OQU1FKTsKKyAgfQorCisgIC8qKiBAdGhyb3dzIEV4Y2VwdGlvbiAqLworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Um93TXVsdGlwbGVWZXJzaW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUoUk9XLCBUSU1FU1RBTVApOworICAgIGIucHV0KENPTFVNTiwgQnl0ZXMudG9CeXRlcyhWQUxVRTEpKTsKKyAgICB0aGlzLnRhYmxlLmNvbW1pdChiKTsKKyAgICAvLyBTaHV0IGRvd24gYW5kIHJlc3RhcnQgdGhlIEhCYXNlIGNsdXN0ZXIKKyAgICB0aGlzLmNsdXN0ZXIuc2h1dGRvd24oKTsKKyAgICB0aGlzLnpvb0tlZXBlckNsdXN0ZXIuc2h1dGRvd24oKTsKKyAgICBMT0cuZGVidWcoIkhCYXNlIGNsdXN0ZXIgc2h1dCBkb3duIC0tIHJlc3RhcnRpbmciKTsKKyAgICB0aGlzLmhCYXNlQ2x1c3RlclNldHVwKCk7CisgICAgLy8gTWFrZSBhIG5ldyBjb25uZWN0aW9uCisgICAgdGhpcy50YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgVEFCTEVfTkFNRSk7CisgICAgLy8gT3ZlcndyaXRlIHByZXZpb3VzIHZhbHVlCisgICAgYiA9IG5ldyBCYXRjaFVwZGF0ZShST1csIFRJTUVTVEFNUCk7CisgICAgYi5wdXQoQ09MVU1OLCBCeXRlcy50b0J5dGVzKFZBTFVFMikpOworICAgIHRoaXMudGFibGUuY29tbWl0KGIpOworICAgIC8vIE5vdyB2ZXJpZnkgdGhhdCBnZXRSb3cocm93LCBjb2x1bW4sIGxhdGVzdCkgd29ya3MKKyAgICBSb3dSZXN1bHQgciA9IHRhYmxlLmdldFJvdyhST1cpOworICAgIGFzc2VydE5vdE51bGwocik7CisgICAgYXNzZXJ0VHJ1ZShyLnNpemUoKSAhPSAwKTsKKyAgICBDZWxsIGMgPSByLmdldChDT0xVTU4pOworICAgIGFzc2VydE5vdE51bGwoYyk7CisgICAgYXNzZXJ0VHJ1ZShjLmdldFZhbHVlKCkubGVuZ3RoICE9IDApOworICAgIFN0cmluZyB2YWx1ZSA9IEJ5dGVzLnRvU3RyaW5nKGMuZ2V0VmFsdWUoKSk7CisgICAgYXNzZXJ0VHJ1ZSh2YWx1ZS5jb21wYXJlVG8oVkFMVUUyKSA9PSAwKTsKKyAgICAvLyBOb3cgY2hlY2sgZ2V0Um93IHdpdGggbXVsdGlwbGUgdmVyc2lvbnMKKyAgICByID0gdGFibGUuZ2V0Um93KFJPVywgSENvbnN0YW50cy5BTExfVkVSU0lPTlMpOworICAgIGZvciAoTWFwLkVudHJ5PGJ5dGVbXSwgQ2VsbD4gZTogci5lbnRyeVNldCgpKSB7CisgICAgICAvLyBDb2x1bW4gbmFtZQorLy8gICAgICBTeXN0ZW0uZXJyLnByaW50KCIgICIgKyBCeXRlcy50b1N0cmluZyhlLmdldEtleSgpKSk7CisgICAgICBjID0gZS5nZXRWYWx1ZSgpOworICAgICAgCisgICAgICAvLyBOZWVkIHRvIGl0ZXJhdGUgc2luY2UgdGhlcmUgbWF5IGJlIG11bHRpcGxlIHZlcnNpb25zCisgICAgICBmb3IgKEl0ZXJhdG9yPE1hcC5FbnRyeTxMb25nLCBieXRlW10+PiBpdCA9IGMuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIGl0Lmhhc05leHQoKTsgKSB7CisgICAgICAgIE1hcC5FbnRyeTxMb25nLCBieXRlW10+IHYgPSBpdC5uZXh0KCk7CisgICAgICAgIHZhbHVlID0gQnl0ZXMudG9TdHJpbmcodi5nZXRWYWx1ZSgpKTsKKy8vICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiA9ICIgKyB2YWx1ZSk7CisgICAgICAgIGFzc2VydFRydWUoVkFMVUUyLmNvbXBhcmVUbyhCeXRlcy50b1N0cmluZyh2LmdldFZhbHVlKCkpKSA9PSAwKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVGVzdEhUYWJsZS5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RIVGFibGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYWMzYzM5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RIVGFibGUuamF2YQpAQCAtMCwwICsxLDM3NyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5UYWJsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkhiYXNlTWFwV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0cyBIVGFibGUKKyAqLworcHVibGljIGNsYXNzIFRlc3RIVGFibGUgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSBpbXBsZW1lbnRzIEhDb25zdGFudHMgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBIQ29sdW1uRGVzY3JpcHRvciBjb2x1bW4gPQorICAgIG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT0xVTU5fRkFNSUxZKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIG5vc3VjaFRhYmxlID0gQnl0ZXMudG9CeXRlcygibm9zdWNoVGFibGUiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSB0YWJsZUFuYW1lID0gQnl0ZXMudG9CeXRlcygidGFibGVBIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gdGFibGVCbmFtZSA9IEJ5dGVzLnRvQnl0ZXMoInRhYmxlQiIpOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJyb3ciKTsKKyAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBhdHRyTmFtZSA9IEJ5dGVzLnRvQnl0ZXMoIlRFU1RBVFRSIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gYXR0clZhbHVlID0gQnl0ZXMudG9CeXRlcygic29tZXZhbHVlIik7CisKKworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Um93KCkgeworICAgIEhUYWJsZSB0YWJsZSA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhDb2x1bW5EZXNjcmlwdG9yIGNvbHVtbjIgPQorICAgICAgICBuZXcgSENvbHVtbkRlc2NyaXB0b3IoQnl0ZXMudG9CeXRlcygiaW5mbzI6IikpOworICAgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgICAgSFRhYmxlRGVzY3JpcHRvciB0ZXN0VGFibGVBRGVzYyA9CisgICAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlQW5hbWUpOworICAgICAgdGVzdFRhYmxlQURlc2MuYWRkRmFtaWx5KGNvbHVtbik7CisgICAgICB0ZXN0VGFibGVBRGVzYy5hZGRGYW1pbHkoY29sdW1uMik7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZSh0ZXN0VGFibGVBRGVzYyk7CisgICAgICAKKyAgICAgIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCB0YWJsZUFuYW1lKTsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdyk7CisgICAgICAKKyAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCA1OyBpKyspCisgICAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5fRkFNSUxZX1NUUitpLCBCeXRlcy50b0J5dGVzKGkpKTsKKyAgICAgIAorICAgICAgdGFibGUuY29tbWl0KGJhdGNoVXBkYXRlKTsKKworICAgICAgYXNzZXJ0VHJ1ZSh0YWJsZS5leGlzdHMocm93KSk7CisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgNTsgaSsrKQorICAgICAgICBhc3NlcnRUcnVlKHRhYmxlLmV4aXN0cyhyb3csIEJ5dGVzLnRvQnl0ZXMoQ09MVU1OX0ZBTUlMWV9TVFIraSkpKTsKKworICAgICAgUm93UmVzdWx0IHJlc3VsdCA9IG51bGw7CisgICAgICByZXN1bHQgPSB0YWJsZS5nZXRSb3cocm93LCAgbmV3IGJ5dGVbXVtdIHtDT0xVTU5fRkFNSUxZfSk7CisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgNTsgaSsrKQorICAgICAgICBhc3NlcnRUcnVlKHJlc3VsdC5jb250YWluc0tleShCeXRlcy50b0J5dGVzKENPTFVNTl9GQU1JTFlfU1RSK2kpKSk7CisgICAgICAKKyAgICAgIHJlc3VsdCA9IHRhYmxlLmdldFJvdyhyb3cpOworICAgICAgZm9yKGludCBpID0gMDsgaSA8IDU7IGkrKykKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuY29udGFpbnNLZXkoQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUitpKSkpOworCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KCJpbmZvMjphIiwgQnl0ZXMudG9CeXRlcygiYSIpKTsKKyAgICAgIHRhYmxlLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICAKKyAgICAgIHJlc3VsdCA9IHRhYmxlLmdldFJvdyhyb3csIG5ldyBieXRlW11bXSB7IENPTFVNTl9GQU1JTFksCisgICAgICAgICAgQnl0ZXMudG9CeXRlcygiaW5mbzI6YSIpIH0pOworICAgICAgZm9yKGludCBpID0gMDsgaSA8IDU7IGkrKykKKyAgICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuY29udGFpbnNLZXkoQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUitpKSkpOworICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuY29udGFpbnNLZXkoQnl0ZXMudG9CeXRlcygiaW5mbzI6YSIpKSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIGZhaWwoIlNob3VsZCBub3QgaGF2ZSBhbnkgZXhjZXB0aW9uICIgKworICAgICAgICBlLmdldENsYXNzKCkpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiB0aGUgdGVzdAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SFRhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlW10gdmFsdWUgPSAidmFsdWUiLmdldEJ5dGVzKFVURjhfRU5DT0RJTkcpOworICAgIAorICAgIHRyeSB7CisgICAgICBuZXcgSFRhYmxlKGNvbmYsIG5vc3VjaFRhYmxlKTsKKyAgICAgIAorICAgIH0gY2F0Y2ggKFRhYmxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgLy8gZXhwZWN0ZWQKKworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICBmYWlsKCk7CisgICAgfQorICAgIAorICAgIEhUYWJsZURlc2NyaXB0b3IgdGFibGVBZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlQW5hbWUpOworICAgIHRhYmxlQWRlc2MuYWRkRmFtaWx5KGNvbHVtbik7CisgICAgCisgICAgSFRhYmxlRGVzY3JpcHRvciB0YWJsZUJkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IodGFibGVCbmFtZSk7CisgICAgdGFibGVCZGVzYy5hZGRGYW1pbHkoY29sdW1uKTsKKworICAgIC8vIGNyZWF0ZSBhIGNvdXBsZSBvZiB0YWJsZXMKKyAgICAKKyAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgYWRtaW4uY3JlYXRlVGFibGUodGFibGVBZGVzYyk7CisgICAgYWRtaW4uY3JlYXRlVGFibGUodGFibGVCZGVzYyk7CisgICAgCisgICAgLy8gcHV0IHNvbWUgZGF0YSBpbnRvIHRhYmxlIEEKKyAgICAKKyAgICBIVGFibGUgYSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVBbmFtZSk7CisgICAgCisgICAgLy8gQXNzZXJ0IHRoZSBtZXRhZGF0YSBpcyBnb29kLgorICAgIEhUYWJsZURlc2NyaXB0b3IgbWV0YSA9CisgICAgICBhLmdldENvbm5lY3Rpb24oKS5nZXRIVGFibGVEZXNjcmlwdG9yKHRhYmxlQWRlc2MuZ2V0TmFtZSgpKTsKKyAgICBhc3NlcnRUcnVlKG1ldGEuZXF1YWxzKHRhYmxlQWRlc2MpKTsKKyAgICAKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5fRkFNSUxZLCB2YWx1ZSk7CisgICAgYS5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIAorICAgIC8vIG9wZW4gYSBuZXcgY29ubmVjdGlvbiB0byBBIGFuZCBhIGNvbm5lY3Rpb24gdG8gYgorICAgIAorICAgIEhUYWJsZSBuZXdBID0gbmV3IEhUYWJsZShjb25mLCB0YWJsZUFuYW1lKTsKKyAgICBIVGFibGUgYiA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVCbmFtZSk7CisKKyAgICAvLyBjb3B5IGRhdGEgZnJvbSBBIHRvIEIKKyAgICAKKyAgICBTY2FubmVyIHMgPQorICAgICAgbmV3QS5nZXRTY2FubmVyKENPTFVNTl9GQU1JTFlfQVJSQVksIEVNUFRZX1NUQVJUX1JPVyk7CisgICAgCisgICAgdHJ5IHsKKyAgICAgIGZvciAoUm93UmVzdWx0IHIgOiBzKSB7CisgICAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHIuZ2V0Um93KCkpOworICAgICAgICBmb3IoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGU6IHIuZW50cnlTZXQoKSkgeworICAgICAgICAgIGJhdGNoVXBkYXRlLnB1dChlLmdldEtleSgpLCBlLmdldFZhbHVlKCkuZ2V0VmFsdWUoKSk7CisgICAgICAgIH0KKyAgICAgICAgYi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICAgIAorICAgIC8vIE9wZW5pbmcgYSBuZXcgY29ubmVjdGlvbiB0byBBIHdpbGwgY2F1c2UgdGhlIHRhYmxlcyB0byBiZSByZWxvYWRlZAorCisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSBhbm90aGVyQSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVBbmFtZSk7CisgICAgICBhbm90aGVyQS5nZXQocm93LCBDT0xVTU5fRkFNSUxZKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIGZhaWwoKTsKKyAgICB9CisgICAgCisgICAgLy8gV2UgY2FuIHN0aWxsIGFjY2VzcyBBIHRocm91Z2ggbmV3QSBiZWNhdXNlIGl0IGhhcyB0aGUgdGFibGUgaW5mb3JtYXRpb24KKyAgICAvLyBjYWNoZWQuIEFuZCBpZiBpdCBuZWVkcyB0byByZWNhbGlicmF0ZSwgdGhhdCB3aWxsIGNhdXNlIHRoZSBpbmZvcm1hdGlvbgorICAgIC8vIHRvIGJlIHJlbG9hZGVkLgorCisgICAgLy8gVGVzdCB1c2VyIG1ldGFkYXRhCisKKyAgICB0cnkgeworICAgICAgLy8gbWFrZSBhIG1vZGlmaWFibGUgZGVzY3JpcHRvcgorICAgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoYS5nZXRUYWJsZURlc2NyaXB0b3IoKSk7CisgICAgICAvLyBvZmZsaW5lIHRoZSB0YWJsZQorICAgICAgYWRtaW4uZGlzYWJsZVRhYmxlKHRhYmxlQW5hbWUpOworICAgICAgLy8gYWRkIGEgdXNlciBhdHRyaWJ1dGUgdG8gSFRECisgICAgICBkZXNjLnNldFZhbHVlKGF0dHJOYW1lLCBhdHRyVmFsdWUpOworICAgICAgLy8gYWRkIGEgdXNlciBhdHRyaWJ1dGUgdG8gSENECisgICAgICBmb3IgKEhDb2x1bW5EZXNjcmlwdG9yIGM6IGRlc2MuZ2V0RmFtaWxpZXMoKSkKKyAgICAgICAgYy5zZXRWYWx1ZShhdHRyTmFtZSwgYXR0clZhbHVlKTsKKyAgICAgIC8vIHVwZGF0ZSBtZXRhZGF0YSBmb3IgYWxsIHJlZ2lvbnMgb2YgdGhpcyB0YWJsZQorICAgICAgYWRtaW4ubW9kaWZ5VGFibGUodGFibGVBbmFtZSwgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfU0VUX0hURCwgZGVzYyk7CisgICAgICAvLyBlbmFibGUgdGhlIHRhYmxlCisgICAgICBhZG1pbi5lbmFibGVUYWJsZSh0YWJsZUFuYW1lKTsKKworICAgICAgLy8gdGVzdCB0aGF0IGF0dHJpYnV0ZSBjaGFuZ2VzIHdlcmUgYXBwbGllZAorICAgICAgZGVzYyA9IGEuZ2V0VGFibGVEZXNjcmlwdG9yKCk7CisgICAgICBpZiAoQnl0ZXMuY29tcGFyZVRvKGRlc2MuZ2V0TmFtZSgpLCB0YWJsZUFuYW1lKSAhPSAwKQorICAgICAgICBmYWlsKCJ3cm9uZyB0YWJsZSBkZXNjcmlwdG9yIHJldHVybmVkIik7CisgICAgICAvLyBjaGVjayBIVEQgYXR0cmlidXRlCisgICAgICB2YWx1ZSA9IGRlc2MuZ2V0VmFsdWUoYXR0ck5hbWUpOworICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgIGZhaWwoIm1pc3NpbmcgSFREIGF0dHJpYnV0ZSB2YWx1ZSIpOworICAgICAgaWYgKEJ5dGVzLmNvbXBhcmVUbyh2YWx1ZSwgYXR0clZhbHVlKSAhPSAwKQorICAgICAgICBmYWlsKCJIVEQgYXR0cmlidXRlIHZhbHVlIGlzIGluY29ycmVjdCIpOworICAgICAgLy8gY2hlY2sgSENEIGF0dHJpYnV0ZQorICAgICAgZm9yIChIQ29sdW1uRGVzY3JpcHRvciBjOiBkZXNjLmdldEZhbWlsaWVzKCkpIHsKKyAgICAgICAgdmFsdWUgPSBjLmdldFZhbHVlKGF0dHJOYW1lKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bGwpCisgICAgICAgICAgZmFpbCgibWlzc2luZyBIQ0QgYXR0cmlidXRlIHZhbHVlIik7CisgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8odmFsdWUsIGF0dHJWYWx1ZSkgIT0gMCkKKyAgICAgICAgICBmYWlsKCJIQ0QgYXR0cmlidXRlIHZhbHVlIGlzIGluY29ycmVjdCIpOworICAgICAgfQorCisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICBmYWlsKCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdENoZWNrQW5kU2F2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFRhYmxlIHRhYmxlID0gbnVsbDsKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBjb2x1bW4yID0KKyAgICAgIG5ldyBIQ29sdW1uRGVzY3JpcHRvcihCeXRlcy50b0J5dGVzKCJpbmZvMjoiKSk7CisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIEhUYWJsZURlc2NyaXB0b3IgdGVzdFRhYmxlQURlc2MgPQorICAgICAgbmV3IEhUYWJsZURlc2NyaXB0b3IodGFibGVBbmFtZSk7CisgICAgdGVzdFRhYmxlQURlc2MuYWRkRmFtaWx5KGNvbHVtbik7CisgICAgdGVzdFRhYmxlQURlc2MuYWRkRmFtaWx5KGNvbHVtbjIpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKHRlc3RUYWJsZUFEZXNjKTsKKyAgICAKKyAgICB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVBbmFtZSk7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZTIgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZTMgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAKKyAgICBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSxieXRlW10+IGV4cGVjdGVkVmFsdWVzID0KKyAgICAgIG5ldyBIYmFzZU1hcFdyaXRhYmxlPGJ5dGVbXSxieXRlW10+KCk7CisgICAgSGJhc2VNYXBXcml0YWJsZTxieXRlW10sYnl0ZVtdPiBiYWRFeHBlY3RlZFZhbHVlcyA9CisgICAgICBuZXcgSGJhc2VNYXBXcml0YWJsZTxieXRlW10sYnl0ZVtdPigpOworICAgIAorICAgIGZvcihpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsKKyAgICAgIC8vIFRoaXMgYmF0Y2h1cGRhdGUgaXMgb3VyIGluaXRpYWwgYmF0Y2ggdXBkYXRlLAorICAgICAgLy8gQXMgc3VjaCB3ZSBhbHNvIHNldCBvdXIgZXhwZWN0ZWQgdmFsdWVzIHRvIHRoZSBzYW1lIHZhbHVlcworICAgICAgLy8gc2luY2Ugd2Ugd2lsbCBiZSBjb21wYXJpbmcgdGhlIHR3bworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTl9GQU1JTFlfU1RSK2ksIEJ5dGVzLnRvQnl0ZXMoaSkpOworICAgICAgZXhwZWN0ZWRWYWx1ZXMucHV0KEJ5dGVzLnRvQnl0ZXMoQ09MVU1OX0ZBTUlMWV9TVFIraSksIEJ5dGVzLnRvQnl0ZXMoaSkpOworICAgICAgCisgICAgICBiYWRFeHBlY3RlZFZhbHVlcy5wdXQoQnl0ZXMudG9CeXRlcyhDT0xVTU5fRkFNSUxZX1NUUitpKSwKKyAgICAgICAgQnl0ZXMudG9CeXRlcyg1MDApKTsKKyAgICAgIAorICAgICAgLy8gVGhpcyBpcyBvdXIgc2Vjb25kIGJhdGNodXBkYXRlIHRoYXQgd2Ugd2lsbCB1c2UgdG8gdXBkYXRlIHRoZSBpbml0aWFsCisgICAgICAvLyBiYXRjaHVwZGF0ZQorICAgICAgYmF0Y2hVcGRhdGUyLnB1dChDT0xVTU5fRkFNSUxZX1NUUitpLCBCeXRlcy50b0J5dGVzKGkrMSkpOworICAgICAgCisgICAgICAvLyBUaGlzIGZpbmFsIGJhdGNoIHVwZGF0ZSBpcyB0byBjaGVjayB0aGF0IG91ciBleHBlY3RlZCB2YWx1ZXMgKHdoaWNoCisgICAgICAvLyBhcmUgbm93IHdyb25nKQorICAgICAgYmF0Y2hVcGRhdGUzLnB1dChDT0xVTU5fRkFNSUxZX1NUUitpLCBCeXRlcy50b0J5dGVzKGkrMikpOworICAgIH0KKyAgICAKKyAgICAvLyBJbml0aWFsaXplIHJvd3MKKyAgICB0YWJsZS5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIAorICAgIC8vIGNoZWNrIGlmIGluY29ycmVjdCB2YWx1ZXMgYXJlIHJldHVybmVkIGZhbHNlCisgICAgYXNzZXJ0RmFsc2UodGFibGUuY2hlY2tBbmRTYXZlKGJhdGNoVXBkYXRlMixiYWRFeHBlY3RlZFZhbHVlcyxudWxsKSk7CisgICAgCisgICAgLy8gbWFrZSBzdXJlIGZpcnN0IGV4cGVjdGVkIHZhbHVlcyBhcmUgY29ycmVjdAorICAgIGFzc2VydFRydWUodGFibGUuY2hlY2tBbmRTYXZlKGJhdGNoVXBkYXRlMiwgZXhwZWN0ZWRWYWx1ZXMsbnVsbCkpOworICAgICAgICAKKyAgICAvLyBtYWtlIHN1cmUgY2hlY2sgYW5kIHNhdmUgdHJ1bHkgc2F2ZXMgdGhlIGRhdGEgYWZ0ZXIgY2hlY2tpbmcgdGhlIGV4cGVjdGVkCisgICAgLy8gdmFsdWVzCisgICAgUm93UmVzdWx0IHIgPSB0YWJsZS5nZXRSb3cocm93KTsKKyAgICBieXRlW11bXSBjb2x1bW5zID0gYmF0Y2hVcGRhdGUyLmdldENvbHVtbnMoKTsKKyAgICBmb3IoaW50IGkgPSAwO2kgPCBjb2x1bW5zLmxlbmd0aDtpKyspIHsKKyAgICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHIuZ2V0KGNvbHVtbnNbaV0pLmdldFZhbHVlKCksYmF0Y2hVcGRhdGUyLmdldChjb2x1bW5zW2ldKSkpOworICAgIH0KKyAgICAKKyAgICAvLyBtYWtlIHN1cmUgdGhhdCB0aGUgb2xkIGV4cGVjdGVkIHZhbHVlcyBmYWlsCisgICAgYXNzZXJ0RmFsc2UodGFibGUuY2hlY2tBbmRTYXZlKGJhdGNoVXBkYXRlMywgZXhwZWN0ZWRWYWx1ZXMsbnVsbCkpOworICB9CisKKyAgLyoqCisgICAqIEZvciBIQURPT1AtMjU3OQorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFRhYmxlTm90Rm91bmRFeGNlcHRpb25XaXRob3V0QW55VGFibGVzKCkgeworICAgIHRyeSB7CisgICAgICBuZXcgSFRhYmxlKGNvbmYsICJub3RBVGFibGUiKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhIFRhYmxlTm90Rm91bmRFeGNlcHRpb24iKTsKKyAgICB9IGNhdGNoIChUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGV4cGVjdGVkCisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIGZhaWwoIlNob3VsZCBoYXZlIHRocm93biBhIFRhYmxlTm90Rm91bmRFeGNlcHRpb24gaW5zdGVhZCBvZiBhICIgKworICAgICAgICBlLmdldENsYXNzKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRDbG9zZXN0Um93QmVmb3JlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBjb2x1bW4yID0KKyAgICAgIG5ldyBIQ29sdW1uRGVzY3JpcHRvcihCeXRlcy50b0J5dGVzKCJpbmZvMjoiKSk7CisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIEhUYWJsZURlc2NyaXB0b3IgdGVzdFRhYmxlQURlc2MgPQorICAgICAgbmV3IEhUYWJsZURlc2NyaXB0b3IodGFibGVBbmFtZSk7CisgICAgdGVzdFRhYmxlQURlc2MuYWRkRmFtaWx5KGNvbHVtbik7CisgICAgdGVzdFRhYmxlQURlc2MuYWRkRmFtaWx5KGNvbHVtbjIpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKHRlc3RUYWJsZUFEZXNjKTsKKyAgICAKKyAgICBieXRlW10gZmlyc3RSb3cgPSBCeXRlcy50b0J5dGVzKCJybyIpOworICAgIGJ5dGVbXSBiZWZvcmVGaXJzdFJvdyA9IEJ5dGVzLnRvQnl0ZXMoInJuIik7CisgICAgYnl0ZVtdIGJlZm9yZVNlY29uZFJvdyA9IEJ5dGVzLnRvQnl0ZXMoInJvdiIpOworICAgIAorICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVBbmFtZSk7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoZmlyc3RSb3cpOworICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlMiA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgIGJ5dGVbXSB6ZXJvID0gbmV3IGJ5dGVbXXswfTsKKyAgICBieXRlW10gb25lID0gbmV3IGJ5dGVbXXsxfTsKKyAgICBieXRlW10gY29sdW1uRmFtaWx5Qnl0ZXMgPSBCeXRlcy50b0J5dGVzKENPTFVNTl9GQU1JTFlfU1RSKTsKKyAgICAKKyAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OX0ZBTUlMWV9TVFIsemVybyk7CisgICAgYmF0Y2hVcGRhdGUyLnB1dChDT0xVTU5fRkFNSUxZX1NUUixvbmUpOworICAgIAorICAgIHRhYmxlLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgdGFibGUuY29tbWl0KGJhdGNoVXBkYXRlMik7CisgICAgCisgICAgUm93UmVzdWx0IHJlc3VsdCA9IG51bGw7CisgICAgCisgICAgLy8gVGVzdCBiZWZvcmUgZmlyc3QgdGhhdCBudWxsIGlzIHJldHVybmVkCisgICAgcmVzdWx0ID0gdGFibGUuZ2V0Q2xvc2VzdFJvd0JlZm9yZShiZWZvcmVGaXJzdFJvdywgY29sdW1uRmFtaWx5Qnl0ZXMpOworICAgIGFzc2VydFRydWUocmVzdWx0ID09IG51bGwpOworICAgIAorICAgIC8vIFRlc3QgYXQgZmlyc3QgdGhhdCBmaXJzdCBpcyByZXR1cm5lZAorICAgIHJlc3VsdCA9IHRhYmxlLmdldENsb3Nlc3RSb3dCZWZvcmUoZmlyc3RSb3csIGNvbHVtbkZhbWlseUJ5dGVzKTsKKyAgICBhc3NlcnRUcnVlKHJlc3VsdC5jb250YWluc0tleShDT0xVTU5fRkFNSUxZX1NUUikpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJlc3VsdC5nZXQoQ09MVU1OX0ZBTUlMWV9TVFIpLmdldFZhbHVlKCksIHplcm8pKTsKKyAgICAKKyAgICAvLyBUZXN0IGluYmV0d2VlbiBmaXJzdCBhbmQgc2Vjb25kIHRoYXQgZmlyc3QgaXMgcmV0dXJuZWQKKyAgICByZXN1bHQgPSB0YWJsZS5nZXRDbG9zZXN0Um93QmVmb3JlKGJlZm9yZVNlY29uZFJvdywgY29sdW1uRmFtaWx5Qnl0ZXMpOworICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zS2V5KENPTFVNTl9GQU1JTFlfU1RSKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocmVzdWx0LmdldChDT0xVTU5fRkFNSUxZX1NUUikuZ2V0VmFsdWUoKSwgemVybykpOworICAgIAorICAgIC8vIFRlc3QgYXQgc2Vjb25kIG1ha2Ugc3VyZSBzZWNvbmQgaXMgcmV0dXJuZWQKKyAgICByZXN1bHQgPSB0YWJsZS5nZXRDbG9zZXN0Um93QmVmb3JlKHJvdywgY29sdW1uRmFtaWx5Qnl0ZXMpOworICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zS2V5KENPTFVNTl9GQU1JTFlfU1RSKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocmVzdWx0LmdldChDT0xVTU5fRkFNSUxZX1NUUikuZ2V0VmFsdWUoKSwgb25lKSk7CisgICAgCisgICAgLy8gVGVzdCBhZnRlciBzZWNvbmQsIG1ha2Ugc3VyZSBzZWNvbmQgaXMgcmV0dXJuZWQKKyAgICByZXN1bHQgPSB0YWJsZS5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLmFkZChyb3csb25lKSwgY29sdW1uRmFtaWx5Qnl0ZXMpOworICAgIGFzc2VydFRydWUocmVzdWx0LmNvbnRhaW5zS2V5KENPTFVNTl9GQU1JTFlfU1RSKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocmVzdWx0LmdldChDT0xVTU5fRkFNSUxZX1NUUikuZ2V0VmFsdWUoKSwgb25lKSk7CisgIH0KKworICAvKioKKyAgICogRm9yIEhBRE9PUC0yNTc5CisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0VGFibGVOb3RGb3VuZEV4Y2VwdGlvbldpdGhBVGFibGUoKSB7CisgICB0cnkgeworICAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgIEhUYWJsZURlc2NyaXB0b3IgdGVzdFRhYmxlQURlc2MgPQorICAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0YWJsZSIpOworICAgICB0ZXN0VGFibGVBRGVzYy5hZGRGYW1pbHkoY29sdW1uKTsKKyAgICAgYWRtaW4uY3JlYXRlVGFibGUodGVzdFRhYmxlQURlc2MpOworCisgICAgIC8vIFRoaXMgc2hvdWxkIHRocm93IGEgVGFibGVOb3RGb3VuZEV4Y2VwdGlvbiwgaXQgaGFzIG5vdCBiZWVuIGNyZWF0ZWQKKyAgICAgbmV3IEhUYWJsZShjb25mLCAibm90QVRhYmxlIik7CisgICAgIAorICAgICBmYWlsKCJTaG91bGQgaGF2ZSB0aHJvd24gYSBUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIik7CisgICB9IGNhdGNoIChUYWJsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgLy8gZXhwZWN0ZWQKKyAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgZmFpbCgiU2hvdWxkIGhhdmUgdGhyb3duIGEgVGFibGVOb3RGb3VuZEV4Y2VwdGlvbiBpbnN0ZWFkIG9mIGEgIiArCisgICAgICAgZS5nZXRDbGFzcygpKTsKKyAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RMaXN0VGFibGVzLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVGVzdExpc3RUYWJsZXMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGE1ZWJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RMaXN0VGFibGVzLmphdmEKQEAgLTAsMCArMSw3MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CisKKy8qKgorICogVGVzdHMgdGhlIGxpc3RUYWJsZXMgY2xpZW50IEFQSQorICovCitwdWJsaWMgY2xhc3MgVGVzdExpc3RUYWJsZXMgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIEhCYXNlQWRtaW4gYWRtaW4gPSBudWxsOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSFRhYmxlRGVzY3JpcHRvcltdIFRBQkxFUyA9IHsKKyAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0YWJsZTEiKSwKKyAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0YWJsZTIiKSwKKyAgICAgIG5ldyBIVGFibGVEZXNjcmlwdG9yKCJ0YWJsZTMiKQorICB9OworICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIEhDb2x1bW5EZXNjcmlwdG9yIGZhbWlseSA9CisgICAgICBuZXcgSENvbHVtbkRlc2NyaXB0b3IoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZX1NUUik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBUQUJMRVMubGVuZ3RoOyBpKyspIHsKKyAgICAgIFRBQkxFU1tpXS5hZGRGYW1pbHkoZmFtaWx5KTsKKyAgICAgIGFkbWluLmNyZWF0ZVRhYmxlKFRBQkxFU1tpXSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIHRoZSB0ZXN0CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RMaXN0VGFibGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yIFtdIHRzID0gYWRtaW4ubGlzdFRhYmxlcygpOworICAgIEhhc2hTZXQ8SFRhYmxlRGVzY3JpcHRvcj4gcmVzdWx0ID0gbmV3IEhhc2hTZXQ8SFRhYmxlRGVzY3JpcHRvcj4odHMubGVuZ3RoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRzLmxlbmd0aDsgaSsrKSB7CisgICAgICByZXN1bHQuYWRkKHRzW2ldKTsKKyAgICB9CisgICAgaW50IHNpemUgPSByZXN1bHQuc2l6ZSgpOworICAgIGFzc2VydEVxdWFscyhUQUJMRVMubGVuZ3RoLCBzaXplKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IFRBQkxFUy5sZW5ndGggJiYgaSA8IHNpemU7IGkrKykgeworICAgICAgYXNzZXJ0VHJ1ZShyZXN1bHQuY29udGFpbnMoVEFCTEVTW2ldKSk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvY2xpZW50L1Rlc3RTY2FubmVyVGltZXMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0U2Nhbm5lclRpbWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWYzNDA3YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0U2Nhbm5lclRpbWVzLmphdmEKQEAgLTAsMCArMSwxMzkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDbHVzdGVyVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CisKKy8qKgorICogVGVzdCB0aGF0IHZlcmlmaWVzIHRoYXQgc2Nhbm5lcnMgcmV0dXJuIGEgZGlmZmVyZW50IHRpbWVzdGFtcCBmb3IgdmFsdWVzIHRoYXQKKyAqIGFyZSBub3Qgc3RvcmVkIGF0IHRoZSBzYW1lIHRpbWUuIChIQkFTRS03MzcpCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0U2Nhbm5lclRpbWVzIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFCTEVfTkFNRSA9ICJoYmFzZTczNyI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGQU0xID0gImZhbTE6IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZBTTIgPSAiZmFtMjoiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUk9XID0gInJvdyI7CisgIAorICAvKioKKyAgICogdGVzdCBmb3IgSEJBU0UtNzM3CisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RIQmFzZTczNyAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKFRBQkxFX05BTUUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihGQU0xKSk7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKEZBTTIpKTsKKyAgICAKKyAgICAvLyBDcmVhdGUgdGFibGUKKyAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgCisgICAgLy8gT3BlbiB0YWJsZQorICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgVEFCTEVfTkFNRSk7CisgICAgCisgICAgLy8gSW5zZXJ0IHNvbWUgdmFsdWVzCisgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShST1cpOworICAgIGIucHV0KEZBTTEgKyAibGV0dGVycyIsICJhYmNkZWZnIi5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICB0YWJsZS5jb21taXQoYik7CisgICAgCisgICAgdHJ5IHsKKyAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpKSB7CisgICAgICAvL2lnbm9yZQorICAgIH0KKyAgICAKKyAgICBiID0gbmV3IEJhdGNoVXBkYXRlKFJPVyk7CisgICAgYi5wdXQoRkFNMSArICJudW1iZXJzIiwgIjEyMzQ1NiIuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgdGFibGUuY29tbWl0KGIpOworICAgIAorICAgIHRyeSB7CisgICAgICBUaHJlYWQuc2xlZXAoMTAwMCk7CisgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaSkgeworICAgICAgLy9pZ25vcmUKKyAgICB9CisgICAgCisgICAgYiA9IG5ldyBCYXRjaFVwZGF0ZShST1cpOworICAgIGIucHV0KEZBTTIgKyAibGV0dGVycyIsICJoaWprbG1ub3AiLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgIHRhYmxlLmNvbW1pdChiKTsKKyAgICAKKyAgICBsb25nIHRpbWVzW10gPSBuZXcgbG9uZ1szXTsKKyAgICBieXRlW11bXSBjb2x1bW5zID0gbmV3IGJ5dGVbXVtdIHsKKyAgICAgICAgRkFNMS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpLAorICAgICAgICBGQU0yLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykKKyAgICB9OworICAgIAorICAgIC8vIEZpcnN0IHNjYW4gdGhlIG1lbWNhY2hlCisgICAgCisgICAgU2Nhbm5lciBzID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zKTsKKyAgICB0cnkgeworICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgIFJvd1Jlc3VsdCByID0gbnVsbDsKKyAgICAgIHdoaWxlICgociA9IHMubmV4dCgpKSAhPSBudWxsKSB7CisgICAgICAgIGZvciAoQ2VsbCBjOiByLnZhbHVlcygpKSB7CisgICAgICAgICAgdGltZXNbaW5kZXgrK10gPSBjLmdldFRpbWVzdGFtcCgpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aW1lcy5sZW5ndGggLSAxOyBpKyspIHsKKyAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IHRpbWVzLmxlbmd0aDsgaisrKSB7CisgICAgICAgIGFzc2VydFRydWUodGltZXNbal0gPiB0aW1lc1tpXSk7CisgICAgICB9CisgICAgfQorICAgIAorICAgIC8vIEZ1c2ggZGF0YSB0byBkaXNrIGFuZCB0cnkgYWdhaW4KKyAgICAKKyAgICBjbHVzdGVyLmZsdXNoY2FjaGUoKTsKKyAgICAKKyAgICB0cnkgeworICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOworICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGkpIHsKKyAgICAgIC8vaWdub3JlCisgICAgfQorICAgIAorICAgIHMgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMpOworICAgIHRyeSB7CisgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgUm93UmVzdWx0IHIgPSBudWxsOworICAgICAgd2hpbGUgKChyID0gcy5uZXh0KCkpICE9IG51bGwpIHsKKyAgICAgICAgZm9yIChDZWxsIGM6IHIudmFsdWVzKCkpIHsKKyAgICAgICAgICB0aW1lc1tpbmRleCsrXSA9IGMuZ2V0VGltZXN0YW1wKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzLmxlbmd0aCAtIDE7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgdGltZXMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0aW1lc1tqXSA+IHRpbWVzW2ldKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC9UZXN0VGltZXN0YW1wLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVGVzdFRpbWVzdGFtcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlNjhiZGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvVGVzdFRpbWVzdGFtcC5qYXZhCkBAIC0wLDAgKzEsNzYgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlRpbWVzdGFtcFRlc3RCYXNlOworCisvKioKKyAqIFRlc3RzIHVzZXIgc3BlY2lmaWFibGUgdGltZSBzdGFtcHMgcHV0dGluZywgZ2V0dGluZyBhbmQgc2Nhbm5pbmcuICBBbHNvCisgKiB0ZXN0cyBzYW1lIGluIHByZXNlbmNlIG9mIGRlbGV0ZXMuICBUZXN0IGNvcmVzIGFyZSB3cml0dGVuIHNvIGNhbiBiZQorICogcnVuIGFnYWluc3QgYW4gSFJlZ2lvbiBhbmQgYWdhaW5zdCBhbiBIVGFibGU6IGkuZS4gYm90aCBsb2NhbCBhbmQgcmVtb3RlLgorICovCitwdWJsaWMgY2xhc3MgVGVzdFRpbWVzdGFtcCBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTl9OQU1FID0gImNvbnRlbnRzOiI7CisgIAorICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIFRlc3RUaW1lc3RhbXAoKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBCYXNpYyB0ZXN0IG9mIHRpbWVzdGFtcHMuCisgICAqIERvIHRoZSBhYm92ZSB0ZXN0cyBmcm9tIGNsaWVudCBzaWRlLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0VGltZXN0YW1wcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFRhYmxlIHQgPSBjcmVhdGVUYWJsZSgpOworICAgIEluY29tbW9uIGluY29tbW9uID0gbmV3IEhUYWJsZUluY29tbW9uKHQpOworICAgIFRpbWVzdGFtcFRlc3RCYXNlLmRvVGVzdERlbGV0ZShpbmNvbW1vbiwgbmV3IEZsdXNoQ2FjaGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBmbHVzaGNhY2hlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2x1c3Rlci5mbHVzaGNhY2hlKCk7CisgICAgICB9CisgICAgIH0pOworICAgIAorICAgIC8vIFBlcmhhcHMgZHJvcCBhbmQgcmVhZGQgdGhlIHRhYmxlIGJldHdlZW4gdGVzdHMgc28gdGhlIGZvcm1lciBkb2VzCisgICAgLy8gbm90IHBvbGx1dGUgdGhpcyBsYXR0ZXI/ICBPciBwdXQgaW50byBzZXBhcmF0ZSB0ZXN0cy4KKyAgICBUaW1lc3RhbXBUZXN0QmFzZS5kb1Rlc3RUaW1lc3RhbXBTY2FubmluZyhpbmNvbW1vbiwgbmV3IEZsdXNoQ2FjaGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBmbHVzaGNhY2hlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgY2x1c3Rlci5mbHVzaGNhY2hlKCk7CisgICAgICB9CisgICAgfSk7CisgIH0KKyAgCisgIC8qIAorICAgKiBDcmVhdGUgYSB0YWJsZSBuYW1lZCBUQUJMRV9OQU1FLgorICAgKiBAcmV0dXJuIEFuIGluc3RhbmNlIG9mIGFuIEhUYWJsZSBjb25uZWN0ZWQgdG8gdGhlIGNyZWF0ZWQgdGFibGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgSFRhYmxlIGNyZWF0ZVRhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT0xVTU5fTkFNRSkpOworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICBhZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICByZXR1cm4gbmV3IEhUYWJsZShjb25mLCBnZXROYW1lKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1Rlc3RJbmRleGVkVGFibGUuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90YWJsZWluZGV4ZWQvVGVzdEluZGV4ZWRUYWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5NDlkNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdGFibGVpbmRleGVkL1Rlc3RJbmRleGVkVGFibGUuamF2YQpAQCAtMCwwICsxLDEzMSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50YWJsZWluZGV4ZWQ7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDbHVzdGVyVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLlBlcmZvcm1hbmNlRXZhbHVhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLnRhYmxlaW5kZXhlZC5JbmRleGVkUmVnaW9uU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK3B1YmxpYyBjbGFzcyBUZXN0SW5kZXhlZFRhYmxlIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0SW5kZXhlZFRhYmxlLmNsYXNzKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFCTEVfTkFNRSA9ICJ0YWJsZTEiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBGQU1JTFkgPSBCeXRlcy50b0J5dGVzKCJmYW1pbHk6Iik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0xfQSA9IEJ5dGVzLnRvQnl0ZXMoImZhbWlseTphIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBJTkRFWF9DT0xfQSA9ICJBIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1JPV1MgPSAxMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9WQUwgPSAxMDAwMDsKKworICBwcml2YXRlIEluZGV4ZWRUYWJsZUFkbWluIGFkbWluOworICBwcml2YXRlIEluZGV4ZWRUYWJsZSB0YWJsZTsKKyAgcHJpdmF0ZSBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVGVzdEluZGV4ZWRUYWJsZSgpIHsKKyAgICBjb25mCisgICAgICAgIC5zZXQoSENvbnN0YW50cy5SRUdJT05fU0VSVkVSX0lNUEwsIEluZGV4ZWRSZWdpb25TZXJ2ZXIuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgICBjb25mLnNldEludCgiaGJhc2UubWFzdGVyLmluZm8ucG9ydCIsIC0xKTsKKyAgICBjb25mLnNldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmluZm8ucG9ydCIsIC0xKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihUQUJMRV9OQU1FKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoRkFNSUxZKSk7CisKKyAgICAvLyBDcmVhdGUgYSBuZXcgaW5kZXggdGhhdCBkb2VzIGxleGljb2dyYXBoaWMgb3JkZXJpbmcgb24gQ09MX0EKKyAgICBJbmRleFNwZWNpZmljYXRpb24gY29sQUluZGV4ID0gbmV3IEluZGV4U3BlY2lmaWNhdGlvbihJTkRFWF9DT0xfQSwKKyAgICAgICAgQ09MX0EpOworICAgIGRlc2MuYWRkSW5kZXgoY29sQUluZGV4KTsKKworICAgIGFkbWluID0gbmV3IEluZGV4ZWRUYWJsZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIHRhYmxlID0gbmV3IEluZGV4ZWRUYWJsZShjb25mLCBkZXNjLmdldE5hbWUoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgd3JpdGVJbml0YWxSb3dzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTV9ST1dTOyBpKyspIHsKKyAgICAgIEJhdGNoVXBkYXRlIHVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShQZXJmb3JtYW5jZUV2YWx1YXRpb24uZm9ybWF0KGkpKTsKKyAgICAgIGJ5dGVbXSBjb2xBID0gUGVyZm9ybWFuY2VFdmFsdWF0aW9uLmZvcm1hdChyYW5kb20ubmV4dEludChNQVhfVkFMKSk7CisgICAgICB1cGRhdGUucHV0KENPTF9BLCBjb2xBKTsKKyAgICAgIHRhYmxlLmNvbW1pdCh1cGRhdGUpOworICAgICAgTE9HLmluZm8oIkluc2VydGVkIHJvdyBbIiArIEJ5dGVzLnRvU3RyaW5nKHVwZGF0ZS5nZXRSb3coKSkgKyAiXSB2YWw6IFsiCisgICAgICAgICAgKyBCeXRlcy50b1N0cmluZyhjb2xBKSArICJdIik7CisgICAgfQorICB9CisKKworICBwdWJsaWMgdm9pZCB0ZXN0SW5pdGlhbFdyaXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVJbml0YWxSb3dzKCk7CisgICAgYXNzZXJ0Um93c0luT3JkZXIoTlVNX1JPV1MpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgYXNzZXJ0Um93c0luT3JkZXIoaW50IG51bVJvd3NFeHBlY3RlZCkgdGhyb3dzIEluZGV4Tm90Rm91bmRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICBTY2FubmVyIHNjYW5uZXIgPSB0YWJsZS5nZXRJbmRleGVkU2Nhbm5lcihJTkRFWF9DT0xfQSwKKyAgICAgICAgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csIG51bGwsIG51bGwsIG51bGwpOworICAgIGludCBudW1Sb3dzID0gMDsKKyAgICBieXRlW10gbGFzdENvbEEgPSBudWxsOworICAgIGZvciAoUm93UmVzdWx0IHJvd1Jlc3VsdCA6IHNjYW5uZXIpIHsKKyAgICAgIGJ5dGVbXSBjb2xBID0gcm93UmVzdWx0LmdldChDT0xfQSkuZ2V0VmFsdWUoKTsKKyAgICAgIExPRy5pbmZvKCJpbmRleCBzY2FuIDogcm93IFsiICsgQnl0ZXMudG9TdHJpbmcocm93UmVzdWx0LmdldFJvdygpKQorICAgICAgICAgICsgIl0gdmFsdWUgWyIgKyBCeXRlcy50b1N0cmluZyhjb2xBKSArICJdIik7CisgICAgICBpZiAobGFzdENvbEEgIT0gbnVsbCkgeworICAgICAgICBBc3NlcnQuYXNzZXJ0VHJ1ZShCeXRlcy5jb21wYXJlVG8obGFzdENvbEEsIGNvbEEpIDw9IDApOworICAgICAgfQorICAgICAgbGFzdENvbEEgPSBjb2xBOworICAgICAgbnVtUm93cysrOworICAgIH0KKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKG51bVJvd3NFeHBlY3RlZCwgbnVtUm93cyk7ICAKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aXBsZVdyaXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgd3JpdGVJbml0YWxSb3dzKCk7CisgICAgd3JpdGVJbml0YWxSb3dzKCk7IC8vIFVwZGF0ZSB0aGUgcm93cy4KKyAgICBhc3NlcnRSb3dzSW5PcmRlcihOVU1fUk9XUyk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3REZWxldGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlSW5pdGFsUm93cygpOworICAgIC8vIERlbGV0ZSB0aGUgZmlyc3Qgcm93OworICAgIHRhYmxlLmRlbGV0ZUFsbChQZXJmb3JtYW5jZUV2YWx1YXRpb24uZm9ybWF0KDApKTsKKyAgICAKKyAgICBhc3NlcnRSb3dzSW5PcmRlcihOVU1fUk9XUyAtIDEpOyAgICAKKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9EaXNhYmxlZFRlc3RUcmFuc2FjdGlvbnMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL0Rpc2FibGVkVGVzdFRyYW5zYWN0aW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiNDUzZTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9EaXNhYmxlZFRlc3RUcmFuc2FjdGlvbnMuamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5UcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsLlRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IHRoZSB0cmFuc2FjdGlvbiBmdW5jdGlvbmFsaXR5LiBUaGlzIHJlcXVpcmVzIHRvIHJ1biBhbgorICoge0BsaW5rIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXJ9LgorICovCitwdWJsaWMgY2xhc3MgRGlzYWJsZWRUZXN0VHJhbnNhY3Rpb25zIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUJMRV9OQU1FID0gInRhYmxlMSI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEZBTUlMWSA9IEJ5dGVzLnRvQnl0ZXMoImZhbWlseToiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIENPTF9BID0gQnl0ZXMudG9CeXRlcygiZmFtaWx5OmEiKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUk9XMSA9IEJ5dGVzLnRvQnl0ZXMoInJvdzEiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFJPVzIgPSBCeXRlcy50b0J5dGVzKCJyb3cyIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBST1czID0gQnl0ZXMudG9CeXRlcygicm93MyIpOworCisgIHByaXZhdGUgSEJhc2VBZG1pbiBhZG1pbjsKKyAgcHJpdmF0ZSBUcmFuc2FjdGlvbmFsVGFibGUgdGFibGU7CisgIHByaXZhdGUgVHJhbnNhY3Rpb25NYW5hZ2VyIHRyYW5zYWN0aW9uTWFuYWdlcjsKKworICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIERpc2FibGVkVGVzdFRyYW5zYWN0aW9ucygpIHsKKyAgICBjb25mLnNldChIQ29uc3RhbnRzLlJFR0lPTl9TRVJWRVJfQ0xBU1MsIFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UuY2xhc3MKKyAgICAgICAgLmdldE5hbWUoKSk7CisgICAgY29uZi5zZXQoSENvbnN0YW50cy5SRUdJT05fU0VSVkVSX0lNUEwsIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuY2xhc3MKKyAgICAgICAgLmdldE5hbWUoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworCisgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoVEFCTEVfTkFNRSk7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKEZBTUlMWSkpOworICAgIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgdGFibGUgPSBuZXcgVHJhbnNhY3Rpb25hbFRhYmxlKGNvbmYsIGRlc2MuZ2V0TmFtZSgpKTsKKworICAgIHRyYW5zYWN0aW9uTWFuYWdlciA9IG5ldyBUcmFuc2FjdGlvbk1hbmFnZXIoY29uZik7CisgICAgd3JpdGVJbml0YWxSb3coKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB3cml0ZUluaXRhbFJvdygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzEpOworICAgIHVwZGF0ZS5wdXQoQ09MX0EsIEJ5dGVzLnRvQnl0ZXMoMSkpOworICAgIHRhYmxlLmNvbW1pdCh1cGRhdGUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNpbXBsZVRyYW5zYWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgPSBtYWtlVHJhbnNhY3Rpb24xKCk7CisgICAgdHJhbnNhY3Rpb25NYW5hZ2VyLnRyeUNvbW1pdCh0cmFuc2FjdGlvblN0YXRlKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RUd29UcmFuc2FjdGlvbnNXaXRob3V0Q29uZmxpY3QoKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICBDb21taXRVbnN1Y2Nlc3NmdWxFeGNlcHRpb24geworICAgIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZTEgPSBtYWtlVHJhbnNhY3Rpb24xKCk7CisgICAgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlMiA9IG1ha2VUcmFuc2FjdGlvbjIoKTsKKworICAgIHRyYW5zYWN0aW9uTWFuYWdlci50cnlDb21taXQodHJhbnNhY3Rpb25TdGF0ZTEpOworICAgIHRyYW5zYWN0aW9uTWFuYWdlci50cnlDb21taXQodHJhbnNhY3Rpb25TdGF0ZTIpOworICB9CisKKyAgcHVibGljIHZvaWQgVGVzdFR3b1RyYW5zYWN0aW9uc1dpdGhDb25mbGljdCgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlMSA9IG1ha2VUcmFuc2FjdGlvbjEoKTsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUyID0gbWFrZVRyYW5zYWN0aW9uMigpOworCisgICAgdHJhbnNhY3Rpb25NYW5hZ2VyLnRyeUNvbW1pdCh0cmFuc2FjdGlvblN0YXRlMik7CisKKyAgICB0cnkgeworICAgICAgdHJhbnNhY3Rpb25NYW5hZ2VyLnRyeUNvbW1pdCh0cmFuc2FjdGlvblN0YXRlMSk7CisgICAgICBmYWlsKCk7CisgICAgfSBjYXRjaCAoQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEdvb2QKKyAgICB9CisgIH0KKworICAvLyBSZWFkIGZyb20gUk9XMSxDT0xfQSBhbmQgcHV0IGl0IGluIFJPVzJfQ09MQSBhbmQgUk9XM19DT0xBCisgIHByaXZhdGUgVHJhbnNhY3Rpb25TdGF0ZSBtYWtlVHJhbnNhY3Rpb24xKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgPSB0cmFuc2FjdGlvbk1hbmFnZXIuYmVnaW5UcmFuc2FjdGlvbigpOworCisgICAgQ2VsbCByb3cxX0EgPSB0YWJsZS5nZXQodHJhbnNhY3Rpb25TdGF0ZSwgUk9XMSwgQ09MX0EpOworCisgICAgQmF0Y2hVcGRhdGUgd3JpdGUxID0gbmV3IEJhdGNoVXBkYXRlKFJPVzIpOworICAgIHdyaXRlMS5wdXQoQ09MX0EsIHJvdzFfQS5nZXRWYWx1ZSgpKTsKKyAgICB0YWJsZS5jb21taXQodHJhbnNhY3Rpb25TdGF0ZSwgd3JpdGUxKTsKKworICAgIEJhdGNoVXBkYXRlIHdyaXRlMiA9IG5ldyBCYXRjaFVwZGF0ZShST1czKTsKKyAgICB3cml0ZTIucHV0KENPTF9BLCByb3cxX0EuZ2V0VmFsdWUoKSk7CisgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHdyaXRlMik7CisKKyAgICByZXR1cm4gdHJhbnNhY3Rpb25TdGF0ZTsKKyAgfQorCisgIC8vIFJlYWQgUk9XMSxDT0xfQSwgaW5jcmVtZW50IGl0cyAoaW50ZWdlcikgdmFsdWUsIHdyaXRlIGJhY2sKKyAgcHJpdmF0ZSBUcmFuc2FjdGlvblN0YXRlIG1ha2VUcmFuc2FjdGlvbjIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFRyYW5zYWN0aW9uU3RhdGUgdHJhbnNhY3Rpb25TdGF0ZSA9IHRyYW5zYWN0aW9uTWFuYWdlci5iZWdpblRyYW5zYWN0aW9uKCk7CisKKyAgICBDZWxsIHJvdzFfQSA9IHRhYmxlLmdldCh0cmFuc2FjdGlvblN0YXRlLCBST1cxLCBDT0xfQSk7CisKKyAgICBpbnQgdmFsdWUgPSBCeXRlcy50b0ludChyb3cxX0EuZ2V0VmFsdWUoKSk7CisKKyAgICBCYXRjaFVwZGF0ZSB3cml0ZSA9IG5ldyBCYXRjaFVwZGF0ZShST1cxKTsKKyAgICB3cml0ZS5wdXQoQ09MX0EsIEJ5dGVzLnRvQnl0ZXModmFsdWUgKyAxKSk7CisgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHdyaXRlKTsKKworICAgIHJldHVybiB0cmFuc2FjdGlvblN0YXRlOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9TdHJlc3NUZXN0VHJhbnNhY3Rpb25zLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9jbGllbnQvdHJhbnNhY3Rpb25hbC9TdHJlc3NUZXN0VHJhbnNhY3Rpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJmZWMwMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2NsaWVudC90cmFuc2FjdGlvbmFsL1N0cmVzc1Rlc3RUcmFuc2FjdGlvbnMuamF2YQpAQCAtMCwwICsxLDQyMCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNCb29sZWFuOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pcGMuVHJhbnNhY3Rpb25hbFJlZ2lvbkludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIudHJhbnNhY3Rpb25hbC5UcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogU3RyZXNzIFRlc3QgdGhlIHRyYW5zYWN0aW9uIGZ1bmN0aW9uYWxpdHkuIFRoaXMgcmVxdWlyZXMgdG8gcnVuIGFuCisgKiB7QGxpbmsgVHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlcn0uIFdlIHJ1biBtYW55IHRocmVhZHMgZG9pbmcgcmVhZHMvd3JpdGVzCisgKiB3aGljaCBtYXkgY29uZmxpY3Qgd2l0aCBlYWNoIG90aGVyLiBXZSBoYXZlIHR3byB0eXBlcyBvZiB0cmFuc2FjdGlvbnMsIHRob3NlCisgKiB3aGljaCBvcGVyYXRlIG9uIHJvd3Mgb2YgYSBzaW5nbGUgdGFibGUsIGFuZCB0aG9zZSB3aGljaCBvcGVyYXRlIG9uIHJvd3MKKyAqIGFjcm9zcyBtdWx0aXBsZSB0YWJsZXMuIEVhY2ggdHJhbnNhY3Rpb24gdHlwZSBoYXMgYSBtb2RpZmljYXRpb24gb3BlcmF0aW9uCisgKiB3aGljaCBjaGFuZ2VzIHR3byB2YWx1ZXMgd2hpbGUgbWFpbnRhaW5pbmcgdGhlIHN1bS4gQWxzbyBlYWNoIHRyYW5zYWN0aW9uCisgKiB0eXBlIGhhcyBhIGNvbnNpc3RlbmN5LWNoZWNrIG9wZXJhdGlvbiB3aGljaCBzdW1zIGFsbCByb3dzIGFuZCB2ZXJpZmllcyB0aGF0CisgKiB0aGUgc3VtIGlzIGFzIGV4cGVjdGVkLgorICovCitwdWJsaWMgY2xhc3MgU3RyZXNzVGVzdFRyYW5zYWN0aW9ucyBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeQorICAgICAgLmdldExvZyhTdHJlc3NUZXN0VHJhbnNhY3Rpb25zLmNsYXNzKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1RBQkxFUyA9IDM7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fU1RfUk9XUyA9IDM7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fTVRfUk9XUyA9IDM7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fVFJBTlNBQ1RJT05TX1BFUl9USFJFQUQgPSAxMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fU0lOR0xFX1RBQkxFX1RIUkVBRFMgPSA2OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX01VTFRJX1RBQkxFX1RIUkVBRFMgPSA2OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgUFJFX0NPTU1JVF9TTEVFUCA9IDEwOworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFJhbmRvbSBSQU5EID0gbmV3IFJhbmRvbSgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBGQU1JTFkgPSBCeXRlcy50b0J5dGVzKCJmYW1pbHk6Iik7CisgIHN0YXRpYyBmaW5hbCBieXRlW10gQ09MID0gQnl0ZXMudG9CeXRlcygiZmFtaWx5OmEiKTsKKworICBwcml2YXRlIEhCYXNlQWRtaW4gYWRtaW47CisgIHByb3RlY3RlZCBUcmFuc2FjdGlvbmFsVGFibGVbXSB0YWJsZXM7CisgIHByb3RlY3RlZCBUcmFuc2FjdGlvbk1hbmFnZXIgdHJhbnNhY3Rpb25NYW5hZ2VyOworCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgU3RyZXNzVGVzdFRyYW5zYWN0aW9ucygpIHsKKyAgICBjb25mLnNldChIQ29uc3RhbnRzLlJFR0lPTl9TRVJWRVJfQ0xBU1MsIFRyYW5zYWN0aW9uYWxSZWdpb25JbnRlcmZhY2UuY2xhc3MKKyAgICAgICAgLmdldE5hbWUoKSk7CisgICAgY29uZi5zZXQoSENvbnN0YW50cy5SRUdJT05fU0VSVkVSX0lNUEwsIFRyYW5zYWN0aW9uYWxSZWdpb25TZXJ2ZXIuY2xhc3MKKyAgICAgICAgLmdldE5hbWUoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworCisgICAgdGFibGVzID0gbmV3IFRyYW5zYWN0aW9uYWxUYWJsZVtOVU1fVEFCTEVTXTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihtYWtlVGFibGVOYW1lKGkpKTsKKyAgICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihGQU1JTFkpKTsKKyAgICAgIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICAgIHRhYmxlc1tpXSA9IG5ldyBUcmFuc2FjdGlvbmFsVGFibGUoY29uZiwgZGVzYy5nZXROYW1lKCkpOworICAgIH0KKworICAgIHRyYW5zYWN0aW9uTWFuYWdlciA9IG5ldyBUcmFuc2FjdGlvbk1hbmFnZXIoY29uZik7CisgIH0KKworICBwcml2YXRlIFN0cmluZyBtYWtlVGFibGVOYW1lKGZpbmFsIGludCBpKSB7CisgICAgcmV0dXJuICJ0YWJsZSIgKyBpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlSW5pdGFsVmFsdWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKFRyYW5zYWN0aW9uYWxUYWJsZSB0YWJsZSA6IHRhYmxlcykgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1fU1RfUk9XUzsgaSsrKSB7CisgICAgICAgIGJ5dGVbXSByb3cgPSBtYWtlU1RSb3coaSk7CisgICAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgICAgYi5wdXQoQ09MLCBCeXRlcy50b0J5dGVzKFNpbmdsZVRhYmxlVHJhbnNhY3Rpb25UaHJlYWQuSU5JVElBTF9WQUxVRSkpOworICAgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgICB9CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTV9NVF9ST1dTOyBpKyspIHsKKyAgICAgICAgYnl0ZVtdIHJvdyA9IG1ha2VNVFJvdyhpKTsKKyAgICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgICAgICBiLnB1dChDT0wsIEJ5dGVzLnRvQnl0ZXMoTXVsdGlUYWJsZVRyYW5zYWN0aW9uVGhyZWFkLklOSVRJQUxfVkFMVUUpKTsKKyAgICAgICAgdGFibGUuY29tbWl0KGIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByb3RlY3RlZCBieXRlW10gbWFrZVNUUm93KGZpbmFsIGludCBpKSB7CisgICAgcmV0dXJuIEJ5dGVzLnRvQnl0ZXMoInN0IiArIGkpOworICB9CisKKyAgcHJvdGVjdGVkIGJ5dGVbXSBtYWtlTVRSb3coZmluYWwgaW50IGkpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcygibXQiICsgaSk7CisgIH0KKworICBzdGF0aWMgaW50IG5leHRUaHJlYWROdW0gPSAxOworICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIEF0b21pY0Jvb2xlYW4gc3RvcFJlcXVlc3QgPSBuZXcgQXRvbWljQm9vbGVhbihmYWxzZSk7CisgIHN0YXRpYyBmaW5hbCBBdG9taWNCb29sZWFuIGNvbnNpc3RlbmN5RmFpbHVyZSA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKworICAvLyBUaHJlYWQgd2hpY2ggcnVucyB0cmFuc2FjdGlvbnMKKyAgYWJzdHJhY3QgY2xhc3MgVHJhbnNhY3Rpb25UaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworICAgIHByaXZhdGUgaW50IG51bVJ1bnMgPSAwOworICAgIHByaXZhdGUgaW50IG51bUFib3J0cyA9IDA7CisgICAgcHJpdmF0ZSBpbnQgbnVtVW5rbm93bnMgPSAwOworCisgICAgcHVibGljIFRyYW5zYWN0aW9uVGhyZWFkKGZpbmFsIFN0cmluZyBuYW1lUHJlZml4KSB7CisgICAgICBzdXBlci5zZXROYW1lKG5hbWVQcmVmaXggKyAidHJhbnNhY3Rpb24gIiArIG5leHRUaHJlYWROdW0rKyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1fVFJBTlNBQ1RJT05TX1BFUl9USFJFQUQ7IGkrKykgeworICAgICAgICBpZiAoc3RvcFJlcXVlc3QuZ2V0KCkpIHsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBudW1SdW5zKys7CisgICAgICAgICAgdHJhbnNhY3Rpb24oKTsKKyAgICAgICAgfSBjYXRjaCAoVW5rbm93blRyYW5zYWN0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBudW1Vbmtub3ducysrOworICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CisgICAgICAgIH0gY2F0Y2ggKENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgbnVtQWJvcnRzKys7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCB0cmFuc2FjdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uOworCisgICAgcHVibGljIGludCBnZXROdW1BYm9ydHMoKSB7CisgICAgICByZXR1cm4gbnVtQWJvcnRzOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0TnVtVW5rbm93bnMoKSB7CisgICAgICByZXR1cm4gbnVtVW5rbm93bnM7CisgICAgfQorCisgICAgcHJvdGVjdGVkIHZvaWQgcHJlQ29tbWl0U2xlZXAoKSB7CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAoUFJFX0NPTU1JVF9TTEVFUCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOworICAgICAgfQorICAgIH0KKworICAgIHByb3RlY3RlZCB2b2lkIGNvbnNpc3RlbmN5RmFpbHVyZSgpIHsKKyAgICAgIExPRy5mYXRhbCgiQ29uc2lzdGVuY3kgZmFpbHVyZSIpOworICAgICAgc3RvcFJlcXVlc3Quc2V0KHRydWUpOworICAgICAgY29uc2lzdGVuY3lGYWlsdXJlLnNldCh0cnVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZXQgdGhlIG51bVJ1bnMuCisgICAgICogCisgICAgICogQHJldHVybiBSZXR1cm4gdGhlIG51bVJ1bnMuCisgICAgICovCisgICAgcHVibGljIGludCBnZXROdW1SdW5zKCkgeworICAgICAgcmV0dXJuIG51bVJ1bnM7CisgICAgfQorCisgIH0KKworICAvLyBBdG9taWNhbGx5IGNoYW5nZSB0aGUgdmFsdWUgb2YgdHdvIHJvd3Mgcm93cyB3aGlsZSBtYWludGFpbmluZyB0aGUgc3VtLgorICAvLyBUaGlzIHNob3VsZCBwcmVzZXJ2ZSB0aGUgZ2xvYmFsIHN1bSBvZiB0aGUgcm93cywgd2hpY2ggaXMgYWxzbyBjaGVja2VkCisgIC8vIHdpdGggYSB0cmFuc2FjdGlvbi4KKyAgcHJpdmF0ZSBjbGFzcyBTaW5nbGVUYWJsZVRyYW5zYWN0aW9uVGhyZWFkIGV4dGVuZHMgVHJhbnNhY3Rpb25UaHJlYWQgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX1ZBTFVFID0gMTA7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVE9UQUxfU1VNID0gSU5JVElBTF9WQUxVRSAqIE5VTV9TVF9ST1dTOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfVFJBTlNGRVJfQU1UID0gMTAwOworCisgICAgcHJpdmF0ZSBUcmFuc2FjdGlvbmFsVGFibGUgdGFibGU7CisgICAgYm9vbGVhbiBkb0NoZWNrID0gZmFsc2U7CisKKyAgICBwdWJsaWMgU2luZ2xlVGFibGVUcmFuc2FjdGlvblRocmVhZCgpIHsKKyAgICAgIHN1cGVyKCJzaW5nbGUgdGFibGUgIik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIHZvaWQgdHJhbnNhY3Rpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgICBpZiAoZG9DaGVjaykgeworICAgICAgICBjaGVja1RvdGFsU3VtKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBkb1NpbmdsZVJvd0NoYW5nZSgpOworICAgICAgfQorICAgICAgZG9DaGVjayA9ICFkb0NoZWNrOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBkb1NpbmdsZVJvd0NoYW5nZSgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgICAgQ29tbWl0VW5zdWNjZXNzZnVsRXhjZXB0aW9uIHsKKyAgICAgIHRhYmxlID0gdGFibGVzW1JBTkQubmV4dEludChOVU1fVEFCTEVTKV07CisgICAgICBpbnQgdHJhbnNmZXJBbW91bnQgPSBSQU5ELm5leHRJbnQoTUFYX1RSQU5TRkVSX0FNVCAqIDIpCisgICAgICAgICAgLSBNQVhfVFJBTlNGRVJfQU1UOworICAgICAgaW50IHJvdzFJbmRleCA9IFJBTkQubmV4dEludChOVU1fU1RfUk9XUyk7CisgICAgICBpbnQgcm93MkluZGV4OworICAgICAgZG8geworICAgICAgICByb3cySW5kZXggPSBSQU5ELm5leHRJbnQoTlVNX1NUX1JPV1MpOworICAgICAgfSB3aGlsZSAocm93MkluZGV4ID09IHJvdzFJbmRleCk7CisgICAgICBieXRlW10gcm93MSA9IG1ha2VTVFJvdyhyb3cxSW5kZXgpOworICAgICAgYnl0ZVtdIHJvdzIgPSBtYWtlU1RSb3cocm93MkluZGV4KTsKKworICAgICAgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlID0gdHJhbnNhY3Rpb25NYW5hZ2VyLmJlZ2luVHJhbnNhY3Rpb24oKTsKKyAgICAgIGludCByb3cxQW1vdW50ID0gQnl0ZXMudG9JbnQodGFibGUuZ2V0KHRyYW5zYWN0aW9uU3RhdGUsIHJvdzEsIENPTCkKKyAgICAgICAgICAuZ2V0VmFsdWUoKSk7CisgICAgICBpbnQgcm93MkFtb3VudCA9IEJ5dGVzLnRvSW50KHRhYmxlLmdldCh0cmFuc2FjdGlvblN0YXRlLCByb3cyLCBDT0wpCisgICAgICAgICAgLmdldFZhbHVlKCkpOworCisgICAgICByb3cxQW1vdW50IC09IHRyYW5zZmVyQW1vdW50OworICAgICAgcm93MkFtb3VudCArPSB0cmFuc2ZlckFtb3VudDsKKworICAgICAgQmF0Y2hVcGRhdGUgdXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdzEpOworICAgICAgdXBkYXRlLnB1dChDT0wsIEJ5dGVzLnRvQnl0ZXMocm93MUFtb3VudCkpOworICAgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHVwZGF0ZSk7CisgICAgICB1cGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93Mik7CisgICAgICB1cGRhdGUucHV0KENPTCwgQnl0ZXMudG9CeXRlcyhyb3cyQW1vdW50KSk7CisgICAgICB0YWJsZS5jb21taXQodHJhbnNhY3Rpb25TdGF0ZSwgdXBkYXRlKTsKKworICAgICAgc3VwZXIucHJlQ29tbWl0U2xlZXAoKTsKKworICAgICAgdHJhbnNhY3Rpb25NYW5hZ2VyLnRyeUNvbW1pdCh0cmFuc2FjdGlvblN0YXRlKTsKKyAgICAgIExPRy5kZWJ1ZygiQ29tbWl0ZWQiKTsKKyAgICB9CisKKyAgICAvLyBDaGVjayB0aGUgdGFibGUgd2UgbGFzdCBtdXRhdGVkCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVG90YWxTdW0oKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgICBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgPSB0cmFuc2FjdGlvbk1hbmFnZXIuYmVnaW5UcmFuc2FjdGlvbigpOworICAgICAgaW50IHRvdGFsU3VtID0gMDsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTlVNX1NUX1JPV1M7IGkrKykgeworICAgICAgICB0b3RhbFN1bSArPSBCeXRlcy50b0ludCh0YWJsZS5nZXQodHJhbnNhY3Rpb25TdGF0ZSwgbWFrZVNUUm93KGkpLCBDT0wpCisgICAgICAgICAgICAuZ2V0VmFsdWUoKSk7CisgICAgICB9CisKKyAgICAgIHRyYW5zYWN0aW9uTWFuYWdlci50cnlDb21taXQodHJhbnNhY3Rpb25TdGF0ZSk7CisgICAgICBpZiAoVE9UQUxfU1VNICE9IHRvdGFsU3VtKSB7CisgICAgICAgIHN1cGVyLmNvbnNpc3RlbmN5RmFpbHVyZSgpOworICAgICAgfQorICAgIH0KKworICB9CisKKyAgLy8gU2ltaWxhciB0byBTaW5nbGVUYWJsZSwgYnV0IHRoaXMgdGltZSB3ZSBtYWludGFpbiBjb25zaXN0ZW5jeSBhY3Jvc3MgdGFibGVzCisgIC8vIHJhdGhlciB0aGFuIHJvd3MKKyAgcHJpdmF0ZSBjbGFzcyBNdWx0aVRhYmxlVHJhbnNhY3Rpb25UaHJlYWQgZXh0ZW5kcyBUcmFuc2FjdGlvblRocmVhZCB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfVkFMVUUgPSAxMDAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRPVEFMX1NVTSA9IElOSVRJQUxfVkFMVUUgKiBOVU1fVEFCTEVTOworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfVFJBTlNGRVJfQU1UID0gMTAwOworCisgICAgcHJpdmF0ZSBieXRlW10gcm93OworICAgIGJvb2xlYW4gZG9DaGVjayA9IGZhbHNlOworCisgICAgcHVibGljIE11bHRpVGFibGVUcmFuc2FjdGlvblRocmVhZCgpIHsKKyAgICAgIHN1cGVyKCJtdWx0aSB0YWJsZSIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIHRyYW5zYWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICBDb21taXRVbnN1Y2Nlc3NmdWxFeGNlcHRpb24geworICAgICAgaWYgKGRvQ2hlY2spIHsKKyAgICAgICAgY2hlY2tUb3RhbFN1bSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZG9TaW5nbGVSb3dDaGFuZ2UoKTsKKyAgICAgIH0KKyAgICAgIGRvQ2hlY2sgPSAhZG9DaGVjazsKKyAgICB9CisKKyAgICBwcml2YXRlIHZvaWQgZG9TaW5nbGVSb3dDaGFuZ2UoKSB0aHJvd3MgSU9FeGNlcHRpb24sCisgICAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgICByb3cgPSBtYWtlTVRSb3coUkFORC5uZXh0SW50KE5VTV9NVF9ST1dTKSk7CisgICAgICBpbnQgdHJhbnNmZXJBbW91bnQgPSBSQU5ELm5leHRJbnQoTUFYX1RSQU5TRkVSX0FNVCAqIDIpCisgICAgICAgICAgLSBNQVhfVFJBTlNGRVJfQU1UOworICAgICAgaW50IHRhYmxlMUluZGV4ID0gUkFORC5uZXh0SW50KHRhYmxlcy5sZW5ndGgpOworICAgICAgaW50IHRhYmxlMkluZGV4OworICAgICAgZG8geworICAgICAgICB0YWJsZTJJbmRleCA9IFJBTkQubmV4dEludCh0YWJsZXMubGVuZ3RoKTsKKyAgICAgIH0gd2hpbGUgKHRhYmxlMkluZGV4ID09IHRhYmxlMUluZGV4KTsKKworICAgICAgVHJhbnNhY3Rpb25hbFRhYmxlIHRhYmxlMSA9IHRhYmxlc1t0YWJsZTFJbmRleF07CisgICAgICBUcmFuc2FjdGlvbmFsVGFibGUgdGFibGUyID0gdGFibGVzW3RhYmxlMkluZGV4XTsKKworICAgICAgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlID0gdHJhbnNhY3Rpb25NYW5hZ2VyLmJlZ2luVHJhbnNhY3Rpb24oKTsKKyAgICAgIGludCB0YWJsZTFBbW91bnQgPSBCeXRlcy50b0ludCh0YWJsZTEuZ2V0KHRyYW5zYWN0aW9uU3RhdGUsIHJvdywgQ09MKQorICAgICAgICAgIC5nZXRWYWx1ZSgpKTsKKyAgICAgIGludCB0YWJsZTJBbW91bnQgPSBCeXRlcy50b0ludCh0YWJsZTIuZ2V0KHRyYW5zYWN0aW9uU3RhdGUsIHJvdywgQ09MKQorICAgICAgICAgIC5nZXRWYWx1ZSgpKTsKKworICAgICAgdGFibGUxQW1vdW50IC09IHRyYW5zZmVyQW1vdW50OworICAgICAgdGFibGUyQW1vdW50ICs9IHRyYW5zZmVyQW1vdW50OworCisgICAgICBCYXRjaFVwZGF0ZSB1cGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgIHVwZGF0ZS5wdXQoQ09MLCBCeXRlcy50b0J5dGVzKHRhYmxlMUFtb3VudCkpOworICAgICAgdGFibGUxLmNvbW1pdCh0cmFuc2FjdGlvblN0YXRlLCB1cGRhdGUpOworCisgICAgICB1cGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgIHVwZGF0ZS5wdXQoQ09MLCBCeXRlcy50b0J5dGVzKHRhYmxlMkFtb3VudCkpOworICAgICAgdGFibGUyLmNvbW1pdCh0cmFuc2FjdGlvblN0YXRlLCB1cGRhdGUpOworCisgICAgICBzdXBlci5wcmVDb21taXRTbGVlcCgpOworCisgICAgICB0cmFuc2FjdGlvbk1hbmFnZXIudHJ5Q29tbWl0KHRyYW5zYWN0aW9uU3RhdGUpOworCisgICAgICBMT0cudHJhY2UoQnl0ZXMudG9TdHJpbmcodGFibGUxLmdldFRhYmxlTmFtZSgpKSArICI6ICIgKyB0YWJsZTFBbW91bnQpOworICAgICAgTE9HLnRyYWNlKEJ5dGVzLnRvU3RyaW5nKHRhYmxlMi5nZXRUYWJsZU5hbWUoKSkgKyAiOiAiICsgdGFibGUyQW1vdW50KTsKKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjaGVja1RvdGFsU3VtKCkgdGhyb3dzIElPRXhjZXB0aW9uLAorICAgICAgICBDb21taXRVbnN1Y2Nlc3NmdWxFeGNlcHRpb24geworICAgICAgVHJhbnNhY3Rpb25TdGF0ZSB0cmFuc2FjdGlvblN0YXRlID0gdHJhbnNhY3Rpb25NYW5hZ2VyLmJlZ2luVHJhbnNhY3Rpb24oKTsKKyAgICAgIGludCB0b3RhbFN1bSA9IDA7CisgICAgICBpbnRbXSBhbW91bnRzID0gbmV3IGludFt0YWJsZXMubGVuZ3RoXTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGludCBhbW91bnQgPSBCeXRlcy50b0ludCh0YWJsZXNbaV0uZ2V0KHRyYW5zYWN0aW9uU3RhdGUsIHJvdywgQ09MKQorICAgICAgICAgICAgLmdldFZhbHVlKCkpOworICAgICAgICBhbW91bnRzW2ldID0gYW1vdW50OworICAgICAgICB0b3RhbFN1bSArPSBhbW91bnQ7CisgICAgICB9CisKKyAgICAgIHRyYW5zYWN0aW9uTWFuYWdlci50cnlDb21taXQodHJhbnNhY3Rpb25TdGF0ZSk7CisKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIExPRy50cmFjZShCeXRlcy50b1N0cmluZyh0YWJsZXNbaV0uZ2V0VGFibGVOYW1lKCkpICsgIjogIiArIGFtb3VudHNbaV0pOworICAgICAgfQorCisgICAgICBpZiAoVE9UQUxfU1VNICE9IHRvdGFsU3VtKSB7CisgICAgICAgIHN1cGVyLmNvbnNpc3RlbmN5RmFpbHVyZSgpOworICAgICAgfQorICAgIH0KKworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFN0cmVzc1RyYW5zYWN0aW9ucygpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIHdyaXRlSW5pdGFsVmFsdWVzKCk7CisKKyAgICBMaXN0PFRyYW5zYWN0aW9uVGhyZWFkPiB0cmFuc2FjdGlvblRocmVhZHMgPSBuZXcgTGlua2VkTGlzdDxUcmFuc2FjdGlvblRocmVhZD4oKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTlVNX1NJTkdMRV9UQUJMRV9USFJFQURTOyBpKyspIHsKKyAgICAgIFRyYW5zYWN0aW9uVGhyZWFkIHRyYW5zYWN0aW9uVGhyZWFkID0gbmV3IFNpbmdsZVRhYmxlVHJhbnNhY3Rpb25UaHJlYWQoKTsKKyAgICAgIHRyYW5zYWN0aW9uVGhyZWFkLnN0YXJ0KCk7CisgICAgICB0cmFuc2FjdGlvblRocmVhZHMuYWRkKHRyYW5zYWN0aW9uVGhyZWFkKTsKKyAgICB9CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTV9NVUxUSV9UQUJMRV9USFJFQURTOyBpKyspIHsKKyAgICAgIFRyYW5zYWN0aW9uVGhyZWFkIHRyYW5zYWN0aW9uVGhyZWFkID0gbmV3IE11bHRpVGFibGVUcmFuc2FjdGlvblRocmVhZCgpOworICAgICAgdHJhbnNhY3Rpb25UaHJlYWQuc3RhcnQoKTsKKyAgICAgIHRyYW5zYWN0aW9uVGhyZWFkcy5hZGQodHJhbnNhY3Rpb25UaHJlYWQpOworICAgIH0KKworICAgIGZvciAoVHJhbnNhY3Rpb25UaHJlYWQgdHJhbnNhY3Rpb25UaHJlYWQgOiB0cmFuc2FjdGlvblRocmVhZHMpIHsKKyAgICAgIHRyYW5zYWN0aW9uVGhyZWFkLmpvaW4oKTsKKyAgICB9CisKKyAgICBmb3IgKFRyYW5zYWN0aW9uVGhyZWFkIHRyYW5zYWN0aW9uVGhyZWFkIDogdHJhbnNhY3Rpb25UaHJlYWRzKSB7CisgICAgICBMT0cuaW5mbyh0cmFuc2FjdGlvblRocmVhZC5nZXROYW1lKCkgKyAiIGRvbmUgd2l0aCAiCisgICAgICAgICAgKyB0cmFuc2FjdGlvblRocmVhZC5nZXROdW1BYm9ydHMoKSArICIgYWJvcnRzLCBhbmQgIgorICAgICAgICAgICsgdHJhbnNhY3Rpb25UaHJlYWQuZ2V0TnVtVW5rbm93bnMoKSArICIgdW5rbm93biB0cmFuc2FjdGlvbnMgb2YgIgorICAgICAgICAgICsgdHJhbnNhY3Rpb25UaHJlYWQuZ2V0TnVtUnVucygpKTsKKyAgICB9CisKKyAgICBkb0ZpbmFsQ29uc2lzdGVuY3lDaGVja3MoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBkb0ZpbmFsQ29uc2lzdGVuY3lDaGVja3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgaW50W10gbXRTdW1zID0gbmV3IGludFtOVU1fTVRfUk9XU107CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtdFN1bXMubGVuZ3RoOyBpKyspIHsKKyAgICAgIG10U3Vtc1tpXSA9IDA7CisgICAgfQorCisgICAgZm9yIChUcmFuc2FjdGlvbmFsVGFibGUgdGFibGUgOiB0YWJsZXMpIHsKKyAgICAgIGludCB0aGlzVGFibGVTdW0gPSAwOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1fU1RfUk9XUzsgaSsrKSB7CisgICAgICAgIGJ5dGVbXSByb3cgPSBtYWtlU1RSb3coaSk7CisgICAgICAgIHRoaXNUYWJsZVN1bSArPSBCeXRlcy50b0ludCh0YWJsZS5nZXQocm93LCBDT0wpLmdldFZhbHVlKCkpOworICAgICAgfQorICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscyhTaW5nbGVUYWJsZVRyYW5zYWN0aW9uVGhyZWFkLlRPVEFMX1NVTSwgdGhpc1RhYmxlU3VtKTsKKworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1fTVRfUk9XUzsgaSsrKSB7CisgICAgICAgIGJ5dGVbXSByb3cgPSBtYWtlTVRSb3coaSk7CisgICAgICAgIG10U3Vtc1tpXSArPSBCeXRlcy50b0ludCh0YWJsZS5nZXQocm93LCBDT0wpLmdldFZhbHVlKCkpOworICAgICAgfQorICAgIH0KKworICAgIGZvciAoaW50IG10U3VtIDogbXRTdW1zKSB7CisgICAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKE11bHRpVGFibGVUcmFuc2FjdGlvblRocmVhZC5UT1RBTF9TVU0sIG10U3VtKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RJbmNsdXNpdmVTdG9wUm93RmlsdGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0SW5jbHVzaXZlU3RvcFJvd0ZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhMzY1NmYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0SW5jbHVzaXZlU3RvcFJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgdGhlIGluY2x1c2l2ZSBzdG9wIHJvdyBmaWx0ZXIKKyAqLworcHVibGljIGNsYXNzIERpc2FibGVkVGVzdEluY2x1c2l2ZVN0b3BSb3dGaWx0ZXIgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBTVE9QX1JPVyA9IEJ5dGVzLnRvQnl0ZXMoInN0b3Bfcm93Iik7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBHT09EX1JPVyA9IEJ5dGVzLnRvQnl0ZXMoImdvb2Rfcm93Iik7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBQQVNUX1NUT1BfUk9XID0gQnl0ZXMudG9CeXRlcygienp6enp6Iik7CisgIAorICBSb3dGaWx0ZXJJbnRlcmZhY2UgbWFpbkZpbHRlcjsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIG1haW5GaWx0ZXIgPSBuZXcgSW5jbHVzaXZlU3RvcFJvd0ZpbHRlcihTVE9QX1JPVyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyBpZGVudGlmaWNhdGlvbiBvZiB0aGUgc3RvcCByb3cKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTdG9wUm93SWRlbnRpZmljYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9wUm93VGVzdHMobWFpbkZpbHRlcik7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyBzZXJpYWxpemF0aW9uCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIERlY29tcG9zZSBtYWluRmlsdGVyIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIG1haW5GaWx0ZXIud3JpdGUob3V0KTsKKyAgICBvdXQuY2xvc2UoKTsKKyAgICBieXRlW10gYnVmZmVyID0gc3RyZWFtLnRvQnl0ZUFycmF5KCk7CisgICAgCisgICAgLy8gUmVjb21wb3NlIG1haW5GaWx0ZXIuCisgICAgRGF0YUlucHV0U3RyZWFtIGluID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgUm93RmlsdGVySW50ZXJmYWNlIG5ld0ZpbHRlciA9IG5ldyBJbmNsdXNpdmVTdG9wUm93RmlsdGVyKCk7CisgICAgbmV3RmlsdGVyLnJlYWRGaWVsZHMoaW4pOworICAgIAorICAgIC8vIEVuc3VyZSB0aGUgc2VyaWFsaXphdGlvbiBwcmVzZXJ2ZWQgdGhlIGZpbHRlciBieSBydW5uaW5nIGEgZnVsbCB0ZXN0LgorICAgIHN0b3BSb3dUZXN0cyhuZXdGaWx0ZXIpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgc3RvcFJvd1Rlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydEZhbHNlKCJGaWx0ZXJpbmcgb24gIiArIEJ5dGVzLnRvU3RyaW5nKEdPT0RfUk9XKSwgZmlsdGVyLmZpbHRlclJvd0tleShHT09EX1JPVykpOworICAgIGFzc2VydEZhbHNlKCJGaWx0ZXJpbmcgb24gIiArIEJ5dGVzLnRvU3RyaW5nKFNUT1BfUk9XKSwgZmlsdGVyLmZpbHRlclJvd0tleShTVE9QX1JPVykpOworICAgIGFzc2VydFRydWUoIkZpbHRlcmluZyBvbiAiICsgQnl0ZXMudG9TdHJpbmcoUEFTVF9TVE9QX1JPVyksIGZpbHRlci5maWx0ZXJSb3dLZXkoUEFTVF9TVE9QX1JPVykpOworICAgIAorICAgIGFzc2VydEZhbHNlKCJGaWx0ZXJpbmcgb24gIiArIEJ5dGVzLnRvU3RyaW5nKEdPT0RfUk9XKSwgZmlsdGVyLmZpbHRlckNvbHVtbihHT09EX1JPVywgbnVsbCwgCisgICAgICBudWxsKSk7CisgICAgYXNzZXJ0RmFsc2UoIkZpbHRlcmluZyBvbiAiICsgQnl0ZXMudG9TdHJpbmcoU1RPUF9ST1cpLCBmaWx0ZXIuZmlsdGVyQ29sdW1uKFNUT1BfUk9XLCBudWxsLCBudWxsKSk7CisgICAgYXNzZXJ0VHJ1ZSgiRmlsdGVyaW5nIG9uICIgKyBCeXRlcy50b1N0cmluZyhQQVNUX1NUT1BfUk9XKSwgZmlsdGVyLmZpbHRlckNvbHVtbihQQVNUX1NUT1BfUk9XLCAKKyAgICAgIG51bGwsIG51bGwpKTsKKworICAgIGFzc2VydEZhbHNlKCJGaWx0ZXJBbGxSZW1haW5pbmciLCBmaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkpOworICAgIGFzc2VydEZhbHNlKCJGaWx0ZXJOb3ROdWxsIiwgZmlsdGVyLmZpbHRlclJvdygoTGlzdDxLZXlWYWx1ZT4pbnVsbCkpOworICAgIAorICAgIGFzc2VydEZhbHNlKCJGaWx0ZXIgYSBudWxsIiwgZmlsdGVyLmZpbHRlclJvd0tleShudWxsKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RQYWdlUm93RmlsdGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0UGFnZVJvd0ZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjMGZkZmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0UGFnZVJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworLyoqCisgKiBUZXN0cyBmb3IgdGhlIHBhZ2Ugcm93IGZpbHRlcgorICovCitwdWJsaWMgY2xhc3MgRGlzYWJsZWRUZXN0UGFnZVJvd0ZpbHRlciBleHRlbmRzIFRlc3RDYXNlIHsKKyAgCisgIFJvd0ZpbHRlckludGVyZmFjZSBtYWluRmlsdGVyOworICBzdGF0aWMgZmluYWwgaW50IFJPV19MSU1JVCA9IDM7CisgIAorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIG1haW5GaWx0ZXIgPSBuZXcgUGFnZVJvd0ZpbHRlcihST1dfTElNSVQpOworICB9CisgIAorICAvKioKKyAgICogdGVzdCBwYWdlIHNpemUgZmlsdGVyCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UGFnZVNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBwYWdlU2l6ZVRlc3RzKG1haW5GaWx0ZXIpOworICB9CisgIAorICAvKioKKyAgICogVGVzdCBmaWx0ZXIgc2VyaWFsaXphdGlvbgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBEZWNvbXBvc2UgbWFpbkZpbHRlciB0byBieXRlcy4KKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gc3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIERhdGFPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oc3RyZWFtKTsKKyAgICBtYWluRmlsdGVyLndyaXRlKG91dCk7CisgICAgb3V0LmNsb3NlKCk7CisgICAgYnl0ZVtdIGJ1ZmZlciA9IHN0cmVhbS50b0J5dGVBcnJheSgpOworICAgIAorICAgIC8vIFJlY29tcG9zZSBtYWluRmlsdGVyLgorICAgIERhdGFJbnB1dFN0cmVhbSBpbiA9IG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZmZlcikpOworICAgIFJvd0ZpbHRlckludGVyZmFjZSBuZXdGaWx0ZXIgPSBuZXcgUGFnZVJvd0ZpbHRlcigpOworICAgIG5ld0ZpbHRlci5yZWFkRmllbGRzKGluKTsKKyAgICAKKyAgICAvLyBFbnN1cmUgdGhlIHNlcmlhbGl6YXRpb24gcHJlc2VydmVkIHRoZSBmaWx0ZXIgYnkgcnVubmluZyBhIGZ1bGwgdGVzdC4KKyAgICBwYWdlU2l6ZVRlc3RzKG5ld0ZpbHRlcik7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBwYWdlU2l6ZVRlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgIHRlc3RGaWx0ZXJzQmV5b25kUGFnZVNpemUoZmlsdGVyLCBST1dfTElNSVQpOworICAgIC8vIFRlc3QgcmVzZXQgd29ya3MgYnkgZ29pbmcgaW4gYWdhaW4uCisgICAgZmlsdGVyLnJlc2V0KCk7CisgICAgdGVzdEZpbHRlcnNCZXlvbmRQYWdlU2l6ZShmaWx0ZXIsIFJPV19MSU1JVCk7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCB0ZXN0RmlsdGVyc0JleW9uZFBhZ2VTaXplKGZpbmFsIFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIsCisgICAgZmluYWwgaW50IHBhZ2VTaXplKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAocGFnZVNpemUgKiAyKTsgaSsrKSB7CisgICAgICBieXRlIFtdIHJvdyA9IEJ5dGVzLnRvQnl0ZXMoSW50ZWdlci50b1N0cmluZyhpKSk7CisgICAgICBib29sZWFuIGZpbHRlck91dCA9IGZpbHRlci5maWx0ZXJSb3dLZXkocm93KTsKKyAgICAgIGlmICghZmlsdGVyT3V0KSB7CisgICAgICAgIGFzc2VydEZhbHNlKCJEaXNhZ3JlZXMgd2l0aCAnZmlsdGVyJyIsIGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBPbmNlIHdlIGhhdmUgYWxsIGZvciBhIHBhZ2UsIGNhbGxzIHRvIGZpbHRlckFsbFJlbWFpbmluZyBzaG91bGQKKyAgICAgICAgLy8gc3RheSB0cnVlLgorICAgICAgICBhc3NlcnRUcnVlKCJEaXNhZ3JlZXMgd2l0aCAnZmlsdGVyJyIsIGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgICAgICAgIGFzc2VydFRydWUoaSA+PSBwYWdlU2l6ZSk7CisgICAgICB9CisgICAgICBmaWx0ZXIucm93UHJvY2Vzc2VkKGZpbHRlck91dCwgcm93KTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RQcmVmaXhSb3dGaWx0ZXIuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RQcmVmaXhSb3dGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNmFmOGYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL0Rpc2FibGVkVGVzdFByZWZpeFJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsOTkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGVzdHMgZm9yIGEgcHJlZml4IHJvdyBmaWx0ZXIKKyAqLworcHVibGljIGNsYXNzIERpc2FibGVkVGVzdFByZWZpeFJvd0ZpbHRlciBleHRlbmRzIFRlc3RDYXNlIHsKKyAgUm93RmlsdGVySW50ZXJmYWNlIG1haW5GaWx0ZXI7CisgIHN0YXRpYyBmaW5hbCBjaGFyIEZJUlNUX0NIQVIgPSAnYSc7CisgIHN0YXRpYyBmaW5hbCBjaGFyIExBU1RfQ0hBUiA9ICdlJzsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBIT1NUX1BSRUZJWCA9ICJvcmcuYXBhY2hlLnNpdGUtIjsKKyAgc3RhdGljIGJ5dGUgW10gR09PRF9CWVRFUyA9IG51bGw7CisKKyAgc3RhdGljIHsKKyAgICB0cnkgeworICAgICAgR09PRF9CWVRFUyA9ICJhYmMiLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORyk7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICBmYWlsKCk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB0aGlzLm1haW5GaWx0ZXIgPSBuZXcgUHJlZml4Um93RmlsdGVyKEJ5dGVzLnRvQnl0ZXMoSE9TVF9QUkVGSVgpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3RzIGZpbHRlcmluZyB1c2luZyBhIHJlZ2V4IG9uIHRoZSByb3cga2V5CisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UHJlZml4T25Sb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBwcmVmaXhSb3dUZXN0cyhtYWluRmlsdGVyKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3Qgc2VyaWFsaXphdGlvbgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNlcmlhbGl6YXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBEZWNvbXBvc2UgbWFpbkZpbHRlciB0byBieXRlcy4KKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gc3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIERhdGFPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oc3RyZWFtKTsKKyAgICBtYWluRmlsdGVyLndyaXRlKG91dCk7CisgICAgb3V0LmNsb3NlKCk7CisgICAgYnl0ZVtdIGJ1ZmZlciA9IHN0cmVhbS50b0J5dGVBcnJheSgpOworICAgIAorICAgIC8vIFJlY29tcG9zZSBmaWx0ZXIuCisgICAgRGF0YUlucHV0U3RyZWFtIGluID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgUm93RmlsdGVySW50ZXJmYWNlIG5ld0ZpbHRlciA9IG5ldyBQcmVmaXhSb3dGaWx0ZXIoKTsKKyAgICBuZXdGaWx0ZXIucmVhZEZpZWxkcyhpbik7CisgICAgCisgICAgLy8gRW5zdXJlIHRoZSBzZXJpYWxpemF0aW9uIHByZXNlcnZlZCB0aGUgZmlsdGVyIGJ5IHJ1bm5pbmcgYWxsIHRlc3QuCisgICAgcHJlZml4Um93VGVzdHMobmV3RmlsdGVyKTsKKyAgfQorIAorICBwcml2YXRlIHZvaWQgcHJlZml4Um93VGVzdHMoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZm9yIChjaGFyIGMgPSBGSVJTVF9DSEFSOyBjIDw9IExBU1RfQ0hBUjsgYysrKSB7CisgICAgICBieXRlIFtdIHQgPSBjcmVhdGVSb3coYyk7CisgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHdpdGggY2hhcmFjZXIgIiArIGMsIGZpbHRlci5maWx0ZXJSb3dLZXkodCkpOworICAgIH0KKyAgICBTdHJpbmcgeWFob29TaXRlID0gImNvbS55YWhvby53d3ciOworICAgIGFzc2VydFRydWUoIkZhaWxlZCB3aXRoIGNoYXJhY3RlciAiICsKKyAgICAgIHlhaG9vU2l0ZSwgZmlsdGVyLmZpbHRlclJvd0tleShCeXRlcy50b0J5dGVzKHlhaG9vU2l0ZSkpKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBieXRlIFtdIGNyZWF0ZVJvdyhmaW5hbCBjaGFyIGMpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcyhIT1NUX1BSRUZJWCArIENoYXJhY3Rlci50b1N0cmluZyhjKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSZWdFeHBSb3dGaWx0ZXIuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSZWdFeHBSb3dGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTlhMTE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL0Rpc2FibGVkVGVzdFJlZ0V4cFJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsMTk5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0cyBmb3IgcmVndWxhciBleHByZXNzaW9uIHJvdyBmaWx0ZXIKKyAqLworcHVibGljIGNsYXNzIERpc2FibGVkVGVzdFJlZ0V4cFJvd0ZpbHRlciBleHRlbmRzIFRlc3RDYXNlIHsKKyAgVHJlZU1hcDxieXRlIFtdLCBDZWxsPiBjb2x2YWx1ZXM7CisgIFJvd0ZpbHRlckludGVyZmFjZSBtYWluRmlsdGVyOworICBzdGF0aWMgZmluYWwgY2hhciBGSVJTVF9DSEFSID0gJ2EnOworICBzdGF0aWMgZmluYWwgY2hhciBMQVNUX0NIQVIgPSAnZSc7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgSE9TVF9QUkVGSVggPSAib3JnLmFwYWNoZS5zaXRlLSI7CisgIHN0YXRpYyBieXRlIFtdIEdPT0RfQllURVMgPSBudWxsOworCisgIHN0YXRpYyB7CisgICAgdHJ5IHsKKyAgICAgIEdPT0RfQllURVMgPSAiYWJjIi5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgZmFpbCgpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgICAgdGhpcy5jb2x2YWx1ZXMgPSBuZXcgVHJlZU1hcDxieXRlIFtdLCBDZWxsPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICBmb3IgKGNoYXIgYyA9IEZJUlNUX0NIQVI7IGMgPCBMQVNUX0NIQVI7IGMrKykgeworICAgICAgY29sdmFsdWVzLnB1dChCeXRlcy50b0J5dGVzKG5ldyBTdHJpbmcobmV3IGNoYXIgW10ge2N9KSksCisgICAgICAgICAgbmV3IENlbGwoR09PRF9CWVRFUywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKSk7CisgICAgfQorICAgIHRoaXMubWFpbkZpbHRlciA9IG5ldyBSZWdFeHBSb3dGaWx0ZXIoSE9TVF9QUkVGSVggKyAiLioiLCBjb2x2YWx1ZXMpOworICB9CisgIAorICAvKioKKyAgICogVGVzdHMgZmlsdGVyaW5nIHVzaW5nIGEgcmVnZXggb24gdGhlIHJvdyBrZXkKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RSZWdleE9uUm93KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgcmVnZXhSb3dUZXN0cyhtYWluRmlsdGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBmaWx0ZXJpbmcgdXNpbmcgYSByZWdleCBvbiByb3cgYW5kIGNvbHVtCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0UmVnZXhPblJvd0FuZENvbHVtbigpIHRocm93cyBFeGNlcHRpb24geworICAgIHJlZ2V4Um93Q29sdW1uVGVzdHMobWFpbkZpbHRlcik7CisgIH0KKyAgCisgIC8qKgorICAgKiBPbmx5IHJldHVybiB2YWx1ZXMgdGhhdCBhcmUgbm90IG51bGwKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RGaWx0ZXJOb3ROdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmlsdGVyTm90TnVsbFRlc3RzKG1haW5GaWx0ZXIpOworICB9CisgIAorICAvKioKKyAgICogVGVzdCBzZXJpYWxpemF0aW9uCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIERlY29tcG9zZSBtYWluRmlsdGVyIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIG1haW5GaWx0ZXIud3JpdGUob3V0KTsKKyAgICBvdXQuY2xvc2UoKTsKKyAgICBieXRlW10gYnVmZmVyID0gc3RyZWFtLnRvQnl0ZUFycmF5KCk7CisgICAgCisgICAgLy8gUmVjb21wb3NlIGZpbHRlci4KKyAgICBEYXRhSW5wdXRTdHJlYW0gaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWZmZXIpKTsKKyAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgbmV3RmlsdGVyID0gbmV3IFJlZ0V4cFJvd0ZpbHRlcigpOworICAgIG5ld0ZpbHRlci5yZWFkRmllbGRzKGluKTsKKyAgICAKKyAgICAvLyBFbnN1cmUgdGhlIHNlcmlhbGl6YXRpb24gcHJlc2VydmVkIHRoZSBmaWx0ZXIgYnkgcnVubmluZyBhbGwgdGVzdC4KKyAgICByZWdleFJvd1Rlc3RzKG5ld0ZpbHRlcik7CisgICAgbmV3RmlsdGVyLnJlc2V0KCk7CisgICAgcmVnZXhSb3dDb2x1bW5UZXN0cyhuZXdGaWx0ZXIpOworICAgIG5ld0ZpbHRlci5yZXNldCgpOworICAgIGZpbHRlck5vdE51bGxUZXN0cyhuZXdGaWx0ZXIpOworICB9CisgCisgIHByaXZhdGUgdm9pZCByZWdleFJvd1Rlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgIGZvciAoY2hhciBjID0gRklSU1RfQ0hBUjsgYyA8PSBMQVNUX0NIQVI7IGMrKykgeworICAgICAgYnl0ZSBbXSB0ID0gY3JlYXRlUm93KGMpOworICAgICAgYXNzZXJ0RmFsc2UoIkZhaWxlZCB3aXRoIGNoYXJhY2VyICIgKyBjLCBmaWx0ZXIuZmlsdGVyUm93S2V5KHQpKTsKKyAgICB9CisgICAgU3RyaW5nIHlhaG9vU2l0ZSA9ICJjb20ueWFob28ud3d3IjsKKyAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBjaGFyYWN0ZXIgIiArCisgICAgICB5YWhvb1NpdGUsIGZpbHRlci5maWx0ZXJSb3dLZXkoQnl0ZXMudG9CeXRlcyh5YWhvb1NpdGUpKSk7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCByZWdleFJvd0NvbHVtblRlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgICAgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIAorICAgIGZvciAoY2hhciBjID0gRklSU1RfQ0hBUjsgYyA8PSBMQVNUX0NIQVI7IGMrKykgeworICAgICAgYnl0ZSBbXSB0ID0gY3JlYXRlUm93KGMpOworICAgICAgZm9yIChNYXAuRW50cnk8Ynl0ZSBbXSwgQ2VsbD4gZTogdGhpcy5jb2x2YWx1ZXMuZW50cnlTZXQoKSkgeworICAgICAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIG9uICIgKyBjLAorICAgICAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4odCwgZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpLmdldFZhbHVlKCkpKTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gVHJ5IGEgcm93IGFuZCBjb2x1bW4gSSBrbm93IHdpbGwgcGFzcy4KKyAgICBjaGFyIGMgPSAnYyc7CisgICAgYnl0ZSBbXSByID0gY3JlYXRlUm93KGMpOworICAgIGJ5dGUgW10gY29sID0gQnl0ZXMudG9CeXRlcyhDaGFyYWN0ZXIudG9TdHJpbmcoYykpOworICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgd2l0aCBjaGFyYWN0ZXIgIiArIGMsCisgICAgICBmaWx0ZXIuZmlsdGVyQ29sdW1uKHIsIGNvbCwgR09PRF9CWVRFUykpOworICAgIAorICAgIC8vIERvIHNhbWUgYnV0IHdpdGggYmFkIGJ5dGVzLgorICAgIGFzc2VydFRydWUoIkZhaWxlZCB3aXRoIGNoYXJhY3RlciAiICsgYywKKyAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4ociwgY29sLCAiYmFkYnl0ZXMiLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpKTsKKyAgICAKKyAgICAvLyBEbyB3aXRoIGdvb2QgYnl0ZXMgYnV0IGJhZCBjb2x1bW4gbmFtZS4gIFNob3VsZCBub3QgZmlsdGVyIG91dC4KKyAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHdpdGggY2hhcmFjdGVyICIgKyBjLAorICAgICAgZmlsdGVyLmZpbHRlckNvbHVtbihyLCBCeXRlcy50b0J5dGVzKCJiYWRjb2x1bW4iKSwgR09PRF9CWVRFUykpOworICAgIAorICAgIC8vIEdvb2QgY29sdW1uLCBnb29kIGJ5dGVzIGJ1dCBiYWQgcm93LgorICAgIGFzc2VydFRydWUoIkZhaWxlZCB3aXRoIGNoYXJhY3RlciAiICsgYywKKyAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4oQnl0ZXMudG9CeXRlcygiYmFkIHJvdyIpLAorICAgICAgICBCeXRlcy50b0J5dGVzKCJiYWRjb2x1bW4iKSwgR09PRF9CWVRFUykpOworICB9CisgCisgIHByaXZhdGUgdm9pZCBmaWx0ZXJOb3ROdWxsVGVzdHMoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTW9kaWZ5IHRoZSBmaWx0ZXIgdG8gZXhwZWN0IGNlcnRhaW4gY29sdW1ucyB0byBiZSBudWxsOgorICAgIC8vIEV4cGVjdGluZyBhIHJvdyBXSVRIIGNvbHVtbktleXM6IGEtZCwgV0lUSE9VVCBjb2x1bW5LZXk6IGUKKyAgICAoKFJlZ0V4cFJvd0ZpbHRlcilmaWx0ZXIpLnNldENvbHVtbkZpbHRlcihuZXcgYnl0ZSBbXSB7TEFTVF9DSEFSfSwgbnVsbCk7CisgICAgCisgICAgY2hhciBzZWNvbmRUb0xhc3QgPSAoY2hhcikoTEFTVF9DSEFSIC0gMSk7CisgICAgY2hhciB0aGlyZFRvTGFzdCA9IChjaGFyKShMQVNUX0NIQVIgLSAyKTsKKyAgICAKKyAgICAvLyBNb2RpZnkgdGhlIHJvdyB0byBiZSBtaXNzaW5nIGFuIGV4cGVjdGVkIGNvbHVtbktleSAoZCkKKyAgICBjb2x2YWx1ZXMucmVtb3ZlKG5ldyBieXRlIFtdIHsoYnl0ZSlzZWNvbmRUb0xhc3R9KTsKKworICAgIC8vIFRyeSBhIHJvdyB0aGF0IGlzIG1pc3NpbmcgYW4gZXhwZWN0ZWQgY29sdW1uS2V5LgorICAgIC8vIFRlc3Rpbmcgcm93IHdpdGggY29sdW1uS2V5czogYS1jCisgICAgYXNzZXJ0VHJ1ZSgiRmFpbGVkIHdpdGggbGFzdCBjb2x1bW5LZXkgIiArIHRoaXJkVG9MYXN0LCBmaWx0ZXIuCisgICAgICBmaWx0ZXJSb3coY29sdmFsdWVzKSk7CisKKyAgICAvLyBUcnkgYSByb3cgdGhhdCBoYXMgYWxsIGV4cGVjdGVkIGNvbHVtbktleXMsIGFuZCBOTyBudWxsLWV4cGVjdGVkCisgICAgLy8gY29sdW1uS2V5cy4KKyAgICAvLyBUZXN0aW5nIHJvdyB3aXRoIGNvbHVtbktleXM6IGEtZAorICAgIGNvbHZhbHVlcy5wdXQobmV3IGJ5dGUgW10geyhieXRlKXNlY29uZFRvTGFzdH0sCisgICAgICAgIG5ldyBDZWxsKEdPT0RfQllURVMsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkpOworICAgIGFzc2VydEZhbHNlKCJGYWlsZWQgd2l0aCBsYXN0IGNvbHVtbktleSAiICsgc2Vjb25kVG9MYXN0LCBmaWx0ZXIuCisgICAgICBmaWx0ZXJSb3coY29sdmFsdWVzKSk7CisKKyAgICAvLyBUcnkgYSByb3cgdGhhdCBoYXMgYWxsIGV4cGVjdGVkIGNvbHVtbktleXMgQU5EIGEgbnVsbC1leHBlY3RlZCBjb2x1bW5LZXkuCisgICAgLy8gVGVzdGluZyByb3cgd2l0aCBjb2x1bW5LZXlzOiBhLWUKKyAgICBjb2x2YWx1ZXMucHV0KG5ldyBieXRlIFtdIHtMQVNUX0NIQVJ9LAorICAgICAgICBuZXcgQ2VsbChHT09EX0JZVEVTLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApKTsKKyAgICBhc3NlcnRUcnVlKCJGYWlsZWQgd2l0aCBsYXN0IGNvbHVtbktleSAiICsgTEFTVF9DSEFSLCBmaWx0ZXIuCisgICAgICBmaWx0ZXJSb3coY29sdmFsdWVzKSk7CisgICAgCisgICAgLy8gVHJ5IGEgcm93IHRoYXQgaGFzIGFsbCBleHBlY3RlZCBjb2x1bW5LZXlzIGFuZCBhIG51bGwtZXhwZWN0ZWQgY29sdW1uS2V5IAorICAgIC8vIHRoYXQgbWFwcyB0byBhIG51bGwgdmFsdWUuCisgICAgLy8gVGVzdGluZyByb3cgd2l0aCBjb2x1bW5LZXlzOiBhLWUsIGUgbWFwcyB0byBudWxsCisvLyAgICBjb2x2YWx1ZXMucHV0KG5ldyBieXRlIFtdIHtMQVNUX0NIQVJ9LCAKKy8vICAgICAgbmV3IENlbGwoSExvZ0VkaXQuREVMRVRFRF9CWVRFUywgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QKSk7CisvLyAgICBhc3NlcnRGYWxzZSgiRmFpbGVkIHdpdGggbGFzdCBjb2x1bW5LZXkgIiArIExBU1RfQ0hBUiArICIgbWFwcGluZyB0byBudWxsLiIsIAorLy8gICAgICBmaWx0ZXIuZmlsdGVyUm93KGNvbHZhbHVlcykpOworICB9CisKKyAgcHJpdmF0ZSBieXRlIFtdIGNyZWF0ZVJvdyhmaW5hbCBjaGFyIGMpIHsKKyAgICByZXR1cm4gQnl0ZXMudG9CeXRlcyhIT1NUX1BSRUZJWCArIENoYXJhY3Rlci50b1N0cmluZyhjKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSb3dGaWx0ZXJBZnRlcldyaXRlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0Um93RmlsdGVyQWZ0ZXJXcml0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0Um93RmlsdGVyQWZ0ZXJXcml0ZS5qYXZhCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0Um93RmlsdGVyT25NdWx0aXBsZUZhbWlsaWVzLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvRGlzYWJsZWRUZXN0Um93RmlsdGVyT25NdWx0aXBsZUZhbWlsaWVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE2ZTNiYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSb3dGaWx0ZXJPbk11bHRpcGxlRmFtaWxpZXMuamF2YQpAQCAtMCwwICsxLDEyOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGVzdCBmb3IgcmVnZXhwIGZpbHRlcnMgKEhCQVNFLTUyNykKKyAqLworcHVibGljIGNsYXNzIERpc2FibGVkVGVzdFJvd0ZpbHRlck9uTXVsdGlwbGVGYW1pbGllcyBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKERpc2FibGVkVGVzdFJvd0ZpbHRlck9uTXVsdGlwbGVGYW1pbGllcy5jbGFzcy5nZXROYW1lKCkpOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFCTEVfTkFNRSA9ICJUZXN0VGFibGUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTjEgPSAiQTpjb2wxIjsKKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gVEVYVF9DT0xVTU4xID0gQnl0ZXMudG9CeXRlcyhDT0xVTU4xKTsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBDT0xVTU4yID0gIkI6Y29sMiI7CisgIHN0YXRpYyBmaW5hbCBieXRlIFtdIFRFWFRfQ09MVU1OMiA9IEJ5dGVzLnRvQnl0ZXMoQ09MVU1OMik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMgPSB7VEVYVF9DT0xVTU4xLCBURVhUX0NPTFVNTjJ9OworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBOVU1fUk9XUyA9IDEwOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gVkFMVUUgPSAiSEVMTE8iLmdldEJ5dGVzKCk7CisKKyAgLyoqIEB0aHJvd3MgSU9FeGNlcHRpb24gKi8KKyAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlRmFtaWxpZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKFRBQkxFX05BTUUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcigiQToiKSk7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKCJCOiIpKTsKKworICAgIC8vIENyZWF0ZSBhIHRhYmxlLgorICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbih0aGlzLmNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworCisgICAgLy8gaW5zZXJ0IHNvbWUgZGF0YSBpbnRvIHRoZSB0ZXN0IHRhYmxlCisgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBUQUJMRV9OQU1FKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTlVNX1JPV1M7IGkrKykgeworICAgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZSgicm93XyIgKyBTdHJpbmcuZm9ybWF0KCIlMSQwNWQiLCBpKSk7CisgICAgICBiLnB1dChURVhUX0NPTFVNTjEsIFZBTFVFKTsKKyAgICAgIGIucHV0KFRFWFRfQ09MVU1OMiwgU3RyaW5nLmZvcm1hdCgiJTEkMDVkIiwgaSkuZ2V0Qnl0ZXMoKSk7CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfQorCisgICAgTE9HLmluZm8oIlByaW50IHRhYmxlIGNvbnRlbnRzIHVzaW5nIHNjYW5uZXIgYmVmb3JlIG1hcC9yZWR1Y2UgZm9yICIgKyBUQUJMRV9OQU1FKTsKKyAgICBzY2FuVGFibGUoVEFCTEVfTkFNRSwgdHJ1ZSk7CisgICAgTE9HLmluZm8oIlByaW50IHRhYmxlIGNvbnRlbnRzIHVzaW5nIHNjYW5uZXIrZmlsdGVyIGJlZm9yZSBtYXAvcmVkdWNlIGZvciAiICsgVEFCTEVfTkFNRSk7CisgICAgc2NhblRhYmxlV2l0aFJvd0ZpbHRlcihUQUJMRV9OQU1FLCB0cnVlKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBzY2FuVGFibGUoZmluYWwgU3RyaW5nIHRhYmxlTmFtZSwgZmluYWwgYm9vbGVhbiBwcmludFZhbHVlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRhYmxlTmFtZSk7CisgICAgU2Nhbm5lciBzY2FubmVyID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgaW50IG51bUZvdW5kID0gZG9TY2FuKHNjYW5uZXIsIHByaW50VmFsdWVzKTsKKyAgICBBc3NlcnQuYXNzZXJ0RXF1YWxzKE5VTV9ST1dTLCBudW1Gb3VuZCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgc2NhblRhYmxlV2l0aFJvd0ZpbHRlcihmaW5hbCBTdHJpbmcgdGFibGVOYW1lLCBmaW5hbCBib29sZWFuIHByaW50VmFsdWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgdGFibGVOYW1lKTsKKyAgICBNYXA8Ynl0ZSBbXSwgQ2VsbD4gY29sdW1uTWFwID0gbmV3IEhhc2hNYXA8Ynl0ZSBbXSwgQ2VsbD4oKTsKKyAgICBjb2x1bW5NYXAucHV0KFRFWFRfQ09MVU1OMSwKKyAgICAgICAgbmV3IENlbGwoVkFMVUUsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkpOworICAgIFJlZ0V4cFJvd0ZpbHRlciBmaWx0ZXIgPSBuZXcgUmVnRXhwUm93RmlsdGVyKG51bGwsIGNvbHVtbk1hcCk7CisgICAgU2Nhbm5lciBzY2FubmVyID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywgZmlsdGVyKTsKKyAgICBpbnQgbnVtRm91bmQgPSBkb1NjYW4oc2Nhbm5lciwgcHJpbnRWYWx1ZXMpOworICAgIEFzc2VydC5hc3NlcnRFcXVhbHMoTlVNX1JPV1MsIG51bUZvdW5kKTsKKyAgfQorCisgIHByaXZhdGUgaW50IGRvU2NhbihmaW5hbCBTY2FubmVyIHNjYW5uZXIsIGZpbmFsIGJvb2xlYW4gcHJpbnRWYWx1ZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgeworICAgICAgaW50IGNvdW50ID0gMDsKKworICAgICAgdHJ5IHsKKyAgICAgICAgZm9yIChSb3dSZXN1bHQgcmVzdWx0IDogc2Nhbm5lcikgeworICAgICAgICAgIGlmIChwcmludFZhbHVlcykgeworICAgICAgICAgICAgTE9HLmluZm8oInJvdzogIiArIEJ5dGVzLnRvU3RyaW5nKHJlc3VsdC5nZXRSb3coKSkpOworCisgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPiBlIDogcmVzdWx0LmVudHJ5U2V0KCkpIHsKKyAgICAgICAgICAgICAgTE9HLmluZm8oIiBjb2x1bW46ICIgKyBlLmdldEtleSgpICsgIiB2YWx1ZTogIgorICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKGUuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgQXNzZXJ0LmFzc2VydEVxdWFscygyLCByZXN1bHQuc2l6ZSgpKTsKKyAgICAgICAgICBjb3VudCsrOworICAgICAgICB9CisKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBjb3VudDsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSb3dGaWx0ZXJTZXQuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9EaXNhYmxlZFRlc3RSb3dGaWx0ZXJTZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWY2N2M1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL0Rpc2FibGVkVGVzdFJvd0ZpbHRlclNldC5qYXZhCkBAIC0wLDAgKzEsMTg4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIGZpbHRlciBzZXRzCisgKi8KK3B1YmxpYyBjbGFzcyBEaXNhYmxlZFRlc3RSb3dGaWx0ZXJTZXQgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlck1QQUxMOworICBSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyTVBPTkU7CisgIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1BBR0VTID0gNTsKKyAgc3RhdGljIGZpbmFsIGNoYXIgRklSU1RfQ0hBUiA9ICdhJzsKKyAgc3RhdGljIGZpbmFsIGNoYXIgTEFTVF9DSEFSID0gJ2UnOworICBUcmVlTWFwPGJ5dGUgW10sIENlbGw+IGNvbHZhbHVlczsKKyAgc3RhdGljIGJ5dGVbXSBHT09EX0JZVEVTID0gbnVsbDsKKyAgc3RhdGljIGJ5dGVbXSBCQURfQllURVMgPSBudWxsOworCisgIHN0YXRpYyB7CisgICAgdHJ5IHsKKyAgICAgIEdPT0RfQllURVMgPSAiYWJjIi5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgICAgQkFEX0JZVEVTID0gImRlZiIuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICB9IGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgIGZhaWwoKTsKKyAgICB9CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgICAgCisgICAgY29sdmFsdWVzID0gbmV3IFRyZWVNYXA8Ynl0ZSBbXSwgQ2VsbD4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgZm9yIChjaGFyIGMgPSBGSVJTVF9DSEFSOyBjIDwgTEFTVF9DSEFSOyBjKyspIHsKKyAgICAgIGNvbHZhbHVlcy5wdXQobmV3IGJ5dGUgW10geyhieXRlKWN9LAorICAgICAgICAgIG5ldyBDZWxsKEdPT0RfQllURVMsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCkpOworICAgIH0KKyAgICAKKyAgICBTZXQ8Um93RmlsdGVySW50ZXJmYWNlPiBmaWx0ZXJzID0gbmV3IEhhc2hTZXQ8Um93RmlsdGVySW50ZXJmYWNlPigpOworICAgIGZpbHRlcnMuYWRkKG5ldyBQYWdlUm93RmlsdGVyKE1BWF9QQUdFUykpOworICAgIGZpbHRlcnMuYWRkKG5ldyBSZWdFeHBSb3dGaWx0ZXIoIi4qcmVnZXguKiIsIGNvbHZhbHVlcykpOworICAgIGZpbHRlcnMuYWRkKG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyKG5ldyBTdG9wUm93RmlsdGVyKEJ5dGVzLnRvQnl0ZXMoInl5eSIpKSkpOworICAgIGZpbHRlcnMuYWRkKG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyKG5ldyBSZWdFeHBSb3dGaWx0ZXIoIi4qbWF0Y2guKiIpKSk7CisgICAgZmlsdGVyTVBBTEwgPSBuZXcgUm93RmlsdGVyU2V0KFJvd0ZpbHRlclNldC5PcGVyYXRvci5NVVNUX1BBU1NfQUxMLCAKKyAgICAgIGZpbHRlcnMpOworICAgIGZpbHRlck1QT05FID0gbmV3IFJvd0ZpbHRlclNldChSb3dGaWx0ZXJTZXQuT3BlcmF0b3IuTVVTVF9QQVNTX09ORSwgCisgICAgICBmaWx0ZXJzKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3QgIm11c3QgcGFzcyBvbmUiCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0TVBPTkUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNUE9ORVRlc3RzKGZpbHRlck1QT05FKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0ICJtdXN0IHBhc3MgYWxsIgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE1QQUxMKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTVBBTExUZXN0cyhmaWx0ZXJNUEFMTCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IHNlcmlhbGl6YXRpb24KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRGVjb21wb3NlIGZpbHRlck1QQUxMIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIGZpbHRlck1QQUxMLndyaXRlKG91dCk7CisgICAgb3V0LmNsb3NlKCk7CisgICAgYnl0ZVtdIGJ1ZmZlciA9IHN0cmVhbS50b0J5dGVBcnJheSgpOworICAgIAorICAgIC8vIFJlY29tcG9zZSBmaWx0ZXJNUEFMTC4KKyAgICBEYXRhSW5wdXRTdHJlYW0gaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWZmZXIpKTsKKyAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgbmV3RmlsdGVyID0gbmV3IFJvd0ZpbHRlclNldCgpOworICAgIG5ld0ZpbHRlci5yZWFkRmllbGRzKGluKTsKKyAgICAKKyAgICAvLyBFbnN1cmUgdGhlIHNlcmlhbGl6YXRpb24gcHJlc2VydmVkIHRoZSBmaWx0ZXIgYnkgcnVubmluZyBhIGZ1bGwgdGVzdC4KKyAgICBNUEFMTFRlc3RzKG5ld0ZpbHRlcik7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBNUE9ORVRlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEEgcm93IHRoYXQgc2hvdWxkbid0IGNhdXNlIGFueSBmaWx0ZXJzIHRvIHJldHVybiB0cnVlLgorICAgIFJGU0Fzc2VydGlvbihmaWx0ZXIsICJyZWdleF9tYXRjaCIsIGZhbHNlKTsKKyAgICAKKyAgICAvLyBBIHJvdyB0aGF0IHNob3VsZCBjYXVzZSB0aGUgV2hpbGVNYXRjaFJvd0ZpbHRlciB0byBmaWx0ZXIgYWxsIHJlbWFpbmluZy4KKyAgICBSRlNBc3NlcnRpb24oZmlsdGVyLCAicmVnZXhfb25seSIsIGZhbHNlKTsKKyAgICAKKyAgICAvLyBNYWtlIHN1cmUgdGhlIG92ZXJhbGwgZmlsdGVyQWxsUmVtYWluaW5nIGlzIHVuY2hhbmdlZCAoY29ycmVjdCBmb3IgCisgICAgLy8gTVVTVF9QQVNTX09ORSkuCisgICAgYXNzZXJ0RmFsc2UoZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICAKKyAgICAvLyBBIHJvdyB0aGF0IHNob3VsZCBjYXVzZSB0aGUgUmVnRXhwUm93RmlsdGVyIHRvIGZhaWwgYW5kIHRoZSAKKyAgICAvLyBTdG9wUm93RmlsdGVyIHRvIGZpbHRlciBhbGwgcmVtYWluaW5nLgorICAgIFJGU0Fzc2VydGlvbihmaWx0ZXIsICJ5eXlfbWF0Y2giLCBmYWxzZSk7CisgICAgCisgICAgLy8gQWNjZXB0IHNldmVyYWwgbW9yZSByb3dzIHN1Y2ggdGhhdCBQYWdlUm93RmlsdGVyIHdpbGwgZXhjZWVkIGl0cyBsaW1pdC4KKyAgICBmb3IgKGludCBpPTA7IGk8PU1BWF9QQUdFUy0zOyBpKyspCisgICAgICBmaWx0ZXIucm93UHJvY2Vzc2VkKGZhbHNlLCBCeXRlcy50b0J5dGVzKCJ1bmltcG9ydGFudF9rZXkiKSk7CisgICAgCisgICAgLy8gQSByb3cgdGhhdCBzaG91bGQgY2F1c2UgdGhlIFJlZ0V4cFJvd0ZpbHRlciB0byBmaWx0ZXIgdGhpcyByb3csIG1ha2luZyAKKyAgICAvLyBhbGwgdGhlIGZpbHRlcnMgcmV0dXJuIHRydWUgYW5kIHRodXMgdGhlIFJvd0ZpbHRlclNldCBhcyB3ZWxsLgorICAgIFJGU0Fzc2VydGlvbihmaWx0ZXIsICJiYWRfY29sdW1uIiwgdHJ1ZSk7CisgICAgCisgICAgLy8gTWFrZSBzdXJlIHRoZSBvdmVyYWxsIGZpbHRlckFsbFJlbWFpbmluZyBpcyB1bmNoYW5nZWQgKGNvcnJlY3QgZm9yIAorICAgIC8vIE1VU1RfUEFTU19PTkUpLgorICAgIGFzc2VydEZhbHNlKGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBNUEFMTFRlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEEgcm93IHRoYXQgc2hvdWxkbid0IGNhdXNlIGFueSBmaWx0ZXJzIHRvIHJldHVybiB0cnVlLgorICAgIFJGU0Fzc2VydGlvbihmaWx0ZXIsICJyZWdleF9tYXRjaCIsIGZhbHNlKTsKKyAgICAKKyAgICAvLyBBIHJvdyB0aGF0IHNob3VsZCBjYXVzZSBXaGlsZU1hdGNoUm93RmlsdGVyIHRvIGZpbHRlciBhbGwgcmVtYWluaW5nLgorICAgIFJGU0Fzc2VydGlvbihmaWx0ZXIsICJyZWdleF9vbmx5IiwgdHJ1ZSk7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhlIG92ZXJhbGwgZmlsdGVyQWxsUmVtYWluaW5nIGlzIGNoYW5nZWQgKGNvcnJlY3QgZm9yIAorICAgIC8vIE1VU1RfUEFTU19BTEwpLgorICAgIFJGU0Fzc2VydFJlc2V0KGZpbHRlcik7CisgICAgCisgICAgLy8gQSByb3cgdGhhdCBzaG91bGQgY2F1c2UgdGhlIFJlZ0V4cFJvd0ZpbHRlciB0byBmYWlsIGFuZCB0aGUgCisgICAgLy8gU3RvcFJvd0ZpbHRlciB0byBmaWx0ZXIgYWxsIHJlbWFpbmluZy4KKyAgICBSRlNBc3NlcnRpb24oZmlsdGVyLCAieXl5X21hdGNoIiwgdHJ1ZSk7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhlIG92ZXJhbGwgZmlsdGVyQWxsUmVtYWluaW5nIGlzIGNoYW5nZWQgKGNvcnJlY3QgZm9yIAorICAgIC8vIE1VU1RfUEFTU19BTEwpLgorICAgIFJGU0Fzc2VydFJlc2V0KGZpbHRlcik7CisgICAgCisgICAgLy8gQSByb3cgdGhhdCBzaG91bGQgY2F1c2UgdGhlIFJlZ0V4cFJvd0ZpbHRlciB0byBmYWlsLgorICAgIGJvb2xlYW4gZmlsdGVyZWQgPSBmaWx0ZXIuZmlsdGVyQ29sdW1uKEJ5dGVzLnRvQnl0ZXMoInJlZ2V4X21hdGNoIiksIAorICAgICAgbmV3IGJ5dGUgW10geyBGSVJTVF9DSEFSIH0sIEJBRF9CWVRFUyk7CisgICAgYXNzZXJ0VHJ1ZSgiRmlsdGVyaW5nIG9uICdyZWdleF9tYXRjaCcgYW5kIGJhZCBjb2x1bW4gZGF0YS4iLCBmaWx0ZXJlZCk7CisgICAgZmlsdGVyTVBBTEwucm93UHJvY2Vzc2VkKGZpbHRlcmVkLCBCeXRlcy50b0J5dGVzKCJyZWdleF9tYXRjaCIpKTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIFJGU0Fzc2VydGlvbihSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyLCBTdHJpbmcgdG9UZXN0LCAKKyAgICBib29sZWFuIGFzc2VydFRydWUpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGUgW10gdGVzdFRleHQgPSBCeXRlcy50b0J5dGVzKHRvVGVzdCk7CisgICAgYm9vbGVhbiBmaWx0ZXJlZCA9IGZpbHRlci5maWx0ZXJSb3dLZXkodGVzdFRleHQpOworICAgIGFzc2VydFRydWUoIkZpbHRlcmluZyBvbiAnIiArIHRvVGVzdCArICInIiwgCisgICAgICBhc3NlcnRUcnVlPyBmaWx0ZXJlZCA6ICFmaWx0ZXJlZCk7CisgICAgZmlsdGVyLnJvd1Byb2Nlc3NlZChmaWx0ZXJlZCwgdGVzdFRleHQpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgUkZTQXNzZXJ0UmVzZXQoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICBhc3NlcnRUcnVlKGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgICAgLy8gUmVzZXQgZm9yIGNvbnRpbnVlZCB0ZXN0aW5nCisgICAgZmlsdGVyLnJlc2V0KCk7CisgICAgYXNzZXJ0RmFsc2UoZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Rlc3RDb2x1bW5WYWx1ZUZpbHRlci5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Rlc3RDb2x1bW5WYWx1ZUZpbHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjE1ZWU0NDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvVGVzdENvbHVtblZhbHVlRmlsdGVyLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgdGhlIHN0b3Agcm93IGZpbHRlcgorICovCitwdWJsaWMgY2xhc3MgVGVzdENvbHVtblZhbHVlRmlsdGVyIGV4dGVuZHMgVGVzdENhc2UgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBST1cgPSBCeXRlcy50b0J5dGVzKCJ0ZXN0Iik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBDT0xVTU4gPSBCeXRlcy50b0J5dGVzKCJ0ZXN0OmZvbyIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gVkFMXzEgPSBCeXRlcy50b0J5dGVzKCJhIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBWQUxfMiA9IEJ5dGVzLnRvQnl0ZXMoImFiIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBWQUxfMyA9IEJ5dGVzLnRvQnl0ZXMoImFiYyIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gVkFMXzQgPSBCeXRlcy50b0J5dGVzKCJhYmNkIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBGVUxMU1RSSU5HXzEgPSAKKyAgICBCeXRlcy50b0J5dGVzKCJUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgdGhlIGxhenkgZG9nLiIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRlVMTFNUUklOR18yID0gCisgICAgQnl0ZXMudG9CeXRlcygiVGhlIHNsb3cgZ3JleSBmb3ggdHJpcHMgb3ZlciB0aGUgbGF6eSBkb2cuIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBRVUlDS19TVUJTVFIgPSAicXVpY2siOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUVVJQ0tfUkVHRVggPSAiLitxdWljay4rIjsKKworICBwcml2YXRlIFJvd0ZpbHRlckludGVyZmFjZSBiYXNpY0ZpbHRlck5ldygpIHsKKyAgICByZXR1cm4gbmV3IENvbHVtblZhbHVlRmlsdGVyKENPTFVNTiwKKyAgICAgICAgQ29sdW1uVmFsdWVGaWx0ZXIuQ29tcGFyZU9wLkdSRUFURVJfT1JfRVFVQUwsIFZBTF8yKTsKKyAgfQorCisgIHByaXZhdGUgUm93RmlsdGVySW50ZXJmYWNlIHN1YnN0ckZpbHRlck5ldygpIHsKKyAgICByZXR1cm4gbmV3IENvbHVtblZhbHVlRmlsdGVyKENPTFVNTiwgQ29sdW1uVmFsdWVGaWx0ZXIuQ29tcGFyZU9wLkVRVUFMLAorICAgICAgbmV3IFN1YnN0cmluZ0NvbXBhcmF0b3IoUVVJQ0tfU1VCU1RSKSk7CisgIH0KKworICBwcml2YXRlIFJvd0ZpbHRlckludGVyZmFjZSByZWdleEZpbHRlck5ldygpIHsKKyAgICByZXR1cm4gbmV3IENvbHVtblZhbHVlRmlsdGVyKENPTFVNTiwgQ29sdW1uVmFsdWVGaWx0ZXIuQ29tcGFyZU9wLkVRVUFMLAorICAgICAgbmV3IFJlZ2V4U3RyaW5nQ29tcGFyYXRvcihRVUlDS19SRUdFWCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGJhc2ljRmlsdGVyVGVzdHMoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRydWUoImJhc2ljRmlsdGVyMSIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgQ09MVU1OLCAwLCBDT0xVTU4ubGVuZ3RoLCBWQUxfMSwgMCwgVkFMXzEubGVuZ3RoKSk7CisgICAgYXNzZXJ0RmFsc2UoImJhc2ljRmlsdGVyMiIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgQ09MVU1OLCAwLCBDT0xVTU4ubGVuZ3RoLCBWQUxfMiwgMCwgVkFMXzIubGVuZ3RoKSk7CisgICAgYXNzZXJ0RmFsc2UoImJhc2ljRmlsdGVyMyIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgQ09MVU1OLCAwLCBDT0xVTU4ubGVuZ3RoLCBWQUxfMywgMCwgVkFMXzMubGVuZ3RoKSk7CisgICAgYXNzZXJ0RmFsc2UoImJhc2ljRmlsdGVyNCIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgQ09MVU1OLCAwLCBDT0xVTU4ubGVuZ3RoLCBWQUxfNCwgMCwgVkFMXzQubGVuZ3RoKSk7CisgICAgYXNzZXJ0RmFsc2UoImJhc2ljRmlsdGVyQWxsUmVtYWluaW5nIiwgZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICBhc3NlcnRGYWxzZSgiYmFzaWNGaWx0ZXJOb3ROdWxsIiwgZmlsdGVyLmZpbHRlclJvdygoTGlzdDxLZXlWYWx1ZT4pbnVsbCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHN1YnN0ckZpbHRlclRlc3RzKFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpIAorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0RmFsc2UoInN1YnN0clRydWUiLCBmaWx0ZXIuZmlsdGVyQ29sdW1uKFJPVywgMCwgUk9XLmxlbmd0aCwKKyAgICAgICAgQ09MVU1OLCAwLCBDT0xVTU4ubGVuZ3RoLCBGVUxMU1RSSU5HXzEsIDAsIEZVTExTVFJJTkdfMS5sZW5ndGgpKTsKKyAgICBhc3NlcnRUcnVlKCJzdWJzdHJGYWxzZSIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgICBDT0xVTU4sIDAsIENPTFVNTi5sZW5ndGgsIEZVTExTVFJJTkdfMiwgMCwgRlVMTFNUUklOR18yLmxlbmd0aCkpOworICAgIGFzc2VydEZhbHNlKCJzdWJzdHJGaWx0ZXJBbGxSZW1haW5pbmciLCBmaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkpOworICAgIGFzc2VydEZhbHNlKCJzdWJzdHJGaWx0ZXJOb3ROdWxsIiwgZmlsdGVyLmZpbHRlclJvdygoTGlzdDxLZXlWYWx1ZT4pbnVsbCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlZ2V4RmlsdGVyVGVzdHMoUm93RmlsdGVySW50ZXJmYWNlIGZpbHRlcikgCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRGYWxzZSgicmVnZXhUcnVlIiwgZmlsdGVyLmZpbHRlckNvbHVtbihST1csIDAsIFJPVy5sZW5ndGgsCisgICAgICAgIENPTFVNTiwgMCwgQ09MVU1OLmxlbmd0aCwgRlVMTFNUUklOR18xLCAwLCBGVUxMU1RSSU5HXzEubGVuZ3RoKSk7CisgICAgYXNzZXJ0VHJ1ZSgicmVnZXhGYWxzZSIsIGZpbHRlci5maWx0ZXJDb2x1bW4oUk9XLCAwLCBST1cubGVuZ3RoLAorICAgICAgICBDT0xVTU4sIDAsIENPTFVNTi5sZW5ndGgsIEZVTExTVFJJTkdfMiwgMCwgRlVMTFNUUklOR18yLmxlbmd0aCkpOworICAgIGFzc2VydEZhbHNlKCJyZWdleEZpbHRlckFsbFJlbWFpbmluZyIsIGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgICAgYXNzZXJ0RmFsc2UoInJlZ2V4RmlsdGVyTm90TnVsbCIsIGZpbHRlci5maWx0ZXJSb3coKExpc3Q8S2V5VmFsdWU+KW51bGwpKTsKKyAgfQorCisgIHByaXZhdGUgUm93RmlsdGVySW50ZXJmYWNlIHNlcmlhbGl6YXRpb25UZXN0KFJvd0ZpbHRlckludGVyZmFjZSBmaWx0ZXIpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBEZWNvbXBvc2UgZmlsdGVyIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIGZpbHRlci53cml0ZShvdXQpOworICAgIG91dC5jbG9zZSgpOworICAgIGJ5dGVbXSBidWZmZXIgPSBzdHJlYW0udG9CeXRlQXJyYXkoKTsKKyAgCisgICAgLy8gUmVjb21wb3NlIGZpbHRlci4KKyAgICBEYXRhSW5wdXRTdHJlYW0gaW4gPQorICAgICAgbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgUm93RmlsdGVySW50ZXJmYWNlIG5ld0ZpbHRlciA9IG5ldyBDb2x1bW5WYWx1ZUZpbHRlcigpOworICAgIG5ld0ZpbHRlci5yZWFkRmllbGRzKGluKTsKKyAgCisgICAgcmV0dXJuIG5ld0ZpbHRlcjsKKyAgfQorCisgIFJvd0ZpbHRlckludGVyZmFjZSBiYXNpY0ZpbHRlcjsKKyAgUm93RmlsdGVySW50ZXJmYWNlIHN1YnN0ckZpbHRlcjsKKyAgUm93RmlsdGVySW50ZXJmYWNlIHJlZ2V4RmlsdGVyOworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgICAgYmFzaWNGaWx0ZXIgPSBiYXNpY0ZpbHRlck5ldygpOworICAgIHN1YnN0ckZpbHRlciA9IHN1YnN0ckZpbHRlck5ldygpOworICAgIHJlZ2V4RmlsdGVyID0gcmVnZXhGaWx0ZXJOZXcoKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBpZGVudGlmaWNhdGlvbiBvZiB0aGUgc3RvcCByb3cKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTdG9wKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYmFzaWNGaWx0ZXJUZXN0cyhiYXNpY0ZpbHRlcik7CisgICAgc3Vic3RyRmlsdGVyVGVzdHMoc3Vic3RyRmlsdGVyKTsKKyAgICByZWdleEZpbHRlclRlc3RzKHJlZ2V4RmlsdGVyKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBzZXJpYWxpemF0aW9uCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFJvd0ZpbHRlckludGVyZmFjZSBuZXdGaWx0ZXIgPSBzZXJpYWxpemF0aW9uVGVzdChiYXNpY0ZpbHRlcik7CisgICAgYmFzaWNGaWx0ZXJUZXN0cyhuZXdGaWx0ZXIpOworICAgIG5ld0ZpbHRlciA9IHNlcmlhbGl6YXRpb25UZXN0KHN1YnN0ckZpbHRlcik7CisgICAgc3Vic3RyRmlsdGVyVGVzdHMobmV3RmlsdGVyKTsKKyAgICBuZXdGaWx0ZXIgPSBzZXJpYWxpemF0aW9uVGVzdChyZWdleEZpbHRlcik7CisgICAgcmVnZXhGaWx0ZXJUZXN0cyhuZXdGaWx0ZXIpOworICB9CisKK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9UZXN0U3RvcFJvd0ZpbHRlci5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Rlc3RTdG9wUm93RmlsdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTdjYzMxNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2ZpbHRlci9UZXN0U3RvcFJvd0ZpbHRlci5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdHMgdGhlIHN0b3Agcm93IGZpbHRlcgorICovCitwdWJsaWMgY2xhc3MgVGVzdFN0b3BSb3dGaWx0ZXIgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBTVE9QX1JPVyA9IEJ5dGVzLnRvQnl0ZXMoInN0b3Bfcm93Iik7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBHT09EX1JPVyA9IEJ5dGVzLnRvQnl0ZXMoImdvb2Rfcm93Iik7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBQQVNUX1NUT1BfUk9XID0gQnl0ZXMudG9CeXRlcygienp6enp6Iik7CisgIAorICBSb3dGaWx0ZXJJbnRlcmZhY2UgbWFpbkZpbHRlcjsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIG1haW5GaWx0ZXIgPSBuZXcgU3RvcFJvd0ZpbHRlcihTVE9QX1JPVyk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyBpZGVudGlmaWNhdGlvbiBvZiB0aGUgc3RvcCByb3cKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTdG9wUm93SWRlbnRpZmljYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9wUm93VGVzdHMobWFpbkZpbHRlcik7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyBzZXJpYWxpemF0aW9uCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2VyaWFsaXphdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIERlY29tcG9zZSBtYWluRmlsdGVyIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIG1haW5GaWx0ZXIud3JpdGUob3V0KTsKKyAgICBvdXQuY2xvc2UoKTsKKyAgICBieXRlW10gYnVmZmVyID0gc3RyZWFtLnRvQnl0ZUFycmF5KCk7CisgICAgCisgICAgLy8gUmVjb21wb3NlIG1haW5GaWx0ZXIuCisgICAgRGF0YUlucHV0U3RyZWFtIGluID0gbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmZmVyKSk7CisgICAgUm93RmlsdGVySW50ZXJmYWNlIG5ld0ZpbHRlciA9IG5ldyBTdG9wUm93RmlsdGVyKCk7CisgICAgbmV3RmlsdGVyLnJlYWRGaWVsZHMoaW4pOworICAgIAorICAgIC8vIEVuc3VyZSB0aGUgc2VyaWFsaXphdGlvbiBwcmVzZXJ2ZWQgdGhlIGZpbHRlciBieSBydW5uaW5nIGEgZnVsbCB0ZXN0LgorICAgIHN0b3BSb3dUZXN0cyhuZXdGaWx0ZXIpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHN0b3BSb3dUZXN0cyhSb3dGaWx0ZXJJbnRlcmZhY2UgZmlsdGVyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRGYWxzZSgiRmlsdGVyaW5nIG9uICIgKyBCeXRlcy50b1N0cmluZyhHT09EX1JPVyksCisgICAgICBmaWx0ZXIuZmlsdGVyUm93S2V5KEdPT0RfUk9XLCAwLCBHT09EX1JPVy5sZW5ndGgpKTsKKyAgICBhc3NlcnRUcnVlKCJGaWx0ZXJpbmcgb24gIiArIEJ5dGVzLnRvU3RyaW5nKFNUT1BfUk9XKSwKKyAgICAgIGZpbHRlci5maWx0ZXJSb3dLZXkoU1RPUF9ST1csIDAsIFNUT1BfUk9XLmxlbmd0aCkpOworICAgIGFzc2VydFRydWUoIkZpbHRlcmluZyBvbiAiICsgQnl0ZXMudG9TdHJpbmcoUEFTVF9TVE9QX1JPVyksCisgICAgICBmaWx0ZXIuZmlsdGVyUm93S2V5KFBBU1RfU1RPUF9ST1csIDAsIFBBU1RfU1RPUF9ST1cubGVuZ3RoKSk7CisgICAgYXNzZXJ0RmFsc2UoIkZpbHRlcmluZyBvbiAiICsgQnl0ZXMudG9TdHJpbmcoR09PRF9ST1cpLAorICAgICAgZmlsdGVyLmZpbHRlckNvbHVtbihHT09EX1JPVywgMCwgR09PRF9ST1cubGVuZ3RoLCBudWxsLCAwLCAwLAorICAgICAgbnVsbCwgMCwgMCkpOworICAgIGFzc2VydFRydWUoIkZpbHRlcmluZyBvbiAiICsgQnl0ZXMudG9TdHJpbmcoU1RPUF9ST1cpLAorICAgICAgZmlsdGVyLmZpbHRlckNvbHVtbihTVE9QX1JPVywgMCwgU1RPUF9ST1cubGVuZ3RoLCBudWxsLCAwLCAwLCBudWxsLCAwLCAwKSk7CisgICAgYXNzZXJ0VHJ1ZSgiRmlsdGVyaW5nIG9uICIgKyBCeXRlcy50b1N0cmluZyhQQVNUX1NUT1BfUk9XKSwKKyAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4oUEFTVF9TVE9QX1JPVywgMCwgUEFTVF9TVE9QX1JPVy5sZW5ndGgsIG51bGwsIDAsIDAsCisgICAgICAgIG51bGwsIDAsIDApKTsKKyAgICBhc3NlcnRGYWxzZSgiRmlsdGVyQWxsUmVtYWluaW5nIiwgZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICBhc3NlcnRGYWxzZSgiRmlsdGVyTm90TnVsbCIsIGZpbHRlci5maWx0ZXJSb3coKExpc3Q8S2V5VmFsdWU+KW51bGwpKTsKKyAgICAKKyAgICBhc3NlcnRGYWxzZSgiRmlsdGVyIGEgbnVsbCIsIGZpbHRlci5maWx0ZXJSb3dLZXkobnVsbCwgMCwgMCkpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Rlc3RXaGlsZU1hdGNoUm93RmlsdGVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9maWx0ZXIvVGVzdFdoaWxlTWF0Y2hSb3dGaWx0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDZlNDc0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvZmlsdGVyL1Rlc3RXaGlsZU1hdGNoUm93RmlsdGVyLmphdmEKQEAgLTAsMCArMSwxNTcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKworLyoqCisgKiBUZXN0cyBmb3IgdGhlIHdoaWxlLW1hdGNoIGZpbHRlcgorICovCitwdWJsaWMgY2xhc3MgVGVzdFdoaWxlTWF0Y2hSb3dGaWx0ZXIgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgV2hpbGVNYXRjaFJvd0ZpbHRlciB3bVN0b3BSb3dGaWx0ZXI7CisgIFdoaWxlTWF0Y2hSb3dGaWx0ZXIgd21SZWdFeHBSb3dGaWx0ZXI7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB3bVN0b3BSb3dGaWx0ZXIgPSBuZXcgV2hpbGVNYXRjaFJvd0ZpbHRlcihuZXcgU3RvcFJvd0ZpbHRlcigKKyAgICAgICAgQnl0ZXMudG9CeXRlcygicyIpKSk7CisgICAgd21SZWdFeHBSb3dGaWx0ZXIgPSBuZXcgV2hpbGVNYXRjaFJvd0ZpbHRlcihuZXcgUmVnRXhwUm93RmlsdGVyKAorICAgICIuKnJlZ2V4LioiKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyB3aGlsZSBtYXRjaCBzdG9wIHJvdworICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFdoaWxlTWF0Y2hTdG9wUm93KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hpbGVNYXRjaFN0b3BSb3dUZXN0cyh3bVN0b3BSb3dGaWx0ZXIpOworICB9CisgIAorICAvKioKKyAgICogVGVzdHMgd2hpbGUgbWF0Y2ggcmVnZXgKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RXaGlsZU1hdGNoUmVnRXhwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hpbGVNYXRjaFJlZ0V4cFRlc3RzKHdtUmVnRXhwUm93RmlsdGVyKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3RzIHNlcmlhbGl6YXRpb24KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTZXJpYWxpemF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRGVjb21wb3NlIHdtUmVnRXhwUm93RmlsdGVyIHRvIGJ5dGVzLgorICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzdHJlYW0pOworICAgIHdtUmVnRXhwUm93RmlsdGVyLndyaXRlKG91dCk7CisgICAgb3V0LmNsb3NlKCk7CisgICAgYnl0ZVtdIGJ1ZmZlciA9IHN0cmVhbS50b0J5dGVBcnJheSgpOworICAgIAorICAgIC8vIFJlY29tcG9zZSB3bVJlZ0V4cFJvd0ZpbHRlci4KKyAgICBEYXRhSW5wdXRTdHJlYW0gaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWZmZXIpKTsKKyAgICBXaGlsZU1hdGNoUm93RmlsdGVyIG5ld0ZpbHRlciA9IG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyKCk7CisgICAgbmV3RmlsdGVyLnJlYWRGaWVsZHMoaW4pOworCisgICAgLy8gRW5zdXJlIHRoZSBzZXJpYWxpemF0aW9uIHByZXNlcnZlZCB0aGUgZmlsdGVyIGJ5IHJ1bm5pbmcgYSBmdWxsIHRlc3QuCisgICAgd2hpbGVNYXRjaFJlZ0V4cFRlc3RzKG5ld0ZpbHRlcik7CisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCB3aGlsZU1hdGNoU3RvcFJvd1Rlc3RzKFdoaWxlTWF0Y2hSb3dGaWx0ZXIgZmlsdGVyKSB0aHJvd3MgCisgICAgRXhjZXB0aW9uIHsKKyAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgaW5uZXJGaWx0ZXIgPSBmaWx0ZXIuZ2V0SW50ZXJuYWxGaWx0ZXIoKTsKKyAgICBTdHJpbmcgdG9UZXN0OworICAgIAorICAgIC8vIFRlc3QgY2FzZXMgdGhhdCBzaG91bGQgcGFzcyB0aGUgcm93CisgICAgdG9UZXN0ID0gImFwcGxlcyI7CisgICAgYXNzZXJ0RmFsc2UoImZpbHRlcjogJyIgKyB0b1Rlc3QgKyAiJyIsIGZpbHRlci5maWx0ZXJSb3dLZXkoQnl0ZXMudG9CeXRlcyh0b1Rlc3QpKSk7CisgICAgYnl0ZSBbXSB0b1Rlc3RCeXRlcyA9IEJ5dGVzLnRvQnl0ZXModG9UZXN0KTsKKyAgICBhc3NlcnRGYWxzZSgiaW5uZXJGaWx0ZXI6ICciICsgdG9UZXN0ICsgIiciLAorICAgICAgaW5uZXJGaWx0ZXIuZmlsdGVyUm93S2V5KHRvVGVzdEJ5dGVzLCAwLCB0b1Rlc3RCeXRlcy5sZW5ndGgpKTsKKworICAgIC8vIFRlc3QgY2FzZXMgdGhhdCBzaG91bGQgZmFpbCB0aGUgcm93CisgICAgdG9UZXN0ID0gInR1bmEiOworICAgIHRvVGVzdEJ5dGVzID0gQnl0ZXMudG9CeXRlcyh0b1Rlc3QpOworICAgIGFzc2VydFRydWUoImZpbHRlcjogJyIgKyB0b1Rlc3QgKyAiJyIsIGZpbHRlci5maWx0ZXJSb3dLZXkodG9UZXN0Qnl0ZXMpKTsKKyAgICBhc3NlcnRUcnVlKCJpbm5lckZpbHRlcjogJyIgKyB0b1Rlc3QgKyAiJyIsCisgICAgICBpbm5lckZpbHRlci5maWx0ZXJSb3dLZXkodG9UZXN0Qnl0ZXMsIDAsIHRvVGVzdEJ5dGVzLmxlbmd0aCkpOworICAgIAorICAgIC8vIFRoZSBkaWZmZXJlbmNlIGluIHN3aXRjaAorICAgIGFzc2VydFRydWUoImZpbHRlcjogZmlsdGVyQWxsUmVtYWluaW5nIiwgZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICBhc3NlcnRGYWxzZSgiaW5uZXJGaWx0ZXI6IGZpbHRlckFsbFJlbWFpbmluZyBwcmUtcmVzZXQiLCAKKyAgICAgIGlubmVyRmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICAKKyAgICAvLyBUZXN0IHJlc2V0dGluZworICAgIGZpbHRlci5yZXNldCgpOworICAgIGFzc2VydEZhbHNlKCJmaWx0ZXI6IGZpbHRlckFsbFJlbWFpbmluZyBwb3N0LXJlc2V0IiwgCisgICAgICAgIGZpbHRlci5maWx0ZXJBbGxSZW1haW5pbmcoKSk7CisgICAgCisgICAgLy8gVGVzdCBmaWx0ZXJOb3ROdWxsIGZvciBmdW5jdGlvbmFsaXR5IG9ubHkgKG5vIHN3aXRjaC1jYXNlcykKKyAgICBhc3NlcnRGYWxzZSgiZmlsdGVyOiBmaWx0ZXJOb3ROdWxsIiwgZmlsdGVyLmZpbHRlclJvdygoTGlzdDxLZXlWYWx1ZT4pbnVsbCkpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgd2hpbGVNYXRjaFJlZ0V4cFRlc3RzKFdoaWxlTWF0Y2hSb3dGaWx0ZXIgZmlsdGVyKSB0aHJvd3MgCisgICAgRXhjZXB0aW9uIHsKKyAgICBSb3dGaWx0ZXJJbnRlcmZhY2UgaW5uZXJGaWx0ZXIgPSBmaWx0ZXIuZ2V0SW50ZXJuYWxGaWx0ZXIoKTsKKyAgICBTdHJpbmcgdG9UZXN0OworICAgIAorICAgIC8vIFRlc3QgY2FzZXMgdGhhdCBzaG91bGQgcGFzcyB0aGUgcm93CisgICAgdG9UZXN0ID0gInJlZ2V4X21hdGNoIjsKKyAgICBieXRlIFtdIHRvVGVzdEJ5dGVzID0gQnl0ZXMudG9CeXRlcyh0b1Rlc3QpOworICAgIGFzc2VydEZhbHNlKCJmaWx0ZXI6ICciICsgdG9UZXN0ICsgIiciLCBmaWx0ZXIuZmlsdGVyUm93S2V5KEJ5dGVzLnRvQnl0ZXModG9UZXN0KSkpOworICAgIGFzc2VydEZhbHNlKCJpbm5lckZpbHRlcjogJyIgKyB0b1Rlc3QgKyAiJyIsCisgICAgICBpbm5lckZpbHRlci5maWx0ZXJSb3dLZXkodG9UZXN0Qnl0ZXMsIDAsIHRvVGVzdEJ5dGVzLmxlbmd0aCkpOworICAgIAorICAgIC8vIFRlc3QgY2FzZXMgdGhhdCBzaG91bGQgZmFpbCB0aGUgcm93CisgICAgdG9UZXN0ID0gIm5vdF9hX21hdGNoIjsKKyAgICB0b1Rlc3RCeXRlcyA9IEJ5dGVzLnRvQnl0ZXModG9UZXN0KTsKKyAgICBhc3NlcnRUcnVlKCJmaWx0ZXI6ICciICsgdG9UZXN0ICsgIiciLCBmaWx0ZXIuZmlsdGVyUm93S2V5KEJ5dGVzLnRvQnl0ZXModG9UZXN0KSkpOworICAgIGFzc2VydFRydWUoImlubmVyRmlsdGVyOiAnIiArIHRvVGVzdCArICInIiwKKyAgICAgIGlubmVyRmlsdGVyLmZpbHRlclJvd0tleSh0b1Rlc3RCeXRlcywgMCwgdG9UZXN0Qnl0ZXMubGVuZ3RoKSk7CisgICAgCisgICAgLy8gVGhlIGRpZmZlcmVuY2UgaW4gc3dpdGNoCisgICAgYXNzZXJ0VHJ1ZSgiZmlsdGVyOiBmaWx0ZXJBbGxSZW1haW5pbmciLCBmaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkpOworICAgIGFzc2VydEZhbHNlKCJpbm5lckZpbHRlcjogZmlsdGVyQWxsUmVtYWluaW5nIHByZS1yZXNldCIsIAorICAgICAgaW5uZXJGaWx0ZXIuZmlsdGVyQWxsUmVtYWluaW5nKCkpOworICAgIAorICAgIC8vIFRlc3QgcmVzZXR0aW5nCisgICAgZmlsdGVyLnJlc2V0KCk7CisgICAgYXNzZXJ0RmFsc2UoImZpbHRlcjogZmlsdGVyQWxsUmVtYWluaW5nIHBvc3QtcmVzZXQiLCAKKyAgICAgICAgZmlsdGVyLmZpbHRlckFsbFJlbWFpbmluZygpKTsKKyAgICAKKyAgICAvLyBUZXN0IGZpbHRlcihUZXh0LCBUZXh0LCBieXRlW10pIGZvciBmdW5jdGlvbmFsaXR5IG9ubHkgKG5vIHN3aXRjaC1jYXNlcykKKyAgICB0b1Rlc3QgPSAiYXNkZl9yZWdleF9oamtsIjsKKyAgICB0b1Rlc3RCeXRlcyA9IEJ5dGVzLnRvQnl0ZXModG9UZXN0KTsKKyAgICBhc3NlcnRGYWxzZSgiZmlsdGVyOiAnIiArIHRvVGVzdCArICInIiwKKyAgICAgIGZpbHRlci5maWx0ZXJDb2x1bW4odG9UZXN0Qnl0ZXMsIDAsIHRvVGVzdEJ5dGVzLmxlbmd0aCwgCisgICAgICBudWxsLCAwLCAwLCBudWxsLCAwLCAwKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL1Rlc3RIYmFzZU9iamVjdFdyaXRhYmxlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9UZXN0SGJhc2VPYmplY3RXcml0YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhNTQ3YTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9UZXN0SGJhc2VPYmplY3RXcml0YWJsZS5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pbzsKKworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlJvd0ZpbHRlckludGVyZmFjZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuU3RvcFJvd0ZpbHRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYXRvcjsKKworcHVibGljIGNsYXNzIFRlc3RIYmFzZU9iamVjdFdyaXRhYmxlIGV4dGVuZHMgVGVzdENhc2UgeworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci50ZWFyRG93bigpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoImJveGluZyIpCisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkT2JqZWN0RGF0YUlucHV0Q29uZmlndXJhdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgSEJhc2VDb25maWd1cmF0aW9uKCk7CisgICAgLy8gRG8gcHJpbWl0aXZlIHR5cGUKKyAgICBmaW5hbCBpbnQgQ09VTlQgPSAxMDE7CisgICAgYXNzZXJ0VHJ1ZShkb1R5cGUoY29uZiwgQ09VTlQsIGludC5jbGFzcykuZXF1YWxzKENPVU5UKSk7CisgICAgLy8gRG8gYXJyYXkKKyAgICBmaW5hbCBieXRlIFtdIHRlc3RpbmcgPSAidGVzdGluZyIuZ2V0Qnl0ZXMoKTsKKyAgICBieXRlIFtdIHJlc3VsdCA9IChieXRlIFtdKWRvVHlwZShjb25mLCB0ZXN0aW5nLCB0ZXN0aW5nLmdldENsYXNzKCkpOworICAgIGFzc2VydFRydWUoV3JpdGFibGVDb21wYXJhdG9yLmNvbXBhcmVCeXRlcyh0ZXN0aW5nLCAwLCB0ZXN0aW5nLmxlbmd0aCwKKyAgICAgICByZXN1bHQsIDAsIHJlc3VsdC5sZW5ndGgpID09IDApOworICAgIC8vIERvIHVuc3VwcG9ydGVkIHR5cGUuCisgICAgYm9vbGVhbiBleGNlcHRpb24gPSBmYWxzZTsKKyAgICB0cnkgeworICAgICAgZG9UeXBlKGNvbmYsIG5ldyBGaWxlKCJhIiksIEZpbGUuY2xhc3MpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHVvZSkgeworICAgICAgZXhjZXB0aW9uID0gdHJ1ZTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShleGNlcHRpb24pOworICAgIC8vIFRyeSBvZGQgdHlwZXMKKyAgICBmaW5hbCBieXRlIEEgPSAnQSc7CisgICAgYnl0ZSBbXSBieXRlcyA9IG5ldyBieXRlWzFdOworICAgIGJ5dGVzWzBdID0gQTsKKyAgICBPYmplY3Qgb2JqID0gZG9UeXBlKGNvbmYsIGJ5dGVzLCBieXRlIFtdLmNsYXNzKTsKKyAgICBhc3NlcnRUcnVlKCgoYnl0ZSBbXSlvYmopWzBdID09IEEpOworICAgIC8vIERvICdrbm93bicgV3JpdGFibGUgdHlwZS4KKyAgICBvYmogPSBkb1R5cGUoY29uZiwgbmV3IFRleHQoIiIpLCBUZXh0LmNsYXNzKTsKKyAgICBhc3NlcnRUcnVlKG9iaiBpbnN0YW5jZW9mIFRleHQpOworICAgIC8vIFRyeSB0eXBlIHRoYXQgc2hvdWxkIGdldCB0cmFuc2ZlcnJlZCBvbGQgZmFzaGlvbiB3YXkuCisgICAgb2JqID0gZG9UeXBlKGNvbmYsIG5ldyBTdG9wUm93RmlsdGVyKEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSksCisgICAgICAgIFJvd0ZpbHRlckludGVyZmFjZS5jbGFzcyk7CisgICAgYXNzZXJ0VHJ1ZShvYmogaW5zdGFuY2VvZiBTdG9wUm93RmlsdGVyKTsKKyAgfQorICAKKyAgcHJpdmF0ZSBPYmplY3QgZG9UeXBlKGZpbmFsIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mLCBmaW5hbCBPYmplY3QgdmFsdWUsCisgICAgICBmaW5hbCBDbGFzczw/PiBjbGF6eikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZVN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBEYXRhT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVTdHJlYW0pOworICAgIEhiYXNlT2JqZWN0V3JpdGFibGUud3JpdGVPYmplY3Qob3V0LCB2YWx1ZSwgY2xhenosIGNvbmYpOworICAgIG91dC5jbG9zZSgpOworICAgIEJ5dGVBcnJheUlucHV0U3RyZWFtIGJhaXMgPQorICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVTdHJlYW0udG9CeXRlQXJyYXkoKSk7CisgICAgRGF0YUlucHV0U3RyZWFtIGRpcyA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oYmFpcyk7CisgICAgT2JqZWN0IHByb2R1Y3QgPSBIYmFzZU9iamVjdFdyaXRhYmxlLnJlYWRPYmplY3QoZGlzLCBjb25mKTsKKyAgICBkaXMuY2xvc2UoKTsKKyAgICByZXR1cm4gcHJvZHVjdDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvS1ZHZW5lcmF0b3IuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL0tWR2VuZXJhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2E4YjgwYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL0tWR2VuZXJhdG9yLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZTsKKworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5pby5CeXRlc1dyaXRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLldyaXRhYmxlQ29tcGFyYXRvcjsKKworLyoqCisgKiBHZW5lcmF0ZSByYW5kb20gPGtleSwgdmFsdWU+IHBhaXJzLgorICogPHA+CisgKiBDb3BpZWQgZnJvbQorICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQURPT1AtMzMxNSI+aGFkb29wLTMzMTUgdGZpbGU8L2E+LgorICogUmVtb3ZlIGFmdGVyIHRmaWxlIGlzIGNvbW1pdHRlZCBhbmQgdXNlIHRoZSB0ZmlsZSB2ZXJzaW9uIG9mIHRoaXMgY2xhc3MKKyAqIGluc3RlYWQuPC9wPgorICovCitjbGFzcyBLVkdlbmVyYXRvciB7CisgIHByaXZhdGUgZmluYWwgUmFuZG9tIHJhbmRvbTsKKyAgcHJpdmF0ZSBmaW5hbCBieXRlW11bXSBkaWN0OworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gc29ydGVkOworICBwcml2YXRlIGZpbmFsIFJhbmRvbURpc3RyaWJ1dGlvbi5EaXNjcmV0ZVJORyBrZXlMZW5STkcsIHZhbExlblJORzsKKyAgcHJpdmF0ZSBCeXRlc1dyaXRhYmxlIGxhc3RLZXk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fS0VZX0xFTiA9IDQ7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBwcmVmaXhbXSA9IG5ldyBieXRlW01JTl9LRVlfTEVOXTsKKworICBwdWJsaWMgS1ZHZW5lcmF0b3IoUmFuZG9tIHJhbmRvbSwgYm9vbGVhbiBzb3J0ZWQsCisgICAgICBSYW5kb21EaXN0cmlidXRpb24uRGlzY3JldGVSTkcga2V5TGVuUk5HLAorICAgICAgUmFuZG9tRGlzdHJpYnV0aW9uLkRpc2NyZXRlUk5HIHZhbExlblJORywKKyAgICAgIFJhbmRvbURpc3RyaWJ1dGlvbi5EaXNjcmV0ZVJORyB3b3JkTGVuUk5HLCBpbnQgZGljdFNpemUpIHsKKyAgICB0aGlzLnJhbmRvbSA9IHJhbmRvbTsKKyAgICBkaWN0ID0gbmV3IGJ5dGVbZGljdFNpemVdW107CisgICAgdGhpcy5zb3J0ZWQgPSBzb3J0ZWQ7CisgICAgdGhpcy5rZXlMZW5STkcgPSBrZXlMZW5STkc7CisgICAgdGhpcy52YWxMZW5STkcgPSB2YWxMZW5STkc7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkaWN0U2l6ZTsgKytpKSB7CisgICAgICBpbnQgd29yZExlbiA9IHdvcmRMZW5STkcubmV4dEludCgpOworICAgICAgZGljdFtpXSA9IG5ldyBieXRlW3dvcmRMZW5dOworICAgICAgcmFuZG9tLm5leHRCeXRlcyhkaWN0W2ldKTsKKyAgICB9CisgICAgbGFzdEtleSA9IG5ldyBCeXRlc1dyaXRhYmxlKCk7CisgICAgZmlsbEtleShsYXN0S2V5KTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGZpbGxLZXkoQnl0ZXNXcml0YWJsZSBvKSB7CisgICAgaW50IGxlbiA9IGtleUxlblJORy5uZXh0SW50KCk7CisgICAgaWYgKGxlbiA8IE1JTl9LRVlfTEVOKSBsZW4gPSBNSU5fS0VZX0xFTjsKKyAgICBvLnNldFNpemUobGVuKTsKKyAgICBpbnQgbiA9IE1JTl9LRVlfTEVOOworICAgIHdoaWxlIChuIDwgbGVuKSB7CisgICAgICBieXRlW10gd29yZCA9IGRpY3RbcmFuZG9tLm5leHRJbnQoZGljdC5sZW5ndGgpXTsKKyAgICAgIGludCBsID0gTWF0aC5taW4od29yZC5sZW5ndGgsIGxlbiAtIG4pOworICAgICAgU3lzdGVtLmFycmF5Y29weSh3b3JkLCAwLCBvLmdldCgpLCBuLCBsKTsKKyAgICAgIG4gKz0gbDsKKyAgICB9CisgICAgaWYgKHNvcnRlZAorICAgICAgICAmJiBXcml0YWJsZUNvbXBhcmF0b3IuY29tcGFyZUJ5dGVzKGxhc3RLZXkuZ2V0KCksIE1JTl9LRVlfTEVOLCBsYXN0S2V5CisgICAgICAgICAgICAuZ2V0U2l6ZSgpCisgICAgICAgICAgICAtIE1JTl9LRVlfTEVOLCBvLmdldCgpLCBNSU5fS0VZX0xFTiwgby5nZXRTaXplKCkgLSBNSU5fS0VZX0xFTikgPiAwKSB7CisgICAgICBpbmNyZW1lbnRQcmVmaXgoKTsKKyAgICB9CisKKyAgICBTeXN0ZW0uYXJyYXljb3B5KHByZWZpeCwgMCwgby5nZXQoKSwgMCwgTUlOX0tFWV9MRU4pOworICAgIGxhc3RLZXkuc2V0KG8pOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGZpbGxWYWx1ZShCeXRlc1dyaXRhYmxlIG8pIHsKKyAgICBpbnQgbGVuID0gdmFsTGVuUk5HLm5leHRJbnQoKTsKKyAgICBvLnNldFNpemUobGVuKTsKKyAgICBpbnQgbiA9IDA7CisgICAgd2hpbGUgKG4gPCBsZW4pIHsKKyAgICAgIGJ5dGVbXSB3b3JkID0gZGljdFtyYW5kb20ubmV4dEludChkaWN0Lmxlbmd0aCldOworICAgICAgaW50IGwgPSBNYXRoLm1pbih3b3JkLmxlbmd0aCwgbGVuIC0gbik7CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KHdvcmQsIDAsIG8uZ2V0KCksIG4sIGwpOworICAgICAgbiArPSBsOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGluY3JlbWVudFByZWZpeCgpIHsKKyAgICBmb3IgKGludCBpID0gTUlOX0tFWV9MRU4gLSAxOyBpID49IDA7IC0taSkgeworICAgICAgKytwcmVmaXhbaV07CisgICAgICBpZiAocHJlZml4W2ldICE9IDApIHJldHVybjsKKyAgICB9CisgICAgCisgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIlByZWZpeCBvdmVyZmxvd24iKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgbmV4dChCeXRlc1dyaXRhYmxlIGtleSwgQnl0ZXNXcml0YWJsZSB2YWx1ZSwgYm9vbGVhbiBkdXBLZXkpIHsKKyAgICBpZiAoZHVwS2V5KSB7CisgICAgICBrZXkuc2V0KGxhc3RLZXkpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIGZpbGxLZXkoa2V5KTsKKyAgICB9CisgICAgZmlsbFZhbHVlKHZhbHVlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvS2V5U2FtcGxlci5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvS2V5U2FtcGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2Y2Y3NjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9LZXlTYW1wbGVyLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqIAorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLkJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuUmFuZG9tRGlzdHJpYnV0aW9uLkRpc2NyZXRlUk5HOworCisvKgorKiA8cD4KKyogQ29waWVkIGZyb20KKyogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQURPT1AtMzMxNSI+aGFkb29wLTMzMTUgdGZpbGU8L2E+LgorKiBSZW1vdmUgYWZ0ZXIgdGZpbGUgaXMgY29tbWl0dGVkIGFuZCB1c2UgdGhlIHRmaWxlIHZlcnNpb24gb2YgdGhpcyBjbGFzcworKiBpbnN0ZWFkLjwvcD4KKyovCitjbGFzcyBLZXlTYW1wbGVyIHsKKyAgUmFuZG9tIHJhbmRvbTsKKyAgaW50IG1pbiwgbWF4OworICBEaXNjcmV0ZVJORyBrZXlMZW5STkc7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNSU5fS0VZX0xFTiA9IDQ7CisKKyAgcHVibGljIEtleVNhbXBsZXIoUmFuZG9tIHJhbmRvbSwgYnl0ZSBbXSBmaXJzdCwgYnl0ZSBbXSBsYXN0LAorICAgICAgRGlzY3JldGVSTkcga2V5TGVuUk5HKSB7CisgICAgdGhpcy5yYW5kb20gPSByYW5kb207CisgICAgbWluID0ga2V5UHJlZml4VG9JbnQoZmlyc3QpOworICAgIG1heCA9IGtleVByZWZpeFRvSW50KGxhc3QpOworICAgIHRoaXMua2V5TGVuUk5HID0ga2V5TGVuUk5HOworICB9CisKKyAgcHJpdmF0ZSBpbnQga2V5UHJlZml4VG9JbnQoYnl0ZSBbXSBrZXkpIHsKKyAgICBieXRlW10gYiA9IGtleTsKKyAgICBpbnQgbyA9IDA7CisgICAgcmV0dXJuIChiW29dICYgMHhmZikgPDwgMjQgfCAoYltvICsgMV0gJiAweGZmKSA8PCAxNgorICAgICAgICB8IChiW28gKyAyXSAmIDB4ZmYpIDw8IDggfCAoYltvICsgM10gJiAweGZmKTsKKyAgfQorICAKKyAgcHVibGljIHZvaWQgbmV4dChCeXRlc1dyaXRhYmxlIGtleSkgeworICAgIGtleS5zZXRTaXplKE1hdGgubWF4KE1JTl9LRVlfTEVOLCBrZXlMZW5STkcubmV4dEludCgpKSk7CisgICAgcmFuZG9tLm5leHRCeXRlcyhrZXkuZ2V0KCkpOworICAgIGludCBuID0gcmFuZG9tLm5leHRJbnQobWF4IC0gbWluKSArIG1pbjsKKyAgICBieXRlW10gYiA9IGtleS5nZXQoKTsKKyAgICBiWzBdID0gKGJ5dGUpIChuID4+IDI0KTsKKyAgICBiWzFdID0gKGJ5dGUpIChuID4+IDE2KTsKKyAgICBiWzJdID0gKGJ5dGUpIChuID4+IDgpOworICAgIGJbM10gPSAoYnl0ZSkgbjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvTmFub1RpbWVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9OYW5vVGltZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzEyZGEwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvTmFub1RpbWVyLmphdmEKQEAgLTAsMCArMSwxOTggQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZTsKKworLyoqCisgKiBBIG5hbm8tc2Vjb25kIHRpbWVyLgorICogPHA+CisgKiBDb3BpZWQgZnJvbQorICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQURPT1AtMzMxNSI+aGFkb29wLTMzMTUgdGZpbGU8L2E+LgorICogUmVtb3ZlIGFmdGVyIHRmaWxlIGlzIGNvbW1pdHRlZCBhbmQgdXNlIHRoZSB0ZmlsZSB2ZXJzaW9uIG9mIHRoaXMgY2xhc3MKKyAqIGluc3RlYWQuPC9wPgorICovCitwdWJsaWMgY2xhc3MgTmFub1RpbWVyIHsKKyAgcHJpdmF0ZSBsb25nIGxhc3QgPSAtMTsKKyAgcHJpdmF0ZSBib29sZWFuIHN0YXJ0ZWQgPSBmYWxzZTsKKyAgcHJpdmF0ZSBsb25nIGN1bXVsYXRlID0gMDsKKworICAvKioKKyAgICogQ29uc3RydWN0b3IKKyAgICogCisgICAqIEBwYXJhbSBzdGFydAorICAgKiAgICAgICAgICBTdGFydCB0aGUgdGltZXIgdXBvbiBjb25zdHJ1Y3Rpb24uCisgICAqLworICBwdWJsaWMgTmFub1RpbWVyKGJvb2xlYW4gc3RhcnQpIHsKKyAgICBpZiAoc3RhcnQpIHRoaXMuc3RhcnQoKTsKKyAgfQorCisgIC8qKgorICAgKiBTdGFydCB0aGUgdGltZXIuCisgICAqIAorICAgKiBOb3RlOiBObyBlZmZlY3QgaWYgdGltZXIgaXMgYWxyZWFkeSBzdGFydGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgc3RhcnQoKSB7CisgICAgaWYgKCF0aGlzLnN0YXJ0ZWQpIHsKKyAgICAgIHRoaXMubGFzdCA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgdGhpcy5zdGFydGVkID0gdHJ1ZTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU3RvcCB0aGUgdGltZXIuCisgICAqIAorICAgKiBOb3RlOiBObyBlZmZlY3QgaWYgdGltZXIgaXMgYWxyZWFkeSBzdG9wcGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgc3RvcCgpIHsKKyAgICBpZiAodGhpcy5zdGFydGVkKSB7CisgICAgICB0aGlzLnN0YXJ0ZWQgPSBmYWxzZTsKKyAgICAgIHRoaXMuY3VtdWxhdGUgKz0gU3lzdGVtLm5hbm9UaW1lKCkgLSB0aGlzLmxhc3Q7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlYWQgdGhlIHRpbWVyLgorICAgKiAKKyAgICogQHJldHVybiB0aGUgZWxhcHNlZCB0aW1lIGluIG5hbm8tc2Vjb25kcy4gTm90ZTogSWYgdGhlIHRpbWVyIGlzIG5ldmVyCisgICAqICAgICAgICAgc3RhcnRlZCBiZWZvcmUsIC0xIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIGxvbmcgcmVhZCgpIHsKKyAgICBpZiAoIXJlYWRhYmxlKCkpIHJldHVybiAtMTsKKworICAgIHJldHVybiB0aGlzLmN1bXVsYXRlOworICB9CisKKyAgLyoqCisgICAqIFJlc2V0IHRoZSB0aW1lci4KKyAgICovCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgIHRoaXMubGFzdCA9IC0xOworICAgIHRoaXMuc3RhcnRlZCA9IGZhbHNlOworICAgIHRoaXMuY3VtdWxhdGUgPSAwOworICB9CisKKyAgLyoqCisgICAqIENoZWNraW5nIHdoZXRoZXIgdGhlIHRpbWVyIGlzIHN0YXJ0ZWQKKyAgICogCisgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aW1lciBpcyBzdGFydGVkLgorICAgKi8KKyAgcHVibGljIGJvb2xlYW4gaXNTdGFydGVkKCkgeworICAgIHJldHVybiB0aGlzLnN0YXJ0ZWQ7CisgIH0KKworICAvKioKKyAgICogRm9ybWF0IHRoZSBlbGFwc2VkIHRpbWUgdG8gYSBodW1hbiB1bmRlcnN0YW5kYWJsZSBzdHJpbmcuCisgICAqIAorICAgKiBOb3RlOiBJZiB0aW1lciBpcyBuZXZlciBzdGFydGVkLCAiRVJSIiB3aWxsIGJlIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICBpZiAoIXJlYWRhYmxlKCkpIHsKKyAgICAgIHJldHVybiAiRVJSIjsKKyAgICB9CisKKyAgICByZXR1cm4gTmFub1RpbWVyLm5hbm9UaW1lVG9TdHJpbmcodGhpcy5jdW11bGF0ZSk7CisgIH0KKworICAvKioKKyAgICogQSB1dGlsaXR5IG1ldGhvZCB0byBmb3JtYXQgYSB0aW1lIGR1cmF0aW9uIGluIG5hbm8gc2Vjb25kcyBpbnRvIGEgaHVtYW4KKyAgICogdW5kZXJzdGFuZGFibGUgc3Rpcm5nLgorICAgKiAKKyAgICogQHBhcmFtIHQKKyAgICogICAgICAgICAgVGltZSBkdXJhdGlvbiBpbiBuYW5vIHNlY29uZHMuCisgICAqIEByZXR1cm4gU3RyaW5nIHJlcHJlc2VudGF0aW9uLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgbmFub1RpbWVUb1N0cmluZyhsb25nIHQpIHsKKyAgICBpZiAodCA8IDApIHJldHVybiAiRVJSIjsKKworICAgIGlmICh0ID09IDApIHJldHVybiAiMCI7CisKKyAgICBpZiAodCA8IDEwMDApIHsKKyAgICAgIHJldHVybiB0ICsgIm5zIjsKKyAgICB9CisKKyAgICBkb3VibGUgdXMgPSAoZG91YmxlKSB0IC8gMTAwMDsKKyAgICBpZiAodXMgPCAxMDAwKSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJS4yZnVzIiwgdXMpOworICAgIH0KKworICAgIGRvdWJsZSBtcyA9IHVzIC8gMTAwMDsKKyAgICBpZiAobXMgPCAxMDAwKSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJS4yZm1zIiwgbXMpOworICAgIH0KKworICAgIGRvdWJsZSBzcyA9IG1zIC8gMTAwMDsKKyAgICBpZiAoc3MgPCAxMDAwKSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJS4yZnMiLCBzcyk7CisgICAgfQorCisgICAgbG9uZyBtbSA9IChsb25nKSBzcyAvIDYwOworICAgIHNzIC09IG1tICogNjA7CisgICAgbG9uZyBoaCA9IG1tIC8gNjA7CisgICAgbW0gLT0gaGggKiA2MDsKKyAgICBsb25nIGRkID0gaGggLyAyNDsKKyAgICBoaCAtPSBkZCAqIDI0OworCisgICAgaWYgKGRkID4gMCkgeworICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVkZCVkaCIsIGRkLCBoaCk7CisgICAgfQorCisgICAgaWYgKGhoID4gMCkgeworICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVkaCVkbSIsIGhoLCBtbSk7CisgICAgfQorCisgICAgaWYgKG1tID4gMCkgeworICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVkbSUuMWZzIiwgbW0sIHNzKTsKKyAgICB9CisKKyAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJS4yZnMiLCBzcyk7CisKKyAgICAvKioKKyAgICAgKiBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsgU3RyaW5nIHNlcCA9ICIiOworICAgICAqIAorICAgICAqIGlmIChkZCA+IDApIHsgU3RyaW5nIHVuaXQgPSAoZGQgPiAxKSA/ICJkYXlzIiA6ICJkYXkiOworICAgICAqIHNiLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlcyVkJXMiLCBzZXAsIGRkLCB1bml0KSk7IHNlcCA9ICIgIjsgfQorICAgICAqIAorICAgICAqIGlmIChoaCA+IDApIHsgU3RyaW5nIHVuaXQgPSAoaGggPiAxKSA/ICJocnMiIDogImhyIjsKKyAgICAgKiBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJXMlZCVzIiwgc2VwLCBoaCwgdW5pdCkpOyBzZXAgPSAiICI7IH0KKyAgICAgKiAKKyAgICAgKiBpZiAobW0gPiAwKSB7IFN0cmluZyB1bml0ID0gKG1tID4gMSkgPyAibWlucyIgOiAibWluIjsKKyAgICAgKiBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJXMlZCVzIiwgc2VwLCBtbSwgdW5pdCkpOyBzZXAgPSAiICI7IH0KKyAgICAgKiAKKyAgICAgKiBpZiAoc3MgPiAwKSB7IFN0cmluZyB1bml0ID0gKHNzID4gMSkgPyAic2VjcyIgOiAic2VjIjsKKyAgICAgKiBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJXMlLjNmJXMiLCBzZXAsIHNzLCB1bml0KSk7IHNlcCA9ICIgIjsgfQorICAgICAqIAorICAgICAqIHJldHVybiBzYi50b1N0cmluZygpOworICAgICAqLworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIHJlYWRhYmxlKCkgeworICAgIHJldHVybiB0aGlzLmxhc3QgIT0gLTE7CisgIH0KKworICAvKioKKyAgICogU2ltcGxlIHRlc3Rlci4KKyAgICogCisgICAqIEBwYXJhbSBhcmdzCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgbG9uZyBpID0gNzsKKworICAgIGZvciAoaW50IHggPSAwOyB4IDwgMjA7ICsreCwgaSAqPSA3KSB7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oTmFub1RpbWVyLm5hbm9UaW1lVG9TdHJpbmcoaSkpOworICAgIH0KKyAgfQorfQorCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9SYW5kb21EaXN0cmlidXRpb24uamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1JhbmRvbURpc3RyaWJ1dGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMTk2NjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9SYW5kb21EaXN0cmlidXRpb24uamF2YQpAQCAtMCwwICsxLDI3MSBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lIG9yIG1vcmUKKyAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoIHRoaXMKKyAqIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YKKyAqIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqIAorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQKKyAqIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZQorICogTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKKyAqIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworCisvKioKKyAqIEEgY2xhc3MgdGhhdCBnZW5lcmF0ZXMgcmFuZG9tIG51bWJlcnMgdGhhdCBmb2xsb3cgc29tZSBkaXN0cmlidXRpb24uCisgKiA8cD4KKyAqIENvcGllZCBmcm9tCisgKiA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0hBRE9PUC0zMzE1Ij5oYWRvb3AtMzMxNSB0ZmlsZTwvYT4uCisgKiBSZW1vdmUgYWZ0ZXIgdGZpbGUgaXMgY29tbWl0dGVkIGFuZCB1c2UgdGhlIHRmaWxlIHZlcnNpb24gb2YgdGhpcyBjbGFzcworICogaW5zdGVhZC48L3A+CisgKi8KK3B1YmxpYyBjbGFzcyBSYW5kb21EaXN0cmlidXRpb24geworICAvKioKKyAgICogSW50ZXJmYWNlIGZvciBkaXNjcmV0ZSAoaW50ZWdlcikgcmFuZG9tIGRpc3RyaWJ1dGlvbnMuCisgICAqLworICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBEaXNjcmV0ZVJORyB7CisgICAgLyoqCisgICAgICogR2V0IHRoZSBuZXh0IHJhbmRvbSBudW1iZXIKKyAgICAgKiAKKyAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IHJhbmRvbSBudW1iZXIuCisgICAgICovCisgICAgcHVibGljIGludCBuZXh0SW50KCk7CisgIH0KKworICAvKioKKyAgICogUChpKT0xLyhtYXgtbWluKQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGbGF0IGltcGxlbWVudHMgRGlzY3JldGVSTkcgeworICAgIHByaXZhdGUgZmluYWwgUmFuZG9tIHJhbmRvbTsKKyAgICBwcml2YXRlIGZpbmFsIGludCBtaW47CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4OworCisgICAgLyoqCisgICAgICogR2VuZXJhdGUgcmFuZG9tIGludGVnZXJzIGZyb20gbWluIChpbmNsdXNpdmUpIHRvIG1heCAoZXhjbHVzaXZlKQorICAgICAqIGZvbGxvd2luZyBldmVuIGRpc3RyaWJ1dGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgVGhlIGJhc2ljIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLgorICAgICAqIEBwYXJhbSBtaW4KKyAgICAgKiAgICAgICAgICBNaW5pbXVtIGludGVnZXIKKyAgICAgKiBAcGFyYW0gbWF4CisgICAgICogICAgICAgICAgbWF4aW11bSBpbnRlZ2VyIChleGNsdXNpdmUpLgorICAgICAqIAorICAgICAqLworICAgIHB1YmxpYyBGbGF0KFJhbmRvbSByYW5kb20sIGludCBtaW4sIGludCBtYXgpIHsKKyAgICAgIGlmIChtaW4gPj0gbWF4KSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgcmFuZ2UiKTsKKyAgICAgIH0KKyAgICAgIHRoaXMucmFuZG9tID0gcmFuZG9tOworICAgICAgdGhpcy5taW4gPSBtaW47CisgICAgICB0aGlzLm1heCA9IG1heDsKKyAgICB9CisgICAgCisgICAgLyoqCisgICAgICogQHNlZSBEaXNjcmV0ZVJORyNuZXh0SW50KCkKKyAgICAgKi8KKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IG5leHRJbnQoKSB7CisgICAgICByZXR1cm4gcmFuZG9tLm5leHRJbnQobWF4IC0gbWluKSArIG1pbjsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogWmlwZiBkaXN0cmlidXRpb24uIFRoZSByYXRpbyBvZiB0aGUgcHJvYmFiaWxpdGllcyBvZiBpbnRlZ2VyIGkgYW5kIGogaXMKKyAgICogZGVmaW5lZCBhcyBmb2xsb3dzOgorICAgKiAKKyAgICogUChpKS9QKGopPSgoai1taW4rMSkvKGktbWluKzEpKV5zaWdtYS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgWmlwZiBpbXBsZW1lbnRzIERpc2NyZXRlUk5HIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgREVGQVVMVF9FUFNJTE9OID0gMC4wMDE7CisgICAgcHJpdmF0ZSBmaW5hbCBSYW5kb20gcmFuZG9tOworICAgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0PEludGVnZXI+IGs7CisgICAgcHJpdmF0ZSBmaW5hbCBBcnJheUxpc3Q8RG91YmxlPiB2OworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0b3IKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcgorICAgICAqICAgICAgICAgIFRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvci4KKyAgICAgKiBAcGFyYW0gbWluCisgICAgICogICAgICAgICAgbWluaW11bSBpbnRlZ2VyIChpbmNsdXN2aWUpCisgICAgICogQHBhcmFtIG1heAorICAgICAqICAgICAgICAgIG1heGltdW0gaW50ZWdlciAoZXhjbHVzaXZlKQorICAgICAqIEBwYXJhbSBzaWdtYQorICAgICAqICAgICAgICAgIHBhcmFtZXRlciBzaWdtYS4gKHNpZ21hID4gMS4wKQorICAgICAqLworICAgIHB1YmxpYyBaaXBmKFJhbmRvbSByLCBpbnQgbWluLCBpbnQgbWF4LCBkb3VibGUgc2lnbWEpIHsKKyAgICAgIHRoaXMociwgbWluLCBtYXgsIHNpZ21hLCBERUZBVUxUX0VQU0lMT04pOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnN0cnVjdG9yLgorICAgICAqIAorICAgICAqIEBwYXJhbSByCisgICAgICogICAgICAgICAgVGhlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLgorICAgICAqIEBwYXJhbSBtaW4KKyAgICAgKiAgICAgICAgICBtaW5pbXVtIGludGVnZXIgKGluY2x1c3ZpZSkKKyAgICAgKiBAcGFyYW0gbWF4CisgICAgICogICAgICAgICAgbWF4aW11bSBpbnRlZ2VyIChleGNsdXNpdmUpCisgICAgICogQHBhcmFtIHNpZ21hCisgICAgICogICAgICAgICAgcGFyYW1ldGVyIHNpZ21hLiAoc2lnbWEgPiAxLjApCisgICAgICogQHBhcmFtIGVwc2lsb24KKyAgICAgKiAgICAgICAgICBBbGxvd2FibGUgZXJyb3IgcGVyY2VudGFnZSAoMCA8IGVwc2lsb24gPCAxLjApLgorICAgICAqLworICAgIHB1YmxpYyBaaXBmKFJhbmRvbSByLCBpbnQgbWluLCBpbnQgbWF4LCBkb3VibGUgc2lnbWEsIGRvdWJsZSBlcHNpbG9uKSB7CisgICAgICBpZiAoKG1heCA8PSBtaW4pIHx8IChzaWdtYSA8PSAxKSB8fCAoZXBzaWxvbiA8PSAwKQorICAgICAgICAgIHx8IChlcHNpbG9uID49IDAuNSkpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBhcmd1bWVudHMiKTsKKyAgICAgIH0KKyAgICAgIHJhbmRvbSA9IHI7CisgICAgICBrID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOworICAgICAgdiA9IG5ldyBBcnJheUxpc3Q8RG91YmxlPigpOworCisgICAgICBkb3VibGUgc3VtID0gMDsKKyAgICAgIGludCBsYXN0ID0gLTE7CisgICAgICBmb3IgKGludCBpID0gbWluOyBpIDwgbWF4OyArK2kpIHsKKyAgICAgICAgc3VtICs9IE1hdGguZXhwKC1zaWdtYSAqIE1hdGgubG9nKGkgLSBtaW4gKyAxKSk7CisgICAgICAgIGlmICgobGFzdCA9PSAtMSkgfHwgaSAqICgxIC0gZXBzaWxvbikgPiBsYXN0KSB7CisgICAgICAgICAgay5hZGQoaSk7CisgICAgICAgICAgdi5hZGQoc3VtKTsKKyAgICAgICAgICBsYXN0ID0gaTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAobGFzdCAhPSBtYXggLSAxKSB7CisgICAgICAgIGsuYWRkKG1heCAtIDEpOworICAgICAgICB2LmFkZChzdW0pOworICAgICAgfQorCisgICAgICB2LnNldCh2LnNpemUoKSAtIDEsIDEuMCk7CisKKyAgICAgIGZvciAoaW50IGkgPSB2LnNpemUoKSAtIDI7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgIHYuc2V0KGksIHYuZ2V0KGkpIC8gc3VtKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIERpc2NyZXRlUk5HI25leHRJbnQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgbmV4dEludCgpIHsKKyAgICAgIGRvdWJsZSBkID0gcmFuZG9tLm5leHREb3VibGUoKTsKKyAgICAgIGludCBpZHggPSBDb2xsZWN0aW9ucy5iaW5hcnlTZWFyY2godiwgZCk7CisKKyAgICAgIGlmIChpZHggPiAwKSB7CisgICAgICAgICsraWR4OworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIGlkeCA9IC0oaWR4ICsgMSk7CisgICAgICB9CisKKyAgICAgIGlmIChpZHggPj0gdi5zaXplKCkpIHsKKyAgICAgICAgaWR4ID0gdi5zaXplKCkgLSAxOworICAgICAgfQorCisgICAgICBpZiAoaWR4ID09IDApIHsKKyAgICAgICAgcmV0dXJuIGsuZ2V0KDApOworICAgICAgfQorCisgICAgICBpbnQgY2VpbGluZyA9IGsuZ2V0KGlkeCk7CisgICAgICBpbnQgbG93ZXIgPSBrLmdldChpZHggLSAxKTsKKworICAgICAgcmV0dXJuIGNlaWxpbmcgLSByYW5kb20ubmV4dEludChjZWlsaW5nIC0gbG93ZXIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBCaW5vbWlhbCBkaXN0cmlidXRpb24uCisgICAqIAorICAgKiBQKGspPXNlbGVjdChuLCBrKSpwXmsqKDEtcCleKG4taykgKGsgPSAwLCAxLCAuLi4sIG4pCisgICAqIAorICAgKiBQKGspPXNlbGVjdChtYXgtbWluLTEsIGstbWluKSpwXihrLW1pbikqKDEtcCleKGstbWluKSooMS1wKV4obWF4LWstMSkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQmlub21pYWwgaW1wbGVtZW50cyBEaXNjcmV0ZVJORyB7CisgICAgcHJpdmF0ZSBmaW5hbCBSYW5kb20gcmFuZG9tOworICAgIHByaXZhdGUgZmluYWwgaW50IG1pbjsKKyAgICBwcml2YXRlIGZpbmFsIGludCBuOworICAgIHByaXZhdGUgZmluYWwgZG91YmxlW10gdjsKKworICAgIHByaXZhdGUgc3RhdGljIGRvdWJsZSBzZWxlY3QoaW50IG4sIGludCBrKSB7CisgICAgICBkb3VibGUgcmV0ID0gMS4wOworICAgICAgZm9yIChpbnQgaSA9IGsgKyAxOyBpIDw9IG47ICsraSkgeworICAgICAgICByZXQgKj0gKGRvdWJsZSkgaSAvIChpIC0gayk7CisgICAgICB9CisgICAgICByZXR1cm4gcmV0OworICAgIH0KKyAgICAKKyAgICBwcml2YXRlIHN0YXRpYyBkb3VibGUgcG93ZXIoZG91YmxlIHAsIGludCBrKSB7CisgICAgICByZXR1cm4gTWF0aC5leHAoayAqIE1hdGgubG9nKHApKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBHZW5lcmF0ZSByYW5kb20gaW50ZWdlcnMgZnJvbSBtaW4gKGluY2x1c2l2ZSkgdG8gbWF4IChleGNsdXNpdmUpCisgICAgICogZm9sbG93aW5nIEJpbm9taWFsIGRpc3RyaWJ1dGlvbi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcmFuZG9tCisgICAgICogICAgICAgICAgVGhlIGJhc2ljIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLgorICAgICAqIEBwYXJhbSBtaW4KKyAgICAgKiAgICAgICAgICBNaW5pbXVtIGludGVnZXIKKyAgICAgKiBAcGFyYW0gbWF4CisgICAgICogICAgICAgICAgbWF4aW11bSBpbnRlZ2VyIChleGNsdXNpdmUpLgorICAgICAqIEBwYXJhbSBwCisgICAgICogICAgICAgICAgcGFyYW1ldGVyLgorICAgICAqIAorICAgICAqLworICAgIHB1YmxpYyBCaW5vbWlhbChSYW5kb20gcmFuZG9tLCBpbnQgbWluLCBpbnQgbWF4LCBkb3VibGUgcCkgeworICAgICAgaWYgKG1pbiA+PSBtYXgpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByYW5nZSIpOworICAgICAgfQorICAgICAgdGhpcy5yYW5kb20gPSByYW5kb207CisgICAgICB0aGlzLm1pbiA9IG1pbjsKKyAgICAgIHRoaXMubiA9IG1heCAtIG1pbiAtIDE7CisgICAgICBpZiAobiA+IDApIHsKKyAgICAgICAgdiA9IG5ldyBkb3VibGVbbiArIDFdOworICAgICAgICBkb3VibGUgc3VtID0gMC4wOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBuOyArK2kpIHsKKyAgICAgICAgICBzdW0gKz0gc2VsZWN0KG4sIGkpICogcG93ZXIocCwgaSkgKiBwb3dlcigxIC0gcCwgbiAtIGkpOworICAgICAgICAgIHZbaV0gPSBzdW07CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbjsgKytpKSB7CisgICAgICAgICAgdltpXSAvPSBzdW07CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICB2ID0gbnVsbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIERpc2NyZXRlUk5HI25leHRJbnQoKQorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgbmV4dEludCgpIHsKKyAgICAgIGlmICh2ID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuIG1pbjsKKyAgICAgIH0KKyAgICAgIGRvdWJsZSBkID0gcmFuZG9tLm5leHREb3VibGUoKTsKKyAgICAgIGludCBpZHggPSBBcnJheXMuYmluYXJ5U2VhcmNoKHYsIGQpOworICAgICAgaWYgKGlkeCA+IDApIHsKKyAgICAgICAgKytpZHg7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZHggPSAtKGlkeCArIDEpOworICAgICAgfQorCisgICAgICBpZiAoaWR4ID49IHYubGVuZ3RoKSB7CisgICAgICAgIGlkeCA9IHYubGVuZ3RoIC0gMTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBpZHggKyBtaW47CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9SYW5kb21TZWVrLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9SYW5kb21TZWVrLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg0NWMwNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1JhbmRvbVNlZWsuamF2YQpAQCAtMCwwICsxLDEyNCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGVSZWFkZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5Mb2NhbEZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5SYXdMb2NhbEZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGUuUmVhZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogUmFuZG9tIHNlZWsgdGVzdC4KKyAqLworcHVibGljIGNsYXNzIFJhbmRvbVNlZWsgeworICBwcml2YXRlIHN0YXRpYyBMaXN0PFN0cmluZz4gc2x1cnAoU3RyaW5nIGZuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJ1ZmZlcmVkUmVhZGVyIGlzdHJlYW0gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoZm5hbWUpKTsKKyAgICBTdHJpbmcgc3RyOworICAgIExpc3Q8U3RyaW5nPiBsID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CisgICAgd2hpbGUgKCAoc3RyPWlzdHJlYW0ucmVhZExpbmUoKSkgIT0gbnVsbCkgeworICAgICAgU3RyaW5nIFtdIHBhcnRzID0gc3RyLnNwbGl0KCIsIik7CisgICAgICBsLmFkZChwYXJ0c1swXSArICI6IiArIHBhcnRzWzFdICsgIjoiICsgcGFydHNbMl0pOworICAgIH0KKyAgICByZXR1cm4gbDsKKyAgfQorICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcmFuZEtleShMaXN0PFN0cmluZz4ga2V5cykgeworICAgIFJhbmRvbSByID0gbmV3IFJhbmRvbSgpOworICAgIC8vcmV0dXJuIGtleXMuZ2V0KHIubmV4dEludChrZXlzLnNpemUoKSkpOworICAgIHJldHVybiAiMiIgKyBJbnRlZ2VyLnRvU3RyaW5nKDcrci5uZXh0SW50KDIpKSArIEludGVnZXIudG9TdHJpbmcoci5uZXh0SW50KDEwMCkpOworICAgIC8vcmV0dXJuIG5ldyBTdHJpbmcoci5uZXh0SW50KDEwMCkpOworICB9CisgIAorICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgW10gYXJndikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb25maWd1cmF0aW9uIGNvbmYgPSBuZXcgQ29uZmlndXJhdGlvbigpOworICAgIGNvbmYuc2V0SW50KCJpby5maWxlLmJ1ZmZlci5zaXplIiwgNjQqMTAyNCk7CisgICAgUmF3TG9jYWxGaWxlU3lzdGVtIHJsZnMgPSBuZXcgUmF3TG9jYWxGaWxlU3lzdGVtKCk7CisgICAgcmxmcy5zZXRDb25mKGNvbmYpOworICAgIExvY2FsRmlsZVN5c3RlbSBsZnMgPSBuZXcgTG9jYWxGaWxlU3lzdGVtKHJsZnMpOworICAgIAorICAgIFBhdGggcGF0aCA9IG5ldyBQYXRoKCIvVXNlcnMvcnlhbi9yZmlsZS5iaWcudHh0Iik7CisgICAgbG9uZyBzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIFNpbXBsZUJsb2NrQ2FjaGUgY2FjaGUgPSBuZXcgU2ltcGxlQmxvY2tDYWNoZSgpOworICAgIC8vTHJ1QmxvY2tDYWNoZSBjYWNoZSA9IG5ldyBMcnVCbG9ja0NhY2hlKCk7CisgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBIRmlsZS5SZWFkZXIobGZzLCBwYXRoLCBjYWNoZSk7CisgICAgcmVhZGVyLmxvYWRGaWxlSW5mbygpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZWFkZXIudHJhaWxlcik7CisgICAgbG9uZyBlbmQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluZGV4IHJlYWQgdGltZTogIiArIChlbmQgLSBzdGFydCkpOworCisgICAgTGlzdDxTdHJpbmc+IGtleXMgPSBzbHVycCgiL1VzZXJzL3J5YW4veGFhLjUwayIpOworICAgIAorICAgIEhGaWxlU2Nhbm5lciBzY2FubmVyID0gcmVhZGVyLmdldFNjYW5uZXIoKTsKKyAgICBpbnQgY291bnQ7CisgICAgbG9uZyB0b3RhbEJ5dGVzID0gMDsKKyAgICBpbnQgbm90Rm91bmQgPSAwOworCisgICAgc3RhcnQgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICBmb3IoY291bnQgPSAwOyBjb3VudCA8IDUwMDAwMDsgKytjb3VudCkgeworICAgICAgU3RyaW5nIGtleSA9IHJhbmRLZXkoa2V5cyk7CisgICAgICBieXRlIFtdIGJrZXkgPSBCeXRlcy50b0J5dGVzKGtleSk7CisgICAgICBpbnQgcmVzID0gc2Nhbm5lci5zZWVrVG8oYmtleSk7CisgICAgICBpZiAocmVzID09IDApIHsKKyAgICAgICAgQnl0ZUJ1ZmZlciBrID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciB2ID0gc2Nhbm5lci5nZXRWYWx1ZSgpOworICAgICAgICB0b3RhbEJ5dGVzICs9IGsubGltaXQoKTsKKyAgICAgICAgdG90YWxCeXRlcyArPSB2LmxpbWl0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICArKyBub3RGb3VuZDsKKyAgICAgIH0KKyAgICAgIGlmIChyZXMgPT0gLTEpIHsKKyAgICAgICAgc2Nhbm5lci5zZWVrVG8oKTsKKyAgICAgIH0KKyAgICAgIC8vIFNjYW4gZm9yIGFub3RoZXIgMTAwMCByb3dzLgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwOyArK2kpIHsKKyAgICAgICAgaWYgKCFzY2FubmVyLm5leHQoKSkKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgQnl0ZUJ1ZmZlciBrID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciB2ID0gc2Nhbm5lci5nZXRWYWx1ZSgpOworICAgICAgICB0b3RhbEJ5dGVzICs9IGsubGltaXQoKTsKKyAgICAgICAgdG90YWxCeXRlcyArPSB2LmxpbWl0KCk7CisgICAgICB9CisgICAgICAKKyAgICAgIGlmICggY291bnQgJSAxMDAwID09IDAgKSB7CisgICAgICAgIGVuZCA9IFN5c3RlbS5uYW5vVGltZSgpOworICAgICAgICAKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQ2FjaGUgYmxvY2sgY291bnQ6ICIgKyBjYWNoZS5zaXplKCkgKyAiIGR1bXBlZDogIisgY2FjaGUuZHVtcHMpOworICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIkNhY2hlIHNpemU6ICIgKyBjYWNoZS5oZWFwU2l6ZSgpKTsKKyAgICAgICAgICAgIGRvdWJsZSBtc1RpbWUgPSAoKGVuZCAtIHN0YXJ0KSAvIDEwMDAwMDAuMCk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNlZWtlZDogIisgY291bnQgKyAiIGluICIgKyBtc1RpbWUgKyAiIChtcykgIiAKKyAgICAgICAgICAgICAgICArICgxMDAwLjAgLyBtc1RpbWUgKSArICIgc2Vla3MvbXMgIgorICAgICAgICAgICAgICAgICsgKG1zVGltZSAvIDEwMDAuMCkgKyAiIG1zL3NlZWsiKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3RhcnQgPSBTeXN0ZW0ubmFub1RpbWUoKTsKKyAgICAgIH0KKyAgICB9CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJUb3RhbCBieXRlczogIiArIHRvdGFsQnl0ZXMgKyAiIG5vdCBmb3VuZDogIiArIG5vdEZvdW5kKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvVGVzdEhGaWxlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0SEZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDU4OWY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvVGVzdEhGaWxlLmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNEYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNEYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZS5SZWFkZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGUuSEZpbGUuV3JpdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uUmF3Q29tcGFyYXRvcjsKKworLyoqCisgKiB0ZXN0IGhmaWxlIGZlYXR1cmVzLgorICogPHA+CisgKiBDb3BpZWQgZnJvbQorICogPGEgaHJlZj0iaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9IQURPT1AtMzMxNSI+aGFkb29wLTMzMTUgdGZpbGU8L2E+LgorICogUmVtb3ZlIGFmdGVyIHRmaWxlIGlzIGNvbW1pdHRlZCBhbmQgdXNlIHRoZSB0ZmlsZSB2ZXJzaW9uIG9mIHRoaXMgY2xhc3MKKyAqIGluc3RlYWQuPC9wPgorICovCitwdWJsaWMgY2xhc3MgVGVzdEhGaWxlIGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdEhGaWxlLmNsYXNzKTsKKyAgCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBST09UX0RJUiA9CisgICAgU3lzdGVtLmdldFByb3BlcnR5KCJ0ZXN0LmJ1aWxkLmRhdGEiLCAiL3RtcC9UZXN0SEZpbGUiKTsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgbWluQmxvY2tTaXplID0gNTEyOworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgbG9jYWxGb3JtYXR0ZXIgPSAiJTAxMGQiOworCisgIC8vIHdyaXRlIHNvbWUgcmVjb3JkcyBpbnRvIHRoZSB0ZmlsZQorICAvLyB3cml0ZSB0aGVtIHR3aWNlCisgIHByaXZhdGUgaW50IHdyaXRlU29tZVJlY29yZHMoV3JpdGVyIHdyaXRlciwgaW50IHN0YXJ0LCBpbnQgbikKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU3RyaW5nIHZhbHVlID0gInZhbHVlIjsKKyAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCAoc3RhcnQgKyBuKTsgaSsrKSB7CisgICAgICBTdHJpbmcga2V5ID0gU3RyaW5nLmZvcm1hdChsb2NhbEZvcm1hdHRlciwgSW50ZWdlci52YWx1ZU9mKGkpKTsKKyAgICAgIHdyaXRlci5hcHBlbmQoQnl0ZXMudG9CeXRlcyhrZXkpLCBCeXRlcy50b0J5dGVzKHZhbHVlICsga2V5KSk7CisgICAgfQorICAgIHJldHVybiAoc3RhcnQgKyBuKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWFkQWxsUmVjb3JkcyhIRmlsZVNjYW5uZXIgc2Nhbm5lcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZWFkQW5kQ2hlY2tieXRlcyhzY2FubmVyLCAwLCAxMDApOworICB9CisKKyAgLy8gcmVhZCB0aGUgcmVjb3JkcyBhbmQgY2hlY2sKKyAgcHJpdmF0ZSBpbnQgcmVhZEFuZENoZWNrYnl0ZXMoSEZpbGVTY2FubmVyIHNjYW5uZXIsIGludCBzdGFydCwgaW50IG4pCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN0cmluZyB2YWx1ZSA9ICJ2YWx1ZSI7CisgICAgaW50IGkgPSBzdGFydDsKKyAgICBmb3IgKDsgaSA8IChzdGFydCArIG4pOyBpKyspIHsKKyAgICAgIEJ5dGVCdWZmZXIga2V5ID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgIEJ5dGVCdWZmZXIgdmFsID0gc2Nhbm5lci5nZXRWYWx1ZSgpOworICAgICAgU3RyaW5nIGtleVN0ciA9IFN0cmluZy5mb3JtYXQobG9jYWxGb3JtYXR0ZXIsIEludGVnZXIudmFsdWVPZihpKSk7CisgICAgICBTdHJpbmcgdmFsU3RyID0gdmFsdWUgKyBrZXlTdHI7CisgICAgICBieXRlIFtdIGtleUJ5dGVzID0gQnl0ZXMudG9CeXRlcyhrZXkpOworICAgICAgYXNzZXJ0VHJ1ZSgiYnl0ZXMgZm9yIGtleXMgZG8gbm90IG1hdGNoICIgKyBrZXlTdHIgKyAiICIgKworICAgICAgICBCeXRlcy50b1N0cmluZyhCeXRlcy50b0J5dGVzKGtleSkpLAorICAgICAgICAgIEFycmF5cy5lcXVhbHMoQnl0ZXMudG9CeXRlcyhrZXlTdHIpLCBrZXlCeXRlcykpOworICAgICAgYnl0ZSBbXSB2YWxCeXRlcyA9IEJ5dGVzLnRvQnl0ZXModmFsKTsKKyAgICAgIGFzc2VydFRydWUoImJ5dGVzIGZvciB2YWxzIGRvIG5vdCBtYXRjaCAiICsgdmFsU3RyICsgIiAiICsKKyAgICAgICAgQnl0ZXMudG9TdHJpbmcodmFsQnl0ZXMpLAorICAgICAgICBBcnJheXMuZXF1YWxzKEJ5dGVzLnRvQnl0ZXModmFsU3RyKSwgdmFsQnl0ZXMpKTsKKyAgICAgIGlmICghc2Nhbm5lci5uZXh0KCkpIHsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICAgIGFzc2VydEVxdWFscyhpLCBzdGFydCArIG4gLSAxKTsKKyAgICByZXR1cm4gKHN0YXJ0ICsgbik7CisgIH0KKworICBwcml2YXRlIGJ5dGVbXSBnZXRTb21lS2V5KGludCByb3dJZCkgeworICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KGxvY2FsRm9ybWF0dGVyLCBJbnRlZ2VyLnZhbHVlT2Yocm93SWQpKS5nZXRCeXRlcygpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlUmVjb3JkcyhXcml0ZXIgd3JpdGVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHdyaXRlU29tZVJlY29yZHMod3JpdGVyLCAwLCAxMDApOworICAgIHdyaXRlci5jbG9zZSgpOworICB9CisKKyAgcHJpdmF0ZSBGU0RhdGFPdXRwdXRTdHJlYW0gY3JlYXRlRlNPdXRwdXQoUGF0aCBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmcy5leGlzdHMobmFtZSkpIGZzLmRlbGV0ZShuYW1lLCB0cnVlKTsKKyAgICBGU0RhdGFPdXRwdXRTdHJlYW0gZm91dCA9IGZzLmNyZWF0ZShuYW1lKTsKKyAgICByZXR1cm4gZm91dDsKKyAgfQorCisgIC8qKgorICAgKiB0ZXN0IG5vbmUgY29kZWNzCisgICAqLworICB2b2lkIGJhc2ljV2l0aFNvbWVDb2RlYyhTdHJpbmcgY29kZWMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBuY1RGaWxlID0gbmV3IFBhdGgoUk9PVF9ESVIsICJiYXNpYy5oZmlsZSIpOworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBmb3V0ID0gY3JlYXRlRlNPdXRwdXQobmNURmlsZSk7CisgICAgV3JpdGVyIHdyaXRlciA9IG5ldyBXcml0ZXIoZm91dCwgbWluQmxvY2tTaXplLAorICAgICAgQ29tcHJlc3Npb24uZ2V0Q29tcHJlc3Npb25BbGdvcml0aG1CeU5hbWUoY29kZWMpLCBudWxsLCBmYWxzZSk7CisgICAgTE9HLmluZm8od3JpdGVyKTsKKyAgICB3cml0ZVJlY29yZHMod3JpdGVyKTsKKyAgICBmb3V0LmNsb3NlKCk7CisgICAgRlNEYXRhSW5wdXRTdHJlYW0gZmluID0gZnMub3BlbihuY1RGaWxlKTsKKyAgICBSZWFkZXIgcmVhZGVyID0gbmV3IFJlYWRlcihmcy5vcGVuKG5jVEZpbGUpLAorICAgICAgZnMuZ2V0RmlsZVN0YXR1cyhuY1RGaWxlKS5nZXRMZW4oKSwgbnVsbCk7CisgICAgLy8gTG9hZCB1cCB0aGUgaW5kZXguCisgICAgcmVhZGVyLmxvYWRGaWxlSW5mbygpOworICAgIExPRy5pbmZvKHJlYWRlcik7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSByZWFkZXIuZ2V0U2Nhbm5lcigpOworICAgIC8vIEFsaWduIHNjYW5uZXIgYXQgc3RhcnQgb2YgdGhlIGZpbGUuCisgICAgc2Nhbm5lci5zZWVrVG8oKTsKKyAgICByZWFkQWxsUmVjb3JkcyhzY2FubmVyKTsKKyAgICBzY2FubmVyLnNlZWtUbyhnZXRTb21lS2V5KDUwKSk7CisgICAgYXNzZXJ0VHJ1ZSgibG9jYXRpb24gbG9va3VwIGZhaWxlZCIsIHNjYW5uZXIuc2Vla1RvKGdldFNvbWVLZXkoNTApKSA9PSAwKTsKKyAgICAvLyByZWFkIHRoZSBrZXkgYW5kIHNlZSBpZiBpdCBtYXRjaGVzCisgICAgQnl0ZUJ1ZmZlciByZWFkS2V5ID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICBhc3NlcnRUcnVlKCJzZWVrZWQga2V5IGRvZXMgbm90IG1hdGNoIiwgQXJyYXlzLmVxdWFscyhnZXRTb21lS2V5KDUwKSwKKyAgICAgIEJ5dGVzLnRvQnl0ZXMocmVhZEtleSkpKTsKKworICAgIHNjYW5uZXIuc2Vla1RvKG5ldyBieXRlWzBdKTsKKyAgICBCeXRlQnVmZmVyIHZhbDEgPSBzY2FubmVyLmdldFZhbHVlKCk7CisgICAgc2Nhbm5lci5zZWVrVG8obmV3IGJ5dGVbMF0pOworICAgIEJ5dGVCdWZmZXIgdmFsMiA9IHNjYW5uZXIuZ2V0VmFsdWUoKTsKKyAgICBhc3NlcnRUcnVlKEFycmF5cy5lcXVhbHMoQnl0ZXMudG9CeXRlcyh2YWwxKSwgQnl0ZXMudG9CeXRlcyh2YWwyKSkpOworCisgICAgcmVhZGVyLmNsb3NlKCk7CisgICAgZmluLmNsb3NlKCk7CisgICAgZnMuZGVsZXRlKG5jVEZpbGUsIHRydWUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRGaWxlRmVhdHVyZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJhc2ljV2l0aFNvbWVDb2RlYygibm9uZSIpOworICAgIGJhc2ljV2l0aFNvbWVDb2RlYygiZ3oiKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB3cml0ZU51bU1ldGFibG9ja3MoV3JpdGVyIHdyaXRlciwgaW50IG4pIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgd3JpdGVyLmFwcGVuZE1ldGFCbG9jaygiSEZpbGVNZXRhIiArIGksICgic29tZXRoaW5nIHRvIHRlc3QiICsgaSkuZ2V0Qnl0ZXMoKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNvbWVUZXN0aW5nV2l0aE1ldGFCbG9jayhXcml0ZXIgd3JpdGVyKSB7CisgICAgd3JpdGVOdW1NZXRhYmxvY2tzKHdyaXRlciwgMTApOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlYWROdW1NZXRhYmxvY2tzKFJlYWRlciByZWFkZXIsIGludCBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICBCeXRlQnVmZmVyIGIgPSByZWFkZXIuZ2V0TWV0YUJsb2NrKCJIRmlsZU1ldGEiICsgaSk7CisgICAgICBieXRlIFtdIGZvdW5kID0gQnl0ZXMudG9CeXRlcyhiKTsKKyAgICAgIGFzc2VydFRydWUoImZhaWxlZCB0byBtYXRjaCBtZXRhZGF0YSIsIEFycmF5cy5lcXVhbHMoCisgICAgICAgICAgKCJzb21ldGhpbmcgdG8gdGVzdCIgKyBpKS5nZXRCeXRlcygpLCBmb3VuZCkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBzb21lUmVhZGluZ1dpdGhNZXRhQmxvY2soUmVhZGVyIHJlYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZWFkTnVtTWV0YWJsb2NrcyhyZWFkZXIsIDEwKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBtZXRhYmxvY2tzKGZpbmFsIFN0cmluZyBjb21wcmVzcykgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUGF0aCBtRmlsZSA9IG5ldyBQYXRoKFJPT1RfRElSLCAibWV0YS5oZmlsZSIpOworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBmb3V0ID0gY3JlYXRlRlNPdXRwdXQobUZpbGUpOworICAgIFdyaXRlciB3cml0ZXIgPSBuZXcgV3JpdGVyKGZvdXQsIG1pbkJsb2NrU2l6ZSwKKyAgICAgIENvbXByZXNzaW9uLmdldENvbXByZXNzaW9uQWxnb3JpdGhtQnlOYW1lKGNvbXByZXNzKSwgbnVsbCwgZmFsc2UpOworICAgIHNvbWVUZXN0aW5nV2l0aE1ldGFCbG9jayh3cml0ZXIpOworICAgIHdyaXRlci5jbG9zZSgpOworICAgIGZvdXQuY2xvc2UoKTsKKyAgICBGU0RhdGFJbnB1dFN0cmVhbSBmaW4gPSBmcy5vcGVuKG1GaWxlKTsKKyAgICBSZWFkZXIgcmVhZGVyID0gbmV3IFJlYWRlcihmcy5vcGVuKG1GaWxlKSwgdGhpcy5mcy5nZXRGaWxlU3RhdHVzKG1GaWxlKQorICAgICAgICAuZ2V0TGVuKCksIG51bGwpOworICAgIHJlYWRlci5sb2FkRmlsZUluZm8oKTsKKyAgICAvLyBObyBkYXRhIC0tIHRoaXMgc2hvdWxkIHJldHVybiBmYWxzZS4KKyAgICBhc3NlcnRGYWxzZShyZWFkZXIuZ2V0U2Nhbm5lcigpLnNlZWtUbygpKTsKKyAgICBzb21lUmVhZGluZ1dpdGhNZXRhQmxvY2socmVhZGVyKTsKKyAgICBmcy5kZWxldGUobUZpbGUsIHRydWUpOworICAgIHJlYWRlci5jbG9zZSgpOworICAgIGZpbi5jbG9zZSgpOworICB9CisKKyAgLy8gdGVzdCBtZXRhIGJsb2NrcyBmb3IgdGZpbGVzCisgIHB1YmxpYyB2b2lkIHRlc3RNZXRhQmxvY2tzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbWV0YWJsb2Nrcygibm9uZSIpOworICAgIG1ldGFibG9ja3MoImd6Iik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3ROdWxsTWV0YUJsb2NrcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFBhdGggbUZpbGUgPSBuZXcgUGF0aChST09UX0RJUiwgIm5vbWV0YS5oZmlsZSIpOworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBmb3V0ID0gY3JlYXRlRlNPdXRwdXQobUZpbGUpOworICAgIFdyaXRlciB3cml0ZXIgPSBuZXcgV3JpdGVyKGZvdXQsIG1pbkJsb2NrU2l6ZSwKKyAgICAgICAgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUsIG51bGwsIGZhbHNlKTsKKyAgICB3cml0ZXIuYXBwZW5kKCJmb28iLmdldEJ5dGVzKCksICJ2YWx1ZSIuZ2V0Qnl0ZXMoKSk7CisgICAgd3JpdGVyLmNsb3NlKCk7CisgICAgZm91dC5jbG9zZSgpOworICAgIFJlYWRlciByZWFkZXIgPSBuZXcgUmVhZGVyKGZzLCBtRmlsZSwgbnVsbCk7CisgICAgcmVhZGVyLmxvYWRGaWxlSW5mbygpOworICAgIGFzc2VydE51bGwocmVhZGVyLmdldE1ldGFCbG9jaygibm9uLWV4aXN0YW50IikpOworICB9CisgIAorICAvKioKKyAgICogTWFrZSBzdXJlIHRoZSBvcmdpbmFscyBmb3Igb3VyIGNvbXByZXNzaW9uIGxpYnMgZG9lc24ndCBjaGFuZ2Ugb24gdXMuCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcHJlc3Npb25PcmRpbmFuY2UoKSB7CisgICAgLy9hc3NlcnRUcnVlKENvbXByZXNzaW9uLkFsZ29yaXRobS5MWk8ub3JkaW5hbCgpID09IDApOworICAgIGFzc2VydFRydWUoQ29tcHJlc3Npb24uQWxnb3JpdGhtLkdaLm9yZGluYWwoKSA9PSAxKTsKKyAgICBhc3NlcnRUcnVlKENvbXByZXNzaW9uLkFsZ29yaXRobS5OT05FLm9yZGluYWwoKSA9PSAyKTsKKyAgfQorICAKKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RDb21wYXJhdG9yKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBQYXRoIG1GaWxlID0gbmV3IFBhdGgoUk9PVF9ESVIsICJtZXRhLnRmaWxlIik7CisgICAgRlNEYXRhT3V0cHV0U3RyZWFtIGZvdXQgPSBjcmVhdGVGU091dHB1dChtRmlsZSk7CisgICAgV3JpdGVyIHdyaXRlciA9IG5ldyBXcml0ZXIoZm91dCwgbWluQmxvY2tTaXplLCBudWxsLAorICAgICAgbmV3IFJhd0NvbXBhcmF0b3I8Ynl0ZSBbXT4oKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoYnl0ZVtdIGIxLCBpbnQgczEsIGludCBsMSwgYnl0ZVtdIGIyLCBpbnQgczIsCisgICAgICAgICAgICBpbnQgbDIpIHsKKyAgICAgICAgICByZXR1cm4gLUJ5dGVzLmNvbXBhcmVUbyhiMSwgczEsIGwxLCBiMiwgczIsIGwyKTsKKyAgICAgICAgICAKKyAgICAgICAgfQorICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCBjb21wYXJlKGJ5dGVbXSBvMSwgYnl0ZVtdIG8yKSB7CisgICAgICAgICAgcmV0dXJuIGNvbXBhcmUobzEsIDAsIG8xLmxlbmd0aCwgbzIsIDAsIG8yLmxlbmd0aCk7CisgICAgICAgIH0KKyAgICAgIH0sIGZhbHNlKTsKKyAgICB3cml0ZXIuYXBwZW5kKCIzIi5nZXRCeXRlcygpLCAiMCIuZ2V0Qnl0ZXMoKSk7CisgICAgd3JpdGVyLmFwcGVuZCgiMiIuZ2V0Qnl0ZXMoKSwgIjAiLmdldEJ5dGVzKCkpOworICAgIHdyaXRlci5hcHBlbmQoIjEiLmdldEJ5dGVzKCksICIwIi5nZXRCeXRlcygpKTsKKyAgICB3cml0ZXIuY2xvc2UoKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1Rlc3RIRmlsZVBlcmZvcm1hbmNlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0SEZpbGVQZXJmb3JtYW5jZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJhZTg4MjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0SEZpbGVQZXJmb3JtYW5jZS5qYXZhCkBAIC0wLDAgKzEsMzg0IEBACisvKioKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uaGZpbGU7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CitpbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLkJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uU2VxdWVuY2VGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLmNvbXByZXNzLkNvbXByZXNzaW9uQ29kZWM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uY29tcHJlc3MuR3ppcENvZGVjOworCisvKioKKyAqICBTZXQgb2YgbG9uZy1ydW5uaW5nIHRlc3RzIHRvIG1lYXN1cmUgcGVyZm9ybWFuY2Ugb2YgSEZpbGUuCisgKiA8cD4KKyAqIENvcGllZCBmcm9tCisgKiA8YSBocmVmPSJodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0hBRE9PUC0zMzE1Ij5oYWRvb3AtMzMxNSB0ZmlsZTwvYT4uCisgKiBSZW1vdmUgYWZ0ZXIgdGZpbGUgaXMgY29tbWl0dGVkIGFuZCB1c2UgdGhlIHRmaWxlIHZlcnNpb24gb2YgdGhpcyBjbGFzcworICogaW5zdGVhZC48L3A+CisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0SEZpbGVQZXJmb3JtYW5jZSBleHRlbmRzIFRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFJPT1RfRElSID0KKyAgICAgIFN5c3RlbS5nZXRQcm9wZXJ0eSgidGVzdC5idWlsZC5kYXRhIiwgIi90bXAvVGVzdEhGaWxlUGVyZm9ybWFuY2UiKTsKKyAgcHJpdmF0ZSBGaWxlU3lzdGVtIGZzOworICBwcml2YXRlIENvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBsb25nIHN0YXJ0VGltZUVwb2NoOworICBwcml2YXRlIGxvbmcgZmluaXNoVGltZUVwb2NoOworICBwcml2YXRlIERhdGVGb3JtYXQgZm9ybWF0dGVyOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29uZiA9IG5ldyBDb25maWd1cmF0aW9uKCk7CisgICAgZnMgPSBGaWxlU3lzdGVtLmdldChjb25mKTsKKyAgICBmb3JtYXR0ZXIgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgieXl5eS1NTS1kZCBISDptbTpzcyIpOworICB9CisKKyAgcHVibGljIHZvaWQgc3RhcnRUaW1lKCkgeworICAgIHN0YXJ0VGltZUVwb2NoID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdFRpbWUoKSArICIgU3RhcnRlZCB0aW1pbmcuIik7CisgIH0KKworICBwdWJsaWMgdm9pZCBzdG9wVGltZSgpIHsKKyAgICBmaW5pc2hUaW1lRXBvY2ggPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oZm9ybWF0VGltZSgpICsgIiBTdG9wcGVkIHRpbWluZy4iKTsKKyAgfQorCisgIHB1YmxpYyBsb25nIGdldEludGVydmFsTWlsbGlzKCkgeworICAgIHJldHVybiBmaW5pc2hUaW1lRXBvY2ggLSBzdGFydFRpbWVFcG9jaDsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHByaW50bG5XaXRoVGltZXN0YW1wKFN0cmluZyBtZXNzYWdlKSB7CisgICAgU3lzdGVtLm91dC5wcmludGxuKGZvcm1hdFRpbWUoKSArICIgICIgKyAgbWVzc2FnZSk7CisgIH0KKworICAvKgorICAgKiBGb3JtYXQgbWlsbGlzIGludG8gbWludXRlcyBhbmQgc2Vjb25kcy4KKyAgICovCisgIHB1YmxpYyBTdHJpbmcgZm9ybWF0VGltZShsb25nIG1pbGlzKXsKKyAgICByZXR1cm4gZm9ybWF0dGVyLmZvcm1hdChtaWxpcyk7CisgIH0KKworICBwdWJsaWMgU3RyaW5nIGZvcm1hdFRpbWUoKXsKKyAgICByZXR1cm4gZm9ybWF0VGltZShTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgIH0KKworICBwcml2YXRlIEZTRGF0YU91dHB1dFN0cmVhbSBjcmVhdGVGU091dHB1dChQYXRoIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGZzLmV4aXN0cyhuYW1lKSkKKyAgICAgIGZzLmRlbGV0ZShuYW1lLCB0cnVlKTsKKyAgICBGU0RhdGFPdXRwdXRTdHJlYW0gZm91dCA9IGZzLmNyZWF0ZShuYW1lKTsKKyAgICByZXR1cm4gZm91dDsKKyAgfQorCisgIC8vVE9ETyBoYXZlIG11bHRpcGxlIHdheXMgb2YgZ2VuZXJhdGluZyBrZXkvdmFsdWUgZS5nLiBkaWN0aW9uYXJ5IHdvcmRzCisgIC8vVE9ETyB0byBoYXZlIGEgc2FtcGxlIGNvbXByZXNzYWJsZSBkYXRhLCBmb3Igbm93LCBtYWRlIDEgb3V0IG9mIDMgdmFsdWVzIHJhbmRvbQorICAvLyAgICAga2V5cyBhcmUgYWxsIHJhbmRvbS4KKworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBLZXlWYWx1ZUdlbmVyYXRvciB7CisgICAgUmFuZG9tIGtleVJhbmRvbWl6ZXI7CisgICAgUmFuZG9tIHZhbHVlUmFuZG9taXplcjsKKyAgICBsb25nIHJhbmRvbVZhbHVlUmF0aW8gPSAzOyAvLyAxIG91dCBvZiByYW5kb21WYWx1ZVJhdGlvIGdlbmVyYXRlZCB2YWx1ZXMgd2lsbCBiZSByYW5kb20uCisgICAgbG9uZyB2YWx1ZVNlcXVlbmNlID0gMCA7CisKKworICAgIEtleVZhbHVlR2VuZXJhdG9yKCkgeworICAgICAga2V5UmFuZG9taXplciA9IG5ldyBSYW5kb20oMEwpOyAvL1RPRE8gd2l0aCBzZWVkIHplcm8KKyAgICAgIHZhbHVlUmFuZG9taXplciA9IG5ldyBSYW5kb20oMUwpOyAvL1RPRE8gd2l0aCBzZWVkIG9uZQorICAgIH0KKworICAgIC8vIEtleSBpcyBhbHdheXMgcmFuZG9tIG5vdy4KKyAgICB2b2lkIGdldEtleShieXRlW10ga2V5KSB7CisgICAgICBrZXlSYW5kb21pemVyLm5leHRCeXRlcyhrZXkpOworICAgIH0KKworICAgIHZvaWQgZ2V0VmFsdWUoYnl0ZVtdIHZhbHVlKSB7CisgICAgICBpZiAodmFsdWVTZXF1ZW5jZSAlIHJhbmRvbVZhbHVlUmF0aW8gPT0gMCkKKyAgICAgICAgICB2YWx1ZVJhbmRvbWl6ZXIubmV4dEJ5dGVzKHZhbHVlKTsKKyAgICAgIHZhbHVlU2VxdWVuY2UrKzsKKyAgICB9CisgIH0KKworICAvKioKKyAgICoKKyAgICogQHBhcmFtIGZpbGVUeXBlICJIRmlsZSIgb3IgIlNlcXVlbmNlRmlsZSIKKyAgICogQHBhcmFtIGtleUxlbmd0aAorICAgKiBAcGFyYW0gdmFsdWVMZW5ndGgKKyAgICogQHBhcmFtIGNvZGVjTmFtZSAibm9uZSIsICJsem8iLCAiZ3oiCisgICAqIEBwYXJhbSByb3dzIG51bWJlciBvZiByb3dzIHRvIGJlIHdyaXR0ZW4uCisgICAqIEBwYXJhbSB3cml0ZU1ldGhvZCB1c2VkIGZvciBIRmlsZSBvbmx5LgorICAgKiBAcGFyYW0gbWluQmxvY2tTaXplIHVzZWQgZm9yIEhGaWxlIG9ubHkuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgICAvL1RPRE8gd3JpdGVNZXRob2Q6IGltcGxlbWVudCBtdWx0aXBsZSB3YXlzIG9mIHdyaXRpbmcgZS5nLiBBKSBrbm93biBsZW5ndGggKG5vIGNodW5rKSBCKSB1c2luZyBhIGJ1ZmZlciBhbmQgc3RyZWFtaW5nIChmb3IgbWFueSBjaHVua3MpLgorICBwdWJsaWMgdm9pZCB0aW1lV3JpdGUoU3RyaW5nIGZpbGVUeXBlLCBpbnQga2V5TGVuZ3RoLCBpbnQgdmFsdWVMZW5ndGgsCisgICAgU3RyaW5nIGNvZGVjTmFtZSwgbG9uZyByb3dzLCBTdHJpbmcgd3JpdGVNZXRob2QsIGludCBtaW5CbG9ja1NpemUpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJGaWxlIFR5cGU6ICIgKyBmaWxlVHlwZSk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJXcml0aW5nICIgKyBmaWxlVHlwZSArICIgd2l0aCBjb2RlY05hbWU6ICIgKyBjb2RlY05hbWUpOworICAgIGxvbmcgdG90YWxCeXRlc1dyaXR0ZW4gPSAwOworCisKKyAgICAvL1VzaW5nIHNlcGFyYXRlIHJhbmRvbWl6ZXIgZm9yIGtleS92YWx1ZSB3aXRoIHNlZWRzIG1hdGNoaW5nIFNlcXVlbmNlIEZpbGUuCisgICAgYnl0ZVtdIGtleSA9IG5ldyBieXRlW2tleUxlbmd0aF07CisgICAgYnl0ZVtdIHZhbHVlID0gbmV3IGJ5dGVbdmFsdWVMZW5ndGhdOworICAgIEtleVZhbHVlR2VuZXJhdG9yIGdlbmVyYXRvciA9IG5ldyBLZXlWYWx1ZUdlbmVyYXRvcigpOworCisgICAgc3RhcnRUaW1lKCk7CisKKyAgICBQYXRoIHBhdGggPSBuZXcgUGF0aChST09UX0RJUiwgZmlsZVR5cGUgKyAiLlBlcmZvcm1hbmNlIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKFJPT1RfRElSICsgcGF0aC5nZXROYW1lKCkpOworICAgIEZTRGF0YU91dHB1dFN0cmVhbSBmb3V0ID0gIGNyZWF0ZUZTT3V0cHV0KHBhdGgpOworCisgICAgaWYgKCJIRmlsZSIuZXF1YWxzKGZpbGVUeXBlKSl7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSEZpbGUgd3JpdGUgbWV0aG9kOiAiKTsKKyAgICAgICAgSEZpbGUuV3JpdGVyIHdyaXRlciA9CisgICAgICAgICAgbmV3IEhGaWxlLldyaXRlcihmb3V0LCBtaW5CbG9ja1NpemUsIGNvZGVjTmFtZSwgbnVsbCk7CisKKyAgICAgICAgLy8gV3JpdGluZyB2YWx1ZSBpbiBvbmUgc2hvdC4KKyAgICAgICAgZm9yIChsb25nIGw9MCA7IGw8cm93cyA7IGwrKyApIHsKKyAgICAgICAgICBnZW5lcmF0b3IuZ2V0S2V5KGtleSk7CisgICAgICAgICAgZ2VuZXJhdG9yLmdldFZhbHVlKHZhbHVlKTsKKyAgICAgICAgICB3cml0ZXIuYXBwZW5kKGtleSwgdmFsdWUpOworICAgICAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IGtleS5sZW5ndGg7CisgICAgICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gdmFsdWUubGVuZ3RoOworICAgICAgICAgfQorICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICB9IGVsc2UgaWYgKCJTZXF1ZW5jZUZpbGUiLmVxdWFscyhmaWxlVHlwZSkpeworICAgICAgICBDb21wcmVzc2lvbkNvZGVjIGNvZGVjID0gbnVsbDsKKyAgICAgICAgaWYgKCJneiIuZXF1YWxzKGNvZGVjTmFtZSkpCisgICAgICAgICAgY29kZWMgPSBuZXcgR3ppcENvZGVjKCk7CisgICAgICAgIGVsc2UgaWYgKCEibm9uZSIuZXF1YWxzKGNvZGVjTmFtZSkpCisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb2RlYyBub3Qgc3VwcG9ydGVkLiIpOworCisgICAgICAgIFNlcXVlbmNlRmlsZS5Xcml0ZXIgd3JpdGVyOworCisgICAgICAgIC8vVE9ETworICAgICAgICAvL0pvYkNvbmYgY29uZiA9IG5ldyBKb2JDb25mKCk7CisKKyAgICAgICAgaWYgKCEibm9uZSIuZXF1YWxzKGNvZGVjTmFtZSkpCisgICAgICAgICAgd3JpdGVyID0gU2VxdWVuY2VGaWxlLmNyZWF0ZVdyaXRlcihjb25mLCBmb3V0LCBCeXRlc1dyaXRhYmxlLmNsYXNzLAorICAgICAgICAgICAgQnl0ZXNXcml0YWJsZS5jbGFzcywgU2VxdWVuY2VGaWxlLkNvbXByZXNzaW9uVHlwZS5CTE9DSywgY29kZWMpOworICAgICAgICBlbHNlCisgICAgICAgICAgd3JpdGVyID0gU2VxdWVuY2VGaWxlLmNyZWF0ZVdyaXRlcihjb25mLCBmb3V0LCBCeXRlc1dyaXRhYmxlLmNsYXNzLAorICAgICAgICAgICAgQnl0ZXNXcml0YWJsZS5jbGFzcywgU2VxdWVuY2VGaWxlLkNvbXByZXNzaW9uVHlwZS5OT05FLCBudWxsKTsKKworICAgICAgICBCeXRlc1dyaXRhYmxlIGtleUJzdzsKKyAgICAgICAgQnl0ZXNXcml0YWJsZSB2YWxCc3c7CisgICAgICAgIGZvciAobG9uZyBsPTAgOyBsPHJvd3MgOyBsKysgKSB7CisKKyAgICAgICAgICAgZ2VuZXJhdG9yLmdldEtleShrZXkpOworICAgICAgICAgICBrZXlCc3cgPSBuZXcgQnl0ZXNXcml0YWJsZShrZXkpOworICAgICAgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiArPSBrZXlCc3cuZ2V0U2l6ZSgpOworCisgICAgICAgICAgIGdlbmVyYXRvci5nZXRWYWx1ZSh2YWx1ZSk7CisgICAgICAgICAgIHZhbEJzdyA9IG5ldyBCeXRlc1dyaXRhYmxlKHZhbHVlKTsKKyAgICAgICAgICAgd3JpdGVyLmFwcGVuZChrZXlCc3csIHZhbEJzdyk7CisgICAgICAgICAgIHRvdGFsQnl0ZXNXcml0dGVuICs9IHZhbEJzdy5nZXRTaXplKCk7CisgICAgICAgIH0KKworICAgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICB9IGVsc2UKKyAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZpbGUgVHlwZSBpcyBub3Qgc3VwcG9ydGVkIik7CisKKyAgICBmb3V0LmNsb3NlKCk7CisgICAgc3RvcFRpbWUoKTsKKworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJEYXRhIHdyaXR0ZW46ICIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHJhdGUgID0gIiArCisgICAgICB0b3RhbEJ5dGVzV3JpdHRlbiAvIGdldEludGVydmFsTWlsbGlzKCkgKiAxMDAwIC8gMTAyNCAvIDEwMjQgKyAiTUIvcyIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHRvdGFsID0gIiArIHRvdGFsQnl0ZXNXcml0dGVuICsgIkIiKTsKKworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJGaWxlIHdyaXR0ZW46ICIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHJhdGUgID0gIiArCisgICAgICBmcy5nZXRGaWxlU3RhdHVzKHBhdGgpLmdldExlbigpIC8gZ2V0SW50ZXJ2YWxNaWxsaXMoKSAqIDEwMDAgLyAxMDI0IC8gMTAyNCArICJNQi9zIik7CisgICAgcHJpbnRsbldpdGhUaW1lc3RhbXAoIiAgdG90YWwgPSAiICsgZnMuZ2V0RmlsZVN0YXR1cyhwYXRoKS5nZXRMZW4oKSArICJCIik7CisgIH0KKworICBwdWJsaWMgdm9pZCB0aW1lUmVhZGluZyhTdHJpbmcgZmlsZVR5cGUsIGludCBrZXlMZW5ndGgsIGludCB2YWx1ZUxlbmd0aCwKKyAgICAgIGxvbmcgcm93cywgaW50IG1ldGhvZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlJlYWRpbmcgZmlsZSBvZiB0eXBlOiAiICsgZmlsZVR5cGUpOworICAgIFBhdGggcGF0aCA9IG5ldyBQYXRoKFJPT1RfRElSLCBmaWxlVHlwZSArICIuUGVyZm9ybWFuY2UiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIklucHV0IGZpbGUgc2l6ZTogIiArIGZzLmdldEZpbGVTdGF0dXMocGF0aCkuZ2V0TGVuKCkpOworICAgIGxvbmcgdG90YWxCeXRlc1JlYWQgPSAwOworCisKKyAgICBCeXRlQnVmZmVyIHZhbDsKKworICAgIEJ5dGVCdWZmZXIga2V5OworCisgICAgc3RhcnRUaW1lKCk7CisgICAgRlNEYXRhSW5wdXRTdHJlYW0gZmluID0gZnMub3BlbihwYXRoKTsKKworICAgIGlmICgiSEZpbGUiLmVxdWFscyhmaWxlVHlwZSkpeworICAgICAgICBIRmlsZS5SZWFkZXIgcmVhZGVyID0gbmV3IEhGaWxlLlJlYWRlcihmcy5vcGVuKHBhdGgpLAorICAgICAgICAgIGZzLmdldEZpbGVTdGF0dXMocGF0aCkuZ2V0TGVuKCksIG51bGwpOworICAgICAgICByZWFkZXIubG9hZEZpbGVJbmZvKCk7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZWFkZXIpOworICAgICAgICBzd2l0Y2ggKG1ldGhvZCkgeworICAgICAgICAKKyAgICAgICAgICBjYXNlIDA6CisgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIEhGaWxlU2Nhbm5lciBzY2FubmVyID0gcmVhZGVyLmdldFNjYW5uZXIoKTsKKyAgICAgICAgICAgICAgc2Nhbm5lci5zZWVrVG8oKTsKKyAgICAgICAgICAgICAgZm9yIChsb25nIGw9MCA7IGw8cm93cyA7IGwrKyApIHsKKyAgICAgICAgICAgICAgICBrZXkgPSBzY2FubmVyLmdldEtleSgpOworICAgICAgICAgICAgICAgIHZhbCA9IHNjYW5uZXIuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCArPSBrZXkubGltaXQoKSArIHZhbC5saW1pdCgpOworICAgICAgICAgICAgICAgIHNjYW5uZXIubmV4dCgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0gZWxzZSBpZigiU2VxdWVuY2VGaWxlIi5lcXVhbHMoZmlsZVR5cGUpKXsKKworICAgICAgICBTZXF1ZW5jZUZpbGUuUmVhZGVyIHJlYWRlcjsKKyAgICAgICAgcmVhZGVyID0gbmV3IFNlcXVlbmNlRmlsZS5SZWFkZXIoZnMsIHBhdGgsIG5ldyBDb25maWd1cmF0aW9uKCkpOworCisgICAgICAgIGlmIChyZWFkZXIuZ2V0Q29tcHJlc3Npb25Db2RlYygpICE9IG51bGwpIHsKKyAgICAgICAgICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJDb21wcmVzc2lvbiBjb2RlYyBjbGFzczogIiArIHJlYWRlci5nZXRDb21wcmVzc2lvbkNvZGVjKCkuZ2V0Q2xhc3MoKSk7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgcHJpbnRsbldpdGhUaW1lc3RhbXAoIkNvbXByZXNzaW9uIGNvZGVjIGNsYXNzOiAiICsgIm5vbmUiKTsKKworICAgICAgICBCeXRlc1dyaXRhYmxlIGtleUJzdyA9IG5ldyBCeXRlc1dyaXRhYmxlKCk7CisgICAgICAgIEJ5dGVzV3JpdGFibGUgdmFsQnN3ID0gbmV3IEJ5dGVzV3JpdGFibGUoKTsKKworICAgICAgICBmb3IgKGxvbmcgbD0wIDsgbDxyb3dzIDsgbCsrICkgeworICAgICAgICAgIHJlYWRlci5uZXh0KGtleUJzdywgdmFsQnN3KTsKKyAgICAgICAgICB0b3RhbEJ5dGVzUmVhZCArPSBrZXlCc3cuZ2V0U2l6ZSgpICsgdmFsQnN3LmdldFNpemUoKTsKKyAgICAgICAgfQorICAgICAgICByZWFkZXIuY2xvc2UoKTsKKworICAgICAgICAvL1RPRE8gbWFrZSBhIHRlc3RzIGZvciBvdGhlciB0eXBlcyBvZiBTZXF1ZW5jZUZpbGUgcmVhZGluZyBzY2VuYXJpb3MKKworICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmlsZSBUeXBlIG5vdCBzdXBwb3J0ZWQuIik7CisgICAgfQorCisKKyAgICAvL3ByaW50bG5XaXRoVGltZXN0YW1wKCJDbG9zaW5nIHJlYWRlciIpOworICAgIGZpbi5jbG9zZSgpOworICAgIHN0b3BUaW1lKCk7CisgICAgLy9wcmludGxuV2l0aFRpbWVzdGFtcCgiRmluaXNoZWQgY2xvc2UiKTsKKworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJGaW5pc2hlZCBpbiAiICsgZ2V0SW50ZXJ2YWxNaWxsaXMoKSArICJtcyIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJEYXRhIHJlYWQ6ICIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHJhdGUgID0gIiArCisgICAgICB0b3RhbEJ5dGVzUmVhZCAvIGdldEludGVydmFsTWlsbGlzKCkgKiAxMDAwIC8gMTAyNCAvIDEwMjQgKyAiTUIvcyIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHRvdGFsID0gIiArIHRvdGFsQnl0ZXNSZWFkICsgIkIiKTsKKworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCJGaWxlIHJlYWQ6ICIpOworICAgIHByaW50bG5XaXRoVGltZXN0YW1wKCIgIHJhdGUgID0gIiArCisgICAgICBmcy5nZXRGaWxlU3RhdHVzKHBhdGgpLmdldExlbigpIC8gZ2V0SW50ZXJ2YWxNaWxsaXMoKSAqIDEwMDAgLyAxMDI0IC8gMTAyNCArICJNQi9zIik7CisgICAgcHJpbnRsbldpdGhUaW1lc3RhbXAoIiAgdG90YWwgPSAiICsgZnMuZ2V0RmlsZVN0YXR1cyhwYXRoKS5nZXRMZW4oKSArICJCIik7CisKKyAgICAvL1RPRE8gdW5jb21tZW50IHRoaXMgZm9yIGZpbmFsIGNvbW1pdHRpbmcgc28gdGVzdCBmaWxlcyBpcyByZW1vdmVkLgorICAgIC8vZnMuZGVsZXRlKHBhdGgsIHRydWUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFJ1bkNvbXBhcmlzb25zKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIGludCBrZXlMZW5ndGggPSAxMDA7IC8vIDEwMEIKKyAgICBpbnQgdmFsdWVMZW5ndGggPSA1KjEwMjQ7IC8vIDVLQgorICAgIGludCBtaW5CbG9ja1NpemUgPSAxMCoxMDI0KjEwMjQ7IC8vIDEwTUIKKyAgICBpbnQgcm93cyA9IDEwMDAwOworCisgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogU2VxdWVuY2UgRmlsZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOworCisgICAgdGltZVdyaXRlKCJTZXF1ZW5jZUZpbGUiLCBrZXlMZW5ndGgsIHZhbHVlTGVuZ3RoLCAibm9uZSIsIHJvd3MsIG51bGwsIG1pbkJsb2NrU2l6ZSk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbisrKysrKytcbiIpOworICAgIHRpbWVSZWFkaW5nKCJTZXF1ZW5jZUZpbGUiLCBrZXlMZW5ndGgsIHZhbHVlTGVuZ3RoLCByb3dzLCAtMSk7CisKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7CisKKyAgICAvKiBESVNBQkxFRCBMWk8KKyAgICB0aW1lV3JpdGUoIlNlcXVlbmNlRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsICJsem8iLCByb3dzLCBudWxsLCBtaW5CbG9ja1NpemUpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG4rKysrKysrXG4iKTsKKyAgICB0aW1lUmVhZGluZygiU2VxdWVuY2VGaWxlIiwga2V5TGVuZ3RoLCB2YWx1ZUxlbmd0aCwgcm93cywgLTEpOworCisgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiIpOworCisgICAgLyogU2VxdWVuY2UgZmlsZSBjYW4gb25seSB1c2UgbmF0aXZlIGhhZG9vcCBsaWJzIGd6aXBwaW5nIHNvIGNvbW1lbnRpbmcgb3V0LgorICAgICAqLworICAgIHRyeSB7CisgICAgICB0aW1lV3JpdGUoIlNlcXVlbmNlRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsICJneiIsIHJvd3MsIG51bGwsCisgICAgICAgIG1pbkJsb2NrU2l6ZSk7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuKysrKysrK1xuIik7CisgICAgICB0aW1lUmVhZGluZygiU2VxdWVuY2VGaWxlIiwga2V5TGVuZ3RoLCB2YWx1ZUxlbmd0aCwgcm93cywgLTEpOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNraXBwaW5nIHNlcXVlbmNlZmlsZSBnejogIiArIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisKKworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cblxuIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogSEZpbGUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKKworICAgIHRpbWVXcml0ZSgiSEZpbGUiLCBrZXlMZW5ndGgsIHZhbHVlTGVuZ3RoLCAibm9uZSIsIHJvd3MsIG51bGwsIG1pbkJsb2NrU2l6ZSk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbisrKysrKytcbiIpOworICAgIHRpbWVSZWFkaW5nKCJIRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsIHJvd3MsIDAgKTsKKworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKy8qIERJU0FCTEVEIExaTworICAgIHRpbWVXcml0ZSgiSEZpbGUiLCBrZXlMZW5ndGgsIHZhbHVlTGVuZ3RoLCAibHpvIiwgcm93cywgbnVsbCwgbWluQmxvY2tTaXplKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuKysrKysrK1xuIik7CisgICAgdGltZVJlYWRpbmcoIkhGaWxlIiwga2V5TGVuZ3RoLCB2YWx1ZUxlbmd0aCwgcm93cywgMCApOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG4rKysrKysrXG4iKTsKKyAgICB0aW1lUmVhZGluZygiSEZpbGUiLCBrZXlMZW5ndGgsIHZhbHVlTGVuZ3RoLCByb3dzLCAxICk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbisrKysrKytcbiIpOworICAgIHRpbWVSZWFkaW5nKCJIRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsIHJvd3MsIDIgKTsKKworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIiKTsKKyovCisgICAgdGltZVdyaXRlKCJIRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsICJneiIsIHJvd3MsIG51bGwsIG1pbkJsb2NrU2l6ZSk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbisrKysrKytcbiIpOworICAgIHRpbWVSZWFkaW5nKCJIRmlsZSIsIGtleUxlbmd0aCwgdmFsdWVMZW5ndGgsIHJvd3MsIDAgKTsKKworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cblxuXG5Ob3RlczogIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIgKiBUaW1pbmcgaW5jbHVkZXMgb3Blbi9jbG9zaW5nIG9mIGZpbGVzLiIpOworICAgIFN5c3RlbS5vdXQucHJpbnRsbigiICogVGltaW5nIGluY2x1ZGVzIHJlYWRpbmcgYm90aCBLZXkgYW5kIFZhbHVlIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIgKiBEYXRhIGlzIGdlbmVyYXRlZCBhcyByYW5kb20gYnl0ZXMuIE90aGVyIG1ldGhvZHMgZS5nLiB1c2luZyAiICsKKyAgICAgICAgICAgICJkaWN0aW9uYXJ5IHdpdGggY2FyZSBmb3IgZGlzdHJpYnV0YXRpb24gb2Ygd29yZHMgaXMgdW5kZXIgZGV2ZWxvcG1lbnQuIik7CisgICAgU3lzdGVtLm91dC5wcmludGxuKCIgKiBUaW1pbmcgb2Ygd3JpdGUgY3VycmVudGx5LCBpbmNsdWRlcyByYW5kb20gdmFsdWUva2V5IGdlbmVyYXRpb25zLiAiICsKKyAgICAgICAgICAgICJXaGljaCBpcyB0aGUgc2FtZSBmb3IgU2VxdWVuY2UgRmlsZSBhbmQgSEZpbGUuIEFub3RoZXIgcG9zc2liaWxpdHkgaXMgdG8gZ2VuZXJhdGUgIiArCisgICAgICAgICAgICAidGVzdCBkYXRhIGJlZm9yZWhhbmQiKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiAqIFdlIG5lZWQgdG8gbWl0aWdhdGUgY2FjaGUgZWZmZWN0IG9uIGJlbmNobWFyay4gV2UgY2FuIGFwcGx5IHNldmVyYWwgIiArCisgICAgICAgICAgICAiaWRlYXMsIGZvciBuZXh0IHN0ZXAgd2UgZG8gYSBsYXJnZSBkdW1teSByZWFkIGJldHdlZW4gYmVuY2htYXJrIHJlYWQgdG8gZGlzbWFudGxlICIgKworICAgICAgICAgICAgImNhY2hpbmcgb2YgZGF0YS4gUmVuYW1pbmcgb2YgZmlsZSBtYXkgYmUgaGVscGZ1bC4gV2UgY2FuIGhhdmUgYSBsb29wIHRoYXQgcmVhZHMgd2l0aCIgKworICAgICAgICAgICAgIiB0aGUgc2FtZSBtZXRob2Qgc2V2ZXJhbCB0aW1lcyBhbmQgZmxvb2QgY2FjaGUgZXZlcnkgdGltZSBhbmQgYXZlcmFnZSBpdCB0byBnZXQgYSIgKworICAgICAgICAgICAgIiBiZXR0ZXIgbnVtYmVyLiIpOworICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvVGVzdEhGaWxlU2Vlay5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvaW8vaGZpbGUvVGVzdEhGaWxlU2Vlay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNDRhOTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0SEZpbGVTZWVrLmphdmEKQEAgLTAsMCArMSw1MDAgQEAKKy8qKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzCisgKiB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGCisgKiBsaWNlbnNlcyB0aGlzIGZpbGUgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICogCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUCisgKiBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUKKyAqIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCisgKiB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CitpbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKKworaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jbGkuQ29tbWFuZExpbmU7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNsaS5Db21tYW5kTGluZVBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY2xpLkdudVBhcnNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY2xpLkhlbHBGb3JtYXR0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNsaS5PcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNsaS5PcHRpb25CdWlsZGVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5jbGkuT3B0aW9uczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuY2xpLlBhcnNlRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmNvbmYuQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFJbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GU0RhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlLlJlYWRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZS5Xcml0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uQnl0ZXNXcml0YWJsZTsKKworLyoqCisgKiB0ZXN0IHRoZSBwZXJmb3JtYW5jZSBmb3Igc2Vlay4KKyAqIDxwPgorICogQ29waWVkIGZyb20KKyAqIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEFET09QLTMzMTUiPmhhZG9vcC0zMzE1IHRmaWxlPC9hPi4KKyAqIFJlbW92ZSBhZnRlciB0ZmlsZSBpcyBjb21taXR0ZWQgYW5kIHVzZSB0aGUgdGZpbGUgdmVyc2lvbiBvZiB0aGlzIGNsYXNzCisgKiBpbnN0ZWFkLjwvcD4KKyAqLworcHVibGljIGNsYXNzIFRlc3RIRmlsZVNlZWsgZXh0ZW5kcyBUZXN0Q2FzZSB7IAorICBwcml2YXRlIE15T3B0aW9ucyBvcHRpb25zOworICBwcml2YXRlIENvbmZpZ3VyYXRpb24gY29uZjsKKyAgcHJpdmF0ZSBQYXRoIHBhdGg7CisgIHByaXZhdGUgRmlsZVN5c3RlbSBmczsKKyAgcHJpdmF0ZSBOYW5vVGltZXIgdGltZXI7CisgIHByaXZhdGUgUmFuZG9tIHJuZzsKKyAgcHJpdmF0ZSBSYW5kb21EaXN0cmlidXRpb24uRGlzY3JldGVSTkcga2V5TGVuR2VuOworICBwcml2YXRlIEtWR2VuZXJhdG9yIGt2R2VuOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKG9wdGlvbnMgPT0gbnVsbCkgeworICAgICAgb3B0aW9ucyA9IG5ldyBNeU9wdGlvbnMobmV3IFN0cmluZ1swXSk7CisgICAgfQorCisgICAgY29uZiA9IG5ldyBDb25maWd1cmF0aW9uKCk7CisgICAgY29uZi5zZXRJbnQoInRmaWxlLmZzLmlucHV0LmJ1ZmZlci5zaXplIiwgb3B0aW9ucy5mc0lucHV0QnVmZmVyU2l6ZSk7CisgICAgY29uZi5zZXRJbnQoInRmaWxlLmZzLm91dHB1dC5idWZmZXIuc2l6ZSIsIG9wdGlvbnMuZnNPdXRwdXRCdWZmZXJTaXplKTsKKyAgICBwYXRoID0gbmV3IFBhdGgobmV3IFBhdGgob3B0aW9ucy5yb290RGlyKSwgb3B0aW9ucy5maWxlKTsKKyAgICBmcyA9IHBhdGguZ2V0RmlsZVN5c3RlbShjb25mKTsKKyAgICB0aW1lciA9IG5ldyBOYW5vVGltZXIoZmFsc2UpOworICAgIHJuZyA9IG5ldyBSYW5kb20ob3B0aW9ucy5zZWVkKTsKKyAgICBrZXlMZW5HZW4gPQorICAgICAgICBuZXcgUmFuZG9tRGlzdHJpYnV0aW9uLlppcGYobmV3IFJhbmRvbShybmcubmV4dExvbmcoKSksCisgICAgICAgICAgICBvcHRpb25zLm1pbktleUxlbiwgb3B0aW9ucy5tYXhLZXlMZW4sIDEuMik7CisgICAgUmFuZG9tRGlzdHJpYnV0aW9uLkRpc2NyZXRlUk5HIHZhbExlbkdlbiA9CisgICAgICAgIG5ldyBSYW5kb21EaXN0cmlidXRpb24uRmxhdChuZXcgUmFuZG9tKHJuZy5uZXh0TG9uZygpKSwKKyAgICAgICAgICAgIG9wdGlvbnMubWluVmFsTGVuZ3RoLCBvcHRpb25zLm1heFZhbExlbmd0aCk7CisgICAgUmFuZG9tRGlzdHJpYnV0aW9uLkRpc2NyZXRlUk5HIHdvcmRMZW5HZW4gPQorICAgICAgICBuZXcgUmFuZG9tRGlzdHJpYnV0aW9uLkZsYXQobmV3IFJhbmRvbShybmcubmV4dExvbmcoKSksCisgICAgICAgICAgICBvcHRpb25zLm1pbldvcmRMZW4sIG9wdGlvbnMubWF4V29yZExlbik7CisgICAga3ZHZW4gPQorICAgICAgICBuZXcgS1ZHZW5lcmF0b3Iocm5nLCB0cnVlLCBrZXlMZW5HZW4sIHZhbExlbkdlbiwgd29yZExlbkdlbiwKKyAgICAgICAgICAgIG9wdGlvbnMuZGljdFNpemUpOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB7CisgICAgdHJ5IHsKKyAgICAgIGZzLmNsb3NlKCk7CisgICAgfQorICAgIGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgLy8gTm90aGluZworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgRlNEYXRhT3V0cHV0U3RyZWFtIGNyZWF0ZUZTT3V0cHV0KFBhdGggbmFtZSwgRmlsZVN5c3RlbSBmcykKKyAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmcy5leGlzdHMobmFtZSkpIHsKKyAgICAgIGZzLmRlbGV0ZShuYW1lLCB0cnVlKTsKKyAgICB9CisgICAgRlNEYXRhT3V0cHV0U3RyZWFtIGZvdXQgPSBmcy5jcmVhdGUobmFtZSk7CisgICAgcmV0dXJuIGZvdXQ7CisgIH0KKworICBwcml2YXRlIHZvaWQgY3JlYXRlVEZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGxvbmcgdG90YWxCeXRlcyA9IDA7CisgICAgRlNEYXRhT3V0cHV0U3RyZWFtIGZvdXQgPSBjcmVhdGVGU091dHB1dChwYXRoLCBmcyk7CisgICAgdHJ5IHsKKyAgICAgIFdyaXRlciB3cml0ZXIgPQorICAgICAgICAgIG5ldyBXcml0ZXIoZm91dCwgb3B0aW9ucy5taW5CbG9ja1NpemUsIG9wdGlvbnMuY29tcHJlc3MsIG51bGwpOworICAgICAgdHJ5IHsKKyAgICAgICAgQnl0ZXNXcml0YWJsZSBrZXkgPSBuZXcgQnl0ZXNXcml0YWJsZSgpOworICAgICAgICBCeXRlc1dyaXRhYmxlIHZhbCA9IG5ldyBCeXRlc1dyaXRhYmxlKCk7CisgICAgICAgIHRpbWVyLnN0YXJ0KCk7CisgICAgICAgIGZvciAobG9uZyBpID0gMDsgdHJ1ZTsgKytpKSB7CisgICAgICAgICAgaWYgKGkgJSAxMDAwID09IDApIHsgLy8gdGVzdCB0aGUgc2l6ZSBmb3IgZXZlcnkgMTAwMCByb3dzLgorICAgICAgICAgICAgaWYgKGZzLmdldEZpbGVTdGF0dXMocGF0aCkuZ2V0TGVuKCkgPj0gb3B0aW9ucy5maWxlU2l6ZSkgeworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAga3ZHZW4ubmV4dChrZXksIHZhbCwgZmFsc2UpOworICAgICAgICAgIGJ5dGUgW10gayA9IG5ldyBieXRlIFtrZXkuZ2V0U2l6ZSgpXTsKKyAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleS5nZXQoKSwgMCwgaywgMCwga2V5LmdldFNpemUoKSk7CisgICAgICAgICAgYnl0ZSBbXSB2ID0gbmV3IGJ5dGUgW3ZhbC5nZXRTaXplKCldOworICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodmFsLmdldCgpLCAwLCB2LCAwLCBrZXkuZ2V0U2l6ZSgpKTsKKyAgICAgICAgICB3cml0ZXIuYXBwZW5kKGssIHYpOworICAgICAgICAgIHRvdGFsQnl0ZXMgKz0ga2V5LmdldFNpemUoKTsKKyAgICAgICAgICB0b3RhbEJ5dGVzICs9IHZhbC5nZXRTaXplKCk7CisgICAgICAgIH0KKyAgICAgICAgdGltZXIuc3RvcCgpOworICAgICAgfQorICAgICAgZmluYWxseSB7CisgICAgICAgIHdyaXRlci5jbG9zZSgpOworICAgICAgfQorICAgIH0KKyAgICBmaW5hbGx5IHsKKyAgICAgIGZvdXQuY2xvc2UoKTsKKyAgICB9CisgICAgZG91YmxlIGR1cmF0aW9uID0gKGRvdWJsZSl0aW1lci5yZWFkKCkvMTAwMDsgLy8gaW4gdXMuCisgICAgbG9uZyBmc2l6ZSA9IGZzLmdldEZpbGVTdGF0dXMocGF0aCkuZ2V0TGVuKCk7CisKKyAgICBTeXN0ZW0ub3V0LnByaW50ZigKKyAgICAgICAgInRpbWU6ICVzLi4udW5jb21wcmVzc2VkOiAlLjJmTUIuLi5yYXcgdGhycHQ6ICUuMmZNQi9zXG4iLAorICAgICAgICB0aW1lci50b1N0cmluZygpLCAoZG91YmxlKSB0b3RhbEJ5dGVzIC8gMTAyNCAvIDEwMjQsIHRvdGFsQnl0ZXMKKyAgICAgICAgICAgIC8gZHVyYXRpb24pOworICAgIFN5c3RlbS5vdXQucHJpbnRmKCJ0aW1lOiAlcy4uLmZpbGUgc2l6ZTogJS4yZk1CLi4uZGlzayB0aHJwdDogJS4yZk1CL3NcbiIsCisgICAgICAgIHRpbWVyLnRvU3RyaW5nKCksIChkb3VibGUpIGZzaXplIC8gMTAyNCAvIDEwMjQsIGZzaXplIC8gZHVyYXRpb24pOworICB9CisgIAorICBwdWJsaWMgdm9pZCBzZWVrVEZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCBtaXNzID0gMDsKKyAgICBsb25nIHRvdGFsQnl0ZXMgPSAwOworICAgIEZTRGF0YUlucHV0U3RyZWFtIGZzZGlzID0gZnMub3BlbihwYXRoKTsKKyAgICBSZWFkZXIgcmVhZGVyID0KKyAgICAgIG5ldyBSZWFkZXIoZnNkaXMsIGZzLmdldEZpbGVTdGF0dXMocGF0aCkuZ2V0TGVuKCksIG51bGwpOworICAgIHJlYWRlci5sb2FkRmlsZUluZm8oKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4ocmVhZGVyKTsKKyAgICBLZXlTYW1wbGVyIGtTYW1wbGVyID0KKyAgICAgICAgbmV3IEtleVNhbXBsZXIocm5nLCByZWFkZXIuZ2V0Rmlyc3RLZXkoKSwgcmVhZGVyLmdldExhc3RLZXkoKSwKKyAgICAgICAgICAgIGtleUxlbkdlbik7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSByZWFkZXIuZ2V0U2Nhbm5lcigpOworICAgIEJ5dGVzV3JpdGFibGUga2V5ID0gbmV3IEJ5dGVzV3JpdGFibGUoKTsKKyAgICB0aW1lci5yZXNldCgpOworICAgIHRpbWVyLnN0YXJ0KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnNlZWtDb3VudDsgKytpKSB7CisgICAgICBrU2FtcGxlci5uZXh0KGtleSk7CisgICAgICBieXRlIFtdIGsgPSBuZXcgYnl0ZSBba2V5LmdldFNpemUoKV07CisgICAgICBTeXN0ZW0uYXJyYXljb3B5KGtleS5nZXQoKSwgMCwgaywgMCwga2V5LmdldFNpemUoKSk7CisgICAgICBpZiAoc2Nhbm5lci5zZWVrVG8oaykgPj0gMCkgeworICAgICAgICBCeXRlQnVmZmVyIGJia2V5ID0gc2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgICAgQnl0ZUJ1ZmZlciBiYnZhbCA9IHNjYW5uZXIuZ2V0VmFsdWUoKTsKKyAgICAgICAgdG90YWxCeXRlcyArPSBiYmtleS5saW1pdCgpOworICAgICAgICB0b3RhbEJ5dGVzICs9IGJidmFsLmxpbWl0KCk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgKyttaXNzOworICAgICAgfQorICAgIH0KKyAgICB0aW1lci5zdG9wKCk7CisgICAgU3lzdGVtLm91dC5wcmludGYoCisgICAgICAgICJ0aW1lOiAlcy4uLmF2ZyBzZWVrOiAlcy4uLiVkIGhpdC4uLiVkIG1pc3MuLi5hdmcgSS9PIHNpemU6ICUuMmZLQlxuIiwKKyAgICAgICAgdGltZXIudG9TdHJpbmcoKSwgTmFub1RpbWVyLm5hbm9UaW1lVG9TdHJpbmcodGltZXIucmVhZCgpCisgICAgICAgICAgICAvIG9wdGlvbnMuc2Vla0NvdW50KSwgb3B0aW9ucy5zZWVrQ291bnQgLSBtaXNzLCBtaXNzLAorICAgICAgICAoZG91YmxlKSB0b3RhbEJ5dGVzIC8gMTAyNCAvIChvcHRpb25zLnNlZWtDb3VudCAtIG1pc3MpKTsKKworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0U2Vla3MoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChvcHRpb25zLmRvQ3JlYXRlKCkpIHsKKyAgICAgIGNyZWF0ZVRGaWxlKCk7CisgICAgfQorCisgICAgaWYgKG9wdGlvbnMuZG9SZWFkKCkpIHsKKyAgICAgIHNlZWtURmlsZSgpOworICAgIH0KKworICAgIGlmIChvcHRpb25zLmRvQ3JlYXRlKCkpIHsKKyAgICAgIGZzLmRlbGV0ZShwYXRoLCB0cnVlKTsKKyAgICB9CisgIH0KKyAgCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEludGVnZXJSYW5nZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZnJvbSwgdG87CisKKyAgICBwdWJsaWMgSW50ZWdlclJhbmdlKGludCBmcm9tLCBpbnQgdG8pIHsKKyAgICAgIHRoaXMuZnJvbSA9IGZyb207CisgICAgICB0aGlzLnRvID0gdG87CisgICAgfQorCisgICAgcHVibGljIHN0YXRpYyBJbnRlZ2VyUmFuZ2UgcGFyc2UoU3RyaW5nIHMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICBTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKHMsICIgXHQsIik7CisgICAgICBpZiAoc3QuY291bnRUb2tlbnMoKSAhPSAyKSB7CisgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiQmFkIGludGVnZXIgc3BlY2lmaWNhdGlvbjogIiArIHMpOworICAgICAgfQorICAgICAgaW50IGZyb20gPSBJbnRlZ2VyLnBhcnNlSW50KHN0Lm5leHRUb2tlbigpKTsKKyAgICAgIGludCB0byA9IEludGVnZXIucGFyc2VJbnQoc3QubmV4dFRva2VuKCkpOworICAgICAgcmV0dXJuIG5ldyBJbnRlZ2VyUmFuZ2UoZnJvbSwgdG8pOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZnJvbSgpIHsKKyAgICAgIHJldHVybiBmcm9tOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgdG8oKSB7CisgICAgICByZXR1cm4gdG87CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTXlPcHRpb25zIHsKKyAgICAvLyBoYXJkIGNvZGVkIGNvbnN0YW50cworICAgIGludCBkaWN0U2l6ZSA9IDEwMDA7CisgICAgaW50IG1pbldvcmRMZW4gPSA1OworICAgIGludCBtYXhXb3JkTGVuID0gMjA7CisgICAKKyAgICBTdHJpbmcgcm9vdERpciA9CisgICAgICAgIFN5c3RlbS5nZXRQcm9wZXJ0eSgidGVzdC5idWlsZC5kYXRhIiwgIi90bXAvVGVzdFRGaWxlU2VlayIpOworICAgIFN0cmluZyBmaWxlID0gIlRlc3RURmlsZVNlZWsiOworICAgIC8vIFN0cmluZyBjb21wcmVzcyA9ICJsem8iOyBESVNBQkxFRAorICAgIFN0cmluZyBjb21wcmVzcyA9ICJub25lIjsKKyAgICBpbnQgbWluS2V5TGVuID0gMTA7CisgICAgaW50IG1heEtleUxlbiA9IDUwOworICAgIGludCBtaW5WYWxMZW5ndGggPSAxMDI0OworICAgIGludCBtYXhWYWxMZW5ndGggPSAyICogMTAyNDsKKyAgICBpbnQgbWluQmxvY2tTaXplID0gMSAqIDEwMjQgKiAxMDI0OworICAgIGludCBmc091dHB1dEJ1ZmZlclNpemUgPSAxOworICAgIGludCBmc0lucHV0QnVmZmVyU2l6ZSA9IDA7CisgICAgLy8gRGVmYXVsdCB3cml0aW5nIDEwTUIuCisgICAgbG9uZyBmaWxlU2l6ZSA9IDEwICogMTAyNCAqIDEwMjQ7CisgICAgbG9uZyBzZWVrQ291bnQgPSAxMDAwOworICAgIGxvbmcgc2VlZDsKKworICAgIHN0YXRpYyBmaW5hbCBpbnQgT1BfQ1JFQVRFID0gMTsKKyAgICBzdGF0aWMgZmluYWwgaW50IE9QX1JFQUQgPSAyOworICAgIGludCBvcCA9IE9QX0NSRUFURSB8IE9QX1JFQUQ7CisKKyAgICBib29sZWFuIHByb2NlZWQgPSBmYWxzZTsKKworICAgIHB1YmxpYyBNeU9wdGlvbnMoU3RyaW5nW10gYXJncykgeworICAgICAgc2VlZCA9IFN5c3RlbS5uYW5vVGltZSgpOworCisgICAgICB0cnkgeworICAgICAgICBPcHRpb25zIG9wdHMgPSBidWlsZE9wdGlvbnMoKTsKKyAgICAgICAgQ29tbWFuZExpbmVQYXJzZXIgcGFyc2VyID0gbmV3IEdudVBhcnNlcigpOworICAgICAgICBDb21tYW5kTGluZSBsaW5lID0gcGFyc2VyLnBhcnNlKG9wdHMsIGFyZ3MsIHRydWUpOworICAgICAgICBwcm9jZXNzT3B0aW9ucyhsaW5lLCBvcHRzKTsKKyAgICAgICAgdmFsaWRhdGVPcHRpb25zKCk7CisgICAgICB9CisgICAgICBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZS5nZXRNZXNzYWdlKCkpOworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyeSBcIi0taGVscFwiIG9wdGlvbiBmb3IgZGV0YWlscy4iKTsKKyAgICAgICAgc2V0U3RvcFByb2NlZWQoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBwcm9jZWVkKCkgeworICAgICAgcmV0dXJuIHByb2NlZWQ7CisgICAgfQorCisgICAgcHJpdmF0ZSBPcHRpb25zIGJ1aWxkT3B0aW9ucygpIHsKKyAgICAgIE9wdGlvbiBjb21wcmVzcyA9CisgICAgICAgICAgT3B0aW9uQnVpbGRlci53aXRoTG9uZ09wdCgiY29tcHJlc3MiKS53aXRoQXJnTmFtZSgiW25vbmV8bHpvfGd6XSIpCisgICAgICAgICAgICAgIC5oYXNBcmcoKS53aXRoRGVzY3JpcHRpb24oImNvbXByZXNzaW9uIHNjaGVtZSIpLmNyZWF0ZSgnYycpOworCisgICAgICBPcHRpb24gZmlsZVNpemUgPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIud2l0aExvbmdPcHQoImZpbGUtc2l6ZSIpLndpdGhBcmdOYW1lKCJzaXplLWluLU1CIikKKyAgICAgICAgICAgICAgLmhhc0FyZygpLndpdGhEZXNjcmlwdGlvbigidGFyZ2V0IHNpemUgb2YgdGhlIGZpbGUgKGluIE1CKS4iKQorICAgICAgICAgICAgICAuY3JlYXRlKCdzJyk7CisKKyAgICAgIE9wdGlvbiBmc0lucHV0QnVmZmVyU3ogPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIud2l0aExvbmdPcHQoImZzLWlucHV0LWJ1ZmZlciIpLndpdGhBcmdOYW1lKCJzaXplIikKKyAgICAgICAgICAgICAgLmhhc0FyZygpLndpdGhEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgICAgICJzaXplIG9mIHRoZSBmaWxlIHN5c3RlbSBpbnB1dCBidWZmZXIgKGluIGJ5dGVzKS4iKS5jcmVhdGUoCisgICAgICAgICAgICAgICAgICAnaScpOworCisgICAgICBPcHRpb24gZnNPdXRwdXRCdWZmZXJTaXplID0KKyAgICAgICAgICBPcHRpb25CdWlsZGVyLndpdGhMb25nT3B0KCJmcy1vdXRwdXQtYnVmZmVyIikud2l0aEFyZ05hbWUoInNpemUiKQorICAgICAgICAgICAgICAuaGFzQXJnKCkud2l0aERlc2NyaXB0aW9uKAorICAgICAgICAgICAgICAgICAgInNpemUgb2YgdGhlIGZpbGUgc3lzdGVtIG91dHB1dCBidWZmZXIgKGluIGJ5dGVzKS4iKS5jcmVhdGUoCisgICAgICAgICAgICAgICAgICAnbycpOworCisgICAgICBPcHRpb24ga2V5TGVuID0KKyAgICAgICAgICBPcHRpb25CdWlsZGVyCisgICAgICAgICAgICAgIC53aXRoTG9uZ09wdCgia2V5LWxlbmd0aCIpCisgICAgICAgICAgICAgIC53aXRoQXJnTmFtZSgibWluLG1heCIpCisgICAgICAgICAgICAgIC5oYXNBcmcoKQorICAgICAgICAgICAgICAud2l0aERlc2NyaXB0aW9uKAorICAgICAgICAgICAgICAgICAgInRoZSBsZW5ndGggcmFuZ2Ugb2YgdGhlIGtleSAoaW4gYnl0ZXMpIikKKyAgICAgICAgICAgICAgLmNyZWF0ZSgnaycpOworCisgICAgICBPcHRpb24gdmFsdWVMZW4gPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIKKyAgICAgICAgICAgICAgLndpdGhMb25nT3B0KCJ2YWx1ZS1sZW5ndGgiKQorICAgICAgICAgICAgICAud2l0aEFyZ05hbWUoIm1pbixtYXgiKQorICAgICAgICAgICAgICAuaGFzQXJnKCkKKyAgICAgICAgICAgICAgLndpdGhEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgICAgICJ0aGUgbGVuZ3RoIHJhbmdlIG9mIHRoZSB2YWx1ZSAoaW4gYnl0ZXMpIikKKyAgICAgICAgICAgICAgLmNyZWF0ZSgndicpOworCisgICAgICBPcHRpb24gYmxvY2tTeiA9CisgICAgICAgICAgT3B0aW9uQnVpbGRlci53aXRoTG9uZ09wdCgiYmxvY2siKS53aXRoQXJnTmFtZSgic2l6ZS1pbi1LQiIpLmhhc0FyZygpCisgICAgICAgICAgICAgIC53aXRoRGVzY3JpcHRpb24oIm1pbmltdW0gYmxvY2sgc2l6ZSAoaW4gS0IpIikuY3JlYXRlKCdiJyk7CisKKyAgICAgIE9wdGlvbiBzZWVkID0KKyAgICAgICAgICBPcHRpb25CdWlsZGVyLndpdGhMb25nT3B0KCJzZWVkIikud2l0aEFyZ05hbWUoImxvbmctaW50IikuaGFzQXJnKCkKKyAgICAgICAgICAgICAgLndpdGhEZXNjcmlwdGlvbigic3BlY2lmeSB0aGUgc2VlZCIpLmNyZWF0ZSgnUycpOworCisgICAgICBPcHRpb24gb3BlcmF0aW9uID0KKyAgICAgICAgICBPcHRpb25CdWlsZGVyLndpdGhMb25nT3B0KCJvcGVyYXRpb24iKS53aXRoQXJnTmFtZSgicnx3fHJ3IikuaGFzQXJnKCkKKyAgICAgICAgICAgICAgLndpdGhEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgICAgICJhY3Rpb246IHNlZWstb25seSwgY3JlYXRlLW9ubHksIHNlZWstYWZ0ZXItY3JlYXRlIikuY3JlYXRlKAorICAgICAgICAgICAgICAgICAgJ3gnKTsKKworICAgICAgT3B0aW9uIHJvb3REaXIgPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIud2l0aExvbmdPcHQoInJvb3QtZGlyIikud2l0aEFyZ05hbWUoInBhdGgiKS5oYXNBcmcoKQorICAgICAgICAgICAgICAud2l0aERlc2NyaXB0aW9uKAorICAgICAgICAgICAgICAgICAgInNwZWNpZnkgcm9vdCBkaXJlY3Rvcnkgd2hlcmUgZmlsZXMgd2lsbCBiZSBjcmVhdGVkLiIpCisgICAgICAgICAgICAgIC5jcmVhdGUoJ3InKTsKKworICAgICAgT3B0aW9uIGZpbGUgPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIud2l0aExvbmdPcHQoImZpbGUiKS53aXRoQXJnTmFtZSgibmFtZSIpLmhhc0FyZygpCisgICAgICAgICAgICAgIC53aXRoRGVzY3JpcHRpb24oInNwZWNpZnkgdGhlIGZpbGUgbmFtZSB0byBiZSBjcmVhdGVkIG9yIHJlYWQuIikKKyAgICAgICAgICAgICAgLmNyZWF0ZSgnZicpOworCisgICAgICBPcHRpb24gc2Vla0NvdW50ID0KKyAgICAgICAgICBPcHRpb25CdWlsZGVyCisgICAgICAgICAgICAgIC53aXRoTG9uZ09wdCgic2VlayIpCisgICAgICAgICAgICAgIC53aXRoQXJnTmFtZSgiY291bnQiKQorICAgICAgICAgICAgICAuaGFzQXJnKCkKKyAgICAgICAgICAgICAgLndpdGhEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgICAgICJzcGVjaWZ5IGhvdyBtYW55IHNlZWsgb3BlcmF0aW9ucyB3ZSBwZXJmb3JtIChyZXF1aXJlcyAteCByIG9yIC14IHJ3LiIpCisgICAgICAgICAgICAgIC5jcmVhdGUoJ24nKTsKKworICAgICAgT3B0aW9uIGhlbHAgPQorICAgICAgICAgIE9wdGlvbkJ1aWxkZXIud2l0aExvbmdPcHQoImhlbHAiKS5oYXNBcmcoZmFsc2UpLndpdGhEZXNjcmlwdGlvbigKKyAgICAgICAgICAgICAgInNob3cgdGhpcyBzY3JlZW4iKS5jcmVhdGUoImgiKTsKKworICAgICAgcmV0dXJuIG5ldyBPcHRpb25zKCkuYWRkT3B0aW9uKGNvbXByZXNzKS5hZGRPcHRpb24oZmlsZVNpemUpLmFkZE9wdGlvbigKKyAgICAgICAgICBmc0lucHV0QnVmZmVyU3opLmFkZE9wdGlvbihmc091dHB1dEJ1ZmZlclNpemUpLmFkZE9wdGlvbihrZXlMZW4pCisgICAgICAgICAgLmFkZE9wdGlvbihibG9ja1N6KS5hZGRPcHRpb24ocm9vdERpcikuYWRkT3B0aW9uKHZhbHVlTGVuKS5hZGRPcHRpb24oCisgICAgICAgICAgICAgIG9wZXJhdGlvbikuYWRkT3B0aW9uKHNlZWtDb3VudCkuYWRkT3B0aW9uKGZpbGUpLmFkZE9wdGlvbihoZWxwKTsKKworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBwcm9jZXNzT3B0aW9ucyhDb21tYW5kTGluZSBsaW5lLCBPcHRpb25zIG9wdHMpCisgICAgICAgIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CisgICAgICAvLyAtLWhlbHAgLWggYW5kIC0tdmVyc2lvbiAtViBtdXN0IGJlIHByb2Nlc3NlZCBmaXJzdC4KKyAgICAgIGlmIChsaW5lLmhhc09wdGlvbignaCcpKSB7CisgICAgICAgIEhlbHBGb3JtYXR0ZXIgZm9ybWF0dGVyID0gbmV3IEhlbHBGb3JtYXR0ZXIoKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJURmlsZSBhbmQgU2VxRmlsZSBiZW5jaG1hcmsuIik7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOworICAgICAgICBmb3JtYXR0ZXIucHJpbnRIZWxwKDEwMCwKKyAgICAgICAgICAgICJqYXZhIC4uLiBUZXN0VEZpbGVTZXFGaWxlQ29tcGFyaXNvbiBbb3B0aW9uc10iLAorICAgICAgICAgICAgIlxuU3VwcG9ydGVkIG9wdGlvbnM6Iiwgb3B0cywgIiIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisKKyAgICAgIGlmIChsaW5lLmhhc09wdGlvbignYycpKSB7CisgICAgICAgIGNvbXByZXNzID0gbGluZS5nZXRPcHRpb25WYWx1ZSgnYycpOworICAgICAgfQorCisgICAgICBpZiAobGluZS5oYXNPcHRpb24oJ2QnKSkgeworICAgICAgICBkaWN0U2l6ZSA9IEludGVnZXIucGFyc2VJbnQobGluZS5nZXRPcHRpb25WYWx1ZSgnZCcpKTsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdzJykpIHsKKyAgICAgICAgZmlsZVNpemUgPSBMb25nLnBhcnNlTG9uZyhsaW5lLmdldE9wdGlvblZhbHVlKCdzJykpICogMTAyNCAqIDEwMjQ7CisgICAgICB9CisKKyAgICAgIGlmIChsaW5lLmhhc09wdGlvbignaScpKSB7CisgICAgICAgIGZzSW5wdXRCdWZmZXJTaXplID0gSW50ZWdlci5wYXJzZUludChsaW5lLmdldE9wdGlvblZhbHVlKCdpJykpOworICAgICAgfQorCisgICAgICBpZiAobGluZS5oYXNPcHRpb24oJ28nKSkgeworICAgICAgICBmc091dHB1dEJ1ZmZlclNpemUgPSBJbnRlZ2VyLnBhcnNlSW50KGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ28nKSk7CisgICAgICB9CisgICAgICAKKyAgICAgIGlmIChsaW5lLmhhc09wdGlvbignbicpKSB7CisgICAgICAgIHNlZWtDb3VudCA9IEludGVnZXIucGFyc2VJbnQobGluZS5nZXRPcHRpb25WYWx1ZSgnbicpKTsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdrJykpIHsKKyAgICAgICAgSW50ZWdlclJhbmdlIGlyID0gSW50ZWdlclJhbmdlLnBhcnNlKGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ2snKSk7CisgICAgICAgIG1pbktleUxlbiA9IGlyLmZyb20oKTsKKyAgICAgICAgbWF4S2V5TGVuID0gaXIudG8oKTsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCd2JykpIHsKKyAgICAgICAgSW50ZWdlclJhbmdlIGlyID0gSW50ZWdlclJhbmdlLnBhcnNlKGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ3YnKSk7CisgICAgICAgIG1pblZhbExlbmd0aCA9IGlyLmZyb20oKTsKKyAgICAgICAgbWF4VmFsTGVuZ3RoID0gaXIudG8oKTsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdiJykpIHsKKyAgICAgICAgbWluQmxvY2tTaXplID0gSW50ZWdlci5wYXJzZUludChsaW5lLmdldE9wdGlvblZhbHVlKCdiJykpICogMTAyNDsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdyJykpIHsKKyAgICAgICAgcm9vdERpciA9IGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ3InKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdmJykpIHsKKyAgICAgICAgZmlsZSA9IGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ2YnKTsKKyAgICAgIH0KKworICAgICAgaWYgKGxpbmUuaGFzT3B0aW9uKCdTJykpIHsKKyAgICAgICAgc2VlZCA9IExvbmcucGFyc2VMb25nKGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ1MnKSk7CisgICAgICB9CisKKyAgICAgIGlmIChsaW5lLmhhc09wdGlvbigneCcpKSB7CisgICAgICAgIFN0cmluZyBzdHJPcCA9IGxpbmUuZ2V0T3B0aW9uVmFsdWUoJ3gnKTsKKyAgICAgICAgaWYgKHN0ck9wLmVxdWFscygiciIpKSB7CisgICAgICAgICAgb3AgPSBPUF9SRUFEOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHN0ck9wLmVxdWFscygidyIpKSB7CisgICAgICAgICAgb3AgPSBPUF9DUkVBVEU7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoc3RyT3AuZXF1YWxzKCJydyIpKSB7CisgICAgICAgICAgb3AgPSBPUF9DUkVBVEUgfCBPUF9SRUFEOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiVW5rbm93biBhY3Rpb24gc3BlY2lmaWVyOiAiICsgc3RyT3ApOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHByb2NlZWQgPSB0cnVlOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCB2YWxpZGF0ZU9wdGlvbnMoKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24geworICAgICAgaWYgKCFjb21wcmVzcy5lcXVhbHMoIm5vbmUiKSAmJiAhY29tcHJlc3MuZXF1YWxzKCJsem8iKQorICAgICAgICAgICYmICFjb21wcmVzcy5lcXVhbHMoImd6IikpIHsKKyAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJVbmtub3duIGNvbXByZXNzaW9uIHNjaGVtZTogIiArIGNvbXByZXNzKTsKKyAgICAgIH0KKworICAgICAgaWYgKG1pbktleUxlbiA+PSBtYXhLZXlMZW4pIHsKKyAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKAorICAgICAgICAgICAgIk1heCBrZXkgbGVuZ3RoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG1pbiBrZXkgbGVuZ3RoLiIpOworICAgICAgfQorCisgICAgICBpZiAobWluVmFsTGVuZ3RoID49IG1heFZhbExlbmd0aCkgeworICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oCisgICAgICAgICAgICAiTWF4IHZhbHVlIGxlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBtaW4gdmFsdWUgbGVuZ3RoLiIpOworICAgICAgfQorCisgICAgICBpZiAobWluV29yZExlbiA+PSBtYXhXb3JkTGVuKSB7CisgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICJNYXggd29yZCBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYW4gbWluIHdvcmQgbGVuZ3RoLiIpOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBzZXRTdG9wUHJvY2VlZCgpIHsKKyAgICAgIHByb2NlZWQgPSBmYWxzZTsKKyAgICB9CisKKyAgICBwdWJsaWMgYm9vbGVhbiBkb0NyZWF0ZSgpIHsKKyAgICAgIHJldHVybiAob3AgJiBPUF9DUkVBVEUpICE9IDA7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gZG9SZWFkKCkgeworICAgICAgcmV0dXJuIChvcCAmIE9QX1JFQUQpICE9IDA7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmd2KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFRlc3RIRmlsZVNlZWsgdGVzdENhc2UgPSBuZXcgVGVzdEhGaWxlU2VlaygpOworICAgIE15T3B0aW9ucyBvcHRpb25zID0gbmV3IE15T3B0aW9ucyhhcmd2KTsKKyAgICAKKyAgICBpZiAob3B0aW9ucy5wcm9jZWVkID09IGZhbHNlKSB7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgdGVzdENhc2Uub3B0aW9ucyA9IG9wdGlvbnM7CisgICAgdGVzdENhc2Uuc2V0VXAoKTsKKyAgICB0ZXN0Q2FzZS50ZXN0U2Vla3MoKTsKKyAgICB0ZXN0Q2FzZS50ZWFyRG93bigpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0U2Vla1RvLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9pby9oZmlsZS9UZXN0U2Vla1RvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWZhODBhMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL2lvL2hmaWxlL1Rlc3RTZWVrVG8uamF2YQpAQCAtMCwwICsxLDEyMyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZTRGF0YU91dHB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IHtAbGluayBIRmlsZVNjYW5uZXIjc2Vla1RvKGJ5dGVbXSl9IGFuZCBpdHMgdmFyaWFudHMuCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0U2Vla1RvIGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisKKyAgUGF0aCBtYWtlTmV3RmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBuY1RGaWxlID0gbmV3IFBhdGgodGhpcy50ZXN0RGlyLCAiYmFzaWMuaGZpbGUiKTsKKyAgICBGU0RhdGFPdXRwdXRTdHJlYW0gZm91dCA9IHRoaXMuZnMuY3JlYXRlKG5jVEZpbGUpOworICAgIEhGaWxlLldyaXRlciB3cml0ZXIgPSBuZXcgSEZpbGUuV3JpdGVyKGZvdXQsIDQwLCAibm9uZSIsIG51bGwpOworICAgIC8vIDQgYnl0ZXMgKiAzICogMiBmb3IgZWFjaCBrZXkvdmFsdWUgKworICAgIC8vIDMgZm9yIGtleXMsIDE1IGZvciB2YWx1ZXMgPSA0MiAod29vdCkKKyAgICB3cml0ZXIuYXBwZW5kKEJ5dGVzLnRvQnl0ZXMoImMiKSwgQnl0ZXMudG9CeXRlcygidmFsdWUiKSk7CisgICAgd3JpdGVyLmFwcGVuZChCeXRlcy50b0J5dGVzKCJlIiksIEJ5dGVzLnRvQnl0ZXMoInZhbHVlIikpOworICAgIHdyaXRlci5hcHBlbmQoQnl0ZXMudG9CeXRlcygiZyIpLCBCeXRlcy50b0J5dGVzKCJ2YWx1ZSIpKTsKKyAgICAvLyBibG9jayB0cmFuc2l0aW9uCisgICAgd3JpdGVyLmFwcGVuZChCeXRlcy50b0J5dGVzKCJpIiksIEJ5dGVzLnRvQnl0ZXMoInZhbHVlIikpOworICAgIHdyaXRlci5hcHBlbmQoQnl0ZXMudG9CeXRlcygiayIpLCBCeXRlcy50b0J5dGVzKCJ2YWx1ZSIpKTsKKyAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICBmb3V0LmNsb3NlKCk7CisgICAgcmV0dXJuIG5jVEZpbGU7CisgIH0KKyAgcHVibGljIHZvaWQgdGVzdFNlZWtCZWZvcmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBQYXRoIHAgPSBtYWtlTmV3RmlsZSgpOworICAgIEhGaWxlLlJlYWRlciByZWFkZXIgPSBuZXcgSEZpbGUuUmVhZGVyKGZzLCBwLCBudWxsKTsKKyAgICByZWFkZXIubG9hZEZpbGVJbmZvKCk7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSByZWFkZXIuZ2V0U2Nhbm5lcigpOworICAgIGFzc2VydEVxdWFscyhmYWxzZSwgc2Nhbm5lci5zZWVrQmVmb3JlKEJ5dGVzLnRvQnl0ZXMoImEiKSkpOworICAgIAorICAgIGFzc2VydEVxdWFscyhmYWxzZSwgc2Nhbm5lci5zZWVrQmVmb3JlKEJ5dGVzLnRvQnl0ZXMoImMiKSkpOworICAgIAorICAgIGFzc2VydEVxdWFscyh0cnVlLCBzY2FubmVyLnNlZWtCZWZvcmUoQnl0ZXMudG9CeXRlcygiZCIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJjIiwgc2Nhbm5lci5nZXRLZXlTdHJpbmcoKSk7CisgICAgCisgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHNjYW5uZXIuc2Vla0JlZm9yZShCeXRlcy50b0J5dGVzKCJlIikpKTsKKyAgICBhc3NlcnRFcXVhbHMoImMiLCBzY2FubmVyLmdldEtleVN0cmluZygpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHModHJ1ZSwgc2Nhbm5lci5zZWVrQmVmb3JlKEJ5dGVzLnRvQnl0ZXMoImYiKSkpOworICAgIGFzc2VydEVxdWFscygiZSIsIHNjYW5uZXIuZ2V0S2V5U3RyaW5nKCkpOworICAgIAorICAgIGFzc2VydEVxdWFscyh0cnVlLCBzY2FubmVyLnNlZWtCZWZvcmUoQnl0ZXMudG9CeXRlcygiZyIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJlIiwgc2Nhbm5lci5nZXRLZXlTdHJpbmcoKSk7CisgICAgCisgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHNjYW5uZXIuc2Vla0JlZm9yZShCeXRlcy50b0J5dGVzKCJoIikpKTsKKyAgICBhc3NlcnRFcXVhbHMoImciLCBzY2FubmVyLmdldEtleVN0cmluZygpKTsKKyAgICBhc3NlcnRFcXVhbHModHJ1ZSwgc2Nhbm5lci5zZWVrQmVmb3JlKEJ5dGVzLnRvQnl0ZXMoImkiKSkpOworICAgIGFzc2VydEVxdWFscygiZyIsIHNjYW5uZXIuZ2V0S2V5U3RyaW5nKCkpOworICAgIGFzc2VydEVxdWFscyh0cnVlLCBzY2FubmVyLnNlZWtCZWZvcmUoQnl0ZXMudG9CeXRlcygiaiIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJpIiwgc2Nhbm5lci5nZXRLZXlTdHJpbmcoKSk7CisgICAgYXNzZXJ0RXF1YWxzKHRydWUsIHNjYW5uZXIuc2Vla0JlZm9yZShCeXRlcy50b0J5dGVzKCJrIikpKTsKKyAgICBhc3NlcnRFcXVhbHMoImkiLCBzY2FubmVyLmdldEtleVN0cmluZygpKTsKKyAgICBhc3NlcnRFcXVhbHModHJ1ZSwgc2Nhbm5lci5zZWVrQmVmb3JlKEJ5dGVzLnRvQnl0ZXMoImwiKSkpOworICAgIGFzc2VydEVxdWFscygiayIsIHNjYW5uZXIuZ2V0S2V5U3RyaW5nKCkpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0U2Vla1RvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUGF0aCBwID0gbWFrZU5ld0ZpbGUoKTsKKyAgICBIRmlsZS5SZWFkZXIgcmVhZGVyID0gbmV3IEhGaWxlLlJlYWRlcihmcywgcCwgbnVsbCk7CisgICAgcmVhZGVyLmxvYWRGaWxlSW5mbygpOworICAgIGFzc2VydEVxdWFscygyLCByZWFkZXIuYmxvY2tJbmRleC5jb3VudCk7CisgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSByZWFkZXIuZ2V0U2Nhbm5lcigpOworICAgIC8vIGxpZXMgYmVmb3JlIHRoZSBzdGFydCBvZiB0aGUgZmlsZS4KKyAgICBhc3NlcnRFcXVhbHMoLTEsIHNjYW5uZXIuc2Vla1RvKEJ5dGVzLnRvQnl0ZXMoImEiKSkpOworICAKKyAgICBhc3NlcnRFcXVhbHMoMSwgc2Nhbm5lci5zZWVrVG8oQnl0ZXMudG9CeXRlcygiZCIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJjIiwgc2Nhbm5lci5nZXRLZXlTdHJpbmcoKSk7CisgICAgCisgICAgLy8gQWNyb3NzIGEgYmxvY2sgYm91bmRhcnkgbm93LgorICAgIGFzc2VydEVxdWFscygxLCBzY2FubmVyLnNlZWtUbyhCeXRlcy50b0J5dGVzKCJoIikpKTsKKyAgICBhc3NlcnRFcXVhbHMoImciLCBzY2FubmVyLmdldEtleVN0cmluZygpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoMSwgc2Nhbm5lci5zZWVrVG8oQnl0ZXMudG9CeXRlcygibCIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKCJrIiwgc2Nhbm5lci5nZXRLZXlTdHJpbmcoKSk7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIHRlc3RCbG9ja0NvbnRhaW5pbmdLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBQYXRoIHAgPSBtYWtlTmV3RmlsZSgpOworICAgIEhGaWxlLlJlYWRlciByZWFkZXIgPSBuZXcgSEZpbGUuUmVhZGVyKGZzLCBwLCBudWxsKTsKKyAgICByZWFkZXIubG9hZEZpbGVJbmZvKCk7CisgICAgU3lzdGVtLm91dC5wcmludGxuKHJlYWRlci5ibG9ja0luZGV4LnRvU3RyaW5nKCkpOworICAgIC8vIGZhbGxzIGJlZm9yZSB0aGUgc3RhcnQgb2YgdGhlIGZpbGUuCisgICAgYXNzZXJ0RXF1YWxzKC0xLCByZWFkZXIuYmxvY2tJbmRleC5ibG9ja0NvbnRhaW5pbmdLZXkoQnl0ZXMudG9CeXRlcygiYSIpLCAwLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIHJlYWRlci5ibG9ja0luZGV4LmJsb2NrQ29udGFpbmluZ0tleShCeXRlcy50b0J5dGVzKCJjIiksIDAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgcmVhZGVyLmJsb2NrSW5kZXguYmxvY2tDb250YWluaW5nS2V5KEJ5dGVzLnRvQnl0ZXMoImQiKSwgMCwgMSkpOworICAgIGFzc2VydEVxdWFscygwLCByZWFkZXIuYmxvY2tJbmRleC5ibG9ja0NvbnRhaW5pbmdLZXkoQnl0ZXMudG9CeXRlcygiZSIpLCAwLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIHJlYWRlci5ibG9ja0luZGV4LmJsb2NrQ29udGFpbmluZ0tleShCeXRlcy50b0J5dGVzKCJnIiksIDAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgcmVhZGVyLmJsb2NrSW5kZXguYmxvY2tDb250YWluaW5nS2V5KEJ5dGVzLnRvQnl0ZXMoImgiKSwgMCwgMSkpOworICAgIGFzc2VydEVxdWFscygxLCByZWFkZXIuYmxvY2tJbmRleC5ibG9ja0NvbnRhaW5pbmdLZXkoQnl0ZXMudG9CeXRlcygiaSIpLCAwLCAxKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHJlYWRlci5ibG9ja0luZGV4LmJsb2NrQ29udGFpbmluZ0tleShCeXRlcy50b0J5dGVzKCJqIiksIDAsIDEpKTsKKyAgICBhc3NlcnRFcXVhbHMoMSwgcmVhZGVyLmJsb2NrSW5kZXguYmxvY2tDb250YWluaW5nS2V5KEJ5dGVzLnRvQnl0ZXMoImsiKSwgMCwgMSkpOworICAgIGFzc2VydEVxdWFscygxLCByZWFkZXIuYmxvY2tJbmRleC5ibG9ja0NvbnRhaW5pbmdLZXkoQnl0ZXMudG9CeXRlcygibCIpLCAwLCAxKSk7CisKKworICAgIAorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Rlc3RUYWJsZUluZGV4LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGVzdFRhYmxlSW5kZXguamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDg0Mjg0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvbWFwcmVkL1Rlc3RUYWJsZUluZGV4LmphdmEKQEAgLTAsMCArMSwyNjEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXByZWQ7CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlOworaW1wb3J0IGp1bml0LnRleHR1aS5UZXN0UnVubmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlU3lzdGVtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXIuSFJlZ2lvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LlNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uUm93UmVzdWx0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5NdWx0aVJlZ2lvblRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5GaWxlT3V0cHV0Rm9ybWF0OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDbGllbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLkpvYkNvbmY7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1pbmlNUkNsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5sdWNlbmUuaW5kZXguVGVybTsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5zZWFyY2guSW5kZXhTZWFyY2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5zZWFyY2guTXVsdGlTZWFyY2hlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5zZWFyY2guU2VhcmNoYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmx1Y2VuZS5zZWFyY2guU2VhcmNoZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5sdWNlbmUuc2VhcmNoLlRlcm1RdWVyeTsKKworLyoqCisgKiBUZXN0IE1hcC9SZWR1Y2Ugam9iIHRvIGJ1aWxkIGluZGV4IG92ZXIgSEJhc2UgdGFibGUKKyAqLworcHVibGljIGNsYXNzIFRlc3RUYWJsZUluZGV4IGV4dGVuZHMgTXVsdGlSZWdpb25UYWJsZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0VGFibGVJbmRleC5jbGFzcyk7CisKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBUQUJMRV9OQU1FID0gIm1vcmV0ZXN0IjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBJTlBVVF9DT0xVTU4gPSAiY29udGVudHM6IjsKKyAgc3RhdGljIGZpbmFsIGJ5dGUgW10gVEVYVF9JTlBVVF9DT0xVTU4gPSBCeXRlcy50b0J5dGVzKElOUFVUX0NPTFVNTik7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1VUUFVUX0NPTFVNTiA9ICJ0ZXh0OiI7CisgIHN0YXRpYyBmaW5hbCBieXRlIFtdIFRFWFRfT1VUUFVUX0NPTFVNTiA9IEJ5dGVzLnRvQnl0ZXMoT1VUUFVUX0NPTFVNTik7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUk9XS0VZX05BTUUgPSAia2V5IjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBJTkRFWF9ESVIgPSAidGVzdGluZGV4IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXVtdIGNvbHVtbnMgPSBuZXcgYnl0ZSBbXVtdIHsKKyAgICBURVhUX0lOUFVUX0NPTFVNTiwKKyAgICBURVhUX09VVFBVVF9DT0xVTU4KKyAgfTsKKworICBwcml2YXRlIEpvYkNvbmYgam9iQ29uZiA9IG51bGw7CisKKyAgLyoqIGRlZmF1bHQgY29uc3RydWN0b3IgKi8KKyAgcHVibGljIFRlc3RUYWJsZUluZGV4KCkgeworICAgIHN1cGVyKElOUFVUX0NPTFVNTik7CisgICAgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKFRBQkxFX05BTUUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihJTlBVVF9DT0xVTU4pKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoT1VUUFVUX0NPTFVNTikpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaWYgKGpvYkNvbmYgIT0gbnVsbCkgeworICAgICAgRmlsZVV0aWwuZnVsbHlEZWxldGUobmV3IEZpbGUoam9iQ29uZi5nZXQoImhhZG9vcC50bXAuZGlyIikpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVGVzdCBIQmFzZSBtYXAvcmVkdWNlCisgICAqIAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0VGFibGVJbmRleCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYm9vbGVhbiBwcmludFJlc3VsdHMgPSBmYWxzZTsKKyAgICBpZiAocHJpbnRSZXN1bHRzKSB7CisgICAgICBMT0cuaW5mbygiUHJpbnQgdGFibGUgY29udGVudHMgYmVmb3JlIG1hcC9yZWR1Y2UiKTsKKyAgICB9CisgICAgc2NhblRhYmxlKHByaW50UmVzdWx0cyk7CisKKyAgICBNaW5pTVJDbHVzdGVyIG1yQ2x1c3RlciA9IG5ldyBNaW5pTVJDbHVzdGVyKDIsIGZzLmdldFVyaSgpLnRvU3RyaW5nKCksIDEpOworCisgICAgLy8gc2V0IGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyIGZvciBpbmRleCBidWlsZAorICAgIGNvbmYuc2V0KCJoYmFzZS5pbmRleC5jb25mIiwgY3JlYXRlSW5kZXhDb25mQ29udGVudCgpKTsKKworICAgIHRyeSB7CisgICAgICBqb2JDb25mID0gbmV3IEpvYkNvbmYoY29uZiwgVGVzdFRhYmxlSW5kZXguY2xhc3MpOworICAgICAgam9iQ29uZi5zZXRKb2JOYW1lKCJpbmRleCBjb2x1bW4gY29udGVudHMiKTsKKyAgICAgIGpvYkNvbmYuc2V0TnVtTWFwVGFza3MoMik7CisgICAgICAvLyBudW1iZXIgb2YgaW5kZXhlcyB0byBwYXJ0aXRpb24gaW50bworICAgICAgam9iQ29uZi5zZXROdW1SZWR1Y2VUYXNrcygxKTsKKworICAgICAgLy8gdXNlIGlkZW50aXR5IG1hcCAoYSB3YXN0ZSwgYnV0IGp1c3QgYXMgYW4gZXhhbXBsZSkKKyAgICAgIElkZW50aXR5VGFibGVNYXAuaW5pdEpvYihUQUJMRV9OQU1FLCBJTlBVVF9DT0xVTU4sCisgICAgICAgICAgSWRlbnRpdHlUYWJsZU1hcC5jbGFzcywgam9iQ29uZik7CisKKyAgICAgIC8vIHVzZSBJbmRleFRhYmxlUmVkdWNlIHRvIGJ1aWxkIGEgTHVjZW5lIGluZGV4CisgICAgICBqb2JDb25mLnNldFJlZHVjZXJDbGFzcyhJbmRleFRhYmxlUmVkdWNlLmNsYXNzKTsKKyAgICAgIEZpbGVPdXRwdXRGb3JtYXQuc2V0T3V0cHV0UGF0aChqb2JDb25mLCBuZXcgUGF0aChJTkRFWF9ESVIpKTsKKyAgICAgIGpvYkNvbmYuc2V0T3V0cHV0Rm9ybWF0KEluZGV4T3V0cHV0Rm9ybWF0LmNsYXNzKTsKKworICAgICAgSm9iQ2xpZW50LnJ1bkpvYihqb2JDb25mKTsKKworICAgIH0gZmluYWxseSB7CisgICAgICBtckNsdXN0ZXIuc2h1dGRvd24oKTsKKyAgICB9CisKKyAgICBpZiAocHJpbnRSZXN1bHRzKSB7CisgICAgICBMT0cuaW5mbygiUHJpbnQgdGFibGUgY29udGVudHMgYWZ0ZXIgbWFwL3JlZHVjZSIpOworICAgIH0KKyAgICBzY2FuVGFibGUocHJpbnRSZXN1bHRzKTsKKworICAgIC8vIHZlcmlmeSBpbmRleCByZXN1bHRzCisgICAgdmVyaWZ5KCk7CisgIH0KKworICBwcml2YXRlIFN0cmluZyBjcmVhdGVJbmRleENvbmZDb250ZW50KCkgeworICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgYnVmZmVyLmFwcGVuZCgiPGNvbmZpZ3VyYXRpb24+PGNvbHVtbj48cHJvcGVydHk+IiArCisgICAgICAiPG5hbWU+aGJhc2UuY29sdW1uLm5hbWU8L25hbWU+PHZhbHVlPiIgKyBJTlBVVF9DT0xVTU4gKworICAgICAgIjwvdmFsdWU+PC9wcm9wZXJ0eT4iKTsKKyAgICBidWZmZXIuYXBwZW5kKCI8cHJvcGVydHk+PG5hbWU+aGJhc2UuY29sdW1uLnN0b3JlPC9uYW1lPiAiICsKKyAgICAgICI8dmFsdWU+dHJ1ZTwvdmFsdWU+PC9wcm9wZXJ0eT4iKTsKKyAgICBidWZmZXIuYXBwZW5kKCI8cHJvcGVydHk+PG5hbWU+aGJhc2UuY29sdW1uLmluZGV4PC9uYW1lPiIgKworICAgICAgIjx2YWx1ZT50cnVlPC92YWx1ZT48L3Byb3BlcnR5PiIpOworICAgIGJ1ZmZlci5hcHBlbmQoIjxwcm9wZXJ0eT48bmFtZT5oYmFzZS5jb2x1bW4udG9rZW5pemU8L25hbWU+IiArCisgICAgICAiPHZhbHVlPmZhbHNlPC92YWx1ZT48L3Byb3BlcnR5PiIpOworICAgIGJ1ZmZlci5hcHBlbmQoIjxwcm9wZXJ0eT48bmFtZT5oYmFzZS5jb2x1bW4uYm9vc3Q8L25hbWU+IiArCisgICAgICAiPHZhbHVlPjM8L3ZhbHVlPjwvcHJvcGVydHk+Iik7CisgICAgYnVmZmVyLmFwcGVuZCgiPHByb3BlcnR5PjxuYW1lPmhiYXNlLmNvbHVtbi5vbWl0Lm5vcm1zPC9uYW1lPiIgKworICAgICAgIjx2YWx1ZT5mYWxzZTwvdmFsdWU+PC9wcm9wZXJ0eT48L2NvbHVtbj4iKTsKKyAgICBidWZmZXIuYXBwZW5kKCI8cHJvcGVydHk+PG5hbWU+aGJhc2UuaW5kZXgucm93a2V5Lm5hbWU8L25hbWU+PHZhbHVlPiIgKworICAgICAgUk9XS0VZX05BTUUgKyAiPC92YWx1ZT48L3Byb3BlcnR5PiIpOworICAgIGJ1ZmZlci5hcHBlbmQoIjxwcm9wZXJ0eT48bmFtZT5oYmFzZS5pbmRleC5tYXguYnVmZmVyZWQuZG9jczwvbmFtZT4iICsKKyAgICAgICI8dmFsdWU+NTAwPC92YWx1ZT48L3Byb3BlcnR5PiIpOworICAgIGJ1ZmZlci5hcHBlbmQoIjxwcm9wZXJ0eT48bmFtZT5oYmFzZS5pbmRleC5tYXguZmllbGQubGVuZ3RoPC9uYW1lPiIgKworICAgICAgIjx2YWx1ZT4xMDAwMDwvdmFsdWU+PC9wcm9wZXJ0eT4iKTsKKyAgICBidWZmZXIuYXBwZW5kKCI8cHJvcGVydHk+PG5hbWU+aGJhc2UuaW5kZXgubWVyZ2UuZmFjdG9yPC9uYW1lPiIgKworICAgICAgIjx2YWx1ZT4xMDwvdmFsdWU+PC9wcm9wZXJ0eT4iKTsKKyAgICBidWZmZXIuYXBwZW5kKCI8cHJvcGVydHk+PG5hbWU+aGJhc2UuaW5kZXgudXNlLmNvbXBvdW5kLmZpbGU8L25hbWU+IiArCisgICAgICAiPHZhbHVlPnRydWU8L3ZhbHVlPjwvcHJvcGVydHk+Iik7CisgICAgYnVmZmVyLmFwcGVuZCgiPHByb3BlcnR5PjxuYW1lPmhiYXNlLmluZGV4Lm9wdGltaXplPC9uYW1lPiIgKworICAgICAgIjx2YWx1ZT50cnVlPC92YWx1ZT48L3Byb3BlcnR5PjwvY29uZmlndXJhdGlvbj4iKTsKKworICAgIEluZGV4Q29uZmlndXJhdGlvbiBjID0gbmV3IEluZGV4Q29uZmlndXJhdGlvbigpOworICAgIGMuYWRkRnJvbVhNTChidWZmZXIudG9TdHJpbmcoKSk7CisgICAgcmV0dXJuIGMudG9TdHJpbmcoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBzY2FuVGFibGUoYm9vbGVhbiBwcmludFJlc3VsdHMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCBUQUJMRV9OQU1FKTsKKyAgICBTY2FubmVyIHNjYW5uZXIgPSB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMsCisgICAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICB0cnkgeworICAgICAgZm9yIChSb3dSZXN1bHQgciA6IHNjYW5uZXIpIHsKKyAgICAgICAgaWYgKHByaW50UmVzdWx0cykgeworICAgICAgICAgIExPRy5pbmZvKCJyb3c6ICIgKyByLmdldFJvdygpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPiBlIDogci5lbnRyeVNldCgpKSB7CisgICAgICAgICAgaWYgKHByaW50UmVzdWx0cykgeworICAgICAgICAgICAgTE9HLmluZm8oIiBjb2x1bW46ICIgKyBlLmdldEtleSgpICsgIiB2YWx1ZTogIgorICAgICAgICAgICAgICAgICsgbmV3IFN0cmluZyhlLmdldFZhbHVlKCkuZ2V0VmFsdWUoKSwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgdmVyaWZ5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBGb3JjZSBhIGNhY2hlIGZsdXNoIGZvciBldmVyeSBvbmxpbmUgcmVnaW9uIHRvIGVuc3VyZSB0aGF0IHdoZW4gdGhlCisgICAgLy8gc2Nhbm5lciB0YWtlcyBpdHMgc25hcHNob3QsIGFsbCB0aGUgdXBkYXRlcyBoYXZlIG1hZGUgaXQgaW50byB0aGUgY2FjaGUuCisgICAgZm9yIChIUmVnaW9uIHIgOiBjbHVzdGVyLmdldFJlZ2lvblRocmVhZHMoKS5nZXQoMCkuZ2V0UmVnaW9uU2VydmVyKCkuCisgICAgICAgIGdldE9ubGluZVJlZ2lvbnMoKSkgeworICAgICAgSFJlZ2lvbkluY29tbW9uIHJlZ2lvbiA9IG5ldyBIUmVnaW9uSW5jb21tb24ocik7CisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgIH0KKworICAgIFBhdGggbG9jYWxEaXIgPSBuZXcgUGF0aChnZXRVbml0VGVzdGRpcihnZXROYW1lKCkpLCAiaW5kZXhfIiArCisgICAgICBJbnRlZ2VyLnRvU3RyaW5nKG5ldyBSYW5kb20oKS5uZXh0SW50KCkpKTsKKyAgICB0aGlzLmZzLmNvcHlUb0xvY2FsRmlsZShuZXcgUGF0aChJTkRFWF9ESVIpLCBsb2NhbERpcik7CisgICAgRmlsZVN5c3RlbSBsb2NhbGZzID0gRmlsZVN5c3RlbS5nZXRMb2NhbChjb25mKTsKKyAgICBGaWxlU3RhdHVzIFtdIGluZGV4RGlycyA9IGxvY2FsZnMubGlzdFN0YXR1cyhsb2NhbERpcik7CisgICAgU2VhcmNoZXIgc2VhcmNoZXIgPSBudWxsOworICAgIFNjYW5uZXIgc2Nhbm5lciA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIGlmIChpbmRleERpcnMubGVuZ3RoID09IDEpIHsKKyAgICAgICAgc2VhcmNoZXIgPSBuZXcgSW5kZXhTZWFyY2hlcigobmV3IEZpbGUoaW5kZXhEaXJzWzBdLmdldFBhdGgoKS4KKyAgICAgICAgICB0b1VyaSgpKSkuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgfSBlbHNlIGlmIChpbmRleERpcnMubGVuZ3RoID4gMSkgeworICAgICAgICBTZWFyY2hhYmxlW10gc2VhcmNoZXJzID0gbmV3IFNlYXJjaGFibGVbaW5kZXhEaXJzLmxlbmd0aF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5kZXhEaXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgICAgc2VhcmNoZXJzW2ldID0gbmV3IEluZGV4U2VhcmNoZXIoKG5ldyBGaWxlKGluZGV4RGlyc1tpXS5nZXRQYXRoKCkuCisgICAgICAgICAgICB0b1VyaSgpKS5nZXRBYnNvbHV0ZVBhdGgoKSkpOworICAgICAgICB9CisgICAgICAgIHNlYXJjaGVyID0gbmV3IE11bHRpU2VhcmNoZXIoc2VhcmNoZXJzKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigibm8gaW5kZXggZGlyZWN0b3J5IGZvdW5kIik7CisgICAgICB9CisKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgVEFCTEVfTkFNRSk7CisgICAgICBzY2FubmVyID0gdGFibGUuZ2V0U2Nhbm5lcihjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisKKyAgICAgIEluZGV4Q29uZmlndXJhdGlvbiBpbmRleENvbmYgPSBuZXcgSW5kZXhDb25maWd1cmF0aW9uKCk7CisgICAgICBTdHJpbmcgY29udGVudCA9IGNvbmYuZ2V0KCJoYmFzZS5pbmRleC5jb25mIik7CisgICAgICBpZiAoY29udGVudCAhPSBudWxsKSB7CisgICAgICAgIGluZGV4Q29uZi5hZGRGcm9tWE1MKGNvbnRlbnQpOworICAgICAgfQorICAgICAgU3RyaW5nIHJvd2tleU5hbWUgPSBpbmRleENvbmYuZ2V0Um93a2V5TmFtZSgpOworCisgICAgICBpbnQgY291bnQgPSAwOworICAgICAgZm9yIChSb3dSZXN1bHQgciA6IHNjYW5uZXIpIHsKKyAgICAgICAgU3RyaW5nIHZhbHVlID0gQnl0ZXMudG9TdHJpbmcoci5nZXRSb3coKSk7CisgICAgICAgIFRlcm0gdGVybSA9IG5ldyBUZXJtKHJvd2tleU5hbWUsIHZhbHVlKTsKKyAgICAgICAgaW50IGhpdENvdW50ID0gc2VhcmNoZXIuc2VhcmNoKG5ldyBUZXJtUXVlcnkodGVybSkpLmxlbmd0aCgpOworICAgICAgICBhc3NlcnRFcXVhbHMoImNoZWNrIHJvdyAiICsgdmFsdWUsIDEsIGhpdENvdW50KTsKKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0KKyAgICAgIExPRy5kZWJ1ZygiU2VhcmNoZXIubWF4RG9jOiAiICsgc2VhcmNoZXIubWF4RG9jKCkpOworICAgICAgTE9HLmRlYnVnKCJJbmRleFJlYWRlci5udW1Eb2NzOiAiICsgKChJbmRleFNlYXJjaGVyKXNlYXJjaGVyKS5nZXRJbmRleFJlYWRlcigpLm51bURvY3MoKSk7ICAgICAgCisgICAgICBpbnQgbWF4RG9jID0gKChJbmRleFNlYXJjaGVyKXNlYXJjaGVyKS5nZXRJbmRleFJlYWRlcigpLm51bURvY3MoKTsKKyAgICAgIGFzc2VydEVxdWFscygiY2hlY2sgbnVtYmVyIG9mIHJvd3MiLCBtYXhEb2MsIGNvdW50KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKG51bGwgIT0gc2VhcmNoZXIpCisgICAgICAgIHNlYXJjaGVyLmNsb3NlKCk7CisgICAgICBpZiAobnVsbCAhPSBzY2FubmVyKQorICAgICAgICBzY2FubmVyLmNsb3NlKCk7CisgICAgfQorICB9CisgIC8qKgorICAgKiBAcGFyYW0gYXJncyB1bnVzZWQKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICBUZXN0UnVubmVyLnJ1bihuZXcgVGVzdFN1aXRlKFRlc3RUYWJsZUluZGV4LmNsYXNzKSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGVzdFRhYmxlTWFwUmVkdWNlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXByZWQvVGVzdFRhYmxlTWFwUmVkdWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjIwYzFjOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hcHJlZC9UZXN0VGFibGVNYXBSZWR1Y2UuamF2YQpAQCAtMCwwICsxLDI0NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hcHJlZDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5GaWxlVXRpbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTXVsdGlSZWdpb25UYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkNlbGw7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uSW1tdXRhYmxlQnl0ZXNXcml0YWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5Sb3dSZXN1bHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWQuSm9iQ2xpZW50OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5Kb2JDb25mOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NYXBSZWR1Y2VCYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5NaW5pTVJDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5PdXRwdXRDb2xsZWN0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLlJlcG9ydGVyOworCisvKioKKyAqIFRlc3QgTWFwL1JlZHVjZSBqb2Igb3ZlciBIQmFzZSB0YWJsZXMuIFRoZSBtYXAvcmVkdWNlIHByb2Nlc3Mgd2UncmUgdGVzdGluZworICogb24gb3VyIHRhYmxlcyBpcyBzaW1wbGUgLSB0YWtlIGV2ZXJ5IHJvdyBpbiB0aGUgdGFibGUsIHJldmVyc2UgdGhlIHZhbHVlIG9mCisgKiBhIHBhcnRpY3VsYXIgY2VsbCwgYW5kIHdyaXRlIGl0IGJhY2sgdG8gdGhlIHRhYmxlLgorICovCitwdWJsaWMgY2xhc3MgVGVzdFRhYmxlTWFwUmVkdWNlIGV4dGVuZHMgTXVsdGlSZWdpb25UYWJsZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPQorICAgIExvZ0ZhY3RvcnkuZ2V0TG9nKFRlc3RUYWJsZU1hcFJlZHVjZS5jbGFzcy5nZXROYW1lKCkpOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTVVMVElfUkVHSU9OX1RBQkxFX05BTUUgPSAibXJ0ZXN0IjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBJTlBVVF9DT0xVTU4gPSAiY29udGVudHM6IjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBPVVRQVVRfQ09MVU1OID0gInRleHQ6IjsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW11bXSBjb2x1bW5zID0gbmV3IGJ5dGUgW11bXSB7CisgICAgQnl0ZXMudG9CeXRlcyhJTlBVVF9DT0xVTU4pLAorICAgIEJ5dGVzLnRvQnl0ZXMoT1VUUFVUX0NPTFVNTikKKyAgfTsKKworICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIFRlc3RUYWJsZU1hcFJlZHVjZSgpIHsKKyAgICBzdXBlcihJTlBVVF9DT0xVTU4pOworICAgIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcihNVUxUSV9SRUdJT05fVEFCTEVfTkFNRSk7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKElOUFVUX0NPTFVNTikpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihPVVRQVVRfQ09MVU1OKSk7CisgIH0KKworICAvKioKKyAgICogUGFzcyB0aGUgZ2l2ZW4ga2V5IGFuZCBwcm9jZXNzZWQgcmVjb3JkIHJlZHVjZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBQcm9jZXNzQ29udGVudHNNYXBwZXIKKyAgZXh0ZW5kcyBNYXBSZWR1Y2VCYXNlCisgIGltcGxlbWVudHMgVGFibGVNYXA8SW1tdXRhYmxlQnl0ZXNXcml0YWJsZSwgQmF0Y2hVcGRhdGU+IHsKKyAgICAvKioKKyAgICAgKiBQYXNzIHRoZSBrZXksIGFuZCByZXZlcnNlZCB2YWx1ZSB0byByZWR1Y2UKKyAgICAgKiBAcGFyYW0ga2V5IAorICAgICAqIEBwYXJhbSB2YWx1ZSAKKyAgICAgKiBAcGFyYW0gb3V0cHV0IAorICAgICAqIEBwYXJhbSByZXBvcnRlciAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG1hcChJbW11dGFibGVCeXRlc1dyaXRhYmxlIGtleSwgUm93UmVzdWx0IHZhbHVlLAorICAgICAgT3V0cHV0Q29sbGVjdG9yPEltbXV0YWJsZUJ5dGVzV3JpdGFibGUsIEJhdGNoVXBkYXRlPiBvdXRwdXQsCisgICAgICBSZXBvcnRlciByZXBvcnRlcikgCisgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICh2YWx1ZS5zaXplKCkgIT0gMSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlRoZXJlIHNob3VsZCBvbmx5IGJlIG9uZSBpbnB1dCBjb2x1bW4iKTsKKyAgICAgIH0KKyAgICAgIGJ5dGUgW11bXSBrZXlzID0gdmFsdWUua2V5U2V0KCkudG9BcnJheShuZXcgYnl0ZSBbdmFsdWUuc2l6ZSgpXVtdKTsKKyAgICAgIGlmKCFCeXRlcy5lcXVhbHMoa2V5c1swXSwgQnl0ZXMudG9CeXRlcyhJTlBVVF9DT0xVTU4pKSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIldyb25nIGlucHV0IGNvbHVtbi4gRXhwZWN0ZWQ6ICIgKyBJTlBVVF9DT0xVTU4KKyAgICAgICAgICAgICsgIiBidXQgZ290OiAiICsga2V5c1swXSk7CisgICAgICB9CisKKyAgICAgIC8vIEdldCB0aGUgb3JpZ2luYWwgdmFsdWUgYW5kIHJldmVyc2UgaXQKKyAgICAgIAorICAgICAgU3RyaW5nIG9yaWdpbmFsVmFsdWUgPQorICAgICAgICBuZXcgU3RyaW5nKHZhbHVlLmdldChrZXlzWzBdKS5nZXRWYWx1ZSgpLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpOworICAgICAgU3RyaW5nQnVpbGRlciBuZXdWYWx1ZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICBmb3IoaW50IGkgPSBvcmlnaW5hbFZhbHVlLmxlbmd0aCgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgbmV3VmFsdWUuYXBwZW5kKG9yaWdpbmFsVmFsdWUuY2hhckF0KGkpKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLy8gTm93IHNldCB0aGUgdmFsdWUgdG8gYmUgY29sbGVjdGVkCisKKyAgICAgIEJhdGNoVXBkYXRlIG91dHZhbCA9IG5ldyBCYXRjaFVwZGF0ZShrZXkuZ2V0KCkpOworICAgICAgb3V0dmFsLnB1dChPVVRQVVRfQ09MVU1OLCBCeXRlcy50b0J5dGVzKG5ld1ZhbHVlLnRvU3RyaW5nKCkpKTsKKyAgICAgIG91dHB1dC5jb2xsZWN0KGtleSwgb3V0dmFsKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IGEgbWFwL3JlZHVjZSBhZ2FpbnN0IGEgbXVsdGktcmVnaW9uIHRhYmxlCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aVJlZ2lvblRhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBydW5UZXN0T25UYWJsZShuZXcgSFRhYmxlKGNvbmYsIE1VTFRJX1JFR0lPTl9UQUJMRV9OQU1FKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgcnVuVGVzdE9uVGFibGUoSFRhYmxlIHRhYmxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE1pbmlNUkNsdXN0ZXIgbXJDbHVzdGVyID0gbmV3IE1pbmlNUkNsdXN0ZXIoMiwgZnMuZ2V0VXJpKCkudG9TdHJpbmcoKSwgMSk7CisKKyAgICBKb2JDb25mIGpvYkNvbmYgPSBudWxsOworICAgIHRyeSB7CisgICAgICBMT0cuaW5mbygiQmVmb3JlIG1hcC9yZWR1Y2Ugc3RhcnR1cCIpOworICAgICAgam9iQ29uZiA9IG5ldyBKb2JDb25mKGNvbmYsIFRlc3RUYWJsZU1hcFJlZHVjZS5jbGFzcyk7CisgICAgICBqb2JDb25mLnNldEpvYk5hbWUoInByb2Nlc3MgY29sdW1uIGNvbnRlbnRzIik7CisgICAgICBqb2JDb25mLnNldE51bVJlZHVjZVRhc2tzKDEpOworICAgICAgVGFibGVNYXBSZWR1Y2VVdGlsLmluaXRUYWJsZU1hcEpvYihCeXRlcy50b1N0cmluZyh0YWJsZS5nZXRUYWJsZU5hbWUoKSksCisgICAgICAgIElOUFVUX0NPTFVNTiwgUHJvY2Vzc0NvbnRlbnRzTWFwcGVyLmNsYXNzLAorICAgICAgICBJbW11dGFibGVCeXRlc1dyaXRhYmxlLmNsYXNzLCBCYXRjaFVwZGF0ZS5jbGFzcywgam9iQ29uZik7CisgICAgICBUYWJsZU1hcFJlZHVjZVV0aWwuaW5pdFRhYmxlUmVkdWNlSm9iKEJ5dGVzLnRvU3RyaW5nKHRhYmxlLmdldFRhYmxlTmFtZSgpKSwKKyAgICAgICAgSWRlbnRpdHlUYWJsZVJlZHVjZS5jbGFzcywgam9iQ29uZik7CisgICAgICAgICAgICAKKyAgICAgIExPRy5pbmZvKCJTdGFydGVkICIgKyBCeXRlcy50b1N0cmluZyh0YWJsZS5nZXRUYWJsZU5hbWUoKSkpOworICAgICAgSm9iQ2xpZW50LnJ1bkpvYihqb2JDb25mKTsKKyAgICAgIExPRy5pbmZvKCJBZnRlciBtYXAvcmVkdWNlIGNvbXBsZXRpb24iKTsKKworICAgICAgLy8gdmVyaWZ5IG1hcC1yZWR1Y2UgcmVzdWx0cworICAgICAgdmVyaWZ5KEJ5dGVzLnRvU3RyaW5nKHRhYmxlLmdldFRhYmxlTmFtZSgpKSk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIG1yQ2x1c3Rlci5zaHV0ZG93bigpOworICAgICAgaWYgKGpvYkNvbmYgIT0gbnVsbCkgeworICAgICAgICBGaWxlVXRpbC5mdWxseURlbGV0ZShuZXcgRmlsZShqb2JDb25mLmdldCgiaGFkb29wLnRtcC5kaXIiKSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCB2ZXJpZnkoU3RyaW5nIHRhYmxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRhYmxlTmFtZSk7CisgICAgYm9vbGVhbiB2ZXJpZmllZCA9IGZhbHNlOworICAgIGxvbmcgcGF1c2UgPSBjb25mLmdldExvbmcoImhiYXNlLmNsaWVudC5wYXVzZSIsIDUgKiAxMDAwKTsKKyAgICBpbnQgbnVtUmV0cmllcyA9IGNvbmYuZ2V0SW50KCJoYmFzZS5jbGllbnQucmV0cmllcy5udW1iZXIiLCA1KTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bVJldHJpZXM7IGkrKykgeworICAgICAgdHJ5IHsKKyAgICAgICAgTE9HLmluZm8oIlZlcmlmaWNhdGlvbiBhdHRlbXB0ICMiICsgaSk7CisgICAgICAgIHZlcmlmeUF0dGVtcHQodGFibGUpOworICAgICAgICB2ZXJpZmllZCA9IHRydWU7CisgICAgICAgIGJyZWFrOworICAgICAgfSBjYXRjaCAoTnVsbFBvaW50ZXJFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBJZiBoZXJlLCBhIGNlbGwgd2FzIGVtcHR5LiAgUHJlc3VtZSBpdHMgYmVjYXVzZSB1cGRhdGVzIGNhbWUgaW4KKyAgICAgICAgLy8gYWZ0ZXIgdGhlIHNjYW5uZXIgaGFkIGJlZW4gb3BlbmVkLiAgV2FpdCBhIHdoaWxlIGFuZCByZXRyeS4KKyAgICAgICAgTE9HLmRlYnVnKCJWZXJpZmljYXRpb24gYXR0ZW1wdCBmYWlsZWQ6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICB9CisgICAgICB0cnkgeworICAgICAgICBUaHJlYWQuc2xlZXAocGF1c2UpOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAvLyBjb250aW51ZQorICAgICAgfQorICAgIH0KKyAgICBhc3NlcnRUcnVlKHZlcmlmaWVkKTsKKyAgfQorCisgIC8qKgorICAgKiBMb29rcyBhdCBldmVyeSB2YWx1ZSBvZiB0aGUgbWFwcmVkdWNlIG91dHB1dCBhbmQgdmVyaWZpZXMgdGhhdCBpbmRlZWQKKyAgICogdGhlIHZhbHVlcyBoYXZlIGJlZW4gcmV2ZXJzZWQuCisgICAqIEBwYXJhbSB0YWJsZSBUYWJsZSB0byBzY2FuLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgd2UgZmFpbGVkIHRvIGZpbmQgYSBjZWxsIHZhbHVlCisgICAqLworICBwcml2YXRlIHZvaWQgdmVyaWZ5QXR0ZW1wdChmaW5hbCBIVGFibGUgdGFibGUpIHRocm93cyBJT0V4Y2VwdGlvbiwgTnVsbFBvaW50ZXJFeGNlcHRpb24geworICAgIFNjYW5uZXIgc2Nhbm5lciA9CisgICAgICB0YWJsZS5nZXRTY2FubmVyKGNvbHVtbnMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICB0cnkgeworICAgICAgZm9yIChSb3dSZXN1bHQgciA6IHNjYW5uZXIpIHsKKyAgICAgICAgaWYgKExPRy5pc0RlYnVnRW5hYmxlZCgpKSB7CisgICAgICAgICAgaWYgKHIuc2l6ZSgpID4gMiApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVG9vIG1hbnkgcmVzdWx0cywgZXhwZWN0ZWQgMiBnb3QgIiArCisgICAgICAgICAgICAgIHIuc2l6ZSgpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnl0ZVtdIGZpcnN0VmFsdWUgPSBudWxsOworICAgICAgICBieXRlW10gc2Vjb25kVmFsdWUgPSBudWxsOworICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICBmb3IoTWFwLkVudHJ5PGJ5dGUgW10sIENlbGw+IGU6IHIuZW50cnlTZXQoKSkgeworICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgICAgICBmaXJzdFZhbHVlID0gZS5nZXRWYWx1ZSgpLmdldFZhbHVlKCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChjb3VudCA9PSAxKSB7CisgICAgICAgICAgICBzZWNvbmRWYWx1ZSA9IGUuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpOworICAgICAgICAgIH0KKyAgICAgICAgICBjb3VudCsrOworICAgICAgICAgIGlmIChjb3VudCA9PSAyKSB7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIFN0cmluZyBmaXJzdCA9ICIiOworICAgICAgICBpZiAoZmlyc3RWYWx1ZSA9PSBudWxsKSB7CisgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKEJ5dGVzLnRvU3RyaW5nKHIuZ2V0Um93KCkpICsKKyAgICAgICAgICAgICI6IGZpcnN0IHZhbHVlIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBmaXJzdCA9IG5ldyBTdHJpbmcoZmlyc3RWYWx1ZSwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICAgICAgCisgICAgICAgIFN0cmluZyBzZWNvbmQgPSAiIjsKKyAgICAgICAgaWYgKHNlY29uZFZhbHVlID09IG51bGwpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oQnl0ZXMudG9TdHJpbmcoci5nZXRSb3coKSkgKworICAgICAgICAgICAgIjogc2Vjb25kIHZhbHVlIGlzIG51bGwiKTsKKyAgICAgICAgfQorICAgICAgICBieXRlW10gc2Vjb25kUmV2ZXJzZWQgPSBuZXcgYnl0ZVtzZWNvbmRWYWx1ZS5sZW5ndGhdOworICAgICAgICBmb3IgKGludCBpID0gMCwgaiA9IHNlY29uZFZhbHVlLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tLCBpKyspIHsKKyAgICAgICAgICBzZWNvbmRSZXZlcnNlZFtpXSA9IHNlY29uZFZhbHVlW2pdOworICAgICAgICB9CisgICAgICAgIHNlY29uZCA9IG5ldyBTdHJpbmcoc2Vjb25kUmV2ZXJzZWQsIEhDb25zdGFudHMuVVRGOF9FTkNPRElORyk7CisKKyAgICAgICAgaWYgKGZpcnN0LmNvbXBhcmVUbyhzZWNvbmQpICE9IDApIHsKKyAgICAgICAgICBpZiAoTE9HLmlzRGVidWdFbmFibGVkKCkpIHsKKyAgICAgICAgICAgIExPRy5kZWJ1Zygic2Vjb25kIGtleSBpcyBub3QgdGhlIHJldmVyc2Ugb2YgZmlyc3QuIHJvdz0iICsKKyAgICAgICAgICAgICAgICByLmdldFJvdygpICsgIiwgZmlyc3QgdmFsdWU9IiArIGZpcnN0ICsgIiwgc2Vjb25kIHZhbHVlPSIgKworICAgICAgICAgICAgICAgIHNlY29uZCk7CisgICAgICAgICAgfQorICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzY2FubmVyLmNsb3NlKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvT09NRUhNYXN0ZXIuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL21hc3Rlci9PT01FSE1hc3Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NzU5MmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9tYXN0ZXIvT09NRUhNYXN0ZXIuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSE1zZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKKworLyoqCisgKiBBbiBITWFzdGVyIHRoYXQgcnVucyBvdXQgb2YgbWVtb3J5LgorICogRXZlcnl0aW1lIGEgcmVnaW9uIHNlcnZlciByZXBvcnRzIGluLCBhZGQgdG8gdGhlIHJldGFpbmVkIGhlYXAgb2YgbWVtb3J5LgorICogTmVlZHMgdG8gYmUgc3RhcnRlZCBtYW51YWxseSBhcyBpbgorICogPGNvZGU+JHtIQkFTRV9IT01FfS9iaW4vaGJhc2UgLi9iaW4vaGJhc2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuT09NRUhNYXN0ZXIgc3RhcnQvY29kZT4uCisgKi8KK3B1YmxpYyBjbGFzcyBPT01FSE1hc3RlciBleHRlbmRzIEhNYXN0ZXIgeworICBwcml2YXRlIExpc3Q8Ynl0ZSBbXT4gcmV0YWluZXIgPSBuZXcgQXJyYXlMaXN0PGJ5dGVbXT4oKTsKKyAgCisgIHB1YmxpYyBPT01FSE1hc3RlcihIQmFzZUNvbmZpZ3VyYXRpb24gY29uZikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlcihjb25mKTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBITXNnW10gcmVnaW9uU2VydmVyUmVwb3J0KEhTZXJ2ZXJJbmZvIHNlcnZlckluZm8sIEhNc2dbXSBtc2dzLCAKKyAgICBIUmVnaW9uSW5mb1tdIG1vc3RMb2FkZWRSZWdpb25zKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFJldGFpbiAxTS4KKyAgICB0aGlzLnJldGFpbmVyLmFkZChuZXcgYnl0ZSBbMTAyNCAqIDEwMjRdKTsKKyAgICByZXR1cm4gc3VwZXIucmVnaW9uU2VydmVyUmVwb3J0KHNlcnZlckluZm8sIG1zZ3MsIG1vc3RMb2FkZWRSZWdpb25zKTsKKyAgfQorCisgIC8qKgorICAgKiBAcGFyYW0gYXJncworICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgeworICAgIGRvTWFpbihhcmdzLCBPT01FSE1hc3Rlci5jbGFzcyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9EaXNhYmxlZFRlc3RSZWdpb25TZXJ2ZXJFeGl0LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvRGlzYWJsZWRUZXN0UmVnaW9uU2VydmVyRXhpdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5MTQwY2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvRGlzYWJsZWRUZXN0UmVnaW9uU2VydmVyRXhpdC5qYXZhCkBAIC0wLDAgKzEsMjA3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5Mb2NhbEhCYXNlQ2x1c3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSEJhc2VBZG1pbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRlc3RzIHJlZ2lvbiBzZXJ2ZXIgZmFpbG92ZXIgd2hlbiBhIHJlZ2lvbiBzZXJ2ZXIgZXhpdHMgYm90aCBjbGVhbmx5IGFuZAorICogd2hlbiBpdCBhYm9ydHMuCisgKi8KK3B1YmxpYyBjbGFzcyBEaXNhYmxlZFRlc3RSZWdpb25TZXJ2ZXJFeGl0IGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworICBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgIEhUYWJsZSB0YWJsZTsKKworICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIERpc2FibGVkVGVzdFJlZ2lvblNlcnZlckV4aXQoKSB7CisgICAgc3VwZXIoMik7CisgICAgY29uZi5zZXRJbnQoImlwYy5jbGllbnQuY29ubmVjdC5tYXgucmV0cmllcyIsIDUpOyAvLyByZWR1Y2UgaXBjIHJldHJpZXMKKyAgICBjb25mLnNldEludCgiaXBjLmNsaWVudC50aW1lb3V0IiwgMTAwMDApOyAgICAgICAgIC8vIGFuZCBpcGMgdGltZW91dCAKKyAgICBjb25mLnNldEludCgiaGJhc2UuY2xpZW50LnBhdXNlIiwgMTAwMDApOyAgICAgICAgIC8vIGluY3JlYXNlIGNsaWVudCB0aW1lb3V0CisgICAgY29uZi5zZXRJbnQoImhiYXNlLmNsaWVudC5yZXRyaWVzLm51bWJlciIsIDEwKTsgICAvLyBpbmNyZWFzZSBIQmFzZSByZXRyaWVzCisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IGFib3J0IG9mIHJlZ2lvbiBzZXJ2ZXIuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RBYm9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gV2hlbiB0aGUgTUVUQSB0YWJsZSBjYW4gYmUgb3BlbmVkLCB0aGUgcmVnaW9uIHNlcnZlcnMgYXJlIHJ1bm5pbmcKKyAgICBuZXcgSFRhYmxlKGNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKyAgICAvLyBDcmVhdGUgdGFibGUgYW5kIGFkZCBhIHJvdy4KKyAgICBmaW5hbCBTdHJpbmcgdGFibGVOYW1lID0gZ2V0TmFtZSgpOworICAgIGJ5dGUgW10gcm93ID0gY3JlYXRlVGFibGVBbmRBZGRSb3codGFibGVOYW1lKTsKKyAgICAvLyBTdGFydCB1cCBhIG5ldyByZWdpb24gc2VydmVyIHRvIHRha2Ugb3ZlciBzZXJ2aW5nIG9mIHJvb3QgYW5kIG1ldGEKKyAgICAvLyBhZnRlciB3ZSBzaHV0IGRvd24gdGhlIGN1cnJlbnQgbWV0YS9yb290IGhvc3QuCisgICAgdGhpcy5jbHVzdGVyLnN0YXJ0UmVnaW9uU2VydmVyKCk7CisgICAgLy8gTm93IGFib3J0IHRoZSBtZXRhIHJlZ2lvbiBzZXJ2ZXIgYW5kIHdhaXQgZm9yIGl0IHRvIGdvIGRvd24gYW5kIGNvbWUgYmFjaworICAgIHN0b3BPckFib3J0TWV0YVJlZ2lvblNlcnZlcih0cnVlKTsKKyAgICAvLyBWZXJpZnkgdGhhdCBldmVyeXRoaW5nIGlzIGJhY2sgdXAuCisgICAgTE9HLmluZm8oIlN0YXJ0aW5nIHVwIHRoZSB2ZXJpZmljYXRpb24gdGhyZWFkIGZvciAiICsgZ2V0TmFtZSgpKTsKKyAgICBUaHJlYWQgdCA9IHN0YXJ0VmVyaWZpY2F0aW9uVGhyZWFkKHRhYmxlTmFtZSwgcm93KTsKKyAgICB0LnN0YXJ0KCk7CisgICAgdGhyZWFkRHVtcGluZ0pvaW4odCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IGFib3J0IG9mIHJlZ2lvbiBzZXJ2ZXIuCisgICAqIFRlc3QgaXMgZmxha2V5IHVwIG9uIGh1ZHNvbi4gIE5lZWRzIHdvcmsuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RDbGVhbkV4aXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFdoZW4gdGhlIE1FVEEgdGFibGUgY2FuIGJlIG9wZW5lZCwgdGhlIHJlZ2lvbiBzZXJ2ZXJzIGFyZSBydW5uaW5nCisgICAgbmV3IEhUYWJsZSh0aGlzLmNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKyAgICAvLyBDcmVhdGUgdGFibGUgYW5kIGFkZCBhIHJvdy4KKyAgICBmaW5hbCBTdHJpbmcgdGFibGVOYW1lID0gZ2V0TmFtZSgpOworICAgIGJ5dGUgW10gcm93ID0gY3JlYXRlVGFibGVBbmRBZGRSb3codGFibGVOYW1lKTsKKyAgICAvLyBTdGFydCB1cCBhIG5ldyByZWdpb24gc2VydmVyIHRvIHRha2Ugb3ZlciBzZXJ2aW5nIG9mIHJvb3QgYW5kIG1ldGEKKyAgICAvLyBhZnRlciB3ZSBzaHV0IGRvd24gdGhlIGN1cnJlbnQgbWV0YS9yb290IGhvc3QuCisgICAgdGhpcy5jbHVzdGVyLnN0YXJ0UmVnaW9uU2VydmVyKCk7CisgICAgLy8gTm93IGFib3J0IHRoZSBtZXRhIHJlZ2lvbiBzZXJ2ZXIgYW5kIHdhaXQgZm9yIGl0IHRvIGdvIGRvd24gYW5kIGNvbWUgYmFjaworICAgIHN0b3BPckFib3J0TWV0YVJlZ2lvblNlcnZlcihmYWxzZSk7CisgICAgLy8gVmVyaWZ5IHRoYXQgZXZlcnl0aGluZyBpcyBiYWNrIHVwLgorICAgIExPRy5pbmZvKCJTdGFydGluZyB1cCB0aGUgdmVyaWZpY2F0aW9uIHRocmVhZCBmb3IgIiArIGdldE5hbWUoKSk7CisgICAgVGhyZWFkIHQgPSBzdGFydFZlcmlmaWNhdGlvblRocmVhZCh0YWJsZU5hbWUsIHJvdyk7CisgICAgdC5zdGFydCgpOworICAgIHRocmVhZER1bXBpbmdKb2luKHQpOworICB9CisgIAorICBwcml2YXRlIGJ5dGUgW10gY3JlYXRlVGFibGVBbmRBZGRSb3coZmluYWwgU3RyaW5nIHRhYmxlTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcih0YWJsZU5hbWUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkpKTsKKyAgICBIQmFzZUFkbWluIGFkbWluID0gbmV3IEhCYXNlQWRtaW4oY29uZik7CisgICAgYWRtaW4uY3JlYXRlVGFibGUoZGVzYyk7CisgICAgLy8gcHV0IHNvbWUgdmFsdWVzIGluIHRoZSB0YWJsZQorICAgIHRoaXMudGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRhYmxlTmFtZSk7CisgICAgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJyb3cxIik7CisgICAgQmF0Y2hVcGRhdGUgYiA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgIGIucHV0KEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSwgQnl0ZXMudG9CeXRlcyh0YWJsZU5hbWUpKTsKKyAgICB0YWJsZS5jb21taXQoYik7CisgICAgcmV0dXJuIHJvdzsKKyAgfQorCisgIC8qCisgICAqIFN0b3AgdGhlIHJlZ2lvbiBzZXJ2ZXIgc2VydmluZyB0aGUgbWV0YSByZWdpb24gYW5kIHdhaXQgZm9yIHRoZSBtZXRhIHJlZ2lvbgorICAgKiB0byBnZXQgcmVhc3NpZ25lZC4gVGhpcyBpcyBhbHdheXMgdGhlIG1vc3QgcHJvYmxlbWF0aWMgY2FzZS4KKyAgICogCisgICAqIEBwYXJhbSBhYm9ydCBzZXQgdG8gdHJ1ZSBpZiByZWdpb24gc2VydmVyIHNob3VsZCBiZSBhYm9ydGVkLCBpZiBmYWxzZSBpdAorICAgKiBpcyBqdXN0IHNodXQgZG93bi4KKyAgICovCisgIHByaXZhdGUgdm9pZCBzdG9wT3JBYm9ydE1ldGFSZWdpb25TZXJ2ZXIoYm9vbGVhbiBhYm9ydCkgeworICAgIExpc3Q8TG9jYWxIQmFzZUNsdXN0ZXIuUmVnaW9uU2VydmVyVGhyZWFkPiByZWdpb25UaHJlYWRzID0KKyAgICAgIGNsdXN0ZXIuZ2V0UmVnaW9uVGhyZWFkcygpOworICAgIAorICAgIGludCBzZXJ2ZXIgPSAtMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZ2lvblRocmVhZHMuc2l6ZSgpICYmIHNlcnZlciA9PSAtMTsgaSsrKSB7CisgICAgICBIUmVnaW9uU2VydmVyIHMgPSByZWdpb25UaHJlYWRzLmdldChpKS5nZXRSZWdpb25TZXJ2ZXIoKTsKKyAgICAgIENvbGxlY3Rpb248SFJlZ2lvbj4gcmVnaW9ucyA9IHMuZ2V0T25saW5lUmVnaW9ucygpOworICAgICAgZm9yIChIUmVnaW9uIHIgOiByZWdpb25zKSB7CisgICAgICAgIGlmIChCeXRlcy5lcXVhbHMoci5nZXRUYWJsZURlc2MoKS5nZXROYW1lKCksCisgICAgICAgICAgICBIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSkpIHsKKyAgICAgICAgICBzZXJ2ZXIgPSBpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGlmIChzZXJ2ZXIgPT0gLTEpIHsKKyAgICAgIExPRy5mYXRhbCgiY291bGQgbm90IGZpbmQgcmVnaW9uIHNlcnZlciBzZXJ2aW5nIG1ldGEgcmVnaW9uIik7CisgICAgICBmYWlsKCk7CisgICAgfQorICAgIGlmIChhYm9ydCkgeworICAgICAgdGhpcy5jbHVzdGVyLmFib3J0UmVnaW9uU2VydmVyKHNlcnZlcik7CisgICAgICAKKyAgICB9IGVsc2UgeworICAgICAgdGhpcy5jbHVzdGVyLnN0b3BSZWdpb25TZXJ2ZXIoc2VydmVyKTsKKyAgICB9CisgICAgTE9HLmluZm8odGhpcy5jbHVzdGVyLndhaXRPblJlZ2lvblNlcnZlcihzZXJ2ZXIpICsgIiBoYXMgYmVlbiAiICsKKyAgICAgICAgKGFib3J0ID8gImFib3J0ZWQiIDogInNodXQgZG93biIpKTsKKyAgfQorICAKKyAgLyoKKyAgICogUnVuIHZlcmlmaWNhdGlvbiBpbiBhIHRocmVhZCBzbyBJIGNhbiBjb25jdXJyZW50bHkgcnVuIGEgdGhyZWFkLWR1bXBlcgorICAgKiB3aGlsZSB3ZSdyZSB3YWl0aW5nIChiZWNhdXNlIGluIHRoaXMgdGVzdCBzb21ldGltZXMgdGhlIG1ldGEgc2Nhbm5lcgorICAgKiBsb29rcyB0byBiZSBiZSBzdHVjaykuCisgICAqIEBwYXJhbSB0YWJsZU5hbWUgTmFtZSBvZiB0YWJsZSB0byBmaW5kLgorICAgKiBAcGFyYW0gcm93IFJvdyB3ZSBleHBlY3QgdG8gZmluZC4KKyAgICogQHJldHVybiBWZXJpZmljYXRpb24gdGhyZWFkLiAgQ2FsbGVyIG5lZWRzIHRvIGNhbGxzIHN0YXJ0IG9uIGl0LgorICAgKi8KKyAgcHJpdmF0ZSBUaHJlYWQgc3RhcnRWZXJpZmljYXRpb25UaHJlYWQoZmluYWwgU3RyaW5nIHRhYmxlTmFtZSwKKyAgICAgIGZpbmFsIGJ5dGUgW10gcm93KSB7CisgICAgUnVubmFibGUgcnVubmFibGUgPSBuZXcgUnVubmFibGUoKSB7CisgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgLy8gTm93IHRyeSB0byBvcGVuIGEgc2Nhbm5lciBvbiB0aGUgbWV0YSB0YWJsZS4gU2hvdWxkIHN0YWxsIHVudGlsCisgICAgICAgICAgLy8gbWV0YSBzZXJ2ZXIgY29tZXMgYmFjayB1cC4KKyAgICAgICAgICBIVGFibGUgdCA9IG5ldyBIVGFibGUoY29uZiwgSENvbnN0YW50cy5NRVRBX1RBQkxFX05BTUUpOworICAgICAgICAgIFNjYW5uZXIgcyA9CisgICAgICAgICAgICB0LmdldFNjYW5uZXIoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZX0FSUkFZLAorICAgICAgICAgICAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICAgIAorICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgTE9HLmZhdGFsKCJjb3VsZCBub3QgcmUtb3BlbiBtZXRhIHRhYmxlIGJlY2F1c2UiLCBlKTsKKyAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0KKyAgICAgICAgU2Nhbm5lciBzY2FubmVyID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY2xpZW50IGNhbiBmaW5kIHRoZSBkYXRhIGFmdGVyIHRoZSByZWdpb24gaGFzIG1vdmVkCisgICAgICAgICAgLy8gdG8gYSBkaWZmZXJlbnQgc2VydmVyCisgICAgICAgICAgc2Nhbm5lciA9CisgICAgICAgICAgICB0YWJsZS5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwKKyAgICAgICAgICAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XKTsKKyAgICAgICAgICBMT0cuaW5mbygiT2J0YWluZWQgc2Nhbm5lciAiICsgc2Nhbm5lcik7CisgICAgICAgICAgZm9yIChSb3dSZXN1bHQgciA6IHNjYW5uZXIpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHIuZ2V0Um93KCksIHJvdykpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDEsIHIuc2l6ZSgpKTsKKyAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IHIuZ2V0KEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwoYnl0ZXMpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSh0YWJsZU5hbWUuZXF1YWxzKEJ5dGVzLnRvU3RyaW5nKGJ5dGVzKSkpOworICAgICAgICAgIH0KKyAgICAgICAgICBMT0cuaW5mbygiU3VjY2VzcyEiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICBpZiAoc2Nhbm5lciAhPSBudWxsKSB7CisgICAgICAgICAgICBMT0cuaW5mbygiQ2xvc2luZyBzY2FubmVyICIgKyBzY2FubmVyKTsKKyAgICAgICAgICAgIHNjYW5uZXIuY2xvc2UoKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9OworICAgIHJldHVybiBuZXcgVGhyZWFkKHJ1bm5hYmxlKTsKKyAgfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9PT01FUmVnaW9uU2VydmVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvT09NRVJlZ2lvblNlcnZlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxMzBiYWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvT09NRVJlZ2lvblNlcnZlci5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNvbmZpZ3VyYXRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3M7CisKKy8qKgorICogQSByZWdpb24gc2VydmVyIHRoYXQgd2lsbCBPT01FLgorICogRXZlcnl0aW1lIHtAbGluayAjYmF0Y2hVcGRhdGUoVGV4dCwgbG9uZywgQmF0Y2hVcGRhdGUpfSBpcyBjYWxsZWQsIHdlIGFkZAorICoga2VlcCBhcm91bmQgYSByZWZlcmVuY2UgdG8gdGhlIGJhdGNoLiAgVXNlIHRoaXMgY2xhc3MgdG8gdGVzdCBPT01FIGV4dHJlbWVzLgorICogTmVlZHMgdG8gYmUgc3RhcnRlZCBtYW51YWxseSBhcyBpbgorICogPGNvZGU+JHtIQkFTRV9IT01FfS9iaW4vaGJhc2UgLi9iaW4vaGJhc2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuT09NRVJlZ2lvblNlcnZlciBzdGFydDwvY29kZT4uCisgKi8KK3B1YmxpYyBjbGFzcyBPT01FUmVnaW9uU2VydmVyIGV4dGVuZHMgSFJlZ2lvblNlcnZlciB7CisgIHByaXZhdGUgTGlzdDxCYXRjaFVwZGF0ZT4gcmV0YWluZXIgPSBuZXcgQXJyYXlMaXN0PEJhdGNoVXBkYXRlPigpOworCisgIHB1YmxpYyBPT01FUmVnaW9uU2VydmVyKEhCYXNlQ29uZmlndXJhdGlvbiBjb25mKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHN1cGVyKGNvbmYpOworICB9CisKKyAgcHVibGljIE9PTUVSZWdpb25TZXJ2ZXIoSFNlcnZlckFkZHJlc3MgYWRkcmVzcywgSEJhc2VDb25maWd1cmF0aW9uIGNvbmYpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3VwZXIoYWRkcmVzcywgY29uZik7CisgIH0KKyAgCisgIHB1YmxpYyB2b2lkIGJhdGNoVXBkYXRlKGJ5dGUgW10gcmVnaW9uTmFtZSwgQmF0Y2hVcGRhdGUgYikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBzdXBlci5iYXRjaFVwZGF0ZShyZWdpb25OYW1lLCBiLCAtMUwpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzA7IGkrKykgeworICAgICAgLy8gQWRkIHRoZSBiYXRjaCB1cGRhdGUgMzAgdGltZXMgdG8gYnJpbmcgb24gdGhlIE9PTUUgZmFzdGVyLgorICAgICAgdGhpcy5yZXRhaW5lci5hZGQoYik7CisgICAgfQorICB9CisgIAorICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CisgICAgSFJlZ2lvblNlcnZlci5kb01haW4oYXJncywgT09NRVJlZ2lvblNlcnZlci5jbGFzcyk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEF0b21pY0luY3JlbWVudC5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RBdG9taWNJbmNyZW1lbnQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NTFkYWYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RBdG9taWNJbmNyZW1lbnQuamF2YQpAQCAtMCwwICsxLDEyMSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgVGVzdEF0b21pY0luY3JlbWVudCBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0QXRvbWljSW5jcmVtZW50LmNsYXNzKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTlRFTlRTID0gQnl0ZXMudG9CeXRlcygiY29udGVudHM6Iik7CisKKyAgcHVibGljIHZvaWQgdGVzdEluY3JlbWVudCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZSB0YWJsZSA9IG51bGw7CisKKyAgICAgIC8vIFNldHVwCisKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICBkZXNjLmFkZEZhbWlseSgKKyAgICAgICAgICBuZXcgSENvbHVtbkRlc2NyaXB0b3IoQ09OVEVOVFMsICAgICAgICAgICAgICAgLy8gQ29sdW1uIG5hbWUKKyAgICAgICAgICAgICAgMSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF4IHZlcnNpb25zCisgICAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQ09NUFJFU1NJT04sICAgLy8gbm8gY29tcHJlc3Npb24KKyAgICAgICAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9JTl9NRU1PUlksICAgICAgLy8gbm90IGluIG1lbW9yeQorICAgICAgICAgICAgICBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0JMT0NLQ0FDSEUsCisgICAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfTEVOR1RILAorICAgICAgICAgICAgICBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX1RUTCwKKyAgICAgICAgICAgICAgZmFsc2UKKyAgICAgICAgICApCisgICAgICApOworCisgICAgICAvLyBDcmVhdGUgdGhlIHRhYmxlCisKKyAgICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworCisgICAgICB0cnkgeworICAgICAgICAvLyBHaXZlIGNhY2hlIGZsdXNoZXIgYW5kIGxvZyByb2xsZXIgYSBjaGFuY2UgdG8gcnVuCisgICAgICAgIC8vIE90aGVyd2lzZSB3ZSdsbCBuZXZlciBoaXQgdGhlIGJsb29tIGZpbHRlciwganVzdCB0aGUgbWVtY2FjaGUKKyAgICAgICAgVGhyZWFkLnNsZWVwKGNvbmYuZ2V0TG9uZyhIQ29uc3RhbnRzLlRIUkVBRF9XQUtFX0ZSRVFVRU5DWSwgMTAgKiAxMDAwKSAqIDEwKTsKKyAgICAgICAgCisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIGlnbm9yZQorICAgICAgfQorICAgICAgLy8gT3BlbiB0YWJsZQorCisgICAgICB0YWJsZSA9IG5ldyBIVGFibGUoY29uZiwgZGVzYy5nZXROYW1lKCkpOworICAgICAgCisgICAgICBieXRlIFtdIHJvdyA9IEJ5dGVzLnRvQnl0ZXMoImZvbyIpOworICAgICAgYnl0ZSBbXSBjb2x1bW4gPSAiY29udGVudHM6MSIuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICAgIC8vIGluY3JlbWVudCBieSAxOgorICAgICAgYXNzZXJ0RXF1YWxzKDFMLCB0YWJsZS5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgMSkpOworICAgICAgCisgICAgICAvLyBzZXQgYSB3ZWlyZCB2YWx1ZSwgdGhlbiBpbmNyZW1lbnQ6CisgICAgICByb3cgPSBCeXRlcy50b0J5dGVzKCJmb28yIik7CisgICAgICBieXRlIFtdIHZhbHVlID0gezAsMCwyfTsKKyAgICAgIEJhdGNoVXBkYXRlIGJ1ID0gbmV3IEJhdGNoVXBkYXRlKHJvdyk7CisgICAgICBidS5wdXQoY29sdW1uLCB2YWx1ZSk7CisgICAgICB0YWJsZS5jb21taXQoYnUpOworICAgICAgCisgICAgICBhc3NlcnRFcXVhbHMoM0wsIHRhYmxlLmluY3JlbWVudENvbHVtblZhbHVlKHJvdywgY29sdW1uLCAxKSk7CisKKyAgICAgIGFzc2VydEVxdWFscygtMkwsIHRhYmxlLmluY3JlbWVudENvbHVtblZhbHVlKHJvdywgY29sdW1uLCAtNSkpOworICAgICAgYXNzZXJ0RXF1YWxzKC01MDJMLCB0YWJsZS5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgLTUwMCkpOworICAgICAgYXNzZXJ0RXF1YWxzKDE1MDBMLCB0YWJsZS5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgMjAwMikpOworICAgICAgYXNzZXJ0RXF1YWxzKDE1MDFMLCB0YWJsZS5pbmNyZW1lbnRDb2x1bW5WYWx1ZShyb3csIGNvbHVtbiwgMSkpOworCisgICAgICByb3cgPSBCeXRlcy50b0J5dGVzKCJmb28zIik7CisgICAgICBieXRlW10gdmFsdWUyID0gezEsMiwzLDQsNSw2LDcsOCw5fTsKKyAgICAgIGJ1ID0gbmV3IEJhdGNoVXBkYXRlKHJvdyk7CisgICAgICBidS5wdXQoY29sdW1uLCB2YWx1ZTIpOworICAgICAgdGFibGUuY29tbWl0KGJ1KTsKKyAgICAgIAorICAgICAgdHJ5IHsKKyAgICAgICAgdGFibGUuaW5jcmVtZW50Q29sdW1uVmFsdWUocm93LCBjb2x1bW4sIDEpOworICAgICAgICBmYWlsKCk7CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiRXhwZWN0ZWQgZXhjZXB0aW9uOiAiICsgZSk7CisgICAgICAgIC8vIGV4cGVjdGVkIGV4Y2VwdGlvbi4KKyAgICAgIH0KKyAgICAgIAorCisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICBpZiAoZSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgIElPRXhjZXB0aW9uIGkgPSAoSU9FeGNlcHRpb24pIGU7CisgICAgICAgIHRocm93IGk7CisgICAgICB9CisgICAgICBmYWlsKCk7CisgICAgfQorCisgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RCbG9vbUZpbHRlcnMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0Qmxvb21GaWx0ZXJzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTEwNzNlMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0Qmxvb21GaWx0ZXJzLmphdmEKQEAgLTAsMCArMSwyNDcgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJBZGRyZXNzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDbHVzdGVyVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IQmFzZUFkbWluOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIFRlc3RzIHBlci1jb2x1bW4gYmxvb20gZmlsdGVycyAqLworcHVibGljIGNsYXNzIFRlc3RCbG9vbUZpbHRlcnMgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdEJsb29tRmlsdGVycy5jbGFzcyk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT05URU5UUyA9IEJ5dGVzLnRvQnl0ZXMoImNvbnRlbnRzOiIpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW11bXSByb3dzID0geworICAgIEJ5dGVzLnRvQnl0ZXMoIndtandqenl2IiksCisgICAgQnl0ZXMudG9CeXRlcygiYmFpZXRpYnoiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJndWhzZ3hudiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoIm1obnF5Y3RvIiksCisgICAgQnl0ZXMudG9CeXRlcygieGN5cWFmZ3oiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ6aWRvYW1nYiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInRmdGZpcnpkIiksCisgICAgQnl0ZXMudG9CeXRlcygib2thcHFscmciKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ5Y2N3endzcSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInFtb251ZnF1IiksCisgICAgQnl0ZXMudG9CeXRlcygid2xzY3Rld3MiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJta3NkaHFyaSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInd4eGxsb2tqIiksCisgICAgQnl0ZXMudG9CeXRlcygiZXZpdXFwbHMiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJiYXZvdHFtaiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInlpYnF6aGRsIiksCisgICAgQnl0ZXMudG9CeXRlcygiY3NmcW1zeXIiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJndXhsaXl1aCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInB6aWNpZXRqIiksCisgICAgQnl0ZXMudG9CeXRlcygicWR3Z3Jxd28iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ1amZ6ZWNtaSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImR6ZXFmdmZpIiksCisgICAgQnl0ZXMudG9CeXRlcygicGhvZWdzaWoiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJidnVkZmNvdSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImRvd3ptY2l6IiksCisgICAgQnl0ZXMudG9CeXRlcygiZXR2aGtpenAiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJyenVycXljZyIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImtycWZ4dWdlIiksCisgICAgQnl0ZXMudG9CeXRlcygiZ2ZsY29odGQiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJmY3JjeHRwcyIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInFydG92eGRxIiksCisgICAgQnl0ZXMudG9CeXRlcygiYXlweHdyd2kiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJkY2tweXpuciIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoIm1kYWF3bnB6IiksCisgICAgQnl0ZXMudG9CeXRlcygicGFrZGZ2Y2EiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ4amdsZmJleiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInhkc2Vjb2ZpIiksCisgICAgQnl0ZXMudG9CeXRlcygic2pscmZjYWIiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJlYmNqYXd4diIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImhrYWZram15IiksCisgICAgQnl0ZXMudG9CeXRlcygib2ltbXdheG8iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJxY3V6cmF6byIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoIm5xeWRma3drIiksCisgICAgQnl0ZXMudG9CeXRlcygiZnJ5YnZtbGIiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJhbXhtYXF3cyIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImd0a292a2d4IiksCisgICAgQnl0ZXMudG9CeXRlcygidmd3eHJ3c3MiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ4cmh6bWNlcCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInRhZnd6aWlsIiksCisgICAgQnl0ZXMudG9CeXRlcygiZXJqbW5jbnYiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJoZXl6cXpybiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInNvd3Z5aHR1IiksCisgICAgQnl0ZXMudG9CeXRlcygiaGVlaXhnenkiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJrdGNhaGNvYiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImxqaGJ5YmdnIiksCisgICAgQnl0ZXMudG9CeXRlcygiamlxZmNrc2wiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJhbmpka2pobSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInV6Y2djdXhwIiksCisgICAgQnl0ZXMudG9CeXRlcygidnpkaGpxbGEiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJzdmhnd3d6cSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInpoc3d2aGJwIiksCisgICAgQnl0ZXMudG9CeXRlcygidWVjZXlid3kiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJjemtxeWtjdyIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImN0aXNheWlyIiksCisgICAgQnl0ZXMudG9CeXRlcygiaHBwYmdjaXUiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJuaHpnbGpmayIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInZhemlxbGxmIiksCisgICAgQnl0ZXMudG9CeXRlcygibmFydnJyaWoiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJrY2V2YmJxaSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInF5bXVhcW5wIiksCisgICAgQnl0ZXMudG9CeXRlcygicHdxcGZoc3IiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJwZXllaWN1ayIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImt1ZGx3aWhpIiksCisgICAgQnl0ZXMudG9CeXRlcygicGttcWVqbG0iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ5bHd6amZ0bCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInJocXJscWFyIiksCisgICAgQnl0ZXMudG9CeXRlcygieG1mdHZ6c3AiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJpYWVtdGloayIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInltc2JycWN1IiksCisgICAgQnl0ZXMudG9CeXRlcygieWZubGN4dG8iKSwKKyAgICBCeXRlcy50b0J5dGVzKCJubHVxb3BxaCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoIndtcnpodG94IiksCisgICAgQnl0ZXMudG9CeXRlcygicW5mZmhxYmwiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ6eXBxcG5idyIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoIm9pb2toYXRkIiksCisgICAgQnl0ZXMudG9CeXRlcygibWRyYWRkaXUiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ6cW9hdGx0dCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImV3aHVsYnRtIiksCisgICAgQnl0ZXMudG9CeXRlcygibm1zd3BzZGYiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ4c2pldGVxZSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInVmdWJjYm1hIiksCisgICAgQnl0ZXMudG9CeXRlcygicGh5eHZyZHMiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ2aG5mbGRhcCIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoInpycmx5Y21nIiksCisgICAgQnl0ZXMudG9CeXRlcygiYmVjb3RjangiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJ3dmJ1Ym9rbiIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImF2a2dpb3ByIiksCisgICAgQnl0ZXMudG9CeXRlcygibWJxcXhtcnYiKSwKKyAgICBCeXRlcy50b0J5dGVzKCJpYnBsZ3Z1dSIpLAorICAgIEJ5dGVzLnRvQnl0ZXMoImRnaHZwa2djIikKKyAgfTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdW10gdGVzdEtleXMgPSB7CisgICAgICBCeXRlcy50b0J5dGVzKCJhYmNkZWZnaCIpLAorICAgICAgQnl0ZXMudG9CeXRlcygiaWprbG1ub3AiKSwKKyAgICAgIEJ5dGVzLnRvQnl0ZXMoInFyc3R1dnd4IiksCisgICAgICBCeXRlcy50b0J5dGVzKCJ5emFiY2RlZiIpCisgIH07CisgIAorICAvKioKKyAgICogVGVzdCB0aGF0IHVzZXMgYXV0b21hdGljIGJsb29tIGZpbHRlcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBAU3VwcHJlc3NXYXJuaW5ncygibnVsbCIpCisgIHB1YmxpYyB2b2lkIHRlc3RDb21wdXRlZFBhcmFtZXRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgSFRhYmxlIHRhYmxlID0gbnVsbDsKKworICAgIC8vIFNldHVwCisgICAgCisgICAgSFRhYmxlRGVzY3JpcHRvciBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICBkZXNjLmFkZEZhbWlseSgKKyAgICAgICAgbmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTlRFTlRTLCAgICAgICAgICAgICAgIC8vIENvbHVtbiBuYW1lCisgICAgICAgICAgICAxLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYXggdmVyc2lvbnMKKyAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQ09NUFJFU1NJT04sICAgLy8gbm8gY29tcHJlc3Npb24KKyAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfSU5fTUVNT1JZLCAgICAgIC8vIG5vdCBpbiBtZW1vcnkKKyAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfQkxPQ0tDQUNIRSwKKyAgICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfTEVOR1RILAorICAgICAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9UVEwsCisgICAgICAgICAgICB0cnVlCisgICAgICAgICkKKyAgICApOworCisgICAgLy8gQ3JlYXRlIHRoZSB0YWJsZQorCisgICAgSEJhc2VBZG1pbiBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworCisgICAgLy8gT3BlbiB0YWJsZQorCisgICAgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIGRlc2MuZ2V0TmFtZSgpKTsKKworICAgIC8vIFN0b3JlIHNvbWUgdmFsdWVzCisKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKKyAgICAgIGJ5dGUgW10gcm93ID0gcm93c1tpXTsKKyAgICAgIFN0cmluZyB2YWx1ZSA9IEJ5dGVzLnRvU3RyaW5nKHJvdyk7CisgICAgICBCYXRjaFVwZGF0ZSBiID0gbmV3IEJhdGNoVXBkYXRlKHJvdyk7CisgICAgICBiLnB1dChDT05URU5UUywgdmFsdWUuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICB0YWJsZS5jb21taXQoYik7CisgICAgfQorICAgIAorICAgIC8vIEdldCBIUmVnaW9uSW5mbyBmb3Igb3VyIHRhYmxlCisgICAgTWFwPEhSZWdpb25JbmZvLCBIU2VydmVyQWRkcmVzcz4gcmVnaW9ucyA9IHRhYmxlLmdldFJlZ2lvbnNJbmZvKCk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIHJlZ2lvbnMuc2l6ZSgpKTsKKyAgICBIUmVnaW9uSW5mbyBpbmZvID0gbnVsbDsKKyAgICBmb3IgKEhSZWdpb25JbmZvIGhyaTogcmVnaW9ucy5rZXlTZXQoKSkgeworICAgICAgaW5mbyA9IGhyaTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICAKKyAgICAvLyBSZXF1ZXN0IGEgY2FjaGUgZmx1c2gKKyAgICBIUmVnaW9uU2VydmVyIGhycyA9IGNsdXN0ZXIuZ2V0UmVnaW9uU2VydmVyKDApOworICAgIAorICAgIGhycy5nZXRGbHVzaFJlcXVlc3RlcigpLnJlcXVlc3QoaHJzLmdldE9ubGluZVJlZ2lvbihpbmZvLmdldFJlZ2lvbk5hbWUoKSkpOworCisgICAgdHJ5IHsKKyAgICAgIC8vIEdpdmUgY2FjaGUgZmx1c2hlciBhbmQgbG9nIHJvbGxlciBhIGNoYW5jZSB0byBydW4KKyAgICAgIC8vIE90aGVyd2lzZSB3ZSdsbCBuZXZlciBoaXQgdGhlIGJsb29tIGZpbHRlciwganVzdCB0aGUgbWVtY2FjaGUKKyAgICAgIFRocmVhZC5zbGVlcChjb25mLmdldExvbmcoSENvbnN0YW50cy5USFJFQURfV0FLRV9GUkVRVUVOQ1ksIDEwICogMTAwMCkgKiAxMCk7CisgICAgICAKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBpZ25vcmUKKyAgICB9CisgICAgCisgICAgZm9yKGludCBpID0gMDsgaSA8IHRlc3RLZXlzLmxlbmd0aDsgaSsrKSB7CisgICAgICBDZWxsIHZhbHVlID0gdGFibGUuZ2V0KHRlc3RLZXlzW2ldLCBDT05URU5UUyk7CisgICAgICBpZih2YWx1ZSAhPSBudWxsICYmIHZhbHVlLmdldFZhbHVlKCkubGVuZ3RoICE9IDApIHsKKyAgICAgICAgTE9HLmVycm9yKCJub24gZXhpc3RhbnQga2V5OiAiICsgQnl0ZXMudG9TdHJpbmcodGVzdEtleXNbaV0pICsgIiByZXR1cm5lZCB2YWx1ZTogIiArCisgICAgICAgICAgICBCeXRlcy50b1N0cmluZyh2YWx1ZS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIGZhaWwoKTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7CisgICAgICBDZWxsIHZhbHVlID0gdGFibGUuZ2V0KHJvd3NbaV0sIENPTlRFTlRTKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlLmdldFZhbHVlKCkubGVuZ3RoID09IDApIHsKKyAgICAgICAgTE9HLmVycm9yKCJObyB2YWx1ZSByZXR1cm5lZCBmb3Igcm93ICIgKyBCeXRlcy50b1N0cmluZyhyb3dzW2ldKSk7CisgICAgICAgIGZhaWwoKTsKKyAgICAgIH0KKyAgICB9CisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICBpZiAoZSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgIElPRXhjZXB0aW9uIGkgPSAoSU9FeGNlcHRpb24pIGU7CisgICAgICAgIHRocm93IGk7CisgICAgICB9CisgICAgICBmYWlsKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdENvbXBhY3Rpb24uamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0Q29tcGFjdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlMmFjZGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdENvbXBhY3Rpb24uamF2YQpAQCAtMCwwICsxLDE5MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmRmcy5NaW5pREZTQ2x1c3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkhGaWxlU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRlc3QgY29tcGFjdGlvbnMKKyAqLworcHVibGljIGNsYXNzIFRlc3RDb21wYWN0aW9uIGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdENvbXBhY3Rpb24uY2xhc3MuZ2V0TmFtZSgpKTsKKyAgcHJpdmF0ZSBIUmVnaW9uIHIgPSBudWxsOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTFVNTl9GQU1JTFkgPSBDT0xGQU1JTFlfTkFNRTE7CisgIHByaXZhdGUgZmluYWwgYnl0ZSBbXSBTVEFSVFJPVyA9IEJ5dGVzLnRvQnl0ZXMoU1RBUlRfS0VZKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xVTU5fRkFNSUxZX1RFWFQgPSBDT0xVTU5fRkFNSUxZOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NUEFDVElPTl9USFJFU0hPTEQgPSBNQVhWRVJTSU9OUzsKKworICBwcml2YXRlIE1pbmlERlNDbHVzdGVyIGNsdXN0ZXI7CisgIAorICAvKiogY29uc3RydWN0b3IgKi8KKyAgcHVibGljIFRlc3RDb21wYWN0aW9uKCkgeworICAgIHN1cGVyKCk7CisgICAgCisgICAgLy8gU2V0IGNhY2hlIGZsdXNoIHNpemUgdG8gMU1CCisgICAgY29uZi5zZXRJbnQoImhiYXNlLmhyZWdpb24ubWVtY2FjaGUuZmx1c2guc2l6ZSIsIDEwMjQqMTAyNCk7CisgICAgY29uZi5zZXRJbnQoImhiYXNlLmhyZWdpb24ubWVtY2FjaGUuYmxvY2subXVsdGlwbGllciIsIDEwKTsKKyAgICB0aGlzLmNsdXN0ZXIgPSBudWxsOworICB9CisgIAorICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0aGlzLmNsdXN0ZXIgPSBuZXcgTWluaURGU0NsdXN0ZXIoY29uZiwgMiwgdHJ1ZSwgKFN0cmluZ1tdKW51bGwpOworICAgIC8vIE1ha2UgdGhlIGhiYXNlIHJvb3RkaXIgbWF0Y2ggdGhlIG1pbmlkZnMgd2UganVzdCBzcGFuIHVwCisgICAgdGhpcy5jb25mLnNldChIQ29uc3RhbnRzLkhCQVNFX0RJUiwKKyAgICAgIHRoaXMuY2x1c3Rlci5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICAgIHN1cGVyLnNldFVwKCk7CisgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICB0aGlzLnIgPSBjcmVhdGVOZXdIUmVnaW9uKGh0ZCwgbnVsbCwgbnVsbCk7CisgIH0KKyAgCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIEhMb2cgaGxvZyA9IHIuZ2V0TG9nKCk7CisgICAgdGhpcy5yLmNsb3NlKCk7CisgICAgaGxvZy5jbG9zZUFuZERlbGV0ZSgpOworICAgIGlmICh0aGlzLmNsdXN0ZXIgIT0gbnVsbCkgeworICAgICAgc2h1dGRvd25EZnMoY2x1c3Rlcik7CisgICAgfQorICAgIHN1cGVyLnRlYXJEb3duKCk7CisgIH0KKyAgCisgIC8qKgorICAgKiBSdW4gY29tcGFjdGlvbiBhbmQgZmx1c2hpbmcgbWVtY2FjaGUKKyAgICogQXNzZXJ0IGRlbGV0ZXMgZ2V0IGNsZWFuZWQgdXAuCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0Q29tcGFjdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGNyZWF0ZVN0b3JlRmlsZShyKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IENPTVBBQ1RJT05fVEhSRVNIT0xEOyBpKyspIHsKKyAgICAgIGNyZWF0ZVN0b3JlRmlsZShyKTsKKyAgICB9CisgICAgLy8gQWRkIG1vcmUgY29udGVudC4gIE5vdyB0aGVyZSBhcmUgYWJvdXQgNSB2ZXJzaW9ucyBvZiBlYWNoIGNvbHVtbi4KKyAgICAvLyBEZWZhdWx0IGlzIHRoYXQgdGhlcmUgb25seSAzIChNQVhWRVJTSU9OUykgdmVyc2lvbnMgYWxsb3dlZCBwZXIgY29sdW1uLgorICAgIC8vIEFzc2VydCA9PSAzIHdoZW4gd2UgYXNrIGZvciB2ZXJzaW9ucy4KKyAgICBhZGRDb250ZW50KG5ldyBIUmVnaW9uSW5jb21tb24ociksIEJ5dGVzLnRvU3RyaW5nKENPTFVNTl9GQU1JTFkpKTsKKyAgICAvLyBGSVghIQorICAgIENlbGxbXSBjZWxsVmFsdWVzID0gCisgICAgICBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShyLmdldChTVEFSVFJPVywgQ09MVU1OX0ZBTUlMWV9URVhULCAtMSwgMTAwIC8qVG9vIG1hbnkqLykpOworICAgIC8vIEFzc2VydCB0aGF0IEkgY2FuIGdldCAzIHZlcnNpb25zIHNpbmNlIGl0IGlzIHRoZSBtYXggSSBzaG91bGQgZ2V0CisgICAgYXNzZXJ0RXF1YWxzKGNlbGxWYWx1ZXMubGVuZ3RoLCAzKTsKKyAgICByLmZsdXNoY2FjaGUoKTsKKyAgICByLmNvbXBhY3RTdG9yZXMoKTsKKyAgICAvLyBBbHdheXMgMyB2ZXJzaW9ucyBpZiB0aGF0IGlzIHdoYXQgbWF4IHZlcnNpb25zIGlzLgorICAgIGJ5dGUgW10gc2Vjb25kUm93Qnl0ZXMgPSBTVEFSVF9LRVkuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKTsKKyAgICAvLyBJbmNyZW1lbnQgdGhlIGxlYXN0IHNpZ25pZmljYW50IGNoYXJhY3RlciBzbyB3ZSBnZXQgdG8gbmV4dCByb3cuCisgICAgc2Vjb25kUm93Qnl0ZXNbU1RBUlRfS0VZX0JZVEVTLmxlbmd0aCAtIDFdKys7CisgICAgLy8gRklYCisgICAgY2VsbFZhbHVlcyA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHIuZ2V0KHNlY29uZFJvd0J5dGVzLCBDT0xVTU5fRkFNSUxZX1RFWFQsIC0xLCAxMDAvKlRvbyBtYW55Ki8pKTsKKyAgICBMT0cuaW5mbygiQ291bnQgb2YgIiArIEJ5dGVzLnRvU3RyaW5nKHNlY29uZFJvd0J5dGVzKSArICI6ICIgKworICAgICAgY2VsbFZhbHVlcy5sZW5ndGgpOworICAgIGFzc2VydFRydWUoY2VsbFZhbHVlcy5sZW5ndGggPT0gMyk7CisKKyAgICAvLyBOb3cgYWRkIGRlbGV0ZXMgdG8gbWVtY2FjaGUgYW5kIHRoZW4gZmx1c2ggaXQuICBUaGF0IHdpbGwgcHV0IHVzIG92ZXIKKyAgICAvLyB0aGUgY29tcGFjdGlvbiB0aHJlc2hvbGQgb2YgMyBzdG9yZSBmaWxlcy4gIENvbXBhY3RpbmcgdGhlc2Ugc3RvcmUgZmlsZXMKKyAgICAvLyBzaG91bGQgcmVzdWx0IGluIGEgY29tcGFjdGVkIHN0b3JlIGZpbGUgdGhhdCBoYXMgbm8gcmVmZXJlbmNlcyB0byB0aGUKKyAgICAvLyBkZWxldGVkIHJvdy4KKyAgICByLmRlbGV0ZUFsbChzZWNvbmRSb3dCeXRlcywgQ09MVU1OX0ZBTUlMWV9URVhULCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAgICAgIG51bGwpOworICAgIC8vIEFzc2VydCBkZWxldGVkLgorICAgIGFzc2VydE51bGwoci5nZXQoc2Vjb25kUm93Qnl0ZXMsIENPTFVNTl9GQU1JTFlfVEVYVCwgLTEsIDEwMCAvKlRvbyBtYW55Ki8pKTsKKyAgICByLmZsdXNoY2FjaGUoKTsKKyAgICBhc3NlcnROdWxsKHIuZ2V0KHNlY29uZFJvd0J5dGVzLCBDT0xVTU5fRkFNSUxZX1RFWFQsIC0xLCAxMDAgLypUb28gbWFueSovKSk7CisgICAgLy8gQWRkIGEgYml0IG9mIGRhdGEgYW5kIGZsdXNoLiAgU3RhcnQgYWRkaW5nIGF0ICdiYmInLgorICAgIGNyZWF0ZVNtYWxsZXJTdG9yZUZpbGUodGhpcy5yKTsKKyAgICByLmZsdXNoY2FjaGUoKTsKKyAgICAvLyBBc3NlcnQgdGhhdCB0aGUgc2Vjb25kIHJvdyBpcyBzdGlsbCBkZWxldGVkLgorICAgIGNlbGxWYWx1ZXMgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShyLmdldChzZWNvbmRSb3dCeXRlcywKKyAgICAgIENPTFVNTl9GQU1JTFlfVEVYVCwgLTEsIDEwMCAvKlRvbyBtYW55Ki8pKTsKKyAgICBhc3NlcnROdWxsKHIuZ2V0KHNlY29uZFJvd0J5dGVzLCBDT0xVTU5fRkFNSUxZX1RFWFQsIC0xLCAxMDAgLypUb28gbWFueSovKSk7CisgICAgLy8gRm9yY2UgbWFqb3IgY29tcGFjdGlvbi4KKyAgICByLmNvbXBhY3RTdG9yZXModHJ1ZSk7CisgICAgYXNzZXJ0RXF1YWxzKHIuZ2V0U3RvcmUoQ09MVU1OX0ZBTUlMWV9URVhUKS5nZXRTdG9yZWZpbGVzKCkuc2l6ZSgpLCAxKTsKKyAgICBhc3NlcnROdWxsKHIuZ2V0KHNlY29uZFJvd0J5dGVzLCBDT0xVTU5fRkFNSUxZX1RFWFQsIC0xLCAxMDAgLypUb28gbWFueSovKSk7CisgICAgLy8gTWFrZSBzdXJlIHRoZSBzdG9yZSBmaWxlcyBkbyBoYXZlIHNvbWUgJ2FhYScga2V5cyBpbiB0aGVtIC0tIGV4YWN0bHkgMy4KKyAgICAvLyBBbHNvLCB0aGF0IGNvbXBhY3RlZCBzdG9yZSBmaWxlcyBkbyBub3QgaGF2ZSBhbnkgc2Vjb25kUm93Qnl0ZXMgYmVjYXVzZQorICAgIC8vIHRoZXkgd2VyZSBkZWxldGVkLgorICAgIGludCBjb3VudCA9IDA7CisgICAgYm9vbGVhbiBjb250YWluc1N0YXJ0Um93ID0gZmFsc2U7CisgICAgZm9yIChTdG9yZUZpbGUgZjogdGhpcy5yLnN0b3Jlcy5nZXQoQ09MVU1OX0ZBTUlMWV9URVhUKS5nZXRTdG9yZWZpbGVzKCkuCisgICAgICAgIHZhbHVlcygpKSB7CisgICAgICBIRmlsZVNjYW5uZXIgc2Nhbm5lciA9IGYuZ2V0UmVhZGVyKCkuZ2V0U2Nhbm5lcigpOworICAgICAgc2Nhbm5lci5zZWVrVG8oKTsKKyAgICAgIGRvIHsKKyAgICAgICAgYnl0ZSBbXSByb3cgPSBzY2FubmVyLmdldEtleVZhbHVlKCkuZ2V0Um93KCk7CisgICAgICAgIGlmIChCeXRlcy5lcXVhbHMocm93LCBTVEFSVFJPVykpIHsKKyAgICAgICAgICBjb250YWluc1N0YXJ0Um93ID0gdHJ1ZTsKKyAgICAgICAgICBjb3VudCsrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIEFmdGVyIG1ham9yIGNvbXBhY3Rpb24sIHNob3VsZCBiZSBub25lIG9mIHRoZXNlIHJvd3MgaW4gY29tcGFjdGVkCisgICAgICAgICAgLy8gZmlsZS4KKyAgICAgICAgICBhc3NlcnRGYWxzZShCeXRlcy5lcXVhbHMocm93LCBzZWNvbmRSb3dCeXRlcykpOworICAgICAgICB9CisgICAgICB9IHdoaWxlKHNjYW5uZXIubmV4dCgpKTsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZShjb250YWluc1N0YXJ0Um93KTsKKyAgICBhc3NlcnRUcnVlKGNvdW50ID09IDMpOworICAgIC8vIERvIGEgc2ltcGxlIFRUTCB0ZXN0LgorICAgIGZpbmFsIGludCB0dGxJblNlY29uZHMgPSAxOworICAgIGZvciAoU3RvcmUgc3RvcmU6IHRoaXMuci5zdG9yZXMudmFsdWVzKCkpIHsKKyAgICAgIHN0b3JlLnR0bCA9IHR0bEluU2Vjb25kcyAqIDEwMDA7CisgICAgfQorICAgIFRocmVhZC5zbGVlcCh0dGxJblNlY29uZHMgKiAxMDAwKTsKKyAgICByLmNvbXBhY3RTdG9yZXModHJ1ZSk7CisgICAgY291bnQgPSBjb3VudCgpOworICAgIGFzc2VydFRydWUoY291bnQgPT0gMCk7CisgIH0KKyAgCisgIHByaXZhdGUgaW50IGNvdW50KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbnQgY291bnQgPSAwOworICAgIGZvciAoU3RvcmVGaWxlIGY6IHRoaXMuci5zdG9yZXMuCisgICAgICAgIGdldChDT0xVTU5fRkFNSUxZX1RFWFQpLmdldFN0b3JlZmlsZXMoKS52YWx1ZXMoKSkgeworICAgICAgSEZpbGVTY2FubmVyIHNjYW5uZXIgPSBmLmdldFJlYWRlcigpLmdldFNjYW5uZXIoKTsKKyAgICAgIGlmICghc2Nhbm5lci5zZWVrVG8oKSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGRvIHsKKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0gd2hpbGUoc2Nhbm5lci5uZXh0KCkpOworICAgIH0KKyAgICByZXR1cm4gY291bnQ7CisgIH0KKworICBwcml2YXRlIHZvaWQgY3JlYXRlU3RvcmVGaWxlKGZpbmFsIEhSZWdpb24gcmVnaW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb25JbmNvbW1vbiBsb2FkZXIgPSBuZXcgSFJlZ2lvbkluY29tbW9uKHJlZ2lvbik7CisgICAgYWRkQ29udGVudChsb2FkZXIsIEJ5dGVzLnRvU3RyaW5nKENPTFVNTl9GQU1JTFkpKTsKKyAgICBsb2FkZXIuZmx1c2hjYWNoZSgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVNtYWxsZXJTdG9yZUZpbGUoZmluYWwgSFJlZ2lvbiByZWdpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbkluY29tbW9uIGxvYWRlciA9IG5ldyBIUmVnaW9uSW5jb21tb24ocmVnaW9uKTsgCisgICAgYWRkQ29udGVudChsb2FkZXIsIEJ5dGVzLnRvU3RyaW5nKENPTFVNTl9GQU1JTFkpLAorICAgICAgICAoImJiYiIpLmdldEJ5dGVzKCksIG51bGwpOworICAgIGxvYWRlci5mbHVzaGNhY2hlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0RGVsZXRlQWxsLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdERlbGV0ZUFsbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3ZTQxZDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdERlbGV0ZUFsbC5qYXZhCkBAIC0wLDAgKzEsMjM0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IHRoZSBmdW5jdGlvbmFsaXR5IG9mIGRlbGV0ZUFsbC4KKyAqLworcHVibGljIGNsYXNzIFRlc3REZWxldGVBbGwgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0RGVsZXRlQWxsLmNsYXNzKTsKKyAgCisgIHByaXZhdGUgZmluYWwgU3RyaW5nIENPTFVNTl9SRUdFWCA9ICJbYS16QS1aMC05XSo6W2J8Y10/IjsKKyAgCisgIHByaXZhdGUgTWluaURGU0NsdXN0ZXIgbWluaUhkZnM7CisgIAorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIHRyeSB7CisgICAgICB0aGlzLm1pbmlIZGZzID0gbmV3IE1pbmlERlNDbHVzdGVyKHRoaXMuY29uZiwgMSwgdHJ1ZSwgbnVsbCk7CisgICAgICAvLyBTZXQgdGhlIGhiYXNlLnJvb3RkaXIgdG8gYmUgdGhlIGhvbWUgZGlyZWN0b3J5IGluIG1pbmkgZGZzLgorICAgICAgdGhpcy5jb25mLnNldChIQ29uc3RhbnRzLkhCQVNFX0RJUiwKKyAgICAgICAgdGhpcy5taW5pSGRmcy5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoImVycm9yIHN0YXJ0aW5nIE1pbmlERlNDbHVzdGVyIiwgZSk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3RzIGZvciBIQURPT1AtMTU1MC4KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgSFJlZ2lvbkluY29tbW9uIHJlZ2lvbl9pbmNvbW1vbiA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gY3JlYXRlVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICByZWdpb24gPSBjcmVhdGVOZXdIUmVnaW9uKGh0ZCwgbnVsbCwgbnVsbCk7CisgICAgICByZWdpb25faW5jb21tb24gPSBuZXcgSFJlZ2lvbkluY29tbW9uKHJlZ2lvbik7CisgICAgICAKKyAgICAgIC8vIHRlc3QgbWVtY2FjaGUKKyAgICAgIG1ha2VTdXJlSXRXb3JrcyhyZWdpb24sIHJlZ2lvbl9pbmNvbW1vbiwgZmFsc2UpOworICAgICAgLy8gdGVzdCBoc3RvcmUKKyAgICAgIG1ha2VTdXJlSXRXb3JrcyhyZWdpb24sIHJlZ2lvbl9pbmNvbW1vbiwgdHJ1ZSk7CisgICAgICAKKyAgICAgIC8vIHJlZ2V4IHRlc3QgbWVtY2FjaGUKKyAgICAgIG1ha2VTdXJlUmVnZXhXb3JrcyhyZWdpb24sIHJlZ2lvbl9pbmNvbW1vbiwgZmFsc2UpOworICAgICAgLy8gcmVnZXggdGVzdCBoc3RvcmUKKyAgICAgIG1ha2VTdXJlUmVnZXhXb3JrcyhyZWdpb24sIHJlZ2lvbl9pbmNvbW1vbiwgdHJ1ZSk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChyZWdpb24gIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJlZ2lvbi5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmVnaW9uLmdldExvZygpLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgICB9CisgICAgfQorICB9CisgICAgCisgIHByaXZhdGUgdm9pZCBtYWtlU3VyZUl0V29ya3MoSFJlZ2lvbiByZWdpb24sIEhSZWdpb25JbmNvbW1vbiByZWdpb25faW5jb21tb24sIAorICAgIGJvb2xlYW4gZmx1c2gpCisgIHRocm93cyBFeGNlcHRpb257CisgICAgLy8gaW5zZXJ0IGEgZmV3IHZlcnNpb25zIHdvcnRoIG9mIGRhdGEgZm9yIGEgcm93CisgICAgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJ0ZXN0X3JvdyIpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgbG9uZyBwYXN0ID0gbm93IC0gMTAwOworICAgIGxvbmcgZnV0dXJlID0gbm93ICsgMTAwOworICAgIFRocmVhZC5zbGVlcCgxMDApOworICAgIExPRy5pbmZvKCJub3c9IiArIG5vdyArICIsIHBhc3Q9IiArIHBhc3QgKyAiLCBmdXR1cmU9IiArIGZ1dHVyZSk7CisKKyAgICBieXRlIFtdIGNvbEEgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImEiKTsKKyAgICBieXRlIFtdIGNvbEIgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImIiKTsKKyAgICBieXRlIFtdIGNvbEMgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImMiKTsKKyAgICBieXRlIFtdIGNvbEQgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pKTsKKworICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgbm93KTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQSwgY2VsbERhdGEoMCwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgwLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEMsIGNlbGxEYXRhKDAsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sRCwgY2VsbERhdGEoMCwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93LCBwYXN0KTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQSwgY2VsbERhdGEoMSwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgxLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEMsIGNlbGxEYXRhKDEsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sRCwgY2VsbERhdGEoMSwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIAorICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgZnV0dXJlKTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQSwgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgyLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEMsIGNlbGxEYXRhKDIsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sRCwgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9CisKKyAgICAvLyBjYWxsIGRlbGV0ZSBhbGwgYXQgYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBvbmx5IHRoZSBtb3N0IHJlY2VudCBzdHVmZiBpcyBsZWZ0IGJlaGluZAorICAgIHJlZ2lvbi5kZWxldGVBbGwocm93LCBub3csIG51bGwpOworICAgIGlmIChmbHVzaCkge3JlZ2lvbl9pbmNvbW1vbi5mbHVzaGNhY2hlKCk7fSAgICAKKyAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCBmdXR1cmUsIGNlbGxEYXRhKDIsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgcGFzdCwgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgbm93LCBudWxsKTsKKyAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xELCBmdXR1cmUsIGNlbGxEYXRhKDIsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sRCwgcGFzdCwgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sRCwgbm93LCBudWxsKTsKKworICAgIC8vIGNhbGwgZGVsZXRlIGFsbCB3L28gYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBub3RoaW5nIGlzIGxlZnQuCisgICAgcmVnaW9uLmRlbGV0ZUFsbChyb3csIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgbnVsbCk7CisgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9ICAgIAorICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEEsIG5vdywgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgcGFzdCwgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgZnV0dXJlLCBudWxsKTsKKyAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xELCBub3csIG51bGwpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEQsIHBhc3QsIG51bGwpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEQsIGZ1dHVyZSwgbnVsbCk7CisgICAgCisgIH0KKworICBwcml2YXRlIHZvaWQgbWFrZVN1cmVSZWdleFdvcmtzKEhSZWdpb24gcmVnaW9uLCBIUmVnaW9uSW5jb21tb24gcmVnaW9uX2luY29tbW9uLCAKKyAgICAgIGJvb2xlYW4gZmx1c2gpCisgICAgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICAgIC8vIGluc2VydCBhIGZldyB2ZXJzaW9ucyB3b3J0aCBvZiBkYXRhIGZvciBhIHJvdworICAgICAgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJ0ZXN0X3JvdyIpOworICAgICAgbG9uZyB0MCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgbG9uZyB0MSA9IHQwIC0gMTUwMDA7CisgICAgICBsb25nIHQyID0gdDEgLSAxNTAwMDsKKworICAgICAgYnl0ZSBbXSBjb2xBID0gQnl0ZXMudG9CeXRlcyhCeXRlcy50b1N0cmluZyhDT0xVTU5TWzBdKSArICJhIik7CisgICAgICBieXRlIFtdIGNvbEIgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImIiKTsKKyAgICAgIGJ5dGUgW10gY29sQyA9IEJ5dGVzLnRvQnl0ZXMoQnl0ZXMudG9TdHJpbmcoQ09MVU1OU1swXSkgKyAiYyIpOworICAgICAgYnl0ZSBbXSBjb2xEID0gQnl0ZXMudG9CeXRlcyhCeXRlcy50b1N0cmluZyhDT0xVTU5TWzBdKSk7CisKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEEsIGNlbGxEYXRhKDAsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgwLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMCwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEQsIGNlbGxEYXRhKDAsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3csIHQxKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xBLCBjZWxsRGF0YSgxLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQiwgY2VsbERhdGEoMSwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEMsIGNlbGxEYXRhKDEsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xELCBjZWxsRGF0YSgxLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7ICAgICAgCisgICAgICByZWdpb25faW5jb21tb24uY29tbWl0KGJhdGNoVXBkYXRlKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93LCB0Mik7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQSwgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEIsIGNlbGxEYXRhKDIsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xDLCBjZWxsRGF0YSgyLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7ICAgICAgCisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sRCwgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgICAgcmVnaW9uX2luY29tbW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisKKyAgICAgIGlmIChmbHVzaCkge3JlZ2lvbl9pbmNvbW1vbi5mbHVzaGNhY2hlKCk7fQorCisgICAgICAvLyBjYWxsIGRlbGV0ZSB0aGUgbWF0Y2hpbmcgY29sdW1ucyBhdCBhIHRpbWVzdGFtcCwgCisgICAgICAvLyBtYWtlIHN1cmUgb25seSB0aGUgbW9zdCByZWNlbnQgc3R1ZmYgaXMgbGVmdCBiZWhpbmQKKyAgICAgIHJlZ2lvbi5kZWxldGVBbGxCeVJlZ2V4KHJvdywgQ09MVU1OX1JFR0VYLCB0MSwgbnVsbCk7CisgICAgICBpZiAoZmx1c2gpIHtyZWdpb25faW5jb21tb24uZmx1c2hjYWNoZSgpO30gICAgCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MCwgY2VsbERhdGEoMCwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEEsIHQxLCBjZWxsRGF0YSgxLCBmbHVzaCkpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgdDIsIGNlbGxEYXRhKDIsIGZsdXNoKSk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xCLCB0MCwgY2VsbERhdGEoMCwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQxLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQyLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQwLCBjZWxsRGF0YSgwLCBmbHVzaCkpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDEsIG51bGwpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDIsIG51bGwpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sRCwgdDAsIGNlbGxEYXRhKDAsIGZsdXNoKSk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xELCB0MSwgbnVsbCk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xELCB0MiwgbnVsbCk7CisKKyAgICAgIC8vIGNhbGwgZGVsZXRlIGFsbCB3L28gYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBub3RoaW5nIGlzIGxlZnQuCisgICAgICByZWdpb24uZGVsZXRlQWxsQnlSZWdleChyb3csIENPTFVNTl9SRUdFWCwgCisgICAgICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBudWxsKTsKKyAgICAgIGlmIChmbHVzaCkge3JlZ2lvbl9pbmNvbW1vbi5mbHVzaGNhY2hlKCk7fSAgICAKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEEsIHQwLCBjZWxsRGF0YSgwLCBmbHVzaCkpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgdDEsIGNlbGxEYXRhKDEsIGZsdXNoKSk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MiwgY2VsbERhdGEoMiwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQwLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQxLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQyLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQwLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQxLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQyLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEQsIHQwLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEQsIHQxLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEQsIHQyLCBudWxsKTsKKyAgICAgIAorICAgIH0KKyAgCisgIHByaXZhdGUgU3RyaW5nIGNlbGxEYXRhKGludCB0c051bSwgYm9vbGVhbiBmbHVzaCl7CisgICAgcmV0dXJuICJ0IiArIHRzTnVtICsgIiBkYXRhIiArIChmbHVzaCA/ICIgLSB3aXRoIGZsdXNoIiA6ICIiKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIGlmICh0aGlzLm1pbmlIZGZzICE9IG51bGwpIHsKKyAgICAgIHNodXRkb3duRGZzKHRoaXMubWluaUhkZnMpOworICAgIH0KKyAgICBzdXBlci50ZWFyRG93bigpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdERlbGV0ZUZhbWlseS5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3REZWxldGVGYW1pbHkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MWY2MDc2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3REZWxldGVGYW1pbHkuamF2YQpAQCAtMCwwICsxLDIyNSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZGZzLk1pbmlERlNDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogVGVzdCB0aGUgZnVuY3Rpb25hbGl0eSBvZiBkZWxldGVGYW1pbHkuCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0RGVsZXRlRmFtaWx5IGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdERlbGV0ZUZhbWlseS5jbGFzcyk7CisgIHByaXZhdGUgTWluaURGU0NsdXN0ZXIgbWluaUhkZnM7CisKKyAgLy9mb3IgZmFtaWx5IHJlZ2V4IGRlbGV0aW9uIHRlc3QKKyAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09MRkFNSUxZX1JFR0VYID0gImNvbFthLXpBLVpdKjEiOworICAKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB0aGlzLm1pbmlIZGZzID0gbmV3IE1pbmlERlNDbHVzdGVyKHRoaXMuY29uZiwgMSwgdHJ1ZSwgbnVsbCk7CisgICAgLy8gU2V0IHRoZSBoYmFzZS5yb290ZGlyIHRvIGJlIHRoZSBob21lIGRpcmVjdG9yeSBpbiBtaW5pIGRmcy4KKyAgICB0aGlzLmNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLAorICAgICAgdGhpcy5taW5pSGRmcy5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICB9CisgIAorICAvKioKKyAgICogVGVzdHMgZm9yIEhBRE9PUC0yMzg0LgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdERlbGV0ZUZhbWlseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEhSZWdpb24gcmVnaW9uID0gbnVsbDsKKyAgICBIUmVnaW9uSW5jb21tb24gcmVnaW9uX2luY29tbW9uID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICAgIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oaHRkLCBudWxsLCBudWxsKTsKKyAgICAgIHJlZ2lvbl9pbmNvbW1vbiA9IG5ldyBIUmVnaW9uSW5jb21tb24ocmVnaW9uKTsKKyAgICAgIAorICAgICAgLy8gdGVzdCBtZW1jYWNoZQorICAgICAgbWFrZVN1cmVJdFdvcmtzKHJlZ2lvbiwgcmVnaW9uX2luY29tbW9uLCBmYWxzZSk7CisgICAgICAvLyB0ZXN0IGhzdG9yZQorICAgICAgbWFrZVN1cmVJdFdvcmtzKHJlZ2lvbiwgcmVnaW9uX2luY29tbW9uLCB0cnVlKTsKKyAgICAgIC8vIGZhbWlseSByZWdleCB0ZXN0IG1lbWNhY2hlCisgICAgICBtYWtlU3VyZVJlZ2V4V29ya3MocmVnaW9uLCByZWdpb25faW5jb21tb24sIGZhbHNlKTsKKyAgICAgIC8vIGZhbWlseSByZWdleCB0ZXN0IGhzdG9yZQorICAgICAgbWFrZVN1cmVSZWdleFdvcmtzKHJlZ2lvbiwgcmVnaW9uX2luY29tbW9uLCB0cnVlKTsKKyAgICAgIAorICAgIH0gZmluYWxseSB7CisgICAgICBpZiAocmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZWdpb24uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIHJlZ2lvbi5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgfQorICAgIH0KKyAgfQorICAgIAorICBwcml2YXRlIHZvaWQgbWFrZVN1cmVJdFdvcmtzKEhSZWdpb24gcmVnaW9uLCBIUmVnaW9uSW5jb21tb24gcmVnaW9uX2luY29tbW9uLCAKKyAgICBib29sZWFuIGZsdXNoKQorICB0aHJvd3MgRXhjZXB0aW9ueworICAgIC8vIGluc2VydCBhIGZldyB2ZXJzaW9ucyB3b3J0aCBvZiBkYXRhIGZvciBhIHJvdworICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcygidGVzdF9yb3ciKTsKKyAgICBsb25nIHQwID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgbG9uZyB0MSA9IHQwIC0gMTUwMDA7CisgICAgbG9uZyB0MiA9IHQxIC0gMTUwMDA7CisKKyAgICBieXRlIFtdIGNvbEEgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImEiKTsKKyAgICBieXRlIFtdIGNvbEIgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImIiKTsKKyAgICBieXRlIFtdIGNvbEMgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMV0pICsgImMiKTsKKworICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbnVsbDsKKyAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3csIHQwKTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQSwgY2VsbERhdGEoMCwgZmx1c2gpLmdldEJ5dGVzKCkpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgwLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEMsIGNlbGxEYXRhKDAsIGZsdXNoKS5nZXRCeXRlcygpKTsgICAgICAKKyAgICByZWdpb25faW5jb21tb24uY29tbWl0KGJhdGNoVXBkYXRlKTsKKworICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDEpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xBLCBjZWxsRGF0YSgxLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEIsIGNlbGxEYXRhKDEsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMSwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIAorICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDIpOworICAgIGJhdGNoVXBkYXRlLnB1dChjb2xBLCBjZWxsRGF0YSgyLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEIsIGNlbGxEYXRhKDIsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9CisKKyAgICAvLyBjYWxsIGRlbGV0ZSBmYW1pbHkgYXQgYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBvbmx5IHRoZSBtb3N0IHJlY2VudCBzdHVmZgorICAgIC8vIGZvciBjb2x1bW4gYyBpcyBsZWZ0IGJlaGluZAorICAgIHJlZ2lvbi5kZWxldGVGYW1pbHkocm93LCBDT0xVTU5TWzBdLCB0MSwgbnVsbCk7CisgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9CisgICAgLy8gbW9zdCByZWNlbnQgZm9yIEEsQixDIHNob3VsZCBiZSBmaW5lCisgICAgLy8gQSxCIGF0IG9sZGVyIHRpbWVzdGFtcHMgc2hvdWxkIGJlIGdvbmUKKyAgICAvLyBDIHNob3VsZCBiZSBmaW5lIGZvciBvbGRlciB0aW1lc3RhbXBzCisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgdDAsIGNlbGxEYXRhKDAsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQSwgdDEsIG51bGwpOyAgICAKKyAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MiwgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQiwgdDAsIGNlbGxEYXRhKDAsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQiwgdDEsIG51bGwpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQyLCBudWxsKTsgICAgCisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDAsIGNlbGxEYXRhKDAsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDEsIGNlbGxEYXRhKDEsIGZsdXNoKSk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDIsIGNlbGxEYXRhKDIsIGZsdXNoKSk7ICAgICAgICAKKworICAgIC8vIGNhbGwgZGVsZXRlIGZhbWlseSB3L28gYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBub3RoaW5nIGlzIGxlZnQgZXhjZXB0IGZvcgorICAgIC8vIGNvbHVtbiBDLgorICAgIHJlZ2lvbi5kZWxldGVGYW1pbHkocm93LCBDT0xVTU5TWzBdLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgIGlmIChmbHVzaCkge3JlZ2lvbl9pbmNvbW1vbi5mbHVzaGNhY2hlKCk7fQorICAgIC8vIEEsQiBmb3IgbGF0ZXN0IHRpbWVzdGFtcCBzaG91bGQgYmUgZ29uZQorICAgIC8vIEMgc2hvdWxkIHN0aWxsIGJlIGZpbmUKKyAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MCwgbnVsbCk7CisgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQiwgdDAsIG51bGwpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQwLCBjZWxsRGF0YSgwLCBmbHVzaCkpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQxLCBjZWxsRGF0YSgxLCBmbHVzaCkpOworICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQyLCBjZWxsRGF0YSgyLCBmbHVzaCkpOyAgICAgICAgCisgICAgCisgIH0KKyAgCisgIHByaXZhdGUgdm9pZCBtYWtlU3VyZVJlZ2V4V29ya3MoSFJlZ2lvbiByZWdpb24sIEhSZWdpb25JbmNvbW1vbiByZWdpb25faW5jb21tb24sIAorICAgICAgYm9vbGVhbiBmbHVzaCkKKyAgICB0aHJvd3MgRXhjZXB0aW9ueworICAgICAgLy8gaW5zZXJ0IGEgZmV3IHZlcnNpb25zIHdvcnRoIG9mIGRhdGEgZm9yIGEgcm93CisgICAgICBieXRlIFtdIHJvdyA9IEJ5dGVzLnRvQnl0ZXMoInRlc3Rfcm93Iik7CisgICAgICBsb25nIHQwID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICBsb25nIHQxID0gdDAgLSAxNTAwMDsKKyAgICAgIGxvbmcgdDIgPSB0MSAtIDE1MDAwOworCisgICAgICBieXRlIFtdIGNvbEEgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImEiKTsKKyAgICAgIGJ5dGUgW10gY29sQiA9IEJ5dGVzLnRvQnl0ZXMoQnl0ZXMudG9TdHJpbmcoQ09MVU1OU1swXSkgKyAiYiIpOworICAgICAgYnl0ZSBbXSBjb2xDID0gQnl0ZXMudG9CeXRlcyhCeXRlcy50b1N0cmluZyhDT0xVTU5TWzFdKSArICJjIik7CisKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbnVsbDsKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEEsIGNlbGxEYXRhKDAsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgwLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMCwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgICAgcmVnaW9uX2luY29tbW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDEpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEEsIGNlbGxEYXRhKDEsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgxLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMSwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgICAgcmVnaW9uX2luY29tbW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdywgdDIpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNvbEEsIGNlbGxEYXRhKDIsIGZsdXNoKS5nZXRCeXRlcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xCLCBjZWxsRGF0YSgyLCBmbHVzaCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY29sQywgY2VsbERhdGEoMiwgZmx1c2gpLmdldEJ5dGVzKCkpOyAgICAgIAorICAgICAgcmVnaW9uX2luY29tbW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisKKyAgICAgIGlmIChmbHVzaCkge3JlZ2lvbl9pbmNvbW1vbi5mbHVzaGNhY2hlKCk7fQorCisgICAgICAvLyBjYWxsIGRlbGV0ZSBmYW1pbHkgYXQgYSB0aW1lc3RhbXAsIG1ha2Ugc3VyZSBvbmx5IHRoZSBtb3N0IHJlY2VudCBzdHVmZgorICAgICAgLy8gZm9yIGNvbHVtbiBjIGlzIGxlZnQgYmVoaW5kCisgICAgICByZWdpb24uZGVsZXRlRmFtaWx5QnlSZWdleChyb3csIENPTEZBTUlMWV9SRUdFWCwgdDEsIG51bGwpOworICAgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9CisgICAgICAvLyBtb3N0IHJlY2VudCBmb3IgQSxCLEMgc2hvdWxkIGJlIGZpbmUKKyAgICAgIC8vIEEsQiBhdCBvbGRlciB0aW1lc3RhbXBzIHNob3VsZCBiZSBnb25lCisgICAgICAvLyBDIHNob3VsZCBiZSBmaW5lIGZvciBvbGRlciB0aW1lc3RhbXBzCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MCwgY2VsbERhdGEoMCwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEEsIHQxLCBudWxsKTsgICAgCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xBLCB0MiwgbnVsbCk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xCLCB0MCwgY2VsbERhdGEoMCwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQxLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQyLCBudWxsKTsgICAgCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xDLCB0MCwgY2VsbERhdGEoMCwgZmx1c2gpKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQxLCBjZWxsRGF0YSgxLCBmbHVzaCkpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDIsIGNlbGxEYXRhKDIsIGZsdXNoKSk7ICAgICAgICAKKworICAgICAgLy8gY2FsbCBkZWxldGUgZmFtaWx5IHcvbyBhIHRpbWVzdGFtcCwgbWFrZSBzdXJlIG5vdGhpbmcgaXMgbGVmdCBleGNlcHQgZm9yCisgICAgICAvLyBjb2x1bW4gQy4KKyAgICAgIHJlZ2lvbi5kZWxldGVGYW1pbHlCeVJlZ2V4KHJvdywgQ09MRkFNSUxZX1JFR0VYLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIG51bGwpOworICAgICAgaWYgKGZsdXNoKSB7cmVnaW9uX2luY29tbW9uLmZsdXNoY2FjaGUoKTt9CisgICAgICAvLyBBLEIgZm9yIGxhdGVzdCB0aW1lc3RhbXAgc2hvdWxkIGJlIGdvbmUKKyAgICAgIC8vIEMgc2hvdWxkIHN0aWxsIGJlIGZpbmUKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEEsIHQwLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEIsIHQwLCBudWxsKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCByb3csIGNvbEMsIHQwLCBjZWxsRGF0YSgwLCBmbHVzaCkpOworICAgICAgYXNzZXJ0Q2VsbEVxdWFscyhyZWdpb24sIHJvdywgY29sQywgdDEsIGNlbGxEYXRhKDEsIGZsdXNoKSk7CisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgcm93LCBjb2xDLCB0MiwgY2VsbERhdGEoMiwgZmx1c2gpKTsgICAgICAgIAorICAgICAgCisgICAgfQorICAKKyAgcHJpdmF0ZSBTdHJpbmcgY2VsbERhdGEoaW50IHRzTnVtLCBib29sZWFuIGZsdXNoKXsKKyAgICByZXR1cm4gInQiICsgdHNOdW0gKyAiIGRhdGEiICsgKGZsdXNoID8gIiAtIHdpdGggZmx1c2giIDogIiIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMubWluaUhkZnMgIT0gbnVsbCkgeworICAgICAgdGhpcy5taW5pSGRmcy5zaHV0ZG93bigpOworICAgIH0KKyAgICBzdXBlci50ZWFyRG93bigpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEdldC5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RHZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTU1MTRiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RHZXQuamF2YQpAQCAtMCwwICsxLDE2NiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmRmcy5NaW5pREZTQ2x1c3RlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CisKKy8qKiBUZXN0IGNhc2UgZm9yIGdldCAqLworcHVibGljIGNsYXNzIFRlc3RHZXQgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRlc3RHZXQuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gQ09OVEVOVFMgPSBCeXRlcy50b0J5dGVzKCJjb250ZW50czoiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBST1dfS0VZID0KKyAgICBIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8uZ2V0UmVnaW9uTmFtZSgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0VSVkVSX0FERFJFU1MgPSAiZm9vLmJhci5jb206MTIzNCI7CisKKworICAKKyAgcHJpdmF0ZSB2b2lkIHZlcmlmeUdldChmaW5hbCBIUmVnaW9uSW5jb21tb24gciwgZmluYWwgU3RyaW5nIGV4cGVjdGVkU2VydmVyKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIFRoaXMgc2hvdWxkIHJldHVybiBhIHZhbHVlIGJlY2F1c2UgdGhlcmUgaXMgb25seSBvbmUgZmFtaWx5IG1lbWJlcgorICAgIENlbGwgdmFsdWUgPSByLmdldChST1dfS0VZLCBDT05URU5UUyk7CisgICAgYXNzZXJ0Tm90TnVsbCh2YWx1ZSk7CisgICAgCisgICAgLy8gVGhpcyBzaG91bGQgbm90IHJldHVybiBhIHZhbHVlIGJlY2F1c2UgdGhlcmUgYXJlIG11bHRpcGxlIGZhbWlseSBtZW1iZXJzCisgICAgdmFsdWUgPSByLmdldChST1dfS0VZLCBIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkpOworICAgIGFzc2VydE51bGwodmFsdWUpOworICAgIAorICAgIC8vIEZpbmQgb3V0IHdoYXQgZ2V0RnVsbCByZXR1cm5zCisgICAgTWFwPGJ5dGUgW10sIENlbGw+IHZhbHVlcyA9IHIuZ2V0RnVsbChST1dfS0VZKTsKKyAgICAKKyAgICAvLyBhc3NlcnRFcXVhbHMoNCwgdmFsdWVzLmtleVNldCgpLnNpemUoKSk7CisgICAgZm9yIChNYXAuRW50cnk8Ynl0ZVtdLCBDZWxsPiBlbnRyeSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CisgICAgICBieXRlW10gY29sdW1uID0gZW50cnkuZ2V0S2V5KCk7CisgICAgICBDZWxsIGNlbGwgPSBlbnRyeS5nZXRWYWx1ZSgpOworICAgICAgaWYgKEJ5dGVzLmVxdWFscyhjb2x1bW4sIEhDb25zdGFudHMuQ09MX1NFUlZFUikpIHsKKyAgICAgICAgU3RyaW5nIHNlcnZlciA9IFdyaXRhYmxlcy5jZWxsVG9TdHJpbmcoY2VsbCk7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZFNlcnZlciwgc2VydmVyKTsKKyAgICAgICAgTE9HLmluZm8oc2VydmVyKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKiAKKyAgICogdGhlIHRlc3QKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWluaURGU0NsdXN0ZXIgY2x1c3RlciA9IG51bGw7CisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworCisgICAgdHJ5IHsKKyAgICAgIAorICAgICAgLy8gSW5pdGlhbGl6YXRpb24KKyAgICAgIAorICAgICAgY2x1c3RlciA9IG5ldyBNaW5pREZTQ2x1c3Rlcihjb25mLCAyLCB0cnVlLCAoU3RyaW5nW10pbnVsbCk7CisgICAgICAvLyBTZXQgdGhlIGhiYXNlLnJvb3RkaXIgdG8gYmUgdGhlIGhvbWUgZGlyZWN0b3J5IGluIG1pbmkgZGZzLgorICAgICAgdGhpcy5jb25mLnNldChIQ29uc3RhbnRzLkhCQVNFX0RJUiwKKyAgICAgICAgY2x1c3Rlci5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICAgICAgCisgICAgICBIVGFibGVEZXNjcmlwdG9yIGRlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcigidGVzdCIpOworICAgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTlRFTlRTKSk7CisgICAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKSk7CisgICAgICAKKyAgICAgIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oZGVzYywgbnVsbCwgbnVsbCk7CisgICAgICBIUmVnaW9uSW5jb21tb24gciA9IG5ldyBIUmVnaW9uSW5jb21tb24ocmVnaW9uKTsKKyAgICAgIAorICAgICAgLy8gV3JpdGUgaW5mb3JtYXRpb24gdG8gdGhlIHRhYmxlCisKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbnVsbDsKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPV19LRVksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT05URU5UUywgQ09OVEVOVFMpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8sIAorICAgICAgICAgIFdyaXRhYmxlcy5nZXRCeXRlcyhIUmVnaW9uSW5mby5ST09UX1JFR0lPTklORk8pKTsKKyAgICAgIHIuY29tbWl0KGJhdGNoVXBkYXRlKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoUk9XX0tFWSwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KEhDb25zdGFudHMuQ09MX1NFUlZFUiwgCisgICAgICAgIEJ5dGVzLnRvQnl0ZXMobmV3IEhTZXJ2ZXJBZGRyZXNzKFNFUlZFUl9BRERSRVNTKS50b1N0cmluZygpKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoSENvbnN0YW50cy5DT0xfU1RBUlRDT0RFLCBCeXRlcy50b0J5dGVzKDEyMzQ1KSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQnl0ZXMudG9TdHJpbmcoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZKSArCisgICAgICAgICJyZWdpb24iLCBCeXRlcy50b0J5dGVzKCJyZWdpb24iKSk7CisgICAgICByLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICAKKyAgICAgIC8vIFZlcmlmeSB0aGF0IGdldCB3b3JrcyB0aGUgc2FtZSBmcm9tIG1lbWNhY2hlIGFzIHdoZW4gcmVhZGluZyBmcm9tIGRpc2sKKyAgICAgIC8vIE5PVEUgZHVtcFJlZ2lvbiB3b24ndCB3b3JrIGhlcmUgYmVjYXVzZSBpdCBvbmx5IHJlYWRzIGZyb20gZGlzay4KKyAgICAgIAorICAgICAgdmVyaWZ5R2V0KHIsIFNFUlZFUl9BRERSRVNTKTsKKyAgICAgIAorICAgICAgLy8gQ2xvc2UgYW5kIHJlLW9wZW4gcmVnaW9uLCBmb3JjaW5nIHVwZGF0ZXMgdG8gZGlzaworICAgICAgCisgICAgICByZWdpb24uY2xvc2UoKTsKKyAgICAgIHJlZ2lvbiA9IG9wZW5DbG9zZWRSZWdpb24ocmVnaW9uKTsKKyAgICAgIHIgPSBuZXcgSFJlZ2lvbkluY29tbW9uKHJlZ2lvbik7CisgICAgICAKKyAgICAgIC8vIFJlYWQgaXQgYmFjaworICAgICAgCisgICAgICB2ZXJpZnlHZXQociwgU0VSVkVSX0FERFJFU1MpOworICAgICAgCisgICAgICAvLyBVcGRhdGUgb25lIGZhbWlseSBtZW1iZXIgYW5kIGFkZCBhIG5ldyBvbmUKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoUk9XX0tFWSwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KEJ5dGVzLnRvU3RyaW5nKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSkgKyAicmVnaW9uIiwKKyAgICAgICAgInJlZ2lvbjIiLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgICAgU3RyaW5nIG90aGVyU2VydmVyTmFtZSA9ICJiYXIuZm9vLmNvbTo0MzIxIjsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChIQ29uc3RhbnRzLkNPTF9TRVJWRVIsIAorICAgICAgICBCeXRlcy50b0J5dGVzKG5ldyBIU2VydmVyQWRkcmVzcyhvdGhlclNlcnZlck5hbWUpLnRvU3RyaW5nKCkpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkpICsgImp1bmsiLAorICAgICAgICAianVuayIuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICByLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisKKyAgICAgIHZlcmlmeUdldChyLCBvdGhlclNlcnZlck5hbWUpOworICAgICAgCisgICAgICAvLyBDbG9zZSByZWdpb24gYW5kIHJlLW9wZW4gaXQKKyAgICAgIAorICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICByZWdpb24gPSBvcGVuQ2xvc2VkUmVnaW9uKHJlZ2lvbik7CisgICAgICByID0gbmV3IEhSZWdpb25JbmNvbW1vbihyZWdpb24pOworCisgICAgICAvLyBSZWFkIGl0IGJhY2sKKyAgICAgIAorICAgICAgdmVyaWZ5R2V0KHIsIG90aGVyU2VydmVyTmFtZSk7CisKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIC8vIENsb3NlIHJlZ2lvbiBvbmNlIGFuZCBmb3IgYWxsCisgICAgICAgIHJlZ2lvbi5jbG9zZSgpOworICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICAgIGlmIChjbHVzdGVyICE9IG51bGwpIHsKKyAgICAgICAgc2h1dGRvd25EZnMoY2x1c3Rlcik7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEdldDIuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0R2V0Mi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0NzM1OGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEdldDIuamF2YQpAQCAtMCwwICsxLDcyMSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5OYXZpZ2FibGVTZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLlN0b3BSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuZmlsdGVyLldoaWxlTWF0Y2hSb3dGaWx0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIHtAbGluayBUZXN0R2V0fSBpcyBhIG1lZGxleSBvZiB0ZXN0cyBvZiBnZXQgYWxsIGRvbmUgdXAgYXMgYSBzaW5nbGUgdGVzdC4KKyAqIFRoaXMgY2xhc3MgCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0R2V0MiBleHRlbmRzIEhCYXNlVGVzdENhc2UgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgcHJpdmF0ZSBNaW5pREZTQ2x1c3RlciBtaW5pSGRmczsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUMDAgPSAiMDAwIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFQxMCA9ICIwMTAiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVDExID0gIjAxMSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUMTIgPSAiMDEyIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFQyMCA9ICIwMjAiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVDMwID0gIjAzMCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUMzEgPSAiMDMxIjsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIHRoaXMubWluaUhkZnMgPSBuZXcgTWluaURGU0NsdXN0ZXIodGhpcy5jb25mLCAxLCB0cnVlLCBudWxsKTsKKyAgICAvLyBTZXQgdGhlIGhiYXNlLnJvb3RkaXIgdG8gYmUgdGhlIGhvbWUgZGlyZWN0b3J5IGluIG1pbmkgZGZzLgorICAgIHRoaXMuY29uZi5zZXQoSENvbnN0YW50cy5IQkFTRV9ESVIsCisgICAgICB0aGlzLm1pbmlIZGZzLmdldEZpbGVTeXN0ZW0oKS5nZXRIb21lRGlyZWN0b3J5KCkudG9TdHJpbmcoKSk7CisgIH0KKworCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRGdWxsTXVsdGlNYXBmaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBudWxsOworICAgIE1hcDxieXRlIFtdLCBDZWxsPiByZXN1bHRzID0gbnVsbDsKKyAgICAKKyAgICB0cnkgeworICAgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICAgIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oaHRkLCBudWxsLCBudWxsKTsKKworICAgICAgLy8gVGVzdCBvcmRlcmluZyBpc3N1ZQorICAgICAgLy8KKyAgICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcygicm93MSIpOworICAgICAKKyAgICAgIC8vIHdyaXRlIHNvbWUgZGF0YQorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzBdLCAib2xkZXJWYWx1ZSIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworCisgICAgICAvLyBmbHVzaAorICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKworICAgICAgLy8gYXNzZXJ0IHRoYXQgZ2V0RnVsbCBnaXZlcyB1cyB0aGUgb2xkZXIgdmFsdWUKKyAgICAgIHJlc3VsdHMgPSByZWdpb24uZ2V0RnVsbChyb3csIChOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4pbnVsbCwKKyAgICAgICAgTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgICBhc3NlcnRFcXVhbHMoIm9sZGVyVmFsdWUiLAorICAgICAgICBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIAorICAgICAgLy8gd3JpdGUgYSBuZXcgdmFsdWUgZm9yIHRoZSBjZWxsCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3cpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJuZXdlclZhbHVlIi5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisKKyAgICAgIC8vIGZsdXNoCisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgICAgCisgICAgICAvLyBhc3NlcnQgdGhhdCBnZXRGdWxsIGdpdmVzIHVzIHRoZSBsYXRlciB2YWx1ZQorICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRGdWxsKHJvdywgKE5hdmlnYWJsZVNldDxieXRlIFtdPiludWxsLAorICAgICAgICBMQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsKKyAgICAgIGFzc2VydEVxdWFscygibmV3ZXJWYWx1ZSIsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAKKyAgICAgIC8vCisgICAgICAvLyBUZXN0IHRoZSBkZWxldGUgbWFza2luZyBpc3N1ZQorICAgICAgLy8KKyAgICAgIGJ5dGUgW10gcm93MiA9IEJ5dGVzLnRvQnl0ZXMoInJvdzIiKTsKKyAgICAgIGJ5dGUgW10gY2VsbDEgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImEiKTsKKyAgICAgIGJ5dGUgW10gY2VsbDIgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImIiKTsKKyAgICAgIGJ5dGUgW10gY2VsbDMgPSBCeXRlcy50b0J5dGVzKEJ5dGVzLnRvU3RyaW5nKENPTFVNTlNbMF0pICsgImMiKTsKKworICAgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgIAorICAgICAgLy8gd3JpdGUgc29tZSBkYXRhIGF0IHR3byBjb2x1bW5zCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShyb3cyLCBub3cpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNlbGwxLCAiY29sdW1uMCB2YWx1ZSIuZ2V0Qnl0ZXMoKSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY2VsbDIsICJjb2x1bW4xIHZhbHVlIi5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICAKKyAgICAgIC8vIGZsdXNoCisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgICAgCisgICAgICAvLyBhc3NlcnQgaSBnZXQgYm90aCBjb2x1bW5zCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldEZ1bGwocm93MiwKKyAgICAgICAgKE5hdmlnYWJsZVNldDxieXRlIFtdPiludWxsLCBMQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsKKyAgICAgIGFzc2VydEVxdWFscygiU2hvdWxkIGhhdmUgdHdvIGNvbHVtbnMgaW4gdGhlIHJlc3VsdHMgbWFwIiwgMiwgcmVzdWx0cy5zaXplKCkpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjb2x1bW4wIHZhbHVlIiwgbmV3IFN0cmluZyhyZXN1bHRzLmdldChjZWxsMSkuZ2V0VmFsdWUoKSkpOworICAgICAgYXNzZXJ0RXF1YWxzKCJjb2x1bW4xIHZhbHVlIiwgbmV3IFN0cmluZyhyZXN1bHRzLmdldChjZWxsMikuZ2V0VmFsdWUoKSkpOworICAgICAgCisgICAgICAvLyB3cml0ZSBhIGRlbGV0ZSBmb3IgdGhlIGZpcnN0IGNvbHVtbgorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93Miwgbm93KTsKKyAgICAgIGJhdGNoVXBkYXRlLmRlbGV0ZShjZWxsMSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoY2VsbDIsICJjb2x1bW4xIG5ldyB2YWx1ZSIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgICAgICAgCisgICAgICAvLyBmbHVzaAorICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsgCisgICAgICAKKyAgICAgIC8vIGFzc2VydCBpIGdldCB0aGUgc2Vjb25kIGNvbHVtbiBvbmx5CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldEZ1bGwocm93MiwgKE5hdmlnYWJsZVNldDxieXRlIFtdPiludWxsLAorICAgICAgICBMQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihCeXRlcy50b1N0cmluZyhyZXN1bHRzLmtleVNldCgpLml0ZXJhdG9yKCkubmV4dCgpKSk7CisgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBoYXZlIG9uZSBjb2x1bW4gaW4gdGhlIHJlc3VsdHMgbWFwIiwgMSwgcmVzdWx0cy5zaXplKCkpOworICAgICAgYXNzZXJ0TnVsbCgiY29sdW1uMCB2YWx1ZSIsIHJlc3VsdHMuZ2V0KGNlbGwxKSk7CisgICAgICBhc3NlcnRFcXVhbHMoImNvbHVtbjEgbmV3IHZhbHVlIiwgbmV3IFN0cmluZyhyZXN1bHRzLmdldChjZWxsMikuZ2V0VmFsdWUoKSkpOworICAgICAgCisgICAgICAvLworICAgICAgLy8gSW5jbHVkZSBhIGRlbGV0ZSBhbmQgdmFsdWUgZnJvbSB0aGUgbWVtY2FjaGUgaW4gdGhlIG1peAorICAgICAgLy8KKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHJvdzIsIG5vdyk7CisgICAgICBiYXRjaFVwZGF0ZS5kZWxldGUoY2VsbDIpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KGNlbGwzLCAiY29sdW1uMyB2YWx1ZSEiLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKworICAgICAgLy8gYXNzZXJ0IGkgZ2V0IHRoZSB0aGlyZCBjb2x1bW4gb25seQorICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRGdWxsKHJvdzIsIChOYXZpZ2FibGVTZXQ8Ynl0ZSBbXT4pbnVsbCwgTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBoYXZlIG9uZSBjb2x1bW4gaW4gdGhlIHJlc3VsdHMgbWFwIiwgMSwgcmVzdWx0cy5zaXplKCkpOworICAgICAgYXNzZXJ0TnVsbCgiY29sdW1uMCB2YWx1ZSIsIHJlc3VsdHMuZ2V0KGNlbGwxKSk7CisgICAgICBhc3NlcnROdWxsKCJjb2x1bW4xIHZhbHVlIiwgcmVzdWx0cy5nZXQoY2VsbDIpKTsKKyAgICAgIGFzc2VydEVxdWFscygiY29sdW1uMyB2YWx1ZSEiLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KGNlbGwzKS5nZXRWYWx1ZSgpKSk7CisgICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9ICAKKyAgfQorCisgIC8qKgorICAgKiBUZXN0IGZvciBIQkFTRS04MDggYW5kIEhCQVNFLTgwOS4KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RNYXhWZXJzaW9uc0FuZERlbGV0aW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworICAgIHRyeSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgICAgcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihodGQsIG51bGwsIG51bGwpOworICAgICAgCisgICAgICBieXRlIFtdIGNvbHVtbiA9IENPTFVNTlNbMF07CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICAgIGFkZFRvUm93KHJlZ2lvbiwgVDAwLCBjb2x1bW4sIGksIFQwMC5nZXRCeXRlcygpKTsKKyAgICAgIH0KKyAgICAgIGNoZWNrVmVyc2lvbnMocmVnaW9uLCBUMDAsIGNvbHVtbik7CisgICAgICAvLyBGbHVzaCBhbmQgcmV0cnkuCisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgICAgY2hlY2tWZXJzaW9ucyhyZWdpb24sIFQwMCwgY29sdW1uKTsKKyAgICAgIAorICAgICAgLy8gTm93IGRlbGV0ZSBhbGwgdGhlbiByZXRyeQorICAgICAgcmVnaW9uLmRlbGV0ZUFsbChCeXRlcy50b0J5dGVzKFQwMCksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLCBudWxsKTsKKyAgICAgIENlbGwgW10gY2VsbHMgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShyZWdpb24uZ2V0KEJ5dGVzLnRvQnl0ZXMoVDAwKSwgY29sdW1uLCAtMSwKKyAgICAgICAgSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9WRVJTSU9OUykpOworICAgICAgYXNzZXJ0VHJ1ZShjZWxscyA9PSBudWxsKTsKKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisgICAgICBjZWxscyA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHJlZ2lvbi5nZXQoQnl0ZXMudG9CeXRlcyhUMDApLCBjb2x1bW4sIC0xLAorICAgICAgICAgIEhDb2x1bW5EZXNjcmlwdG9yLkRFRkFVTFRfVkVSU0lPTlMpKTsKKyAgICAgIGFzc2VydFRydWUoY2VsbHMgPT0gbnVsbCk7CisgICAgICAKKyAgICAgIC8vIE5vdyBhZGQgYmFjayB0aGUgcm93cworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgICBhZGRUb1JvdyhyZWdpb24sIFQwMCwgY29sdW1uLCBpLCBUMDAuZ2V0Qnl0ZXMoKSk7CisgICAgICB9CisgICAgICAvLyBSdW4gc2FtZSB2ZXJpZmljYXRpb25zLgorICAgICAgY2hlY2tWZXJzaW9ucyhyZWdpb24sIFQwMCwgY29sdW1uKTsKKyAgICAgIC8vIEZsdXNoIGFuZCByZXRyeS4KKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisgICAgICBjaGVja1ZlcnNpb25zKHJlZ2lvbiwgVDAwLCBjb2x1bW4pOworICAgIH0gZmluYWxseSB7CisgICAgICBpZiAocmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZWdpb24uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIHJlZ2lvbi5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKiBGb3IgSEJBU0UtNjk0IAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2xvc2VzdFJvd0JlZm9yZTIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gbnVsbDsKKyAgICAKKyAgICB0cnkgeworICAgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICAgIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oaHRkLCBudWxsLCBudWxsKTsKKyAgICAgCisgICAgICAvLyBzZXQgdXAgc29tZSB0ZXN0IGRhdGEKKyAgICAgIFN0cmluZyB0MTAgPSAiMDEwIjsKKyAgICAgIFN0cmluZyB0MjAgPSAiMDIwIjsKKyAgICAgIFN0cmluZyB0MzAgPSAiMDMwIjsKKyAgICAgIFN0cmluZyB0NDAgPSAiMDQwIjsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUodDEwKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzBdLCAidDEwIGJ5dGVzIi5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHQzMCk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgInQzMCBieXRlcyIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSh0NDApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJ0NDAgYnl0ZXMiLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKworICAgICAgLy8gdHJ5IGZpbmRpbmcgIjAzNSIKKyAgICAgIFN0cmluZyB0MzUgPSAiMDM1IjsKKyAgICAgIE1hcDxieXRlIFtdLCBDZWxsPiByZXN1bHRzID0gCisgICAgICAgIHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXModDM1KSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IFN0cmluZyhyZXN1bHRzLmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSwgInQzMCBieXRlcyIpOworCisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworCisgICAgICAvLyB0cnkgZmluZGluZyAiMDM1IgorICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXModDM1KSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMobmV3IFN0cmluZyhyZXN1bHRzLmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSwgInQzMCBieXRlcyIpOworCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSh0MjApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJ0MjAgYnl0ZXMiLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKworICAgICAgLy8gdHJ5IGZpbmRpbmcgIjAzNSIKKyAgICAgIHJlc3VsdHMgPSByZWdpb24uZ2V0Q2xvc2VzdFJvd0JlZm9yZShCeXRlcy50b0J5dGVzKHQzNSksIENPTFVNTlNbMF0pOworICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSksICJ0MzAgYnl0ZXMiKTsKKworICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKworICAgICAgLy8gdHJ5IGZpbmRpbmcgIjAzNSIKKyAgICAgIHJlc3VsdHMgPSByZWdpb24uZ2V0Q2xvc2VzdFJvd0JlZm9yZShCeXRlcy50b0J5dGVzKHQzNSksIENPTFVNTlNbMF0pOworICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSksICJ0MzAgYnl0ZXMiKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgYWRkVG9Sb3coZmluYWwgSFJlZ2lvbiByLCBmaW5hbCBTdHJpbmcgcm93LCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGZpbmFsIGxvbmcgdHMsIGZpbmFsIGJ5dGUgW10gYnl0ZXMpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUocm93LCB0cyk7CisgICAgYmF0Y2hVcGRhdGUucHV0KGNvbHVtbiwgYnl0ZXMpOworICAgIHIuYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNoZWNrVmVyc2lvbnMoZmluYWwgSFJlZ2lvbiByZWdpb24sIGZpbmFsIFN0cmluZyByb3csCisgICAgICBmaW5hbCBieXRlIFtdIGNvbHVtbikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlIFtdIHIgPSBCeXRlcy50b0J5dGVzKHJvdyk7CisgICAgQ2VsbCBbXSBjZWxscyA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHJlZ2lvbi5nZXQociwgY29sdW1uLCAtMSwgMTAwKSk7CisgICAgYXNzZXJ0VHJ1ZShjZWxscy5sZW5ndGggPT0gSENvbHVtbkRlc2NyaXB0b3IuREVGQVVMVF9WRVJTSU9OUyk7CisgICAgY2VsbHMgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShyZWdpb24uZ2V0KHIsIGNvbHVtbiwgLTEsIDEpKTsKKyAgICBhc3NlcnRUcnVlKGNlbGxzLmxlbmd0aCA9PSAxKTsKKyAgICBjZWxscyA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHJlZ2lvbi5nZXQociwgY29sdW1uLCAtMSwgMTAwMDApKTsKKyAgICBhc3NlcnRUcnVlKGNlbGxzLmxlbmd0aCA9PSBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX1ZFUlNJT05TKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRlc3QgZmlsZSBvZiBtdWx0aXBsZSBkZWxldGVzIGFuZCB3aXRoIGRlbGV0ZXMgYXMgZmluYWwga2V5LgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEJBU0UtNzUxIj5IQkFTRS03NTE8L2E+CisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2xvc2VzdFJvd0JlZm9yZTMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb24gcmVnaW9uID0gbnVsbDsKKyAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gY3JlYXRlVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICByZWdpb24gPSBjcmVhdGVOZXdIUmVnaW9uKGh0ZCwgbnVsbCwgbnVsbCk7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFQwMCk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgVDAwLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoVDEwKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzBdLCBUMTAuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShUMjApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sIFQyMC5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICAKKyAgICAgIE1hcDxieXRlIFtdLCBDZWxsPiByZXN1bHRzID0KKyAgICAgICAgcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMjApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMjAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShUMjApOworICAgICAgYmF0Y2hVcGRhdGUuZGVsZXRlKENPTFVNTlNbMF0pOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKyAgICAgIAorICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDIwKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoVDMwKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzBdLCBUMzAuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMzApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMzAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShUMzApOworICAgICAgYmF0Y2hVcGRhdGUuZGVsZXRlKENPTFVNTlNbMF0pOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDMwKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIHJlc3VsdHMgPSByZWdpb24uZ2V0Q2xvc2VzdFJvd0JlZm9yZShCeXRlcy50b0J5dGVzKFQzMSksIENPTFVNTlNbMF0pOworICAgICAgYXNzZXJ0RXF1YWxzKFQxMCwgbmV3IFN0cmluZyhyZXN1bHRzLmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSk7CisKKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisKKyAgICAgIC8vIHRyeSBmaW5kaW5nICIwMTAiIGFmdGVyIGZsdXNoCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMzApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMTAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDMxKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIAorICAgICAgLy8gUHV0IGludG8gYSBkaWZmZXJlbnQgY29sdW1uIGZhbWlseS4gIFNob3VsZCBtYWtlIGl0IHNvIEkgc3RpbGwgZ2V0IHQxMAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoVDIwKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzFdLCBUMjAuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMzApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMTAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDMxKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMzApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMTAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDMxKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIAorICAgICAgLy8gTm93IHRyeSBjb21ibyBvZiBtZW1jYWNoZSBhbmQgbWFwZmlsZXMuICBEZWxldGUgdGhlIHQyMCBDT0xVTVNbMV0KKyAgICAgIC8vIGluIG1lbW9yeTsgbWFrZSBzdXJlIHdlIGdldCBiYWNrIHQxMCBhZ2Fpbi4KKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFQyMCk7CisgICAgICBiYXRjaFVwZGF0ZS5kZWxldGUoQ09MVU1OU1sxXSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDMwKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDEwLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICAgIAorICAgICAgLy8gQXNrIGZvciBhIHZhbHVlIG9mZiB0aGUgZW5kIG9mIHRoZSBmaWxlLiAgU2hvdWxkIHJldHVybiB0MTAuCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyhUMzEpLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhUMTAsIG5ldyBTdHJpbmcocmVzdWx0cy5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSkpOworICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICAgIHJlc3VsdHMgPSByZWdpb24uZ2V0Q2xvc2VzdFJvd0JlZm9yZShCeXRlcy50b0J5dGVzKFQzMSksIENPTFVNTlNbMF0pOworICAgICAgYXNzZXJ0RXF1YWxzKFQxMCwgbmV3IFN0cmluZyhyZXN1bHRzLmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSk7CisgICAgICAKKyAgICAgIC8vIE9rLiAgTGV0IHRoZSBjYW5kaWRhdGUgY29tZSBvdXQgb2YgbWFwZmlsZXMgYnV0IGhhdmUgZGVsZXRlIG9mCisgICAgICAvLyB0aGUgY2FuZGlkYXRlIGJlIGluIG1lbW9yeS4KKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFQxMSk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgVDExLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFQxMCk7CisgICAgICBiYXRjaFVwZGF0ZS5kZWxldGUoQ09MVU1OU1swXSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgcmVzdWx0cyA9IHJlZ2lvbi5nZXRDbG9zZXN0Um93QmVmb3JlKEJ5dGVzLnRvQnl0ZXMoVDEyKSwgQ09MVU1OU1swXSk7CisgICAgICBhc3NlcnRFcXVhbHMoVDExLCBuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvKioKKyAgICogVGVzdHMgZm9yIEhBRE9PUC0yMTYxLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEdldEZ1bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgSW50ZXJuYWxTY2FubmVyIHNjYW5uZXIgPSBudWxsOworICAgIHRyeSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgICAgcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihodGQsIG51bGwsIG51bGwpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBDT0xVTU5TLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIGFkZENvbnRlbnQocmVnaW9uLCBDT0xVTU5TW2ldKTsKKyAgICAgIH0KKyAgICAgIC8vIEZpbmQgdHdvIHJvd3MgdG8gdXNlIGRvaW5nIGdldEZ1bGwuCisgICAgICBmaW5hbCBieXRlIFtdIGFyYml0cmFyeVN0YXJ0Um93ID0gQnl0ZXMudG9CeXRlcygiYiIpOworICAgICAgYnl0ZSBbXSBhY3R1YWxTdGFydFJvdyA9IG51bGw7CisgICAgICBmaW5hbCBieXRlIFtdIGFyYml0cmFyeVN0b3BSb3cgPSBCeXRlcy50b0J5dGVzKCJjIik7CisgICAgICBieXRlIFtdIGFjdHVhbFN0b3BSb3cgPSBudWxsOworICAgICAgYnl0ZSBbXVtdIGNvbHVtbnMgPSB7Q09MRkFNSUxZX05BTUUxfTsKKyAgICAgIHNjYW5uZXIgPSByZWdpb24uZ2V0U2Nhbm5lcihjb2x1bW5zLAorICAgICAgICAgIGFyYml0cmFyeVN0YXJ0Um93LCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsCisgICAgICAgICAgbmV3IFdoaWxlTWF0Y2hSb3dGaWx0ZXIobmV3IFN0b3BSb3dGaWx0ZXIoYXJiaXRyYXJ5U3RvcFJvdykpKTsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IHZhbHVlID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIHdoaWxlIChzY2FubmVyLm5leHQodmFsdWUpKSB7IAorICAgICAgICBpZiAoYWN0dWFsU3RhcnRSb3cgPT0gbnVsbCkgeworICAgICAgICAgIGFjdHVhbFN0YXJ0Um93ID0gdmFsdWUuZ2V0KDApLmdldFJvdygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGFjdHVhbFN0b3BSb3cgPSB2YWx1ZS5nZXQoMCkuZ2V0Um93KCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIC8vIEFzc2VydCBJIGdvdCBhbGwgb3V0LgorICAgICAgYXNzZXJ0Q29sdW1uc1ByZXNlbnQocmVnaW9uLCBhY3R1YWxTdGFydFJvdyk7CisgICAgICBhc3NlcnRDb2x1bW5zUHJlc2VudChyZWdpb24sIGFjdHVhbFN0b3BSb3cpOworICAgICAgLy8gRm9yY2UgYSBmbHVzaCBzbyBzdG9yZSBmaWxlcyBjb21lIGludG8gcGxheS4KKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisgICAgICAvLyBBc3NlcnQgSSBnb3QgYWxsIG91dC4KKyAgICAgIGFzc2VydENvbHVtbnNQcmVzZW50KHJlZ2lvbiwgYWN0dWFsU3RhcnRSb3cpOworICAgICAgYXNzZXJ0Q29sdW1uc1ByZXNlbnQocmVnaW9uLCBhY3R1YWxTdG9wUm93KTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHNjYW5uZXIgIT0gbnVsbCkgeworICAgICAgICBzY2FubmVyLmNsb3NlKCk7CisgICAgICB9CisgICAgICBpZiAocmVnaW9uICE9IG51bGwpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICByZWdpb24uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICB9CisgICAgICAgIHJlZ2lvbi5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgLyoqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRBdFRpbWVzdGFtcCgpIHRocm93cyBJT0V4Y2VwdGlvbnsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgSFJlZ2lvbkluY29tbW9uIHJlZ2lvbl9pbmNvbW1vbiA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gY3JlYXRlVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICByZWdpb24gPSBjcmVhdGVOZXdIUmVnaW9uKGh0ZCwgbnVsbCwgbnVsbCk7CisgICAgICByZWdpb25faW5jb21tb24gPSBuZXcgSFJlZ2lvbkluY29tbW9uKHJlZ2lvbik7CisgICAgICAKKyAgICAgIGxvbmcgcmlnaHRfbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICBsb25nIG9uZV9zZWNvbmRfYWdvID0gcmlnaHRfbm93IC0gMTAwMDsKKyAgICAgIAorICAgICAgU3RyaW5nIHQgPSAidGVzdF9yb3ciOworICAgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUodCwgb25lX3NlY29uZF9hZ28pOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJvbGQgdGV4dCIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb25faW5jb21tb24uY29tbWl0KGJhdGNoVXBkYXRlKTsKKyAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHQsIHJpZ2h0X25vdyk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgIm5ldyB0ZXh0Ii5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbl9pbmNvbW1vbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgQnl0ZXMudG9CeXRlcyh0KSwgQ09MVU1OU1swXSwKKyAgICAgICAgcmlnaHRfbm93LCAibmV3IHRleHQiKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCBCeXRlcy50b0J5dGVzKHQpLCBDT0xVTU5TWzBdLAorICAgICAgICBvbmVfc2Vjb25kX2FnbywgIm9sZCB0ZXh0Iik7CisgICAgICAKKyAgICAgIC8vIEZvcmNlIGEgZmx1c2ggc28gc3RvcmUgZmlsZXMgY29tZSBpbnRvIHBsYXkuCisgICAgICByZWdpb25faW5jb21tb24uZmx1c2hjYWNoZSgpOworCisgICAgICBhc3NlcnRDZWxsRXF1YWxzKHJlZ2lvbiwgQnl0ZXMudG9CeXRlcyh0KSwgQ09MVU1OU1swXSwgcmlnaHRfbm93LCAibmV3IHRleHQiKTsKKyAgICAgIGFzc2VydENlbGxFcXVhbHMocmVnaW9uLCBCeXRlcy50b0J5dGVzKHQpLCBDT0xVTU5TWzBdLCBvbmVfc2Vjb25kX2FnbywgIm9sZCB0ZXh0Iik7CisKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBGb3IgSEFET09QLTI0NDMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEdldENsb3Nlc3RSb3dCZWZvcmUoKSB0aHJvd3MgSU9FeGNlcHRpb257CisKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSBudWxsOworICAgIAorICAgIHRyeSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgICAgcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihodGQsIG51bGwsIG51bGwpOworICAgICAKKyAgICAgIC8vIHNldCB1cCBzb21lIHRlc3QgZGF0YQorICAgICAgU3RyaW5nIHQxMCA9ICIwMTAiOworICAgICAgU3RyaW5nIHQyMCA9ICIwMjAiOworICAgICAgU3RyaW5nIHQzMCA9ICIwMzAiOworICAgICAgU3RyaW5nIHQzNSA9ICIwMzUiOworICAgICAgU3RyaW5nIHQ0MCA9ICIwNDAiOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSh0MTApOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJ0MTAgYnl0ZXMiLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUodDIwKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT0xVTU5TWzBdLCAidDIwIGJ5dGVzIi5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHQzMCk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgInQzMCBieXRlcyIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZSh0MzUpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KENPTFVNTlNbMF0sICJ0MzUgYnl0ZXMiLmdldEJ5dGVzKCkpOworICAgICAgcmVnaW9uLmJhdGNoVXBkYXRlKGJhdGNoVXBkYXRlLCBudWxsKTsKKyAgICAgIAorICAgICAgYmF0Y2hVcGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUodDM1KTsKKyAgICAgIGJhdGNoVXBkYXRlLmRlbGV0ZShDT0xVTU5TWzBdKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShiYXRjaFVwZGF0ZSwgbnVsbCk7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKHQ0MCk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQ09MVU1OU1swXSwgInQ0MCBieXRlcyIuZ2V0Qnl0ZXMoKSk7CisgICAgICByZWdpb24uYmF0Y2hVcGRhdGUoYmF0Y2hVcGRhdGUsIG51bGwpOworICAgICAgCisgICAgICAvLyB0cnkgZmluZGluZyAiMDE1IgorICAgICAgU3RyaW5nIHQxNSA9ICIwMTUiOworICAgICAgTWFwPGJ5dGUgW10sIENlbGw+IHJlc3VsdHMgPSAKKyAgICAgICAgcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MTUpLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDEwIGJ5dGVzIik7CisKKyAgICAgIC8vIHRyeSAiMDIwIiwgd2Ugc2hvdWxkIGdldCB0aGF0IHJvdyBleGFjdGx5CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MjApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDIwIGJ5dGVzIik7CisgICAgICAKKyAgICAgIC8vIHRyeSAiMDM4Iiwgc2hvdWxkIHNraXAgZGVsZXRlZCAiMDM1IiBhbmQgZ2V0ICIwMzAiCisgICAgICBTdHJpbmcgdDM4ID0gIjAzOCI7CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MzgpLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDMwIGJ5dGVzIik7CisgICAgICAKKyAgICAgIC8vIHRyeSAiMDUwIiwgc2hvdWxkIGdldCBzdHVmZiBmcm9tICIwNDAiCisgICAgICBTdHJpbmcgdDUwID0gIjA1MCI7CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0NTApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDQwIGJ5dGVzIik7CisKKyAgICAgIC8vIGZvcmNlIGEgZmx1c2gKKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisKKyAgICAgIC8vIHRyeSBmaW5kaW5nICIwMTUiCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MTUpLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDEwIGJ5dGVzIik7CisKKyAgICAgIC8vIHRyeSAiMDIwIiwgd2Ugc2hvdWxkIGdldCB0aGF0IHJvdyBleGFjdGx5CisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MjApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDIwIGJ5dGVzIik7CisKKyAgICAgIC8vIHRyeSAiMDM4Iiwgc2hvdWxkIHNraXAgZGVsZXRlZCAiMDM1IiBhbmQgZ2V0ICIwMzAiCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0MzgpLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDMwIGJ5dGVzIik7CisKKyAgICAgIC8vIHRyeSAiMDUwIiwgc2hvdWxkIGdldCBzdHVmZiBmcm9tICIwNDAiCisgICAgICByZXN1bHRzID0gcmVnaW9uLmdldENsb3Nlc3RSb3dCZWZvcmUoQnl0ZXMudG9CeXRlcyh0NTApLCBDT0xVTU5TWzBdKTsKKyAgICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdHMuZ2V0KENPTFVNTlNbMF0pLmdldFZhbHVlKCkpLCAidDQwIGJ5dGVzIik7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChyZWdpb24gIT0gbnVsbCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJlZ2lvbi5jbG9zZSgpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgIH0KKyAgICAgICAgcmVnaW9uLmdldExvZygpLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEZvciBIQkFTRS00MAorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEdldEZ1bGxXaXRoU3BlY2lmaWVkQ29sdW1ucygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSFJlZ2lvbiByZWdpb24gPSBudWxsOworICAgIEhSZWdpb25JbmNvbW1vbiByZWdpb25faW5jb21tb24gPSBudWxsOworICAgIHRyeSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgICAgcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihodGQsIG51bGwsIG51bGwpOworICAgICAgcmVnaW9uX2luY29tbW9uID0gbmV3IEhSZWdpb25JbmNvbW1vbihyZWdpb24pOworICAgICAgCisgICAgICAvLyB3cml0ZSBhIHJvdyB3aXRoIGEgYnVuY2ggb2YgY29sdW1ucworICAgICAgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJzb21lX3JvdyIpOworICAgICAgQmF0Y2hVcGRhdGUgYnUgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgIGJ1LnB1dChDT0xVTU5TWzBdLCAiY29sdW1uIDAiLmdldEJ5dGVzKCkpOworICAgICAgYnUucHV0KENPTFVNTlNbMV0sICJjb2x1bW4gMSIuZ2V0Qnl0ZXMoKSk7CisgICAgICBidS5wdXQoQ09MVU1OU1syXSwgImNvbHVtbiAyIi5nZXRCeXRlcygpKTsKKyAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZShidSwgbnVsbCk7CisgICAgICAKKyAgICAgIGFzc2VydFNwZWNpZmllZENvbHVtbnMocmVnaW9uLCByb3cpOworICAgICAgLy8gdHJ5IGl0IGFnYWluIHdpdGggYSBjYWNoZSBmbHVzaCB0byBpbnZvbHZlIHRoZSBzdG9yZSwgbm90IGp1c3QgdGhlIAorICAgICAgLy8gbWVtY2FjaGUuCisgICAgICByZWdpb25faW5jb21tb24uZmx1c2hjYWNoZSgpOworICAgICAgYXNzZXJ0U3BlY2lmaWVkQ29sdW1ucyhyZWdpb24sIHJvdyk7CisgICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgcmVnaW9uLmNsb3NlKCk7CisgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgICAgfQorICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9ICAgIAorICB9CisgIAorICBwcml2YXRlIHZvaWQgYXNzZXJ0U3BlY2lmaWVkQ29sdW1ucyhmaW5hbCBIUmVnaW9uIHJlZ2lvbiwgZmluYWwgYnl0ZSBbXSByb3cpIAorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFRyZWVTZXQ8Ynl0ZSBbXT4gYWxsID0gbmV3IFRyZWVTZXQ8Ynl0ZSBbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgVHJlZVNldDxieXRlIFtdPiBvbmUgPSBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICBUcmVlU2V0PGJ5dGUgW10+IG5vbmUgPSBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICAKKyAgICBhbGwuYWRkKENPTFVNTlNbMF0pOworICAgIGFsbC5hZGQoQ09MVU1OU1sxXSk7CisgICAgYWxsLmFkZChDT0xVTU5TWzJdKTsgICAgICAKKyAgICBvbmUuYWRkKENPTFVNTlNbMF0pOworCisgICAgLy8gbWFrZSBzdXJlIHdlIGdldCBhbGwgb2YgdGhlbSB3aXRoIHN0YW5kYXJkIGdldEZ1bGwKKyAgICBNYXA8Ynl0ZSBbXSwgQ2VsbD4gcmVzdWx0ID0gcmVnaW9uLmdldEZ1bGwocm93LCBudWxsLCAKKyAgICAgIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAwIik7CisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzFdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAxIik7CisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzJdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAyIik7CisgICAgICAgICAgCisgICAgLy8gdHJ5IHRvIGdldCBqdXN0IG9uZQorICAgIHJlc3VsdCA9IHJlZ2lvbi5nZXRGdWxsKHJvdywgb25lLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVAsIDEsIG51bGwpOworICAgIGFzc2VydEVxdWFscyhuZXcgU3RyaW5nKHJlc3VsdC5nZXQoQ09MVU1OU1swXSkuZ2V0VmFsdWUoKSksICJjb2x1bW4gMCIpOworICAgIGFzc2VydE51bGwocmVzdWx0LmdldChDT0xVTU5TWzFdKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICBhc3NlcnROdWxsKHJlc3VsdC5nZXQoQ09MVU1OU1syXSkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgIC8vIHRyeSB0byBnZXQgYWxsIG9mIHRoZW0gKHNwZWNpZmllZCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICByZXN1bHQgPSByZWdpb24uZ2V0RnVsbChyb3csIGFsbCwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsgICAgICAgCisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzBdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAwIik7CisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzFdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAxIik7CisgICAgYXNzZXJ0RXF1YWxzKG5ldyBTdHJpbmcocmVzdWx0LmdldChDT0xVTU5TWzJdKS5nZXRWYWx1ZSgpKSwgImNvbHVtbiAyIik7CisgICAgCisgICAgLy8gdHJ5IHRvIGdldCBub25lIHdpdGggZW1wdHkgY29sdW1uIHNldAorICAgIHJlc3VsdCA9IHJlZ2lvbi5nZXRGdWxsKHJvdywgbm9uZSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCAxLCBudWxsKTsKKyAgICBhc3NlcnROdWxsKHJlc3VsdC5nZXQoQ09MVU1OU1swXSkpOworICAgIGFzc2VydE51bGwocmVzdWx0LmdldChDT0xVTU5TWzFdKSk7CisgICAgYXNzZXJ0TnVsbChyZXN1bHQuZ2V0KENPTFVNTlNbMl0pKTsgICAgCisgIH0gIAorCisgIHByaXZhdGUgdm9pZCBhc3NlcnRDb2x1bW5zUHJlc2VudChmaW5hbCBIUmVnaW9uIHIsIGZpbmFsIGJ5dGUgW10gcm93KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE1hcDxieXRlIFtdLCBDZWxsPiByZXN1bHQgPSAKKyAgICAgIHIuZ2V0RnVsbChyb3csIG51bGwsIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwgMSwgbnVsbCk7CisgICAgaW50IGNvbHVtbkNvdW50ID0gMDsKKyAgICBmb3IgKE1hcC5FbnRyeTxieXRlIFtdLCBDZWxsPiBlOiByZXN1bHQuZW50cnlTZXQoKSkgeworICAgICAgY29sdW1uQ291bnQrKzsKKyAgICAgIGJ5dGUgW10gY29sdW1uID0gZS5nZXRLZXkoKTsKKyAgICAgIGJvb2xlYW4gbGVnaXRDb2x1bW4gPSBmYWxzZTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQ09MVU1OUy5sZW5ndGg7IGkrKykgeworICAgICAgICAvLyBBc3NlcnQgdmFsdWUgaXMgc2FtZSBhcyByb3cuICBUaGlzIGlzICduYXR1cmUnIG9mIHRoZSBkYXRhIGFkZGVkLgorICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3csIGUuZ2V0VmFsdWUoKS5nZXRWYWx1ZSgpKSk7CisgICAgICAgIGlmIChCeXRlcy5lcXVhbHMoQ09MVU1OU1tpXSwgY29sdW1uKSkgeworICAgICAgICAgIGxlZ2l0Q29sdW1uID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYXNzZXJ0VHJ1ZSgiaXMgbGVnaXQgY29sdW1uIG5hbWUiLCBsZWdpdENvbHVtbik7CisgICAgfQorICAgIGFzc2VydEVxdWFscygiY291bnQgb2YgY29sdW1ucyIsIGNvbHVtbkNvdW50LCBDT0xVTU5TLmxlbmd0aCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBpZiAodGhpcy5taW5pSGRmcyAhPSBudWxsKSB7CisgICAgICB0aGlzLm1pbmlIZGZzLnNodXRkb3duKCk7CisgICAgfQorICAgIHN1cGVyLnRlYXJEb3duKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0SExvZy5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RITG9nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTJhYmU1NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0SExvZy5qYXZhCkBAIC0wLDAgKzEsMTUxIEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZGZzLk1pbmlERlNDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaW8uU2VxdWVuY2VGaWxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmlvLlNlcXVlbmNlRmlsZS5SZWFkZXI7CisKKy8qKiBKVW5pdCB0ZXN0IGNhc2UgZm9yIEhMb2cgKi8KK3B1YmxpYyBjbGFzcyBUZXN0SExvZyBleHRlbmRzIEhCYXNlVGVzdENhc2UgaW1wbGVtZW50cyBIQ29uc3RhbnRzIHsKKyAgcHJpdmF0ZSBQYXRoIGRpcjsKKyAgcHJpdmF0ZSBNaW5pREZTQ2x1c3RlciBjbHVzdGVyOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGNsdXN0ZXIgPSBuZXcgTWluaURGU0NsdXN0ZXIoY29uZiwgMiwgdHJ1ZSwgKFN0cmluZ1tdKW51bGwpOworICAgIC8vIFNldCB0aGUgaGJhc2Uucm9vdGRpciB0byBiZSB0aGUgaG9tZSBkaXJlY3RvcnkgaW4gbWluaSBkZnMuCisgICAgdGhpcy5jb25mLnNldChIQ29uc3RhbnRzLkhCQVNFX0RJUiwKKyAgICAgIHRoaXMuY2x1c3Rlci5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICAgIHN1cGVyLnNldFVwKCk7CisgICAgdGhpcy5kaXIgPSBuZXcgUGF0aCgiL2hiYXNlIiwgZ2V0TmFtZSgpKTsKKyAgICBpZiAoZnMuZXhpc3RzKGRpcikpIHsKKyAgICAgIGZzLmRlbGV0ZShkaXIsIHRydWUpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIGlmICh0aGlzLmZzLmV4aXN0cyh0aGlzLmRpcikpIHsKKyAgICAgIHRoaXMuZnMuZGVsZXRlKHRoaXMuZGlyLCB0cnVlKTsKKyAgICB9CisgICAgc2h1dGRvd25EZnMoY2x1c3Rlcik7CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgfQorIAorICAvKioKKyAgICogSnVzdCB3cml0ZSBtdWx0aXBsZSBsb2dzIHRoZW4gc3BsaXQuICBCZWZvcmUgZml4IGZvciBIQURPT1AtMjI4MywgdGhpcworICAgKiB3b3VsZCBmYWlsLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U3BsaXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lID0gQnl0ZXMudG9CeXRlcyhnZXROYW1lKCkpOworICAgIGZpbmFsIGJ5dGUgW10gcm93TmFtZSA9IHRhYmxlTmFtZTsKKyAgICBITG9nIGxvZyA9IG5ldyBITG9nKHRoaXMuZnMsIHRoaXMuZGlyLCB0aGlzLmNvbmYsIG51bGwpOworICAgIC8vIEFkZCBlZGl0cyBmb3IgdGhyZWUgcmVnaW9ucy4KKyAgICB0cnkgeworICAgICAgZm9yIChpbnQgaWkgPSAwOyBpaSA8IDM7IGlpKyspIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKKyAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IDM7IGorKykgeworICAgICAgICAgICAgTGlzdDxLZXlWYWx1ZT4gZWRpdCA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgICAgICBieXRlIFtdIGNvbHVtbiA9IEJ5dGVzLnRvQnl0ZXMoImNvbHVtbjoiICsgSW50ZWdlci50b1N0cmluZyhqKSk7CisgICAgICAgICAgICBlZGl0LmFkZChuZXcgS2V5VmFsdWUocm93TmFtZSwgY29sdW1uLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAgICAgICAgICAgICAgY29sdW1uKSk7CisgICAgICAgICAgICBsb2cuYXBwZW5kKEJ5dGVzLnRvQnl0ZXMoSW50ZWdlci50b1N0cmluZyhpKSksIHRhYmxlTmFtZSwgZWRpdCwgZmFsc2UpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBsb2cucm9sbFdyaXRlcigpOworICAgICAgfQorICAgICAgSExvZy5zcGxpdExvZyh0aGlzLnRlc3REaXIsIHRoaXMuZGlyLCB0aGlzLmZzLCB0aGlzLmNvbmYpOworICAgICAgbG9nID0gbnVsbDsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKGxvZyAhPSBudWxsKSB7CisgICAgICAgIGxvZy5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0QXBwZW5kKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBpbnQgQ09MX0NPVU5UID0gMTA7CisgICAgZmluYWwgYnl0ZSBbXSByZWdpb25OYW1lID0gQnl0ZXMudG9CeXRlcygicmVnaW9ubmFtZSIpOworICAgIGZpbmFsIGJ5dGUgW10gdGFibGVOYW1lID0gQnl0ZXMudG9CeXRlcygidGFibGVuYW1lIik7CisgICAgZmluYWwgYnl0ZSBbXSByb3cgPSBCeXRlcy50b0J5dGVzKCJyb3ciKTsKKyAgICBSZWFkZXIgcmVhZGVyID0gbnVsbDsKKyAgICBITG9nIGxvZyA9IG5ldyBITG9nKGZzLCBkaXIsIHRoaXMuY29uZiwgbnVsbCk7CisgICAgdHJ5IHsKKyAgICAgIC8vIFdyaXRlIGNvbHVtbnMgbmFtZWQgMSwgMiwgMywgZXRjLiBhbmQgdGhlbiB2YWx1ZXMgb2Ygc2luZ2xlIGJ5dGUKKyAgICAgIC8vIDEsIDIsIDMuLi4KKyAgICAgIGxvbmcgdGltZXN0YW1wID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICBMaXN0PEtleVZhbHVlPiBjb2xzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQ09MX0NPVU5UOyBpKyspIHsKKyAgICAgICAgY29scy5hZGQobmV3IEtleVZhbHVlKHJvdywgQnl0ZXMudG9CeXRlcygiY29sdW1uOiIgKyBJbnRlZ2VyLnRvU3RyaW5nKGkpKSwKKyAgICAgICAgICB0aW1lc3RhbXAsIG5ldyBieXRlW10geyAoYnl0ZSkoaSArICcwJykgfSkpOworICAgICAgfQorICAgICAgbG9nLmFwcGVuZChyZWdpb25OYW1lLCB0YWJsZU5hbWUsIGNvbHMsIGZhbHNlKTsKKyAgICAgIGxvbmcgbG9nU2VxSWQgPSBsb2cuc3RhcnRDYWNoZUZsdXNoKCk7CisgICAgICBsb2cuY29tcGxldGVDYWNoZUZsdXNoKHJlZ2lvbk5hbWUsIHRhYmxlTmFtZSwgbG9nU2VxSWQpOworICAgICAgbG9nLmNsb3NlKCk7CisgICAgICBQYXRoIGZpbGVuYW1lID0gbG9nLmNvbXB1dGVGaWxlbmFtZShsb2cuZ2V0RmlsZW51bSgpKTsKKyAgICAgIGxvZyA9IG51bGw7CisgICAgICAvLyBOb3cgb3BlbiBhIHJlYWRlciBvbiB0aGUgbG9nIGFuZCBhc3NlcnQgYXBwZW5kIHdvcmtlZC4KKyAgICAgIHJlYWRlciA9IG5ldyBTZXF1ZW5jZUZpbGUuUmVhZGVyKGZzLCBmaWxlbmFtZSwgY29uZik7CisgICAgICBITG9nS2V5IGtleSA9IG5ldyBITG9nS2V5KCk7CisgICAgICBLZXlWYWx1ZSB2YWwgPSBuZXcgS2V5VmFsdWUoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQ09MX0NPVU5UOyBpKyspIHsKKyAgICAgICAgcmVhZGVyLm5leHQoa2V5LCB2YWwpOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyZWdpb25OYW1lLCBrZXkuZ2V0UmVnaW9uTmFtZSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHRhYmxlTmFtZSwga2V5LmdldFRhYmxlbmFtZSgpKSk7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvdywgdmFsLmdldFJvdygpKSk7CisgICAgICAgIGFzc2VydEVxdWFscygoYnl0ZSkoaSArICcwJyksIHZhbC5nZXRWYWx1ZSgpWzBdKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGtleSArICIgIiArIHZhbCk7CisgICAgICB9CisgICAgICB3aGlsZSAocmVhZGVyLm5leHQoa2V5LCB2YWwpKSB7CisgICAgICAgIC8vIEFzc2VydCBvbmx5IG9uZSBtb3JlIHJvdy4uLiB0aGUgbWV0YSBmbHVzaGVkIHJvdy4KKyAgICAgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocmVnaW9uTmFtZSwga2V5LmdldFJlZ2lvbk5hbWUoKSkpOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyh0YWJsZU5hbWUsIGtleS5nZXRUYWJsZW5hbWUoKSkpOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhITG9nLk1FVEFST1csIHZhbC5nZXRSb3coKSkpOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhITG9nLk1FVEFDT0xVTU4sIHZhbC5nZXRDb2x1bW4oKSkpOworICAgICAgICBhc3NlcnRFcXVhbHMoMCwgQnl0ZXMuY29tcGFyZVRvKEhMb2cuQ09NUExFVEVfQ0FDSEVfRkxVU0gsCisgICAgICAgICAgdmFsLmdldFZhbHVlKCkpKTsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGtleSArICIgIiArIHZhbCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChsb2cgIT0gbnVsbCkgeworICAgICAgICBsb2cuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICAgIGlmIChyZWFkZXIgIT0gbnVsbCkgeworICAgICAgICByZWFkZXIuY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0SE1lbWNhY2hlLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhNZW1jYWNoZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxYTQyMDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhNZW1jYWNoZS5qYXZhCkBAIC0wLDAgKzEsNDU4IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnJtaS5VbmV4cGVjdGVkRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTmF2aWdhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uLkNvdW50ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIG1lbWNhY2hlIHRlc3QgY2FzZSAqLworcHVibGljIGNsYXNzIFRlc3RITWVtY2FjaGUgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgTWVtY2FjaGUgaG1lbWNhY2hlOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBST1dfQ09VTlQgPSAxMDsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OU19DT1VOVCA9IDEwOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTFVNTl9GQU1JTFkgPSAiY29sdW1uIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklSU1RfUk9XID0gMTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE5VTV9WQUxTID0gMTAwMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT05URU5UU19CQVNJQyA9IEJ5dGVzLnRvQnl0ZXMoImNvbnRlbnRzOmJhc2ljIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05URU5UU1RSID0gImNvbnRlbnRzdHIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5DSE9STlVNID0gImFuY2hvcjphbmNob3JudW0tIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFOQ0hPUlNUUiA9ICJhbmNob3JzdHIiOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnNldFVwKCk7CisgICAgdGhpcy5obWVtY2FjaGUgPSBuZXcgTWVtY2FjaGUoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RHZXRXaXRoRGVsZXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWVtY2FjaGUgbWMgPSBuZXcgTWVtY2FjaGUoSENvbnN0YW50cy5GT1JFVkVSLCBLZXlWYWx1ZS5ST09UX0NPTVBBUkFUT1IpOworICAgIGZpbmFsIGludCBzdGFydCA9IDA7CisgICAgZmluYWwgaW50IGVuZCA9IDU7CisgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBmb3IgKGludCBrID0gc3RhcnQ7IGsgPD0gZW5kOyBrKyspIHsKKyAgICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcyhrKTsKKyAgICAgIEtleVZhbHVlIGtleSA9IG5ldyBLZXlWYWx1ZShyb3csIENPTlRFTlRTX0JBU0lDLCBub3csCisgICAgICAgIChDT05URU5UU1RSICsgaykuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICBtYy5hZGQoa2V5KTsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihrZXkpOworICAgICAga2V5ID0gbmV3IEtleVZhbHVlKHJvdywgQnl0ZXMudG9CeXRlcyhBTkNIT1JOVU0gKyBrKSwgbm93LAorICAgICAgICAoQU5DSE9SU1RSICsgaykuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICBtYy5hZGQoa2V5KTsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihrZXkpOworICAgIH0KKyAgICBLZXlWYWx1ZSBrZXkgPSBuZXcgS2V5VmFsdWUoQnl0ZXMudG9CeXRlcyhzdGFydCksIENPTlRFTlRTX0JBU0lDLCBub3cpOworICAgIExpc3Q8S2V5VmFsdWU+IGtleXMgPSBtYy5nZXQoa2V5LCAxKTsKKyAgICBhc3NlcnRUcnVlKGtleXMuc2l6ZSgpID09IDEpOworICAgIEtleVZhbHVlIGRlbGV0ZSA9IGtleS5jbG9uZURlbGV0ZSgpOworICAgIG1jLmFkZChkZWxldGUpOworICAgIGtleXMgPSBtYy5nZXQoZGVsZXRlLCAxKTsKKyAgICBhc3NlcnRUcnVlKGtleXMuc2l6ZSgpID09IDApOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdEJpbmFyeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTWVtY2FjaGUgbWMgPSBuZXcgTWVtY2FjaGUoSENvbnN0YW50cy5GT1JFVkVSLCBLZXlWYWx1ZS5ST09UX0NPTVBBUkFUT1IpOworICAgIGZpbmFsIGludCBzdGFydCA9IDQzOworICAgIGZpbmFsIGludCBlbmQgPSA0NjsKKyAgICBmb3IgKGludCBrID0gc3RhcnQ7IGsgPD0gZW5kOyBrKyspIHsKKyAgICAgIGJ5dGUgW10ga2sgPSBCeXRlcy50b0J5dGVzKGspOworICAgICAgYnl0ZSBbXSByb3cgPQorICAgICAgICBCeXRlcy50b0J5dGVzKCIuTUVUQS4sdGFibGUsIiArIEJ5dGVzLnRvU3RyaW5nKGtrKSArICIsMSwiICsgayk7CisgICAgICBLZXlWYWx1ZSBrZXkgPSBuZXcgS2V5VmFsdWUocm93LCBDT05URU5UU19CQVNJQywKKyAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCksCisgICAgICAgIChDT05URU5UU1RSICsgaykuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICBtYy5hZGQoa2V5KTsKKyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihrZXkpOworLy8gICAgICBrZXkgPSBuZXcgS2V5VmFsdWUocm93LCBCeXRlcy50b0J5dGVzKEFOQ0hPUk5VTSArIGspLAorLy8gICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLAorLy8gICAgICAgIChBTkNIT1JTVFIgKyBrKS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKy8vICAgICAgbWMuYWRkKGtleSk7CisvLyAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihrZXkpOworICAgIH0KKyAgICBpbnQgaW5kZXggPSBzdGFydDsKKyAgICBmb3IgKEtleVZhbHVlIGt2OiBtYy5tZW1jYWNoZSkgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKGt2KTsKKyAgICAgIGJ5dGUgW10gYiA9IGt2LmdldFJvdygpOworICAgICAgLy8gSGFyZGNvZGVkIG9mZnNldHMgaW50byBTdHJpbmcKKyAgICAgIFN0cmluZyBzdHIgPSBCeXRlcy50b1N0cmluZyhiLCAxMywgNCk7CisgICAgICBieXRlIFtdIGJiID0gQnl0ZXMudG9CeXRlcyhpbmRleCk7CisgICAgICBTdHJpbmcgYmJTdHIgPSBCeXRlcy50b1N0cmluZyhiYik7CisgICAgICBhc3NlcnRFcXVhbHMoc3RyLCBiYlN0cik7CisgICAgICBpbmRleCsrOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdE1lbWNhY2hlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKGludCBrID0gRklSU1RfUk9XOyBrIDw9IE5VTV9WQUxTOyBrKyspIHsKKyAgICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcygicm93XyIgKyBrKTsKKyAgICAgIEtleVZhbHVlIGtleSA9IG5ldyBLZXlWYWx1ZShyb3csIENPTlRFTlRTX0JBU0lDLAorICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwKKyAgICAgICAgKENPTlRFTlRTVFIgKyBrKS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIGhtZW1jYWNoZS5hZGQoa2V5KTsKKyAgICAgIGtleSA9IG5ldyBLZXlWYWx1ZShyb3csIEJ5dGVzLnRvQnl0ZXMoQU5DSE9STlVNICsgayksCisgICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLAorICAgICAgICAoQU5DSE9SU1RSICsgaykuZ2V0Qnl0ZXMoSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKSk7CisgICAgICBobWVtY2FjaGUuYWRkKGtleSk7CisgICAgfQorICAgIC8vIHRoaXMuaG1lbWNhY2hlLmR1bXAoKTsKKworICAgIC8vIFJlYWQgdGhlbSBiYWNrCisKKyAgICBmb3IgKGludCBrID0gRklSU1RfUk9XOyBrIDw9IE5VTV9WQUxTOyBrKyspIHsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IHJlc3VsdHM7CisgICAgICBieXRlIFtdIHJvdyA9IEJ5dGVzLnRvQnl0ZXMoInJvd18iICsgayk7CisgICAgICBLZXlWYWx1ZSBrZXkgPSBuZXcgS2V5VmFsdWUocm93LCBDT05URU5UU19CQVNJQywgTG9uZy5NQVhfVkFMVUUpOworICAgICAgcmVzdWx0cyA9IGhtZW1jYWNoZS5nZXQoa2V5LCAxKTsKKyAgICAgIGFzc2VydE5vdE51bGwoIm5vIGRhdGEgZm9yICIgKyBrZXkudG9TdHJpbmcoKSwgcmVzdWx0cyk7CisgICAgICBhc3NlcnRFcXVhbHMoMSwgcmVzdWx0cy5zaXplKCkpOworICAgICAgS2V5VmFsdWUga3YgPSByZXN1bHRzLmdldCgwKTsKKyAgICAgIFN0cmluZyBib2R5c3RyID0gQnl0ZXMudG9TdHJpbmcoa3YuZ2V0QnVmZmVyKCksIGt2LmdldFZhbHVlT2Zmc2V0KCksCisgICAgICAgIGt2LmdldFZhbHVlTGVuZ3RoKCkpOworICAgICAgU3RyaW5nIHRlc3RzdHIgPSBDT05URU5UU1RSICsgazsKKyAgICAgIGFzc2VydFRydWUoIkluY29ycmVjdCB2YWx1ZSBmb3Iga2V5OiAoIiArIGtleS50b1N0cmluZygpICsKKyAgICAgICAgICAiKSwgZXhwZWN0ZWQ6ICciICsgdGVzdHN0ciArICInIGdvdDogJyIgKworICAgICAgICAgIGJvZHlzdHIgKyAiJyIsIHRlc3RzdHIuY29tcGFyZVRvKGJvZHlzdHIpID09IDApOworICAgICAgCisgICAgICBrZXkgPSBuZXcgS2V5VmFsdWUocm93LCBCeXRlcy50b0J5dGVzKEFOQ0hPUk5VTSArIGspLCBMb25nLk1BWF9WQUxVRSk7CisgICAgICByZXN1bHRzID0gaG1lbWNhY2hlLmdldChrZXksIDEpOworICAgICAgYXNzZXJ0Tm90TnVsbCgibm8gZGF0YSBmb3IgIiArIGtleS50b1N0cmluZygpLCByZXN1bHRzKTsKKyAgICAgIGFzc2VydEVxdWFscygxLCByZXN1bHRzLnNpemUoKSk7CisgICAgICBrdiA9IHJlc3VsdHMuZ2V0KDApOworICAgICAgYm9keXN0ciA9IEJ5dGVzLnRvU3RyaW5nKGt2LmdldEJ1ZmZlcigpLCBrdi5nZXRWYWx1ZU9mZnNldCgpLAorICAgICAgICBrdi5nZXRWYWx1ZUxlbmd0aCgpKTsKKyAgICAgIHRlc3RzdHIgPSBBTkNIT1JTVFIgKyBrOworICAgICAgYXNzZXJ0VHJ1ZSgiSW5jb3JyZWN0IHZhbHVlIGZvciBrZXk6ICgiICsga2V5LnRvU3RyaW5nKCkgKworICAgICAgICAgICIpLCBleHBlY3RlZDogJyIgKyB0ZXN0c3RyICsgIicgZ290OiAnIiArIGJvZHlzdHIgKyAiJyIsCisgICAgICAgICAgdGVzdHN0ci5jb21wYXJlVG8oYm9keXN0cikgPT0gMCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBieXRlIFtdIGdldFJvd05hbWUoZmluYWwgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIEJ5dGVzLnRvQnl0ZXMoInJvdyIgKyBJbnRlZ2VyLnRvU3RyaW5nKGluZGV4KSk7CisgIH0KKworICBwcml2YXRlIGJ5dGUgW10gZ2V0Q29sdW1uTmFtZShmaW5hbCBpbnQgcm93SW5kZXgsIGZpbmFsIGludCBjb2xJbmRleCkgeworICAgIHJldHVybiBCeXRlcy50b0J5dGVzKENPTFVNTl9GQU1JTFkgKyAiOiIgKyBJbnRlZ2VyLnRvU3RyaW5nKHJvd0luZGV4KSArICI7IiArCisgICAgICAgIEludGVnZXIudG9TdHJpbmcoY29sSW5kZXgpKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGRzIHtAbGluayAjUk9XX0NPVU5UfSByb3dzIGFuZCB7QGxpbmsgI0NPTFVNTlNfQ09VTlR9CisgICAqIEBwYXJhbSBobWMgSW5zdGFuY2UgdG8gYWRkIHJvd3MgdG8uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gCisgICAqLworICBwcml2YXRlIHZvaWQgYWRkUm93cyhmaW5hbCBNZW1jYWNoZSBobWMpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IFJPV19DT1VOVDsgaSsrKSB7CisgICAgICBsb25nIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgICAgZm9yIChpbnQgaWkgPSAwOyBpaSA8IENPTFVNTlNfQ09VTlQ7IGlpKyspIHsKKyAgICAgICAgYnl0ZSBbXSBrID0gZ2V0Q29sdW1uTmFtZShpLCBpaSk7CisgICAgICAgIGhtYy5hZGQobmV3IEtleVZhbHVlKGdldFJvd05hbWUoaSksIGssIHRpbWVzdGFtcCwgaykpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBydW5TbmFwc2hvdChmaW5hbCBNZW1jYWNoZSBobWMpIHRocm93cyBVbmV4cGVjdGVkRXhjZXB0aW9uIHsKKyAgICAvLyBTYXZlIG9mZiBvbGQgc3RhdGUuCisgICAgaW50IG9sZEhpc3RvcnlTaXplID0gaG1jLmdldFNuYXBzaG90KCkuc2l6ZSgpOworICAgIGhtYy5zbmFwc2hvdCgpOworICAgIFNldDxLZXlWYWx1ZT4gc3MgPSBobWMuZ2V0U25hcHNob3QoKTsKKyAgICAvLyBNYWtlIHNvbWUgYXNzZXJ0aW9ucyBhYm91dCB3aGF0IGp1c3QgaGFwcGVuZWQuCisgICAgYXNzZXJ0VHJ1ZSgiSGlzdG9yeSBzaXplIGhhcyBub3QgaW5jcmVhc2VkIiwgb2xkSGlzdG9yeVNpemUgPCBzcy5zaXplKCkpOworICAgIGhtYy5jbGVhclNuYXBzaG90KHNzKTsKKyAgfQorCisgIC8qKiAKKyAgICogVGVzdCBtZW1jYWNoZSBzbmFwc2hvdHMKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNuYXBzaG90dGluZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgaW50IHNuYXBzaG90Q291bnQgPSA1OworICAgIC8vIEFkZCBzb21lIHJvd3MsIHJ1biBhIHNuYXBzaG90LiBEbyBpdCBhIGZldyB0aW1lcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNuYXBzaG90Q291bnQ7IGkrKykgeworICAgICAgYWRkUm93cyh0aGlzLmhtZW1jYWNoZSk7CisgICAgICBydW5TbmFwc2hvdCh0aGlzLmhtZW1jYWNoZSk7CisgICAgICBTZXQ8S2V5VmFsdWU+IHNzID0gdGhpcy5obWVtY2FjaGUuZ2V0U25hcHNob3QoKTsKKyAgICAgIGFzc2VydEVxdWFscygiSGlzdG9yeSBub3QgYmVpbmcgY2xlYXJlZCIsIDAsIHNzLnNpemUoKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGlzRXhwZWN0ZWRSb3dXaXRob3V0VGltZXN0YW1wcyhmaW5hbCBpbnQgcm93SW5kZXgsCisgICAgICBMaXN0PEtleVZhbHVlPiBrdnMpIHsKKyAgICBpbnQgaSA9IDA7CisgICAgZm9yIChLZXlWYWx1ZSBrdjoga3ZzKSB7CisgICAgICBTdHJpbmcgZXhwZWN0ZWRDb2xuYW1lID0gQnl0ZXMudG9TdHJpbmcoZ2V0Q29sdW1uTmFtZShyb3dJbmRleCwgaSsrKSk7CisgICAgICBTdHJpbmcgY29sbmFtZVN0ciA9IGt2LmdldENvbHVtblN0cmluZygpOworICAgICAgYXNzZXJ0RXF1YWxzKCJDb2x1bW4gbmFtZSIsIGNvbG5hbWVTdHIsIGV4cGVjdGVkQ29sbmFtZSk7CisgICAgICAvLyBWYWx1ZSBpcyBjb2x1bW4gbmFtZSBhcyBieXRlcy4gIFVzdWFsbHkgcmVzdWx0IGlzCisgICAgICAvLyAxMDAgYnl0ZXMgaW4gc2l6ZSBhdCBsZWFzdC4gVGhpcyBpcyB0aGUgZGVmYXVsdCBzaXplCisgICAgICAvLyBmb3IgQnl0ZXNXcml0ZWFibGUuICBGb3IgY29tcGFyaXNvbiwgY29udmVydCBieXRlcyB0bworICAgICAgLy8gU3RyaW5nIGFuZCB0cmltIHRvIHJlbW92ZSB0cmFpbGluZyBudWxsIGJ5dGVzLgorICAgICAgU3RyaW5nIGNvbHZhbHVlU3RyID0gQnl0ZXMudG9TdHJpbmcoa3YuZ2V0QnVmZmVyKCksIGt2LmdldFZhbHVlT2Zmc2V0KCksCisgICAgICAgIGt2LmdldFZhbHVlTGVuZ3RoKCkpOworICAgICAgYXNzZXJ0RXF1YWxzKCJDb250ZW50IiwgY29sbmFtZVN0ciwgY29sdmFsdWVTdHIpOworICAgIH0KKyAgfQorCisgIC8qKiBUZXN0IGdldEZ1bGwgZnJvbSBtZW1jYWNoZQorICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEdldEZ1bGwoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIGFkZFJvd3ModGhpcy5obWVtY2FjaGUpOworICAgIFRocmVhZC5zbGVlcCgxKTsKKyAgICBhZGRSb3dzKHRoaXMuaG1lbWNhY2hlKTsKKyAgICBUaHJlYWQuc2xlZXAoMSk7CisgICAgYWRkUm93cyh0aGlzLmhtZW1jYWNoZSk7CisgICAgVGhyZWFkLnNsZWVwKDEpOworICAgIGFkZFJvd3ModGhpcy5obWVtY2FjaGUpOworICAgIGxvbmcgbm93ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgTWFwPEtleVZhbHVlLCBDb3VudGVyPiB2ZXJzaW9uQ291bnRlciA9CisgICAgICBuZXcgVHJlZU1hcDxLZXlWYWx1ZSwgQ291bnRlcj4odGhpcy5obWVtY2FjaGUuY29tcGFyYXRvcklnbm9yZVRpbWVzdGFtcCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBST1dfQ09VTlQ7IGkrKykgeworICAgICAgS2V5VmFsdWUga3YgPSBuZXcgS2V5VmFsdWUoZ2V0Um93TmFtZShpKSwgbm93KTsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IGFsbCA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMgPQorICAgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4oS2V5VmFsdWUuQ09NUEFSQVRPUik7CisgICAgICB0aGlzLmhtZW1jYWNoZS5nZXRGdWxsKGt2LCBudWxsLCBudWxsLCAxLCB2ZXJzaW9uQ291bnRlciwgZGVsZXRlcywgYWxsLAorICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICBpc0V4cGVjdGVkUm93V2l0aG91dFRpbWVzdGFtcHMoaSwgYWxsKTsKKyAgICB9CisgICAgLy8gVGVzdCBnZXR0aW5nIHR3byB2ZXJzaW9ucy4KKyAgICB2ZXJzaW9uQ291bnRlciA9CisgICAgICBuZXcgVHJlZU1hcDxLZXlWYWx1ZSwgQ291bnRlcj4odGhpcy5obWVtY2FjaGUuY29tcGFyYXRvcklnbm9yZVRpbWVzdGFtcCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBST1dfQ09VTlQ7IGkrKykgeworICAgICAgS2V5VmFsdWUga3YgPSBuZXcgS2V5VmFsdWUoZ2V0Um93TmFtZShpKSwgbm93KTsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IGFsbCA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBOYXZpZ2FibGVTZXQ8S2V5VmFsdWU+IGRlbGV0ZXMgPQorICAgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4oS2V5VmFsdWUuQ09NUEFSQVRPUik7CisgICAgICB0aGlzLmhtZW1jYWNoZS5nZXRGdWxsKGt2LCBudWxsLCBudWxsLCAyLCB2ZXJzaW9uQ291bnRlciwgZGVsZXRlcywgYWxsLAorICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICBieXRlIFtdIHByZXZpb3VzUm93ID0gbnVsbDsKKyAgICAgIGludCBjb3VudCA9IDA7CisgICAgICBmb3IgKEtleVZhbHVlIGs6IGFsbCkgeworICAgICAgICBpZiAocHJldmlvdXNSb3cgIT0gbnVsbCkgeworICAgICAgICAgIGFzc2VydFRydWUodGhpcy5obWVtY2FjaGUuY29tcGFyYXRvci5jb21wYXJlUm93cyhrLCBwcmV2aW91c1JvdykgPT0gMCk7CisgICAgICAgIH0KKyAgICAgICAgcHJldmlvdXNSb3cgPSBrLmdldFJvdygpOworICAgICAgICBjb3VudCsrOworICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKFJPV19DT1VOVCAqIDIsIGNvdW50KTsKKyAgICB9CisgIH0KKworICAvKiogVGVzdCBnZXROZXh0Um93IGZyb20gbWVtY2FjaGUKKyAgICogQHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RHZXROZXh0Um93KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBhZGRSb3dzKHRoaXMuaG1lbWNhY2hlKTsKKyAgICAvLyBBZGQgbW9yZSB2ZXJzaW9ucyB0byBtYWtlIGl0IGEgbGl0dGxlIG1vcmUgaW50ZXJlc3RpbmcuCisgICAgVGhyZWFkLnNsZWVwKDEpOworICAgIGFkZFJvd3ModGhpcy5obWVtY2FjaGUpOworICAgIEtleVZhbHVlIGNsb3Nlc3RUb0VtcHR5ID0gdGhpcy5obWVtY2FjaGUuZ2V0TmV4dFJvdyhLZXlWYWx1ZS5MT1dFU1RLRVkpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhjbG9zZXN0VG9FbXB0eSwKKyAgICAgIG5ldyBLZXlWYWx1ZShnZXRSb3dOYW1lKDApLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpID09IDApOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUk9XX0NPVU5UOyBpKyspIHsKKyAgICAgIEtleVZhbHVlIG5yID0gdGhpcy5obWVtY2FjaGUuZ2V0TmV4dFJvdyhuZXcgS2V5VmFsdWUoZ2V0Um93TmFtZShpKSwKKyAgICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpKTsKKyAgICAgIGlmIChpICsgMSA9PSBST1dfQ09VTlQpIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG5yLCBudWxsKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhuciwKKyAgICAgICAgICBuZXcgS2V5VmFsdWUoZ2V0Um93TmFtZShpICsgMSksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSkgPT0gMCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIFRlc3QgZ2V0Q2xvc2VzdCBmcm9tIG1lbWNhY2hlCisgICAqIEB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24gCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q2xvc2VzdCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgYWRkUm93cyh0aGlzLmhtZW1jYWNoZSk7CisgICAgLy8gQWRkIG1vcmUgdmVyc2lvbnMgdG8gbWFrZSBpdCBhIGxpdHRsZSBtb3JlIGludGVyZXN0aW5nLgorICAgIFRocmVhZC5zbGVlcCgxKTsKKyAgICBhZGRSb3dzKHRoaXMuaG1lbWNhY2hlKTsKKyAgICBLZXlWYWx1ZSBrdiA9IHRoaXMuaG1lbWNhY2hlLmdldE5leHRSb3coS2V5VmFsdWUuTE9XRVNUS0VZKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLkNPTVBBUkFUT1IuY29tcGFyZVJvd3MobmV3IEtleVZhbHVlKGdldFJvd05hbWUoMCksCisgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSksIGt2KSA9PSAwKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IFJPV19DT1VOVDsgaSsrKSB7CisgICAgICBLZXlWYWx1ZSBuciA9IHRoaXMuaG1lbWNhY2hlLmdldE5leHRSb3cobmV3IEtleVZhbHVlKGdldFJvd05hbWUoaSksCisgICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSk7CisgICAgICBpZiAoaSArIDEgPT0gUk9XX0NPVU5UKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhuciwgbnVsbCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBhc3NlcnRUcnVlKEtleVZhbHVlLkNPTVBBUkFUT1IuY29tcGFyZVJvd3MobnIsCisgICAgICAgICAgbmV3IEtleVZhbHVlKGdldFJvd05hbWUoaSArIDEpLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpID09IDApOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUZXN0IG1lbWNhY2hlIHNjYW5uZXIKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKiBAdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNjYW5uZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBhZGRSb3dzKHRoaXMuaG1lbWNhY2hlKTsKKyAgICBUaHJlYWQuc2xlZXAoMSk7CisgICAgYWRkUm93cyh0aGlzLmhtZW1jYWNoZSk7CisgICAgVGhyZWFkLnNsZWVwKDEpOworICAgIGFkZFJvd3ModGhpcy5obWVtY2FjaGUpOworICAgIGxvbmcgdGltZXN0YW1wID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgTmF2aWdhYmxlU2V0PGJ5dGUgW10+IGNvbHVtbnMgPSBuZXcgVHJlZVNldDxieXRlIFtdPihCeXRlcy5CWVRFU19DT01QQVJBVE9SKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IFJPV19DT1VOVDsgaSsrKSB7CisgICAgICBmb3IgKGludCBpaSA9IDA7IGlpIDwgQ09MVU1OU19DT1VOVDsgaWkrKykgeworICAgICAgICBjb2x1bW5zLmFkZChnZXRDb2x1bW5OYW1lKGksIGlpKSk7CisgICAgICB9CisgICAgfQorICAgIEludGVybmFsU2Nhbm5lciBzY2FubmVyID0KKyAgICAgIHRoaXMuaG1lbWNhY2hlLmdldFNjYW5uZXIodGltZXN0YW1wLCBjb2x1bW5zLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IHNjYW5uZXIubmV4dChyZXN1bHRzKTsgaSsrKSB7CisgICAgICBLZXlWYWx1ZS5DT01QQVJBVE9SLmNvbXBhcmVSb3dzKHJlc3VsdHMuZ2V0KDApLCBnZXRSb3dOYW1lKGkpKTsKKyAgICAgIGFzc2VydEVxdWFscygiQ291bnQgb2YgY29sdW1ucyIsIENPTFVNTlNfQ09VTlQsIHJlc3VsdHMuc2l6ZSgpKTsKKyAgICAgIGlzRXhwZWN0ZWRSb3dXaXRob3V0VGltZXN0YW1wcyhpLCByZXN1bHRzKTsKKyAgICAgIC8vIENsZWFyIG91dCBzZXQuICBPdGhlcndpc2Ugcm93IHJlc3VsdHMgYWNjdW11bGF0ZS4KKyAgICAgIHJlc3VsdHMuY2xlYXIoKTsKKyAgICB9CisgIH0KKworICAvKiogRm9yIEhCQVNFLTUyOCAqLworICBwdWJsaWMgdm9pZCB0ZXN0R2V0Um93S2V5QXRPckJlZm9yZSgpIHsKKyAgICAvLyBzZXQgdXAgc29tZSB0ZXN0IGRhdGEKKyAgICBieXRlIFtdIHQxMCA9IEJ5dGVzLnRvQnl0ZXMoIjAxMCIpOworICAgIGJ5dGUgW10gdDIwID0gQnl0ZXMudG9CeXRlcygiMDIwIik7CisgICAgYnl0ZSBbXSB0MzAgPSBCeXRlcy50b0J5dGVzKCIwMzAiKTsKKyAgICBieXRlIFtdIHQzNSA9IEJ5dGVzLnRvQnl0ZXMoIjAzNSIpOworICAgIGJ5dGUgW10gdDQwID0gQnl0ZXMudG9CeXRlcygiMDQwIik7CisgICAgCisgICAgaG1lbWNhY2hlLmFkZChnZXRLVih0MTAsICJ0MTAgYnl0ZXMiLmdldEJ5dGVzKCkpKTsKKyAgICBobWVtY2FjaGUuYWRkKGdldEtWKHQyMCwgInQyMCBieXRlcyIuZ2V0Qnl0ZXMoKSkpOworICAgIGhtZW1jYWNoZS5hZGQoZ2V0S1YodDMwLCAidDMwIGJ5dGVzIi5nZXRCeXRlcygpKSk7CisgICAgaG1lbWNhY2hlLmFkZChnZXRLVih0MzUsICJ0MzUgYnl0ZXMiLmdldEJ5dGVzKCkpKTsKKyAgICAvLyB3cml0ZSBhIGRlbGV0ZSBpbiB0aGVyZSB0byBzZWUgaWYgdGhpbmdzIHN0aWxsIHdvcmsgb2sKKyAgICBobWVtY2FjaGUuYWRkKGdldERlbGV0ZUtWKHQzNSkpOworICAgIGhtZW1jYWNoZS5hZGQoZ2V0S1YodDQwLCAidDQwIGJ5dGVzIi5nZXRCeXRlcygpKSk7CisgICAgCisgICAgTmF2aWdhYmxlU2V0PEtleVZhbHVlPiByZXN1bHRzID0gbnVsbDsKKyAgICAKKyAgICAvLyB0cnkgZmluZGluZyAiMDE1IgorICAgIHJlc3VsdHMgPQorICAgICAgbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KHRoaXMuaG1lbWNhY2hlLmNvbXBhcmF0b3IuZ2V0Q29tcGFyYXRvcklnbm9yaW5nVHlwZSgpKTsKKyAgICBLZXlWYWx1ZSB0MTUgPSBuZXcgS2V5VmFsdWUoQnl0ZXMudG9CeXRlcygiMDE1IiksCisgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgaG1lbWNhY2hlLmdldFJvd0tleUF0T3JCZWZvcmUodDE1LCByZXN1bHRzKTsKKyAgICBLZXlWYWx1ZSBrdiA9IHJlc3VsdHMubGFzdCgpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhrdiwgdDEwKSA9PSAwKTsKKworICAgIC8vIHRyeSAiMDIwIiwgd2Ugc2hvdWxkIGdldCB0aGF0IHJvdyBleGFjdGx5CisgICAgcmVzdWx0cyA9CisgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4odGhpcy5obWVtY2FjaGUuY29tcGFyYXRvci5nZXRDb21wYXJhdG9ySWdub3JpbmdUeXBlKCkpOworICAgIGhtZW1jYWNoZS5nZXRSb3dLZXlBdE9yQmVmb3JlKG5ldyBLZXlWYWx1ZSh0MjAsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSwKKyAgICAgIHJlc3VsdHMpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhyZXN1bHRzLmxhc3QoKSwgdDIwKSA9PSAwKTsKKworICAgIC8vIHRyeSAiMDMwIiwgd2Ugc2hvdWxkIGdldCB0aGF0IHJvdyBleGFjdGx5CisgICAgcmVzdWx0cyA9CisgICAgICBuZXcgVHJlZVNldDxLZXlWYWx1ZT4odGhpcy5obWVtY2FjaGUuY29tcGFyYXRvci5nZXRDb21wYXJhdG9ySWdub3JpbmdUeXBlKCkpOworICAgIGhtZW1jYWNoZS5nZXRSb3dLZXlBdE9yQmVmb3JlKG5ldyBLZXlWYWx1ZSh0MzAsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSwKKyAgICAgIHJlc3VsdHMpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhyZXN1bHRzLmxhc3QoKSwgdDMwKSA9PSAwKTsKKyAgCisgICAgLy8gdHJ5ICIwMzgiLCBzaG91bGQgc2tpcCB0aGUgZGVsZXRlZCAiMDM1IiBhbmQgZ2l2ZSAiMDMwIgorICAgIHJlc3VsdHMgPQorICAgICAgbmV3IFRyZWVTZXQ8S2V5VmFsdWU+KHRoaXMuaG1lbWNhY2hlLmNvbXBhcmF0b3IuZ2V0Q29tcGFyYXRvcklnbm9yaW5nVHlwZSgpKTsKKyAgICBieXRlIFtdIHQzOCA9IEJ5dGVzLnRvQnl0ZXMoIjAzOCIpOworICAgIGhtZW1jYWNoZS5nZXRSb3dLZXlBdE9yQmVmb3JlKG5ldyBLZXlWYWx1ZSh0MzgsIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKSwKKyAgICAgIHJlc3VsdHMpOworICAgIGFzc2VydFRydWUoS2V5VmFsdWUuQ09NUEFSQVRPUi5jb21wYXJlUm93cyhyZXN1bHRzLmxhc3QoKSwgdDMwKSA9PSAwKTsKKyAgCisgICAgLy8gdHJ5ICIwNTAiLCBzaG91bGQgZ2V0IHN0dWZmIGZyb20gIjA0MCIKKyAgICByZXN1bHRzID0KKyAgICAgIG5ldyBUcmVlU2V0PEtleVZhbHVlPih0aGlzLmhtZW1jYWNoZS5jb21wYXJhdG9yLmdldENvbXBhcmF0b3JJZ25vcmluZ1R5cGUoKSk7CisgICAgYnl0ZSBbXSB0NTAgPSBCeXRlcy50b0J5dGVzKCIwNTAiKTsKKyAgICBobWVtY2FjaGUuZ2V0Um93S2V5QXRPckJlZm9yZShuZXcgS2V5VmFsdWUodDUwLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSksCisgICAgICByZXN1bHRzKTsKKyAgICBhc3NlcnRUcnVlKEtleVZhbHVlLkNPTVBBUkFUT1IuY29tcGFyZVJvd3MocmVzdWx0cy5sYXN0KCksIHQ0MCkgPT0gMCk7CisgIH0KKworICBwcml2YXRlIEtleVZhbHVlIGdldERlbGV0ZUtWKGJ5dGUgW10gcm93KSB7CisgICAgcmV0dXJuIG5ldyBLZXlWYWx1ZShyb3csIEJ5dGVzLnRvQnl0ZXMoInRlc3RfY29sOiIpLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCBLZXlWYWx1ZS5UeXBlLkRlbGV0ZSwgbnVsbCk7CisgIH0KKworICBwcml2YXRlIEtleVZhbHVlIGdldEtWKGJ5dGUgW10gcm93LCBieXRlIFtdIHZhbHVlKSB7CisgICAgcmV0dXJuIG5ldyBLZXlWYWx1ZShyb3csIEJ5dGVzLnRvQnl0ZXMoInRlc3RfY29sOiIpLAorICAgICAgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLCB2YWx1ZSk7CisgIH0KKworICAvKioKKyAgICogVGVzdCBtZW1jYWNoZSBzY2FubmVyIHNjYW5uaW5nIGNhY2hlZCByb3dzLCBIQkFTRS02ODYKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFNjYW5uZXJfNjg2KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhZGRSb3dzKHRoaXMuaG1lbWNhY2hlKTsKKyAgICBsb25nIHRpbWVzdGFtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIE5hdmlnYWJsZVNldDxieXRlIFtdPiBjb2xzID0gbmV3IFRyZWVTZXQ8Ynl0ZSBbXT4oQnl0ZXMuQllURVNfQ09NUEFSQVRPUik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBST1dfQ09VTlQ7IGkrKykgeworICAgICAgZm9yIChpbnQgaWkgPSAwOyBpaSA8IENPTFVNTlNfQ09VTlQ7IGlpKyspIHsKKyAgICAgICAgY29scy5hZGQoZ2V0Q29sdW1uTmFtZShpLCBpaSkpOworICAgICAgfQorICAgIH0KKyAgICAvL3N0YXJ0aW5nIGZyb20gZWFjaCByb3csIHZhbGlkYXRlIHJlc3VsdHMgc2hvdWxkIGNvbnRhaW4gdGhlIHN0YXJ0aW5nIHJvdworICAgIGZvciAoaW50IHN0YXJ0Um93SWQgPSAwOyBzdGFydFJvd0lkIDwgUk9XX0NPVU5UOyBzdGFydFJvd0lkKyspIHsKKyAgICAgIEludGVybmFsU2Nhbm5lciBzY2FubmVyID0gdGhpcy5obWVtY2FjaGUuZ2V0U2Nhbm5lcih0aW1lc3RhbXAsCisgICAgICAgICAgY29scywgZ2V0Um93TmFtZShzdGFydFJvd0lkKSk7CisgICAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBzY2FubmVyLm5leHQocmVzdWx0cyk7IGkrKykgeworICAgICAgICBpbnQgcm93SWQgPSBzdGFydFJvd0lkICsgaTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiUm93IG5hbWUiLAorICAgICAgICAgIEtleVZhbHVlLkNPTVBBUkFUT1IuY29tcGFyZVJvd3MocmVzdWx0cy5nZXQoMCksCisgICAgICAgICAgZ2V0Um93TmFtZShyb3dJZCkpID09IDApOworICAgICAgICBhc3NlcnRFcXVhbHMoIkNvdW50IG9mIGNvbHVtbnMiLCBDT0xVTU5TX0NPVU5ULCByZXN1bHRzLnNpemUoKSk7CisgICAgICAgIExpc3Q8S2V5VmFsdWU+IHJvdyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAgIGZvciAoS2V5VmFsdWUga3YgOiByZXN1bHRzKSB7CisgICAgICAgICAgcm93LmFkZChrdik7CisgICAgICAgIH0KKyAgICAgICAgaXNFeHBlY3RlZFJvd1dpdGhvdXRUaW1lc3RhbXBzKHJvd0lkLCByb3cpOworICAgICAgICAvLyBDbGVhciBvdXQgc2V0LiAgT3RoZXJ3aXNlIHJvdyByZXN1bHRzIGFjY3VtdWxhdGUuCisgICAgICAgIHJlc3VsdHMuY2xlYXIoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhSZWdpb24uamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0SFJlZ2lvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzMjYwZTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhSZWdpb24uamF2YQpAQCAtMCwwICsxLDY1NSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5LZXlWYWx1ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKKy8qKgorICogQmFzaWMgc3RhbmQtYWxvbmUgdGVzdGluZyBvZiBIUmVnaW9uLgorICogCisgKiBBIGxvdCBvZiB0aGUgbWV0YSBpbmZvcm1hdGlvbiBmb3IgYW4gSFJlZ2lvbiBub3cgbGl2ZXMgaW5zaWRlIG90aGVyCisgKiBIUmVnaW9ucyBvciBpbiB0aGUgSEJhc2VNYXN0ZXIsIHNvIG9ubHkgYmFzaWMgdGVzdGluZyBpcyBwb3NzaWJsZS4KKyAqLworcHVibGljIGNsYXNzIFRlc3RIUmVnaW9uIGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisgIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coVGVzdEhSZWdpb24uY2xhc3MpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSVJTVF9ST1cgPSAxOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTlVNX1ZBTFMgPSAxMDAwOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVOVFNfQkFTSUNfU1RSID0gImNvbnRlbnRzOmJhc2ljIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT05URU5UU19CQVNJQyA9IEJ5dGVzLnRvQnl0ZXMoQ09OVEVOVFNfQkFTSUNfU1RSKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFTlRTVFIgPSAiY29udGVudHN0ciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTkNIT1JOVU0gPSAiYW5jaG9yOmFuY2hvcm51bS0iOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5DSE9SU1RSID0gImFuY2hvcnN0ciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gQ09OVEVOVFNfRklSU1RDT0wgPSBCeXRlcy50b0J5dGVzKCJjb250ZW50czpmaXJzdGNvbCIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIEFOQ0hPUl9TRUNPTkRDT0wgPSBCeXRlcy50b0J5dGVzKCJhbmNob3I6c2Vjb25kY29sIik7CisgIAorICBwcml2YXRlIE1pbmlERlNDbHVzdGVyIGNsdXN0ZXIgPSBudWxsOworICBwcml2YXRlIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG51bGw7CisgIEhSZWdpb24gciA9IG51bGw7CisgIEhSZWdpb25JbmNvbW1vbiByZWdpb24gPSBudWxsOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IG51bUluc2VydGVkID0gMDsKKworICAvKioKKyAgICogQHNlZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlI3NldFVwKCkKKyAgICovCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHRoaXMuY29uZi5zZXQoImhiYXNlLmhzdG9yZS5jb21wYWN0aW9uVGhyZXNob2xkIiwgIjIiKTsKKworICAgIGNvbmYuc2V0TG9uZygiaGJhc2UuaHJlZ2lvbi5tYXguZmlsZXNpemUiLCA2NTUzNik7CisKKyAgICBjbHVzdGVyID0gbmV3IE1pbmlERlNDbHVzdGVyKGNvbmYsIDIsIHRydWUsIChTdHJpbmdbXSludWxsKTsKKyAgICBmcyA9IGNsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpOworICAgIAorICAgIC8vIFNldCB0aGUgaGJhc2Uucm9vdGRpciB0byBiZSB0aGUgaG9tZSBkaXJlY3RvcnkgaW4gbWluaSBkZnMuCisgICAgdGhpcy5jb25mLnNldChIQ29uc3RhbnRzLkhCQVNFX0RJUiwKKyAgICAgIHRoaXMuY2x1c3Rlci5nZXRGaWxlU3lzdGVtKCkuZ2V0SG9tZURpcmVjdG9yeSgpLnRvU3RyaW5nKCkpOworICAgIAorICAgIHN1cGVyLnNldFVwKCk7CisgIH0KKworICAvKioKKyAgICogU2luY2UgYWxsIHRoZSAidGVzdHMiIGRlcGVuZCBvbiB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgdGVzdCwgdGhleSBhcmUKKyAgICogbm90IEp1bml0IHRlc3RzIHRoYXQgY2FuIHN0YW5kIGFsb25lLiBDb25zZXF1ZW50bHkgd2UgaGF2ZSBhIHNpbmdsZSBKdW5pdAorICAgKiB0ZXN0IHRoYXQgcnVucyB0aGUgInN1Yi10ZXN0cyIgYXMgcHJpdmF0ZSBtZXRob2RzLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEhSZWdpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBpbml0KCk7CisgICAgICBsb2NrcygpOworICAgICAgYmFkUHV0cygpOworICAgICAgYmFzaWMoKTsKKyAgICAgIHNjYW4oKTsKKyAgICAgIHNwbGl0QW5kTWVyZ2UoKTsKKyAgICAgIHJlYWQoKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgc2h1dGRvd25EZnMoY2x1c3Rlcik7CisgICAgfQorICB9CisKKyAgLy8gQ3JlYXRlIGRpcmVjdG9yaWVzLCBzdGFydCBtaW5pIGNsdXN0ZXIsIGV0Yy4KKyAgCisgIHByaXZhdGUgdm9pZCBpbml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoInRlc3QiKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoImNvbnRlbnRzOiIpKTsKKyAgICBkZXNjLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoImFuY2hvcjoiKSk7CisgICAgciA9IGNyZWF0ZU5ld0hSZWdpb24oZGVzYywgbnVsbCwgbnVsbCk7CisgICAgcmVnaW9uID0gbmV3IEhSZWdpb25JbmNvbW1vbihyKTsKKyAgICBMT0cuaW5mbygic2V0dXAgY29tcGxldGVkLiIpOworICB9CisKKyAgLy8gVGVzdCBiYXNpYyBmdW5jdGlvbmFsaXR5LiBXcml0ZXMgdG8gY29udGVudHM6YmFzaWMgYW5kIGFuY2hvcjphbmNob3JudW0tKgorCisgIHByaXZhdGUgdm9pZCBiYXNpYygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgIC8vIFdyaXRlIG91dCBhIGJ1bmNoIG9mIHZhbHVlcworICAgIGZvciAoaW50IGsgPSBGSVJTVF9ST1c7IGsgPD0gTlVNX1ZBTFM7IGsrKykgeworICAgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPSAKKyAgICAgICAgbmV3IEJhdGNoVXBkYXRlKEJ5dGVzLnRvQnl0ZXMoInJvd18iICsgayksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChDT05URU5UU19CQVNJQywKKyAgICAgICAgICAoQ09OVEVOVFNUUiArIGspLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgICAgYmF0Y2hVcGRhdGUucHV0KEJ5dGVzLnRvQnl0ZXMoQU5DSE9STlVNICsgayksCisgICAgICAgICAgKEFOQ0hPUlNUUiArIGspLmdldEJ5dGVzKEhDb25zdGFudHMuVVRGOF9FTkNPRElORykpOworICAgICAgcmVnaW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgfQorICAgIExPRy5pbmZvKCJXcml0ZSAiICsgTlVNX1ZBTFMgKyAiIHJvd3MuIEVsYXBzZWQgdGltZTogIgorICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisKKyAgICAvLyBGbHVzaCBjYWNoZQorCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICByZWdpb24uZmx1c2hjYWNoZSgpOworCisgICAgTE9HLmluZm8oIkNhY2hlIGZsdXNoIGVsYXBzZWQgdGltZTogIgorICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisKKyAgICAvLyBSZWFkIHRoZW0gYmFjayBpbgorCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICBieXRlIFtdIGNvbGxhYmVsID0gbnVsbDsKKyAgICBmb3IgKGludCBrID0gRklSU1RfUk9XOyBrIDw9IE5VTV9WQUxTOyBrKyspIHsKKyAgICAgIFN0cmluZyByb3dsYWJlbFN0ciA9ICJyb3dfIiArIGs7CisgICAgICBieXRlIFtdIHJvd2xhYmVsID0gQnl0ZXMudG9CeXRlcyhyb3dsYWJlbFN0cik7CisgICAgICBpZiAoayAlIDEwMCA9PSAwKSBMT0cuaW5mbyhCeXRlcy50b1N0cmluZyhyb3dsYWJlbCkpOworICAgICAgQ2VsbCBjID0gcmVnaW9uLmdldChyb3dsYWJlbCwgQ09OVEVOVFNfQkFTSUMpOworICAgICAgYXNzZXJ0Tm90TnVsbCgiSyBpcyAiICsgaywgYyk7CisgICAgICBieXRlIFtdIGJvZHlkYXRhID0gYy5nZXRWYWx1ZSgpOworICAgICAgYXNzZXJ0Tm90TnVsbChib2R5ZGF0YSk7CisgICAgICBTdHJpbmcgYm9keXN0ciA9IG5ldyBTdHJpbmcoYm9keWRhdGEsIEhDb25zdGFudHMuVVRGOF9FTkNPRElORykudHJpbSgpOworICAgICAgU3RyaW5nIHRlc3RzdHIgPSBDT05URU5UU1RSICsgazsKKyAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIGZvciBrZXk6ICgiICsgcm93bGFiZWxTdHIgKyAiLCIgKyBDT05URU5UU19CQVNJQ19TVFIKKyAgICAgICAgICArICIpLCBleHBlY3RlZDogJyIgKyB0ZXN0c3RyICsgIicgZ290OiAnIiArIGJvZHlzdHIgKyAiJyIsCisgICAgICAgICAgYm9keXN0ciwgdGVzdHN0cik7CisgICAgICBTdHJpbmcgY29sbGFiZWxTdHIgPSBBTkNIT1JOVU0gKyBrOworICAgICAgY29sbGFiZWwgPSBCeXRlcy50b0J5dGVzKGNvbGxhYmVsU3RyKTsKKyAgICAgIGJvZHlkYXRhID0gcmVnaW9uLmdldChyb3dsYWJlbCwgY29sbGFiZWwpLmdldFZhbHVlKCk7CisgICAgICBib2R5c3RyID0gbmV3IFN0cmluZyhib2R5ZGF0YSwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKS50cmltKCk7CisgICAgICB0ZXN0c3RyID0gQU5DSE9SU1RSICsgazsKKyAgICAgIGFzc2VydEVxdWFscygiSW5jb3JyZWN0IHZhbHVlIGZvciBrZXk6ICgiICsgcm93bGFiZWxTdHIgKyAiLCIgKyBjb2xsYWJlbFN0cgorICAgICAgICAgICsgIiksIGV4cGVjdGVkOiAnIiArIHRlc3RzdHIgKyAiJyBnb3Q6ICciICsgYm9keXN0ciArICInIiwKKyAgICAgICAgICBib2R5c3RyLCB0ZXN0c3RyKTsKKyAgICB9CisKKyAgICBMT0cuaW5mbygiUmVhZCAiICsgTlVNX1ZBTFMgKyAiIHJvd3MuIEVsYXBzZWQgdGltZTogIgorICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisKKyAgICBMT0cuaW5mbygiYmFzaWMgY29tcGxldGVkLiIpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgYmFkUHV0cygpIHsKKyAgICAvLyBUcnkgY29sdW1uIG5hbWUgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIHRhYmxlLiAgICAKKyAgICBib29sZWFuIGV4Y2VwdGlvblRocm93biA9IGZhbHNlOworICAgIGV4Y2VwdGlvblRocm93biA9IGZhbHNlOworICAgIHRyeSB7CisgICAgICBCYXRjaFVwZGF0ZSBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShCeXRlcy50b0J5dGVzKCJTb21lIG9sZCBrZXkiKSk7CisgICAgICBTdHJpbmcgdW5yZWdpc3RlcmVkQ29sTmFtZSA9ICJGYW1pbHlHcm91cDpGYW1pbHlMYWJlbCI7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoQnl0ZXMudG9CeXRlcyh1bnJlZ2lzdGVyZWRDb2xOYW1lKSwKKyAgICAgICAgdW5yZWdpc3RlcmVkQ29sTmFtZS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIHJlZ2lvbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGV4Y2VwdGlvblRocm93biA9IHRydWU7CisgICAgfSBmaW5hbGx5IHsKKyAgICB9CisgICAgYXNzZXJ0VHJ1ZSgiQmFkIGZhbWlseSIsIGV4Y2VwdGlvblRocm93bik7CisgICAgTE9HLmluZm8oImJhZFB1dHMgY29tcGxldGVkLiIpOworICB9CisgIAorICAvKioKKyAgICogVGVzdCBnZXR0aW5nIGFuZCByZWxlYXNpbmcgbG9ja3MuCisgICAqLworICBwcml2YXRlIHZvaWQgbG9ja3MoKSB7CisgICAgZmluYWwgaW50IHRocmVhZENvdW50ID0gMTA7CisgICAgZmluYWwgaW50IGxvY2tDb3VudCA9IDEwOworICAgIAorICAgIExpc3Q8VGhyZWFkPnRocmVhZHMgPSBuZXcgQXJyYXlMaXN0PFRocmVhZD4odGhyZWFkQ291bnQpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhyZWFkQ291bnQ7IGkrKykgeworICAgICAgdGhyZWFkcy5hZGQobmV3IFRocmVhZChJbnRlZ2VyLnRvU3RyaW5nKGkpKSB7CisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgSW50ZWdlciBbXSBsb2NraWRzID0gbmV3IEludGVnZXJbbG9ja0NvdW50XTsKKyAgICAgICAgICAvLyBHZXQgbG9ja3MuCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb2NrQ291bnQ7IGkrKykgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgYnl0ZSBbXSByb3dpZCA9IEJ5dGVzLnRvQnl0ZXMoSW50ZWdlci50b1N0cmluZyhpKSk7CisgICAgICAgICAgICAgIGxvY2tpZHNbaV0gPSByLm9idGFpblJvd0xvY2socm93aWQpOworICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMocm93aWQsIHIuZ2V0Um93RnJvbUxvY2sobG9ja2lkc1tpXSkpOworICAgICAgICAgICAgICBMT0cuZGVidWcoZ2V0TmFtZSgpICsgIiBsb2NrZWQgIiArIEJ5dGVzLnRvU3RyaW5nKHJvd2lkKSk7CisgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiIHNldCAiICsKKyAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhsb2NrQ291bnQpICsgIiBsb2NrcyIpOworICAgICAgICAgIAorICAgICAgICAgIC8vIEFib3J0IG91dHN0YW5kaW5nIGxvY2tzLgorICAgICAgICAgIGZvciAoaW50IGkgPSBsb2NrQ291bnQgLSAxOyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgci5yZWxlYXNlUm93TG9jayhsb2NraWRzW2ldKTsKKyAgICAgICAgICAgIExPRy5kZWJ1ZyhnZXROYW1lKCkgKyAiIHVubG9ja2VkICIgKyBpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgTE9HLmRlYnVnKGdldE5hbWUoKSArICIgcmVsZWFzZWQgIiArCisgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobG9ja0NvdW50KSArICIgbG9ja3MiKTsKKyAgICAgICAgfQorICAgICAgfSk7CisgICAgfQorICAgIAorICAgIC8vIFN0YXJ0dXAgYWxsIG91ciB0aHJlYWRzLgorICAgIGZvciAoVGhyZWFkIHQgOiB0aHJlYWRzKSB7CisgICAgICB0LnN0YXJ0KCk7CisgICAgfQorICAgIAorICAgIC8vIE5vdyB3YWl0IGFyb3VuZCB0aWxsIGFsbCBhcmUgZG9uZS4KKyAgICBmb3IgKFRocmVhZCB0OiB0aHJlYWRzKSB7CisgICAgICB3aGlsZSAodC5pc0FsaXZlKCkpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAoMSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAvLyBHbyBhcm91bmQgYWdhaW4uCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgTE9HLmluZm8oImxvY2tzIGNvbXBsZXRlZC4iKTsKKyAgfQorCisgIC8vIFRlc3Qgc2Nhbm5lcnMuIFdyaXRlcyBjb250ZW50czpmaXJzdGNvbCBhbmQgYW5jaG9yOnNlY29uZGNvbAorICAKKyAgcHJpdmF0ZSB2b2lkIHNjYW4oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW10gY29scyBbXSA9IHsKKyAgICAgICAgQ09OVEVOVFNfRklSU1RDT0wsCisgICAgICAgIEFOQ0hPUl9TRUNPTkRDT0wKKyAgICB9OworCisgICAgLy8gVGVzdCB0aGUgU2Nhbm5lciEhIQorICAgIFN0cmluZ1tdIHZhbHMxID0gbmV3IFN0cmluZ1sxMDAwXTsKKyAgICBmb3IoaW50IGsgPSAwOyBrIDwgdmFsczEubGVuZ3RoOyBrKyspIHsKKyAgICAgIHZhbHMxW2tdID0gSW50ZWdlci50b1N0cmluZyhrKTsKKyAgICB9CisKKyAgICAvLyAxLiAgSW5zZXJ0IGEgYnVuY2ggb2YgdmFsdWVzCisgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBmb3IoaW50IGsgPSAwOyBrIDwgdmFsczEubGVuZ3RoIC8gMjsgaysrKSB7CisgICAgICBTdHJpbmcga0xhYmVsID0gU3RyaW5nLmZvcm1hdCgiJTEkMDNkIiwgayk7CisKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gCisgICAgICAgIG5ldyBCYXRjaFVwZGF0ZShCeXRlcy50b0J5dGVzKCJyb3dfdmFsczFfIiArIGtMYWJlbCksIAorICAgICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xzWzBdLCB2YWxzMVtrXS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xzWzFdLCB2YWxzMVtrXS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIHJlZ2lvbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgICAgbnVtSW5zZXJ0ZWQgKz0gMjsKKyAgICB9CisgICAgTE9HLmluZm8oIldyaXRlICIgKyAodmFsczEubGVuZ3RoIC8gMikgKyAiIGVsYXBzZWQgdGltZTogIgorICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisKKyAgICAvLyAyLiAgU2NhbiBmcm9tIGNhY2hlCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgU2Nhbm5lckluY29tbW9uIHMgPSB0aGlzLnJlZ2lvbi5nZXRTY2FubmVyKGNvbHMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIGludCBudW1GZXRjaGVkID0gMDsKKyAgICB0cnkgeworICAgICAgTGlzdDxLZXlWYWx1ZT4gY3VyVmFscyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBpbnQgayA9IDA7CisgICAgICB3aGlsZShzLm5leHQoY3VyVmFscykpIHsKKyAgICAgICAgZm9yIChLZXlWYWx1ZSBrdjogY3VyVmFscykgeworICAgICAgICAgIGJ5dGUgW10gdmFsID0ga3YuZ2V0VmFsdWUoKTsKKyAgICAgICAgICBpbnQgY3VydmFsID0KKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQobmV3IFN0cmluZyh2YWwsIEhDb25zdGFudHMuVVRGOF9FTkNPRElORykudHJpbSgpKTsKKyAgICAgICAgICBmb3IoaW50IGogPSAwOyBqIDwgY29scy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgaWYgKCFrdi5tYXRjaGluZ0NvbHVtbihjb2xzW2pdKSkgeworICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkVycm9yIGF0OiAiICsga3YgICsgIiAiICsgQnl0ZXMudG9TdHJpbmcoY29sc1tqXSksCisgICAgICAgICAgICAgICAgaywgY3VydmFsKTsKKyAgICAgICAgICAgICAgbnVtRmV0Y2hlZCsrOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY3VyVmFscy5jbGVhcigpOworICAgICAgICBrKys7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKG51bUluc2VydGVkLCBudW1GZXRjaGVkKTsKKworICAgIExPRy5pbmZvKCJTY2FubmVkICIgKyAodmFsczEubGVuZ3RoIC8gMikKKyAgICAgICAgKyAiIHJvd3MgZnJvbSBjYWNoZS4gRWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKworICAgIC8vIDMuICBGbHVzaCB0byBkaXNrCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICBMT0cuaW5mbygiQ2FjaGUgZmx1c2ggZWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKworICAgIC8vIDQuICBTY2FuIGZyb20gZGlzaworICAgIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIHMgPSB0aGlzLnJlZ2lvbi5nZXRTY2FubmVyKGNvbHMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIG51bUZldGNoZWQgPSAwOworICAgIHRyeSB7CisgICAgICBMaXN0PEtleVZhbHVlPiBjdXJWYWxzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGludCBrID0gMDsKKyAgICAgIHdoaWxlKHMubmV4dChjdXJWYWxzKSkgeworICAgICAgICBmb3IoSXRlcmF0b3I8S2V5VmFsdWU+IGl0ID0gY3VyVmFscy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7ICkgeworICAgICAgICAgIEtleVZhbHVlIGt2ID0gaXQubmV4dCgpOworICAgICAgICAgIGJ5dGUgW10gY29sID0ga3YuZ2V0Q29sdW1uKCk7CisgICAgICAgICAgYnl0ZSBbXSB2YWwgPSBrdi5nZXRWYWx1ZSgpOworICAgICAgICAgIGludCBjdXJ2YWwgPQorICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludChuZXcgU3RyaW5nKHZhbCwgSENvbnN0YW50cy5VVEY4X0VOQ09ESU5HKS50cmltKCkpOworICAgICAgICAgIGZvcihpbnQgaiA9IDA7IGogPCBjb2xzLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgICBpZiAoQnl0ZXMuY29tcGFyZVRvKGNvbCwgY29sc1tqXSkgPT0gMCkgeworICAgICAgICAgICAgICBhc3NlcnRFcXVhbHMoIkVycm9yIGF0OiIgKyBrdi5nZXRSb3coKSArICIvIgorICAgICAgICAgICAgICAgICAgKyBrdi5nZXRUaW1lc3RhbXAoKQorICAgICAgICAgICAgICAgICAgKyAiLCBWYWx1ZSBmb3IgIiArIGNvbCArICIgc2hvdWxkIGJlOiAiICsgaworICAgICAgICAgICAgICAgICAgKyAiLCBidXQgd2FzIGZldGNoZWQgYXM6ICIgKyBjdXJ2YWwsIGssIGN1cnZhbCk7CisgICAgICAgICAgICAgIG51bUZldGNoZWQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgY3VyVmFscy5jbGVhcigpOworICAgICAgICBrKys7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKCJJbnNlcnRlZCAiICsgbnVtSW5zZXJ0ZWQgKyAiIHZhbHVlcywgYnV0IGZldGNoZWQgIiArIG51bUZldGNoZWQsIG51bUluc2VydGVkLCBudW1GZXRjaGVkKTsKKworICAgIExPRy5pbmZvKCJTY2FubmVkICIgKyAodmFsczEubGVuZ3RoIC8gMikKKyAgICAgICAgKyAiIHJvd3MgZnJvbSBkaXNrLiBFbGFwc2VkIHRpbWU6ICIKKyAgICAgICAgKyAoKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lKSAvIDEwMDAuMCkpOworCisgICAgLy8gNS4gIEluc2VydCBtb3JlIHZhbHVlcworICAgIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGZvcihpbnQgayA9IHZhbHMxLmxlbmd0aC8yOyBrIDwgdmFsczEubGVuZ3RoOyBrKyspIHsKKyAgICAgIFN0cmluZyBrTGFiZWwgPSBTdHJpbmcuZm9ybWF0KCIlMSQwM2QiLCBrKTsKKyAgICAgIEJhdGNoVXBkYXRlIGJhdGNoVXBkYXRlID0gCisgICAgICAgIG5ldyBCYXRjaFVwZGF0ZShCeXRlcy50b0J5dGVzKCJyb3dfdmFsczFfIiArIGtMYWJlbCksIAorICAgICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xzWzBdLCB2YWxzMVtrXS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChjb2xzWzFdLCB2YWxzMVtrXS5nZXRCeXRlcyhIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpKTsKKyAgICAgIHJlZ2lvbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgICAgbnVtSW5zZXJ0ZWQgKz0gMjsKKyAgICB9CisKKyAgICBMT0cuaW5mbygiV3JpdGUgIiArICh2YWxzMS5sZW5ndGggLyAyKSArICIgcm93cyAoc2Vjb25kIGhhbGYpLiBFbGFwc2VkIHRpbWU6ICIKKyAgICAgICAgKyAoKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lKSAvIDEwMDAuMCkpOworCisgICAgLy8gNi4gIFNjYW4gZnJvbSBjYWNoZSBhbmQgZGlzaworICAgIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIHMgPSB0aGlzLnJlZ2lvbi5nZXRTY2FubmVyKGNvbHMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgbnVtRmV0Y2hlZCA9IDA7CisgICAgdHJ5IHsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IGN1clZhbHMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgaW50IGsgPSAwOworICAgICAgd2hpbGUocy5uZXh0KGN1clZhbHMpKSB7CisgICAgICAgIGZvcihJdGVyYXRvcjxLZXlWYWx1ZT4gaXQgPSBjdXJWYWxzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CisgICAgICAgICAgS2V5VmFsdWUga3YgPSBpdC5uZXh0KCk7CisgICAgICAgICAgYnl0ZSBbXSBjb2wgPSBrdi5nZXRDb2x1bW4oKTsKKyAgICAgICAgICBieXRlIFtdIHZhbCA9IGt2LmdldFZhbHVlKCk7CisgICAgICAgICAgaW50IGN1cnZhbCA9CisgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KG5ldyBTdHJpbmcodmFsLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpLnRyaW0oKSk7CisgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IGNvbHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIGlmKEJ5dGVzLmNvbXBhcmVUbyhjb2wsIGNvbHNbal0pID09IDApIHsKKyAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCJFcnJvciBhdDoiICsga3YuZ2V0Um93KCkgKyAiLyIKKyAgICAgICAgICAgICAgICAgICsga3YuZ2V0VGltZXN0YW1wKCkKKyAgICAgICAgICAgICAgICAgICsgIiwgVmFsdWUgZm9yICIgKyBjb2wgKyAiIHNob3VsZCBiZTogIiArIGsKKyAgICAgICAgICAgICAgICAgICsgIiwgYnV0IHdhcyBmZXRjaGVkIGFzOiAiICsgY3VydmFsLCBrLCBjdXJ2YWwpOworICAgICAgICAgICAgICBudW1GZXRjaGVkKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGN1clZhbHMuY2xlYXIoKTsKKyAgICAgICAgaysrOworICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICAgIGFzc2VydEVxdWFscygiSW5zZXJ0ZWQgIiArIG51bUluc2VydGVkICsgIiB2YWx1ZXMsIGJ1dCBmZXRjaGVkICIgKworICAgICAgbnVtRmV0Y2hlZCwgbnVtSW5zZXJ0ZWQsIG51bUZldGNoZWQpOworCisgICAgTE9HLmluZm8oIlNjYW5uZWQgIiArIHZhbHMxLmxlbmd0aAorICAgICAgICArICIgcm93cyBmcm9tIGNhY2hlIGFuZCBkaXNrLiBFbGFwc2VkIHRpbWU6ICIKKyAgICAgICAgKyAoKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lKSAvIDEwMDAuMCkpOworICAgIAorICAgIC8vIDcuICBGbHVzaCB0byBkaXNrCisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICBMT0cuaW5mbygiQ2FjaGUgZmx1c2ggZWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKyAgICAKKyAgICAvLyA4LiAgU2NhbiBmcm9tIGRpc2sKKyAgICBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBzID0gdGhpcy5yZWdpb24uZ2V0U2Nhbm5lcihjb2xzLCBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywKKyAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICBudW1GZXRjaGVkID0gMDsKKyAgICB0cnkgeworICAgICAgTGlzdDxLZXlWYWx1ZT4gY3VyVmFscyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICBpbnQgayA9IDA7CisgICAgICB3aGlsZShzLm5leHQoY3VyVmFscykpIHsKKyAgICAgICAgZm9yKEl0ZXJhdG9yPEtleVZhbHVlPiBpdCA9IGN1clZhbHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICBLZXlWYWx1ZSBrdiA9IGl0Lm5leHQoKTsKKyAgICAgICAgICBieXRlIFtdIGNvbCA9IGt2LmdldENvbHVtbigpOworICAgICAgICAgIGJ5dGUgW10gdmFsID0ga3YuZ2V0VmFsdWUoKTsKKyAgICAgICAgICBpbnQgY3VydmFsID0KKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQobmV3IFN0cmluZyh2YWwsIEhDb25zdGFudHMuVVRGOF9FTkNPRElORykudHJpbSgpKTsKKyAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvbHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8oY29sLCBjb2xzW2pdKSA9PSAwKSB7CisgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVmFsdWUgZm9yICIgKyBCeXRlcy50b1N0cmluZyhjb2wpICsgIiBzaG91bGQgYmU6ICIgKyBrCisgICAgICAgICAgICAgICAgICArICIsIGJ1dCB3YXMgZmV0Y2hlZCBhczogIiArIGN1cnZhbCwgY3VydmFsLCBrKTsKKyAgICAgICAgICAgICAgbnVtRmV0Y2hlZCsrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjdXJWYWxzLmNsZWFyKCk7CisgICAgICAgIGsrKzsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoIkluc2VydGVkICIgKyBudW1JbnNlcnRlZCArICIgdmFsdWVzLCBidXQgZmV0Y2hlZCAiICsgbnVtRmV0Y2hlZCwKKyAgICAgIG51bUluc2VydGVkLCBudW1GZXRjaGVkKTsKKyAgICBMT0cuaW5mbygiU2Nhbm5lZCAiICsgdmFsczEubGVuZ3RoCisgICAgICAgICsgIiByb3dzIGZyb20gZGlzay4gRWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKworICAgIC8vIDkuIFNjYW4gd2l0aCBhIHN0YXJ0aW5nIHBvaW50CisgICAgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgcyA9IHRoaXMucmVnaW9uLmdldFNjYW5uZXIoY29scywgQnl0ZXMudG9CeXRlcygicm93X3ZhbHMxXzUwMCIpLAorICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgbnVtRmV0Y2hlZCA9IDA7CisgICAgdHJ5IHsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IGN1clZhbHMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgaW50IGsgPSA1MDA7CisgICAgICB3aGlsZShzLm5leHQoY3VyVmFscykpIHsKKyAgICAgICAgZm9yKEl0ZXJhdG9yPEtleVZhbHVlPiBpdCA9IGN1clZhbHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKKyAgICAgICAgICBLZXlWYWx1ZSBrdiA9IGl0Lm5leHQoKTsKKyAgICAgICAgICBieXRlIFtdIGNvbCA9IGt2LmdldENvbHVtbigpOworICAgICAgICAgIGJ5dGUgW10gdmFsID0ga3YuZ2V0VmFsdWUoKTsKKyAgICAgICAgICBpbnQgY3VydmFsID0KKyAgICAgICAgICAgIEludGVnZXIucGFyc2VJbnQobmV3IFN0cmluZyh2YWwsIEhDb25zdGFudHMuVVRGOF9FTkNPRElORykudHJpbSgpKTsKKyAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvbHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8oY29sLCBjb2xzW2pdKSA9PSAwKSB7CisgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVmFsdWUgZm9yICIgKyBCeXRlcy50b1N0cmluZyhjb2wpICsgIiBzaG91bGQgYmU6ICIgKyBrCisgICAgICAgICAgICAgICAgICArICIsIGJ1dCB3YXMgZmV0Y2hlZCBhczogIiArIGN1cnZhbCwgY3VydmFsLCBrKTsKKyAgICAgICAgICAgICAgbnVtRmV0Y2hlZCsrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjdXJWYWxzLmNsZWFyKCk7CisgICAgICAgIGsrKzsKKyAgICAgIH0KKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoIlNob3VsZCBoYXZlIGZldGNoZWQgIiArIChudW1JbnNlcnRlZCAvIDIpICsKKyAgICAgICIgdmFsdWVzLCBidXQgZmV0Y2hlZCAiICsgbnVtRmV0Y2hlZCwgKG51bUluc2VydGVkIC8gMiksIG51bUZldGNoZWQpOworICAgIAorICAgIExPRy5pbmZvKCJTY2FubmVkICIgKyAobnVtRmV0Y2hlZCAvIDIpCisgICAgICAgICsgIiByb3dzIGZyb20gZGlzayB3aXRoIHNwZWNpZmllZCBzdGFydCBwb2ludC4gRWxhcHNlZCB0aW1lOiAiCisgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKworICAgIExPRy5pbmZvKCJzY2FuIGNvbXBsZXRlZC4iKTsKKyAgfQorICAKKyAgLy8gTk9URTogVGhpcyB0ZXN0IGRlcGVuZHMgb24gdGVzdEJhdGNoV3JpdGUgc3VjY2VlZGluZworICBwcml2YXRlIHZvaWQgc3BsaXRBbmRNZXJnZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGF0aCBvbGRSZWdpb25QYXRoID0gci5nZXRSZWdpb25EaXIoKTsKKyAgICBieXRlIFtdIHNwbGl0Um93ID0gci5jb21wYWN0U3RvcmVzKCk7CisgICAgYXNzZXJ0Tm90TnVsbChzcGxpdFJvdyk7CisgICAgbG9uZyBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBIUmVnaW9uIHN1YnJlZ2lvbnMgW10gPSByLnNwbGl0UmVnaW9uKHNwbGl0Um93KTsKKyAgICBpZiAoc3VicmVnaW9ucyAhPSBudWxsKSB7CisgICAgICBMT0cuaW5mbygiU3BsaXQgcmVnaW9uIGVsYXBzZWQgdGltZTogIgorICAgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKyAgICAgIGFzc2VydEVxdWFscygiTnVtYmVyIG9mIHN1YnJlZ2lvbnMiLCBzdWJyZWdpb25zLmxlbmd0aCwgMik7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN1YnJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgc3VicmVnaW9uc1tpXSA9IG9wZW5DbG9zZWRSZWdpb24oc3VicmVnaW9uc1tpXSk7CisgICAgICAgIHN1YnJlZ2lvbnNbaV0uY29tcGFjdFN0b3JlcygpOworICAgICAgfQorICAgICAgCisgICAgICAvLyBOb3cgbWVyZ2UgaXQgYmFjayB0b2dldGhlcgorICAgICAgUGF0aCBvbGRSZWdpb24xID0gc3VicmVnaW9uc1swXS5nZXRSZWdpb25EaXIoKTsKKyAgICAgIFBhdGggb2xkUmVnaW9uMiA9IHN1YnJlZ2lvbnNbMV0uZ2V0UmVnaW9uRGlyKCk7CisgICAgICBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICAgIHIgPSBIUmVnaW9uLm1lcmdlQWRqYWNlbnQoc3VicmVnaW9uc1swXSwgc3VicmVnaW9uc1sxXSk7CisgICAgICByZWdpb24gPSBuZXcgSFJlZ2lvbkluY29tbW9uKHIpOworICAgICAgTE9HLmluZm8oIk1lcmdlIHJlZ2lvbnMgZWxhcHNlZCB0aW1lOiAiICsKKyAgICAgICAgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKyAgICAgIGZzLmRlbGV0ZShvbGRSZWdpb24xLCB0cnVlKTsKKyAgICAgIGZzLmRlbGV0ZShvbGRSZWdpb24yLCB0cnVlKTsKKyAgICAgIGZzLmRlbGV0ZShvbGRSZWdpb25QYXRoLCB0cnVlKTsKKyAgICB9CisgICAgTE9HLmluZm8oInNwbGl0QW5kTWVyZ2UgY29tcGxldGVkLiIpOworICB9CisKKyAgLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgZXZlcnl0aGluZyBpcyBzdGlsbCB0aGVyZSBhZnRlciBzcGxpdHRpbmcgYW5kIG1lcmdpbmcKKyAgCisgIHByaXZhdGUgdm9pZCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBGaXJzdCB2ZXJpZnkgdGhlIGRhdGEgd3JpdHRlbiBieSB0ZXN0QmFzaWMoKQorICAgIGJ5dGUgW11bXSBjb2xzID0geworICAgICAgICBCeXRlcy50b0J5dGVzKEFOQ0hPUk5VTSArICJbMC05XSsiKSwKKyAgICAgICAgQ09OVEVOVFNfQkFTSUMKKyAgICB9OworICAgIGxvbmcgc3RhcnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgSW50ZXJuYWxTY2FubmVyIHMgPQorICAgICAgci5nZXRTY2FubmVyKGNvbHMsIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLAorICAgICAgICAgIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLCBudWxsKTsKKyAgICB0cnkgeworICAgICAgaW50IGNvbnRlbnRzRmV0Y2hlZCA9IDA7CisgICAgICBpbnQgYW5jaG9yRmV0Y2hlZCA9IDA7CisgICAgICBMaXN0PEtleVZhbHVlPiBjdXJWYWxzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGludCBrID0gMDsKKyAgICAgIHdoaWxlKHMubmV4dChjdXJWYWxzKSkgeworICAgICAgICBmb3IoSXRlcmF0b3I8S2V5VmFsdWU+IGl0ID0gY3VyVmFscy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7ICkgeworICAgICAgICAgIEtleVZhbHVlIGt2ID0gaXQubmV4dCgpOworICAgICAgICAgIGJ5dGUgW10gY29sID0ga3YuZ2V0Q29sdW1uKCk7CisgICAgICAgICAgYnl0ZSBbXSB2YWwgPSBrdi5nZXRWYWx1ZSgpOworICAgICAgICAgIFN0cmluZyBjdXJ2YWwgPSBCeXRlcy50b1N0cmluZyh2YWwpOworICAgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8oY29sLCBDT05URU5UU19CQVNJQykgPT0gMCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZSgiRXJyb3IgYXQ6IiArIGt2CisgICAgICAgICAgICAgICAgKyAiLCBWYWx1ZSBmb3IgIiArIGNvbCArICIgc2hvdWxkIHN0YXJ0IHdpdGg6ICIgKyBDT05URU5UU1RSCisgICAgICAgICAgICAgICAgKyAiLCBidXQgd2FzIGZldGNoZWQgYXM6ICIgKyBjdXJ2YWwsCisgICAgICAgICAgICAgICAgY3VydmFsLnN0YXJ0c1dpdGgoQ09OVEVOVFNUUikpOworICAgICAgICAgICAgY29udGVudHNGZXRjaGVkKys7CisgICAgICAgICAgICAKKyAgICAgICAgICB9IGVsc2UgaWYgKEJ5dGVzLnRvU3RyaW5nKGNvbCkuc3RhcnRzV2l0aChBTkNIT1JOVU0pKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCJFcnJvciBhdDoiICsga3YKKyAgICAgICAgICAgICAgICArICIsIFZhbHVlIGZvciAiICsgQnl0ZXMudG9TdHJpbmcoY29sKSArCisgICAgICAgICAgICAgICAgIiBzaG91bGQgc3RhcnQgd2l0aDogIiArIEFOQ0hPUlNUUgorICAgICAgICAgICAgICAgICsgIiwgYnV0IHdhcyBmZXRjaGVkIGFzOiAiICsgY3VydmFsLAorICAgICAgICAgICAgICAgIGN1cnZhbC5zdGFydHNXaXRoKEFOQ0hPUlNUUikpOworICAgICAgICAgICAgYW5jaG9yRmV0Y2hlZCsrOworICAgICAgICAgICAgCisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJVTkVYUEVDVEVEIENPTFVNTiAiICsgQnl0ZXMudG9TdHJpbmcoY29sKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGN1clZhbHMuY2xlYXIoKTsKKyAgICAgICAgaysrOworICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJFeHBlY3RlZCAiICsgTlVNX1ZBTFMgKyAiICIgKyBCeXRlcy50b1N0cmluZyhDT05URU5UU19CQVNJQykgKworICAgICAgICAiIHZhbHVlcywgYnV0IGZldGNoZWQgIiArIGNvbnRlbnRzRmV0Y2hlZCwgTlVNX1ZBTFMsIGNvbnRlbnRzRmV0Y2hlZCk7CisgICAgICBhc3NlcnRFcXVhbHMoIkV4cGVjdGVkICIgKyBOVU1fVkFMUyArICIgIiArIEFOQ0hPUk5VTSArCisgICAgICAgICIgdmFsdWVzLCBidXQgZmV0Y2hlZCAiICsgYW5jaG9yRmV0Y2hlZCwgTlVNX1ZBTFMsIGFuY2hvckZldGNoZWQpOworCisgICAgICBMT0cuaW5mbygiU2Nhbm5lZCAiICsgTlVNX1ZBTFMKKyAgICAgICAgICArICIgcm93cyBmcm9tIGRpc2suIEVsYXBzZWQgdGltZTogIgorICAgICAgICAgICsgKChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgLyAxMDAwLjApKTsKKyAgICAgIAorICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICAgIAorICAgIC8vIFZlcmlmeSB0ZXN0U2NhbiBkYXRhCisgICAgCisgICAgY29scyA9IG5ldyBieXRlIFtdW10ge0NPTlRFTlRTX0ZJUlNUQ09MLCBBTkNIT1JfU0VDT05EQ09MfTsKKyAgICAKKyAgICBzdGFydFRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKworICAgIHMgPSByLmdldFNjYW5uZXIoY29scywgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csCisgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwgbnVsbCk7CisgICAgdHJ5IHsKKyAgICAgIGludCBudW1GZXRjaGVkID0gMDsKKyAgICAgIExpc3Q8S2V5VmFsdWU+IGN1clZhbHMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgaW50IGsgPSAwOworICAgICAgd2hpbGUocy5uZXh0KGN1clZhbHMpKSB7CisgICAgICAgIGZvcihJdGVyYXRvcjxLZXlWYWx1ZT4gaXQgPSBjdXJWYWxzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CisgICAgICAgICAgS2V5VmFsdWUga3YgPSBpdC5uZXh0KCk7CisgICAgICAgICAgYnl0ZSBbXSBjb2wgPSBrdi5nZXRDb2x1bW4oKTsKKyAgICAgICAgICBieXRlIFtdIHZhbCA9IGt2LmdldFZhbHVlKCk7CisgICAgICAgICAgaW50IGN1cnZhbCA9CisgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KG5ldyBTdHJpbmcodmFsLCBIQ29uc3RhbnRzLlVURjhfRU5DT0RJTkcpLnRyaW0oKSk7CisKKyAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvbHMubGVuZ3RoOyBqKyspIHsKKyAgICAgICAgICAgIGlmIChCeXRlcy5jb21wYXJlVG8oY29sLCBjb2xzW2pdKSA9PSAwKSB7CisgICAgICAgICAgICAgIGFzc2VydEVxdWFscygiVmFsdWUgZm9yICIgKyBCeXRlcy50b1N0cmluZyhjb2wpICsgIiBzaG91bGQgYmU6ICIgKyBrCisgICAgICAgICAgICAgICAgICArICIsIGJ1dCB3YXMgZmV0Y2hlZCBhczogIiArIGN1cnZhbCwgY3VydmFsLCBrKTsKKyAgICAgICAgICAgICAgbnVtRmV0Y2hlZCsrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjdXJWYWxzLmNsZWFyKCk7CisgICAgICAgIGsrKzsKKyAgICAgIH0KKyAgICAgIGFzc2VydEVxdWFscygiSW5zZXJ0ZWQgIiArIG51bUluc2VydGVkICsgIiB2YWx1ZXMsIGJ1dCBmZXRjaGVkICIgKworICAgICAgICBudW1GZXRjaGVkLCBudW1JbnNlcnRlZCwgbnVtRmV0Y2hlZCk7CisKKyAgICAgIExPRy5pbmZvKCJTY2FubmVkICIgKyAobnVtRmV0Y2hlZCAvIDIpCisgICAgICAgICAgKyAiIHJvd3MgZnJvbSBkaXNrLiBFbGFwc2VkIHRpbWU6ICIKKyAgICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisgICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgICAKKyAgICAvLyBUZXN0IGEgc2Nhbm5lciB3aGljaCBvbmx5IHNwZWNpZmllcyB0aGUgY29sdW1uIGZhbWlseSBuYW1lCisgICAgCisgICAgY29scyA9IG5ldyBieXRlIFtdW10geworICAgICAgICBCeXRlcy50b0J5dGVzKCJhbmNob3I6IikKKyAgICB9OworICAgIAorICAgIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIAorICAgIHMgPSByLmdldFNjYW5uZXIoY29scywgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLCBudWxsKTsKKworICAgIHRyeSB7CisgICAgICBpbnQgZmV0Y2hlZCA9IDA7CisgICAgICBMaXN0PEtleVZhbHVlPiBjdXJWYWxzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIHdoaWxlKHMubmV4dChjdXJWYWxzKSkgeworICAgICAgICBmb3IoSXRlcmF0b3I8S2V5VmFsdWU+IGl0ID0gY3VyVmFscy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7ICkgeworICAgICAgICAgIGl0Lm5leHQoKTsKKyAgICAgICAgICBmZXRjaGVkKys7CisgICAgICAgIH0KKyAgICAgICAgY3VyVmFscy5jbGVhcigpOworICAgICAgfQorICAgICAgYXNzZXJ0RXF1YWxzKCJJbnNlcnRlZCAiICsgKE5VTV9WQUxTICsgbnVtSW5zZXJ0ZWQvMikgKworICAgICAgICAiIHZhbHVlcywgYnV0IGZldGNoZWQgIiArIGZldGNoZWQsIChOVU1fVkFMUyArIG51bUluc2VydGVkLzIpLCBmZXRjaGVkKTsKKyAgICAgIExPRy5pbmZvKCJTY2FubmVkICIgKyBmZXRjaGVkCisgICAgICAgICAgKyAiIHJvd3MgZnJvbSBkaXNrLiBFbGFwc2VkIHRpbWU6ICIKKyAgICAgICAgICArICgoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUpIC8gMTAwMC4wKSk7CisgICAgICAKKyAgICB9IGZpbmFsbHkgeworICAgICAgcy5jbG9zZSgpOworICAgIH0KKyAgICBMT0cuaW5mbygicmVhZCBjb21wbGV0ZWQuIik7CisgIH0KKyAgCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhSZWdpb25JbmZvLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdEhSZWdpb25JbmZvLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNiMjJmYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0SFJlZ2lvbkluZm8uamF2YQpAQCAtMCwwICsxLDM3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCitwdWJsaWMgY2xhc3MgVGVzdEhSZWdpb25JbmZvIGV4dGVuZHMgSEJhc2VUZXN0Q2FzZSB7CisgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVIUmVnaW9uSW5mb05hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgdGFibGVOYW1lID0gInRhYmxlbmFtZSI7CisgICAgZmluYWwgYnl0ZSBbXSB0biA9IEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKTsKKyAgICBTdHJpbmcgc3RhcnRLZXkgPSAic3RhcnRrZXkiOworICAgIGZpbmFsIGJ5dGUgW10gc2sgPSBCeXRlcy50b0J5dGVzKHN0YXJ0S2V5KTsKKyAgICBTdHJpbmcgaWQgPSAiaWQiOworICAgIGJ5dGUgW10gbmFtZSA9IEhSZWdpb25JbmZvLmNyZWF0ZVJlZ2lvbk5hbWUodG4sIHNrLCBpZCk7CisgICAgU3RyaW5nIG5hbWVTdHIgPSBCeXRlcy50b1N0cmluZyhuYW1lKTsKKyAgICBhc3NlcnRFcXVhbHMobmFtZVN0ciwgdGFibGVOYW1lICsgIiwiICsgc3RhcnRLZXkgKyAiLCIgKyBpZCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0TG9nUm9sbGluZy5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RMb2dSb2xsaW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWVmMTEwZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0TG9nUm9sbGluZy5qYXZhCkBAIC0wLDAgKzEsMTY0IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDbHVzdGVyVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IGxvZyBkZWxldGlvbiBhcyBsb2dzIGFyZSByb2xsZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0TG9nUm9sbGluZyBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRlc3RMb2dSb2xsaW5nLmNsYXNzKTsKKyAgcHJpdmF0ZSBIUmVnaW9uU2VydmVyIHNlcnZlcjsKKyAgcHJpdmF0ZSBITG9nIGxvZzsKKyAgcHJpdmF0ZSBTdHJpbmcgdGFibGVOYW1lOworICBwcml2YXRlIGJ5dGVbXSB2YWx1ZTsKKyAgCisgIC8qKgorICAgKiBjb25zdHJ1Y3RvcgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIFRlc3RMb2dSb2xsaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gc3RhcnQgb25lIHJlZ2lvbnNlcnZlciBhbmQgYSBtaW5pZGZzLgorICAgIHN1cGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMuc2VydmVyID0gbnVsbDsKKyAgICAgIHRoaXMubG9nID0gbnVsbDsKKyAgICAgIHRoaXMudGFibGVOYW1lID0gbnVsbDsKKyAgICAgIHRoaXMudmFsdWUgPSBudWxsOworICAgICAgCisgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKTsKKyAgICAgIFN0cmluZ0J1aWxkZXIgdiA9IG5ldyBTdHJpbmdCdWlsZGVyKGNsYXNzTmFtZSk7CisgICAgICB3aGlsZSAodi5sZW5ndGgoKSA8IDEwMDApIHsKKyAgICAgICAgdi5hcHBlbmQoY2xhc3NOYW1lKTsKKyAgICAgIH0KKyAgICAgIHZhbHVlID0gQnl0ZXMudG9CeXRlcyh2LnRvU3RyaW5nKCkpOworICAgICAgCisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIExPRy5mYXRhbCgiZXJyb3IgaW4gY29uc3RydWN0b3IiLCBlKTsKKyAgICAgIHRocm93IGU7CisgICAgfQorICB9CisKKyAgLy8gTmVlZCB0byBvdmVycmlkZSB0aGlzIHNldHVwIHNvIHdlIGNhbiBlZGl0IHRoZSBjb25maWcgYmVmb3JlIGl0IGdldHMgc2VudAorICAvLyB0byB0aGUgY2x1c3RlciBzdGFydHVwLgorICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgcHJlSEJhc2VDbHVzdGVyU2V0dXAoKSB7CisgICAgLy8gRm9yY2UgYSByZWdpb24gc3BsaXQgYWZ0ZXIgZXZlcnkgNzY4S0IKKyAgICBjb25mLnNldExvbmcoImhiYXNlLmhyZWdpb24ubWF4LmZpbGVzaXplIiwgNzY4TCAqIDEwMjRMKTsKKworICAgIC8vIFdlIHJvbGwgdGhlIGxvZyBhZnRlciBldmVyeSAzMiB3cml0ZXMKKyAgICBjb25mLnNldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm1heGxvZ2VudHJpZXMiLCAzMik7CisKKyAgICAvLyBGb3IgbGVzcyBmcmVxdWVudGx5IHVwZGF0ZWQgcmVnaW9ucyBmbHVzaCBhZnRlciBldmVyeSAyIGZsdXNoZXMKKyAgICBjb25mLnNldEludCgiaGJhc2UuaHJlZ2lvbi5tZW1jYWNoZS5vcHRpb25hbGZsdXNoY291bnQiLCAyKTsKKworICAgIC8vIFdlIGZsdXNoIHRoZSBjYWNoZSBhZnRlciBldmVyeSA4MTkyIGJ5dGVzCisgICAgY29uZi5zZXRJbnQoImhiYXNlLmhyZWdpb24ubWVtY2FjaGUuZmx1c2guc2l6ZSIsIDgxOTIpOworCisgICAgLy8gTWFrZSBsZWFzZSB0aW1lb3V0IGxvbmdlciwgbGVhc2UgY2hlY2tzIGxlc3MgZnJlcXVlbnQKKyAgICBjb25mLnNldEludCgiaGJhc2UubWFzdGVyLmxlYXNlLnBlcmlvZCIsIDEwICogMTAwMCk7CisKKyAgICAvLyBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIHRpbWUgYmV0d2VlbiBjbGllbnQgcmV0cmllcworICAgIGNvbmYuc2V0TG9uZygiaGJhc2UuY2xpZW50LnBhdXNlIiwgMTUgKiAxMDAwKTsKKworICAgIC8vIFJlZHVjZSB0aHJlYWQgd2FrZSBmcmVxdWVuY3kgc28gdGhhdCBvdGhlciB0aHJlYWRzIGNhbiBnZXQKKyAgICAvLyBhIGNoYW5jZSB0byBydW4uCisgICAgY29uZi5zZXRJbnQoSENvbnN0YW50cy5USFJFQURfV0FLRV9GUkVRVUVOQ1ksIDIgKiAxMDAwKTsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHN0YXJ0QW5kV3JpdGVEYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV2hlbiB0aGUgTUVUQSB0YWJsZSBjYW4gYmUgb3BlbmVkLCB0aGUgcmVnaW9uIHNlcnZlcnMgYXJlIHJ1bm5pbmcKKyAgICBuZXcgSFRhYmxlKGNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKworICAgIHRoaXMuc2VydmVyID0gY2x1c3Rlci5nZXRSZWdpb25UaHJlYWRzKCkuZ2V0KDApLmdldFJlZ2lvblNlcnZlcigpOworICAgIHRoaXMubG9nID0gc2VydmVyLmdldExvZygpOworICAgIAorICAgIC8vIENyZWF0ZSB0aGUgdGVzdCB0YWJsZSBhbmQgb3BlbiBpdAorICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKHRhYmxlTmFtZSk7CisgICAgZGVzYy5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSkpOworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbihjb25mKTsKKyAgICBhZG1pbi5jcmVhdGVUYWJsZShkZXNjKTsKKyAgICBIVGFibGUgdGFibGUgPSBuZXcgSFRhYmxlKGNvbmYsIHRhYmxlTmFtZSk7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8PSAyNTY7IGkrKykgeyAgICAvLyAyNTYgd3JpdGVzIHNob3VsZCBjYXVzZSA4IGxvZyByb2xscworICAgICAgQmF0Y2hVcGRhdGUgYiA9CisgICAgICAgIG5ldyBCYXRjaFVwZGF0ZSgicm93IiArIFN0cmluZy5mb3JtYXQoIiUxJDA0ZCIsIGkpKTsKKyAgICAgIGIucHV0KEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWSwgdmFsdWUpOworICAgICAgdGFibGUuY29tbWl0KGIpOworCisgICAgICBpZiAoaSAlIDMyID09IDApIHsKKyAgICAgICAgLy8gQWZ0ZXIgZXZlcnkgMzIgd3JpdGVzIHNsZWVwIHRvIGxldCB0aGUgbG9nIHJvbGxlciBydW4KKworICAgICAgICB0cnkgeworICAgICAgICAgIFRocmVhZC5zbGVlcCgyMDAwKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIGNvbnRpbnVlCisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0cyB0aGF0IGxvZ3MgYXJlIGRlbGV0ZWQKKyAgICogCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0TG9nUm9sbGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgIHRhYmxlTmFtZSA9IGdldE5hbWUoKTsKKyAgICB0cnkgeworICAgICAgc3RhcnRBbmRXcml0ZURhdGEoKTsKKyAgICAgIExPRy5pbmZvKCJhZnRlciB3cml0aW5nIHRoZXJlIGFyZSAiICsgbG9nLmdldE51bUxvZ0ZpbGVzKCkgKyAiIGxvZyBmaWxlcyIpOworICAgICAgCisgICAgICAvLyBmbHVzaCBhbGwgcmVnaW9ucworICAgICAgCisgICAgICBMaXN0PEhSZWdpb24+IHJlZ2lvbnMgPQorICAgICAgICBuZXcgQXJyYXlMaXN0PEhSZWdpb24+KHNlcnZlci5nZXRPbmxpbmVSZWdpb25zKCkpOworICAgICAgZm9yIChIUmVnaW9uIHI6IHJlZ2lvbnMpIHsKKyAgICAgICAgci5mbHVzaGNhY2hlKCk7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vIE5vdyByb2xsIHRoZSBsb2cKKyAgICAgIGxvZy5yb2xsV3JpdGVyKCk7CisgICAgICAKKyAgICAgIGludCBjb3VudCA9IGxvZy5nZXROdW1Mb2dGaWxlcygpOworICAgICAgTE9HLmluZm8oImFmdGVyIGZsdXNoaW5nIGFsbCByZWdpb25zIGFuZCByb2xsaW5nIGxvZ3MgdGhlcmUgYXJlICIgKworICAgICAgICAgIGxvZy5nZXROdW1Mb2dGaWxlcygpICsgIiBsb2cgZmlsZXMiKTsKKyAgICAgIGFzc2VydFRydWUoKCJhY3R1YWwgY291bnQ6ICIgKyBjb3VudCksIGNvdW50IDw9IDIpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoInVuZXhwZWN0ZWQgZXhjZXB0aW9uIiwgZSk7CisgICAgICB0aHJvdyBlOworICAgIH0KKyAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdExydUhhc2hNYXAuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0THJ1SGFzaE1hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhYmI3NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdExydUhhc2hNYXAuamF2YQpAQCAtMCwwICsxLDM1NCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlcjsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTdG9yZUtleTsKKworcHVibGljIGNsYXNzIFRlc3RMcnVIYXNoTWFwIGV4dGVuZHMgVGVzdENhc2UgeworICBwcml2YXRlIHN0YXRpYyBMcnVIYXNoTWFwPEhTdG9yZUtleSwgSFN0b3JlS2V5PiBscnUgPSBudWxsOworCisgIHByaXZhdGUgc3RhdGljIEhTdG9yZUtleVtdIGtleXMgPSBudWxsOworICBwcml2YXRlIHN0YXRpYyBIU3RvcmVLZXkga2V5ID0gbnVsbDsKKyAgcHJpdmF0ZSBzdGF0aWMgSFN0b3JlS2V5IHRtcEtleSA9IG51bGw7CisgIAorICBwcml2YXRlIHN0YXRpYyBIU3RvcmVLZXlbXSB2YWxzID0gbnVsbDsKKyAgcHJpdmF0ZSBzdGF0aWMgSFN0b3JlS2V5IHZhbCA9IG51bGw7CisgIHByaXZhdGUgc3RhdGljIEhTdG9yZUtleSB0bXBWYWwgPSBudWxsOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgSFN0b3JlS2V5W10gdG1wRGF0YSA9IG51bGw7CisgIAorICAvL0hhdmUgdG8gc2V0IHR5cGUKKyAgcHJpdmF0ZSBzdGF0aWMgU2V0PExydUhhc2hNYXAuRW50cnk8SFN0b3JlS2V5LCBIU3RvcmVLZXk+PiBoYXNoU2V0ID0gbnVsbDsKKyAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxMcnVIYXNoTWFwLkVudHJ5PEhTdG9yZUtleSwgSFN0b3JlS2V5Pj4gZW50cnlMaXN0ID0gbnVsbDsKKyAgcHJpdmF0ZSBzdGF0aWMgTHJ1SGFzaE1hcC5FbnRyeTxIU3RvcmVLZXksIEhTdG9yZUtleT4gZW50cnkgPSBudWxsOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgUmFuZG9tIHJhbmQgPSBudWxsOworICBwcml2YXRlIHN0YXRpYyBpbnQgRU5UUllfQVJSQVlfTEVOID0gMjAwMDsKKyAgcHJpdmF0ZSBzdGF0aWMgaW50IExPT1BTID0gMTA7CisKKyAgcHJvdGVjdGVkIHZvaWQgc2V0VXAoKQorICB0aHJvd3MgRXhjZXB0aW9ueworICAgIHN1cGVyLnNldFVwKCk7CisgICAgbG9uZyBtYXhNZW1Vc2FnZSA9IDEwMDAwMDAwTDsKKyAgICAvL1VzaW5nIHRoZSBkZWZhdWx0IHZhbHVlcyBmb3IgZXZlcnl0aGluZywgZXhjZXB0IG1lbVVzYWdlCisgICAgbHJ1ID0gIG5ldyBMcnVIYXNoTWFwPEhTdG9yZUtleSwgSFN0b3JlS2V5PihtYXhNZW1Vc2FnZSk7CisKKyAgICAKKyAgICByYW5kID0gbmV3IFJhbmRvbSgpOworCisgICAga2V5cyAgICA9IG5ldyBIU3RvcmVLZXlbRU5UUllfQVJSQVlfTEVOXTsKKyAgICB2YWxzICAgID0gbmV3IEhTdG9yZUtleVtFTlRSWV9BUlJBWV9MRU5dOworICAgIHRtcERhdGEgPSBuZXcgSFN0b3JlS2V5W0VOVFJZX0FSUkFZX0xFTl07CisgIH0KKworICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpCisgIHRocm93cyBFeGNlcHRpb257CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgfQorICAKKworICAvKioKKyAgICogVGhpcyB0ZXN0IGFkZHMgZGF0YSB0byB0aGUgTHJ1IGFuZCBjaGVja3MgdGhhdCB0aGUgaGVhZCBhbmQgdGFpbCBwb2ludGVycworICAgKiBhcmUgdXBkYXRlZCBjb3JyZWN0bHkKKyAgICovCisgICBwdWJsaWMgdm9pZCB0ZXN0QWRkX1BvaW50ZXJzKCl7CisgICAgIGZvcihpbnQgaT0wOyBpPExPT1BTOyBpKyspeworICAgICAgIHNlcXVlbnRpYWwoa2V5cyk7CisgICAgICAgdG1wS2V5ID0ga2V5c1swXTsKKyAgICAgICAKKyAgICAgICBmb3IoSFN0b3JlS2V5IGtleToga2V5cyl7CisgICAgICAgICBscnUucHV0KGtleSwga2V5KTsKKyAgICAgICAgIGFzc2VydFRydWUoImhlYWRQdHIga2V5IG5vdCBjb3JyZWN0IiwKKyAgICAgICAgICAgICBscnUuZ2V0SGVhZFB0cigpLmdldEtleSgpLmVxdWFscyh0bXBLZXkpKTsKKyAgICAgICAgIAorICAgICAgICAgYXNzZXJ0VHJ1ZSgidGFpbFB0ciBrZXkgbm90IGNvcnJlY3QiLAorICAgICAgICAgICAgIGxydS5nZXRUYWlsUHRyKCkuZ2V0S2V5KCkuZXF1YWxzKGtleSkpOworICAgICAgIH0KKyAgICAgICBscnUuY2xlYXIoKTsKKyAgICAgfQorICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3RBZGRfUG9pbnRlcnM6IE9LIik7CisgICB9ICAKKyAgICAKKyAgLyoqCisgICAqIFRoaXMgdGVzdCBhZGRzIGRhdGEgdG8gdGhlIExydSBhbmQgY2hlY2tzIHRoYXQgdGhlIG1lbUZyZWUgdmFyaWFibGUgbmV2ZXIKKyAgICogZ29lcyBiZWxvdyAwICAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RBZGRfTWVtVXNhZ2VfcmFuZG9tKCl7CisgICAgZm9yKGludCBpPTA7IGk8TE9PUFM7IGkrKyl7CisgICAgICByYW5kb20oa2V5cyk7CisgICAgICAKKyAgICAgIGZvcihIU3RvcmVLZXkga2V5IDoga2V5cyl7CisgICAgICAgIGxydS5wdXQoa2V5LCBrZXkpOworICAKKyAgICAgICAgYXNzZXJ0VHJ1ZSgiTWVtb3J5IHVzYWdlIGV4Y2VlZGVkISIsIGxydS5nZXRNZW1GcmVlKCkgPiAwKTsKKyAgICAgIH0KKworICAgICAgbHJ1LmNsZWFyKCk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdEFkZF9NZW1Vc2FnZTogT0siKTsKKyAgfQorICAKKyAgLyoqCisgICAqIFRoaXMgdGVzdCBhZGRzIGRhdGEgdG8gdGhlIExydSBhbmQgY2hlY2tzIHRoYXQgdGhlIG1lbUZyZWUgdmFyaWFibGUgbmV2ZXIKKyAgICogZ29lcyBiZWxvdyAwICAKKyAgICovCisgICBwdWJsaWMgdm9pZCB0ZXN0QWRkX01lbVVzYWdlX3NlcXVlbnRpYWwoKXsKKyAgICAgZm9yKGludCBpPTA7IGk8TE9PUFM7IGkrKyl7CisgICAgICAgc2VxdWVudGlhbChrZXlzKTsKKyAgICAgICAKKyAgICAgICBmb3IoSFN0b3JlS2V5IGtleSA6IGtleXMpeworICAgICAgICAgbHJ1LnB1dChrZXksIGtleSk7CisgICAKKyAgICAgICAgIGFzc2VydFRydWUoIk1lbW9yeSB1c2FnZSBleGNlZWRlZCEiLCBscnUuZ2V0TWVtRnJlZSgpID4gMCk7CisgICAgICAgfQorCisgICAgICAgbHJ1LmNsZWFyKCk7CisgICAgIH0KKyAgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0QWRkX01lbVVzYWdlOiBPSyIpOworICAgfQorICAgCisgIC8qKgorICAgKiBUaGlzIHRlc3QgYWRkcyBkYXRhIHRvIHRoZSBMcnUgYW5kIGNoZWNrcyB0aGF0IHRoZSBvcmRlciBpbiB0aGUgbHJ1IGlzIHRoZQorICAgKiBzYW1lIGFzIHRoZSBpbnNlcnQgb3JkZXIKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RBZGRfT3JkZXIoKQorICB0aHJvd3MgRXhjZXB0aW9ueworICAgIGZvcihpbnQgaT0wOyBpPExPT1BTOyBpKyspeworICAgICAgLy9BZGRpbmcgdG8gTHJ1CisgICAgICBwdXQoKTsKKyAgICAgICAgICAgIAorICAgICAgLy9HZXR0aW5nIG9yZGVyIGZyb20gbHJ1CisgICAgICBlbnRyeUxpc3QgPSBscnUuZW50cnlMcnVMaXN0KCk7CisgICAgICAKKyAgICAgIC8vQ29tcGFyaW5nIG9yZGVycworICAgICAgYXNzZXJ0VHJ1ZSgiRGlmZmVyZW50IGxlbmd0aHMiICwga2V5cy5sZW5ndGggPT0gZW50cnlMaXN0LnNpemUoKSk7CisgICAgICBpbnQgaiA9IDA7CisgICAgICBmb3IoTWFwLkVudHJ5IGVudHJ5IDogZW50cnlMaXN0KXsKKyAgICAgICAgLy9Db21wYXJpbmcga2V5cworICAgICAgICBhc3NlcnRUcnVlKCJEaWZmZXJlbnQgb3JkZXIiLCBrZXlzW2orK10uZXF1YWxzKGVudHJ5LmdldEtleSgpKSk7CisgICAgICB9CisKKyAgICAgIC8vQ2xlYXJpbmcgdGhlIExydQorICAgICAgbHJ1LmNsZWFyKCk7ICAKKyAgICB9CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0QWRkX09yZGVyOiBPSyIpOworICB9ICAgIAorICAgIAorICAgIAorICAvKioKKyAgICogVGhpcyB0ZXN0IGFkZHMgZGF0YSB0byB0aGUgTHJ1LCBjbGVhcnMgaXQgYW5kIGNoZWNrcyB0aGF0IHRoZSBtZW1vcnlVc2FnZQorICAgKiBsb29rcyBvayBhZnRlcndhcmRzCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0QWRkX0NsZWFyKCkKKyAgdGhyb3dzIEV4Y2VwdGlvbnsKKyAgICBsb25nIGluaXRNZW1Vc2FnZSA9IDBMOworICAgIGxvbmcgcHV0TWVtVXNhZ2UgPSAwTDsKKyAgICBsb25nIGNsZWFyTWVtVXNhZ2UgPSAwTDsKKyAgICBmb3IoaW50IGk9MDsgaTxMT09QUzsgaSsrKXsKKyAgICAgIGluaXRNZW1Vc2FnZSA9IGxydS5nZXRNZW1GcmVlKCk7CisgICAgCisgICAgICAvL0FkZGluZyB0byBMcnUKKyAgICAgIHB1dCgpOworICAgICAgcHV0TWVtVXNhZ2UgPSBscnUuZ2V0TWVtRnJlZSgpOworCisgICAgICAvL0NsZWFyaW5nIHRoZSBMcnUKKyAgICAgIGxydS5jbGVhcigpOworICAgICAgY2xlYXJNZW1Vc2FnZSA9IGxydS5nZXRNZW1GcmVlKCk7CisgICAgICBhc3NlcnRUcnVlKCJtZW1Vc2FnZSB3ZW50IGRvd24iLCBjbGVhck1lbVVzYWdlIDw9IGluaXRNZW1Vc2FnZSk7CisgICAgfQorICAgIAorICAgIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdEFkZF9DbGVhcjogT0siKTsKKyAgfSAgICAKKyAgICAKKyAgICAKKyAgLyoqCisgICAqIFRoaXMgdGVzdCBhZGRzIGRhdGEgdG8gdGhlIExydSBhbmQgY2hlY2tzIHRoYXQgYWxsIHRoZSBkYXRhIHRoYXQgaXMgaW4KKyAgICogdGhlIGhhc2hTZXQgaXMgYWxzbyBpbiB0aGUgRW50cnlMaXN0CisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0QWRkX0NvbnRhaW5tZW50KCl7CisgICAgZm9yKGludCBpPTA7IGk8TE9PUFM7IGkrKyl7CisgICAgICAvL0FkZGluZyB0byBMcnUKKyAgICAgIHB1dCgpOworICAgICAgCisgICAgICAvL0dldHRpbmcgSGFzaFNldAorICAgICAgaGFzaFNldCA9IGxydS5lbnRyeVRhYmxlU2V0KCk7CisgICAgICAKKyAgICAgIC8vR2V0dGluZyBFbnRyeUxpc3QKKyAgICAgIGVudHJ5TGlzdCA9IGxydS5lbnRyeUxydUxpc3QoKTsKKyAgICAgIAorICAgICAgLy9Db21wYXJpbmcKKyAgICAgIGFzc2VydFRydWUoIldyb25nIHNpemUiLCBoYXNoU2V0LnNpemUoKSA9PSBlbnRyeUxpc3Quc2l6ZSgpKTsKKyAgICAgIGZvcihpbnQgaj0wOyBqPGVudHJ5TGlzdC5zaXplKCk7IGorKyl7CisgICAgICAgIGFzc2VydFRydWUoIlNldCBkb2Vzbid0IGNvbnRhaW4gdmFsdWUgZnJvbSBsaXN0IiwKKyAgICAgICAgICBoYXNoU2V0LmNvbnRhaW5zKGVudHJ5TGlzdC5nZXQoaikpKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLy9DbGVhcmluZyB0aGUgTHJ1CisgICAgICBscnUuY2xlYXIoKTsKKyAgICB9CisgICAgU3lzdGVtLm91dC5wcmludGxuKCJ0ZXN0QWRkX0NvbnRhaW5tZW50OiBPSyIpOworICB9CisgICAgCisgICAgCisgIC8qKgorICAgKiBUaGlzIHRlc3QgZ2V0cyBhbiBlbnRyeSBmcm9tIHRoZSBtYXAgYW5kIGNoZWNrcyB0aGF0IHRoZSBwb3NpdGlvbiBvZiBpdCBoYXMKKyAgICogYmVlbiB1cGRhdGVkIGFmdGVyd2FyZHMuCisgICAqLyAgCisgIHB1YmxpYyB2b2lkIHRlc3RHZXQoKXsKKyAgICBpbnQgZ2V0dGVyID0gMDsKKyAgIAorICAgIGZvcihpbnQgaT0wOyBpPExPT1BTOyBpKyspeworICAgICAgLy9BZGRpbmcgdG8gTHJ1CisgICAgICBwdXQoKTsKKyAgICAKKyAgICAgIC8vR2V0dGluZyBhIHJhbmRvbSBlbnRyeSBmcm9tIHRoZSBtYXAKKyAgICAgIGdldHRlciA9IHJhbmQubmV4dEludChFTlRSWV9BUlJBWV9MRU4pOworICAgICAga2V5ID0ga2V5c1tnZXR0ZXJdOworICAgICAgdmFsID0gbHJ1LmdldChrZXkpOworICAgCisgICAgICAvL0NoZWNraW5nIGlmIHRoZSBlbnRyaWVzIHBvc2l0aW9uIGhhcyBjaGFuZ2VkCisgICAgICBlbnRyeUxpc3QgPSBscnUuZW50cnlMcnVMaXN0KCk7CisgICAgICB0bXBLZXkgPSBlbnRyeUxpc3QuZ2V0KGVudHJ5TGlzdC5zaXplKCktMSkuZ2V0S2V5KCk7CisgICAgICBhc3NlcnRUcnVlKCJHZXQgZGlkIG5vdCBwdXQgZW50cnkgZmlyc3QiLCB0bXBLZXkuZXF1YWxzKGtleSkpOworICAgICAgCisgICAgICBpZihnZXR0ZXIgIT0gRU5UUllfQVJSQVlfTEVOIC0xKXsKKyAgICAgICAgdG1wS2V5ID0gZW50cnlMaXN0LmdldChnZXR0ZXIpLmdldEtleSgpOworICAgICAgICBhc3NlcnRGYWxzZSgiR2V0IGRpZCBsZWF2ZSBlbnRyeSBpbiBzYW1lIHBvc2l0aW9uIiwgdG1wS2V5LmVxdWFscyhrZXkpKTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgbHJ1LmNsZWFyKCk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdEdldDogT0siKTsKKyAgfSAgICAKKyAgICAKKyAgLyoqCisgICAqIFVwZGF0ZXMgYW4gZW50cnkgaW4gdGhlIG1hcCBhbmQgY2hlY2tzIHRoYXQgdGhlIHBvc2l0aW9uIG9mIGl0IGhhcyBiZWVuCisgICAqIHVwZGF0ZWQgYWZ0ZXJ3YXJkcy4KKyAgICovICAKKyAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZSgpeworICAgIGZvcihpbnQgaT0wOyBpPExPT1BTOyBpKyspeworICAgICAgLy9BZGRpbmcgdG8gTHJ1CisgICAgICBwdXQoKTsKKyAgICAKKyAgICAgIC8vR2V0dGluZyBhIHJhbmRvbSBlbnRyeSBmcm9tIHRoZSBtYXAKKyAgICAgIGtleSA9IGtleXNbcmFuZC5uZXh0SW50KEVOVFJZX0FSUkFZX0xFTildOworICAgICAgdmFsID0gcmFuZG9tKHZhbCk7CisgICAgICAKKyAgICAgIHRtcFZhbCA9IGxydS5wdXQoa2V5LCB2YWwpOworICAgIAorICAgICAgLy9DaGVja2luZyBpZiB0aGUgdmFsdWUgaGFzIGJlZW4gdXBkYXRlZCBhbmQgdGhhdCB0aGUgcG9zaXRpb24gaSBmaXJzdAorICAgICAgZW50cnlMaXN0ID0gbHJ1LmVudHJ5THJ1TGlzdCgpOworICAgICAgdG1wS2V5ID0gZW50cnlMaXN0LmdldChlbnRyeUxpc3Quc2l6ZSgpLTEpLmdldEtleSgpOworICAgICAgYXNzZXJ0VHJ1ZSgicHV0KHVwZGF0ZSkgZGlkIG5vdCBwdXQgZW50cnkgZmlyc3QiLCB0bXBLZXkuZXF1YWxzKGtleSkpOworICAgICAgaWYoIXZhbC5lcXVhbHModG1wVmFsKSl7CisgICAgICAgIGFzc2VydFRydWUoIlZhbHVlIHdhcyBub3QgdXBkYXRlZCIsCisgICAgICAgICAgZW50cnlMaXN0LmdldChlbnRyeUxpc3Quc2l6ZSgpLTEpLmdldFZhbHVlKCkuZXF1YWxzKHZhbCkpOworICAgICAgICBhc3NlcnRGYWxzZSgiVmFsdWUgd2FzIG5vdCB1cGRhdGVkIiwKKyAgICAgICAgICBlbnRyeUxpc3QuZ2V0KGVudHJ5TGlzdC5zaXplKCktMSkuZ2V0VmFsdWUoKS5lcXVhbHModG1wVmFsKSk7CisgICAgICB9CisgICAgICAKKyAgICAgIGxydS5jbGVhcigpOyAgICAgIAorICAgIH0KKyAgICAKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oInRlc3RVcGRhdGU6IE9LIik7CisgIH0gICAgCisgICAgCisgIC8qKgorICAgKiBSZW1vdmVzIGFuIGVudHJ5IGluIHRoZSBtYXAgYW5kIGNoZWNrcyB0aGF0IGl0IGlzIG5vIGxvbmdlciBpbiB0aGUKKyAgICogZW50cnlMaXN0IG5vciB0aGUgSGFzaFNldCBhZnRlcndhcmRzCisgICAqLyAgCisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmUoKXsKKyAgICBmb3IoaW50IGk9MDsgaTxMT09QUzsgaSsrKXsKKyAgICAgIC8vQWRkaW5nIHRvIExydQorICAgICAgcHV0KCk7CisgICAgICBlbnRyeUxpc3QgPSBscnUuZW50cnlMcnVMaXN0KCk7CisgICAgICAKKyAgICAgIC8vR2V0dGluZyBhIHJhbmRvbSBlbnRyeSBmcm9tIHRoZSBtYXAKKyAgICAgIGtleSA9IGtleXNbcmFuZC5uZXh0SW50KEVOVFJZX0FSUkFZX0xFTildOworICAgICAgdmFsID0gbHJ1LnJlbW92ZShrZXkpOworICAgCisgICAgICAvL0NoZWNraW5nIGtleSBpcyBpbiBsaXN0CisgICAgICBlbnRyeUxpc3QgPSBscnUuZW50cnlMcnVMaXN0KCk7CisgICAgICBmb3IoaW50IGo9MDsgajxlbnRyeUxpc3Quc2l6ZSgpOyBqKyspeworICAgICAgICBhc3NlcnRGYWxzZSgiRW50cnkgZm91bmQgaW4gbGlzdCBhZnRlciByZW1vdmUiLAorICAgICAgICAgIGVudHJ5TGlzdC5nZXQoaikuZXF1YWxzKGtleSkpOworICAgICAgfQorICAgICAgbHJ1LmNsZWFyKCk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbigidGVzdFJlbW92ZTogT0siKTsKKyAgfSAgICAKKworICAKKyAgLy9IZWxwZXJzCisgIHByaXZhdGUgc3RhdGljIHZvaWQgcHV0KCl7CisgICAgLy9TZXR0aW5nIHVwIGtleXMgYW5kIHZhbHVlcworICAgIHJhbmRvbShrZXlzKTsKKyAgICB2YWxzID0ga2V5czsKKyAgICAKKyAgICAvL0luc2VydGluZyBpbnRvIExydQorICAgIGZvcihpbnQgaT0wOyBpPGtleXMubGVuZ3RoOyBpKyspeworICAgICAgbHJ1LnB1dChrZXlzW2ldLCB2YWxzW2ldKTsKKyAgICB9CisgIH0KKyAgCisgIC8vIEdlbmVyYXRpbmcgZGF0YQorICBwcml2YXRlIHN0YXRpYyBIU3RvcmVLZXkgcmFuZG9tKEhTdG9yZUtleSBkYXRhKXsKKyAgICByZXR1cm4gbmV3IEhTdG9yZUtleShCeXRlcy50b0J5dGVzKHJhbmQubmV4dEludChFTlRSWV9BUlJBWV9MRU4pKSk7CisgIH0KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCByYW5kb20oSFN0b3JlS2V5W10ga2V5cyl7CisgICAgZmluYWwgaW50IExFTkdUSCA9IGtleXMubGVuZ3RoOworICAgIFNldDxJbnRlZ2VyPiBzZXQgPSBuZXcgSGFzaFNldDxJbnRlZ2VyPigpOworICAgIGZvcihpbnQgaT0wOyBpPExFTkdUSDsgaSsrKXsKKyAgICAgIEludGVnZXIgcG9zID0gMDsKKyAgICAgIHdoaWxlKHNldC5jb250YWlucyhwb3MgPSBuZXcgSW50ZWdlcihyYW5kLm5leHRJbnQoTEVOR1RIKSkpKXt9CisgICAgICBzZXQuYWRkKHBvcyk7CisgICAgICBrZXlzW2ldID0gbmV3IEhTdG9yZUtleShCeXRlcy50b0J5dGVzKHBvcykpOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXF1ZW50aWFsKEhTdG9yZUtleVtdIGtleXMpeworICAgIGZvcihpbnQgaT0wOyBpPGtleXMubGVuZ3RoOyBpKyspeworICAgICAga2V5c1tpXSA9IG5ldyBIU3RvcmVLZXkoQnl0ZXMudG9CeXRlcyhpKSk7CisgICAgfQorICB9CisgIAorCisgIC8vdGVzdEFkZAorICBwcml2YXRlIEhTdG9yZUtleVtdIG1hcEVudHJpZXNUb0FycmF5KExpc3Q8THJ1SGFzaE1hcC5FbnRyeTxIU3RvcmVLZXksCisgIEhTdG9yZUtleT4+IGVudHJ5TGlzdCl7CisgICAgTGlzdDxIU3RvcmVLZXk+IHJlcyA9IG5ldyBBcnJheUxpc3Q8SFN0b3JlS2V5PigpOworICAgIGZvcihNYXAuRW50cnk8SFN0b3JlS2V5LCBIU3RvcmVLZXk+IGVudHJ5IDogZW50cnlMaXN0KXsKKyAgICAgIHJlcy5hZGQoZW50cnkuZ2V0S2V5KCkpOworICAgIH0gIAorICAgIHJldHVybiByZXMudG9BcnJheShuZXcgSFN0b3JlS2V5WzBdKTsKKyAgfQorICAKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RTY2FubmVyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdFNjYW5uZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjIyNWVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RTY2FubmVyLmphdmEKQEAgLTAsMCArMSwzOTMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkRhdGFPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZGZzLk1pbmlERlNDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IUmVnaW9uSW5mbzsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzczsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5TdG9wUm93RmlsdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmZpbHRlci5XaGlsZU1hdGNoUm93RmlsdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLmhmaWxlLkNvbXByZXNzaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5Xcml0YWJsZXM7CisKKy8qKgorICogVGVzdCBvZiBhIGxvbmctbGl2ZWQgc2Nhbm5lciB2YWxpZGF0aW5nIGFzIHdlIGdvLgorICovCitwdWJsaWMgY2xhc3MgVGVzdFNjYW5uZXIgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2codGhpcy5nZXRDbGFzcygpKTsKKyAgCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgW10gRklSU1RfUk9XID0KKyAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVzsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXVtdIENPTFMgPSB7CisgICAgICBIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkKKyAgfTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXVtdIEVYUExJQ0lUX0NPTFMgPSB7CisgICAgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywKKyAgICBIQ29uc3RhbnRzLkNPTF9TRVJWRVIsCisgICAgSENvbnN0YW50cy5DT0xfU1RBUlRDT0RFCisgIH07CisgIAorICBzdGF0aWMgZmluYWwgSFRhYmxlRGVzY3JpcHRvciBURVNUVEFCTEVERVNDID0KKyAgICBuZXcgSFRhYmxlRGVzY3JpcHRvcigidGVzdHNjYW5uZXIiKTsKKyAgc3RhdGljIHsKKyAgICBURVNUVEFCTEVERVNDLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3IoSENvbnN0YW50cy5DT0xVTU5fRkFNSUxZLAorICAgICAgMTAsICAvLyBUZW4gaXMgYXJiaXRyYXJ5IG51bWJlci4gIEtlZXAgdmVyc2lvbnMgdG8gaGVscCBkZWJ1Z2dnaW5nLgorICAgICAgQ29tcHJlc3Npb24uQWxnb3JpdGhtLk5PTkUuZ2V0TmFtZSgpLCBmYWxzZSwgdHJ1ZSwgOCAqIDEwMjQsCisgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgSENvbnN0YW50cy5GT1JFVkVSLCBmYWxzZSkpOworICB9CisgIC8qKiBIUmVnaW9uSW5mbyBmb3Igcm9vdCByZWdpb24gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBIUmVnaW9uSW5mbyBSRUdJT05fSU5GTyA9CisgICAgbmV3IEhSZWdpb25JbmZvKFRFU1RUQUJMRURFU0MsIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSwKKyAgICBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVkpOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBbXSBST1dfS0VZID0gUkVHSU9OX0lORk8uZ2V0UmVnaW9uTmFtZSgpOworICAKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBTVEFSVF9DT0RFID0gTG9uZy5NQVhfVkFMVUU7CisKKyAgcHJpdmF0ZSBNaW5pREZTQ2x1c3RlciBjbHVzdGVyID0gbnVsbDsKKyAgcHJpdmF0ZSBIUmVnaW9uIHI7CisgIHByaXZhdGUgSFJlZ2lvbkluY29tbW9uIHJlZ2lvbjsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjbHVzdGVyID0gbmV3IE1pbmlERlNDbHVzdGVyKGNvbmYsIDIsIHRydWUsIChTdHJpbmdbXSludWxsKTsKKyAgICAvLyBTZXQgdGhlIGhiYXNlLnJvb3RkaXIgdG8gYmUgdGhlIGhvbWUgZGlyZWN0b3J5IGluIG1pbmkgZGZzLgorICAgIHRoaXMuY29uZi5zZXQoSENvbnN0YW50cy5IQkFTRV9ESVIsCisgICAgICB0aGlzLmNsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpLmdldEhvbWVEaXJlY3RvcnkoKS50b1N0cmluZygpKTsKKyAgICBzdXBlci5zZXRVcCgpOworICAgIAorICB9CisKKyAgLyoqCisgICAqIFRlc3QgYmFzaWMgc3RvcCByb3cgZmlsdGVyIHdvcmtzLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiAKKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTdG9wUm93KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZSBbXSBzdGFydHJvdyA9IEJ5dGVzLnRvQnl0ZXMoImJiYiIpOworICAgIGJ5dGUgW10gc3RvcHJvdyA9IEJ5dGVzLnRvQnl0ZXMoImNjYyIpOworICAgIHRyeSB7CisgICAgICB0aGlzLnIgPSBjcmVhdGVOZXdIUmVnaW9uKFJFR0lPTl9JTkZPLmdldFRhYmxlRGVzYygpLCBudWxsLCBudWxsKTsKKyAgICAgIGFkZENvbnRlbnQodGhpcy5yLCBIQ29uc3RhbnRzLkNPTFVNTl9GQU1JTFkpOworICAgICAgTGlzdDxLZXlWYWx1ZT4gcmVzdWx0cyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgICAvLyBEbyBzaW1wbGUgdGVzdCBvZiBnZXR0aW5nIG9uZSByb3cgb25seSBmaXJzdC4KKyAgICAgIEludGVybmFsU2Nhbm5lciBzID0gci5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwKKyAgICAgICAgICBCeXRlcy50b0J5dGVzKCJhYmMiKSwgSENvbnN0YW50cy5MQVRFU1RfVElNRVNUQU1QLAorICAgICAgICAgIG5ldyBXaGlsZU1hdGNoUm93RmlsdGVyKG5ldyBTdG9wUm93RmlsdGVyKEJ5dGVzLnRvQnl0ZXMoImFiZCIpKSkpOworICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgIHdoaWxlIChzLm5leHQocmVzdWx0cykpIHsKKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0KKyAgICAgIHMuY2xvc2UoKTsKKyAgICAgIGFzc2VydEVxdWFscygxLCBjb3VudCk7CisgICAgICAvLyBOb3cgZG8gc29tZXRoaW5nIGEgYml0IG1vcmUgaW12b2x2ZWQuCisgICAgICBzID0gci5nZXRTY2FubmVyKEhDb25zdGFudHMuQ09MVU1OX0ZBTUlMWV9BUlJBWSwKKyAgICAgICAgc3RhcnRyb3csIEhDb25zdGFudHMuTEFURVNUX1RJTUVTVEFNUCwKKyAgICAgICAgbmV3IFdoaWxlTWF0Y2hSb3dGaWx0ZXIobmV3IFN0b3BSb3dGaWx0ZXIoc3RvcHJvdykpKTsKKyAgICAgIGNvdW50ID0gMDsKKyAgICAgIEtleVZhbHVlIGt2ID0gbnVsbDsKKyAgICAgIHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PEtleVZhbHVlPigpOworICAgICAgZm9yIChib29sZWFuIGZpcnN0ID0gdHJ1ZTsgcy5uZXh0KHJlc3VsdHMpOykgeworICAgICAgICBrdiA9IHJlc3VsdHMuZ2V0KDApOworICAgICAgICBpZiAoZmlyc3QpIHsKKyAgICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IuY29tcGFyZShzdGFydHJvdywga3YuZ2V0Um93KCkpID09IDApOworICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0KKyAgICAgIGFzc2VydFRydWUoQnl0ZXMuQllURVNfQ09NUEFSQVRPUi5jb21wYXJlKHN0b3Byb3csIGt2LmdldFJvdygpKSA+IDApOworICAgICAgLy8gV2UgZ290IHNvbWV0aGluZyBiYWNrLgorICAgICAgYXNzZXJ0VHJ1ZShjb3VudCA+IDEwKTsKKyAgICAgIHMuY2xvc2UoKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdGhpcy5yLmNsb3NlKCk7CisgICAgICB0aGlzLnIuZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIHNodXRkb3duRGZzKHRoaXMuY2x1c3Rlcik7CisgICAgfQorICB9CisKKyAgLyoqIFRoZSB0ZXN0IQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0U2Nhbm5lcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHIgPSBjcmVhdGVOZXdIUmVnaW9uKFRFU1RUQUJMRURFU0MsIG51bGwsIG51bGwpOworICAgICAgcmVnaW9uID0gbmV3IEhSZWdpb25JbmNvbW1vbihyKTsKKyAgICAgIAorICAgICAgLy8gV3JpdGUgaW5mb3JtYXRpb24gdG8gdGhlIG1ldGEgdGFibGUKKworICAgICAgQmF0Y2hVcGRhdGUgYmF0Y2hVcGRhdGUgPQorICAgICAgICBuZXcgQmF0Y2hVcGRhdGUoUk9XX0tFWSwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworCisgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZVN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgIERhdGFPdXRwdXRTdHJlYW0gcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVTdHJlYW0pOworICAgICAgUkVHSU9OX0lORk8ud3JpdGUocyk7CisgICAgICBiYXRjaFVwZGF0ZS5wdXQoSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTywgYnl0ZVN0cmVhbS50b0J5dGVBcnJheSgpKTsKKyAgICAgIHJlZ2lvbi5jb21taXQoYmF0Y2hVcGRhdGUpOworCisgICAgICAvLyBXaGF0IHdlIGp1c3QgY29tbWl0dGVkIGlzIGluIHRoZSBtZW1jYWNoZS4gVmVyaWZ5IHRoYXQgd2UgY2FuIGdldAorICAgICAgLy8gaXQgYmFjayBib3RoIHdpdGggc2Nhbm5pbmcgYW5kIGdldAorICAgICAgCisgICAgICBzY2FuKGZhbHNlLCBudWxsKTsKKyAgICAgIGdldFJlZ2lvbkluZm8oKTsKKyAgICAgIAorICAgICAgLy8gQ2xvc2UgYW5kIHJlLW9wZW4KKyAgICAgIAorICAgICAgci5jbG9zZSgpOworICAgICAgciA9IG9wZW5DbG9zZWRSZWdpb24ocik7CisgICAgICByZWdpb24gPSBuZXcgSFJlZ2lvbkluY29tbW9uKHIpOworCisgICAgICAvLyBWZXJpZnkgd2UgY2FuIGdldCB0aGUgZGF0YSBiYWNrIG5vdyB0aGF0IGl0IGlzIG9uIGRpc2suCisgICAgICAKKyAgICAgIHNjYW4oZmFsc2UsIG51bGwpOworICAgICAgZ2V0UmVnaW9uSW5mbygpOworICAgICAgCisgICAgICAvLyBTdG9yZSBzb21lIG5ldyBpbmZvcm1hdGlvbgorIAorICAgICAgSFNlcnZlckFkZHJlc3MgYWRkcmVzcyA9IG5ldyBIU2VydmVyQWRkcmVzcygiZm9vLmJhci5jb206MTIzNCIpOworCisgICAgICBiYXRjaFVwZGF0ZSA9IG5ldyBCYXRjaFVwZGF0ZShST1dfS0VZLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisKKyAgICAgIGJhdGNoVXBkYXRlLnB1dChIQ29uc3RhbnRzLkNPTF9TRVJWRVIsICBCeXRlcy50b0J5dGVzKGFkZHJlc3MudG9TdHJpbmcoKSkpOworCisgICAgICBiYXRjaFVwZGF0ZS5wdXQoSENvbnN0YW50cy5DT0xfU1RBUlRDT0RFLCBCeXRlcy50b0J5dGVzKFNUQVJUX0NPREUpKTsKKworICAgICAgcmVnaW9uLmNvbW1pdChiYXRjaFVwZGF0ZSk7CisgICAgICAKKyAgICAgIC8vIFZhbGlkYXRlIHRoYXQgd2UgY2FuIHN0aWxsIGdldCB0aGUgSFJlZ2lvbkluZm8sIGV2ZW4gdGhvdWdoIGl0IGlzIGluCisgICAgICAvLyBhbiBvbGRlciByb3cgb24gZGlzayBhbmQgdGhlcmUgaXMgYSBuZXdlciByb3cgaW4gdGhlIG1lbWNhY2hlCisgICAgICAKKyAgICAgIHNjYW4odHJ1ZSwgYWRkcmVzcy50b1N0cmluZygpKTsKKyAgICAgIGdldFJlZ2lvbkluZm8oKTsKKyAgICAgIAorICAgICAgLy8gZmx1c2ggY2FjaGUKKworICAgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKworICAgICAgLy8gVmFsaWRhdGUgYWdhaW4KKyAgICAgIAorICAgICAgc2Nhbih0cnVlLCBhZGRyZXNzLnRvU3RyaW5nKCkpOworICAgICAgZ2V0UmVnaW9uSW5mbygpOworCisgICAgICAvLyBDbG9zZSBhbmQgcmVvcGVuCisgICAgICAKKyAgICAgIHIuY2xvc2UoKTsKKyAgICAgIHIgPSBvcGVuQ2xvc2VkUmVnaW9uKHIpOworICAgICAgcmVnaW9uID0gbmV3IEhSZWdpb25JbmNvbW1vbihyKTsKKworICAgICAgLy8gVmFsaWRhdGUgYWdhaW4KKyAgICAgIAorICAgICAgc2Nhbih0cnVlLCBhZGRyZXNzLnRvU3RyaW5nKCkpOworICAgICAgZ2V0UmVnaW9uSW5mbygpOworCisgICAgICAvLyBOb3cgdXBkYXRlIHRoZSBpbmZvcm1hdGlvbiBhZ2FpbgorCisgICAgICBhZGRyZXNzID0gbmV3IEhTZXJ2ZXJBZGRyZXNzKCJiYXIuZm9vLmNvbTo0MzIxIik7CisgICAgICAKKyAgICAgIGJhdGNoVXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPV19LRVksIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKKworICAgICAgYmF0Y2hVcGRhdGUucHV0KEhDb25zdGFudHMuQ09MX1NFUlZFUiwgCisgICAgICAgIEJ5dGVzLnRvQnl0ZXMoYWRkcmVzcy50b1N0cmluZygpKSk7CisKKyAgICAgIHJlZ2lvbi5jb21taXQoYmF0Y2hVcGRhdGUpOworICAgICAgCisgICAgICAvLyBWYWxpZGF0ZSBhZ2FpbgorICAgICAgCisgICAgICBzY2FuKHRydWUsIGFkZHJlc3MudG9TdHJpbmcoKSk7CisgICAgICBnZXRSZWdpb25JbmZvKCk7CisKKyAgICAgIC8vIGZsdXNoIGNhY2hlCisKKyAgICAgIHJlZ2lvbi5mbHVzaGNhY2hlKCk7CisKKyAgICAgIC8vIFZhbGlkYXRlIGFnYWluCisgICAgICAKKyAgICAgIHNjYW4odHJ1ZSwgYWRkcmVzcy50b1N0cmluZygpKTsKKyAgICAgIGdldFJlZ2lvbkluZm8oKTsKKworICAgICAgLy8gQ2xvc2UgYW5kIHJlb3BlbgorICAgICAgCisgICAgICByLmNsb3NlKCk7CisgICAgICByID0gb3BlbkNsb3NlZFJlZ2lvbihyKTsKKyAgICAgIHJlZ2lvbiA9IG5ldyBIUmVnaW9uSW5jb21tb24ocik7CisKKyAgICAgIC8vIFZhbGlkYXRlIGFnYWluCisgICAgICAKKyAgICAgIHNjYW4odHJ1ZSwgYWRkcmVzcy50b1N0cmluZygpKTsKKyAgICAgIGdldFJlZ2lvbkluZm8oKTsKKyAgICAgIAorICAgICAgLy8gY2xlYW4gdXAKKyAgICAgIAorICAgICAgci5jbG9zZSgpOworICAgICAgci5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgICAgCisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHNodXRkb3duRGZzKGNsdXN0ZXIpOworICAgIH0KKyAgfQorCisgIC8qKiBDb21wYXJlIHRoZSBIUmVnaW9uSW5mbyB3ZSByZWFkIGZyb20gSEJhc2UgdG8gd2hhdCB3ZSBzdG9yZWQgKi8KKyAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlUmVnaW9uSW5mbyhieXRlIFtdIHJlZ2lvbkJ5dGVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhSZWdpb25JbmZvIGluZm8gPQorICAgICAgKEhSZWdpb25JbmZvKSBXcml0YWJsZXMuZ2V0V3JpdGFibGUocmVnaW9uQnl0ZXMsIG5ldyBIUmVnaW9uSW5mbygpKTsKKyAgICAKKyAgICBhc3NlcnRFcXVhbHMoUkVHSU9OX0lORk8uZ2V0UmVnaW9uSWQoKSwgaW5mby5nZXRSZWdpb25JZCgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgaW5mby5nZXRTdGFydEtleSgpLmxlbmd0aCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIGluZm8uZ2V0RW5kS2V5KCkubGVuZ3RoKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgQnl0ZXMuY29tcGFyZVRvKGluZm8uZ2V0UmVnaW9uTmFtZSgpLCBSRUdJT05fSU5GTy5nZXRSZWdpb25OYW1lKCkpKTsKKyAgICBhc3NlcnRFcXVhbHMoMCwgaW5mby5nZXRUYWJsZURlc2MoKS5jb21wYXJlVG8oUkVHSU9OX0lORk8uZ2V0VGFibGVEZXNjKCkpKTsKKyAgfQorICAKKyAgLyoqIFVzZSBhIHNjYW5uZXIgdG8gZ2V0IHRoZSByZWdpb24gaW5mbyBhbmQgdGhlbiB2YWxpZGF0ZSB0aGUgcmVzdWx0cyAqLworICBwcml2YXRlIHZvaWQgc2Nhbihib29sZWFuIHZhbGlkYXRlU3RhcnRjb2RlLCBTdHJpbmcgc2VydmVyTmFtZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsgIAorICAgIEludGVybmFsU2Nhbm5lciBzY2FubmVyID0gbnVsbDsKKyAgICBMaXN0PEtleVZhbHVlPiByZXN1bHRzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICBieXRlIFtdW11bXSBzY2FuQ29sdW1ucyA9IHsKKyAgICAgICAgQ09MUywKKyAgICAgICAgRVhQTElDSVRfQ09MUworICAgIH07CisgICAgCisgICAgZm9yKGludCBpID0gMDsgaSA8IHNjYW5Db2x1bW5zLmxlbmd0aDsgaSsrKSB7CisgICAgICB0cnkgeworICAgICAgICBzY2FubmVyID0gci5nZXRTY2FubmVyKHNjYW5Db2x1bW5zW2ldLCBGSVJTVF9ST1csCisgICAgICAgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSwgbnVsbCk7CisgICAgICAgIHdoaWxlIChzY2FubmVyLm5leHQocmVzdWx0cykpIHsKKyAgICAgICAgICBhc3NlcnRUcnVlKGhhc0NvbHVtbihyZXN1bHRzLCBIQ29uc3RhbnRzLkNPTF9SRUdJT05JTkZPKSk7CisgICAgICAgICAgYnl0ZSBbXSB2YWwgPSBnZXRDb2x1bW4ocmVzdWx0cywgSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTykuZ2V0VmFsdWUoKTsgCisgICAgICAgICAgdmFsaWRhdGVSZWdpb25JbmZvKHZhbCk7CisgICAgICAgICAgaWYodmFsaWRhdGVTdGFydGNvZGUpIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoaGFzQ29sdW1uKHJlc3VsdHMsIEhDb25zdGFudHMuQ09MX1NUQVJUQ09ERSkpOworICAgICAgICAgICAgdmFsID0gZ2V0Q29sdW1uKHJlc3VsdHMsIEhDb25zdGFudHMuQ09MX1NUQVJUQ09ERSkuZ2V0VmFsdWUoKTsKKyAgICAgICAgICAgIGFzc2VydE5vdE51bGwodmFsKTsKKyAgICAgICAgICAgIGFzc2VydEZhbHNlKHZhbC5sZW5ndGggPT0gMCk7CisgICAgICAgICAgICBsb25nIHN0YXJ0Q29kZSA9IEJ5dGVzLnRvTG9uZyh2YWwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKFNUQVJUX0NPREUsIHN0YXJ0Q29kZSk7CisgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIGlmKHNlcnZlck5hbWUgIT0gbnVsbCkgeworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShoYXNDb2x1bW4ocmVzdWx0cywgSENvbnN0YW50cy5DT0xfU0VSVkVSKSk7CisgICAgICAgICAgICB2YWwgPSBnZXRDb2x1bW4ocmVzdWx0cywgSENvbnN0YW50cy5DT0xfU0VSVkVSKS5nZXRWYWx1ZSgpOworICAgICAgICAgICAgYXNzZXJ0Tm90TnVsbCh2YWwpOworICAgICAgICAgICAgYXNzZXJ0RmFsc2UodmFsLmxlbmd0aCA9PSAwKTsKKyAgICAgICAgICAgIFN0cmluZyBzZXJ2ZXIgPSBCeXRlcy50b1N0cmluZyh2YWwpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKDAsIHNlcnZlci5jb21wYXJlVG8oc2VydmVyTmFtZSkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXN1bHRzLmNsZWFyKCk7CisgICAgICAgIH0KKworICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgSW50ZXJuYWxTY2FubmVyIHMgPSBzY2FubmVyOworICAgICAgICBzY2FubmVyID0gbnVsbDsKKyAgICAgICAgaWYocyAhPSBudWxsKSB7CisgICAgICAgICAgcy5jbG9zZSgpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGhhc0NvbHVtbihmaW5hbCBMaXN0PEtleVZhbHVlPiBrdnMsIGZpbmFsIGJ5dGUgW10gY29sdW1uKSB7CisgICAgZm9yIChLZXlWYWx1ZSBrdjoga3ZzKSB7CisgICAgICBpZiAoa3YubWF0Y2hpbmdDb2x1bW4oY29sdW1uKSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHJpdmF0ZSBLZXlWYWx1ZSBnZXRDb2x1bW4oZmluYWwgTGlzdDxLZXlWYWx1ZT4ga3ZzLCBmaW5hbCBieXRlIFtdIGNvbHVtbikgeworICAgIGZvciAoS2V5VmFsdWUga3Y6IGt2cykgeworICAgICAgaWYgKGt2Lm1hdGNoaW5nQ29sdW1uKGNvbHVtbikpIHsKKyAgICAgICAgcmV0dXJuIGt2OworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIC8qKiBVc2UgZ2V0IHRvIHJldHJpZXZlIHRoZSBIUmVnaW9uSW5mbyBhbmQgdmFsaWRhdGUgaXQgKi8KKyAgcHJpdmF0ZSB2b2lkIGdldFJlZ2lvbkluZm8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGUgW10gYnl0ZXMgPSByZWdpb24uZ2V0KFJPV19LRVksIEhDb25zdGFudHMuQ09MX1JFR0lPTklORk8pLmdldFZhbHVlKCk7CisgICAgdmFsaWRhdGVSZWdpb25JbmZvKGJ5dGVzKTsgIAorICB9CisKKyAgLyoqCisgICAqIEhCYXNlLTkxMC4KKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTY2FuQW5kQ29uY3VycmVudEZsdXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdGhpcy5yID0gY3JlYXRlTmV3SFJlZ2lvbihSRUdJT05fSU5GTy5nZXRUYWJsZURlc2MoKSwgbnVsbCwgbnVsbCk7CisgICAgSFJlZ2lvbkluY29tbW9uIGhyaSA9IG5ldyBIUmVnaW9uSW5jb21tb24ocik7CisgICAgdHJ5IHsKKyAgICAgIExPRy5pbmZvKCJBZGRlZDogIiArIAorICAgICAgICBhZGRDb250ZW50KGhyaSwgQnl0ZXMudG9TdHJpbmcoSENvbnN0YW50cy5DT0xfUkVHSU9OSU5GTykpKTsKKyAgICAgIGludCBjb3VudCA9IGNvdW50KGhyaSwgLTEpOworICAgICAgYXNzZXJ0RXF1YWxzKGNvdW50LCBjb3VudChocmksIDEwMCkpOworICAgICAgYXNzZXJ0RXF1YWxzKGNvdW50LCBjb3VudChocmksIDApKTsKKyAgICAgIGFzc2VydEVxdWFscyhjb3VudCwgY291bnQoaHJpLCBjb3VudCAtIDEpKTsKKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgTE9HLmVycm9yKCJGYWlsZWQiLCBlKTsKKyAgICAgIHRocm93IGU7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHRoaXMuci5jbG9zZSgpOworICAgICAgdGhpcy5yLmdldExvZygpLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgICBzaHV0ZG93bkRmcyhjbHVzdGVyKTsKKyAgICB9CisgIH0KKyAKKyAgLyoKKyAgICogQHBhcmFtIGhyaSBSZWdpb24KKyAgICogQHBhcmFtIGZsdXNoSW5kZXggQXQgd2hhdCByb3cgd2Ugc3RhcnQgdGhlIGZsdXNoLgorICAgKiBAcmV0dXJuIENvdW50IG9mIHJvd3MgZm91bmQuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgaW50IGNvdW50KGZpbmFsIEhSZWdpb25JbmNvbW1vbiBocmksIGZpbmFsIGludCBmbHVzaEluZGV4KQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIExPRy5pbmZvKCJUYWtpbmcgb3V0IGNvdW50aW5nIHNjYW4iKTsKKyAgICBTY2FubmVySW5jb21tb24gcyA9IGhyaS5nZXRTY2FubmVyKEVYUExJQ0lUX0NPTFMsCisgICAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLCBIQ29uc3RhbnRzLkxBVEVTVF9USU1FU1RBTVApOworICAgIExpc3Q8S2V5VmFsdWU+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8S2V5VmFsdWU+KCk7CisgICAgaW50IGNvdW50ID0gMDsKKyAgICB3aGlsZSAocy5uZXh0KHZhbHVlcykpIHsKKyAgICAgIGNvdW50Kys7CisgICAgICBpZiAoZmx1c2hJbmRleCA9PSBjb3VudCkgeworICAgICAgICBMT0cuaW5mbygiU3RhcnRpbmcgZmx1c2ggYXQgZmx1c2ggaW5kZXggIiArIGZsdXNoSW5kZXgpOworICAgICAgICBocmkuZmx1c2hjYWNoZSgpOworICAgICAgICBMT0cuaW5mbygiRmluaXNoaW5nIGZsdXNoIik7CisgICAgICB9CisgICAgfQorICAgIHMuY2xvc2UoKTsKKyAgICBMT0cuaW5mbygiRm91bmQgIiArIGNvdW50ICsgIiBpdGVtcyIpOworICAgIHJldHVybiBjb3VudDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RTcGxpdC5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RTcGxpdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5YzI0NjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdFNwbGl0LmphdmEKQEAgLTAsMCArMSwyNjQgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuS2V5VmFsdWU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuVW5rbm93blNjYW5uZXJFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQ2VsbDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIHtATGluayBUZXN0SFJlZ2lvbn0gZG9lcyBhIHNwbGl0IGJ1dCB0aGlzIFRlc3RDYXNlIGFkZHMgdGVzdGluZyBvZiBmYXN0CisgKiBzcGxpdCBhbmQgbWFudWZhY3R1cmVzIG9kZC1iYWxsIHNwbGl0IHNjZW5hcmlvcy4KKyAqLworcHVibGljIGNsYXNzIFRlc3RTcGxpdCBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0U3BsaXQuY2xhc3MuZ2V0TmFtZSgpKTsKKyAgCisgIC8qKiBjb25zdHJ1Y3RvciAqLworICBwdWJsaWMgVGVzdFNwbGl0KCkgeworICAgIHN1cGVyKCk7CisKKyAgICAvLyBBbHdheXMgY29tcGFjdCBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIHN0b3JlIGZpbGUuCisgICAgY29uZi5zZXRJbnQoImhiYXNlLmhzdG9yZS5jb21wYWN0aW9uVGhyZXNob2xkIiwgMik7CisgICAgCisgICAgLy8gTWFrZSBsZWFzZSB0aW1lb3V0IGxvbmdlciwgbGVhc2UgY2hlY2tzIGxlc3MgZnJlcXVlbnQKKyAgICBjb25mLnNldEludCgiaGJhc2UubWFzdGVyLmxlYXNlLnBlcmlvZCIsIDEwICogMTAwMCk7CisgICAgY29uZi5zZXRJbnQoImhiYXNlLm1hc3Rlci5sZWFzZS50aHJlYWQud2FrZWZyZXF1ZW5jeSIsIDUgKiAxMDAwKTsKKyAgICAKKyAgICBjb25mLnNldEludCgiaGJhc2UucmVnaW9uc2VydmVyLmxlYXNlLnBlcmlvZCIsIDEwICogMTAwMCk7CisgICAgCisgICAgLy8gSW5jcmVhc2UgdGhlIGFtb3VudCBvZiB0aW1lIGJldHdlZW4gY2xpZW50IHJldHJpZXMKKyAgICBjb25mLnNldExvbmcoImhiYXNlLmNsaWVudC5wYXVzZSIsIDE1ICogMTAwMCk7CisKKyAgICAvLyBUaGlzIHNpemUgc2hvdWxkIG1ha2UgaXQgc28gd2UgYWx3YXlzIHNwbGl0IHVzaW5nIHRoZSBhZGRDb250ZW50CisgICAgLy8gYmVsb3cuICBBZnRlciBhZGRpbmcgYWxsIGRhdGEsIHRoZSBmaXJzdCByZWdpb24gaXMgMS4zTQorICAgIGNvbmYuc2V0TG9uZygiaGJhc2UuaHJlZ2lvbi5tYXguZmlsZXNpemUiLCAxMDI0ICogMTI4KTsKKyAgfQorCisgIC8qKgorICAgKiBTcGxpdHMgdHdpY2UgYW5kIHZlcmlmaWVzIGdldHRpbmcgZnJvbSBlYWNoIG9mIHRoZSBzcGxpdCByZWdpb25zLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEJhc2ljU3BsaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gY3JlYXRlVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSk7CisgICAgICBodGQuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT0xGQU1JTFlfTkFNRTMpKTsKKyAgICAgIHJlZ2lvbiA9IGNyZWF0ZU5ld0hSZWdpb24oaHRkLCBudWxsLCBudWxsKTsKKyAgICAgIGJhc2ljU3BsaXQocmVnaW9uKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgaWYgKHJlZ2lvbiAhPSBudWxsKSB7CisgICAgICAgIHJlZ2lvbi5jbG9zZSgpOworICAgICAgICByZWdpb24uZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IGZvciBIQkFTRS04MTAKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTY2FuU3BsaXRPblJlZ2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIEhSZWdpb24gcmVnaW9uID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgSFRhYmxlRGVzY3JpcHRvciBodGQgPSBjcmVhdGVUYWJsZURlc2NyaXB0b3IoZ2V0TmFtZSgpKTsKKyAgICAgIGh0ZC5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTEZBTUlMWV9OQU1FMykpOworICAgICAgcmVnaW9uID0gY3JlYXRlTmV3SFJlZ2lvbihodGQsIG51bGwsIG51bGwpOworICAgICAgYWRkQ29udGVudChyZWdpb24sIENPTEZBTUlMWV9OQU1FMyk7CisgICAgICByZWdpb24uZmx1c2hjYWNoZSgpOworICAgICAgZmluYWwgYnl0ZSBbXSBtaWRrZXkgPSByZWdpb24uY29tcGFjdFN0b3JlcygpOworICAgICAgYXNzZXJ0Tm90TnVsbChtaWRrZXkpOworICAgICAgYnl0ZSBbXVtdIGNvbHMgPSB7Q09MRkFNSUxZX05BTUUzfTsKKyAgICAgIGZpbmFsIEludGVybmFsU2Nhbm5lciBzID0gcmVnaW9uLmdldFNjYW5uZXIoY29scywKKyAgICAgICAgSENvbnN0YW50cy5FTVBUWV9TVEFSVF9ST1csIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpLCBudWxsKTsKKyAgICAgIGZpbmFsIEhSZWdpb24gcmVnaW9uRm9yVGhyZWFkID0gcmVnaW9uOworICAgICAgCisgICAgICBUaHJlYWQgc3BsaXRUaHJlYWQgPSBuZXcgVGhyZWFkKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzcGxpdChyZWdpb25Gb3JUaHJlYWQsIG1pZGtleSk7CisgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVW5leHBlY3RlZCBleGNlcHRpb24gIiArIGUpOworICAgICAgICAgIH0gCisgICAgICAgIH0KKyAgICAgIH07CisgICAgICBzcGxpdFRocmVhZC5zdGFydCgpOworICAgICAgSFJlZ2lvblNlcnZlciBzZXJ2ZXIgPSBjbHVzdGVyLmdldFJlZ2lvblRocmVhZHMoKS5nZXQoMCkuZ2V0UmVnaW9uU2VydmVyKCk7CisgICAgICBsb25nIGlkID0gc2VydmVyLmFkZFNjYW5uZXIocyk7CisgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgNjsgaSsrKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgQmF0Y2hVcGRhdGUgdXBkYXRlID0gCisgICAgICAgICAgICBuZXcgQmF0Y2hVcGRhdGUocmVnaW9uLmdldFJlZ2lvbkluZm8oKS5nZXRTdGFydEtleSgpKTsKKyAgICAgICAgICB1cGRhdGUucHV0KENPTEZBTUlMWV9OQU1FMywgQnl0ZXMudG9CeXRlcygidmFsIikpOworICAgICAgICAgIHJlZ2lvbi5iYXRjaFVwZGF0ZSh1cGRhdGUpOworICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDAwKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgIGZhaWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uICIgKyBlKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgc2VydmVyLm5leHQoaWQpOworICAgICAgc2VydmVyLmNsb3NlKGlkKTsKKyAgICB9IGNhdGNoKFVua25vd25TY2FubmVyRXhjZXB0aW9uIGV4KSB7CisgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKKyAgICAgIGZhaWwoIkdvdCB0aGUgIiArIGV4KTsKKyAgICB9IAorICB9CisgIAorICBwcml2YXRlIHZvaWQgYmFzaWNTcGxpdChmaW5hbCBIUmVnaW9uIHJlZ2lvbikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTE9HLmluZm8oIiIgKyBhZGRDb250ZW50KHJlZ2lvbiwgQ09MRkFNSUxZX05BTUUzKSk7CisgICAgcmVnaW9uLmZsdXNoY2FjaGUoKTsKKyAgICBieXRlIFtdIHNwbGl0Um93ID0gcmVnaW9uLmNvbXBhY3RTdG9yZXMoKTsKKyAgICBhc3NlcnROb3ROdWxsKHNwbGl0Um93KTsKKyAgICBMT0cuaW5mbygiU3BsaXRSb3c6ICIgKyBCeXRlcy50b1N0cmluZyhzcGxpdFJvdykpOworICAgIEhSZWdpb24gW10gcmVnaW9ucyA9IHNwbGl0KHJlZ2lvbiwgc3BsaXRSb3cpOworICAgIHRyeSB7CisgICAgICAvLyBOZWVkIHRvIG9wZW4gdGhlIHJlZ2lvbnMuCisgICAgICAvLyBUT0RPOiBBZGQgYW4gJ29wZW4nIHRvIEhSZWdpb24uLi4gZG9uJ3QgZG8gb3BlbiBieSBjb25zdHJ1Y3RpbmcKKyAgICAgIC8vIGluc3RhbmNlLgorICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZWdpb25zLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIHJlZ2lvbnNbaV0gPSBvcGVuQ2xvc2VkUmVnaW9uKHJlZ2lvbnNbaV0pOworICAgICAgfQorICAgICAgLy8gQXNzZXJ0IGNhbiBnZXQgcm93cyBvdXQgb2YgbmV3IHJlZ2lvbnMuIFNob3VsZCBiZSBhYmxlIHRvIGdldCBmaXJzdAorICAgICAgLy8gcm93IGZyb20gZmlyc3QgcmVnaW9uIGFuZCB0aGUgbWlka2V5IGZyb20gc2Vjb25kIHJlZ2lvbi4KKyAgICAgIGFzc2VydEdldChyZWdpb25zWzBdLCBDT0xGQU1JTFlfTkFNRTMsIEJ5dGVzLnRvQnl0ZXMoU1RBUlRfS0VZKSk7CisgICAgICBhc3NlcnRHZXQocmVnaW9uc1sxXSwgQ09MRkFNSUxZX05BTUUzLCBzcGxpdFJvdyk7CisgICAgICAvLyBUZXN0IEkgY2FuIGdldCBzY2FubmVyIGFuZCB0aGF0IGl0IHN0YXJ0cyBhdCByaWdodCBwbGFjZS4KKyAgICAgIGFzc2VydFNjYW4ocmVnaW9uc1swXSwgQ09MRkFNSUxZX05BTUUzLAorICAgICAgICAgIEJ5dGVzLnRvQnl0ZXMoU1RBUlRfS0VZKSk7CisgICAgICBhc3NlcnRTY2FuKHJlZ2lvbnNbMV0sIENPTEZBTUlMWV9OQU1FMywgc3BsaXRSb3cpOworICAgICAgLy8gTm93IHByb3ZlIGNhbid0IHNwbGl0IHJlZ2lvbnMgdGhhdCBoYXZlIHJlZmVyZW5jZXMuCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgLy8gQWRkIHNvIG11Y2ggZGF0YSB0byB0aGlzIHJlZ2lvbiwgd2UgY3JlYXRlIGEgc3RvcmUgZmlsZSB0aGF0IGlzID4KKyAgICAgICAgLy8gdGhhbiBvbmUgb2Ygb3VyIHVuc3BsaXRhYmxlIHJlZmVyZW5jZXMuIGl0IHdpbGwuCisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgMjsgaisrKSB7CisgICAgICAgICAgYWRkQ29udGVudChyZWdpb25zW2ldLCBDT0xGQU1JTFlfTkFNRTMpOworICAgICAgICB9CisgICAgICAgIGFkZENvbnRlbnQocmVnaW9uc1tpXSwgQ09MRkFNSUxZX05BTUUyKTsKKyAgICAgICAgYWRkQ29udGVudChyZWdpb25zW2ldLCBDT0xGQU1JTFlfTkFNRTEpOworICAgICAgICByZWdpb25zW2ldLmZsdXNoY2FjaGUoKTsKKyAgICAgIH0KKworICAgICAgYnl0ZSBbXVtdIG1pZGtleXMgPSBuZXcgYnl0ZSBbcmVnaW9ucy5sZW5ndGhdW107CisgICAgICAvLyBUbyBtYWtlIHJlZ2lvbnMgc3BsaXRhYmxlIGZvcmNlIGNvbXBhY3Rpb24uCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgbWlka2V5c1tpXSA9IHJlZ2lvbnNbaV0uY29tcGFjdFN0b3JlcygpOworICAgICAgfQorCisgICAgICBUcmVlTWFwPFN0cmluZywgSFJlZ2lvbj4gc29ydGVkTWFwID0gbmV3IFRyZWVNYXA8U3RyaW5nLCBIUmVnaW9uPigpOworICAgICAgLy8gU3BsaXQgdGhlc2UgdHdvIGRhdWdodGVyIHJlZ2lvbnMgc28gdGhlbiBJJ2xsIGhhdmUgNCByZWdpb25zLiBXaWxsCisgICAgICAvLyBzcGxpdCBiZWNhdXNlIGFkZGVkIGRhdGEgYWJvdmUuCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgSFJlZ2lvbltdIHJzID0gbnVsbDsKKyAgICAgICAgaWYgKG1pZGtleXNbaV0gIT0gbnVsbCkgeworICAgICAgICAgIHJzID0gc3BsaXQocmVnaW9uc1tpXSwgbWlka2V5c1tpXSk7CisgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBycy5sZW5ndGg7IGorKykgeworICAgICAgICAgICAgc29ydGVkTWFwLnB1dChCeXRlcy50b1N0cmluZyhyc1tqXS5nZXRSZWdpb25OYW1lKCkpLAorICAgICAgICAgICAgICBvcGVuQ2xvc2VkUmVnaW9uKHJzW2pdKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgICBMT0cuaW5mbygiTWFkZSA0IHJlZ2lvbnMiKTsKKyAgICAgIC8vIFRoZSBzcGxpdHMgc2hvdWxkIGhhdmUgYmVlbiBldmVuLiBUZXN0IEkgY2FuIGdldCBzb21lIGFyYml0cmFyeSByb3cgb3V0CisgICAgICAvLyBvZiBlYWNoLgorICAgICAgaW50IGludGVydmFsID0gKExBU1RfQ0hBUiAtIEZJUlNUX0NIQVIpIC8gMzsKKyAgICAgIGJ5dGVbXSBiID0gQnl0ZXMudG9CeXRlcyhTVEFSVF9LRVkpOworICAgICAgZm9yIChIUmVnaW9uIHIgOiBzb3J0ZWRNYXAudmFsdWVzKCkpIHsKKyAgICAgICAgYXNzZXJ0R2V0KHIsIENPTEZBTUlMWV9OQU1FMywgYik7CisgICAgICAgIGJbMF0gKz0gaW50ZXJ2YWw7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVnaW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgICB0cnkgeworICAgICAgICAgIHJlZ2lvbnNbaV0uY2xvc2UoKTsKKyAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIElnbm9yZS4KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGFzc2VydEdldChmaW5hbCBIUmVnaW9uIHIsIGZpbmFsIGJ5dGUgW10gZmFtaWx5LCBmaW5hbCBieXRlIFtdIGspCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gTm93IEkgaGF2ZSBrLCBnZXQgdmFsdWVzIG91dCBhbmQgYXNzZXJ0IHRoZXkgYXJlIGFzIGV4cGVjdGVkLgorICAgIENlbGxbXSByZXN1bHRzID0gQ2VsbC5jcmVhdGVTaW5nbGVDZWxsQXJyYXkoci5nZXQoaywgZmFtaWx5LCAtMSwgSW50ZWdlci5NQVhfVkFMVUUpKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IHJlc3VsdHMubGVuZ3RoOyBqKyspIHsKKyAgICAgIGJ5dGUgW10gdG1wID0gcmVzdWx0c1tqXS5nZXRWYWx1ZSgpOworICAgICAgLy8gUm93IHNob3VsZCBiZSBlcXVhbCB0byB2YWx1ZSBldmVyeSB0aW1lLgorICAgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoaywgdG1wKSk7CisgICAgfQorICB9CisgIAorICAvKgorICAgKiBBc3NlcnQgZmlyc3QgdmFsdWUgaW4gdGhlIHBhc3NlZCByZWdpb24gaXMgPGNvZGU+Zmlyc3RWYWx1ZTwvY29kZT4uCisgICAqIEBwYXJhbSByCisgICAqIEBwYXJhbSBjb2x1bW4KKyAgICogQHBhcmFtIGZpcnN0VmFsdWUKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIGFzc2VydFNjYW4oZmluYWwgSFJlZ2lvbiByLCBmaW5hbCBieXRlIFtdIGNvbHVtbiwKKyAgICAgIGZpbmFsIGJ5dGUgW10gZmlyc3RWYWx1ZSkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlIFtdW10gY29scyA9IHtjb2x1bW59OworICAgIEludGVybmFsU2Nhbm5lciBzID0gci5nZXRTY2FubmVyKGNvbHMsCisgICAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVywgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCksIG51bGwpOworICAgIHRyeSB7CisgICAgICBMaXN0PEtleVZhbHVlPiBjdXJWYWxzID0gbmV3IEFycmF5TGlzdDxLZXlWYWx1ZT4oKTsKKyAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworICAgICAgT1VURVJfTE9PUDogd2hpbGUocy5uZXh0KGN1clZhbHMpKSB7CisgICAgICAgIGZvciAoS2V5VmFsdWUga3Y6IGN1clZhbHMpIHsKKyAgICAgICAgICBieXRlIFtdIHZhbCA9IGt2LmdldFZhbHVlKCk7CisgICAgICAgICAgYnl0ZSBbXSBjdXJ2YWwgPSB2YWw7CisgICAgICAgICAgaWYgKGZpcnN0KSB7CisgICAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShCeXRlcy5jb21wYXJlVG8oY3VydmFsLCBmaXJzdFZhbHVlKSA9PSAwKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gTm90IGFzc2VydGluZyBhbnl0aGluZy4gIE1pZ2h0IGFzIHdlbGwgYnJlYWsuCisgICAgICAgICAgICBicmVhayBPVVRFUl9MT09QOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICBzLmNsb3NlKCk7CisgICAgfQorICB9CisgIAorICBwcm90ZWN0ZWQgSFJlZ2lvbiBbXSBzcGxpdChmaW5hbCBIUmVnaW9uIHIsIGZpbmFsIGJ5dGUgW10gc3BsaXRSb3cpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQXNzZXJ0IGNhbiBnZXQgbWlkIGtleSBmcm9tIHBhc3NlZCByZWdpb24uCisgICAgYXNzZXJ0R2V0KHIsIENPTEZBTUlMWV9OQU1FMywgc3BsaXRSb3cpOworICAgIEhSZWdpb24gW10gcmVnaW9ucyA9IHIuc3BsaXRSZWdpb24oc3BsaXRSb3cpOworICAgIGFzc2VydEVxdWFscyhyZWdpb25zLmxlbmd0aCwgMik7CisgICAgcmV0dXJuIHJlZ2lvbnM7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvVGVzdFN0b3JlRmlsZS5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RTdG9yZUZpbGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDFkMjJmNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0U3RvcmVGaWxlLmphdmEKQEAgLTAsMCArMSwyOTkgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZWdpb25zZXJ2ZXI7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFN0b3JlS2V5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLktleVZhbHVlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJlZmVyZW5jZS5SYW5nZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5oZmlsZS5IRmlsZVNjYW5uZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqCisgKiBUZXN0IEhTdG9yZUZpbGUKKyAqLworcHVibGljIGNsYXNzIFRlc3RTdG9yZUZpbGUgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0U3RvcmVGaWxlLmNsYXNzKTsKKyAgcHJpdmF0ZSBNaW5pREZTQ2x1c3RlciBjbHVzdGVyOworICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIHRoaXMuY2x1c3RlciA9IG5ldyBNaW5pREZTQ2x1c3Rlcih0aGlzLmNvbmYsIDIsIHRydWUsIChTdHJpbmdbXSludWxsKTsKKyAgICAgIC8vIFNldCB0aGUgaGJhc2Uucm9vdGRpciB0byBiZSB0aGUgaG9tZSBkaXJlY3RvcnkgaW4gbWluaSBkZnMuCisgICAgICB0aGlzLmNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLAorICAgICAgICB0aGlzLmNsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpLmdldEhvbWVEaXJlY3RvcnkoKS50b1N0cmluZygpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBzaHV0ZG93bkRmcyhjbHVzdGVyKTsKKyAgICB9CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgfQorICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICBzaHV0ZG93bkRmcyhjbHVzdGVyKTsKKyAgICAvLyBSZWZsZWN0aW9uVXRpbHMucHJpbnRUaHJlYWRJbmZvKG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0KSwKKyAgICAvLyAgIlRlbXBvcmFyeSBlbmQtb2YtdGVzdCB0aHJlYWQgZHVtcCBkZWJ1Z2dpbmcgSEFET09QLTIwNDA6ICIgKyBnZXROYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlIGEgZmlsZSBhbmQgdGhlbiBhc3NlcnQgdGhhdCB3ZSBjYW4gcmVhZCBmcm9tIHRvcCBhbmQgYm90dG9tIGhhbHZlcworICAgKiB1c2luZyB0d28gSGFsZk1hcEZpbGVzLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdEJhc2ljSGFsZk1hcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNYWtlIHVwIGEgZGlyZWN0b3J5IGhpZXJhcmNoeSB0aGF0IGhhcyBhIHJlZ2lvbmRpciBhbmQgZmFtaWx5bmFtZS4KKyAgICBIRmlsZS5Xcml0ZXIgd3JpdGVyID0gU3RvcmVGaWxlLmdldFdyaXRlcih0aGlzLmZzLAorICAgICAgbmV3IFBhdGgobmV3IFBhdGgodGhpcy50ZXN0RGlyLCAicmVnaW9ubmFtZSIpLCAiZmFtaWx5bmFtZSIpLAorICAgICAgMiAqIDEwMjQsIG51bGwsIG51bGwsIGZhbHNlKTsKKyAgICB3cml0ZVN0b3JlRmlsZSh3cml0ZXIpOworICAgIGNoZWNrSGFsZkhGaWxlKG5ldyBTdG9yZUZpbGUodGhpcy5mcywgd3JpdGVyLmdldFBhdGgoKSkpOworICB9CisKKyAgLyoKKyAgICogV3JpdGVzIEhTdG9yZUtleSBhbmQgSW1tdXRhYmxlQnl0ZXMgZGF0YSB0byBwYXNzZWQgd3JpdGVyIGFuZAorICAgKiB0aGVuIGNsb3NlcyBpdC4KKyAgICogQHBhcmFtIHdyaXRlcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgd3JpdGVTdG9yZUZpbGUoZmluYWwgSEZpbGUuV3JpdGVyIHdyaXRlcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGJ5dGUgW10gY29sdW1uID0KKyAgICAgIEJ5dGVzLnRvQnl0ZXMoZ2V0TmFtZSgpICsgS2V5VmFsdWUuQ09MVU1OX0ZBTUlMWV9ERUxJTUlURVIgKyBnZXROYW1lKCkpOworICAgIHRyeSB7CisgICAgICBmb3IgKGNoYXIgZCA9IEZJUlNUX0NIQVI7IGQgPD0gTEFTVF9DSEFSOyBkKyspIHsKKyAgICAgICAgZm9yIChjaGFyIGUgPSBGSVJTVF9DSEFSOyBlIDw9IExBU1RfQ0hBUjsgZSsrKSB7CisgICAgICAgICAgYnl0ZVtdIGIgPSBuZXcgYnl0ZVtdIHsgKGJ5dGUpIGQsIChieXRlKSBlIH07CisgICAgICAgICAgd3JpdGVyLmFwcGVuZChuZXcgS2V5VmFsdWUoYiwgY29sdW1uLCBub3csIGIpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZmluYWxseSB7CisgICAgICB3cml0ZXIuY2xvc2UoKTsKKyAgICB9CisgIH0KKyAgCisgIC8qKgorICAgKiBUZXN0IHRoYXQgb3VyIG1lY2hhbmlzbSBvZiB3cml0aW5nIHN0b3JlIGZpbGVzIGluIG9uZSByZWdpb24gdG8gcmVmZXJlbmNlCisgICAqIHN0b3JlIGZpbGVzIGluIG90aGVyIHJlZ2lvbnMgd29ya3MuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RSZWZlcmVuY2UoKQorICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBhdGggc3RvcmVkaXIgPSBuZXcgUGF0aChuZXcgUGF0aCh0aGlzLnRlc3REaXIsICJyZWdpb25uYW1lIiksICJmYW1pbHluYW1lIik7CisgICAgUGF0aCBkaXIgPSBuZXcgUGF0aChzdG9yZWRpciwgIjEyMzQ1Njc4OTAiKTsKKyAgICAvLyBNYWtlIGEgc3RvcmUgZmlsZSBhbmQgd3JpdGUgZGF0YSB0byBpdC4KKyAgICBIRmlsZS5Xcml0ZXIgd3JpdGVyID0gU3RvcmVGaWxlLmdldFdyaXRlcih0aGlzLmZzLCBkaXIsIDggKiAxMDI0LCBudWxsLAorICAgICAgbnVsbCwgZmFsc2UpOworICAgIHdyaXRlU3RvcmVGaWxlKHdyaXRlcik7CisgICAgU3RvcmVGaWxlIGhzZiA9IG5ldyBTdG9yZUZpbGUodGhpcy5mcywgd3JpdGVyLmdldFBhdGgoKSk7CisgICAgSEZpbGUuUmVhZGVyIHJlYWRlciA9IGhzZi5nZXRSZWFkZXIoKTsKKyAgICAvLyBTcGxpdCBvbiBhIHJvdywgbm90IGluIG1pZGRsZSBvZiByb3cuICBNaWRrZXkgcmV0dXJuZWQgYnkgcmVhZGVyCisgICAgLy8gbWF5IGJlIGluIG1pZGRsZSBvZiByb3cuICBDcmVhdGUgbmV3IG9uZSB3aXRoIGVtcHR5IGNvbHVtbiBhbmQKKyAgICAvLyB0aW1lc3RhbXAuCisgICAgSFN0b3JlS2V5IGhzayA9IEhTdG9yZUtleS5jcmVhdGUocmVhZGVyLm1pZGtleSgpKTsKKyAgICBieXRlIFtdIG1pZGtleSA9IGhzay5nZXRSb3coKTsKKyAgICBoc2sgPSBIU3RvcmVLZXkuY3JlYXRlKHJlYWRlci5nZXRMYXN0S2V5KCkpOworICAgIGJ5dGUgW10gZmluYWxLZXkgPSBoc2suZ2V0Um93KCk7CisgICAgLy8gTWFrZSBhIHJlZmVyZW5jZQorICAgIFBhdGggcmVmUGF0aCA9IFN0b3JlRmlsZS5zcGxpdChmcywgZGlyLCBoc2YsIHJlYWRlci5taWRrZXkoKSwgUmFuZ2UudG9wKTsKKyAgICBTdG9yZUZpbGUgcmVmSHNmID0gbmV3IFN0b3JlRmlsZSh0aGlzLmZzLCByZWZQYXRoKTsKKyAgICAvLyBOb3cgY29uZmlybSB0aGF0IEkgY2FuIHJlYWQgZnJvbSB0aGUgcmVmZXJlbmNlIGFuZCB0aGF0IGl0IG9ubHkgZ2V0cworICAgIC8vIGtleXMgZnJvbSB0b3AgaGFsZiBvZiB0aGUgZmlsZS4KKyAgICBIRmlsZVNjYW5uZXIgcyA9IHJlZkhzZi5nZXRSZWFkZXIoKS5nZXRTY2FubmVyKCk7CisgICAgZm9yKGJvb2xlYW4gZmlyc3QgPSB0cnVlOyAoIXMuaXNTZWVrZWQoKSAmJiBzLnNlZWtUbygpKSB8fCBzLm5leHQoKTspIHsKKyAgICAgIEJ5dGVCdWZmZXIgYmIgPSBzLmdldEtleSgpOworICAgICAgaHNrID0gSFN0b3JlS2V5LmNyZWF0ZShiYi5hcnJheSgpLCBiYi5hcnJheU9mZnNldCgpLCBiYi5saW1pdCgpKTsKKyAgICAgIGlmIChmaXJzdCkgeworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhoc2suZ2V0Um93KCksIG1pZGtleSkpOworICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhoc2suZ2V0Um93KCksIGZpbmFsS2V5KSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgY2hlY2tIYWxmSEZpbGUoZmluYWwgU3RvcmVGaWxlIGYpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZSBbXSBtaWRrZXkgPSBmLmdldFJlYWRlcigpLm1pZGtleSgpOworICAgIC8vIENyZWF0ZSB0b3Agc3BsaXQuCisgICAgUGF0aCB0b3BEaXIgPSBTdG9yZS5nZXRTdG9yZUhvbWVkaXIodGhpcy50ZXN0RGlyLCAxLAorICAgICAgQnl0ZXMudG9CeXRlcyhmLmdldFBhdGgoKS5nZXRQYXJlbnQoKS5nZXROYW1lKCkpKTsKKyAgICBpZiAodGhpcy5mcy5leGlzdHModG9wRGlyKSkgeworICAgICAgdGhpcy5mcy5kZWxldGUodG9wRGlyLCB0cnVlKTsKKyAgICB9CisgICAgUGF0aCB0b3BQYXRoID0gU3RvcmVGaWxlLnNwbGl0KHRoaXMuZnMsIHRvcERpciwgZiwgbWlka2V5LCBSYW5nZS50b3ApOworICAgIC8vIENyZWF0ZSBib3R0b20gc3BsaXQuCisgICAgUGF0aCBib3R0b21EaXIgPSBTdG9yZS5nZXRTdG9yZUhvbWVkaXIodGhpcy50ZXN0RGlyLCAyLAorICAgICAgQnl0ZXMudG9CeXRlcyhmLmdldFBhdGgoKS5nZXRQYXJlbnQoKS5nZXROYW1lKCkpKTsKKyAgICBpZiAodGhpcy5mcy5leGlzdHMoYm90dG9tRGlyKSkgeworICAgICAgdGhpcy5mcy5kZWxldGUoYm90dG9tRGlyLCB0cnVlKTsKKyAgICB9CisgICAgUGF0aCBib3R0b21QYXRoID0gU3RvcmVGaWxlLnNwbGl0KHRoaXMuZnMsIGJvdHRvbURpciwKKyAgICAgIGYsIG1pZGtleSwgUmFuZ2UuYm90dG9tKTsKKyAgICAvLyBNYWtlIHJlYWRlcnMgb24gdG9wIGFuZCBib3R0b20uCisgICAgSEZpbGUuUmVhZGVyIHRvcCA9IG5ldyBTdG9yZUZpbGUodGhpcy5mcywgdG9wUGF0aCkuZ2V0UmVhZGVyKCk7CisgICAgSEZpbGUuUmVhZGVyIGJvdHRvbSA9IG5ldyBTdG9yZUZpbGUodGhpcy5mcywgYm90dG9tUGF0aCkuZ2V0UmVhZGVyKCk7CisgICAgQnl0ZUJ1ZmZlciBwcmV2aW91cyA9IG51bGw7CisgICAgTE9HLmluZm8oIk1pZGtleTogIiArIEJ5dGVzLnRvU3RyaW5nKG1pZGtleSkpOworICAgIGJ5dGUgW10gbWlka2V5Qnl0ZXMgPSBuZXcgSFN0b3JlS2V5KG1pZGtleSkuZ2V0Qnl0ZXMoKTsKKyAgICBCeXRlQnVmZmVyIGJiTWlka2V5Qnl0ZXMgPSBCeXRlQnVmZmVyLndyYXAobWlka2V5Qnl0ZXMpOworICAgIHRyeSB7CisgICAgICAvLyBOb3cgbWFrZSB0d28gSGFsZk1hcEZpbGVzIGFuZCBhc3NlcnQgdGhleSBjYW4gcmVhZCB0aGUgZnVsbCBiYWNraW5nCisgICAgICAvLyBmaWxlLCBvbmUgZnJvbSB0aGUgdG9wIGFuZCB0aGUgb3RoZXIgZnJvbSB0aGUgYm90dG9tLgorICAgICAgLy8gVGVzdCBib3R0b20gaGFsZiBmaXJzdC4KKyAgICAgIC8vIE5vdyB0ZXN0IHJlYWRpbmcgZnJvbSB0aGUgdG9wLgorICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisgICAgICBCeXRlQnVmZmVyIGtleSA9IG51bGw7CisgICAgICBIRmlsZVNjYW5uZXIgdG9wU2Nhbm5lciA9IHRvcC5nZXRTY2FubmVyKCk7CisgICAgICB3aGlsZSAoKCF0b3BTY2FubmVyLmlzU2Vla2VkKCkgJiYgdG9wU2Nhbm5lci5zZWVrVG8oKSkgfHwKKyAgICAgICAgICAodG9wU2Nhbm5lci5pc1NlZWtlZCgpICYmIHRvcFNjYW5uZXIubmV4dCgpKSkgeworICAgICAgICBrZXkgPSB0b3BTY2FubmVyLmdldEtleSgpOworICAgICAgICAKKyAgICAgICAgYXNzZXJ0VHJ1ZSh0b3BTY2FubmVyLmdldFJlYWRlcigpLmdldENvbXBhcmF0b3IoKS5jb21wYXJlKGtleS5hcnJheSgpLAorICAgICAgICAgIGtleS5hcnJheU9mZnNldCgpLCBrZXkubGltaXQoKSwgbWlka2V5Qnl0ZXMsIDAsIG1pZGtleUJ5dGVzLmxlbmd0aCkgPj0gMCk7CisgICAgICAgIGlmIChmaXJzdCkgeworICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgTE9HLmluZm8oIkZpcnN0IGluIHRvcDogIiArIEJ5dGVzLnRvU3RyaW5nKEJ5dGVzLnRvQnl0ZXMoa2V5KSkpOworICAgICAgICB9CisgICAgICB9CisgICAgICBMT0cuaW5mbygiTGFzdCBpbiB0b3A6ICIgKyBCeXRlcy50b1N0cmluZyhCeXRlcy50b0J5dGVzKGtleSkpKTsKKyAgICAgIAorICAgICAgZmlyc3QgPSB0cnVlOworICAgICAgSEZpbGVTY2FubmVyIGJvdHRvbVNjYW5uZXIgPSBib3R0b20uZ2V0U2Nhbm5lcigpOworICAgICAgd2hpbGUgKCghYm90dG9tU2Nhbm5lci5pc1NlZWtlZCgpICYmIGJvdHRvbVNjYW5uZXIuc2Vla1RvKCkpIHx8CisgICAgICAgICAgYm90dG9tU2Nhbm5lci5uZXh0KCkpIHsKKyAgICAgICAgcHJldmlvdXMgPSBib3R0b21TY2FubmVyLmdldEtleSgpOworICAgICAgICBrZXkgPSBib3R0b21TY2FubmVyLmdldEtleSgpOworICAgICAgICBpZiAoZmlyc3QpIHsKKyAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgIExPRy5pbmZvKCJGaXJzdCBpbiBib3R0b206ICIgKworICAgICAgICAgICAgQnl0ZXMudG9TdHJpbmcoQnl0ZXMudG9CeXRlcyhwcmV2aW91cykpKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRUcnVlKGtleS5jb21wYXJlVG8oYmJNaWRrZXlCeXRlcykgPCAwKTsKKyAgICAgIH0KKyAgICAgIGlmIChwcmV2aW91cyAhPSBudWxsKSB7CisgICAgICAgIExPRy5pbmZvKCJMYXN0IGluIGJvdHRvbTogIiArIEJ5dGVzLnRvU3RyaW5nKEJ5dGVzLnRvQnl0ZXMocHJldmlvdXMpKSk7CisgICAgICB9CisgICAgICAvLyBSZW1vdmUgcmVmZXJlbmNlcy4KKyAgICAgIHRoaXMuZnMuZGVsZXRlKHRvcFBhdGgsIGZhbHNlKTsKKyAgICAgIHRoaXMuZnMuZGVsZXRlKGJvdHRvbVBhdGgsIGZhbHNlKTsKKworICAgICAgLy8gTmV4dCB0ZXN0IHVzaW5nIGEgbWlka2V5IHRoYXQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGZpbGUuCisgICAgICAvLyBGaXJzdCwgZG8gYSBrZXkgdGhhdCBpcyA8IHRoYW4gZmlyc3Qga2V5LiBFbnN1cmUgc3BsaXRzIGJlaGF2ZQorICAgICAgLy8gcHJvcGVybHkuCisgICAgICBieXRlIFtdIGJhZG1pZGtleSA9IEJ5dGVzLnRvQnl0ZXMoIiAgLiIpOworICAgICAgdG9wUGF0aCA9IFN0b3JlRmlsZS5zcGxpdCh0aGlzLmZzLCB0b3BEaXIsIGYsIGJhZG1pZGtleSwgUmFuZ2UudG9wKTsKKyAgICAgIGJvdHRvbVBhdGggPSBTdG9yZUZpbGUuc3BsaXQodGhpcy5mcywgYm90dG9tRGlyLCBmLCBiYWRtaWRrZXksCisgICAgICAgIFJhbmdlLmJvdHRvbSk7CisgICAgICB0b3AgPSBuZXcgU3RvcmVGaWxlKHRoaXMuZnMsIHRvcFBhdGgpLmdldFJlYWRlcigpOworICAgICAgYm90dG9tID0gbmV3IFN0b3JlRmlsZSh0aGlzLmZzLCBib3R0b21QYXRoKS5nZXRSZWFkZXIoKTsKKyAgICAgIGJvdHRvbVNjYW5uZXIgPSBib3R0b20uZ2V0U2Nhbm5lcigpOworICAgICAgaW50IGNvdW50ID0gMDsKKyAgICAgIHdoaWxlICgoIWJvdHRvbVNjYW5uZXIuaXNTZWVrZWQoKSAmJiBib3R0b21TY2FubmVyLnNlZWtUbygpKSB8fAorICAgICAgICAgIGJvdHRvbVNjYW5uZXIubmV4dCgpKSB7CisgICAgICAgIGNvdW50Kys7CisgICAgICB9CisgICAgICAvLyBXaGVuIGJhZGtleSBpcyA8IHRoYW4gdGhlIGJvdHRvbSwgc2hvdWxkIHJldHVybiBubyB2YWx1ZXMuCisgICAgICBhc3NlcnRUcnVlKGNvdW50ID09IDApOworICAgICAgLy8gTm93IHJlYWQgZnJvbSB0aGUgdG9wLgorICAgICAgZmlyc3QgPSB0cnVlOworICAgICAgdG9wU2Nhbm5lciA9IHRvcC5nZXRTY2FubmVyKCk7CisgICAgICB3aGlsZSAoKCF0b3BTY2FubmVyLmlzU2Vla2VkKCkgJiYgdG9wU2Nhbm5lci5zZWVrVG8oKSkgfHwKKyAgICAgICAgICB0b3BTY2FubmVyLm5leHQoKSkgeworICAgICAgICBrZXkgPSB0b3BTY2FubmVyLmdldEtleSgpOworICAgICAgICBhc3NlcnRUcnVlKHRvcFNjYW5uZXIuZ2V0UmVhZGVyKCkuZ2V0Q29tcGFyYXRvcigpLmNvbXBhcmUoa2V5LmFycmF5KCksCisgICAgICAgICAga2V5LmFycmF5T2Zmc2V0KCksIGtleS5saW1pdCgpLCBiYWRtaWRrZXksIDAsIGJhZG1pZGtleS5sZW5ndGgpID49IDApOworICAgICAgICBpZiAoZmlyc3QpIHsKKyAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgSFN0b3JlS2V5IGtleWhzayA9IEhTdG9yZUtleS5jcmVhdGUoa2V5KTsKKyAgICAgICAgICBMT0cuaW5mbygiRmlyc3QgdG9wIHdoZW4ga2V5IDwgYm90dG9tOiAiICsga2V5aHNrKTsKKyAgICAgICAgICBTdHJpbmcgdG1wID0gQnl0ZXMudG9TdHJpbmcoa2V5aHNrLmdldFJvdygpKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRtcC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHRtcC5jaGFyQXQoaSkgPT0gJ2EnKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIEhTdG9yZUtleSBrZXloc2sgPSBIU3RvcmVLZXkuY3JlYXRlKGtleSk7CisgICAgICBMT0cuaW5mbygiTGFzdCB0b3Agd2hlbiBrZXkgPCBib3R0b206ICIgKyBrZXloc2spOworICAgICAgU3RyaW5nIHRtcCA9IEJ5dGVzLnRvU3RyaW5nKGtleWhzay5nZXRSb3coKSk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRtcC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgIGFzc2VydFRydWUodG1wLmNoYXJBdChpKSA9PSAneicpOworICAgICAgfQorICAgICAgLy8gUmVtb3ZlIHJlZmVyZW5jZXMuCisgICAgICB0aGlzLmZzLmRlbGV0ZSh0b3BQYXRoLCBmYWxzZSk7CisgICAgICB0aGlzLmZzLmRlbGV0ZShib3R0b21QYXRoLCBmYWxzZSk7CisKKyAgICAgIC8vIFRlc3Qgd2hlbiBiYWRrZXkgaXMgPiB0aGFuIGxhc3Qga2V5IGluIGZpbGUgKCd8fCcgPiAnenonKS4KKyAgICAgIGJhZG1pZGtleSA9IEJ5dGVzLnRvQnl0ZXMoInx8fCIpOworICAgICAgdG9wUGF0aCA9IFN0b3JlRmlsZS5zcGxpdCh0aGlzLmZzLCB0b3BEaXIsIGYsIGJhZG1pZGtleSwgUmFuZ2UudG9wKTsKKyAgICAgIGJvdHRvbVBhdGggPSBTdG9yZUZpbGUuc3BsaXQodGhpcy5mcywgYm90dG9tRGlyLCBmLCBiYWRtaWRrZXksCisgICAgICAgIFJhbmdlLmJvdHRvbSk7CisgICAgICB0b3AgPSBuZXcgU3RvcmVGaWxlKHRoaXMuZnMsIHRvcFBhdGgpLmdldFJlYWRlcigpOworICAgICAgYm90dG9tID0gbmV3IFN0b3JlRmlsZSh0aGlzLmZzLCBib3R0b21QYXRoKS5nZXRSZWFkZXIoKTsKKyAgICAgIGZpcnN0ID0gdHJ1ZTsKKyAgICAgIGJvdHRvbVNjYW5uZXIgPSBib3R0b20uZ2V0U2Nhbm5lcigpOworICAgICAgd2hpbGUgKCghYm90dG9tU2Nhbm5lci5pc1NlZWtlZCgpICYmIGJvdHRvbVNjYW5uZXIuc2Vla1RvKCkpIHx8CisgICAgICAgICAgYm90dG9tU2Nhbm5lci5uZXh0KCkpIHsKKyAgICAgICAga2V5ID0gYm90dG9tU2Nhbm5lci5nZXRLZXkoKTsKKyAgICAgICAgaWYgKGZpcnN0KSB7CisgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICBrZXloc2sgPSBIU3RvcmVLZXkuY3JlYXRlKGtleSk7CisgICAgICAgICAgTE9HLmluZm8oIkZpcnN0IGJvdHRvbSB3aGVuIGtleSA+IHRvcDogIiArIGtleWhzayk7CisgICAgICAgICAgdG1wID0gQnl0ZXMudG9TdHJpbmcoa2V5aHNrLmdldFJvdygpKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRtcC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgICAgICBhc3NlcnRUcnVlKHRtcC5jaGFyQXQoaSkgPT0gJ2EnKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGtleWhzayA9IEhTdG9yZUtleS5jcmVhdGUoa2V5KTsKKyAgICAgIExPRy5pbmZvKCJMYXN0IGJvdHRvbSB3aGVuIGtleSA+IHRvcDogIiArIGtleWhzayk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRtcC5sZW5ndGgoKTsgaSsrKSB7CisgICAgICAgIGFzc2VydFRydWUoQnl0ZXMudG9TdHJpbmcoa2V5aHNrLmdldFJvdygpKS5jaGFyQXQoaSkgPT0gJ3onKTsKKyAgICAgIH0KKyAgICAgIGNvdW50ID0gMDsKKyAgICAgIHRvcFNjYW5uZXIgPSB0b3AuZ2V0U2Nhbm5lcigpOworICAgICAgd2hpbGUgKCghdG9wU2Nhbm5lci5pc1NlZWtlZCgpICYmIHRvcFNjYW5uZXIuc2Vla1RvKCkpIHx8CisgICAgICAgICAgKHRvcFNjYW5uZXIuaXNTZWVrZWQoKSAmJiB0b3BTY2FubmVyLm5leHQoKSkpIHsKKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0KKyAgICAgIC8vIFdoZW4gYmFka2V5IGlzIDwgdGhhbiB0aGUgYm90dG9tLCBzaG91bGQgcmV0dXJuIG5vIHZhbHVlcy4KKyAgICAgIGFzc2VydFRydWUoY291bnQgPT0gMCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmICh0b3AgIT0gbnVsbCkgeworICAgICAgICB0b3AuY2xvc2UoKTsKKyAgICAgIH0KKyAgICAgIGlmIChib3R0b20gIT0gbnVsbCkgeworICAgICAgICBib3R0b20uY2xvc2UoKTsKKyAgICAgIH0KKyAgICAgIGZzLmRlbGV0ZShmLmdldFBhdGgoKSwgdHJ1ZSk7CisgICAgfQorICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvcmVnaW9uc2VydmVyL1Rlc3RUaW1lc3RhbXAuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0VGltZXN0YW1wLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRkYTU3YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci9UZXN0VGltZXN0YW1wLmphdmEKQEAgLTAsMCArMSw4NSBAQAorLyoqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5UaW1lc3RhbXBUZXN0QmFzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFRlc3RzIHVzZXIgc3BlY2lmaWFibGUgdGltZSBzdGFtcHMgcHV0dGluZywgZ2V0dGluZyBhbmQgc2Nhbm5pbmcuICBBbHNvCisgKiB0ZXN0cyBzYW1lIGluIHByZXNlbmNlIG9mIGRlbGV0ZXMuICBUZXN0IGNvcmVzIGFyZSB3cml0dGVuIHNvIGNhbiBiZQorICogcnVuIGFnYWluc3QgYW4gSFJlZ2lvbiBhbmQgYWdhaW5zdCBhbiBIVGFibGU6IGkuZS4gYm90aCBsb2NhbCBhbmQgcmVtb3RlLgorICovCitwdWJsaWMgY2xhc3MgVGVzdFRpbWVzdGFtcCBleHRlbmRzIEhCYXNlQ2x1c3RlclRlc3RDYXNlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIExPRyA9CisgICAgTG9nRmFjdG9yeS5nZXRMb2coVGVzdFRpbWVzdGFtcC5jbGFzcy5nZXROYW1lKCkpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT0xVTU5fTkFNRSA9ICJjb250ZW50czoiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdIENPTFVNTiA9IEJ5dGVzLnRvQnl0ZXMoQ09MVU1OX05BTUUpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVkVSU0lPTlMgPSAzOworICAKKyAgLyoqCisgICAqIFRlc3QgdGhhdCBkZWxldGUgd29ya3MgYWNjb3JkaW5nIHRvIGRlc2NyaXB0aW9uIGluIDxhCisgICAqIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSEFET09QLTE3ODQiPmhhZG9vcC0xNzg0PC9hPi4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdERlbGV0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmluYWwgSFJlZ2lvbiByID0gY3JlYXRlUmVnaW9uKCk7CisgICAgdHJ5IHsKKyAgICAgIGZpbmFsIEhSZWdpb25JbmNvbW1vbiByZWdpb24gPSBuZXcgSFJlZ2lvbkluY29tbW9uKHIpOworICAgICAgVGltZXN0YW1wVGVzdEJhc2UuZG9UZXN0RGVsZXRlKHJlZ2lvbiwgcmVnaW9uKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgci5jbG9zZSgpOworICAgICAgci5nZXRMb2coKS5jbG9zZUFuZERlbGV0ZSgpOworICAgIH0KKyAgICBMT0cuaW5mbygidGVzdERlbGV0ZSgpIGZpbmlzaGVkIik7ICAgIAorICB9CisKKyAgLyoqCisgICAqIFRlc3Qgc2Nhbm5pbmcgYWdhaW5zdCBkaWZmZXJlbnQgdGltZXN0YW1wcy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFRpbWVzdGFtcFNjYW5uaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBIUmVnaW9uIHIgPSBjcmVhdGVSZWdpb24oKTsKKyAgICB0cnkgeworICAgICAgZmluYWwgSFJlZ2lvbkluY29tbW9uIHJlZ2lvbiA9IG5ldyBIUmVnaW9uSW5jb21tb24ocik7CisgICAgICBUaW1lc3RhbXBUZXN0QmFzZS5kb1Rlc3RUaW1lc3RhbXBTY2FubmluZyhyZWdpb24sIHJlZ2lvbik7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHIuY2xvc2UoKTsKKyAgICAgIHIuZ2V0TG9nKCkuY2xvc2VBbmREZWxldGUoKTsKKyAgICB9CisgICAgTE9HLmluZm8oInRlc3RUaW1lc3RhbXBTY2FubmluZygpIGZpbmlzaGVkIik7CisgIH0KKworICBwcml2YXRlIEhSZWdpb24gY3JlYXRlUmVnaW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IGNyZWF0ZVRhYmxlRGVzY3JpcHRvcihnZXROYW1lKCkpOworICAgIGh0ZC5hZGRGYW1pbHkobmV3IEhDb2x1bW5EZXNjcmlwdG9yKENPTFVNTiwgVkVSU0lPTlMsCisgICAgICBIQ29sdW1uRGVzY3JpcHRvci5ERUZBVUxUX0NPTVBSRVNTSU9OLCBmYWxzZSwgZmFsc2UsCisgICAgICBJbnRlZ2VyLk1BWF9WQUxVRSwgSENvbnN0YW50cy5GT1JFVkVSLCBmYWxzZSkpOworICAgIHJldHVybiBjcmVhdGVOZXdIUmVnaW9uKGh0ZCwgbnVsbCwgbnVsbCk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9EaXNhYmxlZFRlc3RITG9nUmVjb3ZlcnkuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL0Rpc2FibGVkVGVzdEhMb2dSZWNvdmVyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwZDViMjcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9EaXNhYmxlZFRlc3RITG9nUmVjb3ZlcnkuamF2YQpAQCAtMCwwICsxLDI3OSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTeXN0ZW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuTG9jYWxIQmFzZUNsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuU2Nhbm5lcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQudHJhbnNhY3Rpb25hbC5Db21taXRVbnN1Y2Nlc3NmdWxFeGNlcHRpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWwuVHJhbnNhY3Rpb25NYW5hZ2VyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC50cmFuc2FjdGlvbmFsLlRyYW5zYWN0aW9uU3RhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LnRyYW5zYWN0aW9uYWwuVHJhbnNhY3Rpb25hbFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkJhdGNoVXBkYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlwYy5UcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uU2VydmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXM7CisKK3B1YmxpYyBjbGFzcyBEaXNhYmxlZFRlc3RITG9nUmVjb3ZlcnkgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKERpc2FibGVkVGVzdEhMb2dSZWNvdmVyeS5jbGFzcyk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBQkxFX05BTUUgPSAidGFibGUxIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gRkFNSUxZID0gQnl0ZXMudG9CeXRlcygiZmFtaWx5OiIpOworICBzdGF0aWMgZmluYWwgYnl0ZVtdIENPTF9BID0gQnl0ZXMudG9CeXRlcygiZmFtaWx5OmEiKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gUk9XMSA9IEJ5dGVzLnRvQnl0ZXMoInJvdzEiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFJPVzIgPSBCeXRlcy50b0J5dGVzKCJyb3cyIik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBST1czID0gQnl0ZXMudG9CeXRlcygicm93MyIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVE9UQUxfVkFMVUUgPSAxMDsKKworICBwcml2YXRlIEhCYXNlQWRtaW4gYWRtaW47CisgIHByaXZhdGUgVHJhbnNhY3Rpb25NYW5hZ2VyIHRyYW5zYWN0aW9uTWFuYWdlcjsKKyAgcHJpdmF0ZSBUcmFuc2FjdGlvbmFsVGFibGUgdGFibGU7CisKKyAgLyoqIGNvbnN0cnVjdG9yICovCisgIHB1YmxpYyBEaXNhYmxlZFRlc3RITG9nUmVjb3ZlcnkoKSB7CisgICAgc3VwZXIoMiwgZmFsc2UpOworCisgICAgY29uZi5zZXQoSENvbnN0YW50cy5SRUdJT05fU0VSVkVSX0NMQVNTLCBUcmFuc2FjdGlvbmFsUmVnaW9uSW50ZXJmYWNlLmNsYXNzCisgICAgICAgIC5nZXROYW1lKCkpOworICAgIGNvbmYuc2V0KEhDb25zdGFudHMuUkVHSU9OX1NFUlZFUl9JTVBMLCBUcmFuc2FjdGlvbmFsUmVnaW9uU2VydmVyLmNsYXNzCisgICAgICAgIC5nZXROYW1lKCkpOworCisgICAgLy8gU2V0IGZsdXNoIHBhcmFtcyBzbyB3ZSBkb24ndCBnZXQgYW55CisgICAgLy8gRklYTUUgKGRlZmF1bHRzIGFyZSBwcm9iYWJseSBmaW5lKQorCisgICAgLy8gQ29waWVkIGZyb20gVGVzdFJlZ2lvblNlcnZlckV4aXQKKyAgICBjb25mLnNldEludCgiaXBjLmNsaWVudC5jb25uZWN0Lm1heC5yZXRyaWVzIiwgNSk7IC8vIHJlZHVjZSBpcGMgcmV0cmllcworICAgIGNvbmYuc2V0SW50KCJpcGMuY2xpZW50LnRpbWVvdXQiLCAxMDAwMCk7IC8vIGFuZCBpcGMgdGltZW91dAorICAgIGNvbmYuc2V0SW50KCJoYmFzZS5jbGllbnQucGF1c2UiLCAxMDAwMCk7IC8vIGluY3JlYXNlIGNsaWVudCB0aW1lb3V0CisgICAgY29uZi5zZXRJbnQoImhiYXNlLmNsaWVudC5yZXRyaWVzLm51bWJlciIsIDEwKTsgLy8gaW5jcmVhc2UgSEJhc2UgcmV0cmllcworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZVN5c3RlbS5nZXRMb2NhbChjb25mKS5kZWxldGUobmV3IFBhdGgoY29uZi5nZXQoSENvbnN0YW50cy5IQkFTRV9ESVIpKSwgdHJ1ZSk7CisgICAgc3VwZXIuc2V0VXAoKTsKKworICAgIEhUYWJsZURlc2NyaXB0b3IgZGVzYyA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKFRBQkxFX05BTUUpOworICAgIGRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihGQU1JTFkpKTsKKyAgICBhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICAgIGFkbWluLmNyZWF0ZVRhYmxlKGRlc2MpOworICAgIHRhYmxlID0gbmV3IFRyYW5zYWN0aW9uYWxUYWJsZShjb25mLCBkZXNjLmdldE5hbWUoKSk7CisKKyAgICB0cmFuc2FjdGlvbk1hbmFnZXIgPSBuZXcgVHJhbnNhY3Rpb25NYW5hZ2VyKGNvbmYpOworICAgIHdyaXRlSW5pdGFsUm93cygpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlSW5pdGFsUm93cygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzEpOworICAgIHVwZGF0ZS5wdXQoQ09MX0EsIEJ5dGVzLnRvQnl0ZXMoVE9UQUxfVkFMVUUpKTsKKyAgICB0YWJsZS5jb21taXQodXBkYXRlKTsKKyAgICB1cGRhdGUgPSBuZXcgQmF0Y2hVcGRhdGUoUk9XMik7CisgICAgdXBkYXRlLnB1dChDT0xfQSwgQnl0ZXMudG9CeXRlcygwKSk7CisgICAgdGFibGUuY29tbWl0KHVwZGF0ZSk7CisgICAgdXBkYXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzMpOworICAgIHVwZGF0ZS5wdXQoQ09MX0EsIEJ5dGVzLnRvQnl0ZXMoMCkpOworICAgIHRhYmxlLmNvbW1pdCh1cGRhdGUpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFdpdGhvdXRGbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgd3JpdGVJbml0YWxSb3dzKCk7CisgICAgVHJhbnNhY3Rpb25TdGF0ZSBzdGF0ZTEgPSBtYWtlVHJhbnNhY3Rpb24oZmFsc2UpOworICAgIHRyYW5zYWN0aW9uTWFuYWdlci50cnlDb21taXQoc3RhdGUxKTsKKyAgICBzdG9wT3JBYm9ydFJlZ2lvblNlcnZlcih0cnVlKTsKKworICAgIFRocmVhZCB0ID0gc3RhcnRWZXJpZmljYXRpb25UaHJlYWQoMSk7CisgICAgdC5zdGFydCgpOworICAgIHRocmVhZER1bXBpbmdKb2luKHQpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFdpdGhGbHVzaEJlZm9yZUNvbW1pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiwKKyAgICAgIENvbW1pdFVuc3VjY2Vzc2Z1bEV4Y2VwdGlvbiB7CisgICAgd3JpdGVJbml0YWxSb3dzKCk7CisgICAgVHJhbnNhY3Rpb25TdGF0ZSBzdGF0ZTEgPSBtYWtlVHJhbnNhY3Rpb24oZmFsc2UpOworICAgIGZsdXNoUmVnaW9uU2VydmVyKCk7CisgICAgdHJhbnNhY3Rpb25NYW5hZ2VyLnRyeUNvbW1pdChzdGF0ZTEpOworICAgIHN0b3BPckFib3J0UmVnaW9uU2VydmVyKHRydWUpOworCisgICAgVGhyZWFkIHQgPSBzdGFydFZlcmlmaWNhdGlvblRocmVhZCgxKTsKKyAgICB0LnN0YXJ0KCk7CisgICAgdGhyZWFkRHVtcGluZ0pvaW4odCk7CisgIH0KKworICAvLyBGSVhNRSwgVE9ETworICAvLyBwdWJsaWMgdm9pZCB0ZXN0V2l0aEZsdXNoQmV0d2VlblRyYW5zYWN0aW9uV3JpdGVzKCkgeworICAvLyBmYWlsKCk7CisgIC8vIH0KKworICBwcml2YXRlIHZvaWQgZmx1c2hSZWdpb25TZXJ2ZXIoKSB7CisgICAgTGlzdDxMb2NhbEhCYXNlQ2x1c3Rlci5SZWdpb25TZXJ2ZXJUaHJlYWQ+IHJlZ2lvblRocmVhZHMgPSBjbHVzdGVyCisgICAgICAgIC5nZXRSZWdpb25UaHJlYWRzKCk7CisKKyAgICBIUmVnaW9uIHJlZ2lvbiA9IG51bGw7CisgICAgaW50IHNlcnZlciA9IC0xOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVnaW9uVGhyZWFkcy5zaXplKCkgJiYgc2VydmVyID09IC0xOyBpKyspIHsKKyAgICAgIEhSZWdpb25TZXJ2ZXIgcyA9IHJlZ2lvblRocmVhZHMuZ2V0KGkpLmdldFJlZ2lvblNlcnZlcigpOworICAgICAgQ29sbGVjdGlvbjxIUmVnaW9uPiByZWdpb25zID0gcy5nZXRPbmxpbmVSZWdpb25zKCk7CisgICAgICBmb3IgKEhSZWdpb24gciA6IHJlZ2lvbnMpIHsKKyAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhyLmdldFRhYmxlRGVzYygpLmdldE5hbWUoKSwgQnl0ZXMudG9CeXRlcyhUQUJMRV9OQU1FKSkpIHsKKyAgICAgICAgICBzZXJ2ZXIgPSBpOworICAgICAgICAgIHJlZ2lvbiA9IHI7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHNlcnZlciA9PSAtMSkgeworICAgICAgTE9HLmZhdGFsKCJjb3VsZCBub3QgZmluZCByZWdpb24gc2VydmVyIHNlcnZpbmcgdGFibGUgcmVnaW9uIik7CisgICAgICBmYWlsKCk7CisgICAgfQorICAgICgoVHJhbnNhY3Rpb25hbFJlZ2lvblNlcnZlcikgcmVnaW9uVGhyZWFkcy5nZXQoc2VydmVyKS5nZXRSZWdpb25TZXJ2ZXIoKSkKKyAgICAgICAgLmdldEZsdXNoUmVxdWVzdGVyKCkucmVxdWVzdChyZWdpb24pOworICB9CisKKyAgLyoqCisgICAqIFN0b3AgdGhlIHJlZ2lvbiBzZXJ2ZXIgc2VydmluZyBUQUJMRV9OQU1FLgorICAgKiAKKyAgICogQHBhcmFtIGFib3J0IHNldCB0byB0cnVlIGlmIHJlZ2lvbiBzZXJ2ZXIgc2hvdWxkIGJlIGFib3J0ZWQsIGlmIGZhbHNlIGl0IGlzCisgICAqIGp1c3Qgc2h1dCBkb3duLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHN0b3BPckFib3J0UmVnaW9uU2VydmVyKGZpbmFsIGJvb2xlYW4gYWJvcnQpIHsKKyAgICBMaXN0PExvY2FsSEJhc2VDbHVzdGVyLlJlZ2lvblNlcnZlclRocmVhZD4gcmVnaW9uVGhyZWFkcyA9IGNsdXN0ZXIKKyAgICAgICAgLmdldFJlZ2lvblRocmVhZHMoKTsKKworICAgIGludCBzZXJ2ZXIgPSAtMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZ2lvblRocmVhZHMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIEhSZWdpb25TZXJ2ZXIgcyA9IHJlZ2lvblRocmVhZHMuZ2V0KGkpLmdldFJlZ2lvblNlcnZlcigpOworICAgICAgQ29sbGVjdGlvbjxIUmVnaW9uPiByZWdpb25zID0gcy5nZXRPbmxpbmVSZWdpb25zKCk7CisgICAgICBMT0cuaW5mbygic2VydmVyOiAiICsgcmVnaW9uVGhyZWFkcy5nZXQoaSkuZ2V0TmFtZSgpKTsKKyAgICAgIGZvciAoSFJlZ2lvbiByIDogcmVnaW9ucykgeworICAgICAgICBMT0cuaW5mbygicmVnaW9uOiAiICsgci5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCkpOworICAgICAgICBpZiAoQnl0ZXMuZXF1YWxzKHIuZ2V0VGFibGVEZXNjKCkuZ2V0TmFtZSgpLCBCeXRlcy50b0J5dGVzKFRBQkxFX05BTUUpKSkgeworICAgICAgICAgIHNlcnZlciA9IGk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHNlcnZlciA9PSAtMSkgeworICAgICAgTE9HLmZhdGFsKCJjb3VsZCBub3QgZmluZCByZWdpb24gc2VydmVyIHNlcnZpbmcgdGFibGUgcmVnaW9uIik7CisgICAgICBmYWlsKCk7CisgICAgfQorICAgIGlmIChhYm9ydCkgeworICAgICAgdGhpcy5jbHVzdGVyLmFib3J0UmVnaW9uU2VydmVyKHNlcnZlcik7CisKKyAgICB9IGVsc2UgeworICAgICAgdGhpcy5jbHVzdGVyLnN0b3BSZWdpb25TZXJ2ZXIoc2VydmVyLCBmYWxzZSk7CisgICAgfQorICAgIExPRy5pbmZvKHRoaXMuY2x1c3Rlci53YWl0T25SZWdpb25TZXJ2ZXIoc2VydmVyKSArICIgaGFzIGJlZW4gIgorICAgICAgICArIChhYm9ydCA/ICJhYm9ydGVkIiA6ICJzaHV0IGRvd24iKSk7CisgIH0KKworICBwcm90ZWN0ZWQgdm9pZCB2ZXJpZnkoZmluYWwgaW50IG51bVJ1bnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gUmVhZHMKKyAgICBpbnQgcm93MSA9IEJ5dGVzLnRvSW50KHRhYmxlLmdldChST1cxLCBDT0xfQSkuZ2V0VmFsdWUoKSk7CisgICAgaW50IHJvdzIgPSBCeXRlcy50b0ludCh0YWJsZS5nZXQoUk9XMiwgQ09MX0EpLmdldFZhbHVlKCkpOworICAgIGludCByb3czID0gQnl0ZXMudG9JbnQodGFibGUuZ2V0KFJPVzMsIENPTF9BKS5nZXRWYWx1ZSgpKTsKKworICAgIGFzc2VydEVxdWFscyhUT1RBTF9WQUxVRSAtIDIgKiBudW1SdW5zLCByb3cxKTsKKyAgICBhc3NlcnRFcXVhbHMobnVtUnVucywgcm93Mik7CisgICAgYXNzZXJ0RXF1YWxzKG51bVJ1bnMsIHJvdzMpOworICB9CisKKyAgLy8gTW92ZSAyIG91dCBvZiBST1cxIGFuZCAxIGludG8gUk9XMiBhbmQgMSBpbnRvIFJPVzMKKyAgcHJpdmF0ZSBUcmFuc2FjdGlvblN0YXRlIG1ha2VUcmFuc2FjdGlvbihmaW5hbCBib29sZWFuIGZsdXNoTWlkV2F5KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBUcmFuc2FjdGlvblN0YXRlIHRyYW5zYWN0aW9uU3RhdGUgPSB0cmFuc2FjdGlvbk1hbmFnZXIuYmVnaW5UcmFuc2FjdGlvbigpOworCisgICAgLy8gUmVhZHMKKyAgICBpbnQgcm93MSA9IEJ5dGVzLnRvSW50KHRhYmxlLmdldCh0cmFuc2FjdGlvblN0YXRlLCBST1cxLCBDT0xfQSkuZ2V0VmFsdWUoKSk7CisgICAgaW50IHJvdzIgPSBCeXRlcy50b0ludCh0YWJsZS5nZXQodHJhbnNhY3Rpb25TdGF0ZSwgUk9XMiwgQ09MX0EpLmdldFZhbHVlKCkpOworICAgIGludCByb3czID0gQnl0ZXMudG9JbnQodGFibGUuZ2V0KHRyYW5zYWN0aW9uU3RhdGUsIFJPVzMsIENPTF9BKS5nZXRWYWx1ZSgpKTsKKworICAgIHJvdzEgLT0gMjsKKyAgICByb3cyICs9IDE7CisgICAgcm93MyArPSAxOworCisgICAgaWYgKGZsdXNoTWlkV2F5KSB7CisgICAgICBmbHVzaFJlZ2lvblNlcnZlcigpOworICAgIH0KKworICAgIC8vIFdyaXRlcworICAgIEJhdGNoVXBkYXRlIHdyaXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzEpOworICAgIHdyaXRlLnB1dChDT0xfQSwgQnl0ZXMudG9CeXRlcyhyb3cxKSk7CisgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHdyaXRlKTsKKworICAgIHdyaXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzIpOworICAgIHdyaXRlLnB1dChDT0xfQSwgQnl0ZXMudG9CeXRlcyhyb3cyKSk7CisgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHdyaXRlKTsKKworICAgIHdyaXRlID0gbmV3IEJhdGNoVXBkYXRlKFJPVzMpOworICAgIHdyaXRlLnB1dChDT0xfQSwgQnl0ZXMudG9CeXRlcyhyb3czKSk7CisgICAgdGFibGUuY29tbWl0KHRyYW5zYWN0aW9uU3RhdGUsIHdyaXRlKTsKKworICAgIHJldHVybiB0cmFuc2FjdGlvblN0YXRlOworICB9CisKKyAgLyoKKyAgICogUnVuIHZlcmlmaWNhdGlvbiBpbiBhIHRocmVhZCBzbyBJIGNhbiBjb25jdXJyZW50bHkgcnVuIGEgdGhyZWFkLWR1bXBlcgorICAgKiB3aGlsZSB3ZSdyZSB3YWl0aW5nIChiZWNhdXNlIGluIHRoaXMgdGVzdCBzb21ldGltZXMgdGhlIG1ldGEgc2Nhbm5lciBsb29rcworICAgKiB0byBiZSBiZSBzdHVjaykuIEBwYXJhbSB0YWJsZU5hbWUgTmFtZSBvZiB0YWJsZSB0byBmaW5kLiBAcGFyYW0gcm93IFJvdyB3ZQorICAgKiBleHBlY3QgdG8gZmluZC4gQHJldHVybiBWZXJpZmljYXRpb24gdGhyZWFkLiBDYWxsZXIgbmVlZHMgdG8gY2FsbHMgc3RhcnQgb24KKyAgICogaXQuCisgICAqLworICBwcml2YXRlIFRocmVhZCBzdGFydFZlcmlmaWNhdGlvblRocmVhZChmaW5hbCBpbnQgbnVtUnVucykgeworICAgIFJ1bm5hYmxlIHJ1bm5hYmxlID0gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIC8vIE5vdyB0cnkgdG8gb3BlbiBhIHNjYW5uZXIgb24gdGhlIG1ldGEgdGFibGUuIFNob3VsZCBzdGFsbCB1bnRpbAorICAgICAgICAgIC8vIG1ldGEgc2VydmVyIGNvbWVzIGJhY2sgdXAuCisgICAgICAgICAgSFRhYmxlIHQgPSBuZXcgSFRhYmxlKGNvbmYsIFRBQkxFX05BTUUpOworICAgICAgICAgIFNjYW5uZXIgcyA9IHQuZ2V0U2Nhbm5lcihuZXcgYnl0ZVtdW10geyBDT0xfQSB9LAorICAgICAgICAgICAgICBIQ29uc3RhbnRzLkVNUFRZX1NUQVJUX1JPVyk7CisgICAgICAgICAgcy5jbG9zZSgpOworCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBMT0cuZmF0YWwoImNvdWxkIG5vdCByZS1vcGVuIG1ldGEgdGFibGUgYmVjYXVzZSIsIGUpOworICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgIHZlcmlmeShudW1SdW5zKTsKKyAgICAgICAgICBMT0cuaW5mbygiU3VjY2VzcyEiKTsKKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH07CisgICAgcmV0dXJuIG5ldyBUaHJlYWQocnVubmFibGUpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UZXN0VHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS9yZWdpb25zZXJ2ZXIvdHJhbnNhY3Rpb25hbC9UZXN0VHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTMzZDc3ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3JlZ2lvbnNlcnZlci90cmFuc2FjdGlvbmFsL1Rlc3RUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIuamF2YQpAQCAtMCwwICsxLDMwOCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci50cmFuc2FjdGlvbmFsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZGZzLk1pbmlERlNDbHVzdGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLlBhdGg7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhUYWJsZURlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuaW8uQmF0Y2hVcGRhdGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhMb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlczsKKworLyoqIEpVbml0IHRlc3QgY2FzZSBmb3IgSExvZyAqLworcHVibGljIGNsYXNzIFRlc3RUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIGltcGxlbWVudHMKKyAgICBIQ29uc3RhbnRzIHsKKyAgcHJpdmF0ZSBQYXRoIGRpcjsKKyAgcHJpdmF0ZSBNaW5pREZTQ2x1c3RlciBjbHVzdGVyOworCisgIGZpbmFsIGJ5dGVbXSB0YWJsZU5hbWUgPSBCeXRlcy50b0J5dGVzKCJ0YWJsZW5hbWUiKTsKKyAgZmluYWwgSFRhYmxlRGVzY3JpcHRvciB0YWJsZURlc2MgPSBuZXcgSFRhYmxlRGVzY3JpcHRvcih0YWJsZU5hbWUpOworICBmaW5hbCBIUmVnaW9uSW5mbyByZWdpb25JbmZvID0gbmV3IEhSZWdpb25JbmZvKHRhYmxlRGVzYywKKyAgICAgIEhDb25zdGFudHMuRU1QVFlfU1RBUlRfUk9XLCBIQ29uc3RhbnRzLkVNUFRZX0VORF9ST1cpOworICBmaW5hbCBieXRlW10gcm93MSA9IEJ5dGVzLnRvQnl0ZXMoInJvdzEiKTsKKyAgZmluYWwgYnl0ZVtdIHZhbDEgPSBCeXRlcy50b0J5dGVzKCJ2YWwxIik7CisgIGZpbmFsIGJ5dGVbXSByb3cyID0gQnl0ZXMudG9CeXRlcygicm93MiIpOworICBmaW5hbCBieXRlW10gdmFsMiA9IEJ5dGVzLnRvQnl0ZXMoInZhbDIiKTsKKyAgZmluYWwgYnl0ZVtdIHJvdzMgPSBCeXRlcy50b0J5dGVzKCJyb3czIik7CisgIGZpbmFsIGJ5dGVbXSB2YWwzID0gQnl0ZXMudG9CeXRlcygidmFsMyIpOworICBmaW5hbCBieXRlW10gY29sID0gQnl0ZXMudG9CeXRlcygiY29sOkEiKTsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjbHVzdGVyID0gbmV3IE1pbmlERlNDbHVzdGVyKGNvbmYsIDIsIHRydWUsIChTdHJpbmdbXSkgbnVsbCk7CisgICAgLy8gU2V0IHRoZSBoYmFzZS5yb290ZGlyIHRvIGJlIHRoZSBob21lIGRpcmVjdG9yeSBpbiBtaW5pIGRmcy4KKyAgICB0aGlzLmNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLCB0aGlzLmNsdXN0ZXIuZ2V0RmlsZVN5c3RlbSgpCisgICAgICAgIC5nZXRIb21lRGlyZWN0b3J5KCkudG9TdHJpbmcoKSk7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgICB0aGlzLmRpciA9IG5ldyBQYXRoKCIvaGJhc2UiLCBnZXROYW1lKCkpOworICAgIGlmIChmcy5leGlzdHMoZGlyKSkgeworICAgICAgZnMuZGVsZXRlKGRpciwgdHJ1ZSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaWYgKHRoaXMuZnMuZXhpc3RzKHRoaXMuZGlyKSkgeworICAgICAgdGhpcy5mcy5kZWxldGUodGhpcy5kaXIsIHRydWUpOworICAgIH0KKyAgICBzaHV0ZG93bkRmcyhjbHVzdGVyKTsKKyAgICBzdXBlci50ZWFyRG93bigpOworICB9CisKKyAgLyoqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTaW5nbGVDb21taXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgSExvZyBsb2cgPSBuZXcgSExvZyhmcywgZGlyLCB0aGlzLmNvbmYsIG51bGwpOworICAgIFRyYW5zYWN0aW9uYWxITG9nTWFuYWdlciBsb2dNYW5nYWVyID0gbmV3IFRyYW5zYWN0aW9uYWxITG9nTWFuYWdlcihsb2csIGZzLAorICAgICAgICByZWdpb25JbmZvLCBjb25mKTsKKworICAgIC8vIFdyaXRlIGNvbHVtbnMgbmFtZWQgMSwgMiwgMywgZXRjLiBhbmQgdGhlbiB2YWx1ZXMgb2Ygc2luZ2xlIGJ5dGUKKyAgICAvLyAxLCAyLCAzLi4uCisgICAgbG9uZyB0cmFuc2FjdGlvbklkID0gMTsKKyAgICBsb2dNYW5nYWVyLndyaXRlU3RhcnRUb0xvZyh0cmFuc2FjdGlvbklkKTsKKworICAgIEJhdGNoVXBkYXRlIHVwZGF0ZTEgPSBuZXcgQmF0Y2hVcGRhdGUocm93MSk7CisgICAgdXBkYXRlMS5wdXQoY29sLCB2YWwxKTsKKyAgICBsb2dNYW5nYWVyLndyaXRlVXBkYXRlVG9Mb2codHJhbnNhY3Rpb25JZCwgdXBkYXRlMSk7CisKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUyID0gbmV3IEJhdGNoVXBkYXRlKHJvdzIpOworICAgIHVwZGF0ZTIucHV0KGNvbCwgdmFsMik7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uSWQsIHVwZGF0ZTIpOworCisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlMyA9IG5ldyBCYXRjaFVwZGF0ZShyb3czKTsKKyAgICB1cGRhdGUzLnB1dChjb2wsIHZhbDMpOworICAgIGxvZ01hbmdhZXIud3JpdGVVcGRhdGVUb0xvZyh0cmFuc2FjdGlvbklkLCB1cGRhdGUzKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVDb21taXRUb0xvZyh0cmFuc2FjdGlvbklkKTsKKworICAgIC8vIGxvZy5jb21wbGV0ZUNhY2hlRmx1c2gocmVnaW9uTmFtZSwgdGFibGVOYW1lLCBsb2dTZXFJZCk7CisKKyAgICBsb2cuY2xvc2UoKTsKKyAgICBQYXRoIGZpbGVuYW1lID0gbG9nLmNvbXB1dGVGaWxlbmFtZShsb2cuZ2V0RmlsZW51bSgpKTsKKworICAgIE1hcDxMb25nLCBMaXN0PEJhdGNoVXBkYXRlPj4gY29tbWl0cyA9IGxvZ01hbmdhZXIuZ2V0Q29tbWl0c0Zyb21Mb2coCisgICAgICAgIGZpbGVuYW1lLCAtMSwgbnVsbCk7CisKKyAgICBhc3NlcnRFcXVhbHMoMSwgY29tbWl0cy5zaXplKCkpOworICAgIGFzc2VydFRydWUoY29tbWl0cy5jb250YWluc0tleSh0cmFuc2FjdGlvbklkKSk7CisgICAgYXNzZXJ0RXF1YWxzKDMsIGNvbW1pdHMuZ2V0KHRyYW5zYWN0aW9uSWQpLnNpemUoKSk7CisKKyAgICBMaXN0PEJhdGNoVXBkYXRlPiB1cGRhdGVzID0gY29tbWl0cy5nZXQodHJhbnNhY3Rpb25JZCk7CisKKyAgICB1cGRhdGUxID0gdXBkYXRlcy5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93MSwgdXBkYXRlMS5nZXRSb3coKSkpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHZhbDEsIHVwZGF0ZTEuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0VmFsdWUoKSkpOworCisgICAgdXBkYXRlMiA9IHVwZGF0ZXMuZ2V0KDEpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvdzIsIHVwZGF0ZTIuZ2V0Um93KCkpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyh2YWwyLCB1cGRhdGUyLml0ZXJhdG9yKCkubmV4dCgpLmdldFZhbHVlKCkpKTsKKworICAgIHVwZGF0ZTMgPSB1cGRhdGVzLmdldCgyKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3czLCB1cGRhdGUzLmdldFJvdygpKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHModmFsMywgdXBkYXRlMy5pdGVyYXRvcigpLm5leHQoKS5nZXRWYWx1ZSgpKSk7CisKKyAgfQorICAKKyAgLyoqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RTaW5nbGVBYm9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICBITG9nIGxvZyA9IG5ldyBITG9nKGZzLCBkaXIsIHRoaXMuY29uZiwgbnVsbCk7CisgICAgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyIGxvZ01hbmdhZXIgPSBuZXcgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyKGxvZywgZnMsCisgICAgICAgIHJlZ2lvbkluZm8sIGNvbmYpOworCisgICAgbG9uZyB0cmFuc2FjdGlvbklkID0gMTsKKyAgICBsb2dNYW5nYWVyLndyaXRlU3RhcnRUb0xvZyh0cmFuc2FjdGlvbklkKTsKKworICAgIEJhdGNoVXBkYXRlIHVwZGF0ZTEgPSBuZXcgQmF0Y2hVcGRhdGUocm93MSk7CisgICAgdXBkYXRlMS5wdXQoY29sLCB2YWwxKTsKKyAgICBsb2dNYW5nYWVyLndyaXRlVXBkYXRlVG9Mb2codHJhbnNhY3Rpb25JZCwgdXBkYXRlMSk7CisKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUyID0gbmV3IEJhdGNoVXBkYXRlKHJvdzIpOworICAgIHVwZGF0ZTIucHV0KGNvbCwgdmFsMik7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uSWQsIHVwZGF0ZTIpOworCisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlMyA9IG5ldyBCYXRjaFVwZGF0ZShyb3czKTsKKyAgICB1cGRhdGUzLnB1dChjb2wsIHZhbDMpOworICAgIGxvZ01hbmdhZXIud3JpdGVVcGRhdGVUb0xvZyh0cmFuc2FjdGlvbklkLCB1cGRhdGUzKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVBYm9ydFRvTG9nKHRyYW5zYWN0aW9uSWQpOworCisgICAgLy8gbG9nLmNvbXBsZXRlQ2FjaGVGbHVzaChyZWdpb25OYW1lLCB0YWJsZU5hbWUsIGxvZ1NlcUlkKTsKKworICAgIGxvZy5jbG9zZSgpOworICAgIFBhdGggZmlsZW5hbWUgPSBsb2cuY29tcHV0ZUZpbGVuYW1lKGxvZy5nZXRGaWxlbnVtKCkpOworCisgICAgTWFwPExvbmcsIExpc3Q8QmF0Y2hVcGRhdGU+PiBjb21taXRzID0gbG9nTWFuZ2Flci5nZXRDb21taXRzRnJvbUxvZygKKyAgICAgICAgZmlsZW5hbWUsIC0xLCBudWxsKTsKKworICAgIGFzc2VydEVxdWFscygwLCBjb21taXRzLnNpemUoKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJsaWV2ZWRDb21taXRzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIEhMb2cgbG9nID0gbmV3IEhMb2coZnMsIGRpciwgdGhpcy5jb25mLCBudWxsKTsKKyAgICBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIgbG9nTWFuZ2FlciA9IG5ldyBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIobG9nLCBmcywKKyAgICAgICAgcmVnaW9uSW5mbywgY29uZik7CisKKyAgICBsb25nIHRyYW5zYWN0aW9uMUlkID0gMTsKKyAgICBsb25nIHRyYW5zYWN0aW9uMklkID0gMjsKKyAgICBsb2dNYW5nYWVyLndyaXRlU3RhcnRUb0xvZyh0cmFuc2FjdGlvbjFJZCk7CisKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUxID0gbmV3IEJhdGNoVXBkYXRlKHJvdzEpOworICAgIHVwZGF0ZTEucHV0KGNvbCwgdmFsMSk7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uMUlkLCB1cGRhdGUxKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVTdGFydFRvTG9nKHRyYW5zYWN0aW9uMklkKTsKKyAgICAKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUyID0gbmV3IEJhdGNoVXBkYXRlKHJvdzIpOworICAgIHVwZGF0ZTIucHV0KGNvbCwgdmFsMik7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uMklkLCB1cGRhdGUyKTsKKworICAgIEJhdGNoVXBkYXRlIHVwZGF0ZTMgPSBuZXcgQmF0Y2hVcGRhdGUocm93Myk7CisgICAgdXBkYXRlMy5wdXQoY29sLCB2YWwzKTsKKyAgICBsb2dNYW5nYWVyLndyaXRlVXBkYXRlVG9Mb2codHJhbnNhY3Rpb24xSWQsIHVwZGF0ZTMpOworCisgICAgbG9nTWFuZ2Flci53cml0ZUNvbW1pdFRvTG9nKHRyYW5zYWN0aW9uMklkKTsKKyAgICBsb2dNYW5nYWVyLndyaXRlQ29tbWl0VG9Mb2codHJhbnNhY3Rpb24xSWQpOworCisgICAgLy8gbG9nLmNvbXBsZXRlQ2FjaGVGbHVzaChyZWdpb25OYW1lLCB0YWJsZU5hbWUsIGxvZ1NlcUlkKTsKKworICAgIGxvZy5jbG9zZSgpOworICAgIFBhdGggZmlsZW5hbWUgPSBsb2cuY29tcHV0ZUZpbGVuYW1lKGxvZy5nZXRGaWxlbnVtKCkpOworCisgICAgTWFwPExvbmcsIExpc3Q8QmF0Y2hVcGRhdGU+PiBjb21taXRzID0gbG9nTWFuZ2Flci5nZXRDb21taXRzRnJvbUxvZygKKyAgICAgICAgZmlsZW5hbWUsIC0xLCBudWxsKTsKKworICAgIGFzc2VydEVxdWFscygyLCBjb21taXRzLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIsIGNvbW1pdHMuZ2V0KHRyYW5zYWN0aW9uMUlkKS5zaXplKCkpOworICAgIGFzc2VydEVxdWFscygxLCBjb21taXRzLmdldCh0cmFuc2FjdGlvbjJJZCkuc2l6ZSgpKTsKKyAgfQorICAKKyAgLyoqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHRlc3RJbnRlcmxpZXZlZEFib3J0Q29tbWl0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgIEhMb2cgbG9nID0gbmV3IEhMb2coZnMsIGRpciwgdGhpcy5jb25mLCBudWxsKTsKKyAgICBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIgbG9nTWFuZ2FlciA9IG5ldyBUcmFuc2FjdGlvbmFsSExvZ01hbmFnZXIobG9nLCBmcywKKyAgICAgICAgcmVnaW9uSW5mbywgY29uZik7CisKKyAgICBsb25nIHRyYW5zYWN0aW9uMUlkID0gMTsKKyAgICBsb25nIHRyYW5zYWN0aW9uMklkID0gMjsKKyAgICBsb2dNYW5nYWVyLndyaXRlU3RhcnRUb0xvZyh0cmFuc2FjdGlvbjFJZCk7CisKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUxID0gbmV3IEJhdGNoVXBkYXRlKHJvdzEpOworICAgIHVwZGF0ZTEucHV0KGNvbCwgdmFsMSk7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uMUlkLCB1cGRhdGUxKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVTdGFydFRvTG9nKHRyYW5zYWN0aW9uMklkKTsKKyAgICAKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUyID0gbmV3IEJhdGNoVXBkYXRlKHJvdzIpOworICAgIHVwZGF0ZTIucHV0KGNvbCwgdmFsMik7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uMklkLCB1cGRhdGUyKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVBYm9ydFRvTG9nKHRyYW5zYWN0aW9uMklkKTsKKyAgICAKKyAgICBCYXRjaFVwZGF0ZSB1cGRhdGUzID0gbmV3IEJhdGNoVXBkYXRlKHJvdzMpOworICAgIHVwZGF0ZTMucHV0KGNvbCwgdmFsMyk7CisgICAgbG9nTWFuZ2Flci53cml0ZVVwZGF0ZVRvTG9nKHRyYW5zYWN0aW9uMUlkLCB1cGRhdGUzKTsKKworICAgIGxvZ01hbmdhZXIud3JpdGVDb21taXRUb0xvZyh0cmFuc2FjdGlvbjFJZCk7CisKKyAgICAvLyBsb2cuY29tcGxldGVDYWNoZUZsdXNoKHJlZ2lvbk5hbWUsIHRhYmxlTmFtZSwgbG9nU2VxSWQpOworCisgICAgbG9nLmNsb3NlKCk7CisgICAgUGF0aCBmaWxlbmFtZSA9IGxvZy5jb21wdXRlRmlsZW5hbWUobG9nLmdldEZpbGVudW0oKSk7CisKKyAgICBNYXA8TG9uZywgTGlzdDxCYXRjaFVwZGF0ZT4+IGNvbW1pdHMgPSBsb2dNYW5nYWVyLmdldENvbW1pdHNGcm9tTG9nKAorICAgICAgICBmaWxlbmFtZSwgLTEsIG51bGwpOworCisgICAgYXNzZXJ0RXF1YWxzKDEsIGNvbW1pdHMuc2l6ZSgpKTsKKyAgICBhc3NlcnRFcXVhbHMoMiwgY29tbWl0cy5nZXQodHJhbnNhY3Rpb24xSWQpLnNpemUoKSk7CisgIH0KKyAgCisgIC8qKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0SW50ZXJsaWV2ZWRDb21taXRBYm9ydCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICBITG9nIGxvZyA9IG5ldyBITG9nKGZzLCBkaXIsIHRoaXMuY29uZiwgbnVsbCk7CisgICAgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyIGxvZ01hbmdhZXIgPSBuZXcgVHJhbnNhY3Rpb25hbEhMb2dNYW5hZ2VyKGxvZywgZnMsCisgICAgICAgIHJlZ2lvbkluZm8sIGNvbmYpOworCisgICAgbG9uZyB0cmFuc2FjdGlvbjFJZCA9IDE7CisgICAgbG9uZyB0cmFuc2FjdGlvbjJJZCA9IDI7CisgICAgbG9nTWFuZ2Flci53cml0ZVN0YXJ0VG9Mb2codHJhbnNhY3Rpb24xSWQpOworCisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlMSA9IG5ldyBCYXRjaFVwZGF0ZShyb3cxKTsKKyAgICB1cGRhdGUxLnB1dChjb2wsIHZhbDEpOworICAgIGxvZ01hbmdhZXIud3JpdGVVcGRhdGVUb0xvZyh0cmFuc2FjdGlvbjFJZCwgdXBkYXRlMSk7CisKKyAgICBsb2dNYW5nYWVyLndyaXRlU3RhcnRUb0xvZyh0cmFuc2FjdGlvbjJJZCk7CisgICAgCisgICAgQmF0Y2hVcGRhdGUgdXBkYXRlMiA9IG5ldyBCYXRjaFVwZGF0ZShyb3cyKTsKKyAgICB1cGRhdGUyLnB1dChjb2wsIHZhbDIpOworICAgIGxvZ01hbmdhZXIud3JpdGVVcGRhdGVUb0xvZyh0cmFuc2FjdGlvbjJJZCwgdXBkYXRlMik7CisKKyAgICBsb2dNYW5nYWVyLndyaXRlQ29tbWl0VG9Mb2codHJhbnNhY3Rpb24ySWQpOworICAgIAorICAgIEJhdGNoVXBkYXRlIHVwZGF0ZTMgPSBuZXcgQmF0Y2hVcGRhdGUocm93Myk7CisgICAgdXBkYXRlMy5wdXQoY29sLCB2YWwzKTsKKyAgICBsb2dNYW5nYWVyLndyaXRlVXBkYXRlVG9Mb2codHJhbnNhY3Rpb24xSWQsIHVwZGF0ZTMpOworCisgICAgbG9nTWFuZ2Flci53cml0ZUFib3J0VG9Mb2codHJhbnNhY3Rpb24xSWQpOworCisgICAgLy8gbG9nLmNvbXBsZXRlQ2FjaGVGbHVzaChyZWdpb25OYW1lLCB0YWJsZU5hbWUsIGxvZ1NlcUlkKTsKKworICAgIGxvZy5jbG9zZSgpOworICAgIFBhdGggZmlsZW5hbWUgPSBsb2cuY29tcHV0ZUZpbGVuYW1lKGxvZy5nZXRGaWxlbnVtKCkpOworCisgICAgTWFwPExvbmcsIExpc3Q8QmF0Y2hVcGRhdGU+PiBjb21taXRzID0gbG9nTWFuZ2Flci5nZXRDb21taXRzRnJvbUxvZygKKyAgICAgICAgZmlsZW5hbWUsIC0xLCBudWxsKTsKKworICAgIGFzc2VydEVxdWFscygxLCBjb21taXRzLnNpemUoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDEsIGNvbW1pdHMuZ2V0KHRyYW5zYWN0aW9uMklkKS5zaXplKCkpOworICB9CisgIAorICAvLyBGSVhNRSBDYW5ub3QgZG8gdGhpcyB0ZXN0IHdpdGhvdXQgYSBnbG9iYWwgdHJhbnNhY3RvbiBtYW5hZ2VyCisgIC8vIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nQ29tbWl0KCkgeworICAvLyBmYWlsKCk7CisgIC8vIH0KKworICAvLyBGSVhNRSBDYW5ub3QgZG8gdGhpcyB0ZXN0IHdpdGhvdXQgYSBnbG9iYWwgdHJhbnNhY3RvbiBtYW5hZ2VyCisgIC8vIHB1YmxpYyB2b2lkIHRlc3RNaXNzaW5nQWJvcnQoKSB7CisgIC8vIGZhaWwoKTsKKyAgLy8gfQorCit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS90aHJpZnQvVGVzdFRocmlmdFNlcnZlci5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L1Rlc3RUaHJpZnRTZXJ2ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YzY2MWFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdGhyaWZ0L1Rlc3RUaHJpZnRTZXJ2ZXIuamF2YQpAQCAtMCwwICsxLDM4MCBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOC0yMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0OworCitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlQ2x1c3RlclRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuQmF0Y2hNdXRhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLkNvbHVtbkRlc2NyaXB0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5JbGxlZ2FsQXJndW1lbnQ7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudGhyaWZ0LmdlbmVyYXRlZC5NdXRhdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS50aHJpZnQuZ2VuZXJhdGVkLlRDZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdC5nZW5lcmF0ZWQuVFJvd1Jlc3VsdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLkJ5dGVzOworCisvKioKKyAqIFVuaXQgdGVzdGluZyBmb3IgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlciwgYSBwYXJ0IG9mIHRoZSAKKyAqIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnRocmlmdCBwYWNrYWdlLiAgCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0VGhyaWZ0U2VydmVyIGV4dGVuZHMgSEJhc2VDbHVzdGVyVGVzdENhc2UgeworCisgIC8vIFN0YXRpYyBuYW1lcyBmb3IgdGFibGVzLCBjb2x1bW5zLCByb3dzLCBhbmQgdmFsdWVzCisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB0YWJsZUFuYW1lID0gQnl0ZXMudG9CeXRlcygidGFibGVBIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB0YWJsZUJuYW1lID0gQnl0ZXMudG9CeXRlcygidGFibGVCIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBjb2x1bW5BbmFtZSA9IEJ5dGVzLnRvQnl0ZXMoImNvbHVtbkE6Iik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBjb2x1bW5CbmFtZSA9IEJ5dGVzLnRvQnl0ZXMoImNvbHVtbkI6Iik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBiYWRDb2x1bW5OYW1lID0gQnl0ZXMudG9CeXRlcygiZm9yZ290Q29sb24iKTsKKyAgcHJpdmF0ZSBzdGF0aWMgYnl0ZVtdIHJvd0FuYW1lID0gQnl0ZXMudG9CeXRlcygicm93QSIpOworICBwcml2YXRlIHN0YXRpYyBieXRlW10gcm93Qm5hbWUgPSBCeXRlcy50b0J5dGVzKCJyb3dCIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB2YWx1ZUFuYW1lID0gQnl0ZXMudG9CeXRlcygidmFsdWVBIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB2YWx1ZUJuYW1lID0gQnl0ZXMudG9CeXRlcygidmFsdWVCIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB2YWx1ZUNuYW1lID0gQnl0ZXMudG9CeXRlcygidmFsdWVDIik7CisgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSB2YWx1ZURuYW1lID0gQnl0ZXMudG9CeXRlcygidmFsdWVEIik7CisKKyAgLyoqCisgICAqIFJ1bnMgYWxsIG9mIHRoZSB0ZXN0cyB1bmRlciBhIHNpbmdsZSBKVW5pdCB0ZXN0IG1ldGhvZC4gIFdlIAorICAgKiBjb25zb2xpZGF0ZSBhbGwgdGVzdGluZyB0byBvbmUgbWV0aG9kIGJlY2F1c2UgSEJhc2VDbHVzdGVyVGVzdENhc2UKKyAgICogaXMgcHJvbmUgdG8gT3V0T2ZNZW1vcnlFeGNlcHRpb25zIHdoZW4gdGhlcmUgYXJlIHRocmVlIG9yIG1vcmUgCisgICAqIEpVbml0IHRlc3QgbWV0aG9kcy4KKyAgICogCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0QWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gUnVuIGFsbCB0ZXN0cworICAgIGRvVGVzdFRhYmxlQ3JlYXRlRHJvcCgpOworICAgIGRvVGVzdFRhYmxlTXV0YXRpb25zKCk7CisgICAgZG9UZXN0VGFibGVUaW1lc3RhbXBzQW5kQ29sdW1ucygpOworICAgIGRvVGVzdFRhYmxlU2Nhbm5lcnMoKTsKKyAgfQorCisgIC8qKgorICAgKiBUZXN0cyBmb3IgY3JlYXRpbmcsIGVuYWJsaW5nLCBkaXNhYmxpbmcsIGFuZCBkZWxldGluZyB0YWJsZXMuICBBbHNvIAorICAgKiB0ZXN0cyB0aGF0IGNyZWF0aW5nIGEgdGFibGUgd2l0aCBhbiBpbnZhbGlkIGNvbHVtbiBuYW1lIHlpZWxkcyBhbiAKKyAgICogSWxsZWdhbEFyZ3VtZW50IGV4Y2VwdGlvbi4KKyAgICogCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCBkb1Rlc3RUYWJsZUNyZWF0ZURyb3AoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUaHJpZnRTZXJ2ZXIuSEJhc2VIYW5kbGVyIGhhbmRsZXIgPSBuZXcgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlcigpOworCisgICAgLy8gQ3JlYXRlL2VuYWJsZS9kaXNhYmxlL2RlbGV0ZSB0YWJsZXMsIGVuc3VyZSBtZXRob2RzIGFjdCBjb3JyZWN0bHkKKyAgICBhc3NlcnRFcXVhbHMoaGFuZGxlci5nZXRUYWJsZU5hbWVzKCkuc2l6ZSgpLCAwKTsKKyAgICBoYW5kbGVyLmNyZWF0ZVRhYmxlKHRhYmxlQW5hbWUsIGdldENvbHVtbkRlc2NyaXB0b3JzKCkpOworICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLmdldFRhYmxlTmFtZXMoKS5zaXplKCksIDEpOworICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLmdldENvbHVtbkRlc2NyaXB0b3JzKHRhYmxlQW5hbWUpLnNpemUoKSwgMik7CisgICAgYXNzZXJ0VHJ1ZShoYW5kbGVyLmlzVGFibGVFbmFibGVkKHRhYmxlQW5hbWUpKTsKKyAgICBoYW5kbGVyLmNyZWF0ZVRhYmxlKHRhYmxlQm5hbWUsIG5ldyBBcnJheUxpc3Q8Q29sdW1uRGVzY3JpcHRvcj4oKSk7CisgICAgYXNzZXJ0RXF1YWxzKGhhbmRsZXIuZ2V0VGFibGVOYW1lcygpLnNpemUoKSwgMik7CisgICAgaGFuZGxlci5kaXNhYmxlVGFibGUodGFibGVCbmFtZSk7CisgICAgYXNzZXJ0RmFsc2UoaGFuZGxlci5pc1RhYmxlRW5hYmxlZCh0YWJsZUJuYW1lKSk7CisgICAgaGFuZGxlci5kZWxldGVUYWJsZSh0YWJsZUJuYW1lKTsKKyAgICBhc3NlcnRFcXVhbHMoaGFuZGxlci5nZXRUYWJsZU5hbWVzKCkuc2l6ZSgpLCAxKTsKKyAgICBoYW5kbGVyLmRpc2FibGVUYWJsZSh0YWJsZUFuYW1lKTsKKyAgICBhc3NlcnRGYWxzZShoYW5kbGVyLmlzVGFibGVFbmFibGVkKHRhYmxlQW5hbWUpKTsKKyAgICBoYW5kbGVyLmVuYWJsZVRhYmxlKHRhYmxlQW5hbWUpOworICAgIGFzc2VydFRydWUoaGFuZGxlci5pc1RhYmxlRW5hYmxlZCh0YWJsZUFuYW1lKSk7CisgICAgaGFuZGxlci5kaXNhYmxlVGFibGUodGFibGVBbmFtZSk7CisgICAgaGFuZGxlci5kZWxldGVUYWJsZSh0YWJsZUFuYW1lKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRyeWluZyB0byBjcmVhdGUgYSB0YWJsZSB3aXRoIGEgYmFkIGNvbHVtbiBuYW1lIGNyZWF0ZXMgCisgICAgLy8gYW4gSWxsZWdhbEFyZ3VtZW50IGV4Y2VwdGlvbi4KKyAgICBMaXN0PENvbHVtbkRlc2NyaXB0b3I+IGNEZXNjcmlwdG9ycyA9IG5ldyBBcnJheUxpc3Q8Q29sdW1uRGVzY3JpcHRvcj4oKTsKKyAgICBDb2x1bW5EZXNjcmlwdG9yIGJhZERlc2NyaXB0b3IgPSBuZXcgQ29sdW1uRGVzY3JpcHRvcigpOworICAgIGJhZERlc2NyaXB0b3IubmFtZSA9IGJhZENvbHVtbk5hbWU7CisgICAgY0Rlc2NyaXB0b3JzLmFkZChiYWREZXNjcmlwdG9yKTsKKyAgICBTdHJpbmcgbWVzc2FnZSA9IG51bGw7CisgICAgdHJ5IHsKKyAgICAgIGhhbmRsZXIuY3JlYXRlVGFibGUodGFibGVCbmFtZSwgY0Rlc2NyaXB0b3JzKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnQgaWEpIHsKKyAgICAgIG1lc3NhZ2UgPSBpYS5tZXNzYWdlOworICAgIH0KKyAgICBhc3NlcnRFcXVhbHMoIkZhbWlseSBuYW1lcyBtdXN0IGVuZCBpbiBhIGNvbG9uOiAiICsgbmV3IFN0cmluZyhiYWRDb2x1bW5OYW1lKSwgbWVzc2FnZSk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgYWRkaW5nIGEgc2VyaWVzIG9mIE11dGF0aW9ucyBhbmQgQmF0Y2hNdXRhdGlvbnMsIGluY2x1ZGluZyBhIAorICAgKiBkZWxldGUgbXV0YXRpb24uICBBbHNvIHRlc3RzIGRhdGEgcmV0cmlldmFsLCBhbmQgZ2V0dGluZyBiYWNrIG11bHRpcGxlIAorICAgKiB2ZXJzaW9ucy4gIAorICAgKiAKKyAgICogQHRocm93cyBFeGNlcHRpb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRvVGVzdFRhYmxlTXV0YXRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0dXAKKyAgICBUaHJpZnRTZXJ2ZXIuSEJhc2VIYW5kbGVyIGhhbmRsZXIgPSBuZXcgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlcigpOworICAgIGhhbmRsZXIuY3JlYXRlVGFibGUodGFibGVBbmFtZSwgZ2V0Q29sdW1uRGVzY3JpcHRvcnMoKSk7CisKKyAgICAvLyBBcHBseSBhIGZldyBNdXRhdGlvbnMgdG8gcm93QQorICAgIGhhbmRsZXIubXV0YXRlUm93KHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBnZXRNdXRhdGlvbnMoKSk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCB0aGUgY2hhbmdlcyB3ZXJlIG1hZGUKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyh2YWx1ZUFuYW1lLCBoYW5kbGVyLmdldCh0YWJsZUFuYW1lLCByb3dBbmFtZSwgY29sdW1uQW5hbWUpLmdldCgwKS52YWx1ZSkpOworICAgIFRSb3dSZXN1bHQgcm93UmVzdWx0MSA9IGhhbmRsZXIuZ2V0Um93KHRhYmxlQW5hbWUsIHJvd0FuYW1lKS5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93QW5hbWUsIHJvd1Jlc3VsdDEucm93KSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHModmFsdWVCbmFtZSwgcm93UmVzdWx0MS5jb2x1bW5zLmdldChjb2x1bW5CbmFtZSkudmFsdWUpKTsKKworICAgIC8vIEFwcGx5IGEgZmV3IEJhdGNoTXV0YXRpb25zIGZvciByb3dBIGFuZCByb3dCCisgICAgaGFuZGxlci5tdXRhdGVSb3dzKHRhYmxlQW5hbWUsIGdldEJhdGNoTXV0YXRpb25zKCkpOworCisgICAgLy8gQXNzZXJ0IHRoYXQgY2hhbmdlcyB3ZXJlIG1hZGUgdG8gcm93QQorICAgIGFzc2VydEZhbHNlKGhhbmRsZXIuZ2V0KHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBjb2x1bW5BbmFtZSkuc2l6ZSgpID4gMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHModmFsdWVDbmFtZSwgaGFuZGxlci5nZXQodGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbkJuYW1lKS5nZXQoMCkudmFsdWUpKTsKKyAgICBMaXN0PFRDZWxsPiB2ZXJzaW9ucyA9IGhhbmRsZXIuZ2V0VmVyKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBjb2x1bW5CbmFtZSwgTUFYVkVSU0lPTlMpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHZhbHVlQ25hbWUsIHZlcnNpb25zLmdldCgwKS52YWx1ZSkpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHZhbHVlQm5hbWUsIHZlcnNpb25zLmdldCgxKS52YWx1ZSkpOworCisgICAgLy8gQXNzZXJ0IHRoYXQgY2hhbmdlcyB3ZXJlIG1hZGUgdG8gcm93QgorICAgIFRSb3dSZXN1bHQgcm93UmVzdWx0MiA9IGhhbmRsZXIuZ2V0Um93KHRhYmxlQW5hbWUsIHJvd0JuYW1lKS5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93Qm5hbWUsIHJvd1Jlc3VsdDIucm93KSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHModmFsdWVDbmFtZSwgcm93UmVzdWx0Mi5jb2x1bW5zLmdldChjb2x1bW5BbmFtZSkudmFsdWUpKTsKKwkgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHZhbHVlRG5hbWUsIHJvd1Jlc3VsdDIuY29sdW1ucy5nZXQoY29sdW1uQm5hbWUpLnZhbHVlKSk7CisKKyAgICAvLyBBcHBseSBzb21lIGRlbGV0ZXMKKyAgICBoYW5kbGVyLmRlbGV0ZUFsbCh0YWJsZUFuYW1lLCByb3dBbmFtZSwgY29sdW1uQm5hbWUpOworICAgIGhhbmRsZXIuZGVsZXRlQWxsUm93KHRhYmxlQW5hbWUsIHJvd0JuYW1lKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSBkZWxldGVzIHdlcmUgYXBwbGllZAorICAgIGludCBzaXplID0gaGFuZGxlci5nZXQodGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbkJuYW1lKS5zaXplKCk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIHNpemUpOworICAgIHNpemUgPSBoYW5kbGVyLmdldFJvdyh0YWJsZUFuYW1lLCByb3dCbmFtZSkuc2l6ZSgpOworICAgIGFzc2VydEVxdWFscygwLCBzaXplKTsKKworICAgIC8vIFRlYXJkb3duCisgICAgaGFuZGxlci5kaXNhYmxlVGFibGUodGFibGVBbmFtZSk7CisgICAgaGFuZGxlci5kZWxldGVUYWJsZSh0YWJsZUFuYW1lKTsKKyAgfQorCisgIC8qKgorICAgKiBTaW1pbGFyIHRvIHRlc3RUYWJsZU11dGF0aW9ucygpLCBleGNlcHQgTXV0YXRpb25zIGFyZSBhcHBsaWVkIHdpdGggCisgICAqIHNwZWNpZmljIHRpbWVzdGFtcHMgYW5kIGRhdGEgcmV0cmlldmFsIHVzZXMgdGhlc2UgdGltZXN0YW1wcyB0byAKKyAgICogZXh0cmFjdCBzcGVjaWZpYyB2ZXJzaW9ucyBvZiBkYXRhLiAgCisgICAqIAorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZG9UZXN0VGFibGVUaW1lc3RhbXBzQW5kQ29sdW1ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldHVwCisgICAgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlciBoYW5kbGVyID0gbmV3IFRocmlmdFNlcnZlci5IQmFzZUhhbmRsZXIoKTsKKyAgICBoYW5kbGVyLmNyZWF0ZVRhYmxlKHRhYmxlQW5hbWUsIGdldENvbHVtbkRlc2NyaXB0b3JzKCkpOworCisgICAgLy8gQXBwbHkgdGltZXN0YW1wZWQgTXV0YXRpb25zIHRvIHJvd0EKKyAgICBsb25nIHRpbWUxID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgaGFuZGxlci5tdXRhdGVSb3dUcyh0YWJsZUFuYW1lLCByb3dBbmFtZSwgZ2V0TXV0YXRpb25zKCksIHRpbWUxKTsKKworICAgIC8vIFNsZWVwIHRvIGFzc3VyZSB0aGF0ICd0aW1lMScgYW5kICd0aW1lMicgd2lsbCBiZSBkaWZmZXJlbnQgZXZlbiB3aXRoIGEKKyAgICAvLyBjb2Fyc2UgZ3JhaW5lZCBzeXN0ZW0gdGltZXIuCisgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgLy8gQXBwbHkgdGltZXN0YW1wZWQgQmF0Y2hNdXRhdGlvbnMgZm9yIHJvd0EgYW5kIHJvd0IKKyAgICBsb25nIHRpbWUyID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgaGFuZGxlci5tdXRhdGVSb3dzVHModGFibGVBbmFtZSwgZ2V0QmF0Y2hNdXRhdGlvbnMoKSwgdGltZTIpOworCisgICAgLy8gQXBwbHkgYW4gb3ZlcmxhcHBpbmcgdGltZXN0YW1wZWQgbXV0YXRpb24gdG8gcm93QgorICAgIGhhbmRsZXIubXV0YXRlUm93VHModGFibGVBbmFtZSwgcm93Qm5hbWUsIGdldE11dGF0aW9ucygpLCB0aW1lMik7CisKKyAgICAvLyBBc3NlcnQgdGhhdCB0aGUgdGltZXN0YW1wLXJlbGF0ZWQgbWV0aG9kcyByZXRyaWV2ZSB0aGUgY29ycmVjdCBkYXRhCisgICAgYXNzZXJ0RXF1YWxzKGhhbmRsZXIuZ2V0VmVyVHModGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbkJuYW1lLCB0aW1lMiwKKyAgICAgIE1BWFZFUlNJT05TKS5zaXplKCksIDIpOworICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLmdldFZlclRzKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBjb2x1bW5CbmFtZSwgdGltZTEsCisgICAgICBNQVhWRVJTSU9OUykuc2l6ZSgpLCAxKTsKKworICAgIFRSb3dSZXN1bHQgcm93UmVzdWx0MSA9IGhhbmRsZXIuZ2V0Um93VHModGFibGVBbmFtZSwgcm93QW5hbWUsIHRpbWUxKS5nZXQoMCk7CisgICAgVFJvd1Jlc3VsdCByb3dSZXN1bHQyID0gaGFuZGxlci5nZXRSb3dUcyh0YWJsZUFuYW1lLCByb3dBbmFtZSwgdGltZTIpLmdldCgwKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3dSZXN1bHQxLmNvbHVtbnMuZ2V0KGNvbHVtbkFuYW1lKS52YWx1ZSwgdmFsdWVBbmFtZSkpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvd1Jlc3VsdDEuY29sdW1ucy5nZXQoY29sdW1uQm5hbWUpLnZhbHVlLCB2YWx1ZUJuYW1lKSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93UmVzdWx0Mi5jb2x1bW5zLmdldChjb2x1bW5CbmFtZSkudmFsdWUsIHZhbHVlQ25hbWUpKTsKKyAgICAKKyAgICAvLyBNYXliZSBJJ2QgcmVhZGluZyB0aGlzIHdyb25nIGJ1dCBhdCBsaW5lICMxODcgYWJvdmUsIHRoZSBCYXRjaE11dGF0aW9ucworICAgIC8vIGFyZSBhZGRpbmcgYSBjb2x1bW5BbmFtZSBhdCB0aW1lMiBzbyB0aGUgYmVsb3cgc2hvdWxkIGJlIHRydWUgbm90IGZhbHNlCisgICAgLy8gLS0gU3QuQWNrCisgICAgYXNzZXJ0VHJ1ZShyb3dSZXN1bHQyLmNvbHVtbnMuY29udGFpbnNLZXkoY29sdW1uQW5hbWUpKTsKKyAgICAKKyAgICBMaXN0PGJ5dGVbXT4gY29sdW1ucyA9IG5ldyBBcnJheUxpc3Q8Ynl0ZVtdPigpOworICAgIGNvbHVtbnMuYWRkKGNvbHVtbkJuYW1lKTsKKworICAgIHJvd1Jlc3VsdDEgPSBoYW5kbGVyLmdldFJvd1dpdGhDb2x1bW5zKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBjb2x1bW5zKS5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93UmVzdWx0MS5jb2x1bW5zLmdldChjb2x1bW5CbmFtZSkudmFsdWUsIHZhbHVlQ25hbWUpKTsKKyAgICBhc3NlcnRGYWxzZShyb3dSZXN1bHQxLmNvbHVtbnMuY29udGFpbnNLZXkoY29sdW1uQW5hbWUpKTsKKworICAgIHJvd1Jlc3VsdDEgPSBoYW5kbGVyLmdldFJvd1dpdGhDb2x1bW5zVHModGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbnMsIHRpbWUxKS5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93UmVzdWx0MS5jb2x1bW5zLmdldChjb2x1bW5CbmFtZSkudmFsdWUsIHZhbHVlQm5hbWUpKTsKKyAgICBhc3NlcnRGYWxzZShyb3dSZXN1bHQxLmNvbHVtbnMuY29udGFpbnNLZXkoY29sdW1uQW5hbWUpKTsKKyAgICAKKyAgICAvLyBBcHBseSBzb21lIHRpbWVzdGFtcGVkIGRlbGV0ZXMKKyAgICBoYW5kbGVyLmRlbGV0ZUFsbFRzKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBjb2x1bW5CbmFtZSwgdGltZTEpOworICAgIGhhbmRsZXIuZGVsZXRlQWxsUm93VHModGFibGVBbmFtZSwgcm93Qm5hbWUsIHRpbWUyKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSB0aW1lc3RhbXAtcmVsYXRlZCBtZXRob2RzIHJldHJpZXZlIHRoZSBjb3JyZWN0IGRhdGEKKyAgICBpbnQgc2l6ZSA9IGhhbmRsZXIuZ2V0VmVyVHModGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbkJuYW1lLCB0aW1lMSwgTUFYVkVSU0lPTlMpLnNpemUoKTsKKyAgICBhc3NlcnRGYWxzZShzaXplID4gMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoaGFuZGxlci5nZXQodGFibGVBbmFtZSwgcm93QW5hbWUsIGNvbHVtbkJuYW1lKS5nZXQoMCkudmFsdWUsIHZhbHVlQ25hbWUpKTsKKyAgICBhc3NlcnRGYWxzZShoYW5kbGVyLmdldFJvdyh0YWJsZUFuYW1lLCByb3dCbmFtZSkuc2l6ZSgpID4gMCk7CisKKyAgICAvLyBUZWFyZG93bgorICAgIGhhbmRsZXIuZGlzYWJsZVRhYmxlKHRhYmxlQW5hbWUpOworICAgIGhhbmRsZXIuZGVsZXRlVGFibGUodGFibGVBbmFtZSk7CisgIH0KKworICAvKioKKyAgICogVGVzdHMgdGhlIGZvdXIgZGlmZmVyZW50IHNjYW5uZXItb3BlbmluZyBtZXRob2RzICh3aXRoIGFuZCB3aXRob3V0IAorICAgKiBhIHN0b3Byb3csIHdpdGggYW5kIHdpdGhvdXQgYSB0aW1lc3RhbXApLiAgCisgICAqIAorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZG9UZXN0VGFibGVTY2FubmVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldHVwCisgICAgVGhyaWZ0U2VydmVyLkhCYXNlSGFuZGxlciBoYW5kbGVyID0gbmV3IFRocmlmdFNlcnZlci5IQmFzZUhhbmRsZXIoKTsKKyAgICBoYW5kbGVyLmNyZWF0ZVRhYmxlKHRhYmxlQW5hbWUsIGdldENvbHVtbkRlc2NyaXB0b3JzKCkpOworCisgICAgLy8gQXBwbHkgdGltZXN0YW1wZWQgTXV0YXRpb25zIHRvIHJvd0EKKyAgICBsb25nIHRpbWUxID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgaGFuZGxlci5tdXRhdGVSb3dUcyh0YWJsZUFuYW1lLCByb3dBbmFtZSwgZ2V0TXV0YXRpb25zKCksIHRpbWUxKTsKKworICAgIC8vIFNsZWVwIHRvIGFzc3VyZSB0aGF0ICd0aW1lMScgYW5kICd0aW1lMicgd2lsbCBiZSBkaWZmZXJlbnQgZXZlbiB3aXRoIGEKKyAgICAvLyBjb2Fyc2UgZ3JhaW5lZCBzeXN0ZW0gdGltZXIuCisgICAgVGhyZWFkLnNsZWVwKDEwMDApOworCisgICAgLy8gQXBwbHkgdGltZXN0YW1wZWQgQmF0Y2hNdXRhdGlvbnMgZm9yIHJvd0EgYW5kIHJvd0IKKyAgICBsb25nIHRpbWUyID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgaGFuZGxlci5tdXRhdGVSb3dzVHModGFibGVBbmFtZSwgZ2V0QmF0Y2hNdXRhdGlvbnMoKSwgdGltZTIpOworCisgICAgLy8gVGVzdCBhIHNjYW5uZXIgb24gYWxsIHJvd3MgYW5kIGFsbCBjb2x1bW5zLCBubyB0aW1lc3RhbXAKKyAgICBpbnQgc2Nhbm5lcjEgPSBoYW5kbGVyLnNjYW5uZXJPcGVuKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCBnZXRDb2x1bW5MaXN0KHRydWUsIHRydWUpKTsKKyAgICBUUm93UmVzdWx0IHJvd1Jlc3VsdDFhID0gaGFuZGxlci5zY2FubmVyR2V0KHNjYW5uZXIxKS5nZXQoMCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93UmVzdWx0MWEucm93LCByb3dBbmFtZSkpOworICAgIC8vIFRoaXMgdXNlZCB0byBiZSAnMScuICBJIGRvbid0IGtub3cgd2h5IHdoZW4gd2UgYXJlIGFza2luZyBmb3IgdHdvIGNvbHVtbnMKKyAgICAvLyBhbmQgd2hlbiB0aGUgbXV0YXRpb25zIGFib3ZlIHdvdWxkIHNlZW0gdG8gYWRkIHR3byBjb2x1bW5zIHRvIHRoZSByb3cuCisgICAgLy8gLS0gU3QuQWNrIDA1LzEyLzIwMDkKKyAgICBhc3NlcnRFcXVhbHMocm93UmVzdWx0MWEuY29sdW1ucy5zaXplKCksIDIpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvd1Jlc3VsdDFhLmNvbHVtbnMuZ2V0KGNvbHVtbkJuYW1lKS52YWx1ZSwgdmFsdWVDbmFtZSkpOworICAgIFRSb3dSZXN1bHQgcm93UmVzdWx0MWIgPSBoYW5kbGVyLnNjYW5uZXJHZXQoc2Nhbm5lcjEpLmdldCgwKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3dSZXN1bHQxYi5yb3csIHJvd0JuYW1lKSk7CisgICAgYXNzZXJ0RXF1YWxzKHJvd1Jlc3VsdDFiLmNvbHVtbnMuc2l6ZSgpLCAyKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3dSZXN1bHQxYi5jb2x1bW5zLmdldChjb2x1bW5BbmFtZSkudmFsdWUsIHZhbHVlQ25hbWUpKTsKKyAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhyb3dSZXN1bHQxYi5jb2x1bW5zLmdldChjb2x1bW5CbmFtZSkudmFsdWUsIHZhbHVlRG5hbWUpKTsKKyAgICBjbG9zZVNjYW5uZXIoc2Nhbm5lcjEsIGhhbmRsZXIpOworCisgICAgLy8gVGVzdCBhIHNjYW5uZXIgb24gYWxsIHJvd3MgYW5kIGFsbCBjb2x1bW5zLCB3aXRoIHRpbWVzdGFtcAorICAgIGludCBzY2FubmVyMiA9IGhhbmRsZXIuc2Nhbm5lck9wZW5Ucyh0YWJsZUFuYW1lLCByb3dBbmFtZSwgZ2V0Q29sdW1uTGlzdCh0cnVlLCB0cnVlKSwgdGltZTEpOworICAgIFRSb3dSZXN1bHQgcm93UmVzdWx0MmEgPSBoYW5kbGVyLnNjYW5uZXJHZXQoc2Nhbm5lcjIpLmdldCgwKTsKKyAgICBhc3NlcnRFcXVhbHMocm93UmVzdWx0MmEuY29sdW1ucy5zaXplKCksIDIpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvd1Jlc3VsdDJhLmNvbHVtbnMuZ2V0KGNvbHVtbkFuYW1lKS52YWx1ZSwgdmFsdWVBbmFtZSkpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHJvd1Jlc3VsdDJhLmNvbHVtbnMuZ2V0KGNvbHVtbkJuYW1lKS52YWx1ZSwgdmFsdWVCbmFtZSkpOworICAgIGNsb3NlU2Nhbm5lcihzY2FubmVyMiwgaGFuZGxlcik7CisKKyAgICAvLyBUZXN0IGEgc2Nhbm5lciBvbiB0aGUgZmlyc3Qgcm93IGFuZCBmaXJzdCBjb2x1bW4gb25seSwgbm8gdGltZXN0YW1wCisgICAgaW50IHNjYW5uZXIzID0gaGFuZGxlci5zY2FubmVyT3BlbldpdGhTdG9wKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCByb3dCbmFtZSwgCisgICAgICAgIGdldENvbHVtbkxpc3QodHJ1ZSwgZmFsc2UpKTsKKyAgICBjbG9zZVNjYW5uZXIoc2Nhbm5lcjMsIGhhbmRsZXIpOworCisgICAgLy8gVGVzdCBhIHNjYW5uZXIgb24gdGhlIGZpcnN0IHJvdyBhbmQgc2Vjb25kIGNvbHVtbiBvbmx5LCB3aXRoIHRpbWVzdGFtcAorICAgIGludCBzY2FubmVyNCA9IGhhbmRsZXIuc2Nhbm5lck9wZW5XaXRoU3RvcFRzKHRhYmxlQW5hbWUsIHJvd0FuYW1lLCByb3dCbmFtZSwgCisgICAgICAgIGdldENvbHVtbkxpc3QoZmFsc2UsIHRydWUpLCB0aW1lMSk7CisgICAgVFJvd1Jlc3VsdCByb3dSZXN1bHQ0YSA9IGhhbmRsZXIuc2Nhbm5lckdldChzY2FubmVyNCkuZ2V0KDApOworICAgIGFzc2VydEVxdWFscyhyb3dSZXN1bHQ0YS5jb2x1bW5zLnNpemUoKSwgMSk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocm93UmVzdWx0NGEuY29sdW1ucy5nZXQoY29sdW1uQm5hbWUpLnZhbHVlLCB2YWx1ZUJuYW1lKSk7CisKKyAgICAvLyBUZWFyZG93bgorICAgIGhhbmRsZXIuZGlzYWJsZVRhYmxlKHRhYmxlQW5hbWUpOworICAgIGhhbmRsZXIuZGVsZXRlVGFibGUodGFibGVBbmFtZSk7CisgIH0KKworICAvKioKKyAgICogCisgICAqIEByZXR1cm4gYSBMaXN0IG9mIENvbHVtbkRlc2NyaXB0b3JzIGZvciB1c2UgaW4gY3JlYXRpbmcgYSB0YWJsZS4gIEhhcyBvbmUgCisgICAqIGRlZmF1bHQgQ29sdW1uRGVzY3JpcHRvciBhbmQgb25lIENvbHVtbkRlc2NyaXB0b3Igd2l0aCBmZXdlciB2ZXJzaW9ucworICAgKi8KKyAgcHJpdmF0ZSBMaXN0PENvbHVtbkRlc2NyaXB0b3I+IGdldENvbHVtbkRlc2NyaXB0b3JzKCkgeworICAgIEFycmF5TGlzdDxDb2x1bW5EZXNjcmlwdG9yPiBjRGVzY3JpcHRvcnMgPSBuZXcgQXJyYXlMaXN0PENvbHVtbkRlc2NyaXB0b3I+KCk7CisKKyAgICAvLyBBIGRlZmF1bHQgQ29sdW1uRGVzY3JpcHRvcgorICAgIENvbHVtbkRlc2NyaXB0b3IgY0Rlc2NBID0gbmV3IENvbHVtbkRlc2NyaXB0b3IoKTsKKyAgICBjRGVzY0EubmFtZSA9IGNvbHVtbkFuYW1lOworICAgIGNEZXNjcmlwdG9ycy5hZGQoY0Rlc2NBKTsKKworICAgIC8vIEEgc2xpZ2h0bHkgY3VzdG9taXplZCBDb2x1bW5EZXNjcmlwdG9yIChvbmx5IDIgdmVyc2lvbnMpCisgICAgQ29sdW1uRGVzY3JpcHRvciBjRGVzY0IgPSBuZXcgQ29sdW1uRGVzY3JpcHRvcihjb2x1bW5CbmFtZSwgMiwgIk5PTkUiLCAKKyAgICAgICAgZmFsc2UsIDIxNDc0ODM2NDcsICJOT05FIiwgMCwgMCwgZmFsc2UsIC0xKTsKKyAgICBjRGVzY3JpcHRvcnMuYWRkKGNEZXNjQik7CisKKyAgICByZXR1cm4gY0Rlc2NyaXB0b3JzOworICB9CisKKyAgLyoqCisgICAqIAorICAgKiBAcGFyYW0gaW5jbHVkZUEgd2hldGhlciBvciBub3QgdG8gaW5jbHVkZSBjb2x1bW5BCisgICAqIEBwYXJhbSBpbmNsdWRlQiB3aGV0aGVyIG9yIG5vdCB0byBpbmNsdWRlIGNvbHVtbkIKKyAgICogQHJldHVybiBhIExpc3Qgb2YgY29sdW1uIG5hbWVzIGZvciB1c2UgaW4gcmV0cmlldmluZyBhIHNjYW5uZXIKKyAgICovCisgIHByaXZhdGUgTGlzdDxieXRlW10+IGdldENvbHVtbkxpc3QoYm9vbGVhbiBpbmNsdWRlQSwgYm9vbGVhbiBpbmNsdWRlQikgeworICAgIExpc3Q8Ynl0ZVtdPiBjb2x1bW5MaXN0ID0gbmV3IEFycmF5TGlzdDxieXRlW10+KCk7CisgICAgaWYgKGluY2x1ZGVBKSBjb2x1bW5MaXN0LmFkZChjb2x1bW5BbmFtZSk7CisgICAgaWYgKGluY2x1ZGVCKSBjb2x1bW5MaXN0LmFkZChjb2x1bW5CbmFtZSk7CisgICAgcmV0dXJuIGNvbHVtbkxpc3Q7CisgIH0KKworICAvKioKKyAgICogCisgICAqIEByZXR1cm4gYSBMaXN0IG9mIE11dGF0aW9ucyBmb3IgYSByb3csIHdpdGggY29sdW1uQSBoYXZpbmcgdmFsdWVBIAorICAgKiBhbmQgY29sdW1uQiBoYXZpbmcgdmFsdWVCCisgICAqLworICBwcml2YXRlIExpc3Q8TXV0YXRpb24+IGdldE11dGF0aW9ucygpIHsKKyAgICBMaXN0PE11dGF0aW9uPiBtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgIG11dGF0aW9ucy5hZGQobmV3IE11dGF0aW9uKGZhbHNlLCBjb2x1bW5BbmFtZSwgdmFsdWVBbmFtZSkpOworICAgIG11dGF0aW9ucy5hZGQobmV3IE11dGF0aW9uKGZhbHNlLCBjb2x1bW5CbmFtZSwgdmFsdWVCbmFtZSkpOworICAgIHJldHVybiBtdXRhdGlvbnM7CisgIH0KKworICAvKioKKyAgICogCisgICAqIEByZXR1cm4gYSBMaXN0IG9mIEJhdGNoTXV0YXRpb25zIHdpdGggdGhlIGZvbGxvd2luZyBlZmZlY3RzOgorICAgKiAocm93QSwgY29sdW1uQSk6IGRlbGV0ZQorICAgKiAocm93QSwgY29sdW1uQik6IHBsYWNlIHZhbHVlQworICAgKiAocm93QiwgY29sdW1uQSk6IHBsYWNlIHZhbHVlQworICAgKiAocm93QiwgY29sdW1uQik6IHBsYWNlIHZhbHVlRCAgCisgICAqLworICBwcml2YXRlIExpc3Q8QmF0Y2hNdXRhdGlvbj4gZ2V0QmF0Y2hNdXRhdGlvbnMoKSB7CisgICAgTGlzdDxCYXRjaE11dGF0aW9uPiBiYXRjaE11dGF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8QmF0Y2hNdXRhdGlvbj4oKTsKKyAgICAvLyBNdXRhdGlvbnMgdG8gcm93QQorICAgIExpc3Q8TXV0YXRpb24+IHJvd0FtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgIHJvd0FtdXRhdGlvbnMuYWRkKG5ldyBNdXRhdGlvbih0cnVlLCBjb2x1bW5BbmFtZSwgbnVsbCkpOworICAgIHJvd0FtdXRhdGlvbnMuYWRkKG5ldyBNdXRhdGlvbihmYWxzZSwgY29sdW1uQm5hbWUsIHZhbHVlQ25hbWUpKTsKKyAgICBiYXRjaE11dGF0aW9ucy5hZGQobmV3IEJhdGNoTXV0YXRpb24ocm93QW5hbWUsIHJvd0FtdXRhdGlvbnMpKTsKKyAgICAvLyBNdXRhdGlvbnMgdG8gcm93QgorICAgIExpc3Q8TXV0YXRpb24+IHJvd0JtdXRhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PE11dGF0aW9uPigpOworICAgIHJvd0JtdXRhdGlvbnMuYWRkKG5ldyBNdXRhdGlvbihmYWxzZSwgY29sdW1uQW5hbWUsIHZhbHVlQ25hbWUpKTsKKyAgICByb3dCbXV0YXRpb25zLmFkZChuZXcgTXV0YXRpb24oZmFsc2UsIGNvbHVtbkJuYW1lLCB2YWx1ZURuYW1lKSk7CisgICAgYmF0Y2hNdXRhdGlvbnMuYWRkKG5ldyBCYXRjaE11dGF0aW9uKHJvd0JuYW1lLCByb3dCbXV0YXRpb25zKSk7CisgICAgcmV0dXJuIGJhdGNoTXV0YXRpb25zOworICB9CisKKyAgLyoqCisgICAqIEFzc2VydHMgdGhhdCB0aGUgcGFzc2VkIHNjYW5uZXIgaXMgZXhoYXVzdGVkLCBhbmQgdGhlbiBjbG9zZXMgCisgICAqIHRoZSBzY2FubmVyLgorICAgKiAKKyAgICogQHBhcmFtIHNjYW5uZXJJZCB0aGUgc2Nhbm5lciB0byBjbG9zZQorICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgSEJhc2VIYW5kbGVyIGludGVyZmFjaW5nIHRvIEhCYXNlCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgY2xvc2VTY2FubmVyKGludCBzY2FubmVySWQsIFRocmlmdFNlcnZlci5IQmFzZUhhbmRsZXIgaGFuZGxlcikgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgaGFuZGxlci5zY2FubmVyR2V0KHNjYW5uZXJJZCk7CisgICAgaGFuZGxlci5zY2FubmVyQ2xvc2Uoc2Nhbm5lcklkKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9EaXNhYmxlZFRlc3RNZXRhVXRpbHMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvRGlzYWJsZWRUZXN0TWV0YVV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2JmOGVmYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvRGlzYWJsZWRUZXN0TWV0YVV0aWxzLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWw7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZUNsdXN0ZXJUZXN0Q2FzZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29sdW1uRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk1pbmlIQmFzZUNsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhUYWJsZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSENvbm5lY3Rpb25NYW5hZ2VyOworCisvKioKKyAqIFRlc3QgaXMgZmxha2V5LiAgTmVlZHMgd29yay4gIEZhaWxzIHRvbyBvZnRlbiBvbiBodWRzb24uCisgKi8KK3B1YmxpYyBjbGFzcyBEaXNhYmxlZFRlc3RNZXRhVXRpbHMgZXh0ZW5kcyBIQmFzZUNsdXN0ZXJUZXN0Q2FzZSB7CisgIHB1YmxpYyB2b2lkIHRlc3RDb2x1bW5FZGl0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIEhCYXNlQWRtaW4gYWRtaW4gPSBuZXcgSEJhc2VBZG1pbih0aGlzLmNvbmYpOworICAgIGZpbmFsIFN0cmluZyBvbGRDb2x1bW4gPSAib2xkY29sdW1uOiI7CisgICAgLy8gQWRkIHRocmVlIHRhYmxlcworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIGh0ZCA9IG5ldyBIVGFibGVEZXNjcmlwdG9yKGdldE5hbWUoKSArIGkpOworICAgICAgaHRkLmFkZEZhbWlseShuZXcgSENvbHVtbkRlc2NyaXB0b3Iob2xkQ29sdW1uKSk7CisgICAgICBhZG1pbi5jcmVhdGVUYWJsZShodGQpOworICAgIH0KKyAgICB0aGlzLmNsdXN0ZXIuc2h1dGRvd24oKTsKKyAgICB0aGlzLmNsdXN0ZXIgPSBudWxsOworICAgIE1ldGFVdGlscyB1dGlscyA9IG5ldyBNZXRhVXRpbHModGhpcy5jb25mKTsKKyAgICAvLyBBZGQgYSBuZXcgY29sdW1uIHRvIHRoZSB0aGlyZCB0YWJsZSwgZ2V0TmFtZSgpICsgJzInLCBhbmQgcmVtb3ZlIHRoZSBvbGQuCisgICAgZmluYWwgYnl0ZSBbXSBlZGl0VGFibGUgPSBCeXRlcy50b0J5dGVzKGdldE5hbWUoKSArIDIpOworICAgIGZpbmFsIGJ5dGUgW10gbmV3Q29sdW1uID0gQnl0ZXMudG9CeXRlcygibmV3Y29sdW1uOiIpOworICAgIHV0aWxzLmFkZENvbHVtbihlZGl0VGFibGUsIG5ldyBIQ29sdW1uRGVzY3JpcHRvcihuZXdDb2x1bW4pKTsKKyAgICB1dGlscy5kZWxldGVDb2x1bW4oZWRpdFRhYmxlLCBCeXRlcy50b0J5dGVzKG9sZENvbHVtbikpOworICAgIHV0aWxzLnNodXRkb3duKCk7CisgICAgLy8gRGVsZXRlIGFnYWluIHNvIHdlIGdvIGdldCBpdCBhbGwgZnJlc2guCisgICAgSENvbm5lY3Rpb25NYW5hZ2VyLmRlbGV0ZUNvbm5lY3Rpb25JbmZvKGNvbmYsIGZhbHNlKTsKKyAgICAvLyBOb3cgYXNzZXJ0IGNvbHVtbnMgd2VyZSBhZGRlZCBhbmQgZGVsZXRlZC4KKyAgICB0aGlzLmNsdXN0ZXIgPSBuZXcgTWluaUhCYXNlQ2x1c3Rlcih0aGlzLmNvbmYsIDEpOworICAgIC8vIE5vdyBhc3NlcnQgY29sdW1ucyB3ZXJlIGFkZGVkIGFuZCBkZWxldGVkLgorICAgIEhUYWJsZSB0ID0gbmV3IEhUYWJsZShjb25mLCBlZGl0VGFibGUpOworICAgIEhUYWJsZURlc2NyaXB0b3IgaHRkID0gdC5nZXRUYWJsZURlc2NyaXB0b3IoKTsKKyAgICBIQ29sdW1uRGVzY3JpcHRvciBoY2QgPSBodGQuZ2V0RmFtaWx5KG5ld0NvbHVtbik7CisgICAgYXNzZXJ0VHJ1ZShoY2QgIT0gbnVsbCk7CisgICAgYXNzZXJ0TnVsbChodGQuZ2V0RmFtaWx5KEJ5dGVzLnRvQnl0ZXMob2xkQ29sdW1uKSkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01pZ3JhdGlvblRlc3QuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvTWlncmF0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0ZjQyMDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL01pZ3JhdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDIyOSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwNyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLnppcC5aaXBFbnRyeTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcElucHV0U3RyZWFtOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNEYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRlNEYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmZzLkZpbGVTdGF0dXM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuRmlsZVN5c3RlbTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhCYXNlVGVzdENhc2U7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50czsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLk1pbmlIQmFzZUNsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW47CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhDb25uZWN0aW9uTWFuYWdlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5jbGllbnQuSFRhYmxlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5TY2FubmVyOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLlJvd1Jlc3VsdDsKKworLyoqCisgKiBSdW5zIG1pZ3JhdGlvbiBvZiBmaWxlc3lzdGVtIGZyb20gaGJhc2UgMC54IHRvIDAueAorICovCitwdWJsaWMgY2xhc3MgTWlncmF0aW9uVGVzdCBleHRlbmRzIEhCYXNlVGVzdENhc2UgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2cgTE9HID0gTG9nRmFjdG9yeS5nZXRMb2coTWlncmF0aW9uVGVzdC5jbGFzcyk7CisgIAorICAvLyBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0aGF0IGlzIGluIHRoZSBkYXRhIGZpbGUuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUJMRU5BTUUgPSAiVGVzdFVwZ3JhZGUiOworICAKKyAgLy8gVGhlIHRhYmxlIGhhcyB0d28gY29sdW1ucworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFtdW10gVEFCTEVOQU1FX0NPTFVNTlMgPQorICAgIHtCeXRlcy50b0J5dGVzKCJjb2x1bW5fYToiKSwgQnl0ZXMudG9CeXRlcygiY29sdW1uX2I6Iil9OworCisgIC8vIEV4cGVjdGVkIGNvdW50IG9mIHJvd3MgaW4gbWlncmF0ZWQgdGFibGUuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFWFBFQ1RFRF9DT1VOVCA9IDE3NTc2OworCisgIC8qKgorICAgKiBUZXN0IG1pZ3JhdGlvbi4gVG8gYmUgdXNlZCBpbiBmdXR1cmUgbWlncmF0aW9ucworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIAorICAgKi8KKyAgcHVibGljIHZvaWQgdGVzdFVwZ3JhZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICB9CisgIAorICAvKgorICAgKiBMb2FkIHVwIHRlc3QgZGF0YS4KKyAgICogQHBhcmFtIGRmcworICAgKiBAcGFyYW0gcm9vdERpcgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgbG9hZFRlc3REYXRhKGZpbmFsIEZpbGVTeXN0ZW0gZGZzLCBmaW5hbCBQYXRoIHJvb3REaXIpCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZVN5c3RlbSBsb2NhbGZzID0gRmlsZVN5c3RlbS5nZXRMb2NhbChjb25mKTsKKyAgICAvLyBHZXQgcGF0aCBmb3IgemlwIGZpbGUuICBJZiBydW5uaW5nIHRoaXMgdGVzdCBpbiBlY2xpcHNlLCBkZWZpbmUKKyAgICAvLyB0aGUgc3lzdGVtIHByb3BlcnR5IHNyYy50ZXN0ZGF0YSBmb3IgeW91ciB0ZXN0IHJ1bi4KKyAgICBTdHJpbmcgc3JjVGVzdGRhdGEgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInNyYy50ZXN0ZGF0YSIpOworICAgIGlmIChzcmNUZXN0ZGF0YSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIkRlZmluZSBzcmMudGVzdCBzeXN0ZW0gcHJvcGVydHkiKTsKKyAgICB9CisgICAgUGF0aCBkYXRhID0gbmV3IFBhdGgoc3JjVGVzdGRhdGEsICJIQURPT1AtMjQ3OC10ZXN0ZGF0YS12MC4xLnppcCIpOworICAgIGlmICghbG9jYWxmcy5leGlzdHMoZGF0YSkpIHsKKyAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24oZGF0YS50b1N0cmluZygpKTsKKyAgICB9CisgICAgRlNEYXRhSW5wdXRTdHJlYW0gaHMgPSBsb2NhbGZzLm9wZW4oZGF0YSk7CisgICAgWmlwSW5wdXRTdHJlYW0gemlwID0gbmV3IFppcElucHV0U3RyZWFtKGhzKTsKKyAgICB1bnppcCh6aXAsIGRmcywgcm9vdERpcik7CisgICAgemlwLmNsb3NlKCk7CisgICAgaHMuY2xvc2UoKTsKKyAgfQorCisgIC8qCisgICAqIFZlcmlmeSBjYW4gcmVhZCB0aGUgbWlncmF0ZWQgdGFibGUuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIHByaXZhdGUgdm9pZCB2ZXJpZnkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIERlbGV0ZSBhbnkgY2FjaGVkIGNvbm5lY3Rpb25zLiAgTmVlZCB0byBkbyB0aGlzIGJlY2F1c2UgY29ubmVjdGlvbiB3YXMKKyAgICAvLyBjcmVhdGVkIGVhcmxpZXIgd2hlbiBubyBtYXN0ZXIgd2FzIGFyb3VuZC4gIFRoZSBmYWN0IHRoYXQgdGhlcmUgd2FzIG5vCisgICAgLy8gbWFzdGVyIGdldHMgY2FjaGVkLiAgTmVlZCB0byBkZWxldGUgc28gd2UgZ28gZ2V0IG1hc3RlciBhZnJlc2guCisgICAgSENvbm5lY3Rpb25NYW5hZ2VyLmRlbGV0ZUNvbm5lY3Rpb25JbmZvKGNvbmYsIGZhbHNlKTsKKyAgICAKKyAgICBMT0cuaW5mbygiU3RhcnQgYSBjbHVzdGVyIGFnYWluc3QgbWlncmF0ZWQgRlMiKTsKKyAgICAvLyBVcCBudW1iZXIgb2YgcmV0cmllcy4gIE5lZWRlZCB3aGlsZSBjbHVzdGVyIHN0YXJ0cyB1cC4gSXRzIGJlZW4gc2V0IHRvIDEKKyAgICAvLyBhYm92ZS4KKyAgICBmaW5hbCBpbnQgcmV0cmllcyA9IDU7CisgICAgdGhpcy5jb25mLnNldEludChIQ29uc3RhbnRzLkhCQVNFX0NMSUVOVF9SRVRSSUVTX05VTUJFUl9LRVksIHJldHJpZXMpOworICAgIAorICAgIE1pbmlIQmFzZUNsdXN0ZXIgY2x1c3RlciA9IG5ldyBNaW5pSEJhc2VDbHVzdGVyKHRoaXMuY29uZiwgMSk7CisgICAgdHJ5IHsKKyAgICAgIEhCYXNlQWRtaW4gaGIgPSBuZXcgSEJhc2VBZG1pbih0aGlzLmNvbmYpOworICAgICAgYXNzZXJ0VHJ1ZShoYi5pc01hc3RlclJ1bm5pbmcoKSk7CisgICAgICBIVGFibGVEZXNjcmlwdG9yIFtdIHRhYmxlcyA9IGhiLmxpc3RUYWJsZXMoKTsKKyAgICAgIGJvb2xlYW4gZm91bmRUYWJsZSA9IGZhbHNlOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0YWJsZXMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgaWYgKEJ5dGVzLmVxdWFscyhCeXRlcy50b0J5dGVzKFRBQkxFTkFNRSksIHRhYmxlc1tpXS5nZXROYW1lKCkpKSB7CisgICAgICAgICAgZm91bmRUYWJsZSA9IHRydWU7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGFzc2VydFRydWUoZm91bmRUYWJsZSk7CisgICAgICBMT0cuaW5mbyhUQUJMRU5BTUUgKyAiIGV4aXN0cy4gIE5vdyB3YWl0aW5nIHRpbGwgc3RhcnRjb2RlICIgKworICAgICAgICAiY2hhbmdlcyBiZWZvcmUgb3BlbmluZyBhIHNjYW5uZXIiKTsKKyAgICAgIHdhaXRPblN0YXJ0Q29kZUNoYW5nZShyZXRyaWVzKTsKKyAgICAgIC8vIERlbGV0ZSBhZ2FpbiBzbyB3ZSBnbyBnZXQgaXQgYWxsIGZyZXNoLgorICAgICAgSENvbm5lY3Rpb25NYW5hZ2VyLmRlbGV0ZUNvbm5lY3Rpb25JbmZvKGNvbmYsIGZhbHNlKTsKKyAgICAgIEhUYWJsZSB0ID0gbmV3IEhUYWJsZSh0aGlzLmNvbmYsIFRBQkxFTkFNRSk7CisgICAgICBpbnQgY291bnQgPSAwOworICAgICAgTE9HLmluZm8oIk9QRU5JTkcgU0NBTk5FUiIpOworICAgICAgU2Nhbm5lciBzID0gdC5nZXRTY2FubmVyKFRBQkxFTkFNRV9DT0xVTU5TKTsKKyAgICAgIHRyeSB7CisgICAgICAgIGZvciAoUm93UmVzdWx0IHI6IHMpIHsKKyAgICAgICAgICBpZiAociA9PSBudWxsIHx8IHIuc2l6ZSgpID09IDApIHsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgICBjb3VudCsrOworICAgICAgICAgIGlmIChjb3VudCAlIDEwMDAgPT0gMCAmJiBjb3VudCA+IDApIHsKKyAgICAgICAgICAgIExPRy5pbmZvKCJJdGVyYXRlZCBvdmVyICIgKyBjb3VudCArICIgcm93cy4iKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0RXF1YWxzKEVYUEVDVEVEX0NPVU5ULCBjb3VudCk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzLmNsb3NlKCk7CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIEhDb25uZWN0aW9uTWFuYWdlci5kZWxldGVDb25uZWN0aW9uSW5mbyhjb25mLCBmYWxzZSk7CisgICAgICBjbHVzdGVyLnNodXRkb3duKCk7CisgICAgfQorICB9CisKKyAgLyoKKyAgICogV2FpdCB0aWxsIHRoZSBzdGFydGNvZGUgY2hhbmdlcyBiZWZvcmUgd2UgcHV0IHVwIGEgc2Nhbm5lci4gIE90aGVyd2lzZQorICAgKiB3ZSB0ZW5kIHRvIGhhbmcsIGF0IGxlYXN0IG9uIGh1ZHNvbiBhbmQgSSd2ZSBoYWQgaXQgdGltZSB0byB0aW1lIG9uCisgICAqIG15IGxhcHRvcC4gIFRoZSBoYW5nIGlzIGRvd24gaW4gUlBDIENsaWVudCBkb2luZyBpdHMgY2FsbC4gIEl0CisgICAqIG5ldmVyIHJldHVybnMgdGhvdWdoIHRoZSBzb2NrZXQgaGFzIGEgcmVhZCB0aW1lb3V0IG9mIDYwIHNlY29uZHMgYnkKKyAgICogZGVmYXVsdC4gU3QuQWNrCisgICAqIEBwYXJhbSByZXRyaWVzIEhvdyBtYW55IHJldHJpZXMgdG8gcnVuLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBwcml2YXRlIHZvaWQgd2FpdE9uU3RhcnRDb2RlQ2hhbmdlKGZpbmFsIGludCByZXRyaWVzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEhUYWJsZSBtID0gbmV3IEhUYWJsZSh0aGlzLmNvbmYsIEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKTsKKyAgICAvLyBUaGlzIGlzIHRoZSBzdGFydCBjb2RlIHRoYXQgaXMgaW4gdGhlIG9sZCBkYXRhLgorICAgIGxvbmcgb2xkU3RhcnRDb2RlID0gMTE5OTczNjMzMjA2Mkw7CisgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3Qgcm93IGZvciB0aGUgVGVzdFRhYmxlIHRoYXQgaXMgaW4gdGhlIG9sZCBkYXRhLgorICAgIGJ5dGUgW10gcm93ID0gQnl0ZXMudG9CeXRlcygiVGVzdFVwZ3JhZGUsLDExOTk3MzYzNjI0NjgiKTsKKyAgICBsb25nIHBhdXNlID0gY29uZi5nZXRMb25nKCJoYmFzZS5jbGllbnQucGF1c2UiLCA1ICogMTAwMCk7CisgICAgbG9uZyBzdGFydGNvZGUgPSAtMTsKKyAgICBib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJldHJpZXM7IGkrKykgeworICAgICAgc3RhcnRjb2RlID0gV3JpdGFibGVzLmNlbGxUb0xvbmcobS5nZXQocm93LCBIQ29uc3RhbnRzLkNPTF9TVEFSVENPREUpKTsKKyAgICAgIGlmIChzdGFydGNvZGUgIT0gb2xkU3RhcnRDb2RlKSB7CisgICAgICAgIGNoYW5nZWQgPSB0cnVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmICgoaSArIDEpICE9IHJldHJpZXMpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBUaHJlYWQuc2xlZXAocGF1c2UpOworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgLy8gY29udGludWUKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICAvLyBJZiBhZnRlciBhbGwgYXR0ZW1wdHMgc3RhcnRjb2RlIGhhcyBub3QgY2hhbmdlZCwgZmFpbC4KKyAgICBpZiAoIWNoYW5nZWQpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU3RhcnRjb2RlIGRpZG4ndCBjaGFuZ2UgYWZ0ZXIgIiArIHJldHJpZXMgKworICAgICAgICAiIGF0dGVtcHRzIik7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHVuemlwKFppcElucHV0U3RyZWFtIHppcCwgRmlsZVN5c3RlbSBkZnMsIFBhdGggcm9vdERpcikKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBaaXBFbnRyeSBlID0gbnVsbDsKKyAgICB3aGlsZSAoKGUgPSB6aXAuZ2V0TmV4dEVudHJ5KCkpICE9IG51bGwpICB7CisgICAgICBpZiAoZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICAgIGRmcy5ta2RpcnMobmV3IFBhdGgocm9vdERpciwgZS5nZXROYW1lKCkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEZTRGF0YU91dHB1dFN0cmVhbSBvdXQgPSBkZnMuY3JlYXRlKG5ldyBQYXRoKHJvb3REaXIsIGUuZ2V0TmFtZSgpKSk7CisgICAgICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVs0MDk2XTsKKyAgICAgICAgaW50IGxlbjsKKyAgICAgICAgZG8geworICAgICAgICAgIGxlbiA9IHppcC5yZWFkKGJ1ZmZlcik7CisgICAgICAgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgICAgIG91dC53cml0ZShidWZmZXIsIDAsIGxlbik7CisgICAgICAgICAgfQorICAgICAgICB9IHdoaWxlIChsZW4gPiAwKTsKKyAgICAgICAgb3V0LmNsb3NlKCk7CisgICAgICB9CisgICAgICB6aXAuY2xvc2VFbnRyeSgpOworICAgIH0KKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIGxpc3RQYXRocyhGaWxlU3lzdGVtIGZpbGVzeXN0ZW0sIFBhdGggZGlyLCBpbnQgcm9vdGRpcmxlbmd0aCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlU3RhdHVzW10gc3RhdHMgPSBmaWxlc3lzdGVtLmxpc3RTdGF0dXMoZGlyKTsKKyAgICBpZiAoc3RhdHMgPT0gbnVsbCB8fCBzdGF0cy5sZW5ndGggPT0gMCkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBTdHJpbmcgcGF0aCA9IHN0YXRzW2ldLmdldFBhdGgoKS50b1N0cmluZygpOworICAgICAgaWYgKHN0YXRzW2ldLmlzRGlyKCkpIHsKKyAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJkICIgKyBwYXRoKTsKKyAgICAgICAgbGlzdFBhdGhzKGZpbGVzeXN0ZW0sIHN0YXRzW2ldLmdldFBhdGgoKSwgcm9vdGRpcmxlbmd0aCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oImYgIiArIHBhdGggKyAiIHNpemU9IiArIHN0YXRzW2ldLmdldExlbigpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRTb3J0ZWRNYXBUZXN0LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRTb3J0ZWRNYXBUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5ZGUyOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvU29mdFNvcnRlZE1hcFRlc3QuamF2YQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0VmFsdWVTb3J0ZWRNYXBUZXN0LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1NvZnRWYWx1ZVNvcnRlZE1hcFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2MxNzkyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9Tb2Z0VmFsdWVTb3J0ZWRNYXBUZXN0LmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5Tb3J0ZWRNYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK3B1YmxpYyBjbGFzcyBTb2Z0VmFsdWVTb3J0ZWRNYXBUZXN0IHsKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB0ZXN0TWFwKFNvcnRlZE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiBtYXApIHsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRlc3RpbmcgIiArIG1hcC5nZXRDbGFzcygpKTsKKyAgICBmb3IoaW50IGkgPSAwOyBpIDwgMTAwMDAwMDsgaSsrKSB7CisgICAgICBtYXAucHV0KG5ldyBJbnRlZ2VyKGkpLCBuZXcgSW50ZWdlcihpKSk7CisgICAgfQorICAgIFN5c3RlbS5vdXQucHJpbnRsbihtYXAuc2l6ZSgpKTsKKyAgICBieXRlW10gYmxvY2sgPSBuZXcgYnl0ZVs4NDkqMTAyNCoxMDI0XTsgLy8gMTAgTUIKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4obWFwLnNpemUoKSk7CisgIH0KKyAgCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKKyAgICB0ZXN0TWFwKG5ldyBTb2Z0VmFsdWVTb3J0ZWRNYXA8SW50ZWdlciwgSW50ZWdlcj4oKSk7CisgICAgdGVzdE1hcChuZXcgVHJlZU1hcDxJbnRlZ2VyLCBJbnRlZ2VyPigpKTsgICAgCisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RCYXNlNjQuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdEJhc2U2NC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwMzgyYmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RCYXNlNjQuamF2YQpAQCAtMCwwICsxLDY3IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA3IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKKy8qKgorICogVGVzdCBvcmRlciBwcmVzZXJ2YXRpb24gY2hhcmFjdGVyaXN0aWNzIG9mIG9yZGVyZWQgQmFzZTY0IGRpYWxlY3QKKyAqLworcHVibGljIGNsYXNzIFRlc3RCYXNlNjQgZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIC8vIE5vdGU6IHVyaXMgaXMgc29ydGVkLiBXZSBuZWVkIHRvIHByb3ZlIHRoYXQgdGhlIG9yZGVyZWQgQmFzZTY0CisgIC8vIHByZXNlcnZlcyB0aGF0IG9yZGVyaW5nCisgIHByaXZhdGUgU3RyaW5nW10gdXJpcyA9IHsKKyAgICAgICJkbnM6Ly9kbnMucG93ZXJzZXQuY29tL3d3dy5wb3dlcnNldC5jb20iLAorICAgICAgImRuczp3d3cucG93ZXJzZXQuY29tIiwKKyAgICAgICJmaWxlOi8vL3Vzci9iaW4vamF2YSIsCisgICAgICAiZmlsZW5hbWUiLAorICAgICAgImZ0cDovL29uZS50d28udGhyZWUvaW5kZXguaHRtbCIsCisgICAgICAiaHR0cDovL29uZS50d28udGhyZWUvaW5kZXguaHRtbCIsCisgICAgICAiaHR0cHM6Ly9vbmUudHdvLnRocmVlOjk0NDMvaW5kZXguaHRtbCIsCisgICAgICAicjpkbnM6Ly9jb20ucG93ZXJzZXQuZG5zL3d3dy5wb3dlcnNldC5jb20iLAorICAgICAgInI6ZnRwOi8vdGhyZWUudHdvLm9uZS9pbmRleC5odG1sIiwKKyAgICAgICJyOmh0dHA6Ly90aHJlZS50d28ub25lL2luZGV4Lmh0bWwiLAorICAgICAgInI6aHR0cHM6Ly90aHJlZS50d28ub25lOjk0NDMvaW5kZXguaHRtbCIKKyAgfTsKKworICAvKioKKyAgICogdGhlIHRlc3QKKyAgICogQHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0QmFzZTY0KCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24geworICAgIFRyZWVNYXA8U3RyaW5nLCBTdHJpbmc+IHNvcnRlZCA9IG5ldyBUcmVlTWFwPFN0cmluZywgU3RyaW5nPigpOworICAgIAorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdXJpcy5sZW5ndGg7IGkrKykgeworICAgICAgYnl0ZVtdIGJ5dGVzID0gdXJpc1tpXS5nZXRCeXRlcygiVVRGLTgiKTsKKyAgICAgIHNvcnRlZC5wdXQoQmFzZTY0LmVuY29kZUJ5dGVzKGJ5dGVzLCBCYXNlNjQuT1JERVJFRCksIHVyaXNbaV0pOworICAgIH0KKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKKworICAgIGludCBpID0gMDsKKyAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFN0cmluZz4gZTogc29ydGVkLmVudHJ5U2V0KCkpIHsKKyAgICAgIGFzc2VydFRydWUodXJpc1tpKytdLmNvbXBhcmVUbyhlLmdldFZhbHVlKCkpID09IDApOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9UZXN0Qnl0ZXMuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdEJ5dGVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTkxOWQ1ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdEJ5dGVzLmphdmEKQEAgLTAsMCArMSwxNTMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCitwdWJsaWMgY2xhc3MgVGVzdEJ5dGVzIGV4dGVuZHMgVGVzdENhc2UgeworICBwdWJsaWMgdm9pZCB0ZXN0U3BsaXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBieXRlIFtdIGxvd2VzdCA9IEJ5dGVzLnRvQnl0ZXMoIkFBQSIpOworICAgIGJ5dGUgW10gbWlkZGxlID0gQnl0ZXMudG9CeXRlcygiQ0NDIik7CisgICAgYnl0ZSBbXSBoaWdoZXN0ID0gQnl0ZXMudG9CeXRlcygiRUVFIik7CisgICAgYnl0ZSBbXVtdIHBhcnRzID0gQnl0ZXMuc3BsaXQobG93ZXN0LCBoaWdoZXN0LCAxKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oQnl0ZXMudG9TdHJpbmcocGFydHNbaV0pKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKDMsIHBhcnRzLmxlbmd0aCk7CisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocGFydHNbMV0sIG1pZGRsZSkpOworICAgIC8vIE5vdyBkaXZpZGUgaW50byB0aHJlZSBwYXJ0cy4gIENoYW5nZSBoaWdoZXN0IHNvIHNwbGl0IGlzIGV2ZW4uCisgICAgaGlnaGVzdCA9IEJ5dGVzLnRvQnl0ZXMoIkRERCIpOworICAgIHBhcnRzID0gQnl0ZXMuc3BsaXQobG93ZXN0LCBoaWdoZXN0LCAyKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7CisgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oQnl0ZXMudG9TdHJpbmcocGFydHNbaV0pKTsKKyAgICB9CisgICAgYXNzZXJ0RXF1YWxzKDQsIHBhcnRzLmxlbmd0aCk7CisgICAgLy8gQXNzZXJ0IHRoYXQgM3JkIHBhcnQgaXMgJ0NDQycuCisgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMocGFydHNbMl0sIG1pZGRsZSkpOworICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFNwbGl0MigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE1vcmUgc3BsaXQgdGVzdHMuCisgICAgYnl0ZSBbXSBsb3dlc3QgPSBCeXRlcy50b0J5dGVzKCJodHRwOi8vQSIpOworICAgIGJ5dGUgW10gaGlnaGVzdCA9IEJ5dGVzLnRvQnl0ZXMoImh0dHA6Ly96Iik7CisgICAgYnl0ZSBbXSBtaWRkbGUgPSBCeXRlcy50b0J5dGVzKCJodHRwOi8vXSIpOworICAgIGJ5dGUgW11bXSBwYXJ0cyA9IEJ5dGVzLnNwbGl0KGxvd2VzdCwgaGlnaGVzdCwgMSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykgeworICAgICAgU3lzdGVtLm91dC5wcmludGxuKEJ5dGVzLnRvU3RyaW5nKHBhcnRzW2ldKSk7CisgICAgfQorICAgIGFzc2VydEVxdWFscygzLCBwYXJ0cy5sZW5ndGgpOworICAgIGFzc2VydFRydWUoQnl0ZXMuZXF1YWxzKHBhcnRzWzFdLCBtaWRkbGUpKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHRlc3RUb0xvbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBsb25nIFtdIGxvbmdzID0gey0xbCwgMTIzbCwgMTIyMjMyMzIzMjMybH07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsb25ncy5sZW5ndGg7IGkrKykgeworICAgICAgYnl0ZSBbXSBiID0gQnl0ZXMudG9CeXRlcyhsb25nc1tpXSk7CisgICAgICBhc3NlcnRFcXVhbHMobG9uZ3NbaV0sIEJ5dGVzLnRvTG9uZyhiKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRvRmxvYXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmbG9hdCBbXSBmbG9hdHMgPSB7LTFmLCAxMjMuMTIzZiwgRmxvYXQuTUFYX1ZBTFVFfTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZsb2F0cy5sZW5ndGg7IGkrKykgeworICAgICAgYnl0ZSBbXSBiID0gQnl0ZXMudG9CeXRlcyhmbG9hdHNbaV0pOworICAgICAgYXNzZXJ0RXF1YWxzKGZsb2F0c1tpXSwgQnl0ZXMudG9GbG9hdChiKSk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgdGVzdFRvRG91YmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZG91YmxlIFtdIGRvdWJsZXMgPSB7RG91YmxlLk1JTl9WQUxVRSwgRG91YmxlLk1BWF9WQUxVRX07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkb3VibGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBieXRlIFtdIGIgPSBCeXRlcy50b0J5dGVzKGRvdWJsZXNbaV0pOworICAgICAgYXNzZXJ0RXF1YWxzKGRvdWJsZXNbaV0sIEJ5dGVzLnRvRG91YmxlKGIpKTsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCB0ZXN0QmluYXJ5U2VhcmNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZSBbXVtdIGFyciA9IHsKKyAgICAgICAgezF9LAorICAgICAgICB7M30sCisgICAgICAgIHs1fSwKKyAgICAgICAgezd9LAorICAgICAgICB7OX0sCisgICAgICAgIHsxMX0sCisgICAgICAgIHsxM30sCisgICAgICAgIHsxNX0sCisgICAgfTsKKyAgICBieXRlIFtdIGtleTEgPSB7MywxfTsKKyAgICBieXRlIFtdIGtleTIgPSB7NCw5fTsKKyAgICBieXRlIFtdIGtleTJfMiA9IHs0fTsKKyAgICBieXRlIFtdIGtleTMgPSB7NSwxMX07CisgICAgCisgICAgYXNzZXJ0RXF1YWxzKDEsIEJ5dGVzLmJpbmFyeVNlYXJjaChhcnIsIGtleTEsIDAsIDEsCisgICAgICBCeXRlcy5CWVRFU19SQVdDT01QQVJBVE9SKSk7CisgICAgYXNzZXJ0RXF1YWxzKDAsIEJ5dGVzLmJpbmFyeVNlYXJjaChhcnIsIGtleTEsIDEsIDEsCisgICAgICBCeXRlcy5CWVRFU19SQVdDT01QQVJBVE9SKSk7CisgICAgYXNzZXJ0RXF1YWxzKC0oMisxKSwgQXJyYXlzLmJpbmFyeVNlYXJjaChhcnIsIGtleTJfMiwKKyAgICAgIEJ5dGVzLkJZVEVTX0NPTVBBUkFUT1IpKTsKKyAgICBhc3NlcnRFcXVhbHMoLSgyKzEpLCBCeXRlcy5iaW5hcnlTZWFyY2goYXJyLCBrZXkyLCAwLCAxLAorICAgICAgQnl0ZXMuQllURVNfUkFXQ09NUEFSQVRPUikpOworICAgIGFzc2VydEVxdWFscyg0LCBCeXRlcy5iaW5hcnlTZWFyY2goYXJyLCBrZXkyLCAxLCAxLAorICAgICAgQnl0ZXMuQllURVNfUkFXQ09NUEFSQVRPUikpOworICAgIGFzc2VydEVxdWFscygyLCBCeXRlcy5iaW5hcnlTZWFyY2goYXJyLCBrZXkzLCAwLCAxLAorICAgICAgQnl0ZXMuQllURVNfUkFXQ09NUEFSQVRPUikpOworICAgIGFzc2VydEVxdWFscyg1LCBCeXRlcy5iaW5hcnlTZWFyY2goYXJyLCBrZXkzLCAxLCAxLAorICAgICAgQnl0ZXMuQllURVNfUkFXQ09NUEFSQVRPUikpOworICB9CisgIAorICBwdWJsaWMgdm9pZCB0ZXN0SW5jcmVtZW50Qnl0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworCisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygxMCwgMSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoMTIsIDEyMzQzNTQ0NSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoMTI0NjM0NjU0LCAxKSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygxMDAwNTQ2MCwgNTAwNTY0NSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoMSwgLTEpKTsKKyAgICBhc3NlcnRUcnVlKGNoZWNrVGVzdEluY3JlbWVudEJ5dGVzKDEwLCAtMSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoMTAsIC01KSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygxMDA1NDM1MDAwLCAtNSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoMTAsIC00MzY1NzY1NSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoLTEsIDEpKTsKKyAgICBhc3NlcnRUcnVlKGNoZWNrVGVzdEluY3JlbWVudEJ5dGVzKC0yNiwgNTAzNDUyMCkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoLTEwNjU3MjAwLCA1KSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygtMTIzNDMyNTAsIDQ1Mzc2NDc1KSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygtMTAsIC01KSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygtMTIzNDMyNTAsIC01KSk7CisgICAgYXNzZXJ0VHJ1ZShjaGVja1Rlc3RJbmNyZW1lbnRCeXRlcygtMTIsIC0zNDU2NTQ0NSkpOworICAgIGFzc2VydFRydWUoY2hlY2tUZXN0SW5jcmVtZW50Qnl0ZXMoLTE1NDY1NDM0NTIsIC0zNDU2NTQ0NSkpOworICB9CisgIAorICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGNoZWNrVGVzdEluY3JlbWVudEJ5dGVzKGxvbmcgdmFsLCBsb25nIGFtb3VudCkgCisgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIHZhbHVlID0gQnl0ZXMudG9CeXRlcyh2YWwpOworICAgIGJ5dGUgW10gdGVzdFZhbHVlID0gey0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMX07CisgICAgaWYgKHZhbHVlWzBdID4gMCkgeworICAgICAgdGVzdFZhbHVlID0gbmV3IGJ5dGVbQnl0ZXMuU0laRU9GX0xPTkddOworICAgIH0KKyAgICBTeXN0ZW0uYXJyYXljb3B5KHZhbHVlLCAwLCB0ZXN0VmFsdWUsIHRlc3RWYWx1ZS5sZW5ndGggLSB2YWx1ZS5sZW5ndGgsCisgICAgICAgIHZhbHVlLmxlbmd0aCk7CisKKyAgICBsb25nIGluY3JlbWVudFJlc3VsdCA9IEJ5dGVzLnRvTG9uZyhCeXRlcy5pbmNyZW1lbnRCeXRlcyh2YWx1ZSwgYW1vdW50KSk7CisKKyAgICByZXR1cm4gKEJ5dGVzLnRvTG9uZyh0ZXN0VmFsdWUpICsgYW1vdW50KSA9PSBpbmNyZW1lbnRSZXN1bHQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdEtleWluZy5qYXZhIGIvc3JjL3Rlc3Qvb3JnL2FwYWNoZS9oYWRvb3AvaGJhc2UvdXRpbC9UZXN0S2V5aW5nLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQxMDZhYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdEtleWluZy5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDcgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisvKioKKyAqIFRlc3RzIHVybCB0cmFuc2Zvcm1hdGlvbnMKKyAqLworcHVibGljIGNsYXNzIFRlc3RLZXlpbmcgZXh0ZW5kcyBUZXN0Q2FzZSB7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3VwZXIuc2V0VXAoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIHN1cGVyLnRlYXJEb3duKCk7CisgIH0KKworICAvKioKKyAgICogVGVzdCB1cmwgdHJhbnNmb3JtYXRpb25zCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0VVJJKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY2hlY2tUcmFuc2Zvcm0oImh0dHA6Ly9hYmM6YmNkQHd3dy5leGFtcGxlLmNvbS9pbmRleC5odG1sIiArCisgICAgICAiP3F1ZXJ5PXNvbWV0aGluZyNtaWRkbGUiKTsKKyAgICBjaGVja1RyYW5zZm9ybSgiZmlsZTovLy91c3IvYmluL2phdmEiKTsKKyAgICBjaGVja1RyYW5zZm9ybSgiZG5zOnd3dy5wb3dlcnNldC5jb20iKTsKKyAgICBjaGVja1RyYW5zZm9ybSgiZG5zOi8vZG5zLnBvd2Vyc2V0LmNvbS93d3cucG93ZXJzZXQuY29tIik7CisgICAgY2hlY2tUcmFuc2Zvcm0oImh0dHA6Ly9vbmUudHdvLnRocmVlL2luZGV4Lmh0bWwiKTsKKyAgICBjaGVja1RyYW5zZm9ybSgiaHR0cHM6Ly9vbmUudHdvLnRocmVlOjk0NDMvaW5kZXguaHRtbCIpOworICAgIGNoZWNrVHJhbnNmb3JtKCJmdHA6Ly9vbmUudHdvLnRocmVlL2luZGV4Lmh0bWwiKTsKKworICAgIGNoZWNrVHJhbnNmb3JtKCJmaWxlbmFtZSIpOworICB9CisgIAorICBwcml2YXRlIHZvaWQgY2hlY2tUcmFuc2Zvcm0oZmluYWwgU3RyaW5nIHUpIHsKKyAgICBTdHJpbmcgayA9IEtleWluZy5jcmVhdGVLZXkodSk7CisgICAgU3RyaW5nIHVyaSA9IEtleWluZy5rZXlUb1VyaShrKTsKKyAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk9yaWdpbmFsIHVybCAiICsgdSArICIsIFRyYW5zZm9ybWVkIHVybCAiICsgayk7CisgICAgYXNzZXJ0RXF1YWxzKHUsIHVyaSk7CisgIH0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RNZXJnZVRvb2wuamF2YSBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdE1lcmdlVG9vbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzZDIwMWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RNZXJnZVRvb2wuamF2YQpAQCAtMCwwICsxLDIzMiBAQAorLyoqCisgKiBDb3B5cmlnaHQgMjAwOCBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24KKyAqCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbDsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5kZnMuTWluaURGU0NsdXN0ZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuZnMuUGF0aDsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb2x1bW5EZXNjcmlwdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhDb25zdGFudHM7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm87CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFRhYmxlRGVzY3JpcHRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5CYXRjaFVwZGF0ZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5pby5DZWxsOworaW1wb3J0IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGU7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhMb2c7CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UucmVnaW9uc2VydmVyLkhSZWdpb247CitpbXBvcnQgb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5Ub29sUnVubmVyOworCisvKiogVGVzdCBzdGFuZCBhbG9uZSBtZXJnZSB0b29sIHRoYXQgY2FuIG1lcmdlIGFyYml0cmFyeSByZWdpb25zICovCitwdWJsaWMgY2xhc3MgVGVzdE1lcmdlVG9vbCBleHRlbmRzIEhCYXNlVGVzdENhc2UgeworICBzdGF0aWMgZmluYWwgTG9nIExPRyA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFRlc3RNZXJnZVRvb2wuY2xhc3MpOworICBzdGF0aWMgZmluYWwgYnl0ZSBbXSBDT0xVTU5fTkFNRSA9IEJ5dGVzLnRvQnl0ZXMoImNvbnRlbnRzOiIpOworICBwcml2YXRlIGZpbmFsIEhSZWdpb25JbmZvW10gc291cmNlUmVnaW9ucyA9IG5ldyBIUmVnaW9uSW5mb1s1XTsKKyAgcHJpdmF0ZSBmaW5hbCBIUmVnaW9uW10gcmVnaW9ucyA9IG5ldyBIUmVnaW9uWzVdOworICBwcml2YXRlIEhUYWJsZURlc2NyaXB0b3IgZGVzYzsKKyAgcHJpdmF0ZSBieXRlIFtdW11bXSByb3dzOworICBwcml2YXRlIE1pbmlERlNDbHVzdGVyIGRmc0NsdXN0ZXIgPSBudWxsOworICAKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdGhpcy5jb25mLnNldCgiaGJhc2UuaHN0b3JlLmNvbXBhY3Rpb25UaHJlc2hvbGQiLCAiMiIpOworCisgICAgLy8gQ3JlYXRlIHRhYmxlIGRlc2NyaXB0aW9uCisgICAgdGhpcy5kZXNjID0gbmV3IEhUYWJsZURlc2NyaXB0b3IoIlRlc3RNZXJnZVRvb2wiKTsKKyAgICB0aGlzLmRlc2MuYWRkRmFtaWx5KG5ldyBIQ29sdW1uRGVzY3JpcHRvcihDT0xVTU5fTkFNRSkpOworCisgICAgLyoKKyAgICAgKiBDcmVhdGUgdGhlIEhSZWdpb25JbmZvcyBmb3IgdGhlIHJlZ2lvbnMuCisgICAgICovCisgICAgLy8gUmVnaW9uIDAgd2lsbCBjb250YWluIHRoZSBrZXkgcmFuZ2UgW3Jvd18wMjAwLHJvd18wMzAwKQorICAgIHNvdXJjZVJlZ2lvbnNbMF0gPSBuZXcgSFJlZ2lvbkluZm8odGhpcy5kZXNjLCBCeXRlcy50b0J5dGVzKCJyb3dfMDIwMCIpLAorICAgICAgQnl0ZXMudG9CeXRlcygicm93XzAzMDAiKSk7CisgICAgCisgICAgLy8gUmVnaW9uIDEgd2lsbCBjb250YWluIHRoZSBrZXkgcmFuZ2UgW3Jvd18wMjUwLHJvd18wNDAwKSBhbmQgb3ZlcmxhcHMKKyAgICAvLyB3aXRoIFJlZ2lvbiAwCisgICAgc291cmNlUmVnaW9uc1sxXSA9CisgICAgICBuZXcgSFJlZ2lvbkluZm8odGhpcy5kZXNjLCBCeXRlcy50b0J5dGVzKCJyb3dfMDI1MCIpLCBCeXRlcy50b0J5dGVzKCJyb3dfMDQwMCIpKTsKKyAgICAKKyAgICAvLyBSZWdpb24gMiB3aWxsIGNvbnRhaW4gdGhlIGtleSByYW5nZSBbcm93XzAxMDAscm93XzAyMDApIGFuZCBpcyBhZGphY2VudAorICAgIC8vIHRvIFJlZ2lvbiAwIG9yIHRoZSByZWdpb24gcmVzdWx0aW5nIGZyb20gdGhlIG1lcmdlIG9mIFJlZ2lvbnMgMCBhbmQgMQorICAgIHNvdXJjZVJlZ2lvbnNbMl0gPQorICAgICAgbmV3IEhSZWdpb25JbmZvKHRoaXMuZGVzYywgQnl0ZXMudG9CeXRlcygicm93XzAxMDAiKSwgQnl0ZXMudG9CeXRlcygicm93XzAyMDAiKSk7CisgICAgCisgICAgLy8gUmVnaW9uIDMgd2lsbCBjb250YWluIHRoZSBrZXkgcmFuZ2UgW3Jvd18wNTAwLHJvd18wNjAwKSBhbmQgaXMgbm90CisgICAgLy8gYWRqYWNlbnQgdG8gYW55IG9mIFJlZ2lvbnMgMCwgMSwgMiBvciB0aGUgbWVyZ2VkIHJlc3VsdCBvZiBhbnkgb3IgYWxsCisgICAgLy8gb2YgdGhvc2UgcmVnaW9ucworICAgIHNvdXJjZVJlZ2lvbnNbM10gPQorICAgICAgbmV3IEhSZWdpb25JbmZvKHRoaXMuZGVzYywgQnl0ZXMudG9CeXRlcygicm93XzA1MDAiKSwgQnl0ZXMudG9CeXRlcygicm93XzA2MDAiKSk7CisgICAgCisgICAgLy8gUmVnaW9uIDQgd2lsbCBoYXZlIGVtcHR5IHN0YXJ0IGFuZCBlbmQga2V5cyBhbmQgb3ZlcmxhcHMgYWxsIHJlZ2lvbnMuCisgICAgc291cmNlUmVnaW9uc1s0XSA9CisgICAgICBuZXcgSFJlZ2lvbkluZm8odGhpcy5kZXNjLCBIQ29uc3RhbnRzLkVNUFRZX0JZVEVfQVJSQVksIEhDb25zdGFudHMuRU1QVFlfQllURV9BUlJBWSk7CisgICAgCisgICAgLyoKKyAgICAgKiBOb3cgY3JlYXRlIHNvbWUgcm93IGtleXMKKyAgICAgKi8KKyAgICB0aGlzLnJvd3MgPSBuZXcgYnl0ZSBbNV1bXVtdOworICAgIHRoaXMucm93c1swXSA9IEJ5dGVzLnRvQnl0ZUFycmF5cyhuZXcgU3RyaW5nW10geyAicm93XzAyMTAiLCAicm93XzAyODAiIH0pOworICAgIHRoaXMucm93c1sxXSA9IEJ5dGVzLnRvQnl0ZUFycmF5cyhuZXcgU3RyaW5nW10geyAicm93XzAyNjAiLCAicm93XzAzNTAiLCAicm93XzAzNSIgfSk7CisgICAgdGhpcy5yb3dzWzJdID0gQnl0ZXMudG9CeXRlQXJyYXlzKG5ldyBTdHJpbmdbXSB7ICJyb3dfMDExMCIsICJyb3dfMDE3NSIsICJyb3dfMDE3NSIsICJyb3dfMDE3NSJ9KTsKKyAgICB0aGlzLnJvd3NbM10gPSBCeXRlcy50b0J5dGVBcnJheXMobmV3IFN0cmluZ1tdIHsgInJvd18wNTI1IiwgInJvd18wNTYwIiwgInJvd18wNTYwIiwgInJvd18wNTYwIiwgInJvd18wNTYwIn0pOworICAgIHRoaXMucm93c1s0XSA9IEJ5dGVzLnRvQnl0ZUFycmF5cyhuZXcgU3RyaW5nW10geyAicm93XzAwNTAiLCAicm93XzEwMDAiLCAicm93XzEwMDAiLCAicm93XzEwMDAiLCAicm93XzEwMDAiLCAicm93XzEwMDAiIH0pOworICAgIAorICAgIC8vIFN0YXJ0IHVwIGRmcworICAgIHRoaXMuZGZzQ2x1c3RlciA9IG5ldyBNaW5pREZTQ2x1c3Rlcihjb25mLCAyLCB0cnVlLCAoU3RyaW5nW10pbnVsbCk7CisgICAgdGhpcy5mcyA9IHRoaXMuZGZzQ2x1c3Rlci5nZXRGaWxlU3lzdGVtKCk7CisgICAgY29uZi5zZXQoImZzLmRlZmF1bHQubmFtZSIsIGZzLmdldFVyaSgpLnRvU3RyaW5nKCkpOworICAgIFBhdGggcGFyZW50ZGlyID0gZnMuZ2V0SG9tZURpcmVjdG9yeSgpOworICAgIGNvbmYuc2V0KEhDb25zdGFudHMuSEJBU0VfRElSLCBwYXJlbnRkaXIudG9TdHJpbmcoKSk7CisgICAgZnMubWtkaXJzKHBhcmVudGRpcik7CisgICAgRlNVdGlscy5zZXRWZXJzaW9uKGZzLCBwYXJlbnRkaXIpOworCisgICAgLy8gTm90ZTogd2UgbXVzdCBjYWxsIHN1cGVyLnNldFVwIGFmdGVyIHN0YXJ0aW5nIHRoZSBtaW5pIGNsdXN0ZXIgb3IKKyAgICAvLyB3ZSB3aWxsIGVuZCB1cCB3aXRoIGEgbG9jYWwgZmlsZSBzeXN0ZW0KKyAgICAKKyAgICBzdXBlci5zZXRVcCgpOworICAgIHRyeSB7CisgICAgICAvLyBDcmVhdGUgcm9vdCBhbmQgbWV0YSByZWdpb25zCisgICAgICBjcmVhdGVSb290QW5kTWV0YVJlZ2lvbnMoKTsKKyAgICAgIC8qCisgICAgICAgKiBDcmVhdGUgdGhlIHJlZ2lvbnMgd2Ugd2lsbCBtZXJnZQorICAgICAgICovCisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNvdXJjZVJlZ2lvbnMubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgcmVnaW9uc1tpXSA9CisgICAgICAgICAgSFJlZ2lvbi5jcmVhdGVIUmVnaW9uKHRoaXMuc291cmNlUmVnaW9uc1tpXSwgdGhpcy50ZXN0RGlyLCB0aGlzLmNvbmYpOworICAgICAgICAvKgorICAgICAgICAgKiBJbnNlcnQgZGF0YQorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCByb3dzW2ldLmxlbmd0aDsgaisrKSB7CisgICAgICAgICAgYnl0ZSBbXSByb3cgPSByb3dzW2ldW2pdOworICAgICAgICAgIEJhdGNoVXBkYXRlIGIgPSBuZXcgQmF0Y2hVcGRhdGUocm93KTsKKyAgICAgICAgICBiLnB1dChDT0xVTU5fTkFNRSwgbmV3IEltbXV0YWJsZUJ5dGVzV3JpdGFibGUocm93KS5nZXQoKSk7CisgICAgICAgICAgcmVnaW9uc1tpXS5iYXRjaFVwZGF0ZShiLCBudWxsKTsKKyAgICAgICAgfQorICAgICAgICBIUmVnaW9uLmFkZFJlZ2lvblRvTUVUQShtZXRhLCByZWdpb25zW2ldKTsKKyAgICAgIH0KKyAgICAgIC8vIENsb3NlIHJvb3QgYW5kIG1ldGEgcmVnaW9ucworICAgICAgY2xvc2VSb290QW5kTWV0YSgpOworICAgICAgCisgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgIHNodXRkb3duRGZzKGRmc0NsdXN0ZXIpOworICAgICAgdGhyb3cgZTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdXBlci50ZWFyRG93bigpOworICAgIHNodXRkb3duRGZzKGRmc0NsdXN0ZXIpOworICB9CisgIAorICAvKgorICAgKiBAcGFyYW0gbXNnIE1lc3NhZ2UgdGhhdCBkZXNjcmliZXMgdGhpcyBtZXJnZQorICAgKiBAcGFyYW0gcmVnaW9uTmFtZTEKKyAgICogQHBhcmFtIHJlZ2lvbk5hbWUyCisgICAqIEBwYXJhbSBsb2cgTG9nIHRvIHVzZSBtZXJnaW5nLgorICAgKiBAcGFyYW0gdXBwZXJib3VuZCBWZXJpZnlpbmcsIGhvdyBoaWdoIHVwIGluIHRoaXMucm93cyB0byBnby4KKyAgICogQHJldHVybiBNZXJnZWQgcmVnaW9uLgorICAgKiBAdGhyb3dzIEV4Y2VwdGlvbgorICAgKi8KKyAgcHJpdmF0ZSBIUmVnaW9uIG1lcmdlQW5kVmVyaWZ5KGZpbmFsIFN0cmluZyBtc2csIGZpbmFsIFN0cmluZyByZWdpb25OYW1lMSwKKyAgICBmaW5hbCBTdHJpbmcgcmVnaW9uTmFtZTIsIGZpbmFsIEhMb2cgbG9nLCBmaW5hbCBpbnQgdXBwZXJib3VuZCkKKyAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWVyZ2UgbWVyZ2VyID0gbmV3IE1lcmdlKHRoaXMuY29uZik7CisgICAgTE9HLmluZm8obXNnKTsKKyAgICBpbnQgZXJyQ29kZSA9IFRvb2xSdW5uZXIucnVuKG1lcmdlciwKKyAgICAgIG5ldyBTdHJpbmdbXSB7dGhpcy5kZXNjLmdldE5hbWVBc1N0cmluZygpLCByZWdpb25OYW1lMSwgcmVnaW9uTmFtZTJ9CisgICAgKTsKKyAgICBhc3NlcnRUcnVlKCInIiArIG1zZyArICInIGZhaWxlZCIsIGVyckNvZGUgPT0gMCk7CisgICAgSFJlZ2lvbkluZm8gbWVyZ2VkSW5mbyA9IG1lcmdlci5nZXRNZXJnZWRIUmVnaW9uSW5mbygpOworICAKKyAgICAvLyBOb3cgdmVyaWZ5IHRoYXQgd2UgY2FuIHJlYWQgYWxsIHRoZSByb3dzIGZyb20gcmVnaW9ucyAwLCAxCisgICAgLy8gaW4gdGhlIG5ldyBtZXJnZWQgcmVnaW9uLgorICAgIEhSZWdpb24gbWVyZ2VkID0KKyAgICAgIEhSZWdpb24ub3BlbkhSZWdpb24obWVyZ2VkSW5mbywgdGhpcy50ZXN0RGlyLCBsb2csIHRoaXMuY29uZik7CisgICAgdmVyaWZ5TWVyZ2UobWVyZ2VkLCB1cHBlcmJvdW5kKTsKKyAgICBtZXJnZWQuY2xvc2UoKTsKKyAgICBMT0cuaW5mbygiVmVyaWZpZWQgIiArIG1zZyk7CisgICAgcmV0dXJuIG1lcmdlZDsKKyAgfQorICAKKyAgcHJpdmF0ZSB2b2lkIHZlcmlmeU1lcmdlKGZpbmFsIEhSZWdpb24gbWVyZ2VkLCBmaW5hbCBpbnQgdXBwZXJib3VuZCkKKyAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHVwcGVyYm91bmQ7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCByb3dzW2ldLmxlbmd0aDsgaisrKSB7CisgICAgICAgIGJ5dGUgW10gYnl0ZXMgPSBDZWxsLmNyZWF0ZVNpbmdsZUNlbGxBcnJheShtZXJnZWQuZ2V0KHJvd3NbaV1bal0sIENPTFVNTl9OQU1FLCAtMSwgLTEpKVswXS5nZXRWYWx1ZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKHJvd3NbaV1bal0udG9TdHJpbmcoKSwgYnl0ZXMpOworICAgICAgICBhc3NlcnRUcnVlKEJ5dGVzLmVxdWFscyhieXRlcywgcm93c1tpXVtqXSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUZXN0IG1lcmdlIHRvb2wuCisgICAqIEB0aHJvd3MgRXhjZXB0aW9uCisgICAqLworICBwdWJsaWMgdm9pZCB0ZXN0TWVyZ2VUb29sKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRmlyc3QgdmVyaWZ5IHdlIGNhbiByZWFkIHRoZSByb3dzIGZyb20gdGhlIHNvdXJjZSByZWdpb25zIGFuZCB0aGF0IHRoZXkKKyAgICAvLyBjb250YWluIHRoZSByaWdodCBkYXRhLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVnaW9ucy5sZW5ndGg7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCByb3dzW2ldLmxlbmd0aDsgaisrKSB7CisgICAgICAgIGJ5dGVbXSBieXRlcyA9IENlbGwuY3JlYXRlU2luZ2xlQ2VsbEFycmF5KHJlZ2lvbnNbaV0uZ2V0KHJvd3NbaV1bal0sIENPTFVNTl9OQU1FLCAtMSwgLTEpKVswXS5nZXRWYWx1ZSgpOworICAgICAgICBhc3NlcnROb3ROdWxsKGJ5dGVzKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShCeXRlcy5lcXVhbHMoYnl0ZXMsIHJvd3NbaV1bal0pKTsKKyAgICAgIH0KKyAgICAgIC8vIENsb3NlIHRoZSByZWdpb24gYW5kIGRlbGV0ZSB0aGUgbG9nCisgICAgICByZWdpb25zW2ldLmNsb3NlKCk7CisgICAgICByZWdpb25zW2ldLmdldExvZygpLmNsb3NlQW5kRGVsZXRlKCk7CisgICAgfQorCisgICAgLy8gQ3JlYXRlIGEgbG9nIHRoYXQgd2UgY2FuIHJldXNlIHdoZW4gd2UgbmVlZCB0byBvcGVuIHJlZ2lvbnMKKyAgICBQYXRoIGxvZ1BhdGggPSBuZXcgUGF0aCgiL3RtcCIsIEhDb25zdGFudHMuSFJFR0lPTl9MT0dESVJfTkFNRSArICJfIiArCisgICAgICBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgTE9HLmluZm8oIkNyZWF0aW5nIGxvZyAiICsgbG9nUGF0aC50b1N0cmluZygpKTsKKyAgICBITG9nIGxvZyA9IG5ldyBITG9nKHRoaXMuZnMsIGxvZ1BhdGgsIHRoaXMuY29uZiwgbnVsbCk7CisgICAgdHJ5IHsKKyAgICAgICAvLyBNZXJnZSBSZWdpb24gMCBhbmQgUmVnaW9uIDEKKyAgICAgIEhSZWdpb24gbWVyZ2VkID0gbWVyZ2VBbmRWZXJpZnkoIm1lcmdpbmcgcmVnaW9ucyAwIGFuZCAxIiwKKyAgICAgICAgdGhpcy5zb3VyY2VSZWdpb25zWzBdLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpLAorICAgICAgICB0aGlzLnNvdXJjZVJlZ2lvbnNbMV0uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCksIGxvZywgMik7CisKKyAgICAgIC8vIE1lcmdlIHRoZSByZXN1bHQgb2YgbWVyZ2luZyByZWdpb25zIDAgYW5kIDEgd2l0aCByZWdpb24gMgorICAgICAgbWVyZ2VkID0gbWVyZ2VBbmRWZXJpZnkoIm1lcmdpbmcgcmVnaW9ucyAwKzEgYW5kIDIiLAorICAgICAgICBtZXJnZWQuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpLAorICAgICAgICB0aGlzLnNvdXJjZVJlZ2lvbnNbMl0uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCksIGxvZywgMyk7CisKKyAgICAgIC8vIE1lcmdlIHRoZSByZXN1bHQgb2YgbWVyZ2luZyByZWdpb25zIDAsIDEgYW5kIDIgd2l0aCByZWdpb24gMworICAgICAgbWVyZ2VkID0gbWVyZ2VBbmRWZXJpZnkoIm1lcmdpbmcgcmVnaW9ucyAwKzErMiBhbmQgMyIsCisgICAgICAgIG1lcmdlZC5nZXRSZWdpb25JbmZvKCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCksCisgICAgICAgIHRoaXMuc291cmNlUmVnaW9uc1szXS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSwgbG9nLCA0KTsKKyAgICAgIAorICAgICAgLy8gTWVyZ2UgdGhlIHJlc3VsdCBvZiBtZXJnaW5nIHJlZ2lvbnMgMCwgMSwgMiBhbmQgMyB3aXRoIHJlZ2lvbiA0CisgICAgICBtZXJnZWQgPSBtZXJnZUFuZFZlcmlmeSgibWVyZ2luZyByZWdpb25zIDArMSsyKzMgYW5kIDQiLAorICAgICAgICBtZXJnZWQuZ2V0UmVnaW9uSW5mbygpLmdldFJlZ2lvbk5hbWVBc1N0cmluZygpLAorICAgICAgICB0aGlzLnNvdXJjZVJlZ2lvbnNbNF0uZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCksIGxvZywgcm93cy5sZW5ndGgpOworICAgIH0gZmluYWxseSB7CisgICAgICBsb2cuY2xvc2VBbmREZWxldGUoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3V0aWwvVGVzdFJvb3RQYXRoLmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RSb290UGF0aC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhNjg0YjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS91dGlsL1Rlc3RSb290UGF0aC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qKgorICogQ29weXJpZ2h0IDIwMDggVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisgKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWw7CisKK2ltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2U7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmcuTG9nOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZ0ZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5mcy5QYXRoOworCisvKioKKyAqIFRlc3QgcmVxdWlyZW1lbnQgdGhhdCByb290IGRpcmVjdG9yeSBtdXN0IGJlIGEgVVJJCisgKi8KK3B1YmxpYyBjbGFzcyBUZXN0Um9vdFBhdGggZXh0ZW5kcyBUZXN0Q2FzZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvZyBMT0cgPSBMb2dGYWN0b3J5LmdldExvZyhUZXN0Um9vdFBhdGguY2xhc3MpOworICAKKyAgLyoqIFRoZSB0ZXN0ICovCisgIHB1YmxpYyB2b2lkIHRlc3RSb290UGF0aCgpIHsKKyAgICB0cnkgeworICAgICAgLy8gVHJ5IGdvb2QgcGF0aAorICAgICAgRlNVdGlscy52YWxpZGF0ZVJvb3RQYXRoKG5ldyBQYXRoKCJmaWxlOi8vL3RtcC9oYmFzZS9oYmFzZSIpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMT0cuZmF0YWwoIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIGNoZWNraW5nIHZhbGlkIHBhdGg6IiwgZSk7CisgICAgICBmYWlsKCk7CisgICAgfQorICAgIHRyeSB7CisgICAgICAvLyBUcnkgZ29vZCBwYXRoCisgICAgICBGU1V0aWxzLnZhbGlkYXRlUm9vdFBhdGgobmV3IFBhdGgoImhkZnM6Ly9hOjkwMDAvaGJhc2UiKSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTE9HLmZhdGFsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiBjaGVja2luZyB2YWxpZCBwYXRoOiIsIGUpOworICAgICAgZmFpbCgpOworICAgIH0KKyAgICB0cnkgeworICAgICAgLy8gYmFkIHBhdGgKKyAgICAgIEZTVXRpbHMudmFsaWRhdGVSb290UGF0aChuZXcgUGF0aCgiL2hiYXNlIikpOworICAgICAgZmFpbCgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEV4cGVjdGVkLgorICAgICAgTE9HLmluZm8oIkdvdCBleHBlY3RlZCBleGNlcHRpb24gd2hlbiBjaGVja2luZyBpbnZhbGlkIHBhdGg6IiwgZSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvSFF1b3J1bVBlZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9vcmcvYXBhY2hlL2hhZG9vcC9oYmFzZS96b29rZWVwZXIvSFF1b3J1bVBlZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2ViZmQzOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L29yZy9hcGFjaGUvaGFkb29wL2hiYXNlL3pvb2tlZXBlci9IUXVvcnVtUGVlclRlc3QuamF2YQpAQCAtMCwwICsxLDk5IEBACisvKioKKyAqIENvcHlyaWdodCAyMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorICoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2Uuem9va2VlcGVyOworCitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQmFzZVRlc3RDYXNlOworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLnNlcnZlci5TZXJ2ZXJDb25maWc7CitpbXBvcnQgb3JnLmFwYWNoZS56b29rZWVwZXIuc2VydmVyLnF1b3J1bS5RdW9ydW1QZWVyQ29uZmlnOworaW1wb3J0IG9yZy5hcGFjaGUuem9va2VlcGVyLnNlcnZlci5xdW9ydW0uUXVvcnVtUGVlci5RdW9ydW1TZXJ2ZXI7CisKKy8qKgorICogVGVzdCBmb3IgSFF1b3J1bVBlZXIuCisgKi8KK3B1YmxpYyBjbGFzcyBIUXVvcnVtUGVlclRlc3QgZXh0ZW5kcyBIQmFzZVRlc3RDYXNlIHsKKyAgLyoqIEB0aHJvd3MgRXhjZXB0aW9uICovCisgIHB1YmxpYyB2b2lkIHRlc3RDb25maWdJbmplY3Rpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgcyA9CisgICAgICAidGlja1RpbWU9MjAwMFxuIiArCisgICAgICAiaW5pdExpbWl0PTEwXG4iICsKKyAgICAgICJzeW5jTGltaXQ9NVxuIiArCisgICAgICAiZGF0YURpcj0ke2hiYXNlLnRtcC5kaXJ9L3pvb2tlZXBlclxuIiArCisgICAgICAiY2xpZW50UG9ydD0yMTgxXG4iICsKKyAgICAgICJzZXJ2ZXIuMD0ke2hiYXNlLm1hc3Rlci5ob3N0bmFtZX06Mjg4ODozODg4XG4iOworCisgICAgSW5wdXRTdHJlYW0gaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocy5nZXRCeXRlcygpKTsKKyAgICBQcm9wZXJ0aWVzIHByb3BlcnRpZXMgPSBIUXVvcnVtUGVlci5wYXJzZUNvbmZpZyhpcyk7CisKKyAgICBTdHJpbmcgdXNlck5hbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIubmFtZSIpOworICAgIFN0cmluZyBkYXRhRGlyID0gIi90bXAvaGJhc2UtIiArIHVzZXJOYW1lICsgIi96b29rZWVwZXIiOworCisgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIudmFsdWVPZigyMDAwKSwgSW50ZWdlci52YWx1ZU9mKHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInRpY2tUaW1lIikpKTsKKyAgICBhc3NlcnRFcXVhbHMoSW50ZWdlci52YWx1ZU9mKDEwKSwgSW50ZWdlci52YWx1ZU9mKHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoImluaXRMaW1pdCIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKEludGVnZXIudmFsdWVPZig1KSwgSW50ZWdlci52YWx1ZU9mKHByb3BlcnRpZXMuZ2V0UHJvcGVydHkoInN5bmNMaW1pdCIpKSk7CisgICAgYXNzZXJ0RXF1YWxzKGRhdGFEaXIsIHByb3BlcnRpZXMuZ2V0KCJkYXRhRGlyIikpOworICAgIGFzc2VydEVxdWFscyhJbnRlZ2VyLnZhbHVlT2YoMjE4MSksIEludGVnZXIudmFsdWVPZihwcm9wZXJ0aWVzLmdldFByb3BlcnR5KCJjbGllbnRQb3J0IikpKTsKKyAgICBhc3NlcnRFcXVhbHMoImxvY2FsaG9zdDoyODg4OjM4ODgiLCBwcm9wZXJ0aWVzLmdldCgic2VydmVyLjAiKSk7CisKKyAgICBRdW9ydW1QZWVyQ29uZmlnLnBhcnNlUHJvcGVydGllcyhwcm9wZXJ0aWVzKTsKKworICAgIGludCB0aWNrVGltZSA9IFF1b3J1bVBlZXJDb25maWcuZ2V0VGlja1RpbWUoKTsKKyAgICBhc3NlcnRFcXVhbHMoMjAwMCwgdGlja1RpbWUpOworICAgIGludCBpbml0TGltaXQgPSBRdW9ydW1QZWVyQ29uZmlnLmdldEluaXRMaW1pdCgpOworICAgIGFzc2VydEVxdWFscygxMCwgaW5pdExpbWl0KTsKKyAgICBpbnQgc3luY0xpbWl0ID0gUXVvcnVtUGVlckNvbmZpZy5nZXRTeW5jTGltaXQoKTsKKyAgICBhc3NlcnRFcXVhbHMoNSwgc3luY0xpbWl0KTsKKyAgICBhc3NlcnRFcXVhbHMoZGF0YURpciwgU2VydmVyQ29uZmlnLmdldERhdGFEaXIoKSk7CisgICAgYXNzZXJ0RXF1YWxzKDIxODEsIFNlcnZlckNvbmZpZy5nZXRDbGllbnRQb3J0KCkpOworICAgIE1hcDxMb25nLFF1b3J1bVNlcnZlcj4gc2VydmVycyA9IFF1b3J1bVBlZXJDb25maWcuZ2V0U2VydmVycygpOworICAgIGFzc2VydEVxdWFscygxLCBzZXJ2ZXJzLnNpemUoKSk7CisgICAgYXNzZXJ0VHJ1ZShzZXJ2ZXJzLmNvbnRhaW5zS2V5KExvbmcudmFsdWVPZigwKSkpOworICAgIFF1b3J1bVNlcnZlciBzZXJ2ZXIgPSBzZXJ2ZXJzLmdldChMb25nLnZhbHVlT2YoMCkpOworICAgIGFzc2VydEVxdWFscygibG9jYWxob3N0Iiwgc2VydmVyLmFkZHIuZ2V0SG9zdE5hbWUoKSk7CisKKyAgICAvLyBPdmVycmlkZSB3aXRoIHN5c3RlbSBwcm9wZXJ0eS4KKyAgICBTeXN0ZW0uc2V0UHJvcGVydHkoImhiYXNlLm1hc3Rlci5ob3N0bmFtZSIsICJmb28uYmFyIik7CisgICAgaXMgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocy5nZXRCeXRlcygpKTsKKyAgICBwcm9wZXJ0aWVzID0gSFF1b3J1bVBlZXIucGFyc2VDb25maWcoaXMpOworICAgIGFzc2VydEVxdWFscygiZm9vLmJhcjoyODg4OjM4ODgiLCBwcm9wZXJ0aWVzLmdldCgic2VydmVyLjAiKSk7CisKKyAgICBRdW9ydW1QZWVyQ29uZmlnLnBhcnNlUHJvcGVydGllcyhwcm9wZXJ0aWVzKTsKKworICAgIHNlcnZlcnMgPSBRdW9ydW1QZWVyQ29uZmlnLmdldFNlcnZlcnMoKTsKKyAgICBzZXJ2ZXIgPSBzZXJ2ZXJzLmdldChMb25nLnZhbHVlT2YoMCkpOworICAgIGFzc2VydEVxdWFscygiZm9vLmJhciIsIHNlcnZlci5hZGRyLmdldEhvc3ROYW1lKCkpOworCisgICAgLy8gU3BlY2lhbCBjYXNlIGZvciBwcm9wZXJ0eSAnaGJhc2UubWFzdGVyLmhvc3RuYW1lJyBiZWluZyAnbG9jYWwnCisgICAgU3lzdGVtLnNldFByb3BlcnR5KCJoYmFzZS5tYXN0ZXIuaG9zdG5hbWUiLCAibG9jYWwiKTsKKyAgICBpcyA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShzLmdldEJ5dGVzKCkpOworICAgIHByb3BlcnRpZXMgPSBIUXVvcnVtUGVlci5wYXJzZUNvbmZpZyhpcyk7CisgICAgYXNzZXJ0RXF1YWxzKCJsb2NhbGhvc3Q6Mjg4ODozODg4IiwgcHJvcGVydGllcy5nZXQoInNlcnZlci4wIikpOworCisgICAgUXVvcnVtUGVlckNvbmZpZy5wYXJzZVByb3BlcnRpZXMocHJvcGVydGllcyk7CisKKyAgICBzZXJ2ZXJzID0gUXVvcnVtUGVlckNvbmZpZy5nZXRTZXJ2ZXJzKCk7CisgICAgc2VydmVyID0gc2VydmVycy5nZXQoTG9uZy52YWx1ZU9mKDApKTsKKyAgICBhc3NlcnRFcXVhbHMoImxvY2FsaG9zdCIsIHNlcnZlci5hZGRyLmdldEhvc3ROYW1lKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdGRhdGEvSEFET09QLTI0NzgtdGVzdGRhdGEtdjAuMS56aXAgYi9zcmMvdGVzdGRhdGEvSEFET09QLTI0NzgtdGVzdGRhdGEtdjAuMS56aXAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjVmM2Q4OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0ZGF0YS9IQURPT1AtMjQ3OC10ZXN0ZGF0YS12MC4xLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9zcmMvd2ViYXBwcy9tYXN0ZXIvaW5kZXguaHRtbCBiL3NyYy93ZWJhcHBzL21hc3Rlci9pbmRleC5odG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkMzAxYWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvd2ViYXBwcy9tYXN0ZXIvaW5kZXguaHRtbApAQCAtMCwwICsxIEBACis8bWV0YSBIVFRQLUVRVUlWPSJSRUZSRVNIIiBjb250ZW50PSIwO3VybD1tYXN0ZXIuanNwIi8+CmRpZmYgLS1naXQgYS9zcmMvd2ViYXBwcy9tYXN0ZXIvbWFzdGVyLmpzcCBiL3NyYy93ZWJhcHBzL21hc3Rlci9tYXN0ZXIuanNwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxZjJhMDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvd2ViYXBwcy9tYXN0ZXIvbWFzdGVyLmpzcApAQCAtMCwwICsxLDEwNSBAQAorPCVAIHBhZ2UgY29udGVudFR5cGU9InRleHQvaHRtbDtjaGFyc2V0PVVURi04Ig0KKyAgaW1wb3J0PSJqYXZhLnV0aWwuKiINCisgIGltcG9ydD0iamF2YS5uZXQuVVJMRW5jb2RlciIgDQorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmlvLlRleHQiDQorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXMiDQorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3Rlci5ITWFzdGVyIg0KKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzIg0KKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5tYXN0ZXIuTWV0YVJlZ2lvbiINCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW4iDQorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvIg0KKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IU2VydmVyQWRkcmVzcyINCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uIg0KKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yIiAlPjwlDQorICBITWFzdGVyIG1hc3RlciA9IChITWFzdGVyKWdldFNlcnZsZXRDb250ZXh0KCkuZ2V0QXR0cmlidXRlKEhNYXN0ZXIuTUFTVEVSKTsNCisgIEhCYXNlQ29uZmlndXJhdGlvbiBjb25mID0gbWFzdGVyLmdldENvbmZpZ3VyYXRpb24oKTsNCisgIEhTZXJ2ZXJBZGRyZXNzIHJvb3RMb2NhdGlvbiA9IG1hc3Rlci5nZXRSb290UmVnaW9uTG9jYXRpb24oKTsNCisgIE1hcDxieXRlIFtdLCBNZXRhUmVnaW9uPiBvbmxpbmVSZWdpb25zID0gbWFzdGVyLmdldE9ubGluZU1ldGFSZWdpb25zKCk7DQorICBNYXA8U3RyaW5nLCBIU2VydmVySW5mbz4gc2VydmVyVG9TZXJ2ZXJJbmZvcyA9DQorICAgIG1hc3Rlci5nZXRTZXJ2ZXJzVG9TZXJ2ZXJJbmZvKCk7DQorICBpbnQgaW50ZXJ2YWwgPSBjb25mLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm1zZ2ludGVydmFsIiwgMzAwMCkvMTAwMDsNCisgIGlmIChpbnRlcnZhbCA9PSAwKSB7DQorICAgICAgaW50ZXJ2YWwgPSAxOw0KKyAgfQ0KKyU+PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiID8+DQorPCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgVHJhbnNpdGlvbmFsLy9FTiIgDQorICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtdHJhbnNpdGlvbmFsLmR0ZCI+IA0KKzxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4NCis8aGVhZD48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDtjaGFyc2V0PVVURi04Ii8+DQorICAgICAgPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzAwIi8+DQorPHRpdGxlPkhCYXNlIE1hc3RlcjogPCU9IG1hc3Rlci5nZXRNYXN0ZXJBZGRyZXNzKCkuZ2V0SG9zdG5hbWUoKSU+OjwlPSBtYXN0ZXIuZ2V0TWFzdGVyQWRkcmVzcygpLmdldFBvcnQoKSAlPjwvdGl0bGU+DQorPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0iL3N0YXRpYy9oYmFzZS5jc3MiIC8+DQorPC9oZWFkPg0KKw0KKzxib2R5Pg0KKw0KKzxhIGlkPSJsb2dvIiBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2x1Y2VuZS1oYWRvb3AvSGJhc2UiPjxpbWcgc3JjPSIvc3RhdGljL2hiYXNlX2xvZ29fbWVkLmdpZiIgYWx0PSJIQmFzZSBMb2dvIiB0aXRsZT0iSEJhc2UgTG9nbyIgLz48L2E+DQorPGgxIGlkPSJwYWdlX3RpdGxlIj5NYXN0ZXI6IDwlPW1hc3Rlci5nZXRNYXN0ZXJBZGRyZXNzKCkuZ2V0SG9zdG5hbWUoKSU+OjwlPW1hc3Rlci5nZXRNYXN0ZXJBZGRyZXNzKCkuZ2V0UG9ydCgpJT48L2gxPg0KKzxwIGlkPSJsaW5rc19tZW51Ij48YSBocmVmPSIvbG9ncy8iPkxvY2FsIGxvZ3M8L2E+LCA8YSBocmVmPSIvc3RhY2tzIj5UaHJlYWQgRHVtcDwvYT4sIDxhIGhyZWY9Ii9sb2dMZXZlbCI+TG9nIExldmVsPC9hPjwvcD4NCis8aHIgaWQ9ImhlYWRfcnVsZSIgLz4NCisNCis8aDI+TWFzdGVyIEF0dHJpYnV0ZXM8L2gyPg0KKzx0YWJsZT4NCis8dHI+PHRoPkF0dHJpYnV0ZSBOYW1lPC90aD48dGg+VmFsdWU8L3RoPjx0aD5EZXNjcmlwdGlvbjwvdGg+PC90cj4NCis8dHI+PHRkPkhCYXNlIFZlcnNpb248L3RkPjx0ZD48JT0gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5WZXJzaW9uSW5mby5nZXRWZXJzaW9uKCkgJT4sIHI8JT0gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5WZXJzaW9uSW5mby5nZXRSZXZpc2lvbigpICU+PC90ZD48dGQ+SEJhc2UgdmVyc2lvbiBhbmQgc3ZuIHJldmlzaW9uPC90ZD48L3RyPg0KKzx0cj48dGQ+SEJhc2UgQ29tcGlsZWQ8L3RkPjx0ZD48JT0gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5WZXJzaW9uSW5mby5nZXREYXRlKCkgJT4sIDwlPSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlZlcnNpb25JbmZvLmdldFVzZXIoKSAlPjwvdGQ+PHRkPldoZW4gSEJhc2UgdmVyc2lvbiB3YXMgY29tcGlsZWQgYW5kIGJ5IHdob208L3RkPjwvdHI+DQorPHRyPjx0ZD5IYWRvb3AgVmVyc2lvbjwvdGQ+PHRkPjwlPSBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlZlcnNpb25JbmZvLmdldFZlcnNpb24oKSAlPiwgcjwlPSBvcmcuYXBhY2hlLmhhZG9vcC51dGlsLlZlcnNpb25JbmZvLmdldFJldmlzaW9uKCkgJT48L3RkPjx0ZD5IYWRvb3AgdmVyc2lvbiBhbmQgc3ZuIHJldmlzaW9uPC90ZD48L3RyPg0KKzx0cj48dGQ+SGFkb29wIENvbXBpbGVkPC90ZD48dGQ+PCU9IG9yZy5hcGFjaGUuaGFkb29wLnV0aWwuVmVyc2lvbkluZm8uZ2V0RGF0ZSgpICU+LCA8JT0gb3JnLmFwYWNoZS5oYWRvb3AudXRpbC5WZXJzaW9uSW5mby5nZXRVc2VyKCkgJT48L3RkPjx0ZD5XaGVuIEhhZG9vcCB2ZXJzaW9uIHdhcyBjb21waWxlZCBhbmQgYnkgd2hvbTwvdGQ+PC90cj4NCis8dHI+PHRkPkhCYXNlIFJvb3QgRGlyZWN0b3J5PC90ZD48dGQ+PCU9IG1hc3Rlci5nZXRSb290RGlyKCkudG9TdHJpbmcoKSAlPjwvdGQ+PHRkPkxvY2F0aW9uIG9mIEhCYXNlIGhvbWUgZGlyZWN0b3J5PC90ZD48L3RyPg0KKzx0cj48dGQ+TG9hZCBhdmVyYWdlPC90ZD48dGQ+PCU9IG1hc3Rlci5nZXRBdmVyYWdlTG9hZCgpICU+PC90ZD48dGQ+QXZlcmFnZSBsb2FkIGFjcm9zcyBhbGwgcmVnaW9uIHNlcnZlcnMuIE5haXZlIGNvbXB1dGF0aW9uLjwvdGQ+PC90cj4NCis8dHI+PHRkPlJlZ2lvbnMgT24gRlM8L3RkPjx0ZD48JT0gbWFzdGVyLmNvdW50UmVnaW9uc09uRlMoKSAlPjwvdGQ+PHRkPlRoZSBOdW1iZXIgb2YgcmVnaW9ucyBvbiBGaWxlU3lzdGVtLiBSb3VnaCBjb3VudC48L3RkPjwvdHI+DQorPC90YWJsZT4NCisNCis8aDI+Q2F0YWxvZyBUYWJsZXM8L2gyPg0KKzwlIA0KKyAgaWYgKHJvb3RMb2NhdGlvbiAhPSBudWxsKSB7ICU+DQorPHRhYmxlPg0KKzx0cj48dGg+VGFibGU8L3RoPjx0aD5EZXNjcmlwdGlvbjwvdGg+PC90cj4NCis8dHI+PHRkPjxhIGhyZWY9L3RhYmxlLmpzcD9uYW1lPTwlPSBVUkxFbmNvZGVyLmVuY29kZShCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSksICJVVEYtOCIpICU+PjwlPSBCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSkgJT48L2E+PC90ZD48dGQ+VGhlIC1ST09ULSB0YWJsZSBob2xkcyByZWZlcmVuY2VzIHRvIGFsbCAuTUVUQS4gcmVnaW9ucy48L3RkPjwvdHI+DQorPCUNCisgICAgaWYgKG9ubGluZVJlZ2lvbnMgIT0gbnVsbCAmJiBvbmxpbmVSZWdpb25zLnNpemUoKSA+IDApIHsgJT4NCis8dHI+PHRkPjxhIGhyZWY9L3RhYmxlLmpzcD9uYW1lPTwlPSBVUkxFbmNvZGVyLmVuY29kZShCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSksICJVVEYtOCIpICU+PjwlPSBCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLk1FVEFfVEFCTEVfTkFNRSkgJT48L2E+PC90ZD48dGQ+VGhlIC5NRVRBLiB0YWJsZSBob2xkcyByZWZlcmVuY2VzIHRvIGFsbCBVc2VyIFRhYmxlIHJlZ2lvbnM8L3RkPjwvdHI+DQorICANCis8JSAgfSAlPg0KKzwvdGFibGU+DQorPCV9ICU+DQorDQorPGgyPlVzZXIgVGFibGVzPC9oMj4NCis8JSBIVGFibGVEZXNjcmlwdG9yW10gdGFibGVzID0gbmV3IEhCYXNlQWRtaW4oY29uZikubGlzdFRhYmxlcygpOyANCisgICBpZih0YWJsZXMgIT0gbnVsbCAmJiB0YWJsZXMubGVuZ3RoID4gMCkgeyAlPg0KKzx0YWJsZT4NCis8dHI+PHRoPlRhYmxlPC90aD48dGg+RGVzY3JpcHRpb248L3RoPjwvdHI+DQorPCUgICBmb3IoSFRhYmxlRGVzY3JpcHRvciBodERlc2MgOiB0YWJsZXMgKSB7ICU+DQorPHRyPjx0ZD48YSBocmVmPS90YWJsZS5qc3A/bmFtZT08JT0gVVJMRW5jb2Rlci5lbmNvZGUoaHREZXNjLmdldE5hbWVBc1N0cmluZygpLCAiVVRGLTgiKSAlPj48JT0gaHREZXNjLmdldE5hbWVBc1N0cmluZygpICU+PC9hPiA8L3RkPjx0ZD48JT0gaHREZXNjLnRvU3RyaW5nKCkgJT48L3RkPjwvdHI+DQorPCUgICB9ICAlPg0KKzxwPiA8JT0gdGFibGVzLmxlbmd0aCAlPiB0YWJsZShzKSBpbiBzZXQuPC9wPg0KKzwvdGFibGU+DQorPCUgfSAlPg0KKw0KKzxoMj5SZWdpb24gU2VydmVyczwvaDI+DQorPCUgaWYgKHNlcnZlclRvU2VydmVySW5mb3MgIT0gbnVsbCAmJiBzZXJ2ZXJUb1NlcnZlckluZm9zLnNpemUoKSA+IDApIHsgJT4NCis8JSAgIGludCB0b3RhbFJlZ2lvbnMgPSAwOw0KKyAgICAgaW50IHRvdGFsUmVxdWVzdHMgPSAwOyANCislPg0KKw0KKzx0YWJsZT4NCis8dHI+PHRoIHJvd3NwYW49PCU9IHNlcnZlclRvU2VydmVySW5mb3Muc2l6ZSgpICsgMSU+PjwvdGg+PHRoPkFkZHJlc3M8L3RoPjx0aD5TdGFydCBDb2RlPC90aD48dGg+TG9hZDwvdGg+PC90cj4NCis8JSAgIFN0cmluZ1tdIHNlcnZlck5hbWVzID0gc2VydmVyVG9TZXJ2ZXJJbmZvcy5rZXlTZXQoKS50b0FycmF5KG5ldyBTdHJpbmdbc2VydmVyVG9TZXJ2ZXJJbmZvcy5zaXplKCldKTsNCisgICAgIEFycmF5cy5zb3J0KHNlcnZlck5hbWVzKTsNCisgICAgIGZvciAoU3RyaW5nIHNlcnZlck5hbWU6IHNlcnZlck5hbWVzKSB7DQorICAgICAgIEhTZXJ2ZXJJbmZvIGhzaSA9IHNlcnZlclRvU2VydmVySW5mb3MuZ2V0KHNlcnZlck5hbWUpOw0KKyAgICAgICBTdHJpbmcgaG9zdG5hbWUgPSBoc2kuZ2V0TmFtZSgpICsgIjoiICsgaHNpLmdldEluZm9Qb3J0KCk7DQorICAgICAgIFN0cmluZyB1cmwgPSAiaHR0cDovLyIgKyBob3N0bmFtZSArICIvIjsNCisgICAgICAgdG90YWxSZWdpb25zICs9IGhzaS5nZXRMb2FkKCkuZ2V0TnVtYmVyT2ZSZWdpb25zKCk7DQorICAgICAgIHRvdGFsUmVxdWVzdHMgKz0gaHNpLmdldExvYWQoKS5nZXROdW1iZXJPZlJlcXVlc3RzKCkgLyBpbnRlcnZhbDsNCisgICAgICAgbG9uZyBzdGFydENvZGUgPSBoc2kuZ2V0U3RhcnRDb2RlKCk7DQorJT4NCis8dHI+PHRkPjxhIGhyZWY9IjwlPSB1cmwgJT4iPjwlPSBob3N0bmFtZSAlPjwvYT48L3RkPjx0ZD48JT0gc3RhcnRDb2RlICU+PC90ZD48dGQ+PCU9IGhzaS5nZXRMb2FkKCkudG9TdHJpbmcoaW50ZXJ2YWwpICU+PC90ZD48L3RyPg0KKzwlICAgfSAlPg0KKzx0cj48dGg+VG90YWw6IDwvdGg+PHRkPnNlcnZlcnM6IDwlPSBzZXJ2ZXJUb1NlcnZlckluZm9zLnNpemUoKSAlPjwvdGQ+PHRkPiZuYnNwOzwvdGQ+PHRkPnJlcXVlc3RzPTwlPSB0b3RhbFJlcXVlc3RzICU+LCByZWdpb25zPTwlPSB0b3RhbFJlZ2lvbnMgJT48L3RkPjwvdHI+DQorPC90YWJsZT4NCisNCis8cD5Mb2FkIGlzIHJlcXVlc3RzIHBlciBzZWNvbmQgYW5kIGNvdW50IG9mIHJlZ2lvbnMgbG9hZGVkPC9wPg0KKzwlIH0gJT4NCis8L2JvZHk+DQorPC9odG1sPg0KZGlmZiAtLWdpdCBhL3NyYy93ZWJhcHBzL21hc3Rlci9yZWdpb25oaXN0b3JpYW4uanNwIGIvc3JjL3dlYmFwcHMvbWFzdGVyL3JlZ2lvbmhpc3Rvcmlhbi5qc3AKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWZiYzk5ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy93ZWJhcHBzL21hc3Rlci9yZWdpb25oaXN0b3JpYW4uanNwCkBAIC0wLDAgKzEsNTYgQEAKKzwlQCBwYWdlIGNvbnRlbnRUeXBlPSJ0ZXh0L2h0bWw7Y2hhcnNldD1VVEYtOCIKKyAgaW1wb3J0PSJqYXZhLnV0aWwuTGlzdCIKKyAgaW1wb3J0PSJqYXZhLnV0aWwucmVnZXguKiIKKyAgaW1wb3J0PSJqYXZhLm5ldC5VUkxFbmNvZGVyIiAKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5SZWdpb25IaXN0b3JpYW4iCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyLkhNYXN0ZXIiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuUmVnaW9uSGlzdG9yaWFuLlJlZ2lvbkhpc3RvcnlJbmZvcm1hdGlvbiIKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzIiU+PCUKKyAgU3RyaW5nIHJlZ2lvbk5hbWUgPSByZXF1ZXN0LmdldFBhcmFtZXRlcigicmVnaW9ubmFtZSIpOworICBITWFzdGVyIG1hc3RlciA9IChITWFzdGVyKWdldFNlcnZsZXRDb250ZXh0KCkuZ2V0QXR0cmlidXRlKEhNYXN0ZXIuTUFTVEVSKTsKKyAgTGlzdDxSZWdpb25IaXN0b3J5SW5mb3JtYXRpb24+IGluZm9ybWF0aW9ucyA9IFJlZ2lvbkhpc3Rvcmlhbi5nZXRJbnN0YW5jZSgpLmdldFJlZ2lvbkhpc3RvcnkocmVnaW9uTmFtZSk7CisgIC8vIFBhdHRlcm4gdXNlZCBzbyB3ZSBjYW4gd3JhcCBhIHJlZ2lvbm5hbWUgaW4gYW4gaHJlZi4KKyAgUGF0dGVybiBwYXR0ZXJuID0gUGF0dGVybi5jb21waWxlKFJlZ2lvbkhpc3Rvcmlhbi5TUExJVF9QUkVGSVggKyAiKC4qKSQiKTsKKyU+PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiID8+Cis8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEuMCBUcmFuc2l0aW9uYWwvL0VOIiAKKyAgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXRyYW5zaXRpb25hbC5kdGQiPiAKKzxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KKzxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sO2NoYXJzZXQ9VVRGLTgiLz4KKyAgICAgIDxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjMwIi8+Cis8dGl0bGU+UmVnaW9uIGluIDwlPSByZWdpb25OYW1lICU+PC90aXRsZT4KKzxsaW5rIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIGhyZWY9Ii9zdGF0aWMvaGJhc2UuY3NzIiAvPgorPC9oZWFkPgorCis8Ym9keT4KKzxhIGlkPSJsb2dvIiBocmVmPSJodHRwOi8vd2lraS5hcGFjaGUub3JnL2x1Y2VuZS1oYWRvb3AvSGJhc2UiPjxpbWcgc3JjPSIvc3RhdGljL2hiYXNlX2xvZ29fbWVkLmdpZiIgYWx0PSJIQmFzZSBMb2dvIiB0aXRsZT0iSEJhc2UgTG9nbyIgLz48L2E+Cis8aDEgaWQ9InBhZ2VfdGl0bGUiPlJlZ2lvbiA8JT0gcmVnaW9uTmFtZSAlPjwvaDE+Cis8cCBpZD0ibGlua3NfbWVudSI+PGEgaHJlZj0iL21hc3Rlci5qc3AiPk1hc3RlcjwvYT4sIDxhIGhyZWY9Ii9sb2dzLyI+TG9jYWwgbG9nczwvYT4sIDxhIGhyZWY9Ii9zdGFja3MiPlRocmVhZCBEdW1wPC9hPiwgPGEgaHJlZj0iL2xvZ0xldmVsIj5Mb2cgTGV2ZWw8L2E+PC9wPgorPGhyIGlkPSJoZWFkX3J1bGUiIC8+Cis8JWlmKGluZm9ybWF0aW9ucyAhPSBudWxsICYmIGluZm9ybWF0aW9ucy5zaXplKCkgPiAwKSB7ICU+Cis8dGFibGU+PHRyPjx0aD5UaW1lc3RhbXA8L3RoPjx0aD5FdmVudDwvdGg+PHRoPkRlc2NyaXB0aW9uPC90aD48L3RyPgorPCUgIGZvciggUmVnaW9uSGlzdG9yeUluZm9ybWF0aW9uIGluZm9ybWF0aW9uIDogaW5mb3JtYXRpb25zKSB7CisgICAgU3RyaW5nIGRlc2NyaXB0aW9uID0gaW5mb3JtYXRpb24uZ2V0RGVzY3JpcHRpb24oKTsKKyAgICBNYXRjaGVyIG0gPSBwYXR0ZXJuLm1hdGNoZXIoZGVzY3JpcHRpb24pOworICAgIGlmIChtLm1hdGNoZXMoKSkgeworICAgICAgLy8gV3JhcCB0aGUgcmVnaW9uIG5hbWUgaW4gYW4gaHJlZiBzbyB1c2VyIGNhbiBjbGljayBvbiBpdC4KKyAgICAgIGRlc2NyaXB0aW9uID0gUmVnaW9uSGlzdG9yaWFuLlNQTElUX1BSRUZJWCArCisgICAgICAiPGEgaHJlZj1cInJlZ2lvbmhpc3Rvcmlhbi5qc3A/cmVnaW9ubmFtZT0iICsgVVJMRW5jb2Rlci5lbmNvZGUobS5ncm91cCgxKSwgIlVURi04IikgKyAiXCI+IiArCisgICAgICAgIG0uZ3JvdXAoMSkgKyAiPC9hPiI7CisgICAgfQorICAgIAorICAgICU+Cis8dHI+PHRkPjwlPSBpbmZvcm1hdGlvbi5nZXRUaW1lc3RhbXBBc1N0cmluZygpICU+PC90ZD48dGQ+PCU9IGluZm9ybWF0aW9uLmdldEV2ZW50KCkgJT48L3RkPjx0ZD48JT0gZGVzY3JpcHRpb24gJT48L3RkPjwvdHI+Cis8JSAgfSAlPgorPC90YWJsZT4KKzxwPgorTWFzdGVyIGlzIHRoZSBzb3VyY2Ugb2YgZm9sbG93aW5nIGV2ZW50czogY3JlYXRpb24sIG9wZW4sIGFuZCBhc3NpZ25tZW50LiAgUmVnaW9ucyBhcmUgdGhlIHNvdXJjZSBvZiBmb2xsb3dpbmcgZXZlbnRzOiBzcGxpdCwgY29tcGFjdGlvbiwgYW5kIGZsdXNoLgorPC9wPgorPCV9IGVsc2UgeyU+Cis8cD4KK1RoaXMgcmVnaW9uIGlzIG5vIGxvbmdlciBhdmFpbGFibGUuIEl0IG1heSBiZSBkdWUgdG8gYSBzcGxpdCwgYSBtZXJnZSBvciB0aGUgbmFtZSBjaGFuZ2VkLgorPC9wPgorPCV9ICU+CisKKworPC9ib2R5PgorPC9odG1sPgpkaWZmIC0tZ2l0IGEvc3JjL3dlYmFwcHMvbWFzdGVyL3RhYmxlLmpzcCBiL3NyYy93ZWJhcHBzL21hc3Rlci90YWJsZS5qc3AKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDVjYjNiOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy93ZWJhcHBzL21hc3Rlci90YWJsZS5qc3AKQEAgLTAsMCArMSwxOTggQEAKKzwlQCBwYWdlIGNvbnRlbnRUeXBlPSJ0ZXh0L2h0bWw7Y2hhcnNldD1VVEYtOCIKKyAgaW1wb3J0PSJqYXZhLmlvLklPRXhjZXB0aW9uIgorICBpbXBvcnQ9ImphdmEudXRpbC5NYXAiCisgIGltcG9ydD0iamF2YS5uZXQuVVJMRW5jb2RlciIgCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaW8uVGV4dCIKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5pby5Xcml0YWJsZSIKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IVGFibGVEZXNjcmlwdG9yIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmNsaWVudC5IVGFibGUiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuY2xpZW50LkhCYXNlQWRtaW4iCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFJlZ2lvbkluZm8iCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckFkZHJlc3MiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSFNlcnZlckluZm8iCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSEJhc2VDb25maWd1cmF0aW9uIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLmlvLkltbXV0YWJsZUJ5dGVzV3JpdGFibGUiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UubWFzdGVyLkhNYXN0ZXIiIAorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLm1hc3Rlci5NZXRhUmVnaW9uIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuQnl0ZXMiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UuSENvbnN0YW50cyIlPjwlCisgIEhNYXN0ZXIgbWFzdGVyID0gKEhNYXN0ZXIpZ2V0U2VydmxldENvbnRleHQoKS5nZXRBdHRyaWJ1dGUoSE1hc3Rlci5NQVNURVIpOworICBIQmFzZUNvbmZpZ3VyYXRpb24gY29uZiA9IG1hc3Rlci5nZXRDb25maWd1cmF0aW9uKCk7CisgIEhCYXNlQWRtaW4gaGJhZG1pbiA9IG5ldyBIQmFzZUFkbWluKGNvbmYpOworICBTdHJpbmcgdGFibGVOYW1lID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoIm5hbWUiKTsKKyAgSFRhYmxlIHRhYmxlID0gbmV3IEhUYWJsZShjb25mLCB0YWJsZU5hbWUpOworICBNYXA8SFNlcnZlckFkZHJlc3MsIEhTZXJ2ZXJJbmZvPiBzZXJ2ZXJBZGRyZXNzVG9TZXJ2ZXJJbmZvcyA9CisgICAgICBtYXN0ZXIuZ2V0U2VydmVyQWRkcmVzc1RvU2VydmVySW5mbygpOworICBTdHJpbmcgdGFibGVIZWFkZXIgPSAiPGgyPlRhYmxlIFJlZ2lvbnM8L2gyPjx0YWJsZT48dHI+PHRoPk5hbWU8L3RoPjx0aD5SZWdpb24gU2VydmVyPC90aD48dGg+RW5jb2RlZCBOYW1lPC90aD48dGg+U3RhcnQgS2V5PC90aD48dGg+RW5kIEtleTwvdGg+PC90cj4iOworICBIU2VydmVyQWRkcmVzcyByb290TG9jYXRpb24gPSBtYXN0ZXIuZ2V0Um9vdFJlZ2lvbkxvY2F0aW9uKCk7CislPgorCis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCIgPz4KKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iIAorICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtdHJhbnNpdGlvbmFsLmR0ZCI+IAorPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgorCis8JQorICBTdHJpbmcgYWN0aW9uID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoImFjdGlvbiIpOworICBTdHJpbmcga2V5ID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoImtleSIpOworICBpZiAoIGFjdGlvbiAhPSBudWxsICkgeworJT4KKzxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sO2NoYXJzZXQ9VVRGLTgiLz4KKyAgICAgIDxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjU7IHVybD0vIi8+Cis8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBocmVmPSIvc3RhdGljL2hiYXNlLmNzcyIgLz4KKzwvaGVhZD4KKzxib2R5PgorPGEgaWQ9ImxvZ28iIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvbHVjZW5lLWhhZG9vcC9IYmFzZSI+PGltZyBzcmM9Ii9zdGF0aWMvaGJhc2VfbG9nb19tZWQuZ2lmIiBhbHQ9IkhCYXNlIExvZ28iIHRpdGxlPSJIQmFzZSBMb2dvIiAvPjwvYT4KKzxoMSBpZD0icGFnZV90aXRsZSI+VGFibGUgYWN0aW9uIHJlcXVlc3QgYWNjZXB0ZWQ8L2gxPgorPHA+PGhyPjxwPgorPCUKKyAgaWYgKGFjdGlvbi5lcXVhbHMoInNwbGl0IikpIHsKKyAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5Lmxlbmd0aCgpID4gMCkgeworICAgICAgV3JpdGFibGVbXSBhcnIgPSBuZXcgV3JpdGFibGVbMV07CisgICAgICBhcnJbMF0gPSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKGtleSkpOworICAgICAgbWFzdGVyLm1vZGlmeVRhYmxlKEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSwgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfU1BMSVQsIGFycik7CisgICAgfSBlbHNlIHsKKyAgICAgIG1hc3Rlci5tb2RpZnlUYWJsZShCeXRlcy50b0J5dGVzKHRhYmxlTmFtZSksIEhDb25zdGFudHMuTU9ESUZZX1RBQkxFX1NQTElULCBudWxsKTsKKyAgICB9CisgICAgJT4gU3BsaXQgcmVxdWVzdCBhY2NlcHRlZC4gPCUKKyAgfSBlbHNlIGlmIChhY3Rpb24uZXF1YWxzKCJjb21wYWN0IikpIHsKKyAgICBpZiAoa2V5ICE9IG51bGwgJiYga2V5Lmxlbmd0aCgpID4gMCkgeworICAgICAgV3JpdGFibGVbXSBhcnIgPSBuZXcgV3JpdGFibGVbMV07CisgICAgICBhcnJbMF0gPSBuZXcgSW1tdXRhYmxlQnl0ZXNXcml0YWJsZShCeXRlcy50b0J5dGVzKGtleSkpOworICAgICAgbWFzdGVyLm1vZGlmeVRhYmxlKEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSwgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfQ09NUEFDVCwgYXJyKTsKKyAgICB9IGVsc2UgeworICAgICAgbWFzdGVyLm1vZGlmeVRhYmxlKEJ5dGVzLnRvQnl0ZXModGFibGVOYW1lKSwgSENvbnN0YW50cy5NT0RJRllfVEFCTEVfQ09NUEFDVCwgbnVsbCk7CisgICAgfQorICAgICU+IENvbXBhY3QgcmVxdWVzdCBhY2NlcHRlZC4gPCUKKyAgfQorJT4KKzxwPlRoaXMgcGFnZSB3aWxsIHJlZnJlc2ggaW4gNSBzZWNvbmRzLgorPC9ib2R5PgorPCUKK30gZWxzZSB7CislPgorPGhlYWQ+PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7Y2hhcnNldD1VVEYtOCIvPgorICAgICAgPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzAiLz4KKzx0aXRsZT5UYWJsZTogPCU9IHRhYmxlTmFtZSAlPjwvdGl0bGU+Cis8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBocmVmPSIvc3RhdGljL2hiYXNlLmNzcyIgLz4KKzwvaGVhZD4KKzxib2R5PgorPGEgaWQ9ImxvZ28iIGhyZWY9Imh0dHA6Ly93aWtpLmFwYWNoZS5vcmcvbHVjZW5lLWhhZG9vcC9IYmFzZSI+PGltZyBzcmM9Ii9zdGF0aWMvaGJhc2VfbG9nb19tZWQuZ2lmIiBhbHQ9IkhCYXNlIExvZ28iIHRpdGxlPSJIQmFzZSBMb2dvIiAvPjwvYT4KKzxoMSBpZD0icGFnZV90aXRsZSI+VGFibGU6IDwlPSB0YWJsZU5hbWUgJT48L2gxPgorPHAgaWQ9ImxpbmtzX21lbnUiPjxhIGhyZWY9Ii9tYXN0ZXIuanNwIj5NYXN0ZXI8L2E+LCA8YSBocmVmPSIvbG9ncy8iPkxvY2FsIGxvZ3M8L2E+LCA8YSBocmVmPSIvc3RhY2tzIj5UaHJlYWQgRHVtcDwvYT4sIDxhIGhyZWY9Ii9sb2dMZXZlbCI+TG9nIExldmVsPC9hPjwvcD4KKzxociBpZD0iaGVhZF9ydWxlIiAvPgorPCUKKyAgaWYodGFibGVOYW1lLmVxdWFscyhCeXRlcy50b1N0cmluZyhIQ29uc3RhbnRzLlJPT1RfVEFCTEVfTkFNRSkpKSB7CislPgorPCU9IHRhYmxlSGVhZGVyICU+Cis8JQorICBpbnQgaW5mb1BvcnQgPSBzZXJ2ZXJBZGRyZXNzVG9TZXJ2ZXJJbmZvcy5nZXQocm9vdExvY2F0aW9uKS5nZXRJbmZvUG9ydCgpOworICBTdHJpbmcgdXJsID0gImh0dHA6Ly8iICsgcm9vdExvY2F0aW9uLmdldEhvc3RuYW1lKCkgKyAiOiIgKyBpbmZvUG9ydCArICIvIjsKKyU+Cis8dHI+CisgIDx0ZD48JT0gdGFibGVOYW1lICU+PC90ZD4KKyAgPHRkPjxhIGhyZWY9IjwlPSB1cmwgJT4iPjwlPSByb290TG9jYXRpb24uZ2V0SG9zdG5hbWUoKSAlPjo8JT0gcm9vdExvY2F0aW9uLmdldFBvcnQoKSAlPjwvYT48L3RkPgorICA8dGQ+LTwvdGQ+CisgIDx0ZD48L3RkPgorICA8dGQ+LTwvdGQ+Cis8L3RyPgorPC90YWJsZT4KKzwlCisgIH0gZWxzZSBpZih0YWJsZU5hbWUuZXF1YWxzKEJ5dGVzLnRvU3RyaW5nKEhDb25zdGFudHMuTUVUQV9UQUJMRV9OQU1FKSkpIHsKKyU+Cis8JT0gdGFibGVIZWFkZXIgJT4KKzwlCisgIE1hcDxieXRlIFtdLCBNZXRhUmVnaW9uPiBvbmxpbmVSZWdpb25zID0gbWFzdGVyLmdldE9ubGluZU1ldGFSZWdpb25zKCk7CisgIGZvciAoTWV0YVJlZ2lvbiBtZXRhOiBvbmxpbmVSZWdpb25zLnZhbHVlcygpKSB7CisgICAgaW50IGluZm9Qb3J0ID0gc2VydmVyQWRkcmVzc1RvU2VydmVySW5mb3MuZ2V0KG1ldGEuZ2V0U2VydmVyKCkpLmdldEluZm9Qb3J0KCk7CisgICAgU3RyaW5nIHVybCA9ICJodHRwOi8vIiArIG1ldGEuZ2V0U2VydmVyKCkuZ2V0SG9zdG5hbWUoKSArICI6IiArIGluZm9Qb3J0ICsgIi8iOworJT4KKzx0cj4KKyAgPHRkPjwlPSBCeXRlcy50b1N0cmluZyhtZXRhLmdldFJlZ2lvbk5hbWUoKSkgJT48L3RkPgorICAgIDx0ZD48YSBocmVmPSI8JT0gdXJsICU+Ij48JT0gbWV0YS5nZXRTZXJ2ZXIoKS50b1N0cmluZygpICU+PC9hPjwvdGQ+CisgICAgPHRkPi08L3RkPjx0ZD48JT0gQnl0ZXMudG9TdHJpbmcobWV0YS5nZXRTdGFydEtleSgpKSAlPjwvdGQ+PHRkPi08L3RkPgorPC90cj4KKzwlICB9ICU+Cis8L3RhYmxlPgorPCV9IGVsc2UgeworICB0cnkgeyAlPgorPGgyPlRhYmxlIEF0dHJpYnV0ZXM8L2gyPgorPHRhYmxlPgorICA8dHI+PHRoPkF0dHJpYnV0ZSBOYW1lPC90aD48dGg+VmFsdWU8L3RoPjx0aD5EZXNjcmlwdGlvbjwvdGg+PC90cj4KKyAgPHRyPjx0ZD5FbmFibGVkPC90ZD48dGQ+PCU9IGhiYWRtaW4uaXNUYWJsZUVuYWJsZWQodGFibGUuZ2V0VGFibGVOYW1lKCkpICU+PC90ZD48dGQ+SXMgdGhlIHRhYmxlIGVuYWJsZWQ8L3RkPjwvdHI+Cis8L3RhYmxlPgorPCUKKyAgTWFwPEhSZWdpb25JbmZvLCBIU2VydmVyQWRkcmVzcz4gcmVnaW9ucyA9IHRhYmxlLmdldFJlZ2lvbnNJbmZvKCk7CisgIGlmKHJlZ2lvbnMgIT0gbnVsbCAmJiByZWdpb25zLnNpemUoKSA+IDApIHsgJT4KKzwlPSAgICAgdGFibGVIZWFkZXIgJT4KKzwlCisgIGZvcihNYXAuRW50cnk8SFJlZ2lvbkluZm8sIEhTZXJ2ZXJBZGRyZXNzPiBocmlFbnRyeSA6IHJlZ2lvbnMuZW50cnlTZXQoKSkgeworICAgIAorICAgIGludCBpbmZvUG9ydCA9IHNlcnZlckFkZHJlc3NUb1NlcnZlckluZm9zLmdldCgKKyAgICAgICAgaHJpRW50cnkuZ2V0VmFsdWUoKSkuZ2V0SW5mb1BvcnQoKTsKKyAgICAKKyAgICBTdHJpbmcgdXJsUmVnaW9uSGlzdG9yaWFuID0KKyAgICAgICAgIi9yZWdpb25oaXN0b3JpYW4uanNwP3JlZ2lvbm5hbWU9IiArIAorICAgICAgICBVUkxFbmNvZGVyLmVuY29kZShocmlFbnRyeS5nZXRLZXkoKS5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSwgIlVURi04Iik7CisKKyAgICBTdHJpbmcgdXJsUmVnaW9uU2VydmVyID0KKyAgICAgICAgImh0dHA6Ly8iICsgaHJpRW50cnkuZ2V0VmFsdWUoKS5nZXRIb3N0bmFtZSgpLnRvU3RyaW5nKCkgKyAiOiIgKyBpbmZvUG9ydCArICIvIjsKKyU+Cis8dHI+CisgIDx0ZD48YSBocmVmPSI8JT0gdXJsUmVnaW9uSGlzdG9yaWFuICU+Ij48JT0gaHJpRW50cnkuZ2V0S2V5KCkuZ2V0UmVnaW9uTmFtZUFzU3RyaW5nKCklPjwvYT48L3RkPgorICA8dGQ+PGEgaHJlZj0iPCU9IHVybFJlZ2lvblNlcnZlciAlPiI+PCU9IGhyaUVudHJ5LmdldFZhbHVlKCkudG9TdHJpbmcoKSAlPjwvYT48L3RkPgorICA8dGQ+PCU9IGhyaUVudHJ5LmdldEtleSgpLmdldEVuY29kZWROYW1lKCklPjwvdGQ+IDx0ZD48JT0gQnl0ZXMudG9TdHJpbmcoaHJpRW50cnkuZ2V0S2V5KCkuZ2V0U3RhcnRLZXkoKSklPjwvdGQ+CisgIDx0ZD48JT0gQnl0ZXMudG9TdHJpbmcoaHJpRW50cnkuZ2V0S2V5KCkuZ2V0RW5kS2V5KCkpJT48L3RkPgorPC90cj4KKzwlIH0gJT4KKzwvdGFibGU+Cis8JSB9Cit9IGNhdGNoKEV4Y2VwdGlvbiBleCkgeworICBleC5wcmludFN0YWNrVHJhY2UoKTsKK30KK30gLy8gZW5kIGVsc2UKKyU+CisKKzxwPjxocj48cD4KK0FjdGlvbnM6Cis8cD4KKzxjZW50ZXI+Cis8dGFibGUgc3R5bGU9ImJvcmRlci1zdHlsZTogbm9uZSIgd2lkdGg9IjkwJSI+Cis8dHI+CisgIDxmb3JtIG1ldGhvZD0iZ2V0Ij4KKyAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYWN0aW9uIiB2YWx1ZT0iY29tcGFjdCI+CisgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im5hbWUiIHZhbHVlPSI8JT0gdGFibGVOYW1lICU+Ij4KKyAgPHRkIHN0eWxlPSJib3JkZXItc3R5bGU6IG5vbmU7IHRleHQtYWxpZ246IGNlbnRlciI+CisgICAgICA8aW5wdXQgc3R5bGU9ImZvbnQtc2l6ZTogMTJwdDsgd2lkdGg6IDEwZW0iIHR5cGU9InN1Ym1pdCIgdmFsdWU9IkNvbXBhY3QiPjwvdGQ+CisgIDx0ZCBzdHlsZT0iYm9yZGVyLXN0eWxlOiBub25lIiB3aWR0aD0iNSUiPiZuYnNwOzwvdGQ+CisgIDx0ZCBzdHlsZT0iYm9yZGVyLXN0eWxlOiBub25lIj5SZWdpb24gS2V5IChvcHRpb25hbCk6PGlucHV0IHR5cGU9InRleHQiIG5hbWU9ImtleSIgc2l6ZT0iNDAiPjwvdGQ+CisgIDx0ZCBzdHlsZT0iYm9yZGVyLXN0eWxlOiBub25lIj5UaGlzIGFjdGlvbiB3aWxsIGZvcmNlIGEgY29tcGFjdGlvbiBvZiBhbGwKKyAgcmVnaW9ucyBvZiB0aGUgdGFibGUsIG9yLCBpZiBhIGtleSBpcyBzdXBwbGllZCwgb25seSB0aGUgcmVnaW9uIGNvbnRhaW5pbmcgdGhlCisgIGdpdmVuIGtleS48L3RkPgorICA8L2Zvcm0+Cis8L3RyPgorPHRyPjx0ZCBzdHlsZT0iYm9yZGVyLXN0eWxlOiBub25lIiBjb2xzcGFuPSI0Ij4mbmJzcDs8L3RkPjwvdHI+Cis8dHI+CisgIDxmb3JtIG1ldGhvZD0iZ2V0Ij4KKyAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYWN0aW9uIiB2YWx1ZT0ic3BsaXQiPgorICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJuYW1lIiB2YWx1ZT0iPCU9IHRhYmxlTmFtZSAlPiI+CisgIDx0ZCBzdHlsZT0iYm9yZGVyLXN0eWxlOiBub25lOyB0ZXh0LWFsaWduOiBjZW50ZXIiPgorICAgICAgPGlucHV0IHN0eWxlPSJmb250LXNpemU6IDEycHQ7IHdpZHRoOiAxMGVtIiB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTcGxpdCI+PC90ZD4KKyAgPHRkIHN0eWxlPSJib3JkZXItc3R5bGU6IG5vbmUiIHdpZHRoPSI1JSI+Jm5ic3A7PC90ZD4KKyAgPHRkIHN0eWxlPSJib3JkZXItc3R5bGU6IG5vbmUiPlJlZ2lvbiBLZXkgKG9wdGlvbmFsKTo8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0ia2V5IiBzaXplPSI0MCI+PC90ZD4KKyAgPHRkIHN0eWxlPSJib3JkZXItc3R5bGU6IG5vbmUiPlRoaXMgYWN0aW9uIHdpbGwgZm9yY2UgYSBzcGxpdCBvZiBhbGwgZWxpZ2libGUKKyAgcmVnaW9ucyBvZiB0aGUgdGFibGUsIG9yLCBpZiBhIGtleSBpcyBzdXBwbGllZCwgb25seSB0aGUgcmVnaW9uIGNvbnRhaW5pbmcgdGhlCisgIGdpdmVuIGtleS4gQW4gZWxpZ2libGUgcmVnaW9uIGlzIG9uZSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gYW55IHJlZmVyZW5jZXMgdG8KKyAgb3RoZXIgcmVnaW9ucy4gU3BsaXQgcmVxdWVzdHMgZm9yIG5vbmVsaWdpYmxlIHJlZ2lvbnMgd2lsbCBiZSBpZ25vcmVkLjwvdGQ+CisgIDwvZm9ybT4KKzwvdHI+Cis8L3RhYmxlPgorPC9jZW50ZXI+Cis8cD4KKworPCUKK30KKyU+CisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL3NyYy93ZWJhcHBzL3JlZ2lvbnNlcnZlci9pbmRleC5odG1sIGIvc3JjL3dlYmFwcHMvcmVnaW9uc2VydmVyL2luZGV4Lmh0bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmRkM2M2YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy93ZWJhcHBzL3JlZ2lvbnNlcnZlci9pbmRleC5odG1sCkBAIC0wLDAgKzEgQEAKKzxtZXRhIEhUVFAtRVFVSVY9IlJFRlJFU0giIGNvbnRlbnQ9IjA7dXJsPXJlZ2lvbnNlcnZlci5qc3AiLz4KZGlmZiAtLWdpdCBhL3NyYy93ZWJhcHBzL3JlZ2lvbnNlcnZlci9yZWdpb25zZXJ2ZXIuanNwIGIvc3JjL3dlYmFwcHMvcmVnaW9uc2VydmVyL3JlZ2lvbnNlcnZlci5qc3AKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmUxZTYwZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy93ZWJhcHBzL3JlZ2lvbnNlcnZlci9yZWdpb25zZXJ2ZXIuanNwCkBAIC0wLDAgKzEsNzEgQEAKKzwlQCBwYWdlIGNvbnRlbnRUeXBlPSJ0ZXh0L2h0bWw7Y2hhcnNldD1VVEYtOCIKKyAgaW1wb3J0PSJqYXZhLnV0aWwuKiIKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5pby5UZXh0IgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uU2VydmVyIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5IUmVnaW9uIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnJlZ2lvbnNlcnZlci5tZXRyaWNzLlJlZ2lvblNlcnZlck1ldHJpY3MiCisgIGltcG9ydD0ib3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5CeXRlcyIKKyAgaW1wb3J0PSJvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5IQ29uc3RhbnRzIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJJbmZvIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhTZXJ2ZXJMb2FkIgorICBpbXBvcnQ9Im9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLkhSZWdpb25JbmZvIiAlPjwlCisgIEhSZWdpb25TZXJ2ZXIgcmVnaW9uU2VydmVyID0gKEhSZWdpb25TZXJ2ZXIpZ2V0U2VydmxldENvbnRleHQoKS5nZXRBdHRyaWJ1dGUoSFJlZ2lvblNlcnZlci5SRUdJT05TRVJWRVIpOworICBIU2VydmVySW5mbyBzZXJ2ZXJJbmZvID0gcmVnaW9uU2VydmVyLmdldFNlcnZlckluZm8oKTsKKyAgUmVnaW9uU2VydmVyTWV0cmljcyBtZXRyaWNzID0gcmVnaW9uU2VydmVyLmdldE1ldHJpY3MoKTsKKyAgQ29sbGVjdGlvbjxIUmVnaW9uSW5mbz4gb25saW5lUmVnaW9ucyA9IHJlZ2lvblNlcnZlci5nZXRTb3J0ZWRPbmxpbmVSZWdpb25JbmZvcygpOworICBpbnQgaW50ZXJ2YWwgPSByZWdpb25TZXJ2ZXIuZ2V0Q29uZmlndXJhdGlvbigpLmdldEludCgiaGJhc2UucmVnaW9uc2VydmVyLm1zZ2ludGVydmFsIiwgMzAwMCkvMTAwMDsKKworJT48P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCIgPz4KKzwhRE9DVFlQRSBodG1sIFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iIAorICAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0bWwxL0RURC94aHRtbDEtdHJhbnNpdGlvbmFsLmR0ZCI+IAorPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgorPGhlYWQ+PG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7Y2hhcnNldD1VVEYtOCIvPgorICAgICAgPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzAwIi8+Cis8dGl0bGU+SEJhc2UgUmVnaW9uIFNlcnZlcjogPCU9IHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLmdldEhvc3RuYW1lKCkgJT46PCU9IHNlcnZlckluZm8uZ2V0U2VydmVyQWRkcmVzcygpLmdldFBvcnQoKSAlPjwvdGl0bGU+Cis8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBocmVmPSIvc3RhdGljL2hiYXNlLmNzcyIgLz4KKzwvaGVhZD4KKworPGJvZHk+Cis8YSBpZD0ibG9nbyIgaHJlZj0iaHR0cDovL3dpa2kuYXBhY2hlLm9yZy9sdWNlbmUtaGFkb29wL0hiYXNlIj48aW1nIHNyYz0iL3N0YXRpYy9oYmFzZV9sb2dvX21lZC5naWYiIGFsdD0iSEJhc2UgTG9nbyIgdGl0bGU9IkhCYXNlIExvZ28iIC8+PC9hPgorPGgxIGlkPSJwYWdlX3RpdGxlIj5SZWdpb24gU2VydmVyOiA8JT0gc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkuZ2V0SG9zdG5hbWUoKSAlPjo8JT0gc2VydmVySW5mby5nZXRTZXJ2ZXJBZGRyZXNzKCkuZ2V0UG9ydCgpICU+PC9oMT4KKzxwIGlkPSJsaW5rc19tZW51Ij48YSBocmVmPSIvbG9ncy8iPkxvY2FsIGxvZ3M8L2E+LCA8YSBocmVmPSIvc3RhY2tzIj5UaHJlYWQgRHVtcDwvYT4sIDxhIGhyZWY9Ii9sb2dMZXZlbCI+TG9nIExldmVsPC9hPjwvcD4KKzxociBpZD0iaGVhZF9ydWxlIiAvPgorCis8aDI+UmVnaW9uIFNlcnZlciBBdHRyaWJ1dGVzPC9oMj4KKzx0YWJsZT4KKzx0cj48dGg+QXR0cmlidXRlIE5hbWU8L3RoPjx0aD5WYWx1ZTwvdGg+PHRoPkRlc2NyaXB0aW9uPC90aD48L3RyPgorPHRyPjx0ZD5IQmFzZSBWZXJzaW9uPC90ZD48dGQ+PCU9IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuVmVyc2lvbkluZm8uZ2V0VmVyc2lvbigpICU+LCByPCU9IG9yZy5hcGFjaGUuaGFkb29wLmhiYXNlLnV0aWwuVmVyc2lvbkluZm8uZ2V0UmV2aXNpb24oKSAlPjwvdGQ+PHRkPkhCYXNlIHZlcnNpb24gYW5kIHN2biByZXZpc2lvbjwvdGQ+PC90cj4KKzx0cj48dGQ+SEJhc2UgQ29tcGlsZWQ8L3RkPjx0ZD48JT0gb3JnLmFwYWNoZS5oYWRvb3AuaGJhc2UudXRpbC5WZXJzaW9uSW5mby5nZXREYXRlKCkgJT4sIDwlPSBvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS51dGlsLlZlcnNpb25JbmZvLmdldFVzZXIoKSAlPjwvdGQ+PHRkPldoZW4gSEJhc2UgdmVyc2lvbiB3YXMgY29tcGlsZWQgYW5kIGJ5IHdob208L3RkPjwvdHI+Cis8dHI+PHRkPk1ldHJpY3M8L3RkPjx0ZD48JT0gbWV0cmljcy50b1N0cmluZygpICU+PC90ZD48dGQ+UmVnaW9uU2VydmVyIE1ldHJpY3M7IGZpbGUgYW5kIGhlYXAgc2l6ZXMgYXJlIGluIG1lZ2FieXRlczwvdGQ+PC90cj4KKzwvdGFibGU+CisKKzxoMj5PbmxpbmUgUmVnaW9uczwvaDI+Cis8JSBpZiAob25saW5lUmVnaW9ucyAhPSBudWxsICYmIG9ubGluZVJlZ2lvbnMuc2l6ZSgpID4gMCkgeyAlPgorPHRhYmxlPgorPHRyPjx0aD5SZWdpb24gTmFtZTwvdGg+PHRoPkVuY29kZWQgTmFtZTwvdGg+PHRoPlN0YXJ0IEtleTwvdGg+PHRoPkVuZCBLZXk8L3RoPjx0aD5NZXRyaWNzPC90aD48L3RyPgorPCUgICBmb3IgKEhSZWdpb25JbmZvIHI6IG9ubGluZVJlZ2lvbnMpIHsgCisgICAgICAgIEhTZXJ2ZXJMb2FkLlJlZ2lvbkxvYWQgbG9hZCA9IHJlZ2lvblNlcnZlci5jcmVhdGVSZWdpb25Mb2FkKHIuZ2V0UmVnaW9uTmFtZSgpKTsKKyAlPgorPHRyPjx0ZD48JT0gci5nZXRSZWdpb25OYW1lQXNTdHJpbmcoKSAlPjwvdGQ+PHRkPjwlPSByLmdldEVuY29kZWROYW1lKCkgJT48L3RkPgorICAgIDx0ZD48JT0gQnl0ZXMudG9TdHJpbmcoci5nZXRTdGFydEtleSgpKSAlPjwvdGQ+PHRkPjwlPSBCeXRlcy50b1N0cmluZyhyLmdldEVuZEtleSgpKSAlPjwvdGQ+CisgICAgPHRkPjwlPSBsb2FkLnRvU3RyaW5nKCkgJT48L3RkPgorICAgIDwvdHI+Cis8JSAgIH0gJT4KKzwvdGFibGU+Cis8cD5SZWdpb24gbmFtZXMgYXJlIG1hZGUgb2YgdGhlIGNvbnRhaW5pbmcgdGFibGUncyBuYW1lLCBhIGNvbW1hLAordGhlIHN0YXJ0IGtleSwgYSBjb21tYSwgYW5kIGEgcmFuZG9tbHkgZ2VuZXJhdGVkIHJlZ2lvbiBpZC4gIFRvIGlsbHVzdHJhdGUsCit0aGUgcmVnaW9uIG5hbWVkCis8ZW0+ZG9tYWlucyxhcGFjaGUub3JnLDU0NjQ4Mjk0MjQyMTEyNjM0MDc8L2VtPiBpcyBwYXJ0eSB0byB0aGUgdGFibGUgCis8ZW0+ZG9tYWluczwvZW0+LCBoYXMgYW4gaWQgb2YgPGVtPjU0NjQ4Mjk0MjQyMTEyNjM0MDc8L2VtPiBhbmQgdGhlIGZpcnN0IGtleQoraW4gdGhlIHJlZ2lvbiBpcyA8ZW0+YXBhY2hlLm9yZzwvZW0+LiAgVGhlIDxlbT4tUk9PVC08L2VtPgorYW5kIDxlbT4uTUVUQS48L2VtPiAndGFibGVzJyBhcmUgaW50ZXJuYWwgc3l0ZW0gdGFibGVzIChvciAnY2F0YWxvZycgdGFibGVzIGluIGRiLXNwZWFrKS4KK1RoZSAtUk9PVC0ga2VlcHMgYSBsaXN0IG9mIGFsbCByZWdpb25zIGluIHRoZSAuTUVUQS4gdGFibGUuICBUaGUgLk1FVEEuIHRhYmxlCitrZWVwcyBhIGxpc3Qgb2YgYWxsIHJlZ2lvbnMgaW4gdGhlIHN5c3RlbS4gVGhlIGVtcHR5IGtleSBpcyB1c2VkIHRvIGRlbm90ZQordGFibGUgc3RhcnQgYW5kIHRhYmxlIGVuZC4gIEEgcmVnaW9uIHdpdGggYW4gZW1wdHkgc3RhcnQga2V5IGlzIHRoZSBmaXJzdCByZWdpb24gaW4gYSB0YWJsZS4KK0lmIHJlZ2lvbiBoYXMgYm90aCBhbiBlbXB0eSBzdGFydCBhbmQgYW4gZW1wdHkgZW5kIGtleSwgaXRzIHRoZSBvbmx5IHJlZ2lvbiBpbiB0aGUgdGFibGUuICBTZWUKKzxhIGhyZWY9Imh0dHA6Ly9oYmFzZS5vcmciPkhCYXNlIEhvbWU8L2E+IGZvciBmdXJ0aGVyIGV4cGxpY2F0aW9uLjxwPgorPCUgfSBlbHNlIHsgJT4KKzxwPk5vdCBzZXJ2aW5nIHJlZ2lvbnM8L3A+Cis8JSB9ICU+Cis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9zcmMvd2ViYXBwcy9yZXN0L01FVEEtSU5GL01BTklGRVNULk1GIGIvc3JjL3dlYmFwcHMvcmVzdC9NRVRBLUlORi9NQU5JRkVTVC5NRgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOGU1NTBlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3dlYmFwcHMvcmVzdC9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMCwwICsxLDkgQEAKK01hbmlmZXN0LVZlcnNpb246IDEuMA0KK0NsYXNzLVBhdGg6IA0KKw0KK01hbmlmZXN0LVZlcnNpb246IDEuMA0KK0NsYXNzLVBhdGg6IA0KKw0KK01hbmlmZXN0LVZlcnNpb246IDEuMA0KK0NsYXNzLVBhdGg6IA0KKw0KZGlmZiAtLWdpdCBhL3NyYy93ZWJhcHBzL3Jlc3QvV0VCLUlORi93ZWIueG1sIGIvc3JjL3dlYmFwcHMvcmVzdC9XRUItSU5GL3dlYi54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFhYTNiNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy93ZWJhcHBzL3Jlc3QvV0VCLUlORi93ZWIueG1sCkBAIC0wLDAgKzEsMTQgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8d2ViLWFwcCBpZD0iV2ViQXBwX0lEIiB2ZXJzaW9uPSIyLjQiIHhtbG5zPSJodHRwOi8vamF2YS5zdW4uY29tL3htbC9ucy9qMmVlIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL25zL2oyZWUgaHR0cDovL2phdmEuc3VuLmNvbS94bWwvbnMvajJlZS93ZWItYXBwXzJfNC54c2QiPgorICA8ZGlzcGxheS1uYW1lPmpzb25yZXN0PC9kaXNwbGF5LW5hbWU+CisgIDxzZXJ2bGV0PgorICAgIDxkZXNjcmlwdGlvbj5IYmFzZSBKU09OUkVTVCBJbnRlcmZhY2U8L2Rlc2NyaXB0aW9uPgorICAgIDxkaXNwbGF5LW5hbWU+YXBpPC9kaXNwbGF5LW5hbWU+CisgICAgPHNlcnZsZXQtbmFtZT5hcGk8L3NlcnZsZXQtbmFtZT4KKyAgICA8c2VydmxldC1jbGFzcz5vcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5yZXN0LkRpc3BhdGNoZXI8L3NlcnZsZXQtY2xhc3M+CisgIDwvc2VydmxldD4KKyAgPHNlcnZsZXQtbWFwcGluZz4KKyAgICA8c2VydmxldC1uYW1lPmFwaTwvc2VydmxldC1uYW1lPgorICAgIDx1cmwtcGF0dGVybj4vYXBpLyo8L3VybC1wYXR0ZXJuPgorICA8L3NlcnZsZXQtbWFwcGluZz4KKzwvd2ViLWFwcD4KZGlmZiAtLWdpdCBhL3NyYy93ZWJhcHBzL3N0YXRpYy9oYmFzZS5jc3MgYi9zcmMvd2ViYXBwcy9zdGF0aWMvaGJhc2UuY3NzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmYTI1ODQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvd2ViYXBwcy9zdGF0aWMvaGJhc2UuY3NzCkBAIC0wLDAgKzEsOCBAQAoraDEsIGgyLCBoMyB7IGNvbG9yOiBEYXJrU2xhdGVCbHVlIH0KK3RhYmxlIHsgYm9yZGVyOiB0aGluIHNvbGlkIERvZGdlckJsdWUgfQordHIgeyBib3JkZXI6IHRoaW4gc29saWQgRG9kZ2VyQmx1ZSB9Cit0ZCB7IGJvcmRlcjogdGhpbiBzb2xpZCBEb2RnZXJCbHVlIH0KK3RoIHsgYm9yZGVyOiB0aGluIHNvbGlkIERvZGdlckJsdWUgfQorI2xvZ28ge2Zsb2F0OiBsZWZ0O30KKyNsb2dvIGltZyB7Ym9yZGVyOiBub25lO30KKyNwYWdlX3RpdGxlIHtwYWRkaW5nLXRvcDogMjdweDt9CmRpZmYgLS1naXQgYS9zcmMvd2ViYXBwcy9zdGF0aWMvaGJhc2VfbG9nb19tZWQuZ2lmIGIvc3JjL3dlYmFwcHMvc3RhdGljL2hiYXNlX2xvZ29fbWVkLmdpZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNmQzZTNjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3dlYmFwcHMvc3RhdGljL2hiYXNlX2xvZ29fbWVkLmdpZgpCaW5hcnkgZmlsZXMgZGlmZmVyCg==