cGFja2FnZSBvcmcuZWNsaXBzZS54dGV4dC54YmFzZS50ZXN0cy5saWIuaW50ZXJuYWwKCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5hbm5vdGF0aW9ucy5BY2Nlc3NvcnMKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5hbm5vdGF0aW9ucy5Ub1N0cmluZwppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQyLmxpYi5TdHJpbmdDb25jYXRlbmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGV4dC54YmFzZS5saWIudXRpbC5Ub1N0cmluZ0J1aWxkZXIKaW1wb3J0IG9yZy5qdW5pdC5UZXN0CgppbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuKgoKQERlcHJlY2F0ZWQKY2xhc3MgVG9TdHJpbmdIZWxwZXJUZXN0IHsKCglAVGVzdCBkZWYgdm9pZCB0ZXN0VG9TdHJpbmcoKSB7CgkJdmFsIGhlbHBlciA9IG5ldyBvcmcuZWNsaXBzZS54dGV4dC54YmFzZS5saWIudXRpbC5Ub1N0cmluZ0hlbHBlcgoJCWFzc2VydEVxdWFscyh0b1VuaXgoCgkJCQknJycKCQlNeUVudGl0eSBbCgkJICBib29sUHJvcCA9IHRydWUKCQkgIGludFByb3AgPSA0MgoJCSAgbXlMaXN0ID0gQXJyYXlMaXN0ICgKCQkgICAgImZvbyIsCgkJICAgICJiYXIiLAoJCSAgICAiYmF6IgoJCSAgKQoJCSAgZnJpZW5kID0gdHJ1ZQoJCSAgNDIKCQkgIFtmb28sIGJhciwgYmF6XQoJCSAgbnVsbAoJCSAgQ0xBU1MKCQkgIHBvbGljeSA9IENMQVNTCgkJXScnJyksIGhlbHBlci50b1N0cmluZyhuZXcgTXlFbnRpdHkobmV3IE15RW50aXR5KSkpCgl9CgoJQFRlc3QgZGVmIHZvaWQgdGVzdFNpbmdsZUxpbmUoKSB7CgkJdmFsIGhlbHBlciA9IG5ldyBUb1N0cmluZ0J1aWxkZXIobmV3IE15RW50aXR5KS5zaW5nbGVMaW5lLmFkZEFsbEZpZWxkcwoKCQlhc3NlcnRFcXVhbHMoCgkJCSdNeUVudGl0eSBbYm9vbFByb3AgPSB0cnVlLCBpbnRQcm9wID0gNDIsIG15TGlzdCA9IEFycmF5TGlzdCAoImZvbyIsImJhciIsImJheiIpLCBmcmllbmQgPSBudWxsLCBwb2xpY3kgPSBDTEFTU10nLAoJCQloZWxwZXIudG9TdHJpbmcoKSkKCX0KCglAVGVzdCBkZWYgdm9pZCB0ZXN0SGlkZUZpZWxkTmFtZXMoKSB7CgkJdmFsIGhlbHBlciA9IG5ldyBUb1N0cmluZ0J1aWxkZXIobmV3IE15RW50aXR5KS5zaW5nbGVMaW5lLmhpZGVGaWVsZE5hbWVzLmFkZEFsbEZpZWxkcwoKCQlhc3NlcnRFcXVhbHMoJ015RW50aXR5IFt0cnVlLCA0MiwgQXJyYXlMaXN0ICgiZm9vIiwiYmFyIiwiYmF6IiksIG51bGwsIENMQVNTXScsIGhlbHBlci50b1N0cmluZygpKQoJfQoKCUBUZXN0IGRlZiB2b2lkIHRlc3RTa2lwTnVsbHMoKSB7CgkJdmFsIGhlbHBlciA9IG5ldyBUb1N0cmluZ0J1aWxkZXIobmV3IE15RW50aXR5KS5za2lwTnVsbHMuYWRkQWxsRmllbGRzCgoJCWFzc2VydEVxdWFscyh0b1VuaXgoCgkJCQknJycKCQlNeUVudGl0eSBbCgkJICBib29sUHJvcCA9IHRydWUKCQkgIGludFByb3AgPSA0MgoJCSAgbXlMaXN0ID0gQXJyYXlMaXN0ICgKCQkgICAgImZvbyIsCgkJICAgICJiYXIiLAoJCSAgICAiYmF6IgoJCSAgKQoJCSAgcG9saWN5ID0gQ0xBU1MKCQldJycnKSwgaGVscGVyLnRvU3RyaW5nKCkpCgl9CgoJQFRlc3QgZGVmIHZvaWQgdGVzdEV4cGxpY2l0RmllbGRMaXN0aW5nKCkgewoJCXZhbCBoZWxwZXIgPSBuZXcgVG9TdHJpbmdCdWlsZGVyKG5ldyBNeUVudGl0eSkuYWRkKCJib29sUHJvcCIsIGZhbHNlKS5hZGRGaWVsZCgiaW50UHJvcCIpCgoJCWFzc2VydEVxdWFscyh0b1VuaXgoCgkJCQknJycKCQlNeUVudGl0eSBbCgkJICBib29sUHJvcCA9IGZhbHNlCgkJICBpbnRQcm9wID0gNDIKCQldJycnKSwgaGVscGVyLnRvU3RyaW5nKCkpCgl9CgoJQFRlc3QgZGVmIHZvaWQgcmVjdXJzaW9uSGFuZGxpbmcoKSB7CgkJdmFsIGhlbHBlciA9IG5ldyBvcmcuZWNsaXBzZS54dGV4dC54YmFzZS5saWIudXRpbC5Ub1N0cmluZ0hlbHBlcgoJCXZhbCBvYmogPSBuZXcgT3RoZXJDbGFzcwoJCW9iai5uYW1lID0gJ2ZvbycKCQlvYmoub3RoZXIgPSBvYmoKCgkJYXNzZXJ0RXF1YWxzKHRvVW5peCgKCQkJCScnJwoJCU90aGVyQ2xhc3MgWwoJCSAgb3RoZXIgPSCrb2JqLnRvU3RyaW5nuwoJCSAgbmFtZSA9ICJmb28iCgkJXScnJyksIGhlbHBlci50b1N0cmluZyhvYmopKQoJfQoKCUBUZXN0IGRlZiB2b2lkIHJlY3Vyc2lvbkhhbmRsaW5nXzAyKCkgewoJCXZhbCBoZWxwZXIgPSBuZXcgb3JnLmVjbGlwc2UueHRleHQueGJhc2UubGliLnV0aWwuVG9TdHJpbmdIZWxwZXIKCQl2YWwgb2JqID0gbmV3IERhdGFDbGFzcygpCgkJb2JqLm90aGVyID0gb2JqCgkJb2JqLm5hbWUgPSAidGVzdCIKCQlhc3NlcnRFcXVhbHModG9Vbml4KAoJCQkJJycnCgkJRGF0YUNsYXNzIFsKCQkgIG90aGVyID0gRGF0YUNsYXNzQKtTeXN0ZW06OmlkZW50aXR5SGFzaENvZGUob2JqKbsKCQkgIG5hbWUgPSAidGVzdCIKCQldJycnKSwgaGVscGVyLnRvU3RyaW5nKG9iaikpCgl9CgoJc3RhdGljIGNsYXNzIE90aGVyQ2xhc3MgewoJCXB1YmxpYyBPdGhlckNsYXNzIG90aGVyCgkJcHVibGljIFN0cmluZyBuYW1lCgl9CgoJQEFjY2Vzc29ycyBAVG9TdHJpbmcgc3RhdGljIGNsYXNzIERhdGFDbGFzcyB7CgkJcHVibGljIERhdGFDbGFzcyBvdGhlcgoJCXB1YmxpYyBTdHJpbmcgbmFtZQoJfQoKCXN0YXRpYyBjbGFzcyBNeUVudGl0eSB7CgkJdmFsIGJvb2xQcm9wID0gdHJ1ZQoJCXZhbCBpbnRQcm9wID0gNDIKCQl2YWwgbXlMaXN0ID0gbmV3QXJyYXlMaXN0KCdmb28nLCAnYmFyJywgJ2JheicpCgkJdmFsIE15RW50aXR5IGZyaWVuZAoJCXZhbCBSZXRlbnRpb25Qb2xpY3kgcG9saWN5ID0gUmV0ZW50aW9uUG9saWN5OjpDTEFTUwoKCQluZXcoKSB7CgkJCXRoaXMuZnJpZW5kID0gbnVsbAoJCX0KCgkJbmV3KE15RW50aXR5IGZyaWVuZCkgewoJCQl0aGlzLmZyaWVuZCA9IGZyaWVuZDsKCQl9CgoJCW92ZXJyaWRlIHRvU3RyaW5nKCkgewoJCQlyZXR1cm4gYm9vbFByb3AgKyAnXG4nICsgaW50UHJvcCArICdcbicgKyBteUxpc3QgKyAnXG4nICsgZnJpZW5kICsgJ1xuJyArIHBvbGljeQoJCX0KCX0KCglkZWYgc3RhdGljIFN0cmluZyB0b1VuaXgoU3RyaW5nIHMpIHsKCQl2YXIgU3RyaW5nQ29uY2F0ZW5hdGlvbiByZXN1bHQgPSBuZXcgU3RyaW5nQ29uY2F0ZW5hdGlvbigiXG4iKQoJCXJlc3VsdC5hcHBlbmQocykKCQlyZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCkKCX0KfQo=