ZGlmZiAtLWdpdCBhL2xpYi9qcy90ZXN0L1J1blRlc3RTZXJ2ZXIuc2ggYi9saWIvanMvdGVzdC9SdW5UZXN0U2VydmVyLnNoCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjU3NGY3YzUKLS0tIC9kZXYvbnVsbAorKysgYi9saWIvanMvdGVzdC9SdW5UZXN0U2VydmVyLnNoCkBAIC0wLDAgKzEsNDAgQEAKKyMhL2Jpbi9iYXNoIAorCisjCisjIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuIFNlZSB0aGUgTk9USUNFIGZpbGUKKyMgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisjIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorIyB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorIyBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorIyAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyMgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyMgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworIyB1bmRlciB0aGUgTGljZW5zZS4KKyMKKworTE9HNEo9Ii4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9zbGY0ai1hcGktMS41LjguamFyOi4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9sb2c0ai0xLjIuMTUuamFyOi4uLy4uL2phdmEvYnVpbGQvaXZ5L2xpYi9zbGY0ai1zaW1wbGUtMS41LjguamFyIgorSFRUUENPUkU9Ii4vaHR0cGNvcmUtNC4wLjEuamFyIgorCitpZiBbIC1mICR7SFRUUENPUkV9IF0KK3RoZW4KKyAgICBlY2hvICJjb21waWxpbmcgdGVzdC4uLiIKK2Vsc2UKKyAgICBlY2hvICJNaXNzaW5nIHJlcXVpcmVkIGZpbGUgJHtIVFRQQ09SRX0iCisgICAgZWNobyAiWW91IGNhbiBkb3dubG9hZCB0aGlzIGZyb20gaHR0cDovL2FyY2hpdmUuYXBhY2hlLm9yZy9kaXN0L2h0dHBjb21wb25lbnRzL2h0dHBjb3JlL2JpbmFyeS9odHRwY29tcG9uZW50cy1jb3JlLTQuMC4xLWJpbi50YXIuZ3oiCisgICAgZWNobyAiUGxhY2UgdGhlIGphciBpbiB0aGlzIGRpcmVjdG9yeSBhbmQgdHJ5IGFnYWluLiIKKyAgICBleGl0CitmaQorCisuLi8uLi8uLi9jb21waWxlci9jcHAvdGhyaWZ0IC0tZ2VuIGphdmEgLi4vLi4vLi4vdGVzdC9UaHJpZnRUZXN0LnRocmlmdAorLi4vLi4vLi4vY29tcGlsZXIvY3BwL3RocmlmdCAtLWdlbiBqcyAuLi8uLi8uLi90ZXN0L1RocmlmdFRlc3QudGhyaWZ0CisKK2phdmFjIC1jcCAke0xPRzRKfTouLi8uLi9qYXZhL2xpYnRocmlmdC5qYXIgZ2VuLWphdmEvdGhyaWZ0L3Rlc3QvKi5qYXZhCitqYXZhYyAtY3AgJHtMT0c0Sn06JHtIVFRQQ09SRX06Li4vLi4vamF2YS9saWJ0aHJpZnQuamFyOmdlbi1qYXZhLyBzcmMvdGVzdC8qLmphdmEgCitqYXZhIC1jcCAgJHtMT0c0Sn06JHtIVFRQQ09SRX06Li4vLi4vamF2YS9saWJ0aHJpZnQuamFyOmdlbi1qYXZhOnNyYyB0ZXN0Lkh0dHBkIC4uLwpkaWZmIC0tZ2l0IGEvbGliL2pzL3Rlc3Qvc3JjL3Rlc3QvSHR0cGQuamF2YSBiL2xpYi9qcy90ZXN0L3NyYy90ZXN0L0h0dHBkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTU1YThiOAotLS0gL2Rldi9udWxsCisrKyBiL2xpYi9qcy90ZXN0L3NyYy90ZXN0L0h0dHBkLmphdmEKQEAgLTAsMCArMSwyOTggQEAKKy8qCisgKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKgorICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKKyAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBGb3IgbW9yZQorICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCisgKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCisgKgorICovCisKK3BhY2thZ2UgdGVzdDsKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLm5ldC5TZXJ2ZXJTb2NrZXQ7CitpbXBvcnQgamF2YS5uZXQuU29ja2V0OworaW1wb3J0IGphdmEubmV0LlVSTERlY29kZXI7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5Db25uZWN0aW9uQ2xvc2VkRXhjZXB0aW9uOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5IdHRwRW50aXR5OworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5IdHRwRW50aXR5RW5jbG9zaW5nUmVxdWVzdDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFJlcXVlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkh0dHBSZXNwb25zZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFNlcnZlckNvbm5lY3Rpb247CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkh0dHBTdGF0dXM7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLk1ldGhvZE5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5LkNvbnRlbnRQcm9kdWNlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5LkVudGl0eVRlbXBsYXRlOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5lbnRpdHkuRmlsZUVudGl0eTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuaW1wbC5EZWZhdWx0SHR0cFJlc3BvbnNlRmFjdG9yeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuaW1wbC5EZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb247CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLmltcGwuTm9Db25uZWN0aW9uUmV1c2VTdHJhdGVneTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkJhc2ljSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkNvcmVDb25uZWN0aW9uUE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wYXJhbXMuQ29yZVByb3RvY29sUE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wYXJhbXMuSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwUHJvY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFByb2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFJlcXVlc3RIYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwUmVxdWVzdEhhbmRsZXJSZWdpc3RyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFNlcnZpY2U7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLnV0aWwuRW50aXR5VXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS50aHJpZnQuVFByb2Nlc3NvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC5wcm90b2NvbC5USlNPTlByb3RvY29sOworaW1wb3J0IG9yZy5hcGFjaGUudGhyaWZ0LnByb3RvY29sLlRQcm90b2NvbDsKK2ltcG9ydCBvcmcuYXBhY2hlLnRocmlmdC50cmFuc3BvcnQuVE1lbW9yeUJ1ZmZlcjsKKworaW1wb3J0IHRocmlmdC50ZXN0LlRocmlmdFRlc3Q7CisKKy8qKgorICogQmFzaWMsIHlldCBmdWxseSBmdW5jdGlvbmFsIGFuZCBzcGVjIGNvbXBsaWFudCwgSFRUUC8xLjEgZmlsZSBzZXJ2ZXIuCisgKiA8cD4KKyAqIFBsZWFzZSBub3RlIHRoZSBwdXJwb3NlIG9mIHRoaXMgYXBwbGljYXRpb24gaXMgZGVtb25zdHJhdGUgdGhlIHVzYWdlIG9mCisgKiBIdHRwQ29yZSBBUElzLiBJdCBpcyBOT1QgaW50ZW5kZWQgdG8gZGVtb25zdHJhdGUgdGhlIG1vc3QgZWZmaWNpZW50IHdheSBvZgorICogYnVpbGRpbmcgYW4gSFRUUCBmaWxlIHNlcnZlci4KKyAqIAorICogCisgKi8KK3B1YmxpYyBjbGFzcyBIdHRwZCB7CisKKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDwgMSkgeworICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJQbGVhc2Ugc3BlY2lmeSBkb2N1bWVudCByb290IGRpcmVjdG9yeSIpOworICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7CisgICAgICAgIH0KKyAgICAgICAgVGhyZWFkIHQgPSBuZXcgUmVxdWVzdExpc3RlbmVyVGhyZWFkKDgwODgsIGFyZ3NbMF0pOworICAgICAgICB0LnNldERhZW1vbihmYWxzZSk7CisgICAgICAgIHQuc3RhcnQoKTsKKyAgICB9CisKKyAgICBzdGF0aWMgY2xhc3MgSHR0cEZpbGVIYW5kbGVyIGltcGxlbWVudHMgSHR0cFJlcXVlc3RIYW5kbGVyIHsKKworICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBkb2NSb290OworCisgICAgICAgIHB1YmxpYyBIdHRwRmlsZUhhbmRsZXIoZmluYWwgU3RyaW5nIGRvY1Jvb3QpIHsKKyAgICAgICAgICAgIHN1cGVyKCk7CisgICAgICAgICAgICB0aGlzLmRvY1Jvb3QgPSBkb2NSb290OworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgaGFuZGxlKGZpbmFsIEh0dHBSZXF1ZXN0IHJlcXVlc3QsIGZpbmFsIEh0dHBSZXNwb25zZSByZXNwb25zZSwgZmluYWwgSHR0cENvbnRleHQgY29udGV4dCkgdGhyb3dzIEh0dHBFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKworICAgICAgICAgICAgU3RyaW5nIG1ldGhvZCA9IHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKS5nZXRNZXRob2QoKS50b1VwcGVyQ2FzZShMb2NhbGUuRU5HTElTSCk7CisgICAgICAgICAgICBpZiAoIW1ldGhvZC5lcXVhbHMoIkdFVCIpICYmICFtZXRob2QuZXF1YWxzKCJIRUFEIikgJiYgIW1ldGhvZC5lcXVhbHMoIlBPU1QiKSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBNZXRob2ROb3RTdXBwb3J0ZWRFeGNlcHRpb24obWV0aG9kICsgIiBtZXRob2Qgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIHRhcmdldCA9IHJlcXVlc3QuZ2V0UmVxdWVzdExpbmUoKS5nZXRVcmkoKTsKKworICAgICAgICAgICAgaWYgKHJlcXVlc3QgaW5zdGFuY2VvZiBIdHRwRW50aXR5RW5jbG9zaW5nUmVxdWVzdCAmJiB0YXJnZXQuZXF1YWxzKCIvc2VydmljZSIpKSB7CisgICAgICAgICAgICAgICAgSHR0cEVudGl0eSBlbnRpdHkgPSAoKEh0dHBFbnRpdHlFbmNsb3NpbmdSZXF1ZXN0KSByZXF1ZXN0KS5nZXRFbnRpdHkoKTsKKyAgICAgICAgICAgICAgICBieXRlW10gZW50aXR5Q29udGVudCA9IEVudGl0eVV0aWxzLnRvQnl0ZUFycmF5KGVudGl0eSk7CisgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJJbmNvbWluZyBjb250ZW50OiAiICsgbmV3IFN0cmluZyhlbnRpdHlDb250ZW50KSk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG91dHB1dCA9IHRoaXMudGhyaWZ0UmVxdWVzdChlbnRpdHlDb250ZW50KTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk91dGdvaW5nIGNvbnRlbnQ6ICIrb3V0cHV0KTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBFbnRpdHlUZW1wbGF0ZSBib2R5ID0gbmV3IEVudGl0eVRlbXBsYXRlKG5ldyBDb250ZW50UHJvZHVjZXIoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhmaW5hbCBPdXRwdXRTdHJlYW0gb3V0c3RyZWFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtV3JpdGVyIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3V0c3RyZWFtLCAiVVRGLTgiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZShvdXRwdXQpOworICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgIGJvZHkuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOworICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEVudGl0eShib2R5KTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisKKyAgICAgICAgICAgICAgICBmaW5hbCBGaWxlIGZpbGUgPSBuZXcgRmlsZSh0aGlzLmRvY1Jvb3QsIFVSTERlY29kZXIuZGVjb2RlKHRhcmdldCkpOworICAgICAgICAgICAgICAgIGlmICghZmlsZS5leGlzdHMoKSkgeworCisgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldFN0YXR1c0NvZGUoSHR0cFN0YXR1cy5TQ19OT1RfRk9VTkQpOworICAgICAgICAgICAgICAgICAgICBFbnRpdHlUZW1wbGF0ZSBib2R5ID0gbmV3IEVudGl0eVRlbXBsYXRlKG5ldyBDb250ZW50UHJvZHVjZXIoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oZmluYWwgT3V0cHV0U3RyZWFtIG91dHN0cmVhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRTdHJlYW1Xcml0ZXIgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvdXRzdHJlYW0sICJVVEYtOCIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZSgiPGh0bWw+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+Cg==