LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vdGVzdC9zZWFyY2gvQXR0aWMvU2VhcmNoVGVzdC5qYXZhLHYgJCAKICogJERhdGU6IDIwMDAvMDMvMTAgMDM6NDc6NDcgJCAKICogJFJldmlzaW9uOiAxLjIgJAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCnBhY2thZ2UgY29tLmlibS50ZXN0LnNlYXJjaDsKCmltcG9ydCBqYXZhLnRleHQuKjsKaW1wb3J0IGphdmEudXRpbC4qOwoKLy9pbXBvcnQgY29tLmlibS50ZXh0Lio7CmltcG9ydCBjb20uaWJtLnRleHQuU2VhcmNoSXRlcmF0b3I7CmltcG9ydCBjb20uaWJtLnRleHQuU3RyaW5nU2VhcmNoOwoKLyoqCiAqIFVuaXQgYW5kIHJlZ3Jlc3Npb24gdGVzdHMgZm9yIHRoZSBTdHJpbmdTZWFyY2ggYW5kIFNlYXJjaEl0ZXJhdG9yIGNsYXNzZXMuCiAqIFRoaXMgdXNlcyA8Y29kZT5JbnRsVGVzdDwvY29kZT4gYXMgYSBmcmFtZXdvcmsgZm9yIHJ1bm5pbmcgdGhlIHRlc3RzCiAqIGFuZCBkaXNwbGF5aW5nIHRoZSBvdXRwdXQuICBCYXNpY2FsbHksIGFueSBtZXRob2QgaGVyZSB0aGF0IHN0YXJ0cyB3aXRoCiAqIDxjb2RlPlRlc3Q8L2NvZGU+IGlzIHJ1biBhcyBhIHRlc3QuCiAqLwpwdWJsaWMgY2xhc3MgU2VhcmNoVGVzdCBleHRlbmRzIGNvbS5pYm0udGVzdC5UZXN0Rm13ayB7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKICAgICAgICBuZXcgU2VhcmNoVGVzdCgpLnJ1bihhcmdzKTsKICAgIH0KICAgIAogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gU3RhdGljIGRhdGE6IGNvbGxhdG9ycyBhbmQgYnJlYWsgaXRlcmF0b3JzIHRvIHVzZSBmb3IgdGVzdGluZwogICAgLy8KICAgIHN0YXRpYyBSdWxlQmFzZWRDb2xsYXRvciBlbkNvbGw7ICAgICAgICAvLyBHZW5lcmljIEVuZ2xpc2ggY29sbGF0b3IKICAgIHN0YXRpYyBSdWxlQmFzZWRDb2xsYXRvciBmckNvbGw7ICAgICAgICAvLyBGcmVuY2ggYWNjZW50IHJ1bGVzCiAgICBzdGF0aWMgUnVsZUJhc2VkQ29sbGF0b3IgZXNDb2xsOyAgICAgICAgLy8gSGFzIFNwYW5pc2ggY29udHJhY3RpbmcgImNoIgogICAgc3RhdGljIFJ1bGVCYXNlZENvbGxhdG9yIGRlQ29sbDsgICAgICAgIC8vIEhhcyBleHBhbnNpb25zLCBlLmcuIGEtdW1sYXV0IC0+IGFlCiAgICAKICAgIHN0YXRpYyB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZW5Db2xsID0gKFJ1bGVCYXNlZENvbGxhdG9yKUNvbGxhdG9yLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CiAgICAgICAgICAgIGZyQ29sbCA9IChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvci5nZXRJbnN0YW5jZShMb2NhbGUuRlJBTkNFKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGVzQ29sbCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbkNvbGwuZ2V0UnVsZXMoKSArICIgJiBDIDwgY2ggOyBjSCA7IENoIDsgQ0giKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGRlQ29sbCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbkNvbGwuZ2V0UnVsZXMoKSArICIgJiBhZSA7IOQgJiBBRSA7IMQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgJiBvZSA7IPYgJiBPRSA7INYiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgJiB1ZSA7IPwgJiBVRSA7INwiKTsgCiAgICAgICAgfQogICAgICAgIGNhdGNoIChQYXJzZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgfQogICAgfQogICAgCiAgICBzdGF0aWMgQnJlYWtJdGVyYXRvciBlbldvcmQgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZShMb2NhbGUuVVMpOwogICAgCiAgICBzdGF0aWMgU3RyaW5nIHRlc3RTdHJpbmcgPSAKICAgICAgICAgICAgImJsYWNrYmlyZHMgUGF0IHBcdTAwRTljaFx1MDBFOSAiICsKICAgICAgICAgICAgInBcdTAwRUFjaGUgcFx1MDBFOWNoZXIgcFx1MDBFQWNoZXIgIiArCiAgICAgICAgICAgICJUb2QgVFx1MDBGNm5lIGJsYWNrIFRvZnUgYmxhY2tiaXJkcyAiICsKICAgICAgICAgICAgIlRvbiBQQVQgdG9laG9sZCAiICsKICAgICAgICAgICAgImJsYWNrYmlyZCAiICsKICAgICAgICAgICAgImJsYWNrLWJpcmQgcGF0ICIgKwogICAgICAgICAgICAidG9lIGJpZyBUb2UiOwogICAgCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFRoZSBwcmltYXJ5IHRlc3QgY29uc2lzdHMgb2YgcnVubmluZyB0aHJvdWdoIGFsbCBvZiB0aGUgc3RyaW5ncyBpbiB0aGlzCiAgICAvLyB0YWJsZSBhbmQgbWFraW5nIHN1cmUgd2UgZmluZCB0aGUgcHJvcGVyIG1hdGNoZXMKICAgIC8vCiAgICBzdGF0aWMgY2xhc3MgVGVzdENhc2UgewogICAgICAgIFRlc3RDYXNlKFJ1bGVCYXNlZENvbGxhdG9yIGMsIGludCBzdHJlbmd0aCwgQnJlYWtJdGVyYXRvciBicmVha2VyLAogICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXR0ZXJuLCBTdHJpbmcgdGFyZ2V0LCBpbnRbXSBtYXRjaGVzKSB7CiAgICAgICAgICAgIHRoaXMuY29sbGF0b3IgPSBjOwogICAgICAgICAgICB0aGlzLnN0cmVuZ3RoID0gc3RyZW5ndGg7CiAgICAgICAgICAgIHRoaXMuYnJlYWtlciA9IGJyZWFrZXI7CiAgICAgICAgICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47CiAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OwogICAgICAgICAgICB0aGlzLm1hdGNoZXMgPSBtYXRjaGVzOwogICAgICAgIH0KICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciAgIGNvbGxhdG9yOwogICAgICAgIGludCAgICAgICAgICAgICAgICAgc3RyZW5ndGg7CiAgICAgICAgQnJlYWtJdGVyYXRvciAgICAgICBicmVha2VyOwogICAgICAgIFN0cmluZyAgICAgICAgICAgICAgcGF0dGVybjsKICAgICAgICBTdHJpbmcgICAgICAgICAgICAgIHRhcmdldDsKICAgICAgICBpbnRbXSAgICAgICAgICAgICAgIG1hdGNoZXM7CiAgICB9OwogICAgc3RhdGljIFRlc3RDYXNlW10gdGVzdENhc2VzID0gewogICAgICAgIG5ldyBUZXN0Q2FzZShlbkNvbGwsIENvbGxhdG9yLlBSSU1BUlksIG51bGwsICJmb3giLAogICAgICAgICAgICAgICAgLy8gICAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkKICAgICAgICAgICAgICAgICAgICAiVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGZveGVzIiwKICAgICAgICAgICAgICAgICAgICBuZXcgaW50W10geyAxNiwgNDAgfQogICAgICAgICAgICAgICAgICAgICksCgogICAgICAgIG5ldyBUZXN0Q2FzZShlbkNvbGwsIENvbGxhdG9yLlBSSU1BUlksIGVuV29yZCwgImZveCIsCiAgICAgICAgICAgICAgICAvLyAgIDAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQogICAgICAgICAgICAgICAgICAgICJUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgdGhlIGxhenkgZm94ZXMiLAogICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7IDE2IH0KICAgICAgICAgICAgICAgICAgICApLAoKICAgICAgICBuZXcgVGVzdENhc2UoZnJDb2xsLCBDb2xsYXRvci5QUklNQVJZLCBudWxsLCAicGVjaGUiLAogICAgICAgICAgICAgICAgICAgIHRlc3RTdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHsgMTUsIDIxLCAyNywgMzQgfQogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgbmV3IFRlc3RDYXNlKGZyQ29sbCwgQ29sbGF0b3IuUFJJTUFSWSwgZW5Xb3JkLCAiYmxhY2tiaXJkIiwKICAgICAgICAgICAgICAgICAgICB0ZXN0U3RyaW5nLAogICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7IDg4LCA5OCB9CiAgICAgICAgICAgICAgICAgICAgKSwKCiAgICAgICAgLy8gTk9URTogdGhpcyBjYXNlIGRlcGVuZHMgb24gYSBidWcgZml4IGluIEpESyAxLjIuMiAoIkNyaWNrZXQiKQogICAgICAgIG5ldyBUZXN0Q2FzZShkZUNvbGwsIENvbGxhdG9yLlBSSU1BUlksIG51bGwsICJ0b2UiLAogICAgICAgICAgICAgICAgLy8gICAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkKICAgICAgICAgICAgICAgICAgICAiVGhpcyBpcyBhIHRvZSBUXHUwMEY2bmUiLAogICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7IDEwLCAxNCB9CiAgICAgICAgICAgICAgICAgICAgKSwKCiAgICAgICAgLyogRHVlIHRvIGEgYnVnIGluIHRoZSBKREsgMS4yIEZDUyB2ZXJzaW9uIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKICAgICAgICAgKiBzZWFyY2hpbmcgdGhyb3VnaCB0ZXh0IGNvbnRhaW5pbmcgY29udHJhY3RpbmcgY2hhcmFjdGVyIHNlcXVlbmNlcyAKICAgICAgICAgKiBpc24ndCB3b3JraW5nIHByb3Blcmx5IHJpZ2h0IG5vdy4gIFRoaXMgd2lsbCBwcm9iYWJseSBiZSBmaXhlZCBpbgogICAgICAgICAqIEpESyAxLjMgKCJLZXN0cmVsIikuICBXaGVuIGl0IGlzLCB1bmNvbW1lbnQgdGhlc2UgdGVzdCBjYXNlcy4KICAgICAgICAgKgogICAgICAgIG5ldyBUZXN0Q2FzZShlc0NvbGwsIENvbGxhdG9yLlBSSU1BUlksIGVuV29yZCwgImNoYW5uZWwiLAogICAgICAgICAgICAgICAgLy8gICAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5CiAgICAgICAgICAgICAgICAgICAgIkEgY2hhbm5lbCwgYW5vdGhlciBDSEFOTkVMLCBtb3JlIENoYW5uZWxzLCBhbmQgb25lIGxhc3QgY2hhbm5lbC4uLiIsCiAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHsgIH0KICAgICAgICAgICAgICAgICAgICApLAoKICAgICAgICBuZXcgVGVzdENhc2UoZXNDb2xsLCBDb2xsYXRvci5URVJUSUFSWSwgZW5Xb3JkLCAiQ2hhbm5lbCIsCiAgICAgICAgICAgICAgICAvLyAgIDAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkKICAgICAgICAgICAgICAgICAgICAiQ2hhbm5lbCwgYW5vdGhlciBjaGFubmVsLCBtb3JlIGNoYW5uZWxzLCBhbmQgb25lIGxhc3QgQ2hhbm5lbCIsCiAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHsgIH0KICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICovCgogICAgfTsKCiAgICAvKioKICAgICAqIFRlc3QgdXNpbmcgdGhlIHRlc3QgY2FzZXMgZGVmaW5lZCBhYm92ZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBUZXN0Q2FzZXMoKSB7CiAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCB0ZXN0Q2FzZXMubGVuZ3RoOyB0KyspCiAgICAgICAgewogICAgICAgICAgICBsb2dsbigiY2FzZSAiICsgdCk7CiAgICAgICAgICAgIFRlc3RDYXNlIGMgPSB0ZXN0Q2FzZXNbdF07CiAgICAgICAgICAgIFN0cmluZ1NlYXJjaCBpdGVyID0gbmV3IFN0cmluZ1NlYXJjaChjLnBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IoYy50YXJnZXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5jb2xsYXRvciwgYy5icmVha2VyKTsKICAgICAgICAgICAgaXRlci5zZXRTdHJlbmd0aChjLnN0cmVuZ3RoKTsKICAgICAgICAgICAgZG9UZXN0Q2FzZShpdGVyLCBjLm1hdGNoZXMpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUZXN0IGZvciBTZWFyY2hJdGVyYXRvci5zZXRPdmVybGFwcGluZygpCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RPdmVybGFwcGluZygpIHsKICAgICAgICAvLyBDcmVhdGUgYSBzZWFyY2ggaXRlcmF0b3IuIAogICAgICAgIFN0cmluZ1NlYXJjaCBpdGVyID0gbmV3IFN0cmluZ1NlYXJjaCgiYWJhYiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcigiYWJhYmFiYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5Db2xsLCBudWxsKTsKICAgICAgICAKICAgICAgICBpbnRbXSBvdmVybGFwID0gbmV3IGludFtdIHsgMCwgMiwgNCB9OyAgLy8gZXhwZWN0ZWQgcmVzdWx0cwogICAgICAgIGludFtdIG5vdnJsYXAgPSBuZXcgaW50W10geyAwLCA0IH07CgogICAgICAgIAogICAgICAgIGRvVGVzdENhc2UoaXRlciwgb3ZlcmxhcCk7ICAgICAgICAgIC8vIE92ZXJsYXBwaW5nIGlzIGFsbG93ZWQgYnkgZGVmYXVsdAogICAgICAgIGlmIChpdGVyLmlzT3ZlcmxhcHBpbmcoKSAhPSB0cnVlKSB7CiAgICAgICAgICAgIGVycmxuKCJFUlJPUjogaXNPdmVybGFwcGluZyByZXR1cm5lZCAiICsgaXRlci5pc092ZXJsYXBwaW5nKCkpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpdGVyLnNldE92ZXJsYXBwaW5nKGZhbHNlKTsgICAgICAgICAvLyBUdXJuICdlbSBiYWNrIG9mZgogICAgICAgIGRvVGVzdENhc2UoaXRlciwgbm92cmxhcCk7CiAgICAgICAgaWYgKGl0ZXIuaXNPdmVybGFwcGluZygpICE9IGZhbHNlKSB7CiAgICAgICAgICAgIGVycmxuKCJFUlJPUjogaXNPdmVybGFwcGluZyByZXR1cm5lZCAiICsgaXRlci5pc092ZXJsYXBwaW5nKCkpOwogICAgICAgIH0KCiAgICAgICAgaXRlci5zZXRPdmVybGFwcGluZyh0cnVlKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG92ZXJsYXApOwogICAgICAgIGlmIChpdGVyLmlzT3ZlcmxhcHBpbmcoKSAhPSB0cnVlKSB7CiAgICAgICAgICAgIGVycmxuKCJFUlJPUjogaXNPdmVybGFwcGluZyByZXR1cm5lZCAiICsgaXRlci5pc092ZXJsYXBwaW5nKCkpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUZXN0IGZvciBTZWFyY2hJdGVyYXRvci5zZXRCcmVha0l0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RCcmVha0l0ZXJhdG9yKCkgewogICAgICAgIFN0cmluZ1NlYXJjaCBpdGVyID0gbmV3IFN0cmluZ1NlYXJjaCgiZm94IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKCJmb3h5IGZveCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbkNvbGwsIG51bGwpOwoKICAgICAgICBCcmVha0l0ZXJhdG9yIGNoYXJCcmVha2VyID0gQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZShMb2NhbGUuVVMpOwogICAgICAgIEJyZWFrSXRlcmF0b3Igd29yZEJyZWFrZXIgPSBCcmVha0l0ZXJhdG9yLmdldFdvcmRJbnN0YW5jZShMb2NhbGUuVVMpOwogICAgICAgIAogICAgICAgIGludFtdIGNoYXJzID0gbmV3IGludFtdIHsgMCwgNSB9OyAgIC8vIGV4cGVjdGVkIHJlc3VsdHMKICAgICAgICBpbnRbXSB3b3JkcyA9IG5ldyBpbnRbXSB7IDUgfTsKICAgICAgICAKICAgICAgICBsb2dsbigiZGVmYXVsdCBicmVhayBpdGVyYXRvci4uLiIpOwogICAgICAgIGRvVGVzdENhc2UoaXRlciwgY2hhcnMpOyAgICAgICAgICAgIC8vIGNoYXJhY3RlciBicmVha2VyIGJ5IGRlZmF1bHQKICAgICAgICAKICAgICAgICBsb2dsbigid29yZCBicmVhayBpdGVyYXRvci4uLiIpOwogICAgICAgIGl0ZXIuc2V0QnJlYWtJdGVyYXRvcih3b3JkQnJlYWtlcik7IC8vIHdvcmQgYnJlYWsgZGV0ZWN0aW9uCiAgICAgICAgZG9UZXN0Q2FzZShpdGVyLCB3b3Jkcyk7CiAgICAgICAgaWYgKGl0ZXIuZ2V0QnJlYWtJdGVyYXRvcigpICE9IHdvcmRCcmVha2VyKSB7CiAgICAgICAgICAgIGVycmxuKCJFUlJPUjogZ2V0QnJlYWtJdGVyYXRvciByZXR1cm5lZCB3cm9uZyBvYmplY3QiKTsKICAgICAgICB9CgogICAgICAgIGxvZ2xuKCJjaGFyIGJyZWFrIGl0ZXJhdG9yLi4uIik7CiAgICAgICAgaXRlci5zZXRCcmVha0l0ZXJhdG9yKGNoYXJCcmVha2VyKTsgLy8gY2hhciBicmVhayBkZXRlY3Rpb24KICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIGNoYXJzKTsKICAgICAgICBpZiAoaXRlci5nZXRCcmVha0l0ZXJhdG9yKCkgIT0gY2hhckJyZWFrZXIpIHsKICAgICAgICAgICAgZXJybG4oIkVSUk9SOiBnZXRCcmVha0l0ZXJhdG9yIHJldHVybmVkIHdyb25nIG9iamVjdCIpOwogICAgICAgIH0KCiAgICAgICAgbG9nbG4oIm51bGwgYnJlYWsgaXRlcmF0b3IuLi4iKTsKICAgICAgICBpdGVyLnNldEJyZWFrSXRlcmF0b3IobnVsbCk7CiAgICAgICAgZG9UZXN0Q2FzZShpdGVyLCBjaGFycyk7CiAgICAgICAgaWYgKGl0ZXIuZ2V0QnJlYWtJdGVyYXRvcigpICE9IG51bGwpIHsKICAgICAgICAgICAgZXJybG4oIkVSUk9SOiBnZXRCcmVha0l0ZXJhdG9yIHJldHVybmVkIHdyb25nIG9iamVjdCIpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBUZXN0IGZvciBTZWFyY2hJdGVyYXRvci5zZXRUYXJnZXQKICAgICAqLwogICAgcHVibGljIHZvaWQgVGVzdFNldFRhcmdldCgpIHsKICAgICAgICBTdHJpbmcgIHBhdCA9ICJmb3giOwogICAgICAgIFN0cmluZyAgdGFyZzEgPSAidGhlIGZveHkgYnJvd24gZm94IjsKICAgICAgICBTdHJpbmcgIHRhcmcyID0gInRoZSBxdWljayBicm93biBmb3giOwogICAgICAgIAogICAgICAgIGludFtdIG1hdGNoMSA9IG5ldyBpbnRbXSB7IDQsIDE1IH07ICAgLy8gZXhwZWN0ZWQgcmVzdWx0cwogICAgICAgIGludFtdIG1hdGNoMiA9IG5ldyBpbnRbXSB7IDE2IH07CgogICAgICAgIFN0cmluZ1NlYXJjaCBpdGVyID0gbmV3IFN0cmluZ1NlYXJjaChwYXQsIG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcih0YXJnMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuQ29sbCwgbnVsbCk7CgogICAgICAgIGxvZ2xuKCJpbml0aWFsIHRleHQuLi4iKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMSk7CiAgICAgICAgYXNzZXJ0RXF1YWwoaXRlci5nZXRUYXJnZXQoKSwgdGFyZzEpOwogICAgICAgIAogICAgICAgIGxvZ2xuKCJ0YXJnZXQgIzIuLi4iKTsKICAgICAgICBpdGVyLnNldFRhcmdldChuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZzIpKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMik7CiAgICAgICAgYXNzZXJ0RXF1YWwoaXRlci5nZXRUYXJnZXQoKSwgdGFyZzIpOwogICAgICAgIAogICAgICAgIGxvZ2xuKCJiYWNrIHRvIHRhcmdldCAjMS4uLiIpOwogICAgICAgIGl0ZXIuc2V0VGFyZ2V0KG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcih0YXJnMSkpOwogICAgICAgIGRvVGVzdENhc2UoaXRlciwgbWF0Y2gxKTsKICAgICAgICBhc3NlcnRFcXVhbChpdGVyLmdldFRhcmdldCgpLCB0YXJnMSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGVzdCBmb3IgU3RyaW5nU2VhcmNoLnNldFN0cmVuZ3RoCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RTZXRTdHJlbmd0aCgpIHsKICAgICAgICBTdHJpbmcgIHBhdCA9ICJmb3giOwogICAgICAgIFN0cmluZyAgdGFyZyA9ICJ0aGUgZm94eSBicm93biBGb3giOwogICAgICAgIAogICAgICAgIGludFtdIG1hdGNoMSA9IG5ldyBpbnRbXSB7IDQsIDE1IH07ICAgLy8gZXhwZWN0ZWQgcmVzdWx0cwogICAgICAgIGludFtdIG1hdGNoMyA9IG5ldyBpbnRbXSB7IDQgfTsKCiAgICAgICAgU3RyaW5nU2VhcmNoIGl0ZXIgPSBuZXcgU3RyaW5nU2VhcmNoKHBhdCwgbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKHRhcmcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbkNvbGwsIG51bGwpOwoKICAgICAgIC8qIGxvZ2xuKCJUcnlpbmcgcHJpbWFyeSBzdHJlbmd0aC4uLiIpOwogICAgICAgIGl0ZXIuc2V0U3RyZW5ndGgoQ29sbGF0b3IuUFJJTUFSWSk7CiAgICAgICAgZG9UZXN0Q2FzZShpdGVyLCBtYXRjaDEpOwogICAgICAgIGlmIChpdGVyLmdldFN0cmVuZ3RoKCkgIT0gQ29sbGF0b3IuUFJJTUFSWSkgewogICAgICAgICAgICBlcnJsbigiRVJST1I6IGdldFN0cmVuZ3RoOiBleHBlY3RlZCBQUklNQVJZLCBnb3QgIiArIGl0ZXIuZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgfSAqLwogICAgICAgIAogICAgICAgIGxvZ2xuKCJUcnlpbmcgdGVydGlhcnkgc3RyZW5ndGguLi4iKTsKICAgICAgICBpdGVyLnNldFN0cmVuZ3RoKENvbGxhdG9yLlRFUlRJQVJZKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMyk7CiAgICAgICAgaWYgKGl0ZXIuZ2V0U3RyZW5ndGgoKSAhPSBDb2xsYXRvci5URVJUSUFSWSkgewogICAgICAgICAgICBlcnJsbigiRVJST1I6IGdldFN0cmVuZ3RoOiBleHBlY3RlZCBQUklNQVJZLCBnb3QgIiArIGl0ZXIuZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgfQogICAgICAgIAogICAgfQoKICAgIC8qKgogICAgICogVGVzdCBmb3IgU3RyaW5nU2VhcmNoLnNldENvbGxhdG9yCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RTZXRDb2xsYXRvcigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgLy8gQ3JlYXRlIGEgdGVzdCBjb2xsYXRvciB0aGF0IHRoaW5rcyAibyIgYW5kICJwIiBhcmUgdGhlIHNhbWUgdGhpbmcKICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciB0ZXN0Q29sbCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbkNvbGwuZ2V0UnVsZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiYgbyxPIDsgcCxQIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIFN0cmluZyAgcGF0ID0gImZveCI7CiAgICAgICAgU3RyaW5nICB0YXJnID0gImZveCBmcHggIjsKICAgICAgICAKICAgICAgICBpbnRbXSBtYXRjaDEgPSBuZXcgaW50W10geyAwIH07ICAgICAvLyBFbmdsaXNoIHJlc3VsdHMKICAgICAgICBpbnRbXSBtYXRjaDIgPSBuZXcgaW50W10geyAwLCA0IH07ICAvLyBUZXN0IGNvbGxhdG9yIHJlc3VsdHMKCiAgICAgICAgU3RyaW5nU2VhcmNoIGl0ZXIgPSBuZXcgU3RyaW5nU2VhcmNoKHBhdCwgbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKHRhcmcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbkNvbGwsIG51bGwpOwoKICAgICAgICBsb2dsbigiVHJ5aW5nIEVuZ2xpc2ggY29sbGF0b3IuLi4iKTsKCiAgICAgICAgaXRlci5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMSk7CiAgICAgICAgaWYgKGl0ZXIuZ2V0Q29sbGF0b3IoKSAhPSBlbkNvbGwpIHsKICAgICAgICAgICAgZXJybG4oIkVSUk9SOiBnZXRDb2xsYXRvciByZXR1cm5lZCB3cm9uZyBjb2xsYXRvciIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBsb2dsbigiVHJ5aW5nIHRlc3QgY29sbGF0b3IuLi4iKTsKCiAgICAgICAgaXRlci5zZXRDb2xsYXRvcih0ZXN0Q29sbCk7CiAgICAgICAgaXRlci5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMik7CiAgICAgICAgaWYgKGl0ZXIuZ2V0Q29sbGF0b3IoKSAhPSB0ZXN0Q29sbCkgewogICAgICAgICAgICBlcnJsbigiRVJST1I6IGdldENvbGxhdG9yIHJldHVybmVkIHdyb25nIGNvbGxhdG9yIik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGxvZ2xuKCJUcnlpbmcgRW5nbGlzaCBjb2xsYXRvciBhZ2Fpbi4uLiIpOwoKICAgICAgICBpdGVyLnNldENvbGxhdG9yKGVuQ29sbCk7CiAgICAgICAgaXRlci5zZXRTdHJlbmd0aChDb2xsYXRvci5QUklNQVJZKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMSk7CiAgICAgICAgaWYgKGl0ZXIuZ2V0Q29sbGF0b3IoKSAhPSBlbkNvbGwpIHsKICAgICAgICAgICAgZXJybG4oIkVSUk9SOiBnZXRDb2xsYXRvciByZXR1cm5lZCB3cm9uZyBjb2xsYXRvciIpOwogICAgICAgIH0KICAgICAgICAKICAgIH0KCiAgICAvKioKICAgICAqIFRlc3QgZm9yIFN0cmluZ1NlYXJjaC5zZXRQYXR0ZXJuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RTZXRQYXR0ZXJuKCkgewogICAgICAgICAgICAgICAgICAgICAgLy8gMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkKICAgICAgICBTdHJpbmcgdGFyZ2V0ID0gIlRoZSBxdWljayBicm93biBmb3gganVtcHMgb3ZlciB0aGUgbGF6eSBmb3hlcyI7CiAgICAgICAgU3RyaW5nIHBhdDEgPSAidGhlIjsKICAgICAgICBTdHJpbmcgcGF0MiA9ICJmb3giOwogICAgICAgIAogICAgICAgIGludFtdIG1hdGNoMSA9IG5ldyBpbnRbXSB7IDAsIDMxIH07CiAgICAgICAgaW50W10gbWF0Y2gyID0gbmV3IGludFtdIHsgMTYsIDQwIH07CgogICAgICAgIFN0cmluZ1NlYXJjaCBpdGVyID0gbmV3IFN0cmluZ1NlYXJjaChwYXQxLCBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZ2V0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5Db2xsLCBudWxsKTsKICAgICAgICBpdGVyLnNldFN0cmVuZ3RoKENvbGxhdG9yLlBSSU1BUlkpOwogICAgICAgIAogICAgICAgIGRvVGVzdENhc2UoaXRlciwgbWF0Y2gxKTsKICAgICAgICBpZiAoIWl0ZXIuZ2V0UGF0dGVybigpLmVxdWFscyhwYXQxKSkgewogICAgICAgICAgICBlcnJsbigiZ2V0UGF0dGVybiByZXR1cm5lZCAnIiArIGl0ZXIuZ2V0UGF0dGVybigpICsgIicsIGV4cGVjdGVkICciCiAgICAgICAgICAgICAgICArIHBhdDEgKyAiJyIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpdGVyLnNldFBhdHRlcm4ocGF0Mik7CiAgICAgICAgZG9UZXN0Q2FzZShpdGVyLCBtYXRjaDIpOwogICAgICAgIGlmICghaXRlci5nZXRQYXR0ZXJuKCkuZXF1YWxzKHBhdDIpKSB7CiAgICAgICAgICAgIGVycmxuKCJnZXRQYXR0ZXJuIHJldHVybmVkICciICsgaXRlci5nZXRQYXR0ZXJuKCkgKyAiJywgZXhwZWN0ZWQgJyIKICAgICAgICAgICAgICAgICsgcGF0MSArICInIik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGl0ZXIuc2V0UGF0dGVybihwYXQxKTsKICAgICAgICBkb1Rlc3RDYXNlKGl0ZXIsIG1hdGNoMSk7CiAgICAgICAgaWYgKCFpdGVyLmdldFBhdHRlcm4oKS5lcXVhbHMocGF0MSkpIHsKICAgICAgICAgICAgZXJybG4oImdldFBhdHRlcm4gcmV0dXJuZWQgJyIgKyBpdGVyLmdldFBhdHRlcm4oKSArICInLCBleHBlY3RlZCAnIgogICAgICAgICAgICAgICAgKyBwYXQxICsgIiciKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVGVzdCBmb3IgYW4gaW5maW5pdGUgbG9vcCB0aGF0IGhhcHBlbmVkIHdoZW4gdGhlIHRhcmdldCB0ZXh0IHN0YXJ0ZWQKICAgICAqIHdpdGggYW4gaWdub3JhYmxlIGNoYXJhY3Rlci4KICAgICAqIFJlcG9ydGVkIGJ5IE11bHkgT3ZlZCwgPG11bHlvdmVkQG5ldHZpc2lvbi5uZXQuaWw+CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIFRlc3RJZ25vcmFibGVMb29wKCkgewogICAgICAgIFN0cmluZyBwYXR0ZXJuID0gImdvIjsKICAgICAgICBTdHJpbmcgdGFyZ2V0ICA9ICIgIG9uIjsKCiAgICAgICAgU3RyaW5nU2VhcmNoIHNlYXJjaDsKICAgICAgICAKICAgICAgICB0cnkgewogICAgICAgICAgICBzZWFyY2g9bmV3IFN0cmluZ1NlYXJjaChwYXR0ZXJuLCBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZ2V0KSwgZW5Db2xsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGxvZ2xuKCJzZWFyY2hpbmcuLi4gIitwYXR0ZXJuKTsKICAgICAgICAgICAgc2VhcmNoLmZpcnN0KCk7CiAgICAgICAgICAgIGxvZ2xuKCJXaWxsIG5ldmVyIGdvIGhlcmUgaWYgc2VhcmNoaW5nIGZvciAnZ28nIik7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgZXJybG4oIkNhdWdodCBleGNlcHRpb246ICIgKyBlLnRvU3RyaW5nKCkpOwogICAgICAgIH0KCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJlbmQiKTsKICAgIH0KICAgIAogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBWYXJpb3VzIGludGVybmFsIHV0aWxpdHkgbWV0aG9kcy4uLi4KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIHZvaWQgYXNzZXJ0RXF1YWwoQ2hhcmFjdGVySXRlcmF0b3IgaTEsIFN0cmluZyBzMikgewogICAgICAgIENoYXJhY3Rlckl0ZXJhdG9yIGkyID0gbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKHMyKTsKICAgICAgICBjaGFyIGMxID0gaTEuZmlyc3QoKTsKICAgICAgICBjaGFyIGMyID0gaTIuZmlyc3QoKTsKICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKGMxID09IGMyICYmIGMxICE9IENoYXJhY3Rlckl0ZXJhdG9yLkRPTkUpIHsKICAgICAgICAgICAgYzEgPSBpMS5uZXh0KCk7CiAgICAgICAgICAgIGMyID0gaTIubmV4dCgpOwogICAgICAgIH0KICAgICAgICBpZiAoYzEgIT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSB8fCBjMiAhPSBDaGFyYWN0ZXJJdGVyYXRvci5ET05FKSB7CiAgICAgICAgICAgIGVycmxuKCJDaGFyYWN0ZXJJdGVyYXRvciBtaXNtYXRjaCBhdCBpbmRleCAiICsgaSk7CiAgICAgICAgfQogICAgfQogICAgCiAgICB2b2lkIGRvVGVzdENhc2UoU3RyaW5nU2VhcmNoIGl0ZXIsIGludFtdIGV4cGVjdGVkKSB7CiAgICAgICAgLy8KICAgICAgICAvLyBUaGUgYmFzaWMgbG9naWMgaGVyZSBpcyBhcyBmb2xsb3dzLi4uICBXZSBjb25zdHJ1Y3QgYSBzZWFyY2gKICAgICAgICAvLyBpdGVyYXRvciBhbmQgdXNlIGl0IHRvIGZpbmQgYWxsIG9mIHRoZSBtYXRjaGVzIGluIHRoZSB0YXJnZXQKICAgICAgICAvLyB0ZXh0LiAgVGhlbiB3ZSBjb21wYXJlIGl0IHRvIHRoZSBleHBlY3RlZCBtYXRjaGVzCiAgICAgICAgLy8KICAgICAgICBWZWN0b3IgbWF0Y2hlcyA9IG5ldyBWZWN0b3IoKTsKCiAgICAgICAgZm9yIChpbnQgaSA9IGl0ZXIuZmlyc3QoKTsgaSAhPSBTZWFyY2hJdGVyYXRvci5ET05FOyBpID0gaXRlci5uZXh0KCkpIHsKICAgICAgICAgICAgbWF0Y2hlcy5hZGRFbGVtZW50KG5ldyBJbnRlZ2VyKGkpKTsKICAgICAgICB9CiAgICAgICAgY29tcGFyZU1hdGNoZXMoZXhwZWN0ZWQsIG1hdGNoZXMpOwogICAgICAgIAogICAgICAgIC8vIE5vdyBkbyB0aGUgc2FtZSBleGFjdCB0aGluZyBhcyBhYm92ZSwgYnV0IGluIHJldmVyc2UKICAgICAgICBsb2dsbigiTm93IHNlYXJjaGluZyBpbiByZXZlcnNlLi4uIik7CiAgICAgICAgbWF0Y2hlcy5yZW1vdmVBbGxFbGVtZW50cygpOwogICAgICAgIGZvciAoaW50IGkgPSBpdGVyLmxhc3QoKTsgaSAhPSBTZWFyY2hJdGVyYXRvci5ET05FOyBpID0gaXRlci5wcmV2aW91cygpKSB7CiAgICAgICAgICAgIG1hdGNoZXMuaW5zZXJ0RWxlbWVudEF0KG5ldyBJbnRlZ2VyKGkpLCAwKTsKICAgICAgICB9CiAgICAgICAgY29tcGFyZU1hdGNoZXMoZXhwZWN0ZWQsIG1hdGNoZXMpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFV0aWxpdHkgZnVuY3Rpb24gdXNlZCBieSBUZXN0Q2FzZXMgdG8gY29tcGFyZSB0aGUgbWF0Y2hlcyB0aGF0CiAgICAgKiB3ZXJlIGZvdW5kIGFnYWluc3QgdGhlIG9uZXMgdGhhdCB3ZXJlIGV4cGVjdGVkCiAgICAgKi8KICAgIHZvaWQgY29tcGFyZU1hdGNoZXMoaW50W10gZXhwZWN0ZWQsIFZlY3RvciBmb3VuZCkgewogICAgICAgIC8vIFN0ZXAgdGhyb3VnaCB0aGUgdHdvIGFycmF5cyBpbiBwYXJhbGxlbCBhbmQgbWFrZSBzdXJlIHRoYXQgdGhleSdyZQogICAgICAgIC8vIHRoZSBzYW1lCiAgICAgICAgCiAgICAgICAgaW50IGU9MCwgZj0wOwogICAgICAgIAogICAgICAgIHdoaWxlIChlIDwgZXhwZWN0ZWQubGVuZ3RoICYmIGYgPCBmb3VuZC5zaXplKCkpIHsKICAgICAgICAgICAgaW50IGVWYWwgPSBleHBlY3RlZFtlXTsKICAgICAgICAgICAgaW50IGZWYWwgPSAoKEludGVnZXIpZm91bmQuZWxlbWVudEF0KGYpKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGVWYWwgPCBmVmFsKSB7CiAgICAgICAgICAgICAgICBlcnJsbigiTWlzc2VkIGV4cGVjdGVkIG1hdGNoIGF0ICIgKyBlVmFsKTsKICAgICAgICAgICAgICAgIGUrKzsKICAgICAgICAgICAgfSBlbHNlIGlmIChlVmFsID4gZlZhbCkgewogICAgICAgICAgICAgICAgZXJybG4oIkZvdW5kIHVuZXhwZWN0ZWQgbWF0Y2ggYXQgIiArIGZWYWwpOwogICAgICAgICAgICAgICAgZisrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZSsrOwogICAgICAgICAgICAgICAgZisrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHdoaWxlIChlIDwgZXhwZWN0ZWQubGVuZ3RoKSB7CiAgICAgICAgICAgIGVycmxuKCJNaXNzZWQgZXhwZWN0ZWQgbWF0Y2ggYXQgIiArIGV4cGVjdGVkW2VdKTsKICAgICAgICAgICAgZSsrOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoZiA8IGZvdW5kLnNpemUoKSkgewogICAgICAgICAgICBpbnQgZlZhbCA9ICgoSW50ZWdlcilmb3VuZC5lbGVtZW50QXQoZikpLmludFZhbHVlKCk7CiAgICAgICAgICAgIGVycmxuKCJGb3VuZCB1bmV4cGVjdGVkIG1hdGNoIGF0ICIgKyBmVmFsKTsKICAgICAgICAgICAgZisrOwogICAgICAgIH0KICAgIH0KfQ==