LyoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICRTb3VyY2U6IC94c3JsL05zdm4vaWN1L3VuaWNvZGV0b29scy9jb20vaWJtL3RleHQvVUNEL1Rlc3REYXRhLmphdmEsdiAkCiogJERhdGU6IDIwMDYvMDQvMDUgMjI6MTI6NDMgJAoqICRSZXZpc2lvbjogMS4yNSAkCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKcGFja2FnZSBjb20uaWJtLnRleHQuVUNEOwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5pby4qOwppbXBvcnQgamF2YS50ZXh0LkRhdGVGb3JtYXQ7CmltcG9ydCBqYXZhLnRleHQuU2ltcGxlRGF0ZUZvcm1hdDsKCmltcG9ydCBjb20uaWJtLmljdS5kZXYudGVzdC51dGlsLkJhZ0Zvcm1hdHRlcjsKaW1wb3J0IGNvbS5pYm0uaWN1LmRldi50ZXN0LnV0aWwuSUNVUHJvcGVydHlGYWN0b3J5OwppbXBvcnQgY29tLmlibS5pY3UuZGV2LnRlc3QudXRpbC5Vbmljb2RlTGFiZWw7CmltcG9ydCBjb20uaWJtLmljdS5kZXYudGVzdC51dGlsLlVuaWNvZGVNYXA7CmltcG9ydCBjb20uaWJtLmljdS5kZXYudGVzdC51dGlsLlVuaWNvZGVQcm9wZXJ0eTsKaW1wb3J0IGNvbS5pYm0uaWN1LmltcGwuQ29sbGVjdGlvblV0aWxpdGllczsKaW1wb3J0IGNvbS5pYm0uaWN1LmltcGwuSUNVRGF0YTsKaW1wb3J0IGNvbS5pYm0uaWN1LmltcGwuSUNVUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBjb20uaWJtLmljdS5pbXBsLlVDaGFyQXJyYXlJdGVyYXRvcjsKaW1wb3J0IGNvbS5pYm0uaWN1LmxhbmcuVUNoYXJhY3RlcjsKaW1wb3J0IGNvbS5pYm0uaWN1LnRleHQuTnVtYmVyRm9ybWF0OwppbXBvcnQgY29tLmlibS5pY3UudGV4dC5TdHJpbmdQcmVwOwppbXBvcnQgY29tLmlibS5pY3UudGV4dC5TdHJpbmdQcmVwUGFyc2VFeGNlcHRpb247CmltcG9ydCBjb20uaWJtLmljdS51dGlsLkN1cnJlbmN5OwppbXBvcnQgY29tLmlibS5pY3UudXRpbC5VTG9jYWxlOwoKaW1wb3J0IGphdmEubWF0aC5CaWdEZWNpbWFsOwoKaW1wb3J0IGphdmEudXRpbC5yZWdleC4qOwoKaW1wb3J0IGNvbS5pYm0uaWN1LnRleHQuKjsKaW1wb3J0IGNvbS5pYm0udGV4dC51dGlsaXR5Lio7CgpwdWJsaWMgY2xhc3MgVGVzdERhdGEgaW1wbGVtZW50cyBVQ0RfVHlwZXMgewogICAgCiAgICBzdGF0aWMgVW5pY29kZVByb3BlcnR5LkZhY3RvcnkgdXBmOwogICAgCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQl0cnlDb25zb2xlMigpOwoJCWlmICh0cnVlKSByZXR1cm47CgkJCgkJc2hvd05vbkNvbXBhdEZ1bGwoZmFsc2UpOwoJCXNob3dOb25Db21wYXRGdWxsKHRydWUpOwoJCQoKCQljaGVja0ZvckNhc2VTdGFiaWxpdHkoZmFsc2UpOwoJCS8vY291bnRDaGFycygpOwoJCWZvbygpOwogICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJtYWluOiAiICsgRGVmYXVsdC5nZXREYXRlKCkpOwogICAgICAgIHVwZiA9IElDVVByb3BlcnR5RmFjdG9yeS5tYWtlKCk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJhZnRlciBmYWN0b3J5OiAiICsgRGVmYXVsdC5nZXREYXRlKCkpOwogCiAgICAgICAgc2hvd1Byb3BEaWZmKAogICAgICAgICAgICAiZ2M9bW4iLCBudWxsLAogICAgICAgICAgICAic2NyaXB0PWluaGVyaXRlZCIsIG51bGwpOwogICAgICAgICAgICAKICAgICAgICAvLyB1cGYuZ2V0UHJvcGVydHkoImdjIikKICAgICAgICAvLy5nZXRQcm9wZXJ0eVNldChuZXcgSUNVUHJvcGVydHlGYWN0b3J5LlJlZ2V4TWF0Y2hlcigibW58bWUiKSxudWxsKQogICAgICAgIAogICAgICAgIHNob3dQcm9wRGlmZigKICAgICAgICAiZ2M9bW58bWUiLCBudWxsLAogICAgICAgICJzY3JpcHQ9aW5oZXJpdGVkIiwgbnVsbCk7CgogICAgICAgIGlmICh0cnVlKSByZXR1cm47CgogICAgICAgIHNob3dQcm9wRGlmZigKICAgICAgICAgICAgIkdlbmVyYWxfQ2F0ZWdvcnk9TCIsIG51bGwsCiAgICAgICAgICAgICJTY3JpcHQhPUluaGVyaXRlZHxDb21tb24iLCAKICAgICAgICAgICAgICAgIHVwZi5nZXRTZXQoInNjcmlwdD1pbmhlcml0ZWQiKQogICAgICAgICAgICAgICAgLmFkZEFsbChVbmlmaWVkQmluYXJ5UHJvcGVydHkuZ2V0U2V0KCJzY3JpcHQ9Y29tbW9uIiwgRGVmYXVsdC51Y2QoKSkpCiAgICAgICAgICAgICAgICAuY29tcGxlbWVudCgpCiAgICAgICAgKTsKICAgICAgIAogICAgICAgIAogICAgICAgIFVuaWNvZGVTZXQgc3Rlcm0gPSBVbmlmaWVkUHJvcGVydHkuZ2V0U2V0KCJTVGVybSIsIERlZmF1bHQudWNkKCkpOwogICAgICAgIFVuaWNvZGVTZXQgdGVybSA9IFVuaWZpZWRQcm9wZXJ0eS5nZXRTZXQoIlRlcm1pbmFsX1B1bmN0dWF0aW9uIiwgRGVmYXVsdC51Y2QoKSk7CiAgICAgICAgVW5pY29kZVNldCBwbyA9IG5ldyBVbmljb2RlU2V0KCJbOnBvOl0iKTsKICAgICAgICBVbmljb2RlU2V0IGVtcHR5ID0gbmV3IFVuaWNvZGVTZXQoKTsKICAgICAgICAKICAgICAgICBVdGlsaXR5LnNob3dTZXREaWZmZXJlbmNlcygKICAgICAgICAgICAgIlNlbnRlbmNlX1Rlcm1pbmFsIiwgc3Rlcm0sIAogICAgICAgICAgICAiRW1wdHkiLCBlbXB0eSwgCiAgICAgICAgICAgIHRydWUsIERlZmF1bHQudWNkKCkpOwoKICAgICAgICBVdGlsaXR5LnNob3dTZXREaWZmZXJlbmNlcygKICAgICAgICAgICAgIlNlbnRlbmNlX1Rlcm1pbmFsIiwgc3Rlcm0sIAogICAgICAgICAgICAiVGVybWluYWxfUHVuY3R1YXRpb24iLCB0ZXJtLCAKICAgICAgICAgICAgdHJ1ZSwgRGVmYXVsdC51Y2QoKSk7CgogICAgICAgIFV0aWxpdHkuc2hvd1NldERpZmZlcmVuY2VzKAogICAgICAgICAgICAiVGVybWluYWxfUHVuY3R1YXRpb24iLCB0ZXJtLCAKICAgICAgICAgICAgIlB1bmN0dWF0aW9uX090aGVyIiwgcG8sIAogICAgICAgICAgICB0cnVlLCBEZWZhdWx0LnVjZCgpKTsKICAgICAgICAKICAgICAgICBpZiAodHJ1ZSkgcmV0dXJuOwogICAgICAgIAogICAgICAgIFVuaWNvZGVTZXQgdXMgPSBnZXRTZXRGb3JOYW1lKCJMQVRJTiBMRVRURVIuKlAiKTsKICAgICAgICBVdGlsaXR5LnNob3dTZXROYW1lcygiIix1cyxmYWxzZSxEZWZhdWx0LnVjZCgpKTsKICAgICAgICAKICAgICAgICB1cyA9IGdldFNldEZvck5hbWUoIi4qVkFSSUEoVElPTnxOVCkuKiIpOwogICAgICAgIFV0aWxpdHkuc2hvd1NldE5hbWVzKCIiLHVzLGZhbHNlLERlZmF1bHQudWNkKCkpOwogICAgICAgCiAgICAgICAgaWYgKHRydWUpIHJldHVybjsKICAgICAgICAKICAgICAgICAvKnNob3dTZXQoKTsKICAgICAgICAqLwogICAgICAgIFN0cmluZyB4ID0gIltbWzpzOl1bOnA6XSZbOmFzY2lpOl1dIHwgW1xcdTIxOTAtXFx1MkJGRl0gfCAiCiAgICAgICAgKyAiW1s6czpdWzpwOl0iCiAgIC8vICAgICArICImWzpkZWNvbXBvc2l0aW9udHlwZT1ub25lOl0iCiAgIC8vICsgIi0gWzppZF9jb250aW51ZTpdIgogICAgICAgICsgIi1bOnNrOl0iCiAgICAgICAgKyAiXV0iOwogICAgICAgIFByaW50V3JpdGVyIHB3ID0gVXRpbGl0eS5vcGVuUHJpbnRXcml0ZXIoIlN5bnRheC50eHQiLCBVdGlsaXR5LlVURjhfV0lORE9XUyk7CiAgICAgICAgc2hvd1NldChwdywgeCwgZmFsc2UpOwogICAgICAgIHNob3dTZXQocHcsICJbW1xcdTIwMDAtXFx1MjA1Rl0tIiArIHggKyAiXSIsIHRydWUpOwogICAgICAgIHNob3dTZXQocHcsICJbWzp3aGl0ZXNwYWNlOl0mWzpkZWNvbXBvc2l0aW9udHlwZT1ub25lOl1dIiwgZmFsc2UpOwogICAgICAgIHB3LmNsb3NlKCk7CiAgICAgICAgCiAgICAgICAgaWYgKHRydWUpIHJldHVybjsKCQkKCQl0ZXN0Rm9ybWF0SGFjaygpOwoJCWlmICh0cnVlKSByZXR1cm47CgkJdGVzdENvbnZlcnRUb0JERCgpOwoJCWlmICh0cnVlKSByZXR1cm47CgkJCgkJU3lzdGVtLm91dC5wcmludGxuKCJTaGlmdDogIiArIFNISUZUICsgIiwgTWFzazogIiArIExvbmcudG9IZXhTdHJpbmcoTUFTSykpOwoJCXNob3dOdW1iZXIoLTUpOwoJCXNob3dOdW1iZXIoMCk7CgkJc2hvd051bWJlcig1KTsKCQlzaG93TnVtYmVyKDUwMCk7CgkJc2hvd051bWJlcig1MDAwMDAwKTsKCQlpZiAodHJ1ZSkgcmV0dXJuOwoJCQoJCVN0cmluZyBzY3JpcHQgPSBhcmdzWzBdOwoJCVByaW50V3JpdGVyIGxvZyA9IFV0aWxpdHkub3BlblByaW50V3JpdGVyKCJUcmFuc2xpdFNrZWxldG9uXyIgKyBzY3JpcHQgKyAiLnR4dCIsIFV0aWxpdHkuVVRGOF9XSU5ET1dTKTsKCQl0cnkgewoJCQlVbmljb2RlU2V0IGJhc2UgPSBuZXcgVW5pY29kZVNldCgiWzoiICsgc2NyaXB0ICsgIjpdIik7CgkJCVVuaWNvZGVTZXRJdGVyYXRvciBpdCA9IG5ldyBVbmljb2RlU2V0SXRlcmF0b3IoYmFzZSk7CgkJCXdoaWxlIChpdC5uZXh0KCkpIHsKCQkJCVN0cmluZyBzID0gVVRGMTYudmFsdWVPZihpdC5jb2RlcG9pbnQpOwoJCQkJU3RyaW5nIG5vcm0gPSBEZWZhdWx0Lm5mZCgpLm5vcm1hbGl6ZShzKTsKCQkJCWlmIChzLmVxdWFscyhub3JtKSAmJiBEZWZhdWx0Lm5ma2QoKS5pc05vcm1hbGl6ZWQobm9ybSkpIHsKCQkJCQlsb2cucHJpbnRsbigiIyAiICsgcyArICIgPD4gWFhYICMgIiArIERlZmF1bHQudWNkKCkuZ2V0TmFtZShpdC5jb2RlcG9pbnQpKTsKCQkJCX0KCQkJfQoJCX0gZmluYWxseSB7CgkJCWxvZy5jbG9zZSgpOwoJCQkJfQoJfQoJCglwcml2YXRlIHN0YXRpYyB2b2lkIHNob3dOb25Db21wYXRGdWxsKGJvb2xlYW4gY29tcGF0KSB7CgkJVUNEIHVjZCA9IFVDRC5tYWtlKCI0LjEuMCIpOwoJCU5vcm1hbGl6ZXIgbmZrYyA9IG5ldyBOb3JtYWxpemVyKE5vcm1hbGl6ZXIuTkZLQywgdWNkLmdldFZlcnNpb24oKSk7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJU3lzdGVtLm91dC5wcmludGxuKGNvbXBhdCA/ICJGdWxsIEZvbGQgPSBTaW1wbGUgTG93ZXIgb2YgTkZLQyIgOiAiRnVsbCBGb2xkICE9IFNpbXBsZSBMb3dlciBvZiBORktDIik7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJaW50IGNvdW50ID0gMDsKCQlmb3IgKGludCBpID0gMDsgaSA8PSAweDEwRkZGRjsgKytpKSB7CgkJCWludCBnYyA9IHVjZC5nZXRDYXRlZ29yeShpKTsKCQkJaWYgKGdjID09IENuIHx8IGdjID09IFBSSVZBVEVfVVNFKSBjb250aW51ZTsKCQkJLy9pZiAoY29tcGF0ID09ICh1Y2QuZ2V0RGVjb21wb3NpdGlvblR5cGUoaSkgPiBVQ0QuQ0FOT05JQ0FMKSkgY29udGludWU7CgkJCVN0cmluZyBzdHIgPSBVVEYxNi52YWx1ZU9mKGkpOwoJCQlTdHJpbmcgc2ltcGxlTG93ZXIgPSB1Y2QuZ2V0Q2FzZShzdHIsIFNJTVBMRSwgTE9XRVIpOwoJCQlTdHJpbmcgZnVsbEZvbGQgPSB1Y2QuZ2V0Q2FzZShzdHIsIEZVTEwsIEZPTEQpOwoJCQkKCQkJaWYgKCFzaW1wbGVMb3dlci5lcXVhbHMoZnVsbEZvbGQpKSB7CgkJCQlTdHJpbmcgbmZrY1N0ciA9IG5ma2Mubm9ybWFsaXplKHN0cik7CgkJCQlTdHJpbmcgc2ltcGxlTG93ZXJOZmtjID0gdWNkLmdldENhc2UobmZrY1N0ciwgU0lNUExFLCBMT1dFUik7CgkJCQlpZiAoY29tcGF0ICE9IChmdWxsRm9sZC5lcXVhbHMoc2ltcGxlTG93ZXJOZmtjKSkpIGNvbnRpbnVlOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKHVjZC5nZXRDb2RlQW5kTmFtZShpKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0U2ltcGxlIExvd2VyOlx0IiArIHVjZC5nZXRDb2RlQW5kTmFtZShzaW1wbGVMb3dlcikpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJcdEZ1bGwgRm9sZDpcdCIgKyB1Y2QuZ2V0Q29kZUFuZE5hbWUoZnVsbEZvbGQpKTsKCQkJCWNvdW50Kys7CgkJCX0KCQl9CgkJU3lzdGVtLm91dC5wcmludGxuKCJDb3VudDpcdCIgKyBjb3VudCk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgdm9pZCB0cnlDb25zb2xlKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gewoJCWZvciAoaW50IGkgPSAxOyBpIDwgMHhGRkZGOyArK2kpIHsKCQkJU3RyaW5nIHMgPSBVVEYzMi52YWx1ZU9mMzIoaSk7CgkJCWJ5dGVbXSBieXRlcyA9IHMuZ2V0Qnl0ZXMoIlVURi04Iik7CgkJCVN0cmluZyB1dGY4Ynl0ZXMgPSAiIjsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBieXRlcy5sZW5ndGg7ICsraikgewoJCQkJaWYgKGogIT0gMCkgdXRmOGJ5dGVzICs9ICIgIjsKCQkJCXV0ZjhieXRlcyArPSBVdGlsaXR5LmhleChieXRlc1tqXSYweEZGLDIpOwoJCQl9CgkJCVN0cmluZyBuYW1lID0gVUNoYXJhY3Rlci5nZXRFeHRlbmRlZE5hbWUoaSk7CgkJCVN5c3RlbS5vdXQucHJpbnRsbihVdGlsaXR5LmhleChpKSArICJcdCgiICsgcyArICIpXHRbIiArIHV0ZjhieXRlcyArICJdXHQiICsgbmFtZSk7CgkJfQoJfQoJCglwcml2YXRlIHN0YXRpYyB2b2lkIHRyeUNvbnNvbGUyKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gewoJCVVuaWNvZGVTZXQgZmFpbHVyZXMgPSBuZXcgVW5pY29kZVNldCgpOwoJCWNoZWNrOgoJCWZvciAoaW50IGkgPSAxOyBpIDw9IDB4MTBGRkZGOyArK2kpIHsKCQkJU3RyaW5nIHMgPSBVVEYzMi52YWx1ZU9mMzIoaSk7CgkJCWJ5dGVbXSBieXRlcyA9IHMuZ2V0Qnl0ZXMoIlVURi04Iik7CgkJCWZvciAoaW50IGogPSAwOyBqIDwgYnl0ZXMubGVuZ3RoOyArK2opIHsKCQkJCXN3aXRjaCAoYnl0ZXNbal0mMHhGRikgewoJCQkJY2FzZSAweDgxOiBjYXNlIDB4OEQ6IGNhc2UgMHg4RjogY2FzZSAweDkwOiBjYXNlIDB4OUQ6CgkJCQkJZmFpbHVyZXMuYWRkKGkpOwoJCQkJCWNvbnRpbnVlIGNoZWNrOwoJCQkJfQoJCQl9CgkJfQoJCVN5c3RlbS5vdXQucHJpbnRsbigiVG90YWwgY29ycnVwdGVkIGNoYXJhY3RlcnM6ICIgKyBmYWlsdXJlcy5zaXplKCkpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiUGVyY2VudCBjb3JydXB0ZWQgY2hhcmFjdGVyczogIiArICgoZmFpbHVyZXMuc2l6ZSgpICsgMC4wKSAvIDB4MTEwMDAwICogMTAwLjAgKyAiJSIpKTsKCQkvL0JhZ0Zvcm1hdHRlciBiZiA9IG5ldyBCYWdGb3JtYXR0ZXIoKTsKCQkvL1N5c3RlbS5vdXQucHJpbnRsbihiZi5zaG93U2V0TmFtZXMoZmFpbHVyZXMpKTsKCX0KCgoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBjb3VudENoYXJzKCkgewoJCWludFtdW10gY291bnQgPSBuZXcgaW50W0FHRV9WRVJTSU9OUy5sZW5ndGhdWzUwXTsKCQlmb3IgKGludCBqID0gMTsgaiA8IEFHRV9WRVJTSU9OUy5sZW5ndGg7ICsraikgewoJCQlVQ0QgdWNkID0gVUNELm1ha2UoQUdFX1ZFUlNJT05TW2pdKTsKCQkJVUNEUHJvcGVydHkgYWxwaGEgPSBEZXJpdmVkUHJvcGVydHkubWFrZSh1Y2QuUHJvcEFscGhhYmV0aWMsIHVjZCk7CgoJCQlpbnQgYWxwaGFDb3VudCA9IDA7CgkJCWZvciAoaW50IGkgPSAwOyBpIDw9MHgxMEZGRkY7ICsraSkgewoJCQkJaW50IHR5cGUgPSB1Y2QuZ2V0Q2F0ZWdvcnkoaSk7CgkJCQlpZiAodWNkLmlzTm9uY2hhcmFjdGVyKGkpKSB0eXBlID0gTElNSVRfQ0FURUdPUlk7CgkJCQkrK2NvdW50W2pdW3R5cGVdOwoJCQkJaWYgKGFscGhhLmhhc1ZhbHVlKGkpIHx8IHR5cGUgPT0gdWNkLk5kKSArK2NvdW50W2pdW0xJTUlUX0NBVEVHT1JZKzFdOwoJCQl9CgkJfQoKCQlmb3IgKGJ5dGUgaSA9IC0xOyBpIDwgTElNSVRfQ0FURUdPUlkrMjsgKytpKSB7CgkJCXN3aXRjaChpKSB7CgkJCWNhc2UgLTE6IFN5c3RlbS5vdXQucHJpbnQoIlx0XHQiKTsgYnJlYWs7CgkJCWRlZmF1bHQ6IFN5c3RlbS5vdXQucHJpbnQoVUNELmdldENhdGVnb3J5SURfZnJvbUluZGV4KGksVUNELkxPTkcpICsgIlx0IiArIFVDRC5nZXRDYXRlZ29yeUlEX2Zyb21JbmRleChpKSk7IGJyZWFrOwoJCQljYXNlIExJTUlUX0NBVEVHT1JZOiBTeXN0ZW0ub3V0LnByaW50KCJOb25jaGFyYWN0ZXIiICsgIlx0IiArICJOQ0NQIik7IGJyZWFrOwoJCQljYXNlIExJTUlUX0NBVEVHT1JZKzE6IFN5c3RlbS5vdXQucHJpbnQoIkFscGhhYmV0aWMiICsgIlx0IiArICJhbHBoYSIpOyBicmVhazsKCQkJfQoJCQlmb3IgKGludCBqID0gMTsgaiA8IEFHRV9WRVJTSU9OUy5sZW5ndGg7ICsraikgewoJCQkJaWYgKGkgPCAwKSBTeXN0ZW0ub3V0LnByaW50KCJcdCoiICsgQUdFX1ZFUlNJT05TW2pdICsgIioiKTsKCQkJCWVsc2UgU3lzdGVtLm91dC5wcmludCgiXHQiICsgY291bnRbal1baV0pOwoJCQl9CgkJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJCX0KCgl9CgoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBmb28oKSB7CgkJU3RyaW5nW10gdGVzdCA9IHsKCQkJCSJ2aWNlcHJlc2lkZW50IiwKCQkJCSJ2aWNlIHByZXNpZGVudCIsCgkJCQkidmljZS1wcmVzaWRlbnQiLAoJCQkJInZpY2UtcHLpc2lkZW50IiwKCQkJCSJ2aWNlLXByZXNpZGVudCdzIG9mZmljZXMiLAoJCQkJInZpY2UtcHJlc2lkZW50cycgb2ZmaWNlcyIsCgkJCQkidmljZS1wcmVzaWRlbnRzIG9mZmljZXMiLAoJCQkJInZpY2UtcHJlc2lkZW50c29mZmljZXMiLAoJCX07CgkJUnVsZUJhc2VkQ29sbGF0b3IgY29sID0gKFJ1bGVCYXNlZENvbGxhdG9yKSBDb2xsYXRvci5nZXRJbnN0YW5jZShuZXcgVUxvY2FsZSgiZnIiKSk7CgkJY29sLnNldFN0cmVuZ3RoKGNvbC5RVUFURVJOQVJZKTsKCQljb2wuc2V0QWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkKGZhbHNlKTsKCgkJQXJyYXlzLnNvcnQodGVzdCwgY29sKTsKCQlMaXN0IHMgPSBBcnJheXMuYXNMaXN0KHRlc3QpOwoJCVN0cmluZyBsYXN0ID0gIiI7CgkJaW50W10gbGV2ZWwgPSBuZXcgaW50WzFdOwoJCWZvciAoSXRlcmF0b3IgaXQgPSBzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKCQkJU3RyaW5nIGN1cnJlbnQgPSAoU3RyaW5nKSBpdC5uZXh0KCk7CgkJCWludCBvcmRlciA9IGxldmVsQ29tcGFyZShjb2wsIGxhc3QsIGN1cnJlbnQsIGxldmVsKTsKCQkJLy9TeXN0ZW0ub3V0LnByaW50KGxldmVsU3RyaW5nc1tsZXZlbFswXV0pOwoJCQkvL1N5c3RlbS5vdXQucHJpbnQob3JkZXIgPCAwID8gIjwiIDogb3JkZXIgPT0gMCA/ICI9IiA6ICI+Iik7CgkJCVN5c3RlbS5vdXQucHJpbnRsbigiXHQiICsgY3VycmVudCk7CgkJCWxhc3QgPSBjdXJyZW50OwoJCX0KCQlmb3IgKGludCBpID0gMDsgaSA8IHRlc3QubGVuZ3RoOyArK2kpIHsKCQkJU3lzdGVtLm91dC5wcmludCh0ZXN0W2ldICsgIjsiKTsKCQl9CgkJU3lzdGVtLm91dC5wcmludGxuKCk7Cgl9CgkKCXN0YXRpYyBTdHJpbmdbXSBsZXZlbFN0cmluZ3MgPSB7Ii4iLCAiLi4iLCAiLi4uIiwgIi4uLi4iLCAiLi4uLi4ifTsKCQoJc3RhdGljIGludCBsZXZlbENvbXBhcmUoUnVsZUJhc2VkQ29sbGF0b3IgY29sLCBTdHJpbmcgYSwgU3RyaW5nIGIsIGludFtdIGxldmVsKSB7CgkJaW50IGRpZmYgPSAwOwoJCWxldmVsWzBdID0gMDsKCQlmb3IgKGludCBpID0gMDsgaSA8IDE1OyArK2kpIHsKCQkJY29sLnNldFN0cmVuZ3RoKGkpOwoJCQlkaWZmID0gY29sLmNvbXBhcmUoYSwgYik7CgkJCWlmIChkaWZmICE9IDApIHsKCQkJCWxldmVsWzBdID0gaTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXJldHVybiBkaWZmOwoJfQoKCU1hdGNoZXIgbTsKCQoJLyoqCgkgKiBAcGFyYW0gaW5idWZmZXIKCSAqIEBwYXJhbSBvdXRidWZmZXIKCSAqIEByZXR1cm4KCSAqLwoJcHVibGljIHN0YXRpYyBib29sZWFuIGVxdWFscyhTdHJpbmdCdWZmZXIgaW5idWZmZXIsIFN0cmluZ0J1ZmZlciBvdXRidWZmZXIpIHsKCQlpZiAoaW5idWZmZXIubGVuZ3RoKCkgIT0gb3V0YnVmZmVyLmxlbmd0aCgpKSByZXR1cm4gZmFsc2U7CgkJZm9yIChpbnQgaSA9IGluYnVmZmVyLmxlbmd0aCgpIC0gMTsgaSA+PSAwOyAtLWkpIHsKCQkJaWYgKGluYnVmZmVyLmNoYXJBdChpKSAhPSBvdXRidWZmZXIuY2hhckF0KGkpKSByZXR1cm4gZmFsc2U7CgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCXByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tGb3JDYXNlU3RhYmlsaXR5KGJvb2xlYW4gbWVyZ2VSYW5nZXMpIHsKCQlVQ0QgdWNkID0gRGVmYXVsdC51Y2QoKTsKCQlUb29sVW5pY29kZVByb3BlcnR5U291cmNlIHVwcyA9IFRvb2xVbmljb2RlUHJvcGVydHlTb3VyY2UubWFrZSgiIik7CgkJVW5pY29kZVNldCBwcm9wVXBwZXJjYXNlID0gdXBzLmdldFNldCgiVXBwZXJjYXNlPXRydWUiKTsKCQlVbmljb2RlU2V0IHByb3BMb3dlcmNhc2UgPSB1cHMuZ2V0U2V0KCJMb3dlcmNhc2U9dHJ1ZSIpOwoJCVVuaWNvZGVTZXQgaXNHY0x0ID0gdXBzLmdldFNldCgiZ2M9THQiKTsKCQlVbmljb2RlU2V0IG90aGVyQWxwaGFiZXRpYyA9IHVwcy5nZXRTZXQoIkFscGhhYmV0aWM9dHJ1ZSIpLmFkZEFsbCh1cHMuZ2V0U2V0KCJnYz1TayIpKTsKCQkvLyBjcmVhdGUgdGhlIGZvbGxvd2luZwoJCVVuaWNvZGVTZXQgaGFzRm9sZCA9IG5ldyBVbmljb2RlU2V0KCk7CgkJVW5pY29kZVNldCBoYXNVcHBlciA9IG5ldyBVbmljb2RlU2V0KCk7CgkJVW5pY29kZVNldCBoYXNMb3dlciA9IG5ldyBVbmljb2RlU2V0KCk7CgkJVW5pY29kZVNldCBoYXNUaXRsZSA9IG5ldyBVbmljb2RlU2V0KCk7CgkJVW5pY29kZVNldCBjb21wYXQgPSBuZXcgVW5pY29kZVNldCgpOwoJCVVuaWNvZGVTZXQgYmljYW1lcmFsc1NjcmlwdHMgPSBuZXcgVW5pY29kZVNldCgpOwoJCQoJCVVuaWNvZGVTZXQgaXNGVXBwZXJjYXNlID0gbmV3IFVuaWNvZGVTZXQoKTsKCQlVbmljb2RlU2V0IGlzRkxvd2VyY2FzZSA9IG5ldyBVbmljb2RlU2V0KCk7CgkJVW5pY29kZVNldCBpc0ZUaXRsZWNhc2UgPSBuZXcgVW5pY29kZVNldCgpOwoKCQlVQ0QgdTQwID0gVUNELm1ha2UoIjQuMC4wIik7CgkJQml0U2V0IHNjcmlwdHMgPSBuZXcgQml0U2V0KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPD0gMHgxMEZGRkY7ICsraSkgewoJCQlpbnQgZ2MgPSB1Y2QuZ2V0Q2F0ZWdvcnkoaSk7CgkJCWlmIChnYyA9PSBDbiB8fCBnYyA9PSBQUklWQVRFX1VTRSkgY29udGludWU7CgkJCVN0cmluZyBzdHIgPSBVVEYxNi52YWx1ZU9mKGkpOwoJCQlpZiAoIXN0ci5lcXVhbHModWNkLmdldENhc2Uoc3RyLCBGVUxMLCBGT0xEKSkpIHsKCQkJCWhhc0ZvbGQuYWRkKGkpOwoJCQkJc2NyaXB0cy5zZXQodWNkLmdldFNjcmlwdChpKSk7CgkJCX0KCQkJaWYgKCFzdHIuZXF1YWxzKHVjZC5nZXRDYXNlKHN0ciwgRlVMTCwgVVBQRVIpKSkgewoJCQkJaGFzVXBwZXIuYWRkKGkpOwoJCQkJc2NyaXB0cy5zZXQodWNkLmdldFNjcmlwdChpKSk7CgkJCX0gZWxzZSB7CgkJCQlpc0ZVcHBlcmNhc2UuYWRkKGkpOwoJCQl9CgkJCWlmICghc3RyLmVxdWFscyh1Y2QuZ2V0Q2FzZShzdHIsIEZVTEwsIExPV0VSKSkpIHsKCQkJCWhhc0xvd2VyLmFkZChpKTsKCQkJCXNjcmlwdHMuc2V0KHVjZC5nZXRTY3JpcHQoaSkpOwoJCQl9IGVsc2UgewoJCQkJaXNGTG93ZXJjYXNlLmFkZChpKTsKCQkJfQoJCQlpZiAoIXN0ci5lcXVhbHModWNkLmdldENhc2Uoc3RyLCBGVUxMLCBUSVRMRSkpKSB7CgkJCQloYXNUaXRsZS5hZGQoaSk7CgkJCQlzY3JpcHRzLnNldCh1Y2QuZ2V0U2NyaXB0KGkpKTsKCQkJfSBlbHNlIHsKCQkJCWlzRlRpdGxlY2FzZS5hZGQoaSk7CgkJCX0KCQkJaWYgKCFzdHIuZXF1YWxzKERlZmF1bHQubmZrZCgpLm5vcm1hbGl6ZShzdHIpKSkgY29tcGF0LmFkZChpKTsKCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4odWNkLmdldENvZGVBbmROYW1lKGkpICsgIlx0IiArICh1NDAuaXNBbGxvY2F0ZWQoaSkgPyAiYWxyZWFkeSBpbiA0LjAiIDogIm5ldyBpbiA0LjEiKSk7CgkJfQoJCUJhZ0Zvcm1hdHRlciBiZiA9IG5ldyBCYWdGb3JtYXR0ZXIoKTsKCQlUcmFuc2xpdGVyYXRvciBudWxsVHJhbnMgPSBUcmFuc2xpdGVyYXRvci5nZXRJbnN0YW5jZSgibnVsbCIpOwoJCWJmLnNldFNob3dMaXRlcmFsKG51bGxUcmFucyk7CgkJYmYuc2V0TWVyZ2VSYW5nZXMobWVyZ2VSYW5nZXMpOwoJCWJmLnNldFVuaWNvZGVQcm9wZXJ0eUZhY3RvcnkodXBzKTsKCQkKCQlVbmljb2RlU2V0IGFsbENhc2VkID0gbmV3IFVuaWNvZGVTZXQoKS5hZGRBbGwoaGFzVXBwZXIpLmFkZEFsbChoYXNMb3dlcikuYWRkQWxsKGhhc1RpdGxlKTsKCQlpc0ZVcHBlcmNhc2UucmV0YWluQWxsKGFsbENhc2VkKTsKCQlpc0ZMb3dlcmNhc2UucmV0YWluQWxsKGFsbENhc2VkKTsKCQlpc0ZUaXRsZWNhc2UucmV0YWluQWxsKGFsbENhc2VkKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oVXRpbGl0eS5CT00pOwoKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJVcHBlcmNhc2U9dHJ1ZSBvciBnYz1MdCB3aXRob3V0IGhhc0xvd2VyIiwgCgkJCQluZXcgVW5pY29kZVNldChwcm9wVXBwZXJjYXNlKS5hZGRBbGwoaXNHY0x0KS5yZW1vdmVBbGwoaGFzTG93ZXIpKTsKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJoYXNMb3dlciwgYnV0IG5vdCAoVXBwZXJjYXNlPXRydWUgb3IgZ2M9THQpIiwgCgkJCQluZXcgVW5pY29kZVNldChoYXNMb3dlcikucmVtb3ZlQWxsKGlzR2NMdCkucmVtb3ZlQWxsKHByb3BVcHBlcmNhc2UpKTsKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJMb3dlcmNhc2U9dHJ1ZSB3aXRob3V0IGhhc1VwcGVyIiwgCgkJCQluZXcgVW5pY29kZVNldChwcm9wTG93ZXJjYXNlKS5hZGRBbGwoaXNHY0x0KS5yZW1vdmVBbGwoaGFzVXBwZXIpKTsKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJoYXNVcHBlciwgYnV0IG5vdCAoTG93ZXJjYXNlPXRydWUgb3IgZ2M9THQpIiwgCgkJCQluZXcgVW5pY29kZVNldChoYXNVcHBlcikucmVtb3ZlQWxsKGlzR2NMdCkucmVtb3ZlQWxsKHByb3BMb3dlcmNhc2UpKTsKCgkJCgkJcHJpbnRJdGVtcyhiZiwgY29tcGF0LCAiRnVuY3Rpb25hbGx5IFVwcGVyY2FzZSwgYnV0IG5vdCBVcHBlcmNhc2U9dHJ1ZSIsIAoJCQkJbmV3IFVuaWNvZGVTZXQoaXNGVXBwZXJjYXNlKS5yZW1vdmVBbGwocHJvcFVwcGVyY2FzZSkpOwoJCXByaW50SXRlbXMoYmYsIGNvbXBhdCwgIlVwcGVyY2FzZT10cnVlLCBidXQgbm90IGZ1bmN0aW9uYWxseSBVcHBlcmNhc2UiLCAKCQkJCW5ldyBVbmljb2RlU2V0KHByb3BVcHBlcmNhc2UpLnJlbW92ZUFsbChpc0ZVcHBlcmNhc2UpKTsKCQkKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJGdW5jdGlvbmFsbHkgTG93ZXJjYXNlLCBidXQgbm90IExvd2VyY2FzZT10cnVlIiwgCgkJCQluZXcgVW5pY29kZVNldChpc0ZMb3dlcmNhc2UpLnJlbW92ZUFsbChwcm9wTG93ZXJjYXNlKSk7CgkJcHJpbnRJdGVtcyhiZiwgY29tcGF0LCAiTG93ZXJjYXNlPXRydWUsIGJ1dCBub3QgZnVuY3Rpb25hbGx5IExvd2VyY2FzZSIsIAoJCQkJbmV3IFVuaWNvZGVTZXQocHJvcExvd2VyY2FzZSkucmVtb3ZlQWxsKGlzRkxvd2VyY2FzZSkpOwoKCgkJVW5pY29kZVNldCBzY3JpcHRTZXQgPSBuZXcgVW5pY29kZVNldCgpOwoJCVVuaWNvZGVQcm9wZXJ0eSBzY3JpcHRQcm9wID0gdXBzLmdldFByb3BlcnR5KCJTY3JpcHQiKTsKCQliZi5zZXRNZXJnZVJhbmdlcyh0cnVlKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIkJpY2FtZXJhbCBTY3JpcHRzOiB0aG9zZSB3aXRoIGF0IGxlYXN0IG9uZSBmdW5jdGlvbmFsbHkgY2FzZWQgY2hhcmFjdGVyLiIpOwoJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2NyaXB0cy5zaXplKCk7ICsraSkgewoJCQlpZiAoIXNjcmlwdHMuZ2V0KGkpKSBjb250aW51ZTsKCQkJLy9pZiAoaSA9PSBDT01NT05fU0NSSVBUKSBjb250aW51ZTsKCQkJU3RyaW5nIHNjcmlwdE5hbWUgPSB1Y2QuZ2V0U2NyaXB0SURfZnJvbUluZGV4KChieXRlKWkpOwoJCQlVbmljb2RlU2V0IHNjcmlwdFVTZXQgPSBzY3JpcHRQcm9wLmdldFNldChzY3JpcHROYW1lKTsKCQkJc2NyaXB0U2V0LmFkZEFsbChzY3JpcHRVU2V0KTsKCQkJcHJpbnRJdGVtcyhiZiwgY29tcGF0LCAiQmljYW1lcmFsIFNjcmlwdDogIiArIHNjcmlwdE5hbWUsCgkJCQkJbmV3IFVuaWNvZGVTZXQoYWxsQ2FzZWQpLnJldGFpbkFsbChzY3JpcHRVU2V0KSk7CgkJfQoJCWJmLnNldE1lcmdlUmFuZ2VzKGZhbHNlKTsKCQlwcmludEl0ZW1zKGJmLCBjb21wYXQsICJCaWNhbWVyYWwgU2NyaXB0OiBpc0FscGhhIG9yIFN5bWJvbCBNb2RpZmllciwgYnV0IG5vdCBpc0Nhc2VkIiwgCgkJCQluZXcgVW5pY29kZVNldChzY3JpcHRTZXQpLnJldGFpbkFsbChvdGhlckFscGhhYmV0aWMpLnJlbW92ZUFsbChhbGxDYXNlZCkpOwoJCXByaW50SXRlbXMoYmYsIGNvbXBhdCwgIkJpY2FtZXJhbCBTY3JpcHQ6IGlzQ2FzZWQsIGJ1dCBub3QgaXNBbHBoYSBvciBTeW1ib2wgTW9kaWZpZXIiLCAKCQkJCW5ldyBVbmljb2RlU2V0KHNjcmlwdFNldCkucmV0YWluQWxsKGFsbENhc2VkKS5yZW1vdmVBbGwob3RoZXJBbHBoYWJldGljKSk7Cgl9CgoJCgkvKioKCSAqIEBwYXJhbSBiZgoJICogQHBhcmFtIGNvbXBhdAoJICogQHBhcmFtIHRlbXAKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludEl0ZW1zKEJhZ0Zvcm1hdHRlciBiZiwgVW5pY29kZVNldCBjb21wYXQsIFN0cmluZyB0aXRsZSwgVW5pY29kZVNldCB0ZW1wKSB7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJU3lzdGVtLm91dC5wcmludGxuKHRpdGxlICsgIiAtLSAobm9uIGNvbXBhdCkiKTsJCQoJCVVuaWNvZGVTZXQgdGVtcDIgPSBuZXcgVW5pY29kZVNldCh0ZW1wKS5yZW1vdmVBbGwoY29tcGF0KTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oYmYuc2hvd1NldE5hbWVzKHRlbXAyKSk7CgkJU3lzdGVtLm91dC5wcmludGxuKCk7CgkJdGVtcDIgPSBuZXcgVW5pY29kZVNldCh0ZW1wKS5yZXRhaW5BbGwoY29tcGF0KTsKCQlTeXN0ZW0ub3V0LnByaW50bG4odGl0bGUgKyAiIC0tIChjb21wYXQpIik7CgkJU3lzdGVtLm91dC5wcmludGxuKGJmLnNob3dTZXROYW1lcyh0ZW1wMikpOwoJfQoKCXN0YXRpYyBQcmludFdyaXRlciBsb2c7CgkKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1NoYXBpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgCWxvZyA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFdyaXRlcihVQ0RfVHlwZXMuR0VOX0RJUiwgImNoZWNrbG9nLnR4dCIpOwogICAgCWNoZWNrUHJvcGVydHkoIkpvaW5pbmdfVHlwZSIsICJOb25fSm9pbmluZyIsICJKb2luaW5nX1R5cGUiLCAiVHJhbnNwYXJlbnQiKTsKICAgIAljaGVja1Byb3BlcnR5KCJKb2luaW5nX0dyb3VwIiwgIk5vX0pvaW5pbmdfR3JvdXAiLCAiSm9pbmluZ19UeXBlIiwgIlRyYW5zcGFyZW50Iik7ICAJCiAgICAgICAJY2hlY2tQcm9wZXJ0eSgiTGluZV9CcmVhayIsICJVbmtub3duIiwgIkxpbmVfQnJlYWsiLCAiQ29tYmluaW5nX01hcmsiKTsKICAgICAgIAljaGVja1Byb3BlcnR5KCJFYXN0X0FzaWFuX1dpZHRoIiwgbnVsbCwgIkxpbmVfQnJlYWsiLCAiQ29tYmluaW5nX01hcmsiKTsKICAgICAgIAljaGVja1Byb3BlcnR5KCJCaWRpX0NsYXNzIiwgbnVsbCwgIkxpbmVfQnJlYWsiLCAiQ29tYmluaW5nX01hcmsiKTsKICAgICAgIAljaGVja1Byb3BlcnR5KCJTY3JpcHQiLCBudWxsLCAiU2NyaXB0IiwgbmV3IFN0cmluZ1tdeyJDb21tb24iLCAiSW5oZXJpdGVkIn0pOwogICAgICAgCWNoZWNrUHJvcGVydHkoIkdlbmVyYWxfQ2F0ZWdvcnkiLCBudWxsLCAiR2VuZXJhbF9DYXRlZ29yeSIsIG5ldyBTdHJpbmdbXXsiU3BhY2luZ19NYXJrIiwgCiAgICAgICAJCQkiRW5jbG9zaW5nX01hcmsiLCAiTm9uc3BhY2luZ19NYXJrIn0pOwogICAgCWxvZy5jbG9zZSgpOwogICAgfQoKICAgIC8qKgoJICogQHBhcmFtIHByb3BlcnR5TmFtZQogICAgICogQHBhcmFtIGV4Y2x1c2lvbgogICAgICogQHBhcmFtIGlnbm9yZVByb3BlcnR5TmFtZSBUT0RPCiAgICAgKiBAcGFyYW0gaWdub3JlVmFsdWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1Byb3BlcnR5KFN0cmluZyBwcm9wZXJ0eU5hbWUsIFN0cmluZyBleGNsdXNpb24sIFN0cmluZyBpZ25vcmVQcm9wZXJ0eU5hbWUsIE9iamVjdCBpZ25vcmVWYWx1ZUxpc3QpIHsKCQlsb2cucHJpbnRsbigpOwoJCWxvZy5wcmludGxuKHByb3BlcnR5TmFtZSArICIgQ2hlY2siKTsKCQlsb2cucHJpbnRsbigpOwoJCVNldCBpZ25vcmVWYWx1ZVNldCA9IG5ldyBIYXNoU2V0KCk7CgkJaWYgKGlnbm9yZVZhbHVlTGlzdCBpbnN0YW5jZW9mIFN0cmluZykgaWdub3JlVmFsdWVTZXQuYWRkKGlnbm9yZVZhbHVlTGlzdCk7CgkJZWxzZSBpZ25vcmVWYWx1ZVNldC5hZGRBbGwoQXJyYXlzLmFzTGlzdCgoT2JqZWN0W10paWdub3JlVmFsdWVMaXN0KSk7CgkJCgkJVG9vbFVuaWNvZGVQcm9wZXJ0eVNvdXJjZSB1cHMgPSBUb29sVW5pY29kZVByb3BlcnR5U291cmNlLm1ha2UoIjQuMC4xIik7CiAgICAJVW5pY29kZVByb3BlcnR5IHVwID0gdXBzLmdldFByb3BlcnR5KHByb3BlcnR5TmFtZSk7CiAgICAJVW5pY29kZVByb3BlcnR5IGlnblByb3AgPSB1cHMuZ2V0UHJvcGVydHkoaWdub3JlUHJvcGVydHlOYW1lKTsKICAgIAlVbmljb2RlUHJvcGVydHkgbmFtZSA9IHVwcy5nZXRQcm9wZXJ0eSgiTmFtZSIpOwogICAgCVVuaWNvZGVTZXQgc2lnbmlmaWNhbnQgPSAoZXhjbHVzaW9uICE9IG51bGwgPyB1cC5nZXRTZXQoZXhjbHVzaW9uKSA6IG5ldyBVbmljb2RlU2V0KCkpLmNvbXBsZW1lbnQoKTsKICAgIAlVbmljb2RlU2V0SXRlcmF0b3IgaXQgPSBuZXcgVW5pY29kZVNldEl0ZXJhdG9yKHNpZ25pZmljYW50KTsKICAgIAlOb3JtYWxpemVyIG4gPSBuZXcgTm9ybWFsaXplcihOb3JtYWxpemVyLk5GRCwgIjQuMC4xIik7CiAgICAJaW50IGNvdW50ZXIgPSAwOwogICAgCXdoaWxlIChpdC5uZXh0KCkpIHsKICAgIAkJU3RyaW5nIGJhc2VWYWx1ZSA9IHVwLmdldFZhbHVlKGl0LmNvZGVwb2ludCk7CiAgICAJCVN0cmluZyBuZmQgPSBuLm5vcm1hbGl6ZShpdC5jb2RlcG9pbnQpOwogICAgCQlpZiAobi5pc05vcm1hbGl6ZWQoaXQuY29kZXBvaW50KSkgY29udGludWU7CiAgICAJCS8vaWYgKG5mZC5lcXVhbHMoaXQuZ2V0U3RyaW5nKCkpKSBjb250aW51ZTsKICAgIAkJaW50IGNwOwogICAgCQlmb3IgKGludCBpID0gMDsgaSA8IG5mZC5sZW5ndGgoKTsgaSArPSBVVEYxNi5nZXRDaGFyQ291bnQoY3ApKSB7CiAgICAJCQljcCA9IFVURjE2LmNoYXJBdChuZmQsIGkpOwogICAgICAgIAkJYm9vbGVhbiBzaG93biA9IGZhbHNlOwogICAgCQkJU3RyaW5nIG5ld1ZhbHVlID0gdXAuZ2V0VmFsdWUoY3ApOyAgICAJCQogICAgCQkJU3RyaW5nIHBvc3NJZ25WYWx1ZSA9IGlnblByb3AuZ2V0VmFsdWUoY3ApOwoJCQkJaWYgKGlnbm9yZVZhbHVlU2V0LmNvbnRhaW5zKHBvc3NJZ25WYWx1ZSkpIHsKCQkJCQkvL2xvZy5wcmludGxuKCItLS0gIiArIG5ld1ZhbHVlICsgIlx0IiArIFV0aWxpdHkuaGV4KGNwKSArICIgIiArIG5hbWUuZ2V0VmFsdWUoY3ApKTsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCS8vbG9nLnByaW50bG4oIioqKiAiICsgbmV3VmFsdWUgKyAiXHQiICsgVXRpbGl0eS5oZXgoY3ApICsgIiAiICsgbmFtZS5nZXRWYWx1ZShjcCkpOwoJCQkJCgkJCQlpZiAoIWJhc2VWYWx1ZS5lcXVhbHMobmV3VmFsdWUpKSB7CiAgICAJCQkJaWYgKCFzaG93bikgbG9nLnByaW50bG4oKCsrY291bnRlcikgKyAiXHRDT05GTElDVFx0IiArIGJhc2VWYWx1ZSArICJcdCIgKyBVdGlsaXR5LmhleChpdC5jb2RlcG9pbnQpICsgIiAiICsgbmFtZS5nZXRWYWx1ZShpdC5jb2RlcG9pbnQpKTsKCQkJCQlsb2cucHJpbnRsbigiXHRORkQoIiArIFV0aWxpdHkuaGV4KGl0LmNvZGVwb2ludCkgKyAiKSBjb250YWluczpcdCIgKyBuZXdWYWx1ZSArICJcdCIgKyBVdGlsaXR5LmhleChjcCkgKyAiICIgKyBuYW1lLmdldFZhbHVlKGNwKSk7CgkJCQkJc2hvd24gPSB0cnVlOwoJCQkJfQogICAgCQl9ICAgIAkJCiAgICAJfQoJfQoKCXB1YmxpYyBzdGF0aWMgY2xhc3MgUmVnZXhNYXRjaGVyIGltcGxlbWVudHMgVW5pY29kZVByb3BlcnR5LlBhdHRlcm5NYXRjaGVyIHsKICAgICAgICBwcml2YXRlIE1hdGNoZXIgbWF0Y2hlcjsKICAgICAgICAKICAgICAgICBwdWJsaWMgVW5pY29kZVByb3BlcnR5LlBhdHRlcm5NYXRjaGVyIHNldChTdHJpbmcgcGF0dGVybikgewogICAgICAgICAgICBtYXRjaGVyID0gUGF0dGVybi5jb21waWxlKHBhdHRlcm4pLm1hdGNoZXIoIiIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgbWF0Y2hlci5yZXNldCgoU3RyaW5nKXZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXIubWF0Y2hlcygpOwogICAgICAgIH0gICAgICAgCiAgICB9CgogICAgc3RhdGljIEJhZ0Zvcm1hdHRlciBiZiA9IG5ldyBCYWdGb3JtYXR0ZXIoKTsKICAgIHN0YXRpYyBVbmljb2RlUHJvcGVydHkuUGF0dGVybk1hdGNoZXIgbWF0Y2hlciA9IG5ldyBSZWdleE1hdGNoZXIoKTsKCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHNob3dQcm9wRGlmZihTdHJpbmcgcDEsIFVuaWNvZGVTZXQgczEsIFN0cmluZyBwMiwgVW5pY29kZVNldCBzMikgewogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUHJvcGVydHkgTGlzdGluZyIpOwogICAgICAgIGlmIChzMSA9PSBudWxsKSB7CiAgICAgICAgICAgIHMxID0gdXBmLmdldFNldChwMSwgbWF0Y2hlciwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIGlmIChzMiA9PSBudWxsKSB7CiAgICAgICAgICAgIHMyID0gdXBmLmdldFNldChwMiwgbWF0Y2hlciwgbnVsbCk7CiAgICAgICAgfSAKICAgICAgICBiZi5zaG93U2V0RGlmZmVyZW5jZXMoYmYuQ09OU09MRSxwMSxzMSxwMixzMik7CiAgICB9CiAgICAKICAgIHN0YXRpYyBwcml2YXRlIFVuaWNvZGVTZXQgZ2V0U2V0Rm9yTmFtZShTdHJpbmcgcmVnZXhQYXR0ZXJuKSB7CiAgICAgICAgVW5pY29kZVNldCByZXN1bHQgPSBuZXcgVW5pY29kZVNldCgpOwogICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZShyZWdleFBhdHRlcm4pOwogICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcigiIik7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAweDEwRkZGRjsgKytpKSB7CiAgICAgICAgICAgIFV0aWxpdHkuZG90KGkpOwogICAgICAgICAgICBpZiAoIURlZmF1bHQudWNkKCkuaXNBc3NpZ25lZChpKSkgY29udGludWU7CiAgICAgICAgICAgIGJ5dGUgY2F0ID0gRGVmYXVsdC51Y2QoKS5nZXRDYXRlZ29yeShpKTsKICAgICAgICAgICAgaWYgKGNhdCA9PSBQUklWQVRFX1VTRSkgY29udGludWU7CiAgICAgICAgICAgIG0ucmVzZXQoRGVmYXVsdC51Y2QoKS5nZXROYW1lKGkpKTsKICAgICAgICAgICAgaWYgKG0ubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBzaG93U2V0KFByaW50V3JpdGVyIHB3LCBTdHJpbmcgeCwgYm9vbGVhbiBzZXBhcmF0ZUxpbmVzKSB7CiAgICAgICAgcHcucHJpbnRsbigiKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih4KTsKICAgICAgICBVbmljb2RlU2V0IHNzID0gbmV3IFVuaWNvZGVTZXQoeCk7CiAgICAgICAgcHcucHJpbnRsbih4KTsKICAgICAgICBVdGlsaXR5LnNob3dTZXROYW1lcyhwdywiIixzcyxzZXBhcmF0ZUxpbmVzLGZhbHNlLERlZmF1bHQudWNkKCkpOwogICAgICAgIHB3LnByaW50bG4oIioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKICAgIH0KCQoJc3RhdGljIGludCBTSElGVCA9IDY7CglzdGF0aWMgaW50IE1BU0sgPSAoMTw8NikgLSAxOwoJc3RhdGljIGludCBPVEhFUiA9IDB4RkYgJiB+TUFTSzsKCglzdGF0aWMgdm9pZCBzaG93TnVtYmVyKGZsb2F0IHgpIHsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIk51bWJlcjogIiArIHgpOwoJCS8vbG9uZyBiaXRzID0gRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoeCk7CgkJbG9uZyBiaXRzID0gKEZsb2F0LmZsb2F0VG9JbnRCaXRzKHgpICsgMEwpIDw8IDMyOwoJCVN5c3RlbS5vdXQucHJpbnRsbigiSUVFRTogIiArIExvbmcudG9CaW5hcnlTdHJpbmcoYml0cykpOwoJCVN5c3RlbS5vdXQucHJpbnQoIkJyb2tlbjogIik7CgkJbG9uZyBsYXN0U2hpZnQgPSA2NC1TSElGVDsKCQlmb3IgKGxvbmcgc2hpZnQgPSA2NC1TSElGVDsgc2hpZnQgPiAwOyBzaGlmdCAtPSBTSElGVCkgewoJCQlsb25nIHRlbXAgPSBiaXRzID4+PiBzaGlmdDsKCQkJdGVtcCAmPSBNQVNLOwoJCQlpZiAodGVtcCAhPSAwKSBsYXN0U2hpZnQgPSBzaGlmdDsKCQkJdGVtcCB8PSBPVEhFUjsKCQkJU3RyaW5nIHBpZWNlID0gTG9uZy50b0JpbmFyeVN0cmluZyh0ZW1wKTsKCQkJU3lzdGVtLm91dC5wcmludCgiICIgKyBwaWVjZSk7CgkJfQoJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJCVN5c3RlbS5vdXQucHJpbnQoIkJ5dGVzOiAxQiIpOwoJCWZvciAobG9uZyBzaGlmdCA9IDY0LVNISUZUOyBzaGlmdCA+PSBsYXN0U2hpZnQ7IHNoaWZ0IC09IFNISUZUKSB7CgkJCWxvbmcgdGVtcCA9IGJpdHMgPj4+IHNoaWZ0OwoJCQl0ZW1wICY9IE1BU0s7CgkJCXRlbXAgfD0gT1RIRVI7CgkJCWlmIChzaGlmdCA9PSBsYXN0U2hpZnQpIHsKCQkJCXRlbXAgJj0gfjB4ODA7CgkJCX0gCgkJCVN0cmluZyBwaWVjZSA9IExvbmcudG9IZXhTdHJpbmcodGVtcCkudG9VcHBlckNhc2UoKTsKCQkJU3lzdGVtLm91dC5wcmludCgiICIgKyBwaWVjZSk7CgkJfQoJCVN5c3RlbS5vdXQucHJpbnRsbigpOwoJfQoJCglzdGF0aWMgaW50IGZpbmRGaXJzdE5vblplcm8oU3RyaW5nIGRpZ2l0cykgewoJCWZvciAoaW50IGkgPSAwOyBpIDwgZGlnaXRzLmxlbmd0aCgpOyArK2kpIHsKCQkJaWYgKGRpZ2l0cy5jaGFyQXQoaSkgIT0gJzAnKSByZXR1cm4gaTsKCQl9CgkJcmV0dXJuIGRpZ2l0cy5sZW5ndGgoKTsKCX0KCQoJc3RhdGljIFN0cmluZyByZW1vdmUoU3RyaW5nIHMsIGludCBzdGFydCwgaW50IGxpbWl0KSB7CgkJcmV0dXJuIHMuc3Vic3RyaW5nKDAsIHN0YXJ0KSArIHMuc3Vic3RyaW5nKGxpbWl0KTsKCX0KCQoJc3RhdGljIFN0cmluZyBoZXhCeXRlKGludCBpKSB7CgkJU3RyaW5nIHJlc3VsdCA9IEludGVnZXIudG9IZXhTdHJpbmcoaSkudG9VcHBlckNhc2UoKTsKCQlpZiAocmVzdWx0Lmxlbmd0aCgpID09IDEpIHJlc3VsdCA9ICcwJyArIHJlc3VsdDsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJCgkvLyBkdW1iIGltcGxlbWVudGF0aW9uCglzdGF0aWMgU3RyaW5nIGNvbnZlcnRUb0JDRChTdHJpbmcgZGlnaXRzKSB7CgkJCgkJLy8gZml4IG5lZ2F0aXZlcywgcmVtb3ZlIGxlYWRpbmcgemVyb3MsIGdldCBkZWNpbWFsCgkJCgkJaW50W10gcGFpcnMgPSBuZXcgaW50WzEyMF07CgkJYm9vbGVhbiBuZWdhdGl2ZSA9IGZhbHNlOwoJCWJvb2xlYW4gcmVtb3ZlZE5lZ2F0aXZlID0gZmFsc2U7CgkJYm9vbGVhbiByZW1vdmVkRGVjaW1hbCA9IGZhbHNlOwoJCWludCBsZWFkWmVyb3MgPSAwOwoJCWludCB0cmFpbFplcm9zID0gMDsKCgkJaWYgKGRpZ2l0cy5jaGFyQXQoMCkgPT0gJy0nKSB7CgkJCW5lZ2F0aXZlID0gdHJ1ZTsKCQkJcmVtb3ZlZE5lZ2F0aXZlID0gdHJ1ZTsKCQkJZGlnaXRzID0gcmVtb3ZlKGRpZ2l0cywgMCwgMSk7CgkJfQoJCXdoaWxlIChkaWdpdHMubGVuZ3RoKCkgPiAwICYmIGRpZ2l0cy5jaGFyQXQoMCkgPT0gJzAnKSB7CgkJCWRpZ2l0cyA9IHJlbW92ZShkaWdpdHMsIDAsIDEpOwoJCQlsZWFkWmVyb3MrKzsKCQl9CgkJaW50IGRlY2ltYWxPZmZzZXQgPSBkaWdpdHMuaW5kZXhPZignLicpOwoJCWlmIChkZWNpbWFsT2Zmc2V0IDwgMCkgewoJCQlkZWNpbWFsT2Zmc2V0ID0gZGlnaXRzLmxlbmd0aCgpOwoJCX0gZWxzZSB7CgkJCWRpZ2l0cyA9IGRpZ2l0cyA9IHJlbW92ZShkaWdpdHMsIGRlY2ltYWxPZmZzZXQsIGRlY2ltYWxPZmZzZXQrMSk7CgkJCXJlbW92ZWREZWNpbWFsID0gdHJ1ZTsKCQl9CgkJCgkJLy8gcmVtb3ZlIHRyYWlsaW5nIHplcm9zCgkJd2hpbGUgKGRpZ2l0cy5sZW5ndGgoKSA+IDAgJiYgZGlnaXRzLmNoYXJBdChkaWdpdHMubGVuZ3RoKCkgLSAxKSA9PSAnMCcpIHsKCQkJZGlnaXRzID0gcmVtb3ZlKGRpZ2l0cywgZGlnaXRzLmxlbmd0aCgpIC0gMSwgZGlnaXRzLmxlbmd0aCgpKTsKCQkJdHJhaWxaZXJvcysrOwoJCX0KCQkKCQkvLyBtYWtlIHRoZSBkaWdpdHMgZXZlbiAoaW4gbm9uLWZyYWN0aW9uIHBhcnQpCgkJaWYgKCgoZGVjaW1hbE9mZnNldCkgJiAxKSAhPSAwKSB7CgkJCWRpZ2l0cyA9ICcwJyArIGRpZ2l0czsgLy8gbWFrZSBldmVuCgkJCSsrZGVjaW1hbE9mZnNldDsKCQkJbGVhZFplcm9zLS07CgkJfQoJCWlmICgoKGRpZ2l0cy5sZW5ndGgoKSkgJiAxKSAhPSAwKSB7CgkJCWRpZ2l0cyA9IGRpZ2l0cyArICcwJzsgLy8gbWFrZSBldmVuCgkJCXRyYWlsWmVyb3MtLTsKCQl9CgkJCgkJLy8gaGFuZGxlIDAKCQlpZiAoZGlnaXRzLmxlbmd0aCgpID09IDApIHsKCQkJbmVnYXRpdmUgPSBmYWxzZTsKCQkJZGlnaXRzID0gIjAwIjsKCQkJbGVhZFplcm9zIC09IDI7CgkJfSAKCQkKCQkvLyBzdG9yZSBleHBvbmVudAoJCWludCBleHAgPSBkZWNpbWFsT2Zmc2V0LzI7CgkJaWYgKCFuZWdhdGl2ZSkgZXhwIHw9IDB4ODA7CgkJZWxzZSBleHAgPSAofmV4cCkgJiAweDdGOwoJCVN0cmluZyByZXN1bHQgPSBoZXhCeXRlKGV4cCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBkaWdpdHMubGVuZ3RoKCk7IGkgKz0gMikgewoJCQlpbnQgYmFzZTEwMCA9ICgoZGlnaXRzLmNoYXJBdChpKSAtICcwJykqMTAgKyAoZGlnaXRzLmNoYXJBdChpKzEpIC0gJzAnKSkgPDwgMTsKCQkJaWYgKGkgPCBkaWdpdHMubGVuZ3RoKCkgLSAyKSBiYXNlMTAwIHw9IDB4MTsgLy8gbWFyayBhbGwgYnV0IGxhc3QKCQkJaWYgKG5lZ2F0aXZlKSBiYXNlMTAwID0gKH5iYXNlMTAwKSAmIDB4RkY7CgkJCXJlc3VsdCArPSAiLiIgKyBoZXhCeXRlKGJhc2UxMDApOwoJCX0KCQkKCQkvKioKCQkvLyBhZGQgYSBzZWNvbmRhcnkgd2VpZ2h0CgkJLy8gYXNzdW1lIHdlIGRvbid0IGNhcmUgYWJvdXQgbW9yZSB0aGFuIHRvbyBtYW55IGxlYWRzL3RyYWlscwoJCWxlYWRaZXJvcyArPSAyOyAvLyBtYWtlIG5vbi1uZWdhdGl2ZTsgbWlnaHQgaGF2ZSBwYWRkZWQgYnkgMiwgZm9yIDAKCQl0cmFpbFplcm9zICs9IDI7IC8vIG1ha2Ugbm9uLW5lZ2F0aXZlOyBtaWdodCBoYXZlIHBhZGRlZCBieSAxCgkJaWYgKGxlYWRaZXJvcyA+IDcpIGxlYWRaZXJvcyA9IDc7CgkJaWYgKHRyYWlsWmVyb3MgPiA3KSB0cmFpbFplcm9zID0gNzsKCQlpbnQgc2Vjb25kYXJ5ID0gKHJlbW92ZWROZWdhdGl2ZSA/IDAgOiAweDgwKSAvLyBvbmx5IGZvciB6ZXJvCgkJCQkJCXwgKGxlYWRaZXJvcyA8PCA0KQoJCQkJCQl8IChyZW1vdmVkRGVjaW1hbCA/IDAgOiAweDA4KQoJCQkJCQl8ICh0cmFpbFplcm9zKTsKCQlyZXN1bHQgKz0gIjsiICsgaGV4Qnl0ZShzZWNvbmRhcnkpOwoJCSovCgkJCgkJcmV0dXJuIHJlc3VsdDsKCX0KCQoJc3RhdGljIGludCBzdGFtcCA9IDA7CglzdGF0aWMgdm9pZCBhZGQoTWFwIG0sIFN0cmluZyBzKSB7CgkJYWRkMihtLCBzKTsKCQlhZGQyKG0sICIwIiArIHMpOwoJCWlmIChzLmluZGV4T2YoJy4nKSA+PSAwKSB7CgkJCWFkZDIobSwgcyArICIwIik7CgkJCWFkZDIobSwgIjAiICsgcyArICIwIik7CgkJfSBlbHNlIHsKCQkJYWRkMihtLCBzICsgIi4iKTsKCQkJYWRkMihtLCAiMCIgKyBzICsgIi4iKTsKCQkJYWRkMihtLCBzICsgIi4wIik7CgkJCWFkZDIobSwgIjAiICsgcyArICIuMCIpOwoJCX0KCX0KCQoJc3RhdGljIHZvaWQgYWRkMihNYXAgbSwgU3RyaW5nIHMpIHsKCQlhZGQzKG0scyk7CgkJaWYgKHMuaW5kZXhPZignLScpIDwgMCkgYWRkMyhtLCAiLSIgKyBzKTsKCX0KCglwcml2YXRlIHN0YXRpYyB2b2lkIGFkZDMoTWFwIG0sIFN0cmluZyBzKSB7CgkJU3RyaW5nIGJhc2UgPSBjb252ZXJ0VG9CQ0Qocyk7CgkJYmFzZSArPSAifCIgKyBNYXRoLnJhbmRvbSgpICsgc3RhbXArKzsgLy8ganVzdCBzb21ldGhpbmcgZm9yIHVuaXF1ZW5lc3MKCQltLnB1dChiYXNlLCBzKTsKCX0KCQoJc3RhdGljIGJvb2xlYW4gU0hPV19BTEwgPSB0cnVlOwoJCglzdGF0aWMgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKExvY2FsZS5FTkdMSVNIKTsKCXN0YXRpYyB7CgkJbmYuc2V0R3JvdXBpbmdVc2VkKGZhbHNlKTsKCX0KCQoJc3RhdGljIFN0cmluZyBjbGVhblRvU3RyaW5nKGRvdWJsZSBkKSB7CgkJcmV0dXJuIG5mLmZvcm1hdChkKTsKCX0KCQoJc3RhdGljIHZvaWQgdGVzdENvbnZlcnRUb0JERCgpIHsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0aW5nIFRlc3QiKTsKCQlkb3VibGVbXSB0ZXN0TGlzdCA9IHswLCAwLjAwMDAwMDAxLCAwLjAwMSwgNSwgMTAsIDUwLCAxMDAsIDEwMDAsIDEwMDAwMDAwMH07CgkJTWFwIG0gPSBuZXcgVHJlZU1hcCgpOwoJCQoJCWZvciAoaW50IGkgPSAwOyBpIDwgdGVzdExpc3QubGVuZ3RoOyArK2kpIHsKCQkJZG91YmxlIGQgPSB0ZXN0TGlzdFtpXTsKCQkJYWRkKG0sIGNsZWFuVG9TdHJpbmcoZCkpOwoJCQlhZGQobSwgY2xlYW5Ub1N0cmluZyhkICsgMC4xKSk7CgkJCWFkZChtLCBjbGVhblRvU3RyaW5nKGQgKyAxKSk7CgkJCWFkZChtLCBjbGVhblRvU3RyaW5nKGQgKyAxLjEpKTsKCQkJaWYgKGQgPiAwLjEpIGFkZChtLCBjbGVhblRvU3RyaW5nKGQgLSAwLjEpKTsKCQkJaWYgKGQgPiAxLjApIGFkZChtLCBjbGVhblRvU3RyaW5nKGQgLSAxLjApKTsKCQkJaWYgKGQgPiAxLjEpIGFkZChtLCBjbGVhblRvU3RyaW5nKGQgLSAxLjEpKTsKCQl9CgkJSXRlcmF0b3IgaXQgPSBtLmtleVNldCgpLml0ZXJhdG9yKCk7CgkJU3RyaW5nIGxhc3RLZXkgPSAiIjsKCQlTdHJpbmcgbGFzdFZhbHVlID0gIiI7CgkJYm9vbGVhbiBsYXN0UHJpbnRlZCA9IGZhbHNlOwoJCWRvdWJsZSBsYXN0TnVtYmVyID0gRG91YmxlLk5FR0FUSVZFX0lORklOSVRZOwoJCWludCBlcnJvckNvdW50ID0gMDsKCQl3aGlsZSAoaXQuaGFzTmV4dCgpKSB7CgkJCVN0cmluZyBrZXkgPSAoU3RyaW5nKSBpdC5uZXh0KCk7CgkJCVN0cmluZyB2YWx1ZSA9IChTdHJpbmcpIG0uZ2V0KGtleSk7CgkJCWtleSA9IGtleS5zdWJzdHJpbmcoMCwga2V5LmluZGV4T2YoJ3wnKSk7IC8vIHJlbW92ZSBzdGFtcAoJCQlkb3VibGUgbnVtYmVyID0gRG91YmxlLnBhcnNlRG91YmxlKHZhbHVlKTsKCQkJaWYgKGxhc3ROdW1iZXIgPiBudW1iZXIpIHsKCQkJCWlmICghbGFzdFByaW50ZWQpIFN5c3RlbS5vdXQucHJpbnRsbigiXHQiICsgbGFzdFZhbHVlICsgIlx0IiArIGxhc3RLZXkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJGYWlsOlx0IiArIHZhbHVlICsgIlx0IiArIGtleSk7CgkJCQlsYXN0UHJpbnRlZCA9IHRydWU7CgkJCQllcnJvckNvdW50Kys7CgkJCX0gZWxzZSBpZiAoU0hPV19BTEwpIHsKCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiXHQiICsgdmFsdWUgKyAiXHQiICsga2V5KTsKCQkJCWxhc3RQcmludGVkID0gdHJ1ZTsKCQkJfQoJCQlsYXN0TnVtYmVyID0gbnVtYmVyOwoJCQlsYXN0S2V5ID0ga2V5OwoJCQlsYXN0VmFsdWUgPSB2YWx1ZTsKCQl9CgkJU3lzdGVtLm91dC5wcmludGxuKCJEb25lIFRlc3QsICIgKyBlcnJvckNvdW50ICsgIiBFcnJvcnMiKTsKCX0KCQoJc3RhdGljIHZvaWQgdGVzdEZvcm1hdEhhY2soKSB7CgkJU3RyaW5nW10gdGVzdEN1cnJlbmNpZXMgPSB7IlVTRCIsIkdCUCIsIkpQWSIsIkVVUiJ9OwoJCUxvY2FsZVtdIHRlc3RMb2NhbGVzID0gTnVtYmVyRm9ybWF0LmdldEF2YWlsYWJsZUxvY2FsZXMoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHRlc3RMb2NhbGVzLmxlbmd0aDsgKytpKSB7CgkJCS8vIHNpbmNlIG5vbmUgb2YgdGhpcyBzaG91bGQgdmFyeSBieSBjb3VudHJ5LCB3ZSdsbCBqdXN0IGRvIGJ5IGxhbmd1YWdlCgkJCWlmICghdGVzdExvY2FsZXNbaV0uZ2V0Q291bnRyeSgpLmVxdWFscygiIikpIGNvbnRpbnVlOwoJCQlTeXN0ZW0ub3V0LnByaW50bG4odGVzdExvY2FsZXNbaV0uZ2V0RGlzcGxheU5hbWUoKSk7CgkJCWZvciAoaW50IGogPSAwOyBqIDwgdGVzdEN1cnJlbmNpZXMubGVuZ3RoOyArK2opIHsKCQkJCU51bWJlckZvcm1hdCBuZiA9IGdldEN1cnJlbmN5Rm9ybWF0KAoJCQkJCUN1cnJlbmN5LmdldEluc3RhbmNlKHRlc3RDdXJyZW5jaWVzW2pdKSwgdGVzdExvY2FsZXNbaV0sIHRydWUpOwoJCQkJU3RyaW5nIG5ld1ZlcnNpb24gPSBuZi5mb3JtYXQoMTIzNC41NjcpOwoJCQkJU3lzdGVtLm91dC5wcmludCgiXHQiICsgbmV3VmVyc2lvbik7CgkJCQluZiA9IGdldEN1cnJlbmN5Rm9ybWF0KAoJCQkJCUN1cnJlbmN5LmdldEluc3RhbmNlKHRlc3RDdXJyZW5jaWVzW2pdKSwgdGVzdExvY2FsZXNbaV0sIGZhbHNlKTsKCQkJCVN0cmluZyBvbGRWZXJzaW9uID0gbmYuZm9ybWF0KDEyMzQuNTY3KTsKCQkJCWlmICghb2xkVmVyc2lvbi5lcXVhbHMobmV3VmVyc2lvbikpIHsKCQkJCQlTeXN0ZW0ub3V0LnByaW50KCIgKCIgKyBvbGRWZXJzaW9uICsgIikiKTsKCQkJCX0KCQkJfQoJCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQl9Cgl9CgkKCXN0YXRpYyBOdW1iZXJGb3JtYXQgZ2V0Q3VycmVuY3lGb3JtYXQoQ3VycmVuY3kgY3VycmVuY3ksIExvY2FsZSBkaXNwbGF5TG9jYWxlLCBib29sZWFuIElDVTI2KSB7CgkJLy8gY29kZSBmb3IgSUNVIDIuNgoJCWlmIChJQ1UyNikgewoJCQlOdW1iZXJGb3JtYXQgcmVzdWx0ID0gTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoKTsKCQkJcmVzdWx0LnNldEN1cnJlbmN5KGN1cnJlbmN5KTsKCQkJcmV0dXJuIHJlc3VsdDsKCQl9CgoJCS8vIHVnbHkgd29yay1hcm91bmQgZm9yIDIuNAoJCURlY2ltYWxGb3JtYXQgcmVzdWx0ID0gKERlY2ltYWxGb3JtYXQpTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoZGlzcGxheUxvY2FsZSk7CgkJSGFja0N1cnJlbmN5SW5mbyBoYWNrID0gKEhhY2tDdXJyZW5jeUluZm8pKGhhY2tEYXRhLmdldChjdXJyZW5jeS5nZXRDdXJyZW5jeUNvZGUoKSkpOwoJCXJlc3VsdC5zZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoaGFjay5kZWNpbWFscyk7CgkJcmVzdWx0LnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyhoYWNrLmRlY2ltYWxzKTsKCQlyZXN1bHQuc2V0Um91bmRpbmdJbmNyZW1lbnQoaGFjay5yb3VuZGluZyk7CgkJRGVjaW1hbEZvcm1hdFN5bWJvbHMgc3ltYm9scyA9IHJlc3VsdC5nZXREZWNpbWFsRm9ybWF0U3ltYm9scygpOwoJCXN5bWJvbHMuc2V0Q3VycmVuY3lTeW1ib2woaGFjay5zeW1ib2wpOwoJCXJlc3VsdC5zZXREZWNpbWFsRm9ybWF0U3ltYm9scyhzeW1ib2xzKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJCglzdGF0aWMgTWFwIGhhY2tEYXRhID0gbmV3IEhhc2hNYXAoKTsKCXN0YXRpYyBjbGFzcyBIYWNrQ3VycmVuY3lJbmZvIHsKCQlpbnQgZGVjaW1hbHM7CgkJZG91YmxlIHJvdW5kaW5nOwoJCVN0cmluZyBzeW1ib2w7CgkJSGFja0N1cnJlbmN5SW5mbyhpbnQgZGVjaW1hbHMsIGRvdWJsZSByb3VuZGluZywgU3RyaW5nIHN5bWJvbCkgewoJCQl0aGlzLmRlY2ltYWxzID0gZGVjaW1hbHM7CgkJCXRoaXMucm91bmRpbmcgPSByb3VuZGluZzsKCQkJdGhpcy5zeW1ib2wgPSBzeW1ib2w7CgkJfQoJfQoJc3RhdGljIHsKCQloYWNrRGF0YS5wdXQoIlVTRCIsIG5ldyBIYWNrQ3VycmVuY3lJbmZvKDIsIDAuMDEsICIkIikpOwoJCWhhY2tEYXRhLnB1dCgiR0JQIiwgbmV3IEhhY2tDdXJyZW5jeUluZm8oMiwgMC4wMSwgIlx1MDBhMyIpKTsKCQloYWNrRGF0YS5wdXQoIkpQWSIsIG5ldyBIYWNrQ3VycmVuY3lJbmZvKDAsIDEsICJcdTAwYTUiKSk7CgkJaGFja0RhdGEucHV0KCJFVVIiLCBuZXcgSGFja0N1cnJlbmN5SW5mbygyLCAwLjAxLCAiXHUyMEFDIikpOwoJfQogICAgLyoKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJTVEFSVCIpOwogICAgICAgIHVjZCA9IFVDRC5tYWtlKCk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJMb2FkZWQgVUNEICIgKyB1Y2QuZ2V0VmVyc2lvbigpICsgIiAiICsgKG5ldyBEYXRlKHVjZC5nZXREYXRlKCkpKSk7CgogICAgICAgIGNoZWNrSG9mZm1hbigiXHUwNUI4XHUwNUI5XHUwNUIxXHUwNTkxXHUwNUMzXHUwNUIwXHUwNUFDXHUwNTlGIik7CiAgICAgICAgY2hlY2tIb2ZmbWFuKCJcdTA1OTJcdTA1QjdcdTA1QkNcdTA1QTVcdTA1QjBcdTA1QzBcdTA1QzRcdTA1QUQiKTsKCiAgICAgICAgbG9uZyBtYXNrID0gMDsKCiAgICAgICAgaWYgKGZhbHNlKSB7CgogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShCSURJX0NMQVNTLCBCSURJX0NMQVNTK05FWFRfRU5VTSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWRCaWRpQ2xhc3MtMy4xLjFkMS50eHQiKTsKCgogICAgICAgIG1hc2sgPSBVdGlsaXR5LnNldEJpdHMoMCwgRGVyaXZlZFByb3BlcnR5LkZDX05GS0NfQ2xvc3VyZSwgRGVyaXZlZFByb3BlcnR5LkV4cGFuZHNPbk5GS0MpOwogICAgICAgIG1hc2sgPSBVdGlsaXR5LmNsZWFyQml0KG1hc2ssIERlcml2ZWRQcm9wZXJ0eS5GdWxsQ29tcEluY2x1c2lvbik7CiAgICAgICAgZ2VuZXJhdGVEZXJpdmVkKG1hc2ssIEhFQURFUl9ERVJJVkVELCAiRGVyaXZlZE5vcm1hbGl6YXRpb25Qcm9wZXJ0aWVzLTMuMS4wZDEudHh0Iik7CgogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShFQVNUX0FTSUFOX1dJRFRILCBFQVNUX0FTSUFOX1dJRFRIK05FWFRfRU5VTSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWRFYXN0QXNpYW5XaWR0aC0zLjEuMGQxLnR4dCIpOwoKICAgICAgICBnZW5lcmF0ZVZlcnRpY2FsU2xpY2UoQ0FURUdPUlksIENBVEVHT1JZK05FWFRfRU5VTSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWRHZW5lcmFsQ2F0ZWdvcnktMy4xLjBkMS50eHQiKTsKICAgICAgICBnZW5lcmF0ZVZlcnRpY2FsU2xpY2UoQ09NQklOSU5HX0NMQVNTLCBDT01CSU5JTkdfQ0xBU1MrTkVYVF9FTlVNLCBLRUVQX1NQRUNJQUwsIEhFQURFUl9ERVJJVkVELAogICAgICAgICAgICAiRGVyaXZlZENvbWJpbmluZ0NsYXNzLTMuMS4wZDEudHh0Iik7CiAgICAgICAgZ2VuZXJhdGVWZXJ0aWNhbFNsaWNlKERFQ09NUE9TSVRJT05fVFlQRSwgREVDT01QT1NJVElPTl9UWVBFK05FWFRfRU5VTSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWREZWNvbXBvc2l0aW9uVHlwZS0zLjEuMGQxLnR4dCIpOwogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShOVU1FUklDX1RZUEUsIE5VTUVSSUNfVFlQRStORVhUX0VOVU0sIEtFRVBfU1BFQ0lBTCwgSEVBREVSX0RFUklWRUQsCiAgICAgICAgICAgICJEZXJpdmVkTnVtZXJpY1R5cGUtMy4xLjBkMS50eHQiKTsKICAgICAgICBnZW5lcmF0ZVZlcnRpY2FsU2xpY2UoRUFTVF9BU0lBTl9XSURUSCwgRUFTVF9BU0lBTl9XSURUSCtORVhUX0VOVU0sIEtFRVBfU1BFQ0lBTCwgSEVBREVSX0RFUklWRUQsCiAgICAgICAgICAgICJEZXJpdmVkRWFzdEFzaWFuV2lkdGgtMy4xLjBkMS50eHQiKTsKICAgICAgICBnZW5lcmF0ZVZlcnRpY2FsU2xpY2UoSk9JTklOR19UWVBFLCBKT0lOSU5HX1RZUEUrTkVYVF9FTlVNLCBLRUVQX1NQRUNJQUwsIEhFQURFUl9ERVJJVkVELAogICAgICAgICAgICAiRGVyaXZlZEpvaW5pbmdUeXBlLTMuMS4wZDEudHh0Iik7CiAgICAgICAgZ2VuZXJhdGVWZXJ0aWNhbFNsaWNlKEpPSU5JTkdfR1JPVVAsIEpPSU5JTkdfR1JPVVArTkVYVF9FTlVNLCBLRUVQX1NQRUNJQUwsIEhFQURFUl9ERVJJVkVELAogICAgICAgICAgICAiRGVyaXZlZEpvaW5pbmdHcm91cC0zLjEuMGQxLnR4dCIpOwogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShCSU5BUllfUFJPUEVSVElFUywgQklOQVJZX1BST1BFUlRJRVMrMSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWRCaW5hcnlQcm9wZXJ0aWVzLTMuMS4wZDEudHh0Iik7CiAgICAgICAgZ2VuZXJhdGVWZXJ0aWNhbFNsaWNlKExJTUlUX0VOVU0sIExJTUlUX0VOVU0sIEtFRVBfU1BFQ0lBTCwgSEVBREVSX0RFUklWRUQsCiAgICAgICAgICAgICJEZXJpdmVkTnVtZXJpY1ZhbHVlcy0zLjEuMGQxLnR4dCIpOwoKICAgICAgICBtYXNrID0gVXRpbGl0eS5zZXRCaXRzKDAsIERlcml2ZWRQcm9wZXJ0eS5Qcm9wTWF0aCwgRGVyaXZlZFByb3BlcnR5Lk1vZF9JRF9Db250aW51ZV9OT19DZik7CiAgICAgICAgZ2VuZXJhdGVEZXJpdmVkKG1hc2ssIEhFQURFUl9ERVJJVkVELCAiRGVyaXZlZENvcmVQcm9wZXJ0aWVzLTMuMS4wZDEudHh0Iik7CgogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShMSU5FX0JSRUFLLCBMSU5FX0JSRUFLK05FWFRfRU5VTSwgS0VFUF9TUEVDSUFMLCBIRUFERVJfREVSSVZFRCwKICAgICAgICAgICAgIkRlcml2ZWRMaW5lQnJlYWstMy4xLjBkMS50eHQiKTsKCiAgICAgICAgZ2VuZXJhdGVWZXJ0aWNhbFNsaWNlKFNDUklQVCsxLCBTQ1JJUFQgKyBORVhUX0VOVU0sIEtFRVBfU1BFQ0lBTCwgSEVBREVSX1NDUklQVFMsICJTY3JpcHRzLTMuMS4wZDQudHh0Iik7CgogICAgICAgIGdlbmVyYXRlVmVydGljYWxTbGljZShCSU5BUllfUFJPUEVSVElFUyArIFdoaXRlX3NwYWNlLCBCSU5BUllfUFJPUEVSVElFUyArIE5vbmNoYXJhY3Rlcl9Db2RlX1BvaW50ICsgMSwKICAgICAgICAgICAgICAgIEtFRVBfU1BFQ0lBTCwgSEVBREVSX0VYVEVORCwgIlByb3BMaXN0LTMuMS4wZDUudHh0Iik7CgoKICAgICAgICAgICAgd3JpdGVOb3JtYWxpemVyVGVzdFN1aXRlKCJOb3JtYWxpemF0aW9uVGVzdC0zLjEuMGQxLnR4dCIpOwoKICAgICAgICB9CgoKCgogICAgICAgICAgICAvL2dlbmVyYXRlRGVyaXZlZChVdGlsaXR5LnNldEJpdHMoMCwgRGVyaXZlZFByb3BlcnR5LlByb3BNYXRoLCBEZXJpdmVkUHJvcGVydHkuTW9kX0lEX0NvbnRpbnVlX05PX0NmKSwKICAgICAgICAgICAgLy8gICAgSEVBREVSX0RFUklWRUQsICJEZXJpdmVkUHJvcERhdGEyLTMuMS4wZDEudHh0Iik7CiAgICAgICAgLy9nZW5lcmF0ZVZlcnRpY2FsU2xpY2UoU0NSSVBULCBTQ1JJUFQrMSwgS0VFUF9TUEVDSUFMLCAiU2NyaXB0Q29tbW9uLTMuMS4wZDEudHh0Iik7CiAgICAgICAgLy9saXN0U3RyaW5ncygiTG93ZXJDYXNlLTMuMS4wZDEudHh0IiwgMCwwKTsKICAgICAgICAvL2dlbmVyYXRlVmVydGljYWxTbGljZSgwLCBMSU1JVF9FTlVNLCBTS0lQX1NQRUNJQUwsIFBST1BMSVNUMSwgIkRlcml2ZWRQcm9wRGF0YTEtMy4xLjBkMS50eHQiKTsKCiAgICAgICAgLy8gQUdFIHN0dWZmCiAgICAgICAgLy9VQ0QgdWNkID0gVUNELm1ha2UoKTsKICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbih1Y2QuZ2V0QWdlSUQoMHg2MSkpOwogICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKHVjZC5nZXRBZ2VJRCgweDJGQTFEKSk7CgoKICAgICAgICAvL2dlbmVyYXRlQ29tcEV4Y2x1c2lvbnMoKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVORCIpOwogICAgfQoKICAgc3RhdGljIE5vcm1hbGl6ZXIgbmZrYyA9IG5ldyBOb3JtYWxpemVyKE5vcm1hbGl6ZXIuTkZLQyk7CgogICAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrSG9mZm1hbihTdHJpbmcgdGVzdCkgewogICAgICAgIFN0cmluZyByZXN1bHQgPSBuZmtjLm5vcm1hbGl6ZSh0ZXN0KTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oVXRpbGl0eS5oZXgodGVzdCkgKyAiID0+ICIgKyBVdGlsaXR5LmhleChyZXN1bHQpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICBzaG93KHRlc3QsIDApOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgIHNob3cocmVzdWx0LCAwKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2hvdyhTdHJpbmcgcywgaW50IGluZGVudCkgewogICAgICAgIGludCBjcDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMubGVuZ3RoKCk7IGkgKz0gVVRGMzIuY291bnQxNihjcCkpIHsKICAgICAgICAgICAgY3AgPSBVVEYzMi5jaGFyMzJBdChzLCBpKTsKICAgICAgICAgICAgU3RyaW5nIGNjID0gIiAiICsgdWNkLmdldENvbWJpbmluZ0NsYXNzKGNwKTsKICAgICAgICAgICAgY2MgPSBVdGlsaXR5LnJlcGVhdCgiICIsIDQgLSBjYy5sZW5ndGgoKSkgKyBjYzsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKFV0aWxpdHkucmVwZWF0KCIgIiwgaW5kZW50KSArIHVjZC5nZXRDb2RlKGNwKSArIGNjICsgIiAiICsgdWNkLmdldE5hbWUoY3ApKTsKICAgICAgICAgICAgU3RyaW5nIGRlY29tcCA9IG5ma2Mubm9ybWFsaXplKGNwKTsKICAgICAgICAgICAgaWYgKCFkZWNvbXAuZXF1YWxzKFVURjMyLnZhbHVlT2YzMihjcCkpKSB7CiAgICAgICAgICAgICAgICBzaG93KGRlY29tcCwgaW5kZW50ICsgNCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIC8vUmVtb3ZlICJkMSIgZnJvbSBEZXJpdmVkSm9pbmluZ0dyb3VwLTMuMS4wZDEudHh0IHR5cGUgbmFtZXMKCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmaXhGaWxlKFN0cmluZyBzKSB7CiAgICAgICAgaW50IGxlbiA9IHMubGVuZ3RoKCk7CiAgICAgICAgaWYgKCFzLmVuZHNXaXRoKCIudHh0IikpIHJldHVybiBzOwogICAgICAgIGlmIChzLmNoYXJBdChsZW4tNikgIT0gJ2QnKSByZXR1cm4gczsKICAgICAgICBjaGFyIGMgPSBzLmNoYXJBdChsZW4tNSk7CiAgICAgICAgaWYgKGMgPCAnMCcgfHwgJzknIDwgYykgcmV0dXJuIHM7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGaXhpbmcgRmlsZSBOYW1lIik7CiAgICAgICAgcmV0dXJuIHMuc3Vic3RyaW5nKDAsbGVuLTYpICsgcy5zdWJzdHJpbmcobGVuLTQpOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBpbnQgSEVBREVSX0VYVEVORCA9IDAsIEhFQURFUl9ERVJJVkVEID0gMSwgSEVBREVSX1NDUklQVFMgPSAyOwoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBkb0hlYWRlcihTdHJpbmcgZmlsZU5hbWUsIFByaW50V3JpdGVyIG91dHB1dCwgaW50IGhlYWRlckNob2ljZSkgewogICAgICAgIG91dHB1dC5wcmludGxuKCIjICIgKyBmaXhGaWxlKGZpbGVOYW1lKSk7CiAgICAgICAgb3V0cHV0LnByaW50bG4oIiMiKTsKICAgICAgICBpZiAoaGVhZGVyQ2hvaWNlID09IEhFQURFUl9TQ1JJUFRTKSB7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjIEZvciBkb2N1bWVudGF0aW9uLCBzZWUgVVRSICMyNDogU2NyaXB0IE5hbWVzIik7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjICAgaHR0cDovL3d3dy51bmljb2RlLm9yZy91bmljb2RlL3JlcG9ydHMvdHIyNC8iKTsKICAgICAgICB9IGVsc2UgaWYgKGhlYWRlckNob2ljZSA9PSBIRUFERVJfRVhURU5EKSB7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjIFVuaWNvZGUgQ2hhcmFjdGVyIERhdGFiYXNlOiBFeHRlbmRlZCBQcm9wZXJ0aWVzIik7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjIEZvciBkb2N1bWVudGF0aW9uLCBzZWUgUHJvcExpc3QuaHRtbCIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjIFVuaWNvZGUgQ2hhcmFjdGVyIERhdGFiYXNlOiBEZXJpdmVkIFByb3BlcnR5IERhdGEiKTsKICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oIiMgR2VuZXJhdGVkIGFsZ29yaXRobWljYWxseSBmcm9tIHRoZSBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZSIpOwogICAgICAgICAgICBvdXRwdXQucHJpbnRsbigiIyBGb3IgZG9jdW1lbnRhdGlvbiwgc2VlIERlcml2ZWRQcm9wZXJ0aWVzLmh0bWwiKTsKICAgICAgICB9CiAgICAgICAgb3V0cHV0LnByaW50bG4oIiMgRGF0ZTogIiArIG15RGF0ZUZvcm1hdC5mb3JtYXQobmV3IERhdGUoKSkgKyAiIFtNRF0iKTsKICAgICAgICBvdXRwdXQucHJpbnRsbigiIyBOb3RlOiBVbmFzc2lnbmVkIGFuZCBOb25jaGFyYWN0ZXIgY29kZXBvaW50cyBhcmUgb21pdHRlZCwiKTsKICAgICAgICBvdXRwdXQucHJpbnRsbigiIyAgICAgICBleGNlcHQgd2hlbiBsaXN0aW5nIE5vbmNoYXJhY3RlciBvciBDbi4iKTsKICAgICAgICBvdXRwdXQucHJpbnRsbigiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKICAgICAgICBvdXRwdXQucHJpbnRsbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBnZW5lcmF0ZURlcml2ZWQgKGxvbmcgYml0TWFzaywgaW50IGhlYWRlckNob2ljZSwgU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHVjZCA9IFVDRC5tYWtlKCIzLjEuMCIpOwogICAgICAgIFByaW50V3JpdGVyIG91dHB1dCA9IFV0aWxpdHkub3BlblByaW50V3JpdGVyKGZpbGVOYW1lKTsKICAgICAgICBkb0hlYWRlcihmaWxlTmFtZSwgb3V0cHV0LCBoZWFkZXJDaG9pY2UpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzI7ICsraSkgewogICAgICAgICAgICBpZiAoKGJpdE1hc2sgJiAoMTw8aSkpID09IDApIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoaSA+PSBERVJJVkVEX1BST1BFUlRZX0xJTUlUKSBicmVhazsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgnLicpOwogICAgICAgICAgICBvdXRwdXQucHJpbnRsbigiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oKTsKICAgICAgICAgICAgbmV3IERlcml2ZWRQcm9wZXJ0eUxpc3Rlcih1Y2QsIGksIG91dHB1dCkucHJpbnQoKTsKICAgICAgICB9CiAgICAgICAgb3V0cHV0LmNsb3NlKCk7CiAgICB9CgogICAgLyoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBsaXN0U3RyaW5ncyhTdHJpbmcgZmlsZSwgaW50IHR5cGUsIGludCBzdWJ0eXBlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHVjZCA9IFVDRC5tYWtlKCIzLjEuMCIpOwogICAgICAgIFVDRCB1Y2QzMCA9IFVDRC5tYWtlKCIzLjAuMCIpOwogICAgICAgIFByaW50V3JpdGVyIG91dHB1dCA9IG5ldyBQcmludFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShHRU5fRElSICsgZmlsZSkpOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDB4MTBGRkZGOyArK2kpIHsKICAgICAgICAgICAgaWYgKChpICYgMHhGRkYpID09IDApIFN5c3RlbS5vdXQucHJpbnRsbigiIyAiICsgaSk7CiAgICAgICAgICAgIGlmICghdWNkLmlzUmVwcmVzZW50ZWQoaSkpIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAodWNkMzAuaXNSZXByZXNlbnRlZChpKSkgY29udGludWU7CiAgICAgICAgICAgIFN0cmluZyBzdHJpbmcgPSAiIjsKICAgICAgICAgICAgc3dpdGNoKHR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDogc3RyaW5nID0gdWNkLmdldFNpbXBsZUxvd2VyY2FzZShpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoVVRGMzIubGVuZ3RoMzIoc3RyaW5nKSA9PSAxICYmIFVURjMyLmNoYXIzMkF0KHN0cmluZywwKSA9PSBpKSBjb250aW51ZTsKICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oVXRpbGl0eS5oZXgoaSkgKyAiOyBDOyAiICsgVXRpbGl0eS5oZXgoc3RyaW5nKSArICI7ICMgIiArIHVjZC5nZXROYW1lKGkpKTsKICAgICAgICB9CiAgICAgICAgb3V0cHV0LmNsb3NlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIGdlbmVyYXRlQ29tcEV4Y2x1c2lvbnMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIFByaW50V3JpdGVyIG91dHB1dCA9IFV0aWxpdHkub3BlblByaW50V3JpdGVyKCJDb21wb3NpdGlvbkV4Y2x1c2lvbnNEZWx0YS50eHQiKTsKICAgICAgICBuZXcgQ29tcExpc3RlcihvdXRwdXQpLnByaW50KCk7CiAgICAgICAgb3V0cHV0LmNsb3NlKCk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIENvbXBMaXN0ZXIgZXh0ZW5kcyBQcm9wZXJ0eUxpc3RlciB7CiAgICAgICAgVUNEIG9sZFVDRDsKICAgICAgICBpbnQgb2xkTGVuZ3RoID0gMDsKCiAgICAgICAgcHVibGljIENvbXBMaXN0ZXIoUHJpbnRXcml0ZXIgb3V0cHV0KSB7CiAgICAgICAgICAgIHRoaXMub3V0cHV0ID0gb3V0cHV0OwogICAgICAgICAgICB1Y2REYXRhID0gVUNELm1ha2UoIjMuMS4wIik7CiAgICAgICAgICAgIG9sZFVDRCA9IFVDRC5tYWtlKCIzLjAuMCIpOwogICAgICAgICAgICBzaG93T25Db25zb2xlID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFN0cmluZyB2YWx1ZU5hbWUoaW50IGNwKSB7CiAgICAgICAgICAgIHJldHVybiBVVEYzMi5sZW5ndGgzMih1Y2REYXRhLmdldERlY29tcG9zaXRpb25NYXBwaW5nKGNwKSkgKyAiIjsKICAgICAgICB9CiAgICAgICAgcHVibGljIGJ5dGUgc3RhdHVzKGludCBjcCkgewogICAgICAgICAgICBpZiAodWNkRGF0YS5nZXREZWNvbXBvc2l0aW9uVHlwZShjcCkgPT0gQ0FOT05JQ0FMCiAgICAgICAgICAgICAgJiYgb2xkVUNELmdldERlY29tcG9zaXRpb25UeXBlKGNwKSAhPSBDQU5PTklDQUwpIHsKICAgICAgICAgICAgICAgIGludCB0ZW1wID0gb2xkTGVuZ3RoOwogICAgICAgICAgICAgICAgb2xkTGVuZ3RoID0gVVRGMzIubGVuZ3RoMzIodWNkRGF0YS5nZXREZWNvbXBvc2l0aW9uTWFwcGluZyhjcCkpOwogICAgICAgICAgICAgICAgaWYgKHRlbXAgIT0gb2xkTGVuZ3RoKSByZXR1cm4gQlJFQUs7CiAgICAgICAgICAgICAgICByZXR1cm4gSU5DTFVERTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gRVhDTFVERTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGJ5dGUgS0VFUF9TUEVDSUFMID0gMCwgU0tJUF9TUEVDSUFMID0gMTsKCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgZ2VuZXJhdGVWZXJ0aWNhbFNsaWNlKGludCBzdGFydEVudW0sIGludCBlbmRFbnVtLCBieXRlIHNraXBTcGVjaWFsLCBpbnQgaGVhZGVyQ2hvaWNlLCBTdHJpbmcgZmlsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCiAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4odWNkLnRvU3RyaW5nKDB4MUUwQSkpOwogICAgICAgIC8qCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHVjZC5nZXREYXRhKDB4RkZGRikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih1Y2QuZ2V0RGF0YSgweDEwMDAwMCkpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih1Y2QuZ2V0RGF0YSgweDEwMDAwMC0xKSk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKHVjZC5nZXREYXRhKDB4MTAwMDAwLTIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4odWNkLmdldERhdGEoMHgxMDAwMDAtMykpOwogICAgICAgIGlmICh0cnVlKSByZXR1cm47CiAgICAgICAgU3RyaW5nIHRlc3QyID0gdWNkLmdldE5hbWUoMHgyQTZENik7CiAgICAgICAgLy8qIC8KCgogICAgICAgIFByaW50V3JpdGVyIG91dHB1dCA9IFV0aWxpdHkub3BlblByaW50V3JpdGVyKGZpbGUpOwogICAgICAgIGRvSGVhZGVyKGZpbGUsIG91dHB1dCwgaGVhZGVyQ2hvaWNlKTsKICAgICAgICAKICAgICAgICBpbnQgbGFzdCA9IC0xOwogICAgICAgIGZvciAoaW50IGkgPSBzdGFydEVudW07IGkgPCBlbmRFbnVtOyArK2kpIHsKICAgICAgICAgICAgVW5pY29kZVByb3BlcnR5IHVwID0gVW5pZmllZEJpbmFyeVByb3BlcnR5Lm1ha2UoaSwgdWNkKTsKICAgICAgICAgICAgaWYgKHVwID09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGkgPT0gREVDT01QT1NJVElPTl9UWVBFIHx8IGkgPT0gTlVNRVJJQ19UWVBFCiAgICAgICAgICAgICAgICB8fCBpID09IChDQVRFR09SWSB8IFVOVVNFRF9DQVRFR09SWSkKICAgICAgICAgICAgICAgIHx8IGkgPT0gKEJJTkFSWV9QUk9QRVJUSUVTIHwgTm9uX2JyZWFrKQogICAgICAgICAgICAgICAgfHwgaSA9PSAoSk9JTklOR19UWVBFIHwgSlRfVSkKICAgICAgICAgICAgICAgIHx8IGkgPT0gKFNDUklQVCB8IFVOVVNFRF9TQ1JJUFQpCiAgICAgICAgICAgICAgICB8fCBpID09IChKT0lOSU5HX0dST1VQIHwgTk9fU0hBUElORykKICAgICAgICAgICAgICAgICkgY29udGludWU7IC8vIHNraXAgemVybyBjYXNlCiAgICAgICAgICAgIGlmIChza2lwU3BlY2lhbCA9PSBTS0lQX1NQRUNJQUwKICAgICAgICAgICAgICAgICAgICAmJiBpID49IChCSU5BUllfUFJPUEVSVElFUyB8IENvbXBvc2l0aW9uRXhjbHVzaW9uKQogICAgICAgICAgICAgICAgICAgICYmIGkgPCAoQUdFICsgTkVYVF9FTlVNKSkgY29udGludWU7CiAgICAgICAgICAgIGlmICgobGFzdCAmIDB4RkYwMCkgIT0gKGkgJiAweEZGMDApICYmIChpIDw9IEJJTkFSWV9QUk9QRVJUSUVTIHx8IGkgPj0gU0NSSVBUKSkgewogICAgICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oKTsKICAgICAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oIiMgIiArIFVDRF9OYW1lcy5VTklGSUVEX1BST1BFUlRJRVNbaT4+OF0pOwogICAgICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oIiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CiAgICAgICAgICAgICAgICBvdXRwdXQucHJpbnRsbigpOwogICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oVUNEX05hbWVzLlVOSUZJRURfUFJPUEVSVElFU1tpPj44XSk7CiAgICAgICAgICAgICAgICBsYXN0ID0gaTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIuIik7CiAgICAgICAgICAgIG5ldyBNeVByb3BlcnR5TGlzdGVyKHVjZCwgaSwgb3V0cHV0KS5wcmludCgpOwogICAgICAgIH0KICAgICAgICBpZiAoZW5kRW51bSA9PSBMSU1JVF9FTlVNKSB7CiAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCk7CiAgICAgICAgICAgICAgICBvdXRwdXQucHJpbnRsbigiIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oIiMgTnVtZXJpYyBWYWx1ZXMgKGZyb20gVW5pY29kZURhdGEudHh0LCBmaWVsZCA2LzcvOCkiKTsKICAgICAgICAgICAgICAgIG91dHB1dC5wcmludGxuKCIjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgICAgICAgICBvdXRwdXQucHJpbnRsbigpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJATlVNRVJJQyBWQUxVRVMiKTsKCiAgICAgICAgICAgIFNldCBmbG9hdFNldCA9IG5ldyBUcmVlU2V0KCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMHgxMEZGRkY7ICsraSkgewogICAgICAgICAgICAgICAgZmxvYXQgbnYgPSB1Y2QuZ2V0TnVtZXJpY1ZhbHVlKGkpOwogICAgICAgICAgICAgICAgaWYgKEZsb2F0LmlzTmFOKG52KSkgY29udGludWU7CiAgICAgICAgICAgICAgICBmbG9hdFNldC5hZGQobmV3IEZsb2F0KG52KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSXRlcmF0b3IgaXQgPSBmbG9hdFNldC5pdGVyYXRvcigpOwogICAgICAgICAgICB3aGlsZShpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIG5ldyBNeUZsb2F0TGlzdGVyKHVjZCwgKChGbG9hdClpdC5uZXh0KCkpLmZsb2F0VmFsdWUoKSwgb3V0cHV0KS5wcmludCgpOwogICAgICAgICAgICAgICAgb3V0cHV0LnByaW50bG4oKTsKICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIi4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvdXRwdXQuY2xvc2UoKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgIH0KCiAgICBzdGF0aWMgVUNEIHVjZDsKCiAgICBzdGF0aWMgcHVibGljIE5vcm1hbGl6ZXIgZm9ybUMsIGZvcm1ELCBmb3JtS0MsIGZvcm1LRDsKCiAgICBzdGF0aWMgcHVibGljIHZvaWQgd3JpdGVOb3JtYWxpemVyVGVzdFN1aXRlKFN0cmluZyBmaWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCiAgICAgICAgUHJpbnRXcml0ZXIgbG9nID0gbmV3IFByaW50V3JpdGVyKAogICAgICAgICAgICBuZXcgQnVmZmVyZWRXcml0ZXIoCiAgICAgICAgICAgIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoCiAgICAgICAgICAgICAgICBuZXcgRmlsZU91dHB1dFN0cmVhbShHRU5fRElSICsgZmlsZU5hbWUpLAogICAgICAgICAgICAgICAgIlVURjgiKSwKICAgICAgICAgICAgMzIqMTAyNCkpOwoJICAgIGZvcm1DID0gbmV3IE5vcm1hbGl6ZXIoTm9ybWFsaXplci5ORkMpOwoJICAgIGZvcm1EID0gbmV3IE5vcm1hbGl6ZXIoTm9ybWFsaXplci5ORkQpOwoJICAgIGZvcm1LQyA9IG5ldyBOb3JtYWxpemVyKE5vcm1hbGl6ZXIuTkZLQyk7CgkgICAgZm9ybUtEID0gbmV3IE5vcm1hbGl6ZXIoTm9ybWFsaXplci5ORktEKTsKCiAgICAgICAgbG9nLnByaW50bG4oIiMgIiArIGZpeEZpbGUoZmlsZU5hbWUpKTsKICAgICAgICBsb2cucHJpbnRsbigiIyIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIE5vcm1hbGl6YXRpb24gVGVzdCBTdWl0ZSIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIERhdGU6ICIgKyBteURhdGVGb3JtYXQuZm9ybWF0KG5ldyBEYXRlKCkpICsgIiBbTURdIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMgRm9ybWF0OiIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMgICBDb2x1bW5zIChjMSwgYzIsLi4uKSBhcmUgc2VwYXJhdGVkIGJ5IHNlbWljb2xvbnMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgIENvbW1lbnRzIGFyZSBpbmRpY2F0ZWQgd2l0aCBoYXNoIG1hcmtzIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyBDT05GT1JNQU5DRToiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAxLiBUaGUgZm9sbG93aW5nIGludmFyaWFudHMgbXVzdCBiZSB0cnVlIGZvciBhbGwgY29uZm9ybWFudCBpbXBsZW1lbnRhdGlvbnMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyIpOwogICAgICAgIGxvZy5wcmludGxuKCIjICAgIE5GQyIpOwogICAgICAgIGxvZy5wcmludGxuKCIjICAgICAgYzIgPT0gIE5GQyhjMSkgPT0gIE5GQyhjMikgPT0gIE5GQyhjMykiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgICAgIGM0ID09ICBORkMoYzQpID09ICBORkMoYzUpIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgICBORkQiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgICAgIGMzID09ICBORkQoYzEpID09ICBORkQoYzIpID09ICBORkQoYzMpIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMgICAgICBjNSA9PSAgTkZEKGM0KSA9PSAgTkZEKGM1Iik7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgICBORktDIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMgICAgICBjNCA9PSBORktDKGMxKSA9PSBORktDKGMyKSA9PSBORktDKGMzKSA9PSBORktDKGM0KSA9PSBORktDKGM1KSIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMgICAgTkZLRCIpOwogICAgICAgIGxvZy5wcmludGxuKCIjICAgICAgYzUgPT0gTkZLRChjMSkgPT0gTkZLRChjMikgPT0gTkZLRChjMykgPT0gTkZLRChjNCkgPT0gTkZLRChjNSkiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIDIuIEZvciBldmVyeSBhc3NpZ25lZCBVbmljb2RlIDMuMS4wIGNvZGUgcG9pbnQgWCB0aGF0IGlzIG5vdCBzcGVjaWZpY2FsbHkiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyAgICBsaXN0ZWQgaW4gUGFydCAxLCB0aGUgZm9sbG93aW5nIGludmFyaWFudHMgbXVzdCBiZSB0cnVlIGZvciBhbGwgY29uZm9ybWFudCIpOwogICAgICAgIGxvZy5wcmludGxuKCIjICAgIGltcGxlbWVudGF0aW9uczoiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyIpOwogICAgICAgIGxvZy5wcmludGxuKCIjICAgICAgWCA9PSBORkMoWCkgPT0gTkZEKFgpID09IE5GS0MoWCkgPT0gTkZLRChYKSIpOwoKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldyaXRpbmcgUGFydCAxIik7CgogICAgICAgIGxvZy5wcmludGxuKCIjIik7CiAgICAgICAgbG9nLnByaW50bG4oIkBQYXJ0MCAjIFNwZWNpZmljIGNhc2VzIik7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKCiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCB0ZXN0U3VpdGVDYXNlcy5sZW5ndGg7ICsraikgewogICAgICAgICAgICB3cml0ZUxpbmUodGVzdFN1aXRlQ2FzZXNbal0sIGxvZywgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJXcml0aW5nIFBhcnQgMiIpOwoKICAgICAgICBsb2cucHJpbnRsbigiIyIpOwogICAgICAgIGxvZy5wcmludGxuKCJAUGFydDEgIyBDaGFyYWN0ZXIgYnkgY2hhcmFjdGVyIHRlc3QiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyBBbGwgY2hhcmFjdGVycyBub3QgZXhwbGljaXRseSBvY2N1cnJpbmcgaW4gYzEgb2YgUGFydCAxIGhhdmUgaWRlbnRpY2FsIE5GQywgRCwgS0MsIEtEIGZvcm1zLiIpOwogICAgICAgIGxvZy5wcmludGxuKCIjIik7CgogICAgICAgIGZvciAoaW50IGNoID0gMDsgY2ggPCAweDEwRkZGRjsgKytjaCkgewogICAgICAgICAgICBVdGlsaXR5LmRvdChjaCk7CiAgICAgICAgICAgIGlmICghdWNkLmlzQXNzaWduZWQoY2gpKSBjb250aW51ZTsKICAgICAgICAgICAgaWYgKHVjZC5pc1BVQShjaCkpIGNvbnRpbnVlOwogICAgICAgICAgICBTdHJpbmcgY2MgPSBVVEYzMi52YWx1ZU9mMzIoY2gpOwogICAgICAgICAgICB3cml0ZUxpbmUoY2MsbG9nLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgVXRpbGl0eS5maXhEb3QoKTsKCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJGaW5kaW5nIEV4YW1wbGVzIik7CgogICAgICAgIFN0cmluZ1tdIGV4YW1wbGUgPSBuZXcgU3RyaW5nWzI1Nl07CgogICAgICAgIGZvciAoaW50IGNoID0gMDsgY2ggPCAweDEwRkZGRjsgKytjaCkgewogICAgICAgICAgICBVdGlsaXR5LmRvdChjaCk7CiAgICAgICAgICAgIGlmICghdWNkLmlzQXNzaWduZWQoY2gpKSBjb250aW51ZTsKICAgICAgICAgICAgaWYgKHVjZC5pc1BVQShjaCkpIGNvbnRpbnVlOwogICAgICAgICAgICBpbnQgY2MgPSB1Y2QuZ2V0Q29tYmluaW5nQ2xhc3MoY2gpOwogICAgICAgICAgICBpZiAoZXhhbXBsZVtjY10gPT0gbnVsbCkgZXhhbXBsZVtjY10gPSBVVEYzMi52YWx1ZU9mMzIoY2gpOwogICAgICAgIH0KCiAgICAgICAgVXRpbGl0eS5maXhEb3QoKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIldyaXRpbmcgUGFydCAzIik7CgogICAgICAgIGxvZy5wcmludGxuKCIjIik7CiAgICAgICAgbG9nLnByaW50bG4oIkBQYXJ0MiAjIENhbm9uaWNhbCBPcmRlciBUZXN0Iik7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKCiAgICAgICAgZm9yIChpbnQgY2ggPSAwOyBjaCA8IDB4MTBGRkZGOyArK2NoKSB7CiAgICAgICAgICAgIFV0aWxpdHkuZG90KGNoKTsKICAgICAgICAgICAgaWYgKCF1Y2QuaXNBc3NpZ25lZChjaCkpIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAodWNkLmlzUFVBKGNoKSkgY29udGludWU7CiAgICAgICAgICAgIHNob3J0IGMgPSB1Y2QuZ2V0Q29tYmluaW5nQ2xhc3MoY2gpOwogICAgICAgICAgICBpZiAoYyA9PSAwKSBjb250aW51ZTsKCiAgICAgICAgICAgIC8vIGFkZCBjaGFyYWN0ZXIgd2l0aCBoaWdoZXIgY2xhc3MsIHNhbWUgY2xhc3MsIGxvd2VyIGNsYXNzCgogICAgICAgICAgICBTdHJpbmcgc2FtcGxlID0gIiI7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBjKzE7IGkgPCBleGFtcGxlLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoZXhhbXBsZVtpXSA9PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIHNhbXBsZSArPSBleGFtcGxlW2ldOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2FtcGxlICs9IGV4YW1wbGVbY107CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBjLTE7IGkgPiAwOyAtLWkpIHsKICAgICAgICAgICAgICAgIGlmIChleGFtcGxlW2ldID09IG51bGwpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgc2FtcGxlICs9IGV4YW1wbGVbaV07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgd3JpdGVMaW5lKCJhIiArIHNhbXBsZSArIFVURjMyLnZhbHVlT2YzMihjaCkgKyAiYiIsIGxvZywgZmFsc2UpOwogICAgICAgICAgICB3cml0ZUxpbmUoImEiICsgVVRGMzIudmFsdWVPZjMyKGNoKSArIHNhbXBsZSArICJiIiwgbG9nLCBmYWxzZSk7CiAgICAgICAgfQogICAgICAgIFV0aWxpdHkuZml4RG90KCk7CiAgICAgICAgbG9nLnByaW50bG4oIiMiKTsKICAgICAgICBsb2cucHJpbnRsbigiIyBFTkQgT0YgRklMRSIpOwogICAgICAgIGxvZy5jbG9zZSgpOwogICAgfQoKICAgIHN0YXRpYyB2b2lkIHdyaXRlTGluZShTdHJpbmcgY2MsIFByaW50V3JpdGVyIGxvZywgYm9vbGVhbiBjaGVjaykgewogICAgICAgIFN0cmluZyBjID0gZm9ybUMubm9ybWFsaXplKGNjKTsKICAgICAgICBTdHJpbmcgZCA9IGZvcm1ELm5vcm1hbGl6ZShjYyk7CiAgICAgICAgU3RyaW5nIGtjID0gZm9ybUtDLm5vcm1hbGl6ZShjYyk7CiAgICAgICAgU3RyaW5nIGtkID0gZm9ybUtELm5vcm1hbGl6ZShjYyk7CiAgICAgICAgaWYgKGNoZWNrICYgY2MuZXF1YWxzKGMpICYmIGNjLmVxdWFscyhkKSAmJiBjYy5lcXVhbHMoa2MpICYmIGNjLmVxdWFscyhrZCkpIHJldHVybjsKICAgICAgICBsb2cucHJpbnRsbigKICAgICAgICAgICAgVXRpbGl0eS5oZXgoY2MsIiAiKSArICI7IiArIFV0aWxpdHkuaGV4KGMsIiAiKSArICI7IiArIFV0aWxpdHkuaGV4KGQsIiAiKSArICI7IgogICAgICAgICAgICArIFV0aWxpdHkuaGV4KGtjLCIgIikgKyAiOyIgKyBVdGlsaXR5LmhleChrZCwiICIpCiAgICAgICAgICAgICsgIjsgIyAoIgogICAgICAgICAgICArIGNvbW1hKGNjKSArICI7ICIgKyBjb21tYShjKSArICI7ICIgKyBjb21tYShkKSArICI7ICIgKyBjb21tYShrYykgKyAiOyAiICsgY29tbWEoa2QpICsgIjsgIgogICAgICAgICAgICArICIpICIgKyB1Y2QuZ2V0TmFtZShjYykpOwogICAgfQoKICAgIHN0YXRpYyBTdHJpbmdCdWZmZXIgY29tbWFSZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgogICAgLy8gbm90IHJlY3Vyc2l2ZSEhIQogICAgc3RhdGljIGZpbmFsIFN0cmluZyBjb21tYShTdHJpbmcgcykgewogICAgICAgIGNvbW1hUmVzdWx0LnNldExlbmd0aCgwKTsKICAgICAgICBpbnQgY3A7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyBpICs9IFVURjMyLmNvdW50MTYoaSkpIHsKICAgICAgICAgICAgY3AgPSBVVEYzMi5jaGFyMzJBdChzLCBpKTsKICAgICAgICAgICAgaWYgKHVjZC5nZXRDYXRlZ29yeShjcCkgPT0gTW4pIGNvbW1hUmVzdWx0LmFwcGVuZCgnXHUyNUNDJyk7CiAgICAgICAgICAgIFVURjMyLmFwcGVuZDMyKGNvbW1hUmVzdWx0LCBjcCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb21tYVJlc3VsdC50b1N0cmluZygpOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSB0ZXN0U3VpdGVDYXNlcyA9IHsKICAgICAgICAiXHUxRTBBIiwKICAgICAgICAiXHUxRTBDIiwKICAgICAgICAiXHUxRTBBXHUwMzIzIiwKICAgICAgICAiXHUxRTBDXHUwMzA3IiwKICAgICAgICAiRFx1MDMwN1x1MDMyMyIsCiAgICAgICAgIkRcdTAzMjNcdTAzMDciLAogICAgICAgICJcdTFFMEFcdTAzMUIiLAogICAgICAgICJcdTFFMENcdTAzMUIiLAogICAgICAgICJcdTFFMEFcdTAzMUJcdTAzMjMiLAogICAgICAgICJcdTFFMENcdTAzMUJcdTAzMDciLAogICAgICAgICJEXHUwMzFCXHUwMzA3XHUwMzIzIiwKICAgICAgICAiRFx1MDMxQlx1MDMyM1x1MDMwNyIsCiAgICAgICAgIlx1MDBDOCIsCiAgICAgICAgIlx1MDExMiIsCiAgICAgICAgIkVcdTAzMDAiLAogICAgICAgICJFXHUwMzA0IiwKICAgICAgICAiXHUxRTE0IiwKICAgICAgICAiXHUwMTEyXHUwMzAwIiwKICAgICAgICAiXHUxRTE0XHUwMzA0IiwKICAgICAgICAiRVx1MDMwNFx1MDMwMCIsCiAgICAgICAgIkVcdTAzMDBcdTAzMDQiLAogICAgfTsKLy8qLwp9