ZGlmZiAtLWdpdCBhL2NvbXBpbGVyL2NwcC9NYWtlZmlsZS5hbSBiL2NvbXBpbGVyL2NwcC9NYWtlZmlsZS5hbQppbmRleCBmYThkMWNhLi5iMWI2YjAxIDEwMDY0NAotLS0gYS9jb21waWxlci9jcHAvTWFrZWZpbGUuYW0KKysrIGIvY29tcGlsZXIvY3BwL01ha2VmaWxlLmFtCkBAIC0xMDAsNiArMTAwLDkgQEAKIGlmIFRIUklGVF9HRU5faHRtbAogdGhyaWZ0X1NPVVJDRVMgKz0gc3JjL2dlbmVyYXRlL3RfaHRtbF9nZW5lcmF0b3IuY2MKIGVuZGlmCitpZiBUSFJJRlRfR0VOX2pzCit0aHJpZnRfU09VUkNFUyArPSBzcmMvZ2VuZXJhdGUvdF9qc19nZW5lcmF0b3IuY2MKK2VuZGlmCiAKIHRocmlmdF9DWFhGTEFHUyA9IC1XYWxsIC1JJChzcmNkaXIpL3NyYyAkKEJPT1NUX0NQUEZMQUdTKQogdGhyaWZ0X0xERkxBR1MgPSAtV2FsbCAkKEJPT1NUX0xERkxBR1MpCmRpZmYgLS1naXQgYS9jb21waWxlci9jcHAvc3JjL2dlbmVyYXRlL3RfanNfZ2VuZXJhdG9yLmNjIGIvY29tcGlsZXIvY3BwL3NyYy9nZW5lcmF0ZS90X2pzX2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OWJlMTI1Ci0tLSAvZGV2L251bGwKKysrIGIvY29tcGlsZXIvY3BwL3NyYy9nZW5lcmF0ZS90X2pzX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDE0NzcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxmc3RyZWFtPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxsaXN0PgorCisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxzc3RyZWFtPgorI2luY2x1ZGUgInBsYXRmb3JtLmgiCit1c2luZyBuYW1lc3BhY2Ugc3RkOworCisKKyNpbmNsdWRlICJ0X29vcF9nZW5lcmF0b3IuaCIKKworLyoqCisgKiBKUyBjb2RlIGdlbmVyYXRvci4KKyAqLworY2xhc3MgdF9qc19nZW5lcmF0b3IgOiBwdWJsaWMgdF9vb3BfZ2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIHRfanNfZ2VuZXJhdG9yKHRfcHJvZ3JhbSogcHJvZ3JhbSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdGQ6Om1hcDxzdGQ6OnN0cmluZywgc3RkOjpzdHJpbmc+JiBwYXJzZWRfb3B0aW9ucywKKyAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgb3B0aW9uX3N0cmluZykgOgorICAgICB0X29vcF9nZW5lcmF0b3IocHJvZ3JhbSkgeworCisgICAgIG91dF9kaXJfYmFzZV8gPSAiZ2VuLWpzIjsKKyAgfQorCisgIC8qKgorICAgKiBJbml0IGFuZCBjbG9zZSBtZXRob2RzCisgICAqLworCisgIHZvaWQgaW5pdF9nZW5lcmF0b3IoKTsKKyAgdm9pZCBjbG9zZV9nZW5lcmF0b3IoKTsKKworICAvKioKKyAgICogUHJvZ3JhbS1sZXZlbCBnZW5lcmF0aW9uIGZ1bmN0aW9ucworICAgKi8KKworICB2b2lkIGdlbmVyYXRlX3R5cGVkZWYgICh0X3R5cGVkZWYqICB0dHlwZWRlZik7CisgIHZvaWQgZ2VuZXJhdGVfZW51bSAgICAgKHRfZW51bSogICAgIHRlbnVtKTsKKyAgdm9pZCBnZW5lcmF0ZV9jb25zdCAgICAodF9jb25zdCogICAgdGNvbnN0KTsKKyAgdm9pZCBnZW5lcmF0ZV9zdHJ1Y3QgICAodF9zdHJ1Y3QqICAgdHN0cnVjdCk7CisgIHZvaWQgZ2VuZXJhdGVfeGNlcHRpb24gKHRfc3RydWN0KiAgIHR4Y2VwdGlvbik7CisgIHZvaWQgZ2VuZXJhdGVfc2VydmljZSAgKHRfc2VydmljZSogIHRzZXJ2aWNlKTsKKworCisgIHN0ZDo6c3RyaW5nIHJlbmRlcl9jb25zdF92YWx1ZSh0X3R5cGUqIHR5cGUsIHRfY29uc3RfdmFsdWUqIHZhbHVlKTsKKworCisgIC8qKgorICAgKiBTdHJ1Y3RzIQorICAgKi8KKyAgdm9pZCBnZW5lcmF0ZV9qc19zdHJ1Y3QodF9zdHJ1Y3QqIHRzdHJ1Y3QsIGJvb2wgaXNfZXhjZXB0aW9uKTsKKyAgdm9pZCBnZW5lcmF0ZV9qc19zdHJ1Y3RfZGVmaW5pdGlvbihzdGQ6Om9mc3RyZWFtJiBvdXQsIHRfc3RydWN0KiB0c3RydWN0LCBib29sIGlzX3hjZXB0aW9uPWZhbHNlKTsKKyAgdm9pZCBnZW5lcmF0ZV9qc19zdHJ1Y3RfcmVhZGVyKHN0ZDo6b2ZzdHJlYW0mIG91dCwgdF9zdHJ1Y3QqIHRzdHJ1Y3QpOworICB2b2lkIGdlbmVyYXRlX2pzX3N0cnVjdF93cml0ZXIoc3RkOjpvZnN0cmVhbSYgb3V0LCB0X3N0cnVjdCogdHN0cnVjdCk7CisgIHZvaWQgZ2VuZXJhdGVfanNfZnVuY3Rpb25faGVscGVycyh0X2Z1bmN0aW9uKiB0ZnVuY3Rpb24pOworCisgIC8qKgorICAgKiBTZXJ2aWNlLWxldmVsIGdlbmVyYXRpb24gZnVuY3Rpb25zCisgICAqLworICB2b2lkIGdlbmVyYXRlX3NlcnZpY2VfaGVscGVycyAgICh0X3NlcnZpY2UqIHRzZXJ2aWNlKTsKKyAgdm9pZCBnZW5lcmF0ZV9zZXJ2aWNlX2ludGVyZmFjZSAodF9zZXJ2aWNlKiB0c2VydmljZSk7CisgIHZvaWQgZ2VuZXJhdGVfc2VydmljZV9yZXN0ICAgICAgKHRfc2VydmljZSogdHNlcnZpY2UpOworICB2b2lkIGdlbmVyYXRlX3NlcnZpY2VfY2xpZW50ICAgICh0X3NlcnZpY2UqIHRzZXJ2aWNlKTsKKyAgdm9pZCBnZW5lcmF0ZV9zZXJ2aWNlX3Byb2Nlc3NvciAodF9zZXJ2aWNlKiB0c2VydmljZSk7CisgIHZvaWQgZ2VuZXJhdGVfcHJvY2Vzc19mdW5jdGlvbiAgKHRfc2VydmljZSogdHNlcnZpY2UsIHRfZnVuY3Rpb24qIHRmdW5jdGlvbik7CisKKyAgLyoqCisgICAqIFNlcmlhbGl6YXRpb24gY29uc3RydWN0cworICAgKi8KKworICB2b2lkIGdlbmVyYXRlX2Rlc2VyaWFsaXplX2ZpZWxkICAgICAgICAoc3RkOjpvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9maWVsZCogICAgdGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzdHJpbmcgcHJlZml4PSIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbmNsYXNzPWZhbHNlKTsKKworICB2b2lkIGdlbmVyYXRlX2Rlc2VyaWFsaXplX3N0cnVjdCAgICAgICAoc3RkOjpvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9zdHJ1Y3QqICAgdHN0cnVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisKKyAgdm9pZCBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9jb250YWluZXIgICAgKHN0ZDo6b2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfdHlwZSogICAgIHR0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzdHJpbmcgcHJlZml4PSIiKTsKKworICB2b2lkIGdlbmVyYXRlX2Rlc2VyaWFsaXplX3NldF9lbGVtZW50ICAoc3RkOjpvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9zZXQqICAgICAgdHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisKKyAgdm9pZCBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9tYXBfZWxlbWVudCAgKHN0ZDo6b2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfbWFwKiAgICAgIHRtYXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyBwcmVmaXg9IiIpOworCisgIHZvaWQgZ2VuZXJhdGVfZGVzZXJpYWxpemVfbGlzdF9lbGVtZW50IChzdGQ6Om9mc3RyZWFtICZvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2xpc3QqICAgICB0bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisKKyAgdm9pZCBnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQgICAgICAgICAgKHN0ZDo6b2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfZmllbGQqICAgIHRmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisKKyAgdm9pZCBnZW5lcmF0ZV9zZXJpYWxpemVfc3RydWN0ICAgICAgICAgKHN0ZDo6b2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfc3RydWN0KiAgIHRzdHJ1Y3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyBwcmVmaXg9IiIpOworCisgIHZvaWQgZ2VuZXJhdGVfc2VyaWFsaXplX2NvbnRhaW5lciAgICAgIChzdGQ6Om9mc3RyZWFtICZvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3R5cGUqICAgICB0dHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisKKyAgdm9pZCBnZW5lcmF0ZV9zZXJpYWxpemVfbWFwX2VsZW1lbnQgICAgKHN0ZDo6b2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfbWFwKiAgICAgIHRtYXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyBraXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIHZpdGVyKTsKKworICB2b2lkIGdlbmVyYXRlX3NlcmlhbGl6ZV9zZXRfZWxlbWVudCAgICAoc3RkOjpvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9zZXQqICAgICAgdG1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIGl0ZXIpOworCisgIHZvaWQgZ2VuZXJhdGVfc2VyaWFsaXplX2xpc3RfZWxlbWVudCAgIChzdGQ6Om9mc3RyZWFtICZvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2xpc3QqICAgICB0bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c3RyaW5nIGl0ZXIpOworCisgIC8qKgorICAgKiBIZWxwZXIgcmVuZGVyaW5nIGZ1bmN0aW9ucworICAgKi8KKworICBzdGQ6OnN0cmluZyBqc19pbmNsdWRlcygpOworICBzdGQ6OnN0cmluZyBkZWNsYXJlX2ZpZWxkKHRfZmllbGQqIHRmaWVsZCwgYm9vbCBpbml0PWZhbHNlLCBib29sIG9iaj1mYWxzZSk7CisgIHN0ZDo6c3RyaW5nIGZ1bmN0aW9uX3NpZ25hdHVyZSh0X2Z1bmN0aW9uKiB0ZnVuY3Rpb24sIHN0ZDo6c3RyaW5nIHByZWZpeD0iIik7CisgIHN0ZDo6c3RyaW5nIGFyZ3VtZW50X2xpc3QodF9zdHJ1Y3QqIHRzdHJ1Y3QpOworICBzdGQ6OnN0cmluZyB0eXBlX3RvX2VudW0odF90eXBlKiB0dHlwZSk7CisKKyAgc3RkOjpzdHJpbmcgYXV0b2dlbl9jb21tZW50KCkgeworICAgIHJldHVybgorICAgICAgc3RkOjpzdHJpbmcoIi8vXG4iKSArCisgICAgICAiLy8gQXV0b2dlbmVyYXRlZCBieSBUaHJpZnRcbiIgKworICAgICAgIi8vXG4iICsKKyAgICAgICIvLyBETyBOT1QgRURJVCBVTkxFU1MgWU9VIEFSRSBTVVJFIFRIQVQgWU9VIEtOT1cgV0hBVCBZT1UgQVJFIERPSU5HXG4iICsKKyAgICAgICIvL1xuIjsKKyAgfQorCisgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBqc19uYW1lc3BhY2VfcGllY2VzKHRfcHJvZ3JhbSogcCkgeworICAgICAgc3RkOjpzdHJpbmcgbnMgPSBwLT5nZXRfbmFtZXNwYWNlKCJqcyIpOworCisgICAgICBzdGQ6OnN0cmluZzo6c2l6ZV90eXBlICAgbG9jOworICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IHBpZWNlczsKKworICAgICAgaWYgKG5zLnNpemUoKSA+IDApIHsKKyAgICAgICAgICB3aGlsZSAoKGxvYyA9IG5zLmZpbmQoIi4iKSkgIT0gc3RkOjpzdHJpbmc6Om5wb3MpIHsKKyAgICAgICAgICAgICAgcGllY2VzLnB1c2hfYmFjayhucy5zdWJzdHIoMCwgbG9jKSk7CisgICAgICAgICAgICAgIG5zID0gbnMuc3Vic3RyKGxvYysxKTsKKyAgICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChucy5zaXplKCkgPiAwKSB7CisgICAgICAgICAgcGllY2VzLnB1c2hfYmFjayhucyk7CisgICAgICB9CisKKyAgICAgIHJldHVybiBwaWVjZXM7CisgIH0KKworICBzdGQ6OnN0cmluZyBqc19uYW1lc3BhY2UodF9wcm9ncmFtKiBwKSB7CisgICAgICBzdGQ6OnN0cmluZyBucyA9IHAtPmdldF9uYW1lc3BhY2UoImpzIik7CisgICAgICBpZiAobnMuc2l6ZSgpID4gMCkgeworICAgICAgICAgIG5zICs9ICIuIjsKKyAgICAgIH0KKworCisgICAgICByZXR1cm4gbnM7CisgIH0KKworIHByaXZhdGU6CisKKyAgLyoqCisgICAqIEZpbGUgc3RyZWFtcworICAgKi8KKyAgc3RkOjpvZnN0cmVhbSBmX3R5cGVzXzsKKyAgc3RkOjpvZnN0cmVhbSBmX3NlcnZpY2VfOworfTsKKworCisvKioKKyAqIFByZXBhcmVzIGZvciBmaWxlIGdlbmVyYXRpb24gYnkgb3BlbmluZyB1cCB0aGUgbmVjZXNzYXJ5IGZpbGUgb3V0cHV0CisgKiBzdHJlYW1zLgorICoKKyAqIEBwYXJhbSB0cHJvZ3JhbSBUaGUgcHJvZ3JhbSB0byBnZW5lcmF0ZQorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjppbml0X2dlbmVyYXRvcigpIHsKKyAgLy8gTWFrZSBvdXRwdXQgZGlyZWN0b3J5CisgIE1LRElSKGdldF9vdXRfZGlyKCkuY19zdHIoKSk7CisKKyAgc3RyaW5nIG91dGRpciA9IGdldF9vdXRfZGlyKCk7CisKKyAgLy8gTWFrZSBvdXRwdXQgZmlsZQorICBzdHJpbmcgZl90eXBlc19uYW1lID0gb3V0ZGlyK3Byb2dyYW1fLT5nZXRfbmFtZSgpKyJfdHlwZXMuanMiOworICBmX3R5cGVzXy5vcGVuKGZfdHlwZXNfbmFtZS5jX3N0cigpKTsKKworICAvLyBQcmludCBoZWFkZXIKKyAgZl90eXBlc18gPDwKKyAgICBhdXRvZ2VuX2NvbW1lbnQoKSA8PAorICAgIGpzX2luY2x1ZGVzKCk7CisKKworICBzdHJpbmcgcG5zOworCisgIC8vc2V0dXAgdGhlIG5hbWVzcGFjZQorICB2ZWN0b3I8c3RyaW5nPiBuc19waWVjZXMgPSBqc19uYW1lc3BhY2VfcGllY2VzKCBwcm9ncmFtXyApOworICBpZiggbnNfcGllY2VzLnNpemUoKSA+IDApeworICAgICAgZl90eXBlc18gPDwgInZhciAiIDw8IG5zX3BpZWNlc1swXSA8PCAiID0ge30iPDxlbmRsOworCisgICAgICBwbnMgPSBuc19waWVjZXNbMF07CisKKyAgICAgIGZvcihzaXplX3QgaT0xOyBpPG5zX3BpZWNlcy5zaXplKCk7IGkrKyl7CisgICAgICAgICAgcG5zICs9ICIuIiArIG5zX3BpZWNlc1tpXTsKKworICAgICAgICAgIGZfdHlwZXNfIDw8IHBucyA8PCAiID0ge30iPDxlbmRsOworICAgICAgfQorICB9CisKK30KKworLyoqCisgKiBQcmludHMgc3RhbmRhcmQganMgaW1wb3J0cworICovCitzdHJpbmcgdF9qc19nZW5lcmF0b3I6OmpzX2luY2x1ZGVzKCkgeworICBzdHJpbmcgaW5jOworCisgIHJldHVybiBpbmM7Cit9CisKKy8qKgorICogQ2xvc2UgdXAgKG9yIGRvd24pIHNvbWUgZmlsZXouCisgKi8KK3ZvaWQgdF9qc19nZW5lcmF0b3I6OmNsb3NlX2dlbmVyYXRvcigpIHsKKyAgLy8gQ2xvc2UgdHlwZXMgZmlsZQorCisgIGZfdHlwZXNfLmNsb3NlKCk7Cit9CisKKy8qKgorICogR2VuZXJhdGVzIGEgdHlwZWRlZi4gVGhpcyBpcyBub3QgZG9uZSBpbiBKUywgdHlwZXMgYXJlIGFsbCBpbXBsaWNpdC4KKyAqCisgKiBAcGFyYW0gdHR5cGVkZWYgVGhlIHR5cGUgZGVmaW5pdGlvbgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV90eXBlZGVmKHRfdHlwZWRlZiogdHR5cGVkZWYpIHt9CisKKy8qKgorICogR2VuZXJhdGVzIGNvZGUgZm9yIGFuIGVudW1lcmF0ZWQgdHlwZS4gU2luY2UgZGVmaW5lIGlzIGV4cGVuc2l2ZSB0byBsb29rdXAKKyAqIGluIEpTLCB3ZSB1c2UgYSBnbG9iYWwgYXJyYXkgZm9yIHRoaXMuCisgKgorICogQHBhcmFtIHRlbnVtIFRoZSBlbnVtZXJhdGlvbgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9lbnVtKHRfZW51bSogdGVudW0pIHsKKworICBmX3R5cGVzXyA8PCBqc19uYW1lc3BhY2UodGVudW0tPmdldF9wcm9ncmFtKCkpPDx0ZW51bS0+Z2V0X25hbWUoKTw8IiA9IHsgIjw8ZW5kbDsKKworICB2ZWN0b3I8dF9lbnVtX3ZhbHVlKj4gY29uc3RhbnRzID0gdGVudW0tPmdldF9jb25zdGFudHMoKTsKKyAgdmVjdG9yPHRfZW51bV92YWx1ZSo+OjppdGVyYXRvciBjX2l0ZXI7CisgIGludCB2YWx1ZSA9IC0xOworICBmb3IgKGNfaXRlciA9IGNvbnN0YW50cy5iZWdpbigpOyBjX2l0ZXIgIT0gY29uc3RhbnRzLmVuZCgpOyArK2NfaXRlcikgeworICAgIGlmICgoKmNfaXRlciktPmhhc192YWx1ZSgpKSB7CisgICAgICB2YWx1ZSA9ICgqY19pdGVyKS0+Z2V0X3ZhbHVlKCk7CisgICAgfSBlbHNlIHsKKyAgICAgICsrdmFsdWU7CisgICAgfQorCisgICAgaWYoY19pdGVyICE9IGNvbnN0YW50cy5iZWdpbigpKQorICAgICAgICBmX3R5cGVzXyA8PCAiLCI7CisKKyAgICBmX3R5cGVzXyA8PCAiJyIgPDwgKCpjX2l0ZXIpLT5nZXRfbmFtZSgpIDw8ICInIDogIiA8PCB2YWx1ZSA8PCBlbmRsOworICB9CisKKyAgZl90eXBlc18gPDwgIn0iPDxlbmRsOworCit9CisKKy8qKgorICogR2VuZXJhdGUgYSBjb25zdGFudCB2YWx1ZQorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9jb25zdCh0X2NvbnN0KiB0Y29uc3QpIHsKKyAgdF90eXBlKiB0eXBlID0gdGNvbnN0LT5nZXRfdHlwZSgpOworICBzdHJpbmcgbmFtZSA9IHRjb25zdC0+Z2V0X25hbWUoKTsKKyAgdF9jb25zdF92YWx1ZSogdmFsdWUgPSB0Y29uc3QtPmdldF92YWx1ZSgpOworCisgIGZfdHlwZXNfIDw8IGpzX25hbWVzcGFjZShwcm9ncmFtXykgIDw8IG5hbWUgPDwgIiA9ICI7CisgIGZfdHlwZXNfIDw8IHJlbmRlcl9jb25zdF92YWx1ZSh0eXBlLCB2YWx1ZSkgPDwgZW5kbDsKK30KKworLyoqCisgKiBQcmludHMgdGhlIHZhbHVlIG9mIGEgY29uc3RhbnQgd2l0aCB0aGUgZ2l2ZW4gdHlwZS4gTm90ZSB0aGF0IHR5cGUgY2hlY2tpbmcKKyAqIGlzIE5PVCBwZXJmb3JtZWQgaW4gdGhpcyBmdW5jdGlvbiBhcyBpdCBpcyBhbHdheXMgcnVuIGJlZm9yZWhhbmQgdXNpbmcgdGhlCisgKiB2YWxpZGF0ZV90eXBlcyBtZXRob2QgaW4gbWFpbi5jYworICovCitzdHJpbmcgdF9qc19nZW5lcmF0b3I6OnJlbmRlcl9jb25zdF92YWx1ZSh0X3R5cGUqIHR5cGUsIHRfY29uc3RfdmFsdWUqIHZhbHVlKSB7CisgIHN0ZDo6b3N0cmluZ3N0cmVhbSBvdXQ7CisKKyAgdHlwZSA9IGdldF90cnVlX3R5cGUodHlwZSk7CisKKyAgaWYgKHR5cGUtPmlzX2Jhc2VfdHlwZSgpKSB7CisgICAgdF9iYXNlX3R5cGU6OnRfYmFzZSB0YmFzZSA9ICgodF9iYXNlX3R5cGUqKXR5cGUpLT5nZXRfYmFzZSgpOworICAgIHN3aXRjaCAodGJhc2UpIHsKKyAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX1NUUklORzoKKyAgICAgIG91dCA8PCAiJyIgPDwgdmFsdWUtPmdldF9zdHJpbmcoKSA8PCAiJyI7CisgICAgICBicmVhazsKKyAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0JPT0w6CisgICAgICBvdXQgPDwgKHZhbHVlLT5nZXRfaW50ZWdlcigpID4gMCA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9CWVRFOgorICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTE2OgorICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTMyOgorICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTY0OgorICAgICAgb3V0IDw8IHZhbHVlLT5nZXRfaW50ZWdlcigpOworICAgICAgYnJlYWs7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9ET1VCTEU6CisgICAgICBpZiAodmFsdWUtPmdldF90eXBlKCkgPT0gdF9jb25zdF92YWx1ZTo6Q1ZfSU5URUdFUikgeworICAgICAgICBvdXQgPDwgdmFsdWUtPmdldF9pbnRlZ2VyKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBvdXQgPDwgdmFsdWUtPmdldF9kb3VibGUoKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICB0aHJvdyAiY29tcGlsZXIgZXJyb3I6IG5vIGNvbnN0IG9mIGJhc2UgdHlwZSAiICsgdF9iYXNlX3R5cGU6OnRfYmFzZV9uYW1lKHRiYXNlKTsKKyAgICB9CisgIH0gZWxzZSBpZiAodHlwZS0+aXNfZW51bSgpKSB7CisgICAgb3V0IDw8IHZhbHVlLT5nZXRfaW50ZWdlcigpOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX3N0cnVjdCgpIHx8IHR5cGUtPmlzX3hjZXB0aW9uKCkpIHsKKyAgICBvdXQgPDwgIm5ldyAiIDw8IGpzX25hbWVzcGFjZSh0eXBlLT5nZXRfcHJvZ3JhbSgpKSA8PCB0eXBlLT5nZXRfbmFtZSgpIDw8ICIoeyIgPDwgZW5kbDsKKyAgICBpbmRlbnRfdXAoKTsKKyAgICBjb25zdCB2ZWN0b3I8dF9maWVsZCo+JiBmaWVsZHMgPSAoKHRfc3RydWN0Kil0eXBlKS0+Z2V0X21lbWJlcnMoKTsKKyAgICB2ZWN0b3I8dF9maWVsZCo+Ojpjb25zdF9pdGVyYXRvciBmX2l0ZXI7CisgICAgY29uc3QgbWFwPHRfY29uc3RfdmFsdWUqLCB0X2NvbnN0X3ZhbHVlKj4mIHZhbCA9IHZhbHVlLT5nZXRfbWFwKCk7CisgICAgbWFwPHRfY29uc3RfdmFsdWUqLCB0X2NvbnN0X3ZhbHVlKj46OmNvbnN0X2l0ZXJhdG9yIHZfaXRlcjsKKyAgICBmb3IgKHZfaXRlciA9IHZhbC5iZWdpbigpOyB2X2l0ZXIgIT0gdmFsLmVuZCgpOyArK3ZfaXRlcikgeworICAgICAgdF90eXBlKiBmaWVsZF90eXBlID0gTlVMTDsKKyAgICAgIGZvciAoZl9pdGVyID0gZmllbGRzLmJlZ2luKCk7IGZfaXRlciAhPSBmaWVsZHMuZW5kKCk7ICsrZl9pdGVyKSB7CisgICAgICAgIGlmICgoKmZfaXRlciktPmdldF9uYW1lKCkgPT0gdl9pdGVyLT5maXJzdC0+Z2V0X3N0cmluZygpKSB7CisgICAgICAgICAgZmllbGRfdHlwZSA9ICgqZl9pdGVyKS0+Z2V0X3R5cGUoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKGZpZWxkX3R5cGUgPT0gTlVMTCkgeworICAgICAgICB0aHJvdyAidHlwZSBlcnJvcjogIiArIHR5cGUtPmdldF9uYW1lKCkgKyAiIGhhcyBubyBmaWVsZCAiICsgdl9pdGVyLT5maXJzdC0+Z2V0X3N0cmluZygpOworICAgICAgfQorICAgICAgb3V0IDw8IHJlbmRlcl9jb25zdF92YWx1ZShnX3R5cGVfc3RyaW5nLCB2X2l0ZXItPmZpcnN0KTsKKyAgICAgIG91dCA8PCAiIDogIjsKKyAgICAgIG91dCA8PCByZW5kZXJfY29uc3RfdmFsdWUoZmllbGRfdHlwZSwgdl9pdGVyLT5zZWNvbmQpOworICAgICAgb3V0IDw8ICIsIjsKKyAgICB9CisKKyAgICBvdXQgPDwgIn0pIjsKKyAgfSBlbHNlIGlmICh0eXBlLT5pc19tYXAoKSkgeworICAgIHRfdHlwZSoga3R5cGUgPSAoKHRfbWFwKil0eXBlKS0+Z2V0X2tleV90eXBlKCk7CisgICAgYm9vbCAgICBrZXlfaXNfc3RyaW5nID0gZmFsc2U7CisgICAgaWYgKGt0eXBlLT5pc19iYXNlX3R5cGUoKSAmJiAoKHRfYmFzZV90eXBlKilrdHlwZSktPmdldF9iYXNlKCkgPT0gdF9iYXNlX3R5cGU6OlRZUEVfU1RSSU5HKXsKKyAgICAgICAga2V5X2lzX3N0cmluZyA9IHRydWU7CisgICAgfQorCisgICAgdF90eXBlKiB2dHlwZSA9ICgodF9tYXAqKXR5cGUpLT5nZXRfdmFsX3R5cGUoKTsKKyAgICBvdXQgPDwgInsiOworCisgICAgY29uc3QgbWFwPHRfY29uc3RfdmFsdWUqLCB0X2NvbnN0X3ZhbHVlKj4mIHZhbCA9IHZhbHVlLT5nZXRfbWFwKCk7CisgICAgbWFwPHRfY29uc3RfdmFsdWUqLCB0X2NvbnN0X3ZhbHVlKj46OmNvbnN0X2l0ZXJhdG9yIHZfaXRlcjsKKyAgICBmb3IgKHZfaXRlciA9IHZhbC5iZWdpbigpOyB2X2l0ZXIgIT0gdmFsLmVuZCgpOyArK3ZfaXRlcikgeworCisgICAgICAgIG91dCA8PCByZW5kZXJfY29uc3RfdmFsdWUoa3R5cGUsIHZfaXRlci0+Zmlyc3QpOworCisgICAgICAgIG91dCA8PCAiIDogIjsKKyAgICAgICAgb3V0IDw8IHJlbmRlcl9jb25zdF92YWx1ZSh2dHlwZSwgdl9pdGVyLT5zZWNvbmQpOworICAgICAgICBvdXQgPDwgIiwiIDw8IGVuZGw7CisgICAgfQorCisgICAgb3V0IDw8ICJ9IjsKKyAgfSBlbHNlIGlmICh0eXBlLT5pc19saXN0KCkgfHwgdHlwZS0+aXNfc2V0KCkpIHsKKyAgICB0X3R5cGUqIGV0eXBlOworICAgIGlmICh0eXBlLT5pc19saXN0KCkpIHsKKyAgICAgIGV0eXBlID0gKCh0X2xpc3QqKXR5cGUpLT5nZXRfZWxlbV90eXBlKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGV0eXBlID0gKCh0X3NldCopdHlwZSktPmdldF9lbGVtX3R5cGUoKTsKKyAgICB9CisgICAgb3V0IDw8ICJbIjsKKyAgICBjb25zdCB2ZWN0b3I8dF9jb25zdF92YWx1ZSo+JiB2YWwgPSB2YWx1ZS0+Z2V0X2xpc3QoKTsKKyAgICB2ZWN0b3I8dF9jb25zdF92YWx1ZSo+Ojpjb25zdF9pdGVyYXRvciB2X2l0ZXI7CisgICAgZm9yICh2X2l0ZXIgPSB2YWwuYmVnaW4oKTsgdl9pdGVyICE9IHZhbC5lbmQoKTsgKyt2X2l0ZXIpIHsKKworICAgICAgb3V0IDw8IHJlbmRlcl9jb25zdF92YWx1ZShldHlwZSwgKnZfaXRlcik7CisgICAgICBvdXQgPDwgIiwiOworICAgIH0KKyAgICBvdXQgPDwgIl0iOworICB9CisgIHJldHVybiBvdXQuc3RyKCk7Cit9CisKKy8qKgorICogTWFrZSBhIHN0cnVjdAorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9zdHJ1Y3QodF9zdHJ1Y3QqIHRzdHJ1Y3QpIHsKKyAgZ2VuZXJhdGVfanNfc3RydWN0KHRzdHJ1Y3QsIGZhbHNlKTsKK30KKworLyoqCisgKiBHZW5lcmF0ZXMgYSBzdHJ1Y3QgZGVmaW5pdGlvbiBmb3IgYSB0aHJpZnQgZXhjZXB0aW9uLiBCYXNpY2FsbHkgdGhlIHNhbWUKKyAqIGFzIGEgc3RydWN0IGJ1dCBleHRlbmRzIHRoZSBFeGNlcHRpb24gY2xhc3MuCisgKgorICogQHBhcmFtIHR4Y2VwdGlvbiBUaGUgc3RydWN0IGRlZmluaXRpb24KKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfeGNlcHRpb24odF9zdHJ1Y3QqIHR4Y2VwdGlvbikgeworICBnZW5lcmF0ZV9qc19zdHJ1Y3QodHhjZXB0aW9uLCB0cnVlKTsKK30KKworLyoqCisgKiBTdHJ1Y3RzIGNhbiBiZSBub3JtYWwgb3IgZXhjZXB0aW9ucy4KKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfanNfc3RydWN0KHRfc3RydWN0KiB0c3RydWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2V4Y2VwdGlvbikgeworICBnZW5lcmF0ZV9qc19zdHJ1Y3RfZGVmaW5pdGlvbihmX3R5cGVzXywgdHN0cnVjdCwgaXNfZXhjZXB0aW9uKTsKK30KKworLyoqCisgKiBHZW5lcmF0ZXMgYSBzdHJ1Y3QgZGVmaW5pdGlvbiBmb3IgYSB0aHJpZnQgZGF0YSB0eXBlLiBUaGlzIGlzIG5vdGhpbmcgaW4gSlMKKyAqIHdoZXJlIHRoZSBvYmplY3RzIGFyZSBhbGwganVzdCBhc3NvY2lhdGl2ZSBhcnJheXMgKHVubGVzcyBvZiBjb3Vyc2Ugd2UKKyAqIGRlY2lkZSB0byBzdGFydCB1c2luZyBvYmplY3RzIGZvciB0aGVtLi4uKQorICoKKyAqIEBwYXJhbSB0c3RydWN0IFRoZSBzdHJ1Y3QgZGVmaW5pdGlvbgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9qc19zdHJ1Y3RfZGVmaW5pdGlvbihvZnN0cmVhbSYgb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfc3RydWN0KiB0c3RydWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfZXhjZXB0aW9uKSB7CisgIGNvbnN0IHZlY3Rvcjx0X2ZpZWxkKj4mIG1lbWJlcnMgPSB0c3RydWN0LT5nZXRfbWVtYmVycygpOworICB2ZWN0b3I8dF9maWVsZCo+Ojpjb25zdF9pdGVyYXRvciBtX2l0ZXI7CisKKyAgb3V0IDw8ICBqc19uYW1lc3BhY2UodHN0cnVjdC0+Z2V0X3Byb2dyYW0oKSkgPDwgdHN0cnVjdC0+Z2V0X25hbWUoKSA8PCIgPSBmdW5jdGlvbihhcmdzKXtcbiI7CisKKworICAvL21lbWJlcnMgd2l0aCBhcmd1bWVudHMKKyAgZm9yIChtX2l0ZXIgPSBtZW1iZXJzLmJlZ2luKCk7IG1faXRlciAhPSBtZW1iZXJzLmVuZCgpOyArK21faXRlcikgeworICAgIHN0cmluZyBkdmFsID0gZGVjbGFyZV9maWVsZCgqbV9pdGVyLHRydWUsdHJ1ZSk7CisgICAgdF90eXBlKiB0ID0gZ2V0X3RydWVfdHlwZSgoKm1faXRlciktPmdldF90eXBlKCkpOworICAgIGlmICgoKm1faXRlciktPmdldF92YWx1ZSgpICE9IE5VTEwgJiYgISh0LT5pc19zdHJ1Y3QoKSB8fCB0LT5pc194Y2VwdGlvbigpKSkgeworICAgICAgICBkdmFsID0gcmVuZGVyX2NvbnN0X3ZhbHVlKCgqbV9pdGVyKS0+Z2V0X3R5cGUoKSwgKCptX2l0ZXIpLT5nZXRfdmFsdWUoKSk7CisgICAgICAgIG91dCA8PCBpbmRlbnQoKSA8PCAidGhpcy4iIDw8ICgqbV9pdGVyKS0+Z2V0X25hbWUoKSA8PCAiID0gIiA8PCBkdmFsIDw8IGVuZGw7CisgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0IDw8IGluZGVudCgpIDw8ICBkdmFsIDw8IGVuZGw7CisgICAgfQorCisgIH0KKworICAvLyBHZW5lcmF0ZSBjb25zdHJ1Y3RvciBmcm9tIGFycmF5CisgIGlmIChtZW1iZXJzLnNpemUoKSA+IDApIHsKKworICAgIGZvciAobV9pdGVyID0gbWVtYmVycy5iZWdpbigpOyBtX2l0ZXIgIT0gbWVtYmVycy5lbmQoKTsgKyttX2l0ZXIpIHsKKyAgICAgIHRfdHlwZSogdCA9IGdldF90cnVlX3R5cGUoKCptX2l0ZXIpLT5nZXRfdHlwZSgpKTsKKyAgICAgIGlmICgoKm1faXRlciktPmdldF92YWx1ZSgpICE9IE5VTEwgJiYgKHQtPmlzX3N0cnVjdCgpIHx8IHQtPmlzX3hjZXB0aW9uKCkpKSB7CisgICAgICAgIGluZGVudChvdXQpIDw8ICJ0aGlzLiIgPDwgKCptX2l0ZXIpLT5nZXRfbmFtZSgpIDw8ICIgPSAiIDw8IHJlbmRlcl9jb25zdF92YWx1ZSh0LCAoKm1faXRlciktPmdldF92YWx1ZSgpKSAgPDwgZW5kbDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBvdXQgPDwgImlmKCBhcmdzICE9IG51bGwgKXsiOworCisgICAgZm9yIChtX2l0ZXIgPSBtZW1iZXJzLmJlZ2luKCk7IG1faXRlciAhPSBtZW1iZXJzLmVuZCgpOyArK21faXRlcikgeworICAgICAgICBvdXQgPDwgaW5kZW50KCkgPDwgImlmIChudWxsICE9IGFyZ3MuIiA8PCAoKm1faXRlciktPmdldF9uYW1lKCkgPDwgIikiIDw8ZW5kbAorICAgICAgICAgICAgPDwgaW5kZW50KCkgPDwgInRoaXMuIiA8PCAoKm1faXRlciktPmdldF9uYW1lKCkgPDwgIiA9IGFyZ3MuIiA8PCAoKm1faXRlciktPmdldF9uYW1lKCkgIDw8IGVuZGwgOworCisgICAgfQorCisgICAgb3V0IDw8ICJ9IjsKKworICB9CisKKyAgaW5kZW50X2Rvd24oKTsKKyAgb3V0IDw8ICJ9XG4iOworCisgIGlmIChpc19leGNlcHRpb24pIHsKKyAgICAgIG91dCA8PCAiZm9yICh2YXIgcHJvcGVydHkgaW4gVGhyaWZ0LkV4Y2VwdGlvbikiPDxlbmRsPDwKKyAgICAgICAgICBqc19uYW1lc3BhY2UodHN0cnVjdC0+Z2V0X3Byb2dyYW0oKSk8PHRzdHJ1Y3QtPmdldF9uYW1lKCk8PCJbcHJvcGVydHldID0gVGhyaWZ0LkV4Y2VwdGlvbltwcm9wZXJ0eV0iPDxlbmRsOworICB9CisKKyAgLy9pbml0IHByb3RvdHlwZQorICBvdXQgPDwganNfbmFtZXNwYWNlKHRzdHJ1Y3QtPmdldF9wcm9ncmFtKCkpPDx0c3RydWN0LT5nZXRfbmFtZSgpIDw8Ii5wcm90b3R5cGUgPSB7fVxuIjsKKworCisgIGdlbmVyYXRlX2pzX3N0cnVjdF9yZWFkZXIob3V0LCB0c3RydWN0KTsKKyAgZ2VuZXJhdGVfanNfc3RydWN0X3dyaXRlcihvdXQsIHRzdHJ1Y3QpOworCit9CisKKy8qKgorICogR2VuZXJhdGVzIHRoZSByZWFkKCkgbWV0aG9kIGZvciBhIHN0cnVjdAorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9qc19zdHJ1Y3RfcmVhZGVyKG9mc3RyZWFtJiBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3N0cnVjdCogdHN0cnVjdCkgeworICBjb25zdCB2ZWN0b3I8dF9maWVsZCo+JiBmaWVsZHMgPSB0c3RydWN0LT5nZXRfbWVtYmVycygpOworICB2ZWN0b3I8dF9maWVsZCo+Ojpjb25zdF9pdGVyYXRvciBmX2l0ZXI7CisKKyAgb3V0IDw8ICBqc19uYW1lc3BhY2UodHN0cnVjdC0+Z2V0X3Byb2dyYW0oKSk8PHRzdHJ1Y3QtPmdldF9uYW1lKCkgPDwgIi5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGlucHV0KXsgIjw8ZW5kbDsKKworICBpbmRlbnRfdXAoKTsKKworICBpbmRlbnQob3V0KSA8PCAidmFyIHJldCA9IGlucHV0LnJlYWRTdHJ1Y3RCZWdpbigpIiA8PCBlbmRsOworCisKKyAgLy8gTG9vcCBvdmVyIHJlYWRpbmcgaW4gZmllbGRzCisgIGluZGVudChvdXQpIDw8ICJ3aGlsZSAoMSkgIiA8PCBlbmRsOworCisgIHNjb3BlX3VwKG91dCk7CisKKyAgaW5kZW50KG91dCkgPDwgInZhciByZXQgPSBpbnB1dC5yZWFkRmllbGRCZWdpbigpIiA8PCBlbmRsOworICBpbmRlbnQob3V0KSA8PCAidmFyIGZuYW1lID0gcmV0LmZuYW1lIiA8PGVuZGw7CisgIGluZGVudChvdXQpIDw8ICJ2YXIgZnR5cGUgPSByZXQuZnR5cGUiIDw8ZW5kbDsKKyAgaW5kZW50KG91dCkgPDwgInZhciBmaWQgICA9IHJldC5maWQiICAgPDxlbmRsOworCisKKyAgLy8gQ2hlY2sgZm9yIGZpZWxkIFNUT1AgbWFya2VyIGFuZCBicmVhaworICBpbmRlbnQob3V0KSA8PCAiaWYgKGZ0eXBlID09IFRocmlmdC5UeXBlLlNUT1ApICIgPDwgZW5kbDsKKyAgaW5kZW50X3VwKCk7CisgIGluZGVudChvdXQpIDw8ICJicmVhayIgPDwgZW5kbDsKKyAgaW5kZW50X2Rvd24oKTsKKworICAvLyBTd2l0Y2ggc3RhdGVtZW50IG9uIHRoZSBmaWVsZCB3ZSBhcmUgcmVhZGluZworICBpbmRlbnQob3V0KSA8PCAic3dpdGNoKGZpZCkiIDw8IGVuZGw7CisKKyAgc2NvcGVfdXAob3V0KTsKKworICAvLyBHZW5lcmF0ZSBkZXNlcmlhbGl6YXRpb24gY29kZSBmb3Iga25vd24gY2FzZXMKKyAgZm9yIChmX2l0ZXIgPSBmaWVsZHMuYmVnaW4oKTsgZl9pdGVyICE9IGZpZWxkcy5lbmQoKTsgKytmX2l0ZXIpIHsKKworICAgIGluZGVudChvdXQpIDw8ICJjYXNlICIgPDwgKCpmX2l0ZXIpLT5nZXRfa2V5KCkgPDwgIjoiOworICAgIGluZGVudChvdXQpIDw8ICJpZiAoZnR5cGUgPT0gIiA8PCB0eXBlX3RvX2VudW0oKCpmX2l0ZXIpLT5nZXRfdHlwZSgpKSA8PCAiKSB7IiA8PCBlbmRsOworCisgICAgaW5kZW50X3VwKCk7CisgICAgZ2VuZXJhdGVfZGVzZXJpYWxpemVfZmllbGQob3V0LCAqZl9pdGVyLCAidGhpcy4iKTsKKyAgICBpbmRlbnRfZG93bigpOworCisgICAgaW5kZW50KG91dCkgPDwgIn0gZWxzZSB7IiA8PCBlbmRsOworCisgICAgaW5kZW50KG91dCkgPDwgICIgIGlucHV0LnNraXAoZnR5cGUpIiA8PCBlbmRsOworCisgICAgb3V0IDw8CisgICAgICBpbmRlbnQoKSA8PCAifSIgPDwgZW5kbCA8PAorICAgICAgaW5kZW50KCkgPDwgImJyZWFrIiA8PCBlbmRsOworCisgIH0KKyAgLy8gSW4gdGhlIGRlZmF1bHQgY2FzZSB3ZSBza2lwIHRoZSBmaWVsZAorICBpbmRlbnQob3V0KSA8PCAgImRlZmF1bHQ6IiA8PCBlbmRsOworICBpbmRlbnQob3V0KSA8PCAgIiAgaW5wdXQuc2tpcChmdHlwZSkiIDw8IGVuZGw7CisKKyAgc2NvcGVfZG93bihvdXQpOworCisgIGluZGVudChvdXQpIDw8ICJpbnB1dC5yZWFkRmllbGRFbmQoKSIgPDwgZW5kbDsKKworICBzY29wZV9kb3duKG91dCk7CisKKyAgaW5kZW50KG91dCkgPDwgImlucHV0LnJlYWRTdHJ1Y3RFbmQoKSIgPDwgZW5kbDsKKworICBpbmRlbnQob3V0KSA8PCAicmV0dXJuIiA8PCBlbmRsOworCisgIGluZGVudF9kb3duKCk7CisgIG91dCA8PCBpbmRlbnQoKSA8PCAifSIgPDwgZW5kbCA8PCBlbmRsOworfQorCisvKioKKyAqIEdlbmVyYXRlcyB0aGUgd3JpdGUoKSBtZXRob2QgZm9yIGEgc3RydWN0CisgKi8KK3ZvaWQgdF9qc19nZW5lcmF0b3I6OmdlbmVyYXRlX2pzX3N0cnVjdF93cml0ZXIob2ZzdHJlYW0mIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfc3RydWN0KiB0c3RydWN0KSB7CisgIHN0cmluZyBuYW1lID0gdHN0cnVjdC0+Z2V0X25hbWUoKTsKKyAgY29uc3QgdmVjdG9yPHRfZmllbGQqPiYgZmllbGRzID0gdHN0cnVjdC0+Z2V0X21lbWJlcnMoKTsKKyAgdmVjdG9yPHRfZmllbGQqPjo6Y29uc3RfaXRlcmF0b3IgZl9pdGVyOworCisgIG91dCA8PCBqc19uYW1lc3BhY2UodHN0cnVjdC0+Z2V0X3Byb2dyYW0oKSk8PCB0c3RydWN0LT5nZXRfbmFtZSgpIDw8ICIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ob3V0cHV0KXsgIjw8ZW5kbDsKKworICBpbmRlbnRfdXAoKTsKKworICBpbmRlbnQob3V0KSA8PCAib3V0cHV0LndyaXRlU3RydWN0QmVnaW4oJyIgPDwgbmFtZSA8PCAiJykiIDw8IGVuZGw7CisKKyAgZm9yIChmX2l0ZXIgPSBmaWVsZHMuYmVnaW4oKTsgZl9pdGVyICE9IGZpZWxkcy5lbmQoKTsgKytmX2l0ZXIpIHsKKyAgICBvdXQgPDwgaW5kZW50KCkgPDwgImlmIChudWxsICE9IHRoaXMuIiA8PCAoKmZfaXRlciktPmdldF9uYW1lKCkgPDwgIikgeyIgPDwgZW5kbDsKKyAgICBpbmRlbnRfdXAoKTsKKworICAgIGluZGVudChvdXQpIDw8CisgICAgICAib3V0cHV0LndyaXRlRmllbGRCZWdpbigiIDw8CisgICAgICAiJyIgPDwgKCpmX2l0ZXIpLT5nZXRfbmFtZSgpIDw8ICInLCAiIDw8CisgICAgICB0eXBlX3RvX2VudW0oKCpmX2l0ZXIpLT5nZXRfdHlwZSgpKSA8PCAiLCAiIDw8CisgICAgICAoKmZfaXRlciktPmdldF9rZXkoKSA8PCAiKSIgPDwgZW5kbDsKKworCisgICAgLy8gV3JpdGUgZmllbGQgY29udGVudHMKKyAgICBnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQob3V0LCAqZl9pdGVyLCAidGhpcy4iKTsKKworICAgIGluZGVudChvdXQpIDw8CisgICAgICAgICJvdXRwdXQud3JpdGVGaWVsZEVuZCgpIiA8PCBlbmRsOworCisgICAgaW5kZW50X2Rvd24oKTsKKyAgICBpbmRlbnQob3V0KSA8PCAifSIgPDwgZW5kbDsKKyAgfQorCisKKyAgb3V0IDw8CisgICAgaW5kZW50KCkgPDwgIm91dHB1dC53cml0ZUZpZWxkU3RvcCgpIiA8PCBlbmRsIDw8CisgICAgaW5kZW50KCkgPDwgIm91dHB1dC53cml0ZVN0cnVjdEVuZCgpIiA8PCBlbmRsOworCisgIG91dCA8PGluZGVudCgpIDw8ICJyZXR1cm4iIDw8IGVuZGw7CisKKyAgaW5kZW50X2Rvd24oKTsKKyAgb3V0IDw8CisgICAgaW5kZW50KCkgPDwgIn0iIDw8IGVuZGwgPDwKKyAgICBlbmRsOworfQorCisvKioKKyAqIEdlbmVyYXRlcyBhIHRocmlmdCBzZXJ2aWNlLgorICoKKyAqIEBwYXJhbSB0c2VydmljZSBUaGUgc2VydmljZSBkZWZpbml0aW9uCisgKi8KK3ZvaWQgdF9qc19nZW5lcmF0b3I6OmdlbmVyYXRlX3NlcnZpY2UodF9zZXJ2aWNlKiB0c2VydmljZSkgeworICAgIHN0cmluZyBmX3NlcnZpY2VfbmFtZSA9IGdldF9vdXRfZGlyKCkrc2VydmljZV9uYW1lXysiLmpzIjsKKyAgICBmX3NlcnZpY2VfLm9wZW4oZl9zZXJ2aWNlX25hbWUuY19zdHIoKSk7CisKKyAgICBnZW5lcmF0ZV9zZXJ2aWNlX2hlbHBlcnModHNlcnZpY2UpOworICAgIGdlbmVyYXRlX3NlcnZpY2VfaW50ZXJmYWNlKHRzZXJ2aWNlKTsKKyAgICBnZW5lcmF0ZV9zZXJ2aWNlX2NsaWVudCh0c2VydmljZSk7CisKKyAgICBmX3NlcnZpY2VfLmNsb3NlKCk7Cit9CisKKy8qKgorICogR2VuZXJhdGVzIGEgc2VydmljZSBzZXJ2ZXIgZGVmaW5pdGlvbi4KKyAqCisgKiBAcGFyYW0gdHNlcnZpY2UgVGhlIHNlcnZpY2UgdG8gZ2VuZXJhdGUgYSBzZXJ2ZXIgZm9yLgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9zZXJ2aWNlX3Byb2Nlc3Nvcih0X3NlcnZpY2UqIHRzZXJ2aWNlKSB7CisKK30KKworLyoqCisgKiBHZW5lcmF0ZXMgYSBwcm9jZXNzIGZ1bmN0aW9uIGRlZmluaXRpb24uCisgKgorICogQHBhcmFtIHRmdW5jdGlvbiBUaGUgZnVuY3Rpb24gdG8gd3JpdGUgYSBkaXNwYXRjaGVyIGZvcgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9wcm9jZXNzX2Z1bmN0aW9uKHRfc2VydmljZSogdHNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9mdW5jdGlvbiogdGZ1bmN0aW9uKSB7CisKK30KKworLyoqCisgKiBHZW5lcmF0ZXMgaGVscGVyIGZ1bmN0aW9ucyBmb3IgYSBzZXJ2aWNlLgorICoKKyAqIEBwYXJhbSB0c2VydmljZSBUaGUgc2VydmljZSB0byBnZW5lcmF0ZSBhIGhlYWRlciBkZWZpbml0aW9uIGZvcgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9zZXJ2aWNlX2hlbHBlcnModF9zZXJ2aWNlKiB0c2VydmljZSkgeworICAgIHZlY3Rvcjx0X2Z1bmN0aW9uKj4gZnVuY3Rpb25zID0gdHNlcnZpY2UtPmdldF9mdW5jdGlvbnMoKTsKKyAgICB2ZWN0b3I8dF9mdW5jdGlvbio+OjppdGVyYXRvciBmX2l0ZXI7CisKKyAgICBmX3NlcnZpY2VfIDw8CisgICAgICAgICIvL0hFTFBFUiBGVU5DVElPTlMgQU5EIFNUUlVDVFVSRVMiIDw8IGVuZGwgPDwgZW5kbDsKKworICAgIGZvciAoZl9pdGVyID0gZnVuY3Rpb25zLmJlZ2luKCk7IGZfaXRlciAhPSBmdW5jdGlvbnMuZW5kKCk7ICsrZl9pdGVyKSB7CisgICAgICAgIHRfc3RydWN0KiB0cyA9ICgqZl9pdGVyKS0+Z2V0X2FyZ2xpc3QoKTsKKyAgICAgICAgc3RyaW5nIG5hbWUgPSB0cy0+Z2V0X25hbWUoKTsKKyAgICAgICAgdHMtPnNldF9uYW1lKHNlcnZpY2VfbmFtZV8gKyAiXyIgKyBuYW1lKTsKKyAgICAgICAgZ2VuZXJhdGVfanNfc3RydWN0X2RlZmluaXRpb24oZl9zZXJ2aWNlXywgdHMsIGZhbHNlKTsKKyAgICAgICAgZ2VuZXJhdGVfanNfZnVuY3Rpb25faGVscGVycygqZl9pdGVyKTsKKyAgICAgICAgdHMtPnNldF9uYW1lKG5hbWUpOworICAgIH0KK30KKworLyoqCisgKiBHZW5lcmF0ZXMgYSBzdHJ1Y3QgYW5kIGhlbHBlcnMgZm9yIGEgZnVuY3Rpb24uCisgKgorICogQHBhcmFtIHRmdW5jdGlvbiBUaGUgZnVuY3Rpb24KKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfanNfZnVuY3Rpb25faGVscGVycyh0X2Z1bmN0aW9uKiB0ZnVuY3Rpb24pIHsKKyAgICB0X3N0cnVjdCByZXN1bHQocHJvZ3JhbV8sIHNlcnZpY2VfbmFtZV8gKyAiXyIgKyB0ZnVuY3Rpb24tPmdldF9uYW1lKCkgKyAiX3Jlc3VsdCIpOworICAgIHRfZmllbGQgc3VjY2Vzcyh0ZnVuY3Rpb24tPmdldF9yZXR1cm50eXBlKCksICJzdWNjZXNzIiwgMCk7CisgICAgaWYgKCF0ZnVuY3Rpb24tPmdldF9yZXR1cm50eXBlKCktPmlzX3ZvaWQoKSkgeworICAgICAgICByZXN1bHQuYXBwZW5kKCZzdWNjZXNzKTsKKyAgICB9CisKKyAgICB0X3N0cnVjdCogeHMgPSB0ZnVuY3Rpb24tPmdldF94Y2VwdGlvbnMoKTsKKyAgICBjb25zdCB2ZWN0b3I8dF9maWVsZCo+JiBmaWVsZHMgPSB4cy0+Z2V0X21lbWJlcnMoKTsKKyAgICB2ZWN0b3I8dF9maWVsZCo+Ojpjb25zdF9pdGVyYXRvciBmX2l0ZXI7CisgICAgZm9yIChmX2l0ZXIgPSBmaWVsZHMuYmVnaW4oKTsgZl9pdGVyICE9IGZpZWxkcy5lbmQoKTsgKytmX2l0ZXIpIHsKKyAgICAgICAgcmVzdWx0LmFwcGVuZCgqZl9pdGVyKTsKKyAgICB9CisKKyAgICBnZW5lcmF0ZV9qc19zdHJ1Y3RfZGVmaW5pdGlvbihmX3NlcnZpY2VfLCAmcmVzdWx0LCBmYWxzZSk7Cit9CisKKy8qKgorICogR2VuZXJhdGVzIGEgc2VydmljZSBpbnRlcmZhY2UgZGVmaW5pdGlvbi4KKyAqCisgKiBAcGFyYW0gdHNlcnZpY2UgVGhlIHNlcnZpY2UgdG8gZ2VuZXJhdGUgYSBoZWFkZXIgZGVmaW5pdGlvbiBmb3IKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VydmljZV9pbnRlcmZhY2UodF9zZXJ2aWNlKiB0c2VydmljZSkgeworCit9CisKKy8qKgorICogR2VuZXJhdGVzIGEgUkVTVCBpbnRlcmZhY2UKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VydmljZV9yZXN0KHRfc2VydmljZSogdHNlcnZpY2UpIHsKKworfQorCisvKioKKyAqIEdlbmVyYXRlcyBhIHNlcnZpY2UgY2xpZW50IGRlZmluaXRpb24uCisgKgorICogQHBhcmFtIHRzZXJ2aWNlIFRoZSBzZXJ2aWNlIHRvIGdlbmVyYXRlIGEgc2VydmVyIGZvci4KKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VydmljZV9jbGllbnQodF9zZXJ2aWNlKiB0c2VydmljZSkgeworICBzdHJpbmcgZXh0ZW5kcyA9ICIiOworCisgIGZfc2VydmljZV8gPDwKKyAgICAgIGpzX25hbWVzcGFjZSh0c2VydmljZS0+Z2V0X3Byb2dyYW0oKSkgPDwgc2VydmljZV9uYW1lXyA8PCAiQ2xpZW50ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCkgeyI8PGVuZGw7CisKKyAgaW5kZW50X3VwKCk7CisKKworICBmX3NlcnZpY2VfIDw8CisgICAgICBpbmRlbnQoKSA8PCAiICB0aGlzLmlucHV0ICA9IGlucHV0IiA8PCBlbmRsIDw8CisgICAgICBpbmRlbnQoKSA8PCAiICB0aGlzLm91dHB1dCA9IG51bGwgPT0gb3V0cHV0ID8gaW5wdXQgOiBvdXRwdXQiIDw8IGVuZGwgPDwKKyAgICAgIGluZGVudCgpIDw8ICIgIHRoaXMuc2VxaWQgID0gMCIgPDwgZW5kbDsKKworICBpbmRlbnRfZG93bigpOworCisgIGZfc2VydmljZV8gPDwKKyAgICAgIGluZGVudCgpIDw8ICJ9IiA8PCBlbmRsOworCisKKyAgaWYgKHRzZXJ2aWNlLT5nZXRfZXh0ZW5kcygpICE9IE5VTEwpIHsKKyAgICAgIGV4dGVuZHMgPSB0c2VydmljZS0+Z2V0X2V4dGVuZHMoKS0+Z2V0X25hbWUoKTsKKworICAgICAgZl9zZXJ2aWNlXyA8PCAiZm9yICh2YXIgcHJvcGVydHkgaW4gIjw8ZXh0ZW5kczw8IkNsaWVudCkiPDxlbmRsPDwKKyAgICAgICAgICBqc19uYW1lc3BhY2UodHNlcnZpY2UtPmdldF9wcm9ncmFtKCkpIDw8IHNlcnZpY2VfbmFtZV88PCJDbGllbnRbcHJvcGVydHldID0gIjw8ZXh0ZW5kczw8IkNsaWVudFtwcm9wZXJ0eV0iPDxlbmRsOworCisgIH0KKworICAvL2luaXQgcHJvdG90eXBlCisgIGZfc2VydmljZV8gPDwgIGpzX25hbWVzcGFjZSh0c2VydmljZS0+Z2V0X3Byb2dyYW0oKSk8PHNlcnZpY2VfbmFtZV8gPDwgIkNsaWVudC5wcm90b3R5cGUgPSB7fSI8PGVuZGw7CisKKworICAvLyBHZW5lcmF0ZSBjbGllbnQgbWV0aG9kIGltcGxlbWVudGF0aW9ucworICB2ZWN0b3I8dF9mdW5jdGlvbio+IGZ1bmN0aW9ucyA9IHRzZXJ2aWNlLT5nZXRfZnVuY3Rpb25zKCk7CisgIHZlY3Rvcjx0X2Z1bmN0aW9uKj46OmNvbnN0X2l0ZXJhdG9yIGZfaXRlcjsKKyAgZm9yIChmX2l0ZXIgPSBmdW5jdGlvbnMuYmVnaW4oKTsgZl9pdGVyICE9IGZ1bmN0aW9ucy5lbmQoKTsgKytmX2l0ZXIpIHsKKyAgICB0X3N0cnVjdCogYXJnX3N0cnVjdCA9ICgqZl9pdGVyKS0+Z2V0X2FyZ2xpc3QoKTsKKyAgICBjb25zdCB2ZWN0b3I8dF9maWVsZCo+JiBmaWVsZHMgPSBhcmdfc3RydWN0LT5nZXRfbWVtYmVycygpOworICAgIHZlY3Rvcjx0X2ZpZWxkKj46OmNvbnN0X2l0ZXJhdG9yIGZsZF9pdGVyOworICAgIHN0cmluZyBmdW5uYW1lID0gKCpmX2l0ZXIpLT5nZXRfbmFtZSgpOworCisgICAgLy8gT3BlbiBmdW5jdGlvbgorICAgIGZfc2VydmljZV8gPDwgIGpzX25hbWVzcGFjZSh0c2VydmljZS0+Z2V0X3Byb2dyYW0oKSk8PHNlcnZpY2VfbmFtZV88PCJDbGllbnQucHJvdG90eXBlLiIgPDwgZnVuY3Rpb25fc2lnbmF0dXJlKCpmX2l0ZXIpIDw8ICJ7IiA8PCBlbmRsOworCisgICAgaW5kZW50X3VwKCk7CisKKyAgICBpbmRlbnQoZl9zZXJ2aWNlXykgPDwgaW5kZW50KCkgPDwKKyAgICAgICJ0aGlzLnNlbmRfIiA8PCBmdW5uYW1lIDw8ICIoIjsKKworICAgIGJvb2wgZmlyc3QgPSB0cnVlOworICAgIGZvciAoZmxkX2l0ZXIgPSBmaWVsZHMuYmVnaW4oKTsgZmxkX2l0ZXIgIT0gZmllbGRzLmVuZCgpOyArK2ZsZF9pdGVyKSB7CisgICAgICBpZiAoZmlyc3QpIHsKKyAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZfc2VydmljZV8gPDwgIiwgIjsKKyAgICAgIH0KKyAgICAgIGZfc2VydmljZV8gPDwgKCpmbGRfaXRlciktPmdldF9uYW1lKCk7CisgICAgfQorICAgIGZfc2VydmljZV8gPDwgIikiIDw8IGVuZGw7CisKKyAgICBpZiAoISgqZl9pdGVyKS0+aXNfb25ld2F5KCkpIHsKKyAgICAgIGZfc2VydmljZV8gPDwgaW5kZW50KCk7CisgICAgICBpZiAoISgqZl9pdGVyKS0+Z2V0X3JldHVybnR5cGUoKS0+aXNfdm9pZCgpKSB7CisgICAgICAgIGZfc2VydmljZV8gPDwgInJldHVybiAiOworICAgICAgfQorICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICAidGhpcy5yZWN2XyIgPDwgZnVubmFtZSA8PCAiKCkiIDw8IGVuZGw7CisgICAgfQorCisgICAgaW5kZW50X2Rvd24oKTsKKworICAgIGZfc2VydmljZV8gPDwgIn0iIDw8IGVuZGwgPDwgZW5kbDsKKworICAgIGZfc2VydmljZV8gPDwgIGpzX25hbWVzcGFjZSh0c2VydmljZS0+Z2V0X3Byb2dyYW0oKSk8PHNlcnZpY2VfbmFtZV8gPDwKKyAgICAgICAgIkNsaWVudC5wcm90b3R5cGUuc2VuZF8iIDw8IGZ1bmN0aW9uX3NpZ25hdHVyZSgqZl9pdGVyKSA8PCAieyIgPDxlbmRsOworCisgICAgaW5kZW50X3VwKCk7CisKKyAgICBzdGQ6OnN0cmluZyBhcmdzbmFtZSA9ICBqc19uYW1lc3BhY2UocHJvZ3JhbV8pKyBzZXJ2aWNlX25hbWVfICsgIl8iICsgKCpmX2l0ZXIpLT5nZXRfbmFtZSgpICsgIl9hcmdzIjsKKworICAgIC8vIFNlcmlhbGl6ZSB0aGUgcmVxdWVzdCBoZWFkZXIKKyAgICBmX3NlcnZpY2VfIDw8CisgICAgICBpbmRlbnQoKSA8PCAidGhpcy5vdXRwdXQud3JpdGVNZXNzYWdlQmVnaW4oJyIgPDwgKCpmX2l0ZXIpLT5nZXRfbmFtZSgpIDw8ICInLCBUaHJpZnQuTWVzc2FnZVR5cGUuQ0FMTCwgdGhpcy5zZXFpZCkiIDw8IGVuZGw7CisKKyAgICBmX3NlcnZpY2VfIDw8CisgICAgICBpbmRlbnQoKSA8PCAidmFyIGFyZ3MgPSBuZXcgIiA8PCBhcmdzbmFtZSA8PCAiKCkiIDw8IGVuZGw7CisKKyAgICBmb3IgKGZsZF9pdGVyID0gZmllbGRzLmJlZ2luKCk7IGZsZF9pdGVyICE9IGZpZWxkcy5lbmQoKTsgKytmbGRfaXRlcikgeworICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICBpbmRlbnQoKSA8PCAiYXJncy4iIDw8ICgqZmxkX2l0ZXIpLT5nZXRfbmFtZSgpIDw8ICIgPSAiIDw8ICgqZmxkX2l0ZXIpLT5nZXRfbmFtZSgpIDw8IGVuZGw7CisgICAgfQorCisgICAgLy8gV3JpdGUgdG8gdGhlIHN0cmVhbQorICAgIGZfc2VydmljZV8gPDwKKyAgICAgIGluZGVudCgpIDw8ICJhcmdzLndyaXRlKHRoaXMub3V0cHV0KSIgPDwgZW5kbCA8PAorICAgICAgaW5kZW50KCkgPDwgInRoaXMub3V0cHV0LndyaXRlTWVzc2FnZUVuZCgpIiA8PCBlbmRsIDw8CisgICAgICBpbmRlbnQoKSA8PCAicmV0dXJuIHRoaXMub3V0cHV0LmdldFRyYW5zcG9ydCgpLmZsdXNoKCkiIDw8IGVuZGw7CisKKworICAgIGluZGVudF9kb3duKCk7CisKKyAgICBmX3NlcnZpY2VfIDw8ICJ9IiA8PCBlbmRsOworCisKKyAgICBpZiAoISgqZl9pdGVyKS0+aXNfb25ld2F5KCkpIHsKKyAgICAgIHN0ZDo6c3RyaW5nIHJlc3VsdG5hbWUgPSBqc19uYW1lc3BhY2UodHNlcnZpY2UtPmdldF9wcm9ncmFtKCkpICsgc2VydmljZV9uYW1lXyArICJfIiArICgqZl9pdGVyKS0+Z2V0X25hbWUoKSArICJfcmVzdWx0IjsKKyAgICAgIHRfc3RydWN0IG5vYXJncyhwcm9ncmFtXyk7CisKKyAgICAgIHRfZnVuY3Rpb24gcmVjdl9mdW5jdGlvbigoKmZfaXRlciktPmdldF9yZXR1cm50eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKCJyZWN2XyIpICsgKCpmX2l0ZXIpLT5nZXRfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZub2FyZ3MpOworICAgICAgLy8gT3BlbiBmdW5jdGlvbgorICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICAgIGVuZGwgPDwgIGpzX25hbWVzcGFjZSh0c2VydmljZS0+Z2V0X3Byb2dyYW0oKSk8PHNlcnZpY2VfbmFtZV8gPDwKKyAgICAgICAgICAiQ2xpZW50LnByb3RvdHlwZS4iIDw8IGZ1bmN0aW9uX3NpZ25hdHVyZSgmcmVjdl9mdW5jdGlvbikgPDwgInsiIDw8IGVuZGw7CisKKyAgICAgIGluZGVudF91cCgpOworCisgICAgICBmX3NlcnZpY2VfIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgInZhciByZXQgPSB0aGlzLmlucHV0LnJlYWRNZXNzYWdlQmVnaW4oKSIgPDwgZW5kbCA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICJ2YXIgZm5hbWUgPSByZXQuZm5hbWUiIDw8IGVuZGwgPDwKKyAgICAgICAgICBpbmRlbnQoKSA8PCAidmFyIG10eXBlID0gcmV0Lm10eXBlIiA8PCBlbmRsIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgInZhciByc2VxaWQ9IHJldC5yc2VxaWQiIDw8ZW5kbCA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICJpZiAobXR5cGUgPT0gVGhyaWZ0Lk1lc3NhZ2VUeXBlLkVYQ0VQVElPTikgeyIgPDwgZW5kbCA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICIgIHZhciB4ID0gbmV3IFRocmlmdC5BcHBsaWNhdGlvbkV4Y2VwdGlvbigpIiA8PCBlbmRsIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgIiAgeC5yZWFkKHRoaXMuaW5wdXQpIiA8PCBlbmRsIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgIiAgdGhpcy5pbnB1dC5yZWFkTWVzc2FnZUVuZCgpIiA8PCBlbmRsIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgIiAgdGhyb3cgeCIgPDwgZW5kbCA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICJ9IiA8PCBlbmRsOworCisKKyAgICAgIGZfc2VydmljZV8gPDwKKyAgICAgICAgaW5kZW50KCkgPDwgInZhciByZXN1bHQgPSBuZXcgIiA8PCByZXN1bHRuYW1lIDw8ICIoKSIgPDwgZW5kbCA8PAorICAgICAgICBpbmRlbnQoKSA8PCAicmVzdWx0LnJlYWQodGhpcy5pbnB1dCkiIDw8IGVuZGw7CisKKworICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICBpbmRlbnQoKSA8PCAidGhpcy5pbnB1dC5yZWFkTWVzc2FnZUVuZCgpIiA8PCBlbmRsIDw8CisgICAgICAgIGVuZGw7CisKKworICAgICAgLy8gQ2FyZWZ1bCwgb25seSByZXR1cm4gcmVzdWx0IGlmIG5vdCBhIHZvaWQgZnVuY3Rpb24KKyAgICAgIGlmICghKCpmX2l0ZXIpLT5nZXRfcmV0dXJudHlwZSgpLT5pc192b2lkKCkpIHsKKyAgICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICJpZiAobnVsbCAhPSByZXN1bHQuc3VjY2VzcyApIHsiIDw8IGVuZGwgPDwKKyAgICAgICAgICBpbmRlbnQoKSA8PCAiICByZXR1cm4gcmVzdWx0LnN1Y2Nlc3MiIDw8IGVuZGwgPDwKKyAgICAgICAgICBpbmRlbnQoKSA8PCAifSIgPDwgZW5kbDsKKyAgICAgIH0KKworICAgICAgdF9zdHJ1Y3QqIHhzID0gKCpmX2l0ZXIpLT5nZXRfeGNlcHRpb25zKCk7CisgICAgICBjb25zdCBzdGQ6OnZlY3Rvcjx0X2ZpZWxkKj4mIHhjZXB0aW9ucyA9IHhzLT5nZXRfbWVtYmVycygpOworICAgICAgdmVjdG9yPHRfZmllbGQqPjo6Y29uc3RfaXRlcmF0b3IgeF9pdGVyOworICAgICAgZm9yICh4X2l0ZXIgPSB4Y2VwdGlvbnMuYmVnaW4oKTsgeF9pdGVyICE9IHhjZXB0aW9ucy5lbmQoKTsgKyt4X2l0ZXIpIHsKKyAgICAgICAgZl9zZXJ2aWNlXyA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICJpZiAobnVsbCAhPSByZXN1bHQuIiA8PCAoKnhfaXRlciktPmdldF9uYW1lKCkgPDwgIikgeyIgPDwgZW5kbCA8PAorICAgICAgICAgIGluZGVudCgpIDw8ICIgIHRocm93IHJlc3VsdC4iIDw8ICgqeF9pdGVyKS0+Z2V0X25hbWUoKSA8PCBlbmRsIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgIn0iIDw8IGVuZGw7CisgICAgICB9CisKKyAgICAgIC8vIENhcmVmdWwsIG9ubHkgcmV0dXJuIF9yZXN1bHQgaWYgbm90IGEgdm9pZCBmdW5jdGlvbgorICAgICAgaWYgKCgqZl9pdGVyKS0+Z2V0X3JldHVybnR5cGUoKS0+aXNfdm9pZCgpKSB7CisgICAgICAgIGluZGVudChmX3NlcnZpY2VfKSA8PAorICAgICAgICAgICJyZXR1cm4iIDw8IGVuZGw7CisgICAgICB9IGVsc2UgeworICAgICAgICBmX3NlcnZpY2VfIDw8CisgICAgICAgICAgaW5kZW50KCkgPDwgInRocm93IFwiIiA8PCAoKmZfaXRlciktPmdldF9uYW1lKCkgPDwgIiBmYWlsZWQ6IHVua25vd24gcmVzdWx0XCIiIDw8IGVuZGw7CisgICAgICB9CisKKyAgICAgIC8vIENsb3NlIGZ1bmN0aW9uCisgICAgICBpbmRlbnRfZG93bigpOworICAgICAgZl9zZXJ2aWNlXyA8PCAifSI8PGVuZGw7CisKKyAgICB9CisgIH0KKworfQorCisvKioKKyAqIERlc2VyaWFsaXplcyBhIGZpZWxkIG9mIGFueSB0eXBlLgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9maWVsZChvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2ZpZWxkKiB0ZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW5jbGFzcykgeworICB0X3R5cGUqIHR5cGUgPSBnZXRfdHJ1ZV90eXBlKHRmaWVsZC0+Z2V0X3R5cGUoKSk7CisKKyAgaWYgKHR5cGUtPmlzX3ZvaWQoKSkgeworICAgIHRocm93ICJDQU5OT1QgR0VORVJBVEUgREVTRVJJQUxJWkUgQ09ERSBGT1Igdm9pZCBUWVBFOiAiICsKKyAgICAgIHByZWZpeCArIHRmaWVsZC0+Z2V0X25hbWUoKTsKKyAgfQorCisgIHN0cmluZyBuYW1lID0gcHJlZml4K3RmaWVsZC0+Z2V0X25hbWUoKTsKKworICBpZiAodHlwZS0+aXNfc3RydWN0KCkgfHwgdHlwZS0+aXNfeGNlcHRpb24oKSkgeworICAgIGdlbmVyYXRlX2Rlc2VyaWFsaXplX3N0cnVjdChvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0X3N0cnVjdCopdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX2NvbnRhaW5lcigpKSB7CisgICAgZ2VuZXJhdGVfZGVzZXJpYWxpemVfY29udGFpbmVyKG91dCwgdHlwZSwgbmFtZSk7CisgIH0gZWxzZSBpZiAodHlwZS0+aXNfYmFzZV90eXBlKCkgfHwgdHlwZS0+aXNfZW51bSgpKSB7CisgICAgaW5kZW50KG91dCkgPDwgInZhciBydG1wID0gaW5wdXQuIjsKKworICAgIGlmICh0eXBlLT5pc19iYXNlX3R5cGUoKSkgeworICAgICAgdF9iYXNlX3R5cGU6OnRfYmFzZSB0YmFzZSA9ICgodF9iYXNlX3R5cGUqKXR5cGUpLT5nZXRfYmFzZSgpOworICAgICAgc3dpdGNoICh0YmFzZSkgeworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9WT0lEOgorICAgICAgICB0aHJvdyAiY29tcGlsZXIgZXJyb3I6IGNhbm5vdCBzZXJpYWxpemUgdm9pZCBmaWVsZCBpbiBhIHN0cnVjdDogIiArCisgICAgICAgICAgbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX1NUUklORzoKKyAgICAgICAgb3V0IDw8ICJyZWFkU3RyaW5nKCkiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfQk9PTDoKKyAgICAgICAgb3V0IDw8ICJyZWFkQm9vbCgpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0JZVEU6CisgICAgICAgIG91dCA8PCAicmVhZEJ5dGUoKSI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JMTY6CisgICAgICAgIG91dCA8PCAicmVhZEkxNigpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0kzMjoKKyAgICAgICAgb3V0IDw8ICJyZWFkSTMyKCkiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTY0OgorICAgICAgICBvdXQgPDwgInJlYWRJNjQoKSI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9ET1VCTEU6CisgICAgICAgIG91dCA8PCAicmVhZERvdWJsZSgpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyAiY29tcGlsZXIgZXJyb3I6IG5vIEpTIG5hbWUgZm9yIGJhc2UgdHlwZSAiICsgdF9iYXNlX3R5cGU6OnRfYmFzZV9uYW1lKHRiYXNlKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKHR5cGUtPmlzX2VudW0oKSkgeworICAgICAgb3V0IDw8ICJyZWFkSTMyKCkiOworICAgIH0KKyAgICBvdXQgPDwgZW5kbDsKKworICAgIG91dCA8PG5hbWUgPDwgIiA9IHJ0bXAudmFsdWUiPDxlbmRsOworCisKKyAgfSBlbHNlIHsKKyAgICBwcmludGYoIkRPIE5PVCBLTk9XIEhPVyBUTyBERVNFUklBTElaRSBGSUVMRCAnJXMnIFRZUEUgJyVzJ1xuIiwKKyAgICAgICAgICAgdGZpZWxkLT5nZXRfbmFtZSgpLmNfc3RyKCksIHR5cGUtPmdldF9uYW1lKCkuY19zdHIoKSk7CisgIH0KK30KKworLyoqCisgKiBHZW5lcmF0ZXMgYW4gdW5zZXJpYWxpemVyIGZvciBhIHZhcmlhYmxlLiBUaGlzIG1ha2VzIHR3byBrZXkgYXNzdW1wdGlvbnMsCisgKiBmaXJzdCB0aGF0IHRoZXJlIGlzIGEgY29uc3QgY2hhciogdmFyaWFibGUgbmFtZWQgZGF0YSB0aGF0IHBvaW50cyB0byB0aGUKKyAqIGJ1ZmZlciBmb3IgZGVzZXJpYWxpemF0aW9uLCBhbmQgdGhhdCB0aGVyZSBpcyBhIHZhcmlhYmxlIHByb3RvY29sIHdoaWNoCisgKiBpcyBhIHJlZmVyZW5jZSB0byBhIFRQcm90b2NvbCBzZXJpYWxpemF0aW9uIG9iamVjdC4KKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfZGVzZXJpYWxpemVfc3RydWN0KG9mc3RyZWFtICZvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3N0cnVjdCogdHN0cnVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgpIHsKKyAgICBvdXQgPDwKKyAgICAgICAgaW5kZW50KCkgPDwgcHJlZml4IDw8ICIgPSBuZXcgIiA8PCAganNfbmFtZXNwYWNlKHRzdHJ1Y3QtPmdldF9wcm9ncmFtKCkpPDx0c3RydWN0LT5nZXRfbmFtZSgpIDw8ICIoKSIgPDwgZW5kbCA8PAorICAgICAgICBpbmRlbnQoKSA8PCBwcmVmaXggPDwgIi5yZWFkKGlucHV0KSIgPDwgZW5kbDsKKworfQorCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9jb250YWluZXIob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfdHlwZSogdHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgcHJlZml4KSB7CisgIHNjb3BlX3VwKG91dCk7CisKKyAgc3RyaW5nIHNpemUgPSB0bXAoIl9zaXplIik7CisgIHN0cmluZyBrdHlwZSA9IHRtcCgiX2t0eXBlIik7CisgIHN0cmluZyB2dHlwZSA9IHRtcCgiX3Z0eXBlIik7CisgIHN0cmluZyBldHlwZSA9IHRtcCgiX2V0eXBlIik7CisKKyAgdF9maWVsZCBmc2l6ZShnX3R5cGVfaTMyLCBzaXplKTsKKyAgdF9maWVsZCBma3R5cGUoZ190eXBlX2J5dGUsIGt0eXBlKTsKKyAgdF9maWVsZCBmdnR5cGUoZ190eXBlX2J5dGUsIHZ0eXBlKTsKKyAgdF9maWVsZCBmZXR5cGUoZ190eXBlX2J5dGUsIGV0eXBlKTsKKworICBvdXQgPDwgaW5kZW50KCkgPDwgInZhciAiIDw8IHNpemUgPDwgIiA9IDAiIDw8IGVuZGw7CisgIG91dCA8PCBpbmRlbnQoKSA8PCAidmFyIHJ0bXAzIiA8PCBlbmRsOworCisKKyAgLy8gRGVjbGFyZSB2YXJpYWJsZXMsIHJlYWQgaGVhZGVyCisgIGlmICh0dHlwZS0+aXNfbWFwKCkpIHsKKyAgICAgIG91dCA8PAorICAgICAgICAgIGluZGVudCgpIDw8IHByZWZpeCA8PCAiID0ge30iIDw8IGVuZGwgPDwKKyAgICAgICAgICBpbmRlbnQoKSA8PCAidmFyICIgPDwga3R5cGUgPDwgIiA9IDAiIDw8IGVuZGwgPDwKKyAgICAgICAgICBpbmRlbnQoKSA8PCAidmFyICIgPDwgdnR5cGUgPDwgIiA9IDAiIDw8IGVuZGw7CisKKyAgICAgIG91dCA8PCBpbmRlbnQoKSA8PCAicnRtcDMgPSBpbnB1dC5yZWFkTWFwQmVnaW4oKSIgPDwgZW5kbDsKKyAgICAgIG91dCA8PCBpbmRlbnQoKSA8PCBrdHlwZSA8PCAiPSBydG1wMy5rdHlwZSIgPDwgZW5kbDsKKyAgICAgIG91dCA8PCBpbmRlbnQoKSA8PCB2dHlwZSA8PCAiPSBydG1wMy52dHlwZSIgPDwgZW5kbDsKKyAgICAgIG91dCA8PCBpbmRlbnQoKSA8PCBzaXplICA8PCAiPSBydG1wMy5zaXplIiA8PCBlbmRsOworCisKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfc2V0KCkpIHsKKworICAgIG91dCA8PAorICAgICAgICBpbmRlbnQoKSA8PCBwcmVmaXggPDwgIiA9IFtdIiA8PCBlbmRsIDw8CisgICAgICAgIGluZGVudCgpIDw8ICJ2YXIgIiA8PCBldHlwZSA8PCAiID0gMCIgPDwgZW5kbCA8PAorICAgICAgICBpbmRlbnQoKSA8PCAicnRtcDMgPSBpbnB1dC5yZWFkU2V0QmVnaW4oKSIgPDwgZW5kbCA8PAorICAgICAgICBpbmRlbnQoKSA8PCBldHlwZSA8PCAiPSBydG1wMy5ldHlwZSI8PGVuZGw8PAorICAgICAgICBpbmRlbnQoKSA8PCBzaXplIDw8ICIgPSBydG1wMy5zaXplIjw8ZW5kbDsKKworICB9IGVsc2UgaWYgKHR0eXBlLT5pc19saXN0KCkpIHsKKworICAgIG91dCA8PAorICAgICAgICBpbmRlbnQoKSA8PCBwcmVmaXggPDwgIiA9IFtdIiA8PCBlbmRsIDw8CisgICAgICAgIGluZGVudCgpIDw8ICJ2YXIgIiA8PCBldHlwZSA8PCAiID0gMCIgPDwgZW5kbCA8PAorICAgICAgICBpbmRlbnQoKSA8PCAicnRtcDMgPSBpbnB1dC5yZWFkTGlzdEJlZ2luKCkiIDw8IGVuZGwgPDwKKyAgICAgICAgaW5kZW50KCkgPDwgZXR5cGUgPDwgIiA9IHJ0bXAzLmV0eXBlIjw8ZW5kbDw8CisgICAgICAgIGluZGVudCgpIDw8IHNpemUgPDwgIiA9IHJ0bXAzLnNpemUiPDxlbmRsOworICB9CisKKyAgLy8gRm9yIGxvb3AgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cworICBzdHJpbmcgaSA9IHRtcCgiX2kiKTsKKyAgaW5kZW50KG91dCkgPDwKKyAgICAiZm9yICh2YXIgIiA8PAorICAgIGkgPDwgIiA9IDA7ICIgPDwgaSA8PCAiIDwgIiA8PCBzaXplIDw8ICI7ICsrIiA8PCBpIDw8ICIpIiA8PCBlbmRsOworCisgIHNjb3BlX3VwKG91dCk7CisKKyAgaWYgKHR0eXBlLT5pc19tYXAoKSkgeworICAgIGdlbmVyYXRlX2Rlc2VyaWFsaXplX21hcF9lbGVtZW50KG91dCwgKHRfbWFwKil0dHlwZSwgcHJlZml4KTsKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfc2V0KCkpIHsKKyAgICBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9zZXRfZWxlbWVudChvdXQsICh0X3NldCopdHR5cGUsIHByZWZpeCk7CisgIH0gZWxzZSBpZiAodHR5cGUtPmlzX2xpc3QoKSkgeworICAgIGdlbmVyYXRlX2Rlc2VyaWFsaXplX2xpc3RfZWxlbWVudChvdXQsICh0X2xpc3QqKXR0eXBlLCBwcmVmaXgpOworICB9CisKKyAgc2NvcGVfZG93bihvdXQpOworCisKKyAgLy8gUmVhZCBjb250YWluZXIgZW5kCisgIGlmICh0dHlwZS0+aXNfbWFwKCkpIHsKKyAgICBpbmRlbnQob3V0KSA8PCAiaW5wdXQucmVhZE1hcEVuZCgpIiA8PCBlbmRsOworICB9IGVsc2UgaWYgKHR0eXBlLT5pc19zZXQoKSkgeworICAgIGluZGVudChvdXQpIDw8ICJpbnB1dC5yZWFkU2V0RW5kKCkiIDw8IGVuZGw7CisgIH0gZWxzZSBpZiAodHR5cGUtPmlzX2xpc3QoKSkgeworICAgIGluZGVudChvdXQpIDw8ICJpbnB1dC5yZWFkTGlzdEVuZCgpIiA8PCBlbmRsOworICB9CisKKyAgc2NvcGVfZG93bihvdXQpOworfQorCisKKy8qKgorICogR2VuZXJhdGVzIGNvZGUgdG8gZGVzZXJpYWxpemUgYSBtYXAKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfZGVzZXJpYWxpemVfbWFwX2VsZW1lbnQob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdF9tYXAqIHRtYXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgpIHsKKyAgc3RyaW5nIGtleSA9IHRtcCgia2V5Iik7CisgIHN0cmluZyB2YWwgPSB0bXAoInZhbCIpOworICB0X2ZpZWxkIGZrZXkodG1hcC0+Z2V0X2tleV90eXBlKCksIGtleSk7CisgIHRfZmllbGQgZnZhbCh0bWFwLT5nZXRfdmFsX3R5cGUoKSwgdmFsKTsKKworICBpbmRlbnQob3V0KSA8PAorICAgIGRlY2xhcmVfZmllbGQoJmZrZXksIHRydWUsIGZhbHNlKSA8PCBlbmRsOworICBpbmRlbnQob3V0KSA8PAorICAgIGRlY2xhcmVfZmllbGQoJmZ2YWwsIHRydWUsIGZhbHNlKSA8PCBlbmRsOworCisgIGdlbmVyYXRlX2Rlc2VyaWFsaXplX2ZpZWxkKG91dCwgJmZrZXkpOworICBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9maWVsZChvdXQsICZmdmFsKTsKKworICBpbmRlbnQob3V0KSA8PAorICAgICAgcHJlZml4IDw8ICJbIiA8PCBrZXkgPDwgIl0gPSAiIDw8IHZhbCA8PCBlbmRsOworfQorCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9zZXRfZWxlbWVudChvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X3NldCogdHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHByZWZpeCkgeworICBzdHJpbmcgZWxlbSA9IHRtcCgiZWxlbSIpOworICB0X2ZpZWxkIGZlbGVtKHRzZXQtPmdldF9lbGVtX3R5cGUoKSwgZWxlbSk7CisKKyAgaW5kZW50KG91dCkgPDwKKyAgICAidmFyICIgPDwgZWxlbSA8PCAiID0gbnVsbCIgPDwgZW5kbDsKKworICBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9maWVsZChvdXQsICZmZWxlbSk7CisKKyAgaW5kZW50KG91dCkgPDwKKyAgICAgIHByZWZpeCA8PCAiLnB1c2goIiA8PCBlbGVtIDw8ICIpIiA8PCBlbmRsOworfQorCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9saXN0X2VsZW1lbnQob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfbGlzdCogdGxpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgcHJlZml4KSB7CisgIHN0cmluZyBlbGVtID0gdG1wKCJlbGVtIik7CisgIHRfZmllbGQgZmVsZW0odGxpc3QtPmdldF9lbGVtX3R5cGUoKSwgZWxlbSk7CisKKyAgaW5kZW50KG91dCkgPDwKKyAgICAidmFyICIgPDwgZWxlbSA8PCAiID0gbnVsbCIgPDwgZW5kbDsKKworICBnZW5lcmF0ZV9kZXNlcmlhbGl6ZV9maWVsZChvdXQsICZmZWxlbSk7CisKKyAgaW5kZW50KG91dCkgPDwKKyAgICAgIHByZWZpeCA8PCAiLnB1c2goIiA8PCBlbGVtIDw8ICIpIiA8PCBlbmRsOworfQorCisKKy8qKgorICogU2VyaWFsaXplcyBhIGZpZWxkIG9mIGFueSB0eXBlLgorICoKKyAqIEBwYXJhbSB0ZmllbGQgVGhlIGZpZWxkIHRvIHNlcmlhbGl6ZQorICogQHBhcmFtIHByZWZpeCBOYW1lIHRvIHByZXBlbmQgdG8gZmllbGQgbmFtZQorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfZmllbGQqIHRmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgpIHsKKyAgdF90eXBlKiB0eXBlID0gZ2V0X3RydWVfdHlwZSh0ZmllbGQtPmdldF90eXBlKCkpOworCisgIC8vIERvIG5vdGhpbmcgZm9yIHZvaWQgdHlwZXMKKyAgaWYgKHR5cGUtPmlzX3ZvaWQoKSkgeworICAgIHRocm93ICJDQU5OT1QgR0VORVJBVEUgU0VSSUFMSVpFIENPREUgRk9SIHZvaWQgVFlQRTogIiArCisgICAgICBwcmVmaXggKyB0ZmllbGQtPmdldF9uYW1lKCk7CisgIH0KKworICBpZiAodHlwZS0+aXNfc3RydWN0KCkgfHwgdHlwZS0+aXNfeGNlcHRpb24oKSkgeworICAgIGdlbmVyYXRlX3NlcmlhbGl6ZV9zdHJ1Y3Qob3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRfc3RydWN0Kil0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCArdGZpZWxkLT5nZXRfbmFtZSgpICk7CisgIH0gZWxzZSBpZiAodHlwZS0+aXNfY29udGFpbmVyKCkpIHsKKyAgICBnZW5lcmF0ZV9zZXJpYWxpemVfY29udGFpbmVyKG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXggKyB0ZmllbGQtPmdldF9uYW1lKCkpOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX2Jhc2VfdHlwZSgpIHx8IHR5cGUtPmlzX2VudW0oKSkgeworCisgICAgc3RyaW5nIG5hbWUgPSB0ZmllbGQtPmdldF9uYW1lKCk7CisKKyAgICAvL0hhY2sgZm9yIHdoZW4gcHJlZml4IGlzIGRlZmluZWQgKGFsd2F5cyBhIGhhc2ggcmVmKQorICAgIGlmKCFwcmVmaXguZW1wdHkoKSkKKyAgICAgIG5hbWUgPSBwcmVmaXggKyB0ZmllbGQtPmdldF9uYW1lKCk7CisKKyAgICBpbmRlbnQob3V0KSA8PCAib3V0cHV0LiI7CisKKyAgICBpZiAodHlwZS0+aXNfYmFzZV90eXBlKCkpIHsKKyAgICAgIHRfYmFzZV90eXBlOjp0X2Jhc2UgdGJhc2UgPSAoKHRfYmFzZV90eXBlKil0eXBlKS0+Z2V0X2Jhc2UoKTsKKyAgICAgIHN3aXRjaCAodGJhc2UpIHsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfVk9JRDoKKyAgICAgICAgdGhyb3cKKyAgICAgICAgICAiY29tcGlsZXIgZXJyb3I6IGNhbm5vdCBzZXJpYWxpemUgdm9pZCBmaWVsZCBpbiBhIHN0cnVjdDogIiArIG5hbWU7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9TVFJJTkc6CisgICAgICAgIG91dCA8PCAid3JpdGVTdHJpbmcoIiA8PCBuYW1lIDw8ICIpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0JPT0w6CisgICAgICAgIG91dCA8PCAid3JpdGVCb29sKCIgPDwgbmFtZSA8PCAiKSI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9CWVRFOgorICAgICAgICBvdXQgPDwgIndyaXRlQnl0ZSgiIDw8IG5hbWUgPDwgIikiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTE2OgorICAgICAgICBvdXQgPDwgIndyaXRlSTE2KCIgPDwgbmFtZSA8PCAiKSI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JMzI6CisgICAgICAgIG91dCA8PCAid3JpdGVJMzIoIiA8PCBuYW1lIDw8ICIpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0k2NDoKKyAgICAgICAgb3V0IDw8ICJ3cml0ZUk2NCgiIDw8IG5hbWUgPDwgIikiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfRE9VQkxFOgorICAgICAgICBvdXQgPDwgIndyaXRlRG91YmxlKCIgPDwgbmFtZSA8PCAiKSI7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgImNvbXBpbGVyIGVycm9yOiBubyBKUyBuYW1lIGZvciBiYXNlIHR5cGUgIiArIHRfYmFzZV90eXBlOjp0X2Jhc2VfbmFtZSh0YmFzZSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmICh0eXBlLT5pc19lbnVtKCkpIHsKKyAgICAgIG91dCA8PCAid3JpdGVJMzIoIiA8PCBuYW1lIDw8ICIpIjsKKyAgICB9CisgICAgb3V0IDw8IGVuZGw7CisKKyAgfSBlbHNlIHsKKyAgICBwcmludGYoIkRPIE5PVCBLTk9XIEhPVyBUTyBTRVJJQUxJWkUgRklFTEQgJyVzJXMnIFRZUEUgJyVzJ1xuIiwKKyAgICAgICAgICAgcHJlZml4LmNfc3RyKCksCisgICAgICAgICAgIHRmaWVsZC0+Z2V0X25hbWUoKS5jX3N0cigpLAorICAgICAgICAgICB0eXBlLT5nZXRfbmFtZSgpLmNfc3RyKCkpOworICB9Cit9CisKKy8qKgorICogU2VyaWFsaXplcyBhbGwgdGhlIG1lbWJlcnMgb2YgYSBzdHJ1Y3QuCisgKgorICogQHBhcmFtIHRzdHJ1Y3QgVGhlIHN0cnVjdCB0byBzZXJpYWxpemUKKyAqIEBwYXJhbSBwcmVmaXggIFN0cmluZyBwcmVmaXggdG8gYXR0YWNoIHRvIGFsbCBmaWVsZHMKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VyaWFsaXplX3N0cnVjdChvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfc3RydWN0KiB0c3RydWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgpIHsKKyAgICBpbmRlbnQob3V0KSA8PCBwcmVmaXggPDwgIi53cml0ZShvdXRwdXQpIiA8PCBlbmRsOworfQorCisvKioKKyAqIFdyaXRlcyBvdXQgYSBjb250YWluZXIKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VyaWFsaXplX2NvbnRhaW5lcihvZnN0cmVhbSAmb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfdHlwZSogdHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHByZWZpeCkgeworICBzY29wZV91cChvdXQpOworCisgIGlmICh0dHlwZS0+aXNfbWFwKCkpIHsKKyAgICBpbmRlbnQob3V0KSA8PAorICAgICAgICAib3V0cHV0LndyaXRlTWFwQmVnaW4oIiA8PAorICAgICAgICB0eXBlX3RvX2VudW0oKCh0X21hcCopdHR5cGUpLT5nZXRfa2V5X3R5cGUoKSkgPDwgIiwgIiA8PAorICAgICAgICB0eXBlX3RvX2VudW0oKCh0X21hcCopdHR5cGUpLT5nZXRfdmFsX3R5cGUoKSkgPDwgIiwgIiA8PAorICAgICAgICBwcmVmaXggPDwgIi5sZW5ndGgpIiA8PCBlbmRsOworICB9IGVsc2UgaWYgKHR0eXBlLT5pc19zZXQoKSkgeworICAgIGluZGVudChvdXQpIDw8CisgICAgICAib3V0cHV0LndyaXRlU2V0QmVnaW4oIiA8PAorICAgICAgdHlwZV90b19lbnVtKCgodF9zZXQqKXR0eXBlKS0+Z2V0X2VsZW1fdHlwZSgpKSA8PCAiLCAiIDw8CisgICAgICAgIHByZWZpeCA8PCAiLmxlbmd0aCkiIDw8IGVuZGw7CisKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfbGlzdCgpKSB7CisKKyAgICBpbmRlbnQob3V0KSA8PAorICAgICAgICAib3V0cHV0LndyaXRlTGlzdEJlZ2luKCIgPDwKKyAgICAgICAgdHlwZV90b19lbnVtKCgodF9saXN0Kil0dHlwZSktPmdldF9lbGVtX3R5cGUoKSkgPDwgIiwgIiA8PAorICAgICAgICBwcmVmaXggPDwgIi5sZW5ndGgpIiA8PCBlbmRsOworCisgIH0KKworICBzY29wZV91cChvdXQpOworCisgIGlmICh0dHlwZS0+aXNfbWFwKCkpIHsKKyAgICBzdHJpbmcga2l0ZXIgPSB0bXAoImtpdGVyIik7CisgICAgc3RyaW5nIHZpdGVyID0gdG1wKCJ2aXRlciIpOworICAgIGluZGVudChvdXQpIDw8ICJmb3IodmFyICI8PGtpdGVyPDwiIGluICI8PHByZWZpeDw8IikiOworICAgIHNjb3BlX3VwKG91dCk7CisgICAgaW5kZW50KG91dCkgPDwgInZhciAiPDx2aXRlcjw8IiA9ICI8PHByZWZpeDw8IlsiPDxraXRlcjw8Il0iPDxlbmRsOworICAgIGdlbmVyYXRlX3NlcmlhbGl6ZV9tYXBfZWxlbWVudChvdXQsICh0X21hcCopdHR5cGUsIGtpdGVyLCB2aXRlcik7CisgICAgc2NvcGVfZG93bihvdXQpOworCisKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfc2V0KCkpIHsKKyAgICBzdHJpbmcgaXRlciA9IHRtcCgiaXRlciIpOworICAgIGluZGVudChvdXQpIDw8CisgICAgICAiZm9yKHZhciAiPDxpdGVyPDwiIGluICIgPDwgcHJlZml4IDw8ICIpIiA8PCBlbmRsOworICAgIHNjb3BlX3VwKG91dCk7CisgICAgaW5kZW50KG91dCkgPDwgaXRlciA8PCAiPSIgPDwgcHJlZml4IDw8ICJbIiA8PCBpdGVyIDw8ICJdIjw8IGVuZGw7CisgICAgZ2VuZXJhdGVfc2VyaWFsaXplX3NldF9lbGVtZW50KG91dCwgKHRfc2V0Kil0dHlwZSwgaXRlcik7CisgICAgc2NvcGVfZG93bihvdXQpOworCisKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfbGlzdCgpKSB7CisgICAgc3RyaW5nIGl0ZXIgPSB0bXAoIml0ZXIiKTsKKyAgICBpbmRlbnQob3V0KSA8PAorICAgICAgICAiZm9yKHZhciAiPDxpdGVyPDwiIGluICI8PCBwcmVmaXggPDwgIikiIDw8IGVuZGw7CisgICAgc2NvcGVfdXAob3V0KTsKKyAgICBpbmRlbnQob3V0KSA8PCBpdGVyIDw8ICI9IiA8PCBwcmVmaXggPDwgIlsiIDw8IGl0ZXIgPDwgIl0iPDwgZW5kbDsKKyAgICBnZW5lcmF0ZV9zZXJpYWxpemVfbGlzdF9lbGVtZW50KG91dCwgKHRfbGlzdCopdHR5cGUsIGl0ZXIpOworICAgIHNjb3BlX2Rvd24ob3V0KTsKKyAgfQorCisgIHNjb3BlX2Rvd24ob3V0KTsKKworICBpZiAodHR5cGUtPmlzX21hcCgpKSB7CisgICAgaW5kZW50KG91dCkgPDwKKyAgICAgICJvdXRwdXQud3JpdGVNYXBFbmQoKSIgPDwgZW5kbDsKKyAgfSBlbHNlIGlmICh0dHlwZS0+aXNfc2V0KCkpIHsKKyAgICBpbmRlbnQob3V0KSA8PAorICAgICAgIm91dHB1dC53cml0ZVNldEVuZCgpIiA8PCBlbmRsOworICB9IGVsc2UgaWYgKHR0eXBlLT5pc19saXN0KCkpIHsKKyAgICBpbmRlbnQob3V0KSA8PAorICAgICAgIm91dHB1dC53cml0ZUxpc3RFbmQoKSIgPDwgZW5kbDsKKyAgfQorCisgIHNjb3BlX2Rvd24ob3V0KTsKK30KKworLyoqCisgKiBTZXJpYWxpemVzIHRoZSBtZW1iZXJzIG9mIGEgbWFwLgorICoKKyAqLwordm9pZCB0X2pzX2dlbmVyYXRvcjo6Z2VuZXJhdGVfc2VyaWFsaXplX21hcF9lbGVtZW50KG9mc3RyZWFtICZvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X21hcCogdG1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBraXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyB2aXRlcikgeworICB0X2ZpZWxkIGtmaWVsZCh0bWFwLT5nZXRfa2V5X3R5cGUoKSwga2l0ZXIpOworICBnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQob3V0LCAma2ZpZWxkKTsKKworICB0X2ZpZWxkIHZmaWVsZCh0bWFwLT5nZXRfdmFsX3R5cGUoKSwgdml0ZXIpOworICBnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQob3V0LCAmdmZpZWxkKTsKK30KKworLyoqCisgKiBTZXJpYWxpemVzIHRoZSBtZW1iZXJzIG9mIGEgc2V0LgorICovCit2b2lkIHRfanNfZ2VuZXJhdG9yOjpnZW5lcmF0ZV9zZXJpYWxpemVfc2V0X2VsZW1lbnQob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRfc2V0KiB0c2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGl0ZXIpIHsKKyAgdF9maWVsZCBlZmllbGQodHNldC0+Z2V0X2VsZW1fdHlwZSgpLCBpdGVyKTsKKyAgZ2VuZXJhdGVfc2VyaWFsaXplX2ZpZWxkKG91dCwgJmVmaWVsZCk7Cit9CisKKy8qKgorICogU2VyaWFsaXplcyB0aGUgbWVtYmVycyBvZiBhIGxpc3QuCisgKi8KK3ZvaWQgdF9qc19nZW5lcmF0b3I6OmdlbmVyYXRlX3NlcmlhbGl6ZV9saXN0X2VsZW1lbnQob2ZzdHJlYW0gJm91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0X2xpc3QqIHRsaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBpdGVyKSB7CisgIHRfZmllbGQgZWZpZWxkKHRsaXN0LT5nZXRfZWxlbV90eXBlKCksIGl0ZXIpOworICBnZW5lcmF0ZV9zZXJpYWxpemVfZmllbGQob3V0LCAmZWZpZWxkKTsKK30KKworLyoqCisgKiBEZWNsYXJlcyBhIGZpZWxkLCB3aGljaCBtYXkgaW5jbHVkZSBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkuCisgKgorICogQHBhcmFtIHR0eXBlIFRoZSB0eXBlCisgKi8KK3N0cmluZyB0X2pzX2dlbmVyYXRvcjo6ZGVjbGFyZV9maWVsZCh0X2ZpZWxkKiB0ZmllbGQsIGJvb2wgaW5pdCwgYm9vbCBvYmopIHsKKyAgc3RyaW5nIHJlc3VsdCA9ICJ0aGlzLiIgKyB0ZmllbGQtPmdldF9uYW1lKCk7CisKKyAgaWYoIW9iail7CisgICAgICByZXN1bHQgPSB0ZmllbGQtPmdldF9uYW1lKCk7CisgIH0KKworICBpZiAoaW5pdCkgeworICAgIHRfdHlwZSogdHlwZSA9IGdldF90cnVlX3R5cGUodGZpZWxkLT5nZXRfdHlwZSgpKTsKKyAgICBpZiAodHlwZS0+aXNfYmFzZV90eXBlKCkpIHsKKyAgICAgIHRfYmFzZV90eXBlOjp0X2Jhc2UgdGJhc2UgPSAoKHRfYmFzZV90eXBlKil0eXBlKS0+Z2V0X2Jhc2UoKTsKKyAgICAgIHN3aXRjaCAodGJhc2UpIHsKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfVk9JRDoKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX1NUUklORzoKKyAgICAgICAgcmVzdWx0ICs9ICIgPSAnJyI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9CT09MOgorICAgICAgICByZXN1bHQgKz0gIiA9IGZhbHNlIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0JZVEU6CisgICAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0kxNjoKKyAgICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfSTMyOgorICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JNjQ6CisgICAgICAgIHJlc3VsdCArPSAiID0gMCI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9ET1VCTEU6CisgICAgICAgIHJlc3VsdCArPSAiID0gMC4wIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB0aHJvdyAiY29tcGlsZXIgZXJyb3I6IG5vIEpTIGluaXRpYWxpemVyIGZvciBiYXNlIHR5cGUgIiArIHRfYmFzZV90eXBlOjp0X2Jhc2VfbmFtZSh0YmFzZSk7CisgICAgICB9CisgICAgfSBlbHNlIGlmICh0eXBlLT5pc19lbnVtKCkpIHsKKyAgICAgIHJlc3VsdCArPSAiID0gMCI7CisgICAgfSBlbHNlIGlmICh0eXBlLT5pc19tYXAoKSl7CisgICAgICByZXN1bHQgKz0gIiA9IHt9IjsKKyAgICB9IGVsc2UgaWYgKHR5cGUtPmlzX2NvbnRhaW5lcigpKSB7CisgICAgICByZXN1bHQgKz0gIiA9IFtdIjsKKyAgICB9IGVsc2UgaWYgKHR5cGUtPmlzX3N0cnVjdCgpIHx8IHR5cGUtPmlzX3hjZXB0aW9uKCkpIHsKKyAgICAgIGlmIChvYmopIHsKKyAgICAgICAgICByZXN1bHQgKz0gIiA9IG5ldyAiICtqc19uYW1lc3BhY2UodHlwZS0+Z2V0X3Byb2dyYW0oKSkgKyB0eXBlLT5nZXRfbmFtZSgpICsgIigpIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdCArPSAiID0gbnVsbCI7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogUmVuZGVycyBhIGZ1bmN0aW9uIHNpZ25hdHVyZSBvZiB0aGUgZm9ybSAndHlwZSBuYW1lKGFyZ3MpJworICoKKyAqIEBwYXJhbSB0ZnVuY3Rpb24gRnVuY3Rpb24gZGVmaW5pdGlvbgorICogQHJldHVybiBTdHJpbmcgb2YgcmVuZGVyZWQgZnVuY3Rpb24gZGVmaW5pdGlvbgorICovCitzdHJpbmcgdF9qc19nZW5lcmF0b3I6OmZ1bmN0aW9uX3NpZ25hdHVyZSh0X2Z1bmN0aW9uKiB0ZnVuY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBwcmVmaXgpIHsKKworICBzdHJpbmcgc3RyOworCisgIHN0ciAgPSBwcmVmaXggKyB0ZnVuY3Rpb24tPmdldF9uYW1lKCkgKyAiID0gZnVuY3Rpb24oIjsKKworCisgIC8vTmVlZCB0byBjcmVhdGUganMgZnVuY3Rpb24gYXJnIGlucHV0cworICBjb25zdCB2ZWN0b3I8dF9maWVsZCo+ICZmaWVsZHMgPSB0ZnVuY3Rpb24tPmdldF9hcmdsaXN0KCktPmdldF9tZW1iZXJzKCk7CisgIHZlY3Rvcjx0X2ZpZWxkKj46OmNvbnN0X2l0ZXJhdG9yIGZfaXRlcjsKKworICBmb3IgKGZfaXRlciA9IGZpZWxkcy5iZWdpbigpOyBmX2l0ZXIgIT0gZmllbGRzLmVuZCgpOyArK2ZfaXRlcikgeworCisgICAgICBpZihmX2l0ZXIgIT0gZmllbGRzLmJlZ2luKCkpCisgICAgICAgICAgc3RyICs9ICIsIjsKKworICAgICAgc3RyICs9ICgqZl9pdGVyKS0+Z2V0X25hbWUoKTsKKyAgfQorCisKKyAgc3RyICs9ICIpIjsKKyAgcmV0dXJuIHN0cjsKK30KKworLyoqCisgKiBSZW5kZXJzIGEgZmllbGQgbGlzdAorICovCitzdHJpbmcgdF9qc19nZW5lcmF0b3I6OmFyZ3VtZW50X2xpc3QodF9zdHJ1Y3QqIHRzdHJ1Y3QpIHsKKyAgc3RyaW5nIHJlc3VsdCA9ICIiOworCisgIGNvbnN0IHZlY3Rvcjx0X2ZpZWxkKj4mIGZpZWxkcyA9IHRzdHJ1Y3QtPmdldF9tZW1iZXJzKCk7CisgIHZlY3Rvcjx0X2ZpZWxkKj46OmNvbnN0X2l0ZXJhdG9yIGZfaXRlcjsKKyAgYm9vbCBmaXJzdCA9IHRydWU7CisgIGZvciAoZl9pdGVyID0gZmllbGRzLmJlZ2luKCk7IGZfaXRlciAhPSBmaWVsZHMuZW5kKCk7ICsrZl9pdGVyKSB7CisgICAgaWYgKGZpcnN0KSB7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQgKz0gIiwgIjsKKyAgICB9CisgICAgcmVzdWx0ICs9ICgqZl9pdGVyKS0+Z2V0X25hbWUoKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCisvKioKKyAqIENvbnZlcnRzIHRoZSBwYXJzZSB0eXBlIHRvIGEgQysrIGVudW0gc3RyaW5nIGZvciB0aGUgZ2l2ZW4gdHlwZS4KKyAqLworc3RyaW5nIHRfanNfZ2VuZXJhdG9yIDo6dHlwZV90b19lbnVtKHRfdHlwZSogdHlwZSkgeworICB0eXBlID0gZ2V0X3RydWVfdHlwZSh0eXBlKTsKKworICBpZiAodHlwZS0+aXNfYmFzZV90eXBlKCkpIHsKKyAgICB0X2Jhc2VfdHlwZTo6dF9iYXNlIHRiYXNlID0gKCh0X2Jhc2VfdHlwZSopdHlwZSktPmdldF9iYXNlKCk7CisgICAgc3dpdGNoICh0YmFzZSkgeworICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfVk9JRDoKKyAgICAgIHRocm93ICJOTyBUX1ZPSUQgQ09OU1RSVUNUIjsKKyAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiAiVGhyaWZ0LlR5cGUuU1RSSU5HIjsKKyAgICBjYXNlIHRfYmFzZV90eXBlOjpUWVBFX0JPT0w6CisgICAgICByZXR1cm4gIlRocmlmdC5UeXBlLkJPT0wiOworICAgIGNhc2UgdF9iYXNlX3R5cGU6OlRZUEVfQllURToKKyAgICAgIHJldHVybiAiVGhyaWZ0LlR5cGUuQllURSI7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JMTY6CisgICAgICByZXR1cm4gIlRocmlmdC5UeXBlLkkxNiI7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JMzI6CisgICAgICByZXR1cm4gIlRocmlmdC5UeXBlLkkzMiI7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9JNjQ6CisgICAgICByZXR1cm4gIlRocmlmdC5UeXBlLkk2NCI7CisgICAgY2FzZSB0X2Jhc2VfdHlwZTo6VFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gIlRocmlmdC5UeXBlLkRPVUJMRSI7CisgICAgfQorICB9IGVsc2UgaWYgKHR5cGUtPmlzX2VudW0oKSkgeworICAgIHJldHVybiAiVGhyaWZ0LlR5cGUuSTMyIjsKKyAgfSBlbHNlIGlmICh0eXBlLT5pc19zdHJ1Y3QoKSB8fCB0eXBlLT5pc194Y2VwdGlvbigpKSB7CisgICAgcmV0dXJuICJUaHJpZnQuVHlwZS5TVFJVQ1QiOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX21hcCgpKSB7CisgICAgcmV0dXJuICJUaHJpZnQuVHlwZS5NQVAiOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX3NldCgpKSB7CisgICAgcmV0dXJuICJUaHJpZnQuVHlwZS5TRVQiOworICB9IGVsc2UgaWYgKHR5cGUtPmlzX2xpc3QoKSkgeworICAgIHJldHVybiAiVGhyaWZ0LlR5cGUuTElTVCI7CisgIH0KKworICB0aHJvdyAiSU5WQUxJRCBUWVBFIElOIHR5cGVfdG9fZW51bTogIiArIHR5cGUtPmdldF9uYW1lKCk7Cit9CisKKworVEhSSUZUX1JFR0lTVEVSX0dFTkVSQVRPUihqcywgIkphdmFzY3JpcHQiLCAiIik7CmRpZmYgLS1naXQgYS9jb25maWd1cmUuYWMgYi9jb25maWd1cmUuYWMKaW5kZXggYTNiMGI0Yi4uNTE1ZTBiNCAxMDA2NDQKLS0tIGEvY29uZmlndXJlLmFjCisrKyBiL2NvbmZpZ3VyZS5hYwpAQCAtMjMxLDYgKzIzMSw4IEBACiBBTV9DT05ESVRJT05BTChbVEhSSUZUX0dFTl94c2RdLCBbdGVzdCAiJGF4X3RocmlmdF9nZW5feHNkIiA9ICJ5ZXMiXSkKIEFYX1RIUklGVF9HRU4oaHRtbCwgW0hUTUxdLCB5ZXMpCiBBTV9DT05ESVRJT05BTChbVEhSSUZUX0dFTl9odG1sXSwgW3Rlc3QgIiRheF90aHJpZnRfZ2VuX2h0bWwiID0gInllcyJdKQorQVhfVEhSSUZUX0dFTihqcywgW0phdmFTY3JpcHRdLCB5ZXMpCitBTV9DT05ESVRJT05BTChbVEhSSUZUX0dFTl9qc10sIFt0ZXN0ICIkYXhfdGhyaWZ0X2dlbl9qcyIgPSAieWVzIl0pCiAKIEFDX0NPTkZJR19IRUFERVJTKGNvbmZpZy5oOmNvbmZpZy5oaW4pCiAKZGlmZiAtLWdpdCBhL2xpYi9qcy9SRUFETUUgYi9saWIvanMvUkVBRE1FCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhZmRjNDMKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanMvUkVBRE1FCkBAIC0wLDAgKzEsNDAgQEAKK1RocmlmdCBKYXZhc2NyaXB0IExpYnJhcnkKKworTGljZW5zZQorPT09PT09PQorCitMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCitvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gU2VlIHRoZSBOT1RJQ0UgZmlsZQorZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KK3JlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQordG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQord2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKK1VubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKK3NvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKK0tJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCitzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCit1bmRlciB0aGUgTGljZW5zZS4KKworVXNpbmcgVGhyaWZ0IHdpdGggSmF2YXNjcmlwdAorPT09PT09PT09PT09PT09PT09PT09CisKK0FsbG93cyBqYXZhc2NyaXB0IGNsaWVudCBpbnRlcmZhY2VzIHRvIFRocmlmdCBzZXJ2aWNlcy4KK1RoaXMgaXMgZ2VhcmVkIGZvciB1c2UgaW4gYSB3ZWIgYnJvd3Nlci4KKworVGhpcyBjbGllbnQgY2FuIG9ubHkgc3BlYWsgdGhlIEpTT04gUHJvdG9jb2wgYW5kIHRoZSBvbmx5IHN1cHBvcnRlZAordHJhbnNwb3J0IGlzIEFKQVguCisKK1RoZXJlIGlzIGEgdGVzdCBodHRwZCBzZXJ2aWNlIGluIHRoZSB0ZXN0IGRpciB0aGF0IHJlcXVpcmVzCitodHRwOi8vaGMuYXBhY2hlLm9yZyB1bmRlciB0ZXN0IGRpcgorCitEZXBlbmRlbmNpZXMKKz09PT09PT09PT09PQorQSBKYXZhU2NyaXB0IGVuYWJsZWQgYnJvd3Nlci4gVGVzdGVkIHdpdGg6CisgKklFIDYsNyw4CisgKkZGIDIsMworICpTYWZhcmkgMyAmIDQKZGlmZiAtLWdpdCBhL2xpYi9qcy90ZXN0L1J1blRlc3RTZXJ2ZXIuc2ggYi9saWIvanMvdGVzdC9SdW5UZXN0U2VydmVyLnNoCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjU3NGY3YzUKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanMvdGVzdC9SdW5UZXN0U2VydmVyLnNoCkBAIC0wLDAgKzEsNDAgQEAKKyMhL2Jpbi9iYXNoIAorCisjCisjIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorIyBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorIyAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyMgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyMgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworIyB1bmRlciB0aGUgTGljZW5zZS4KKyMKKworTE9HNEo9Ii4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9zbGY0ai1hcGktMS41LjguamFyOi4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9sb2c0ai0xLjIuMTUuamFyOi4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9zbGY0ai1zaW1wbGUtMS41LjguamFyIgorSFRUUENPUkU9Ii4vaHR0cGNvcmUtNC4wLjEuamFyIgorCitpZiBbIC1mICR7SFRUUENPUkV9IF0KK3RoZW4KKyAgICBlY2hvICJjb21waWxpbmcgdGVzdC4uLiIKK2Vsc2UKKyAgICBlY2hvICJNaXNzaW5nIHJlcXVpcmVkIGZpbGUgJHtIVFRQQ09SRX0iCisgICAgZWNobyAiWW91IGNhbiBkb3dubG9hZCB0aGlzIGZyb20gaHR0cDovL2FyY2hpdmUuYXBhY2hlLm9yZy9kaXN0L2h0dHBjb21wb25lbnRzL2h0dHBjb3JlL2JpbmFyeS9odHRwY29tcG9uZW50cy1jb3JlLTQuMC4xLWJpbi50YXIuZ3oiCisgICAgZWNobyAiUGxhY2UgdGhlIGphciBpbiB0aGlzIGRpcmVjdG9yeSBhbmQgdHJ5IGFnYWluLiIKKyAgICBleGl0CitmaQorCisuLi8uLi8uLi9jb21waWxlci9jcHAvdGhyaWZ0IC0tZ2VuIGphdmEgLi4vLi4vLi4vdGVzdC9UaHJpZnRUZXN0LnRocmlmdAorLi4vLi4vLi4vY29tcGlsZXIvY3BwL3RocmlmdCAtLWdlbiBqcyAuLi8uLi8uLi90ZXN0L1RocmlmdFRlc3QudGhyaWZ0CisKK2phdmFjIC1jcCAke0xPRzRKfTouLi8uLi9qYXZhL2xpYnRocmlmdC5qYXIgZ2VuLWphdmEvdGhyaWZ0L3Rlc3QvKi5qYXZhCitqYXZhYyAtY3AgJHtMT0c0Sn06JHtIVFRQQ09SRX06Li4vLi4vamF2YS9saWJ0aHJpZnQuamFyOmdlbi1qYXZhLyBzcmMvdGVzdC8qLmphdmEgCitqYXZhIC1jcCAgJHtMT0c0Sn06JHtIVFRQQ09SRX06Li4vLi4vamF2YS9saWJ0aHJpZnQuamFyOmdlbi1qYXZhOnNyYyB0ZXN0Lkh0dHBkIC4uLwpkaWZmIC0tZ2l0IGEvbGliL2pzL3Rlc3Qvc3JjL3Rlc3QvSHR0cGQuamF2YSBiL2xpYi9qcy90ZXN0L3NyYy90ZXN0L0h0dHBkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU1YThiOAotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9qcy90ZXN0L3NyYy90ZXN0L0h0dHBkLmphdmEKQEAgLTAsMCArMSwyOTggQEAKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKgorICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKKyAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQorICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCisgKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCisgKgorICovCisKK3BhY2thZ2UgdGVzdDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlVSTERlY29kZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5Db25uZWN0aW9uQ2xvc2VkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5IdHRwRW50aXR5OworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5IdHRwRW50aXR5RW5jbG9zaW5nUmVxdWVzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFJlcXVlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkh0dHBSZXNwb25zZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFNlcnZlckNvbm5lY3Rpb247CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkh0dHBTdGF0dXM7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5LkNvbnRlbnRQcm9kdWNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5LkVudGl0eVRlbXBsYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5lbnRpdHkuRmlsZUVudGl0eTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuaW1wbC5EZWZhdWx0SHR0cFJlc3BvbnNlRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuaW1wbC5EZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb247CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLmltcGwuTm9Db25uZWN0aW9uUmV1c2VTdHJhdGVneTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkJhc2ljSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkNvcmVDb25uZWN0aW9uUE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wYXJhbXMuQ29yZVByb3RvY29sUE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wYXJhbXMuSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwUHJvY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFByb2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFJlcXVlc3RIYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwUmVxdWVzdEhhbmRsZXJSZWdpc3RyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFNlcnZpY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLnV0aWwuRW50aXR5VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuVFByb2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC5USlNPTlByb3RvY29sOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnByb3RvY29sLlRQcm90b2NvbDsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC50cmFuc3BvcnQuVE1lbW9yeUJ1ZmZlcjsKKworaW1wb3J0IHRocmlmdC50ZXN0LlRocmlmdFRlc3Q7CisKKy8qKgorICogQmFzaWMsIHlldCBmdWxseSBmdW5jdGlvbmFsIGFuZCBzcGVjIGNvbXBsaWFudCwgSFRUUC8xLjEgZmlsZSBzZXJ2ZXIuCisgKiA8cD4KKyAqIFBsZWFzZSBub3RlIHRoZSBwdXJwb3NlIG9mIHRoaXMgYXBwbGljYXRpb24gaXMgZGVtb25zdHJhdGUgdGhlIHVzYWdlIG9mCisgKiBIdHRwQ29yZSBBUElzLiBJdCBpcyBOT1QgaW50ZW5kZWQgdG8gZGVtb25zdHJhdGUgdGhlIG1vc3QgZWZmaWNpZW50IHdheSBvZgorICogYnVpbGRpbmcgYW4gSFRUUCBmaWxlIHNlcnZlci4KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBIdHRwZCB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgeworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJQbGVhc2Ugc3BlY2lmeSBkb2N1bWVudCByb290IGRpcmVjdG9yeSIpOworICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7CisgICAgICAgIH0KKyAgICAgICAgVGhyZWFkIHQgPSBuZXcgUmVxdWVzdExpc3RlbmVyVGhyZWFkKDgwODgsIGFyZ3NbMF0pOworICAgICAgICB0LnNldERhZW1vbihmYWxzZSk7CisgICAgICAgIHQuc3RhcnQoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgSHR0cEZpbGVIYW5kbGVyIGltcGxlbWVudHMgSHR0cFJlcXVlc3RIYW5kbGVyIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBkb2NSb290OworCisgICAgICAgIHB1YmxpYyBIdHRwRmlsZUhhbmRsZXIoZmluYWwgU3RyaW5nIGRvY1Jvb3QpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICB0aGlzLmRvY1Jvb3QgPSBkb2NSb290OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaGFuZGxlKGZpbmFsIEh0dHBSZXF1ZXN0IHJlcXVlc3QsIGZpbmFsIEh0dHBSZXNwb25zZSByZXNwb25zZSwgZmluYWwgSHR0cENvbnRleHQgY29udGV4dCkgdGhyb3dzIEh0dHBFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKworICAgICAgICAgICAgU3RyaW5nIG1ldGhvZCA9IHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKS5nZXRNZXRob2QoKS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgICAgICBpZiAoIW1ldGhvZC5lcXVhbHMoIkdFVCIpICYmICFtZXRob2QuZXF1YWxzKCJIRUFEIikgJiYgIW1ldGhvZC5lcXVhbHMoIlBPU1QiKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24obWV0aG9kICsgIiBtZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKS5nZXRVcmkoKTsKKworICAgICAgICAgICAgaWYgKHJlcXVlc3QgaW5zdGFuY2VvZiBIdHRwRW50aXR5RW5jbG9zaW5nUmVxdWVzdCAmJiB0YXJnZXQuZXF1YWxzKCIvc2VydmljZSIpKSB7CisgICAgICAgICAgICAgICAgSHR0cEVudGl0eSBlbnRpdHkgPSAoKEh0dHBFbnRpdHlFbmNsb3NpbmdSZXF1ZXN0KSByZXF1ZXN0KS5nZXRFbnRpdHkoKTsKKyAgICAgICAgICAgICAgICBieXRlW10gZW50aXR5Q29udGVudCA9IEVudGl0eVV0aWxzLnRvQnl0ZUFycmF5KGVudGl0eSk7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbmNvbWluZyBjb250ZW50OiAiICsgbmV3IFN0cmluZyhlbnRpdHlDb250ZW50KSk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG91dHB1dCA9IHRoaXMudGhyaWZ0UmVxdWVzdChlbnRpdHlDb250ZW50KTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk91dGdvaW5nIGNvbnRlbnQ6ICIrb3V0cHV0KTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBFbnRpdHlUZW1wbGF0ZSBib2R5ID0gbmV3IEVudGl0eVRlbXBsYXRlKG5ldyBDb250ZW50UHJvZHVjZXIoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBPdXRwdXRTdHJlYW0gb3V0c3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0c3RyZWFtLCAiVVRGLTgiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShvdXRwdXQpOworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgIGJvZHkuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOworICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEVudGl0eShib2R5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBuZXcgRmlsZSh0aGlzLmRvY1Jvb3QsIFVSTERlY29kZXIuZGVjb2RlKHRhcmdldCkpOworICAgICAgICAgICAgICAgIGlmICghZmlsZS5leGlzdHMoKSkgeworCisgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldFN0YXR1c0NvZGUoSHR0cFN0YXR1cy5TQ19OT1RfRk9VTkQpOworICAgICAgICAgICAgICAgICAgICBFbnRpdHlUZW1wbGF0ZSBib2R5ID0gbmV3IEVudGl0eVRlbXBsYXRlKG5ldyBDb250ZW50UHJvZHVjZXIoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgT3V0cHV0U3RyZWFtIG91dHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXRzdHJlYW0sICJVVEYtOCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPGh0bWw+PGJvZHk+PGgxPiIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiRmlsZSAiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUoZmlsZS5nZXRQYXRoKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiIG5vdCBmb3VuZCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPC9oMT48L2JvZHk+PC9odG1sPiIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICBib2R5LnNldENvbnRlbnRUeXBlKCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgiKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0RW50aXR5KGJvZHkpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkZpbGUgIiArIGZpbGUuZ2V0UGF0aCgpICsgIiBub3QgZm91bmQiKTsKKworICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZpbGUuY2FuUmVhZCgpIHx8IGZpbGUuaXNEaXJlY3RvcnkoKSkgeworCisgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldFN0YXR1c0NvZGUoSHR0cFN0YXR1cy5TQ19GT1JCSURERU4pOworICAgICAgICAgICAgICAgICAgICBFbnRpdHlUZW1wbGF0ZSBib2R5ID0gbmV3IEVudGl0eVRlbXBsYXRlKG5ldyBDb250ZW50UHJvZHVjZXIoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgT3V0cHV0U3RyZWFtIG91dHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXRzdHJlYW0sICJVVEYtOCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPGh0bWw+PGJvZHk+PGgxPiIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiQWNjZXNzIGRlbmllZCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPC9oMT48L2JvZHk+PC9odG1sPiIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5mbHVzaCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICBib2R5LnNldENvbnRlbnRUeXBlKCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgiKTsKKyAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0RW50aXR5KGJvZHkpOworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkNhbm5vdCByZWFkIGZpbGUgIiArIGZpbGUuZ2V0UGF0aCgpKTsKKworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisKKyAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0U3RhdHVzQ29kZShIdHRwU3RhdHVzLlNDX09LKTsKKyAgICAgICAgICAgICAgICAgICAgRmlsZUVudGl0eSBib2R5ID0gbmV3IEZpbGVFbnRpdHkoZmlsZSwgInRleHQvaHRtbCIpOworICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5zZXRFbnRpdHkoYm9keSk7CisgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU2VydmluZyBmaWxlICIgKyBmaWxlLmdldFBhdGgoKSk7CisKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIHByaXZhdGUgU3RyaW5nIHRocmlmdFJlcXVlc3QoYnl0ZVtdIGlucHV0KXsKKyAgICAgICAgICAgIHRyeXsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIC8vSW5wdXQKKyAgICAgICAgICAgICAgICBUTWVtb3J5QnVmZmVyIGluYnVmZmVyID0gbmV3IFRNZW1vcnlCdWZmZXIoaW5wdXQubGVuZ3RoKTsgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGluYnVmZmVyLndyaXRlKGlucHV0KTsgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIFRQcm90b2NvbCAgaW5wcm90b2NvbCAgID0gbmV3IFRKU09OUHJvdG9jb2woaW5idWZmZXIpOyAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAvL091dHB1dAorICAgICAgICAgICAgICAgIFRNZW1vcnlCdWZmZXIgb3V0YnVmZmVyID0gbmV3IFRNZW1vcnlCdWZmZXIoMTAwKTsgICAgICAgICAgIAorICAgICAgICAgICAgICAgIFRQcm90b2NvbCBvdXRwcm90b2NvbCAgID0gbmV3IFRKU09OUHJvdG9jb2wob3V0YnVmZmVyKTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBUUHJvY2Vzc29yIHByb2Nlc3NvciA9IG5ldyBUaHJpZnRUZXN0LlByb2Nlc3NvcihuZXcgVGVzdEhhbmRsZXIoKSk7ICAgICAgCisgICAgICAgICAgICAgICAgcHJvY2Vzc29yLnByb2Nlc3MoaW5wcm90b2NvbCwgb3V0cHJvdG9jb2wpOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGJ5dGVbXSBvdXRwdXQgPSBuZXcgYnl0ZVtvdXRidWZmZXIubGVuZ3RoKCldOworICAgICAgICAgICAgICAgIG91dGJ1ZmZlci5yZWFkQWxsKG91dHB1dCwgMCwgb3V0cHV0Lmxlbmd0aCk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhvdXRwdXQsIlVURi04Iik7CisgICAgICAgICAgICB9Y2F0Y2goVGhyb3dhYmxlIHQpeworICAgICAgICAgICAgICAgIHJldHVybiAiRXJyb3I6Iit0LmdldE1lc3NhZ2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICB9CisgICAgICAgIAorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBSZXF1ZXN0TGlzdGVuZXJUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgU2VydmVyU29ja2V0IHNlcnZlcnNvY2tldDsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBIdHRwUGFyYW1zIHBhcmFtczsKKyAgICAgICAgcHJpdmF0ZSBmaW5hbCBIdHRwU2VydmljZSBodHRwU2VydmljZTsKKworICAgICAgICBwdWJsaWMgUmVxdWVzdExpc3RlbmVyVGhyZWFkKGludCBwb3J0LCBmaW5hbCBTdHJpbmcgZG9jcm9vdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHRoaXMuc2VydmVyc29ja2V0ID0gbmV3IFNlcnZlclNvY2tldChwb3J0KTsKKyAgICAgICAgICAgIHRoaXMucGFyYW1zID0gbmV3IEJhc2ljSHR0cFBhcmFtcygpOworICAgICAgICAgICAgdGhpcy5wYXJhbXMuc2V0SW50UGFyYW1ldGVyKENvcmVDb25uZWN0aW9uUE5hbWVzLlNPX1RJTUVPVVQsIDEwMDApLnNldEludFBhcmFtZXRlcihDb3JlQ29ubmVjdGlvblBOYW1lcy5TT0NLRVRfQlVGRkVSX1NJWkUsIDggKiAxMDI0KQorICAgICAgICAgICAgICAgICAgICAuc2V0Qm9vbGVhblBhcmFtZXRlcihDb3JlQ29ubmVjdGlvblBOYW1lcy5TVEFMRV9DT05ORUNUSU9OX0NIRUNLLCBmYWxzZSkuc2V0Qm9vbGVhblBhcmFtZXRlcihDb3JlQ29ubmVjdGlvblBOYW1lcy5UQ1BfTk9ERUxBWSwgdHJ1ZSkKKyAgICAgICAgICAgICAgICAgICAgLnNldFBhcmFtZXRlcihDb3JlUHJvdG9jb2xQTmFtZXMuT1JJR0lOX1NFUlZFUiwgIkh0dHBDb21wb25lbnRzLzEuMSIpOworCisgICAgICAgICAgICAvLyBTZXQgdXAgdGhlIEhUVFAgcHJvdG9jb2wgcHJvY2Vzc29yCisgICAgICAgICAgICBIdHRwUHJvY2Vzc29yIGh0dHBwcm9jID0gbmV3IEJhc2ljSHR0cFByb2Nlc3NvcigpOworCisgICAgICAgICAgICAvLyBTZXQgdXAgcmVxdWVzdCBoYW5kbGVycworICAgICAgICAgICAgSHR0cFJlcXVlc3RIYW5kbGVyUmVnaXN0cnkgcmVxaXN0cnkgPSBuZXcgSHR0cFJlcXVlc3RIYW5kbGVyUmVnaXN0cnkoKTsKKyAgICAgICAgICAgIHJlcWlzdHJ5LnJlZ2lzdGVyKCIqIiwgbmV3IEh0dHBGaWxlSGFuZGxlcihkb2Nyb290KSk7CisKKyAgICAgICAgICAgIC8vIFNldCB1cCB0aGUgSFRUUCBzZXJ2aWNlCisgICAgICAgICAgICB0aGlzLmh0dHBTZXJ2aWNlID0gbmV3IEh0dHBTZXJ2aWNlKGh0dHBwcm9jLCBuZXcgTm9Db25uZWN0aW9uUmV1c2VTdHJhdGVneSgpLCBuZXcgRGVmYXVsdEh0dHBSZXNwb25zZUZhY3RvcnkoKSk7CisgICAgICAgICAgICB0aGlzLmh0dHBTZXJ2aWNlLnNldFBhcmFtcyh0aGlzLnBhcmFtcyk7CisgICAgICAgICAgICB0aGlzLmh0dHBTZXJ2aWNlLnNldEhhbmRsZXJSZXNvbHZlcihyZXFpc3RyeSk7CisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkxpc3RlbmluZyBvbiBwb3J0ICIgKyB0aGlzLnNlcnZlcnNvY2tldC5nZXRMb2NhbFBvcnQoKSk7CisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlBvaW50IHlvdXIgYnJvd3NlciB0byBodHRwOi8vbG9jYWxob3N0OjgwODgvdGVzdC90ZXN0Lmh0bWwiKTsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgd2hpbGUgKCFUaHJlYWQuaW50ZXJydXB0ZWQoKSkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIC8vIFNldCB1cCBIVFRQIGNvbm5lY3Rpb24KKyAgICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2tldCA9IHRoaXMuc2VydmVyc29ja2V0LmFjY2VwdCgpOworICAgICAgICAgICAgICAgICAgICBEZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb24gY29ubiA9IG5ldyBEZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbmNvbWluZyBjb25uZWN0aW9uIGZyb20gIiArIHNvY2tldC5nZXRJbmV0QWRkcmVzcygpKTsKKyAgICAgICAgICAgICAgICAgICAgY29ubi5iaW5kKHNvY2tldCwgdGhpcy5wYXJhbXMpOworCisgICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IHdvcmtlciB0aHJlYWQKKyAgICAgICAgICAgICAgICAgICAgVGhyZWFkIHQgPSBuZXcgV29ya2VyVGhyZWFkKHRoaXMuaHR0cFNlcnZpY2UsIGNvbm4pOworICAgICAgICAgICAgICAgICAgICB0LnNldERhZW1vbih0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgdC5zdGFydCgpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkkvTyBlcnJvciBpbml0aWFsaXNpbmcgY29ubmVjdGlvbiB0aHJlYWQ6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHN0YXRpYyBjbGFzcyBXb3JrZXJUaHJlYWQgZXh0ZW5kcyBUaHJlYWQgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgSHR0cFNlcnZpY2UgaHR0cHNlcnZpY2U7CisgICAgICAgIHByaXZhdGUgZmluYWwgSHR0cFNlcnZlckNvbm5lY3Rpb24gY29ubjsKKworICAgICAgICBwdWJsaWMgV29ya2VyVGhyZWFkKGZpbmFsIEh0dHBTZXJ2aWNlIGh0dHBzZXJ2aWNlLCBmaW5hbCBIdHRwU2VydmVyQ29ubmVjdGlvbiBjb25uKSB7CisgICAgICAgICAgICBzdXBlcigpOworICAgICAgICAgICAgdGhpcy5odHRwc2VydmljZSA9IGh0dHBzZXJ2aWNlOworICAgICAgICAgICAgdGhpcy5jb25uID0gY29ubjsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTmV3IGNvbm5lY3Rpb24gdGhyZWFkIik7CisgICAgICAgICAgICBIdHRwQ29udGV4dCBjb250ZXh0ID0gbmV3IEJhc2ljSHR0cENvbnRleHQobnVsbCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHdoaWxlICghVGhyZWFkLmludGVycnVwdGVkKCkgJiYgdGhpcy5jb25uLmlzT3BlbigpKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaHR0cHNlcnZpY2UuaGFuZGxlUmVxdWVzdCh0aGlzLmNvbm4sIGNvbnRleHQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gY2F0Y2ggKENvbm5lY3Rpb25DbG9zZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNsaWVudCBjbG9zZWQgY29ubmVjdGlvbiIpOworICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkkvTyBlcnJvcjogIiArIGV4LmdldE1lc3NhZ2UoKSk7CisgICAgICAgICAgICB9IGNhdGNoIChIdHRwRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJVbnJlY292ZXJhYmxlIEhUVFAgcHJvdG9jb2wgdmlvbGF0aW9uOiAiICsgZXguZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uLnNodXRkb3duKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlKSB7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2xpYi9qcy90ZXN0L3NyYy90ZXN0L1Rlc3RIYW5kbGVyLmphdmEgYi9saWIvanMvdGVzdC9zcmMvdGVzdC9UZXN0SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlYWY2YzYKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanMvdGVzdC9zcmMvdGVzdC9UZXN0SGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMTIzIEBACitwYWNrYWdlIHRlc3Q7CisKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5URXhjZXB0aW9uOworCitpbXBvcnQgdGhyaWZ0LnRlc3QuSW5zYW5pdHk7CitpbXBvcnQgdGhyaWZ0LnRlc3QuVGhyaWZ0VGVzdDsKK2ltcG9ydCB0aHJpZnQudGVzdC5YY2VwdGlvbjsKK2ltcG9ydCB0aHJpZnQudGVzdC5YY2VwdGlvbjI7CitpbXBvcnQgdGhyaWZ0LnRlc3QuWHRydWN0OworaW1wb3J0IHRocmlmdC50ZXN0Llh0cnVjdDI7CitpbXBvcnQgdGhyaWZ0LnRlc3QuTnVtYmVyejsKKworcHVibGljIGNsYXNzIFRlc3RIYW5kbGVyIGltcGxlbWVudHMgVGhyaWZ0VGVzdC5JZmFjZSB7CisKKyAgICBwdWJsaWMgYnl0ZSB0ZXN0Qnl0ZShieXRlIHRoaW5nKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB0aGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgZG91YmxlIHRlc3REb3VibGUoZG91YmxlIHRoaW5nKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB0aGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgTnVtYmVyeiB0ZXN0RW51bShOdW1iZXJ6IHRoaW5nKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB0aGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXhjZXB0aW9uKFN0cmluZyBhcmcpIHRocm93cyBYY2VwdGlvbiwgVEV4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBYY2VwdGlvbigxLCJzZXJ2ZXIgdGVzdCBleGNlcHRpb24iKTsgICAgICAgCisgICAgfQorCisgICAgcHVibGljIGludCB0ZXN0STMyKGludCB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgdGVzdEk2NChsb25nIHRoaW5nKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIHJldHVybiB0aGluZzsKKyAgICB9CisKKyAgICBwdWJsaWMgTWFwPExvbmcsIE1hcDxOdW1iZXJ6LCBJbnNhbml0eT4+IHRlc3RJbnNhbml0eShJbnNhbml0eSBhcmd1bWVudCkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICBNYXA8TG9uZywgTWFwPE51bWJlcnosIEluc2FuaXR5Pj4gcmVzdWx0ID0gbmV3IEhhc2hNYXA8TG9uZywgTWFwPE51bWJlcnosSW5zYW5pdHk+PigpOworICAgICAgICAKKyAgICAgICAgcmVzdWx0LnB1dChMb25nLnZhbHVlT2YoMSksIG5ldyBIYXNoTWFwPE51bWJlcnosSW5zYW5pdHk+KCkpOworICAgICAgICByZXN1bHQuZ2V0KExvbmcudmFsdWVPZigxKSkucHV0KE51bWJlcnouT05FLCBhcmd1bWVudCk7CisgICAgICAgIAorICAgICAgICByZXN1bHQucHV0KExvbmcudmFsdWVPZigyKSwgbmV3IEhhc2hNYXA8TnVtYmVyeixJbnNhbml0eT4oKSk7CisgICAgICAgIHJlc3VsdC5nZXQoTG9uZy52YWx1ZU9mKDIpKS5wdXQoTnVtYmVyei5PTkUsIGFyZ3VtZW50KTsKKyAgICAgICAgCisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgcHVibGljIExpc3Q8SW50ZWdlcj4gdGVzdExpc3QoTGlzdDxJbnRlZ2VyPiB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiB0ZXN0TWFwKE1hcDxJbnRlZ2VyLCBJbnRlZ2VyPiB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIE1hcDxJbnRlZ2VyLCBNYXA8SW50ZWdlciwgSW50ZWdlcj4+IHRlc3RNYXBNYXAoaW50IGhlbGxvKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIE1hcDxJbnRlZ2VyLCBNYXA8SW50ZWdlcixJbnRlZ2VyPj4gcmVzdWx0ID0gbmV3IEhhc2hNYXA8SW50ZWdlciwgTWFwPEludGVnZXIsSW50ZWdlcj4+KCk7CisgICAgICAgIAorICAgICAgICByZXN1bHQucHV0KEludGVnZXIudmFsdWVPZigxKSwgbmV3IEhhc2hNYXA8SW50ZWdlcixJbnRlZ2VyPigpKTsKKyAgICAgICAgcmVzdWx0LmdldChJbnRlZ2VyLnZhbHVlT2YoMSkpLnB1dChJbnRlZ2VyLnZhbHVlT2YoMSksIEludGVnZXIudmFsdWVPZigxKSk7CisgICAgICAgIHJlc3VsdC5nZXQoSW50ZWdlci52YWx1ZU9mKDEpKS5wdXQoSW50ZWdlci52YWx1ZU9mKDIpLCBJbnRlZ2VyLnZhbHVlT2YoMikpOworICAgICAgICByZXN1bHQuZ2V0KEludGVnZXIudmFsdWVPZigyKSkucHV0KEludGVnZXIudmFsdWVPZigxKSwgSW50ZWdlci52YWx1ZU9mKDEpKTsKKyAgICAKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICBwdWJsaWMgWHRydWN0IHRlc3RNdWx0aShieXRlIGFyZzAsIGludCBhcmcxLCBsb25nIGFyZzIsIE1hcDxTaG9ydCwgU3RyaW5nPiBhcmczLCBOdW1iZXJ6IGFyZzQsIGxvbmcgYXJnNSkgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICBYdHJ1Y3QgeHRyID0gbmV3IFh0cnVjdCgpOworICAgICAgICAKKyAgICAgICAgeHRyLmJ5dGVfdGhpbmcgPSBhcmcwOworICAgICAgICB4dHIuaTMyX3RoaW5nICA9IGFyZzE7CisgICAgICAgIHh0ci5pNjRfdGhpbmcgID0gYXJnMjsKKyAgICAgICAgeHRyLnN0cmluZ190aGluZyA9ICJzZXJ2ZXIgc3RyaW5nIjsKKyAgICAgICAgCisgICAgICAgIHJldHVybiB4dHI7CisgICAgfQorCisgICAgcHVibGljIFh0cnVjdCB0ZXN0TXVsdGlFeGNlcHRpb24oU3RyaW5nIGFyZzAsIFN0cmluZyBhcmcxKSB0aHJvd3MgWGNlcHRpb24sIFhjZXB0aW9uMiwgVEV4Y2VwdGlvbiB7CisgICAgICAgIFh0cnVjdCB4dHIgPSBuZXcgWHRydWN0KCk7CisgICAgICAgIHh0ci5zZXRTdHJpbmdfdGhpbmcoYXJnMCk7CisgICAgICAgIHRocm93IG5ldyBYY2VwdGlvbjIoMSx4dHIpOworICAgIH0KKworICAgIHB1YmxpYyBYdHJ1Y3QyIHRlc3ROZXN0KFh0cnVjdDIgdGhpbmcpIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdE9uZXdheShpbnQgc2Vjb25kc1RvU2xlZXApIHRocm93cyBURXhjZXB0aW9uIHsKKyAgICAgICAgdHJ5eworICAgICAgICAgICAgVGhyZWFkLnNsZWVwKHNlY29uZHNUb1NsZWVwICogMTAwMCk7CisgICAgICAgIH1jYXRjaChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKXsKKyAgICAgICAgICAgIAorICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIFNldDxJbnRlZ2VyPiB0ZXN0U2V0KFNldDxJbnRlZ2VyPiB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyB0ZXN0U3RyaW5nKFN0cmluZyB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIFh0cnVjdCB0ZXN0U3RydWN0KFh0cnVjdCB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIGxvbmcgdGVzdFR5cGVkZWYobG9uZyB0aGluZykgdGhyb3dzIFRFeGNlcHRpb24geworICAgICAgICByZXR1cm4gdGhpbmc7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgdGVzdFZvaWQoKSB0aHJvd3MgVEV4Y2VwdGlvbiB7CisgICAgICAgIAorICAgIH0KK30KZGlmZiAtLWdpdCBhL2xpYi9qcy90ZXN0L3Rlc3QuaHRtbCBiL2xpYi9qcy90ZXN0L3Rlc3QuaHRtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDNlYTQwCi0tLSAvZGV2L251bGwKKysrIGIvbGliL2pzL3Rlc3QvdGVzdC5odG1sCkBAIC0wLDAgKzEsMTE1IEBACis8aHRtbD4KKzxoZWFkPgorICA8dGl0bGU+VGhyaWZ0IEphdmFzY3JpcHQgQmluZGluZ3MgLSBFeGFtcGxlPC90aXRsZT4KKworICA8c2NyaXB0IHNyYz0iL3RocmlmdC5qcyIgICAgICAgICAgICAgICAgIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+CisgIDxzY3JpcHQgc3JjPSJnZW4tanMvVGhyaWZ0VGVzdF90eXBlcy5qcyIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48L3NjcmlwdD4KKyAgPHNjcmlwdCBzcmM9Imdlbi1qcy9UaHJpZnRUZXN0LmpzIiAgICAgICB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwvc2NyaXB0PgorCisgIDwhLS0gZm9yIGFzeW5jIGV4YW1wbGUgLS0+CisgIDxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9hamF4Lmdvb2dsZWFwaXMuY29tL2FqYXgvbGlicy9qcXVlcnkvMS4zLjIvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CisKKzwvaGVhZD4KKzxib2R5IGlkPSJib2R5Ij4KKworPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCI+CisKKyAgLy9jcmVhdGUgY2xpZW50CisgIHZhciB0cmFuc3BvcnQgPSBuZXcgVGhyaWZ0LlRyYW5zcG9ydCgiL3NlcnZpY2UiKQorICB2YXIgcHJvdG9jb2wgID0gbmV3IFRocmlmdC5Qcm90b2NvbCh0cmFuc3BvcnQpCisgIHZhciBjbGllbnQgICAgPSBuZXcgVGhyaWZ0VGVzdC5UaHJpZnRUZXN0Q2xpZW50KHByb3RvY29sKQorCisgIC8vY3JlYXRlIGluc2FuaXR5IG9iagorICB2YXIgaW5zYW5pdHkgID0gbmV3IFRocmlmdFRlc3QuSW5zYW5pdHkoKQorICBpbnNhbml0eS51c2VyTWFwW1RocmlmdFRlc3QuTnVtYmVyei5PTkVdID0gMQorICBpbnNhbml0eS51c2VyTWFwW1RocmlmdFRlc3QuTnVtYmVyei5UV09dID0gMgorCisgIHZhciB4dHIgPSBuZXcgVGhyaWZ0VGVzdC5YdHJ1Y3QoKQorICB4dHIuc3RyaW5nX3RoaW5nID0gJ3dvcmtlZCcKKyAgaW5zYW5pdHkueHRydWN0cy5wdXNoKHh0cikKKworICB2YXIgeHRyMj0gbmV3IFRocmlmdFRlc3QuWHRydWN0MigpCisgIHh0cjIuc3RydWN0X3RoaW5nID0geHRyCisKKyAgdmFyIGxpc3QgPSBbMSwyLDNdCisKKyAgLy9ydW4gdGVzdHMgc3luY2hyb25vdXNseQorCisgIGRvY3VtZW50LndyaXRlKCI8aDI+PHU+VGhyaWZ0IEphdmFzY3JpcHQgQmluZGluZ3M8L3U+PC9oMj4iKQorICBkb2N1bWVudC53cml0ZSgiPGgyPlN5bmNocm9ub3VzIEV4YW1wbGU8L2gyPiIpCisgIGRvY3VtZW50LndyaXRlKCJjbGllbnQudGVzdFN0cmluZygpID0+ICIrKGNsaWVudC50ZXN0U3RyaW5nKCJ3b3JrcyIpICAgICA9PSAid29ya3MiKSsiPGJyLz4iKQorICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3RTdHJpbmcodXRmLTgpID0+ICIrKGNsaWVudC50ZXN0U3RyaW5nKCJhh46Sl5xlIikgICA9PSAiYYeOkpecZSIpKyI8YnIvPiIpCisgIGRvY3VtZW50LndyaXRlKCJjbGllbnQudGVzdERvdWJsZSgpID0+ICIrKGNsaWVudC50ZXN0RG91YmxlKDMuMTQpICAgICAgICA9PSAzLjE0KSsiPGJyLz4iKQorICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3RCeXRlKCkgICA9PiAiKyhjbGllbnQudGVzdEJ5dGUoMHgwMSkgICAgICAgICAgPT0gMHgwMSkrIjxici8+IikKKyAgZG9jdW1lbnQud3JpdGUoImNsaWVudC50ZXN0STMyKCkgICAgPT4gIisoY2xpZW50LnRlc3RJMzIoTWF0aC5wb3coMiwzMCkpID09IE1hdGgucG93KDIsMzApKSsiPGJyLz4iKQorICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3RJNjQoKSAgICA9PiAiKyhjbGllbnQudGVzdEk2NChNYXRoLnBvdygyLDYwKSkgPT0gTWF0aC5wb3coMiw2MCkpKyI8YnIvPiIpCisgIGRvY3VtZW50LndyaXRlKCJjbGllbnQudGVzdFN0cnVjdCgpID0+ICIrKGNsaWVudC50ZXN0U3RydWN0KHh0cikuc3RyaW5nX3RoaW5nID09ICJ3b3JrZWQiKSsiPGJyLz4iKQorICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3ROZXN0KCkgICA9PiAiKyhjbGllbnQudGVzdE5lc3QoeHRyMikuc3RydWN0X3RoaW5nLnN0cmluZ190aGluZyA9PSAid29ya2VkIikrIjxici8+IikKKyAgZG9jdW1lbnQud3JpdGUoImNsaWVudC50ZXN0TWFwKCkgICAgPT4gIisoY2xpZW50LnRlc3RNYXAoaW5zYW5pdHkudXNlck1hcClbVGhyaWZ0VGVzdC5OdW1iZXJ6Lk9ORV0gPT0gMSkrIjxici8+IikKKyAgZG9jdW1lbnQud3JpdGUoImNsaWVudC50ZXN0TGlzdCgpICAgPT4gIisoY2xpZW50LnRlc3RMaXN0KGxpc3QpLmxlbmd0aCA9PSAzKSsiPGJyLz4iKQorICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3RTZXQoKSAgICA9PiAiKyhjbGllbnQudGVzdFNldChsaXN0KS5sZW5ndGggPT0gMykrIjxici8+IikKKyAgZG9jdW1lbnQud3JpdGUoImNsaWVudC50ZXN0RW51bSgpICAgPT4gIisoY2xpZW50LnRlc3RFbnVtKFRocmlmdFRlc3QuTnVtYmVyei5PTkUpID09IFRocmlmdFRlc3QuTnVtYmVyei5PTkUpKyI8YnIvPiIpCisKKyAgZG9jdW1lbnQud3JpdGUoImNsaWVudC50ZXN0RXhjZXB0aW9uKCkgPT4gIikKKyAgdHJ5eworICAgIGNsaWVudC50ZXN0RXhjZXB0aW9uKCJnbyIpCisgICAgZG9jdW1lbnQud3JpdGUoImZhbHNlPGJyLz4iKQorICB9Y2F0Y2goZSl7CisgICAgZG9jdW1lbnQud3JpdGUoInRydWU8YnIvPiIpCisgIH0KKworICBkb2N1bWVudC53cml0ZSgiY2xpZW50LnRlc3RJbnNhbml0eSgpID0+ICIpCisgIHZhciByZXMgPSBjbGllbnQudGVzdEluc2FuaXR5KGluc2FuaXR5KQorCisgIGRvY3VtZW50LndyaXRlKChyZXNbIjEiXVsiMSJdLnh0cnVjdHNbMF0uc3RyaW5nX3RoaW5nID09ICJ3b3JrZWQiKSsiPGJyLz4iKQorCisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgLy9SdW4gc2FtZSB0ZXN0cyBhc3luY2hyb25vdXNseQorCisgIHZhciB0cmFuc3BvcnQgPSBuZXcgVGhyaWZ0LlRyYW5zcG9ydCgpCisgIHZhciBwcm90b2NvbCAgPSBuZXcgVGhyaWZ0LlByb3RvY29sKHRyYW5zcG9ydCkKKyAgdmFyIGNsaWVudCAgICA9IG5ldyBUaHJpZnRUZXN0LlRocmlmdFRlc3RDbGllbnQocHJvdG9jb2wpCisKKyAgZG9jdW1lbnQud3JpdGUoIjxoMj5Bc3luY2hyb25vdXMgRXhhbXBsZTwvaDI+IikKKyAgalF1ZXJ5LmFqYXgoeworICAgICB1cmw6ICIvc2VydmljZSIsCisgICAgIGRhdGE6IGNsaWVudC5zZW5kX3Rlc3RJMzIoTWF0aC5wb3coMiwzMCkpLAorICAgICB0eXBlOiAiUE9TVCIsCisgICAgIGNhY2hlOiBmYWxzZSwKKyAgICAgc3VjY2VzczogZnVuY3Rpb24ocmVzKXsKKyAgICAgICAgICAgIHZhciBfdHJhbnNwb3J0ID0gbmV3IFRocmlmdC5UcmFuc3BvcnQoKQorICAgICAgICAgICAgdmFyIF9wcm90b2NvbCAgPSBuZXcgVGhyaWZ0LlByb3RvY29sKF90cmFuc3BvcnQpCisgICAgICAgICAgICB2YXIgX2NsaWVudCAgICA9IG5ldyBUaHJpZnRUZXN0LlRocmlmdFRlc3RDbGllbnQoX3Byb3RvY29sKQorCisgICAgICAgICAgICBfdHJhbnNwb3J0LnNldFJlY3ZCdWZmZXIoIHJlcyApCisKKyAgICAgICAgICAgIHZhciB2ID0gIF9jbGllbnQucmVjdl90ZXN0STMyKCkKKyAgICAgICAgICAgICQoIiNib2R5IikuYXBwZW5kKCJjbGllbnQudGVzdEkzMigpICAgID0+ICIrKHYgPT0gTWF0aC5wb3coMiwzMCkpKyI8YnIvPiIpCisKKyAgICAgfQorICB9KQorCisgIGpRdWVyeS5hamF4KHsKKyAgICAgdXJsOiAiL3NlcnZpY2UiLAorICAgICBkYXRhOiBjbGllbnQuc2VuZF90ZXN0STY0KE1hdGgucG93KDIsNjApKSwKKyAgICAgdHlwZTogIlBPU1QiLAorICAgICBjYWNoZTogZmFsc2UsCisgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlcyl7CisgICAgICAgICAgICB2YXIgX3RyYW5zcG9ydCA9IG5ldyBUaHJpZnQuVHJhbnNwb3J0KCkKKyAgICAgICAgICAgIHZhciBfcHJvdG9jb2wgID0gbmV3IFRocmlmdC5Qcm90b2NvbChfdHJhbnNwb3J0KQorICAgICAgICAgICAgdmFyIF9jbGllbnQgICAgPSBuZXcgVGhyaWZ0VGVzdC5UaHJpZnRUZXN0Q2xpZW50KF9wcm90b2NvbCkKKworICAgICAgICAgICAgX3RyYW5zcG9ydC5zZXRSZWN2QnVmZmVyKCByZXMgKQorCisgICAgICAgICAgICB2YXIgdiA9ICBfY2xpZW50LnJlY3ZfdGVzdEk2NCgpCisgICAgICAgICAgICAkKCIjYm9keSIpLmFwcGVuZCgiY2xpZW50LnRlc3RJNjQoKSAgICA9PiAiKyh2ID09IE1hdGgucG93KDIsNjApKSsiPGJyLz4iKQorCisgICAgIH0KKyAgfSkKKworCisKKzwvc2NyaXB0PgorCis8L2JvZHk+Cis8L2h0bWw+CmRpZmYgLS1naXQgYS9saWIvanMvdGhyaWZ0LmpzIGIvbGliL2pzL3RocmlmdC5qcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzA5ODZmCi0tLSAvZGV2L251bGwKKysrIGIvbGliL2pzL3RocmlmdC5qcwpAQCAtMCwwICsxLDY3MSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLwordmFyIFRocmlmdCA9IHsKKworICAgIFR5cGUgOiB7CisgICAgICAgICJTVE9QIiAgIDogMCwKKyAgICAgICAgIlZPSUQiICAgOiAxLAorICAgICAgICAiQk9PTCIgICA6IDIsCisgICAgICAgICJCWVRFIiAgIDogMywKKyAgICAgICAgIkkwOCIgICAgOiAzLAorICAgICAgICAiRE9VQkxFIiA6IDQsCisgICAgICAgICJJMTYiICAgIDogNiwKKyAgICAgICAgIkkzMiIgICAgOiA4LAorICAgICAgICAiSTY0IiAgICA6IDEwLAorICAgICAgICAiU1RSSU5HIiA6IDExLAorICAgICAgICAiVVRGNyIgICA6IDExLAorICAgICAgICAiU1RSVUNUIiA6IDEyLAorICAgICAgICAiTUFQIiAgICA6IDEzLAorICAgICAgICAiU0VUIiAgICA6IDE0LAorICAgICAgICAiTElTVCIgICA6IDE1LAorICAgICAgICAiVVRGOCIgICA6IDE2LAorICAgICAgICAiVVRGMTYiICA6IDE3CisgICAgfSwKKworICAgIE1lc3NhZ2VUeXBlIDogeworICAgICAgICAiQ0FMTCIgICAgICA6IDEsCisgICAgICAgICJSRVBMWSIgICAgIDogMiwKKyAgICAgICAgIkVYQ0VQVElPTiIgOiAzCisgICAgfQorfQorCitUaHJpZnQuVEV4Y2VwdGlvbiA9IHt9CitUaHJpZnQuVEV4Y2VwdGlvbi5wcm90b3R5cGUgPSB7IAorICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCBtZXNzYWdlLCBjb2RlICkgeworICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICAgICAgICAgIHRoaXMuY29kZSAgICA9IChjb2RlID09IG51bGwpID8gMCA6IGNvZGU7CisgICAgfQorfQorCisKK1RocmlmdC5UQXBwbGljYXRpb25FeGNlcHRpb24gPSB7CisgICAgIlVOS05PV04iICAgICAgICAgICAgICA6IDAsCisgICAgIlVOS05PV05fTUVUSE9EIiAgICAgICA6IDEsCisgICAgIklOVkFMSURfTUVTU0FHRV9UWVBFIiA6IDIsCisgICAgIldST05HX01FVEhPRF9OQU1FIiAgICA6IDMsCisgICAgIkJBRF9TRVFVRU5DRV9JRCIgICAgICA6IDQsCisgICAgIk1JU1NJTkdfUkVTVUxUIiAgICAgICA6IDUgICAgICAgCit9CisKK1RocmlmdC5UQXBwbGljYXRpb25FeGNlcHRpb24gPSBmdW5jdGlvbihtZXNzYWdlLCBjb2RlKXsKKyAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlCisgICAgdGhpcy5jb2RlICAgID0gKGNvZGUgPT0gbnVsbCkgPyAwIDogY29kZQorfQorCitUaHJpZnQuVEFwcGxpY2F0aW9uRXhjZXB0aW9uLnByb3RvdHlwZSA9IHsgCisgICAgICAgCisgICAgcmVhZCA6IGZ1bmN0aW9uKGlucHV0KXsKKyAgICAgICAgCisgICAgICAgIHZhciBmdHlwZQorICAgICAgICB2YXIgZmlkCisgICAgICAgIHZhciByZXQgPSBpbnB1dC5yZWFkU3RydWN0QmVnaW4oZm5hbWUpIAorICAgICAgICAKKyAgICAgICAgdGhpcy5mbmFtZSA9IHJldC5mbmFtZSAgICAgIAorICAgICAgICAKKyAgICAgICAgd2hpbGUoMSl7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIHJldCA9IGlucHV0LnJlYWRGaWVsZEJlZ2luKCkKKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYocmV0LmZ0eXBlID09IFRUeXBlLlNUT1ApCisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgdmFyIGZpZCA9IHJldC5maWQKKyAgICAgICAgICAgIAorICAgICAgICAgICAgc3dpdGNoKGZpZCl7CisgICAgICAgICAgICAgICAgY2FzZSAxOiAKKyAgICAgICAgICAgICAgICAgICAgaWYoIHJldC5mdHlwZSA9PSBUeXBlLlNUUklORyApeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gaW5wdXQucmVhZFN0cmluZygpCisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSByZXQudmFsdWUKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IGlucHV0LnNraXAocmV0LmZ0eXBlKQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgICAgICAgICAgaWYoIHJldC5mdHlwZSA9PSBUeXBlLkkzMiApeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gaW5wdXQucmVhZEkzMigpCisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvZGUgPSByZXQudmFsdWUKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldCAgID0gaW5wdXQuc2tpcChyZXQuZnR5cGUpCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgcmV0ID0gaW5wdXQuc2tpcChyZXQuZnR5cGUpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGlucHV0LnJlYWRGaWVsZEVuZCgpCisgICAgICAgICAgICAKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaW5wdXQucmVhZFN0cnVjdEVuZCgpCisgICAgICAgIAorICAgIH0sCisgICAgCisgICAgd3JpdGU6IGZ1bmN0aW9uKG91dHB1dCl7CisgICAgICAgIHZhciB4ZmVyICAgPSAwOworICAgICAgICAKKyAgICAgICAgb3V0cHV0LndyaXRlU3RydWN0QmVnaW4oJ1RBcHBsaWNhdGlvbkV4Y2VwdGlvbicpOworICAgICAgICAKKyAgICAgICAgaWYgKHRoaXMubWVzc2FnZSkgeworICAgICAgICAgICAgb3V0cHV0LndyaXRlRmllbGRCZWdpbignbWVzc2FnZScsIFR5cGUuU1RSSU5HLCAxKQorICAgICAgICAgICAgb3V0cHV0LndyaXRlU3RyaW5nKHRoaXMuZ2V0TWVzc2FnZSgpKQorICAgICAgICAgICAgb3V0cHV0LndyaXRlRmllbGRFbmQoKQorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAodGhpcy5jb2RlKSB7CisgICAgICAgICAgICBvdXRwdXQud3JpdGVGaWVsZEJlZ2luKCd0eXBlJywgVHlwZS5JMzIsIDIpCisgICAgICAgICAgICBvdXRwdXQud3JpdGVJMzIodGhpcy5jb2RlKQorICAgICAgICAgICAgb3V0cHV0LndyaXRlRmllbGRFbmQoKQorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBvdXRwdXQud3JpdGVGaWVsZFN0b3AoKQorICAgICAgICBvdXRwdXQud3JpdGVTdHJ1Y3RFbmQoKQorICAgICAgIAorICAgIH0sCisgICAgCisgICAgZ2V0Q29kZSA6IGZ1bmN0aW9uKCkgeworICAgICAgICByZXR1cm4gdGhpcy5jb2RlCisgICAgfSwKKyAgICAKKyAgICBnZXRNZXNzYWdlIDogZnVuY3Rpb24oKSB7CisgICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2UKKyAgICB9Cit9CisKKworCisvKioKKyAqSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgdXJsIHRoZW4geW91IG11c3QgaGFuZGxlIGFqYXggb24geW91ciBvd24uCisgKlRoaXMgaXMgaG93IHRvIHVzZSBqcyBiaW5kaW5ncyBpbiBhIGFzeW5jIGZhc2hpb24uCisgKi8KK1RocmlmdC5UcmFuc3BvcnQgPSBmdW5jdGlvbih1cmwpeworICAgIHRoaXMudXJsICAgICAgPSB1cmwKKyAgICB0aGlzLndwb3MgICAgID0gMAorICAgIHRoaXMucnBvcyAgICAgPSAwCisKKyAgICB0aGlzLnNlbmRfYnVmID0gJycKKyAgICB0aGlzLnJlY3ZfYnVmID0gJycKK30KKworVGhyaWZ0LlRyYW5zcG9ydC5wcm90b3R5cGUgPSB7CisKKyAgICAvL0dldHMgdGhlIGJyb3dzZXIgc3BlY2lmaWMgWG1sSHR0cFJlcXVlc3QgT2JqZWN0CisgICAgZ2V0WG1sSHR0cFJlcXVlc3RPYmplY3QgOiBmdW5jdGlvbigpIHsKKwkKKyAgICAgICAgdHJ5IHsgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpIH0gY2F0Y2goZSkge30KKyAgICAgICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCJNc3htbDIuWE1MSFRUUCIpIH0gY2F0Y2ggKGUpIHt9CisgICAgICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKSB9IGNhdGNoIChlKSB7fQorCisgICAgICAgIHRocm93ICJZb3VyIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBYbWxIdHRwUmVxdWVzdCBvYmplY3QuICBUcnkgdXBncmFkaW5nIHRvIEZpcmVmb3guIgorCQorICAgIH0sCisKKyAgICBmbHVzaCA6IGZ1bmN0aW9uKCl7CisKKyAgICAgICAgLy9hc3luYyBtb2RlCisgICAgICAgIGlmKHRoaXMudXJsID09IHVuZGVmaW5lZCB8fCB0aGlzLnVybCA9PSAnJykKKyAgICAgICAgICAgIHJldHVybiB0aGlzLnNlbmRfYnVmOworCisgICAgICAgIHZhciB4cmVxID0gdGhpcy5nZXRYbWxIdHRwUmVxdWVzdE9iamVjdCgpCisgICAgICAgIAkJCisgICAgICAgIGlmICh4cmVxLm92ZXJyaWRlTWltZVR5cGUpCisgICAgICAgICAgICB4cmVxLm92ZXJyaWRlTWltZVR5cGUoImFwcGxpY2F0aW9uL2pzb24iKQorICAgICAgICAKKyAgICAgICAgeHJlcS5vcGVuKCJQT1NUIiwgdGhpcy51cmwsIGZhbHNlKQorICAgICAgICB4cmVxLnNlbmQodGhpcy5zZW5kX2J1ZikKKyAgICAgICAgCisgICAgICAgIGlmICh4cmVxLnJlYWR5U3RhdGUgIT0gNCkKKyAgICAgICAgICAgIHRocm93ICJlbmNvdW50ZXJlZCBhbiB1bmtub3duIGFqYXggcmVhZHkgc3RhdGU6ICIreHJlcS5yZWFkeVN0YXRlCisgICAgICAgIAorICAgICAgICBpZiAoeHJlcS5zdGF0dXMgIT0gMjAwKQorICAgICAgICAgICAgdGhyb3cgImVuY291bnRlcmVkIGEgdW5rbm93biByZXF1ZXN0IHN0YXR1czogIit4cmVxLnN0YXR1cworCisgICAgICAgIHRoaXMucmVjdl9idWYgICAgPSB4cmVxLnJlc3BvbnNlVGV4dAorICAgICAgICB0aGlzLnJlY3ZfYnVmX3N6ID0gdGhpcy5yZWN2X2J1Zi5sZW5ndGgKKyAgICAgICAgdGhpcy53cG9zICAgICAgICA9IHRoaXMucmVjdl9idWYubGVuZ3RoCisgICAgICAgIHRoaXMucnBvcyAgICAgICAgPSAwCisgICAgfSwKKworICAgIHNldFJlY3ZCdWZmZXIgOiBmdW5jdGlvbihidWYpeworICAgICAgICB0aGlzLnJlY3ZfYnVmICAgID0gYnVmCisgICAgICAgIHRoaXMucmVjdl9idWZfc3ogPSB0aGlzLnJlY3ZfYnVmLmxlbmd0aAorICAgICAgICB0aGlzLndwb3MgICAgICAgID0gdGhpcy5yZWN2X2J1Zi5sZW5ndGgKKyAgICAgICAgdGhpcy5ycG9zICAgICAgICA9IDAKKyAgICB9LAorCisgICAgaXNPcGVuIDogZnVuY3Rpb24oKSB7CisgICAgICAgIHJldHVybiB0cnVlCisgICAgfSwKKworICAgIG9wZW4gOiBmdW5jdGlvbigpIHt9LAorCisgICAgY2xvc2U6IGZ1bmN0aW9uKCkge30sCisKKyAgICByZWFkIDogZnVuY3Rpb24obGVuKSB7CisgICAgICAgIHZhciBhdmFpbCA9IHRoaXMud3BvcyAtIHRoaXMucnBvcworICAgICAgIAorICAgICAgICBpZihhdmFpbCA9PSAwKQorICAgICAgICAgICAgcmV0dXJuICcnCisKKyAgICAgICAgdmFyIGdpdmUgPSBsZW4KKworICAgICAgICBpZihhdmFpbCA8IGxlbikKKyAgICAgICAgICAgIGdpdmUgPSBhdmFpbAorCisgICAgICAgIHZhciByZXQgPSB0aGlzLnJlYWRfYnVmLnN1YnN0cih0aGlzLnJwb3MsZ2l2ZSkKKyAgICAgICAgdGhpcy5ycG9zICs9IGdpdmUKKworICAgICAgICAvL2NsZWFyIGJ1ZiB3aGVuIGNvbXBsZXRlPworICAgICAgICByZXR1cm4gcmV0CisgICAgfSwKKworICAgIHJlYWRBbGwgOiBmdW5jdGlvbigpIHsKKyAgICAgICByZXR1cm4gdGhpcy5yZWN2X2J1ZgorICAgIH0sCisKKyAgICB3cml0ZSA6IGZ1bmN0aW9uKGJ1Zil7CisgICAgICAgIHRoaXMuc2VuZF9idWYgPSBidWYKKyAgICB9LAorCisgICAgZ2V0U2VuZEJ1ZmZlciA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHJldHVybiB0aGlzLnNlbmRfYnVmCisgICAgfQorCit9CisKKworCitUaHJpZnQuUHJvdG9jb2wgPSBmdW5jdGlvbih0cmFuc3BvcnQpeworICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0Cit9CisKK1RocmlmdC5Qcm90b2NvbC5UeXBlID0ge30KK1RocmlmdC5Qcm90b2NvbC5UeXBlWyBUaHJpZnQuVHlwZS5CT09MICAgXSA9ICcidGYiJworVGhyaWZ0LlByb3RvY29sLlR5cGVbIFRocmlmdC5UeXBlLkJZVEUgICBdID0gJyJpOCInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuSTE2ICAgIF0gPSAnImkxNiInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuSTMyICAgIF0gPSAnImkzMiInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuSTY0ICAgIF0gPSAnImk2NCInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuRE9VQkxFIF0gPSAnImRibCInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuU1RSVUNUIF0gPSAnInJlYyInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuU1RSSU5HIF0gPSAnInN0ciInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuTUFQICAgIF0gPSAnIm1hcCInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuTElTVCAgIF0gPSAnImxzdCInCitUaHJpZnQuUHJvdG9jb2wuVHlwZVsgVGhyaWZ0LlR5cGUuU0VUICAgIF0gPSAnInNldCInCisKKworVGhyaWZ0LlByb3RvY29sLlJUeXBlID0ge30KK1RocmlmdC5Qcm90b2NvbC5SVHlwZVsgInRmIiBdID0gVGhyaWZ0LlR5cGUuQk9PTAorVGhyaWZ0LlByb3RvY29sLlJUeXBlWyAiaTgiIF0gPSBUaHJpZnQuVHlwZS5CWVRFCitUaHJpZnQuUHJvdG9jb2wuUlR5cGVbICJpMTYiXSA9IFRocmlmdC5UeXBlLkkxNgorVGhyaWZ0LlByb3RvY29sLlJUeXBlWyAiaTMyIl0gPSBUaHJpZnQuVHlwZS5JMzIKK1RocmlmdC5Qcm90b2NvbC5SVHlwZVsgImk2NCJdID0gVGhyaWZ0LlR5cGUuSTY0IAorVGhyaWZ0LlByb3RvY29sLlJUeXBlWyAiZGJsIl0gPSBUaHJpZnQuVHlwZS5ET1VCTEUgCitUaHJpZnQuUHJvdG9jb2wuUlR5cGVbICJyZWMiXSA9IFRocmlmdC5UeXBlLlNUUlVDVCAKK1RocmlmdC5Qcm90b2NvbC5SVHlwZVsgInN0ciJdID0gVGhyaWZ0LlR5cGUuU1RSSU5HCitUaHJpZnQuUHJvdG9jb2wuUlR5cGVbICJtYXAiXSA9IFRocmlmdC5UeXBlLk1BUCAKK1RocmlmdC5Qcm90b2NvbC5SVHlwZVsgImxzdCJdID0gVGhyaWZ0LlR5cGUuTElTVAorVGhyaWZ0LlByb3RvY29sLlJUeXBlWyAic2V0Il0gPSBUaHJpZnQuVHlwZS5TRVQgCisKK1RocmlmdC5Qcm90b2NvbC5WZXJzaW9uID0gMQorCitUaHJpZnQuUHJvdG9jb2wucHJvdG90eXBlID0geworICAgIAorICAgIGdldFRyYW5zcG9ydCA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydAorICAgIH0sCisKKyAgICAvL1dyaXRlIGZ1bmN0aW9ucworICAgIHdyaXRlTWVzc2FnZUJlZ2luIDogZnVuY3Rpb24obmFtZSxtZXNzYWdlVHlwZSxzZXFpZCl7CisgICAgICAgIHRoaXMudHN0YWNrID0gbmV3IEFycmF5KCkKKyAgICAgICAgdGhpcy50cG9zICAgPSBuZXcgQXJyYXkoKTsKKyAgICAgICAgICAgCisgICAgICAgIHRoaXMudHN0YWNrLnB1c2goW1RocmlmdC5Qcm90b2NvbC5WZXJzaW9uLCciJytuYW1lKyciJyxtZXNzYWdlVHlwZSxzZXFpZF0pOworICAgIH0sCisKKyAgICB3cml0ZU1lc3NhZ2VFbmQgOiBmdW5jdGlvbigpeworICAgICAgICB2YXIgb2JqID0gdGhpcy50c3RhY2sucG9wKCkKKyAgICAgICAgCisgICAgICAgIHRoaXMud29iaiA9IHRoaXMudHN0YWNrLnBvcCgpCisgICAgICAgIHRoaXMud29iai5wdXNoKG9iaikKKyAKKyAgICAgICAgdGhpcy53YnVmID0gIlsiK3RoaXMud29iai5qb2luKCIsIikrIl0iOworCisgICAgICAgIHRoaXMudHJhbnNwb3J0LndyaXRlKHRoaXMud2J1Zik7ICAgICAgIAorICAgICB9LAorCisKKyAgICB3cml0ZVN0cnVjdEJlZ2luIDogZnVuY3Rpb24obmFtZSl7CisgICAgICAgIHRoaXMudHBvcy5wdXNoKHRoaXMudHN0YWNrLmxlbmd0aCkKKyAgICAgICAgdGhpcy50c3RhY2sucHVzaCh7fSkKKyAgICB9LAorCisgICAgd3JpdGVTdHJ1Y3RFbmQgOiBmdW5jdGlvbigpeworICAgICAgICAKKyAgICAgICAgdmFyIHAgPSB0aGlzLnRwb3MucG9wKCkKKyAgICAgICAgdmFyIHN0cnVjdCA9IHRoaXMudHN0YWNrW3BdCisgICAgICAgIHZhciBzdHIgPSAieyIKKyAgICAgICAgdmFyIGZpcnN0ID0gdHJ1ZQorICAgICAgICBmb3IoIHZhciBrZXkgaW4gc3RydWN0ICl7CisgICAgICAgICAgICBpZihmaXJzdCkgCisgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBzdHIgKz0gIiwiOworCisgICAgICAgICAgICBzdHIgKz0ga2V5KyI6IitzdHJ1Y3Rba2V5XQorICAgICAgICB9IAorCisgICAgICAgIHN0ciArPSAifSIKKyAgICAgICAgdGhpcy50c3RhY2tbcF0gPSBzdHI7CisgICAgfSwKKworICAgIHdyaXRlRmllbGRCZWdpbiA6IGZ1bmN0aW9uKG5hbWUsZmllbGRUeXBlLGZpZWxkSWQpeworICAgICAgICB0aGlzLnRwb3MucHVzaCh0aGlzLnRzdGFjay5sZW5ndGgpCisgICAgICAgIHRoaXMudHN0YWNrLnB1c2goeyJmaWVsZElkIiA6ICciJytmaWVsZElkKyciJywgImZpZWxkVHlwZSIgOiBUaHJpZnQuUHJvdG9jb2wuVHlwZVtmaWVsZFR5cGVdfSk7CisgICAgICAgCisgICAgfSwKKworICAgIHdyaXRlRmllbGRFbmQgOiBmdW5jdGlvbigpeworICAgICAgICB2YXIgdmFsdWUgICAgID0gdGhpcy50c3RhY2sucG9wKCkKKyAgICAgICAgdmFyIGZpZWxkSW5mbyA9IHRoaXMudHN0YWNrLnBvcCgpIAorICAgICAgICAKKyAgICAgICAgdGhpcy50c3RhY2tbdGhpcy50c3RhY2subGVuZ3RoLTFdW2ZpZWxkSW5mby5maWVsZElkXSA9ICJ7IitmaWVsZEluZm8uZmllbGRUeXBlKyI6Iit2YWx1ZSsifSIgCisgICAgICAgIHRoaXMudHBvcy5wb3AoKQorICAgIH0sCisKKyAgICB3cml0ZUZpZWxkU3RvcCA6IGZ1bmN0aW9uKCl7CisgICAgICAgIC8vbmEKKyAgICB9LAorCisgICAgd3JpdGVNYXBCZWdpbiA6IGZ1bmN0aW9uKGtleVR5cGUsdmFsVHlwZSxzaXplKXsKKyAgICAgICAgLy9zaXplIGlzIGludmFsaWQsIHdlJ2xsIHNldCBpdCBvbiBlbmQuCisgICAgICAgIHRoaXMudHBvcy5wdXNoKHRoaXMudHN0YWNrLmxlbmd0aCkKKyAgICAgICAgdGhpcy50c3RhY2sucHVzaChbVGhyaWZ0LlByb3RvY29sLlR5cGVba2V5VHlwZV0sVGhyaWZ0LlByb3RvY29sLlR5cGVbdmFsVHlwZV0sMF0pIAorICAgIH0sCisKKyAgICB3cml0ZU1hcEVuZCA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHZhciBwICAgPSB0aGlzLnRwb3MucG9wKCkKKyAgICAgICAgCisgICAgICAgIGlmKHAgPT0gdGhpcy50c3RhY2subGVuZ3RoKQorICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAKKyAgICAgICAgaWYoKHRoaXMudHN0YWNrLmxlbmd0aCAtIHAgLSAxKSAlIDIgIT0gMCkKKyAgICAgICAgICAgIHRoaXMudHN0YWNrLnB1c2goIiIpOworCisgICAgICAgIHZhciBzaXplID0gKHRoaXMudHN0YWNrLmxlbmd0aCAtIHAgLSAxKS8yCisKKyAgICAgICAgdGhpcy50c3RhY2tbcF1bdGhpcy50c3RhY2tbcF0ubGVuZ3RoLTFdID0gc2l6ZTsKKyAgICAgICAgCisgICAgICAgIHZhciBtYXAgICA9ICJ7IgorICAgICAgICB2YXIgZmlyc3QgPSB0cnVlCisgICAgICAgIHdoaWxlKCB0aGlzLnRzdGFjay5sZW5ndGggPiBwKzEgKXsKKyAgICAgICAgICAgIHZhciB2ID0gdGhpcy50c3RhY2sucG9wKCkKKyAgICAgICAgICAgIHZhciBrID0gdGhpcy50c3RhY2sucG9wKCkKKyAgICAgICAgICAgIGlmKGZpcnN0KXsKKyAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlCisgICAgICAgICAgICB9ZWxzZXsKKyAgICAgICAgICAgICAgICBtYXAgKz0gIiwiCisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIG1hcCAgKz0gJyInK2srJyI6Jyt2CisgICAgICAgIH0KKyAgICAgICAgbWFwICs9ICJ9IgorICAgICAgICAKKyAgICAgICAgdGhpcy50c3RhY2tbcF0ucHVzaChtYXApCisgICAgICAgIHRoaXMudHN0YWNrW3BdID0gIlsiK3RoaXMudHN0YWNrW3BdLmpvaW4oIiwiKSsiXSIKKyAgICB9LAorCisgICAgd3JpdGVMaXN0QmVnaW4gOiBmdW5jdGlvbihlbGVtVHlwZSxzaXplKXsKKyAgICAgICAgdGhpcy50cG9zLnB1c2godGhpcy50c3RhY2subGVuZ3RoKQorICAgICAgICB0aGlzLnRzdGFjay5wdXNoKFtUaHJpZnQuUHJvdG9jb2wuVHlwZVtlbGVtVHlwZV0sc2l6ZV0pOworICAgIH0sCisKKyAgICB3cml0ZUxpc3RFbmQgOiBmdW5jdGlvbigpeworICAgICAgICB2YXIgcCA9IHRoaXMudHBvcy5wb3AoKQorCisgICAgICAgIHdoaWxlKCB0aGlzLnRzdGFjay5sZW5ndGggPiBwKzEgKXsKKyAgICAgICAgICAgIHRoaXMudHN0YWNrW3BdLnB1c2godGhpcy50c3RhY2sucG9wKCkpCisgICAgICAgIH0KKworICAgICAgICB0aGlzLnRzdGFja1twXSA9ICdbJyt0aGlzLnRzdGFja1twXS5qb2luKCIsIikrJ10nOworICAgIH0sCisKKyAgICB3cml0ZVNldEJlZ2luIDogZnVuY3Rpb24oZWxlbVR5cGUsc2l6ZSl7CisgICAgICAgIHRoaXMudHBvcy5wdXNoKHRoaXMudHN0YWNrLmxlbmd0aCkKKyAgICAgICAgdGhpcy50c3RhY2sucHVzaChbVGhyaWZ0LlByb3RvY29sLlR5cGVbZWxlbVR5cGVdLHNpemVdKTsKKyAgICB9LAorCisgICAgd3JpdGVTZXRFbmQgOiBmdW5jdGlvbigpeworICAgICAgICB2YXIgcCA9IHRoaXMudHBvcy5wb3AoKQorCisgICAgICAgIHdoaWxlKCB0aGlzLnRzdGFjay5sZW5ndGggPiBwKzEgKXsKKyAgICAgICAgICAgIHRoaXMudHN0YWNrW3BdLnB1c2godGhpcy50c3RhY2sucG9wKCkpCisgICAgICAgIH0KKworICAgICAgICB0aGlzLnRzdGFja1twXSA9ICdbJyt0aGlzLnRzdGFja1twXS5qb2luKCIsIikrJ10nOworICAgIH0sCisKKyAgICB3cml0ZUJvb2wgOiBmdW5jdGlvbih2YWx1ZSl7CisgICAgICAgIHRoaXMudHN0YWNrLnB1c2goIHZhbHVlID8gMSA6IDAgKTsKKyAgICB9LAorCisgICAgd3JpdGVCeXRlIDogZnVuY3Rpb24oaTgpeworICAgICAgICB0aGlzLnRzdGFjay5wdXNoKGk4KTsKKyAgICB9LAorCisgICAgd3JpdGVJMTYgOiBmdW5jdGlvbihpMTYpeworICAgICAgICB0aGlzLnRzdGFjay5wdXNoKGkxNik7CisgICAgfSwKKworICAgIHdyaXRlSTMyIDogZnVuY3Rpb24oaTMyKXsKKyAgICAgICAgdGhpcy50c3RhY2sucHVzaChpMzIpOworICAgIH0sCisKKyAgICB3cml0ZUk2NCA6IGZ1bmN0aW9uKGk2NCl7CisgICAgICAgIHRoaXMudHN0YWNrLnB1c2goaTY0KTsKKyAgICB9LAorCisgICAgd3JpdGVEb3VibGUgOiBmdW5jdGlvbihkYmwpeworICAgICAgICB0aGlzLnRzdGFjay5wdXNoKGRibCk7CisgICAgfSwKKworICAgIHdyaXRlU3RyaW5nIDogZnVuY3Rpb24oc3RyKXsKKyAgICAgICAgdGhpcy50c3RhY2sucHVzaCgnIicrZW5jb2RlVVJJQ29tcG9uZW50KHN0cikrJyInKTsKKyAgICB9LAorCisgICAgd3JpdGVCaW5hcnkgOiBmdW5jdGlvbihzdHIpeworICAgICAgICB0aGlzLndyaXRlU3RyaW5nKHN0cik7CisgICAgfSwKKworCisgICAgCisgICAgLy8gUmVhZGluZyBmdW5jdGlvbnMKKyAgICByZWFkTWVzc2FnZUJlZ2luIDogZnVuY3Rpb24obmFtZSwgbWVzc2FnZVR5cGUsIHNlcWlkKXsKKyAgICAgICAgdGhpcy5yc3RhY2sgPSBuZXcgQXJyYXkoKQorICAgICAgICB0aGlzLnJwb3MgICA9IG5ldyBBcnJheSgpCisgICAgICAgCisgICAgICAgIHRoaXMucm9iaiA9IGV2YWwodGhpcy50cmFuc3BvcnQucmVhZEFsbCgpKQorICAgICAgICAKKyAgICAgICAgdmFyIHIgPSB7fSAgICAgCisgICAgICAgIHZhciB2ZXJzaW9uID0gdGhpcy5yb2JqLnNoaWZ0KCkKKyAgICAgICAgCisgICAgICAgIGlmKHZlcnNpb24gIT0gVGhyaWZ0LlByb3RvY29sLlZlcnNpb24peworICAgICAgICAgICAgdGhyb3cgIldyb25nIHRocmlmdCBwcm90b2NvbCB2ZXJzaW9uOiAiK3ZlcnNpb24KKyAgICAgICAgfQorCisgICAgICAgIHJbImZuYW1lIl0gID0gdGhpcy5yb2JqLnNoaWZ0KCkKKyAgICAgICAgclsibXR5cGUiXSAgPSB0aGlzLnJvYmouc2hpZnQoKQorICAgICAgICByWyJyc2VxaWQiXSA9IHRoaXMucm9iai5zaGlmdCgpCisgICAgICAgIAorICAgICAgICAKKyAgICAgICAgLy9nZXQgdG8gdGhlIG1haW4gb2JqCisgICAgICAgIHRoaXMucnN0YWNrLnB1c2godGhpcy5yb2JqLnNoaWZ0KCkpCisgICAgICAKKyAgICAgICAgcmV0dXJuIHIKKyAgICB9LAorCisgIAorICAgIHJlYWRNZXNzYWdlRW5kIDogZnVuY3Rpb24oKXsKKyAgICB9LAorCisgICAgcmVhZFN0cnVjdEJlZ2luIDogZnVuY3Rpb24obmFtZSl7CisgICAgICAgIHZhciByID0ge307CisgICAgICAgIHJbImZuYW1lIl0gPSAnJzsKKyAgICAgICAgICAgICAKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfSwKKworICAgIHJlYWRTdHJ1Y3RFbmQgOiBmdW5jdGlvbigpeworICAgIH0sCisKKyAgICByZWFkRmllbGRCZWdpbiA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHZhciByID0ge307CisgICAgICAgIAorICAgICAgICB2YXIgZmlkICAgPSAtMQorICAgICAgICB2YXIgZnR5cGUgPSBUaHJpZnQuVHlwZS5TVE9QIAorICAgICAgICAKKyAgICAgICAgLy9nZXQgYSBmaWVsZElkCisgICAgICAgIGZvcih2YXIgZiBpbiAodGhpcy5yc3RhY2tbdGhpcy5yc3RhY2subGVuZ3RoLTFdKSl7CisgICAgICAgICAgICBpZihmID09IG51bGwpIGNvbnRpbnVlCisgICAgICAgICAgICAKKyAgICAgICAgICAgIGZpZCA9IHBhcnNlSW50KGYpCisgICAgICAgICAgICB0aGlzLnJwb3MucHVzaCh0aGlzLnJzdGFjay5sZW5ndGgpCisgICAgICAgICAgICAKKyAgICAgICAgICAgIHZhciBmaWVsZCA9IHRoaXMucnN0YWNrW3RoaXMucnN0YWNrLmxlbmd0aC0xXVtmaWRdCisgICAgICAgICAgIAorICAgICAgICAgICAgLy9yZW1vdmUgc28gd2UgZG9uJ3Qgc2VlIGl0IGFnYWluCisgICAgICAgICAgICBkZWxldGUgdGhpcy5yc3RhY2tbdGhpcy5yc3RhY2subGVuZ3RoLTFdW2ZpZF0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgdGhpcy5yc3RhY2sucHVzaChmaWVsZCkgICAgICAgICAgICAKKyAgICAgICAgICAgIAorICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgIGlmKGZpZCAhPSAtMSl7ICAgICAgCisgICAgICAgCisgICAgICAgICAgICAvL3Nob3VsZCBvbmx5IGJlIDEgb2YgdGhlc2UgYnV0IHRoaXMgaXMgdGhlIG9ubHkKKyAgICAgICAgICAgIC8vd2F5IHRvIG1hdGNoIGEga2V5CisgICAgICAgICAgICBmb3IodmFyIGYgaW4gKHRoaXMucnN0YWNrW3RoaXMucnN0YWNrLmxlbmd0aC0xXSkpeworICAgICAgICAgICAgICAgIGlmKFRocmlmdC5Qcm90b2NvbC5SVHlwZVtmXSA9PSBudWxsICkgY29udGludWUKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBmdHlwZSA9IFRocmlmdC5Qcm90b2NvbC5SVHlwZVtmXQorICAgICAgICAgICAgICAgIHRoaXMucnN0YWNrW3RoaXMucnN0YWNrLmxlbmd0aC0xXSA9IHRoaXMucnN0YWNrW3RoaXMucnN0YWNrLmxlbmd0aC0xXVtmXQorICAgICAgICAgICAgfSAgICAgICAgCisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIHJbImZuYW1lIl0gPSAnJworICAgICAgICByWyJmdHlwZSJdID0gZnR5cGUKKyAgICAgICAgclsiZmlkIl0gICA9IGZpZAorICAgICAgICAKKworICAgICAgICByZXR1cm4gcgorICAgIH0sCisKKyAgICByZWFkRmllbGRFbmQgOiBmdW5jdGlvbigpeyAgCisgICAgICAgIHZhciBwb3MgPSB0aGlzLnJwb3MucG9wKCkKKyAgICAgICAgCisgICAgICAgIC8vZ2V0IGJhY2sgdG8gdGhlIHJpZ2h0IHBsYWNlIGluIHRoZSBzdGFjaworICAgICAgICB3aGlsZSh0aGlzLnJzdGFjay5sZW5ndGggPiBwb3MpCisgICAgICAgICAgICB0aGlzLnJzdGFjay5wb3AoKTsKKyAgICAgICAgICAgICAgICAgCisgICAgfSwKKworICAgIHJlYWRNYXBCZWdpbiA6IGZ1bmN0aW9uKGtleVR5cGUsdmFsVHlwZSxzaXplKXsKKyAgICAgICAgCisgICAgICAgIHZhciBtYXAgPSB0aGlzLnJzdGFja1t0aGlzLnJzdGFjay5sZW5ndGgtMV0KKyAgICAgICAgCisgICAgICAgIHZhciByID0ge307CisgICAgICAgIHJbImt0eXBlIl0gPSBUaHJpZnQuUHJvdG9jb2wuUlR5cGVbbWFwLnNoaWZ0KCldCisgICAgICAgIHJbInZ0eXBlIl0gPSBUaHJpZnQuUHJvdG9jb2wuUlR5cGVbbWFwLnNoaWZ0KCldCisgICAgICAgIHJbInNpemUiXSAgPSBtYXAuc2hpZnQoKQorICAgICAgICAKKyAgICAgICAgCisgICAgICAgIHRoaXMucnBvcy5wdXNoKHRoaXMucnN0YWNrLmxlbmd0aCkKKyAgICAgICAgdGhpcy5yc3RhY2sucHVzaChtYXAuc2hpZnQoKSkKKyAgICAgICAgCisgICAgICAgIHJldHVybiByOworICAgIH0sCisKKyAgICByZWFkTWFwRW5kIDogZnVuY3Rpb24oKXsKKyAgICAgICAgdGhpcy5yZWFkRmllbGRFbmQoKQorICAgIH0sCisKKyAgICByZWFkTGlzdEJlZ2luIDogZnVuY3Rpb24oZWxlbVR5cGUsc2l6ZSl7CisgICAgICAKKyAgICAgICAgdmFyIGxpc3QgPSB0aGlzLnJzdGFja1t0aGlzLnJzdGFjay5sZW5ndGgtMV0KKyAgICAgIAorICAgICAgICB2YXIgciA9IHt9OworICAgICAgICByWyJldHlwZSJdID0gVGhyaWZ0LlByb3RvY29sLlJUeXBlW2xpc3Quc2hpZnQoKV07CisgICAgICAgIHJbInNpemUiIF0gPSBsaXN0LnNoaWZ0KCk7CisgICAgICAgIAorICAgICAgICAKKyAgICAgICAgdGhpcy5ycG9zLnB1c2godGhpcy5yc3RhY2subGVuZ3RoKTsKKyAgICAgICAgdGhpcy5yc3RhY2sucHVzaChsaXN0LnNoaWZ0KCkpCisgICAgICAgIAorICAgICAgICAKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfSwKKworICAgIHJlYWRMaXN0RW5kIDogZnVuY3Rpb24oKXsKKyAgICAgICAgdGhpcy5yZWFkRmllbGRFbmQoKQorICAgIH0sCisKKyAgICByZWFkU2V0QmVnaW4gOiBmdW5jdGlvbihlbGVtVHlwZSxzaXplKXsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVhZExpc3RCZWdpbihlbGVtVHlwZSxzaXplKQorICAgIH0sCisKKyAgICByZWFkU2V0RW5kIDogZnVuY3Rpb24oKXsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVhZExpc3RFbmQoKQorICAgIH0sCisKKyAgICByZWFkQm9vbCA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHZhciByID0gdGhpcy5yZWFkSTMyKCkKKyAgICAKKyAgICAgICAgaWYoIHIgIT0gbnVsbCAmJiByWyJ2YWx1ZSJdID09ICIxIiApeworICAgICAgICAgICAgclsidmFsdWUiXSA9IHRydWUKKyAgICAgICAgfWVsc2V7CisgICAgICAgICAgICByWyJ2YWx1ZSJdID0gZmFsc2UKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgcmV0dXJuIHIKKyAgICB9LAorCisgICAgcmVhZEJ5dGUgOiBmdW5jdGlvbigpeworICAgICAgICByZXR1cm4gdGhpcy5yZWFkSTMyKCkKKyAgICB9LAorCisgICAgcmVhZEkxNiA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHJldHVybiB0aGlzLnJlYWRJMzIoKQorICAgIH0sCisgICAKKworICAgIHJlYWRJMzIgOiBmdW5jdGlvbigpeworICAgICAgICB2YXIgZiA9IHRoaXMucnN0YWNrW3RoaXMucnN0YWNrLmxlbmd0aC0xXQorICAgICAgICB2YXIgciA9IHt9ICAgIAorICAgICAgICAgICAgCisgICAgICAgIGlmKGYgaW5zdGFuY2VvZiBBcnJheSl7CisgICAgICAgICAgICByWyJ2YWx1ZSJdID0gZi5wb3AoKQorICAgICAgICAKKyAgICAgICAgfWVsc2UgaWYoZiBpbnN0YW5jZW9mIE9iamVjdCl7CisgICAgICAgICAgIGZvcih2YXIgaSBpbiBmKXsKKyAgICAgICAgICAgICAgICBpZihpID09IG51bGwpIGNvbnRpbnVlCisgICAgICAgICAgICAgICAgdGhpcy5yc3RhY2sucHVzaChmW2ldKQorICAgICAgICAgICAgICAgIGRlbGV0ZSBmW2ldICAKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICByWyJ2YWx1ZSJdID0gaQorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJbInZhbHVlIl0gPSBmCisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIAorICAgICAgICByZXR1cm4gcgorICAgIH0sCisKKyAgICByZWFkSTY0IDogZnVuY3Rpb24oKXsKKyAgICAgICAgcmV0dXJuIHRoaXMucmVhZEkzMigpCisgICAgfSwKKworICAgIHJlYWREb3VibGUgOiBmdW5jdGlvbigpeworICAgICAgICByZXR1cm4gdGhpcy5yZWFkSTMyKCkKKyAgICB9LAorCisgICAgcmVhZFN0cmluZyA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHZhciByID0gdGhpcy5yZWFkSTMyKCkKKyAgICAgICAgclsidmFsdWUiXSA9IGRlY29kZVVSSUNvbXBvbmVudChyWyJ2YWx1ZSJdKQorICAgICAgICAKKyAgICAgICAgcmV0dXJuIHIKKyAgICB9LAorCisgICAgcmVhZEJpbmFyeSA6IGZ1bmN0aW9uKCl7CisgICAgICAgIHJldHVybiB0aGlzLnJlYWRTdHJpbmcoKQorICAgIH0sCisKKyAgICAKKyAgICAvL01ldGhvZCB0byBhcmJpdHJhcmlseSBza2lwIG92ZXIgZGF0YS4KKyAgICBza2lwIDogZnVuY3Rpb24odHlwZSl7CisgICAgICAgIHRocm93ICJza2lwIG5vdCBzdXBwb3J0ZWQgeWV0IgorICAgIH0KKyAgIAorfQorCisKKwpkaWZmIC0tZ2l0IGEvdGVzdC9UaHJpZnRUZXN0LnRocmlmdCBiL3Rlc3QvVGhyaWZ0VGVzdC50aHJpZnQKaW5kZXggZDI1MTgzYi4uOTE5YjY4ZiAxMDA2NDQKLS0tIGEvdGVzdC9UaHJpZnRUZXN0LnRocmlmdAorKysgYi90ZXN0L1RocmlmdFRlc3QudGhyaWZ0CkBAIC0yNiw2ICsyNiw3IEBACiBuYW1lc3BhY2UgcmIgVGhyaWZ0LlRlc3QKIG5hbWVzcGFjZSBwZXJsIFRocmlmdFRlc3QKIG5hbWVzcGFjZSBjc2hhcnAgVGhyaWZ0LlRlc3QKK25hbWVzcGFjZSBqcyBUaHJpZnRUZXN0CiAKIC8qKgogICogRG9jc3RyaW5nIQo=