ZGlmZiAtLWdpdCBhL3BvbS54bWwgYi9wb20ueG1sCmluZGV4IDBjM2ExMGEuLjkxMTNkMjMgMTAwNjQ0Ci0tLSBhL3BvbS54bWwKKysrIGIvcG9tLnhtbApAQCAtMTAxLDYgKzEwMSwxMiBAQAogICAgICAgPHZlcnNpb24+MS40PC92ZXJzaW9uPgogICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgogICAgIDwvZGVwZW5kZW5jeT4KKyAgICA8ZGVwZW5kZW5jeT4KKyAgICAgIDxncm91cElkPmNvbW1vbnMtaW88L2dyb3VwSWQ+CisgICAgICA8YXJ0aWZhY3RJZD5jb21tb25zLWlvPC9hcnRpZmFjdElkPgorICAgICAgPHZlcnNpb24+Mi41PC92ZXJzaW9uPgorICAgICAgPHNjb3BlPnRlc3Q8L3Njb3BlPgorICAgIDwvZGVwZW5kZW5jeT4KICAgPC9kZXBlbmRlbmNpZXM+CiAKICAgPGRpc3RyaWJ1dGlvbk1hbmFnZW1lbnQ+CmRpZmYgLS1naXQgYS9zcmMvY2hhbmdlcy9jaGFuZ2VzLnhtbCBiL3NyYy9jaGFuZ2VzL2NoYW5nZXMueG1sCmluZGV4IGU2MGIzNjQuLjEyNzQ2NzIgMTAwNjQ0Ci0tLSBhL3NyYy9jaGFuZ2VzL2NoYW5nZXMueG1sCisrKyBiL3NyYy9jaGFuZ2VzL2NoYW5nZXMueG1sCkBAIC0yMiw2ICsyMiw3IEBACiAgIDxib2R5PgogCiAgIDxyZWxlYXNlIHZlcnNpb249IjEuMCIgZGF0ZT0idGJhIiBkZXNjcmlwdGlvbj0idGJhIj4KKyAgICA8YWN0aW9uIGlzc3VlPSJURVhULTI3IiB0eXBlPSJhZGQiIGRldj0iY2h0b21wa2kiPk1vdmUgb3JnLmFwYWNoZS5jb21tb25zLmxhbmczLlN0cmluZ0VzY2FwZVV0aWxzLmphdmEgaW50byB0ZXh0PC9hY3Rpb24+CiAgICAgPGFjdGlvbiBpc3N1ZT0iVEVYVC0yMyIgdHlwZT0iYWRkIiBkZXY9ImNodG9tcGtpIj5Nb3ZpbmcgZnJvbSBjb21tb25zLWxhbmcsIHRoZSBwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5sYW5nMy50ZXh0PC9hY3Rpb24+CiAgICAgPGFjdGlvbiBpc3N1ZT0iVEVYVC0xMCIgdHlwZT0iYWRkIiBkZXY9Imtpbm93IiBkdWUtdG89IkRvbiBKZWJhIj5BIG1vcmUgY29tcGxleCBMZXZlbnNodGVpbiBkaXN0YW5jZTwvYWN0aW9uPgogICAgIDxhY3Rpb24gaXNzdWU9IlRFWFQtMjQiIHR5cGU9ImFkZCIgZGV2PSJjaHRvbXBraSI+QWRkIGNvdmVyYWxscyBhbmQgVHJhdmlzLmNpIGludGVncmF0aW9uPC9hY3Rpb24+CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy90ZXh0L1N0cmluZ0VzY2FwZVV0aWxzLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy90ZXh0L1N0cmluZ0VzY2FwZVV0aWxzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI4ODI3NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL3RleHQvU3RyaW5nRXNjYXBlVXRpbHMuamF2YQpAQCAtMCwwICsxLDgxMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy50ZXh0OworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sYW5nMy5DaGFyVXRpbHM7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmxhbmczLlN0cmluZ1V0aWxzOworCitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLnRleHQudHJhbnNsYXRlLkFnZ3JlZ2F0ZVRyYW5zbGF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLnRleHQudHJhbnNsYXRlLkNoYXJTZXF1ZW5jZVRyYW5zbGF0b3I7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLnRleHQudHJhbnNsYXRlLkVudGl0eUFycmF5czsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMudGV4dC50cmFuc2xhdGUuSmF2YVVuaWNvZGVFc2NhcGVyOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy50ZXh0LnRyYW5zbGF0ZS5Mb29rdXBUcmFuc2xhdG9yOworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy50ZXh0LnRyYW5zbGF0ZS5OdW1lcmljRW50aXR5RXNjYXBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMudGV4dC50cmFuc2xhdGUuTnVtZXJpY0VudGl0eVVuZXNjYXBlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMudGV4dC50cmFuc2xhdGUuT2N0YWxVbmVzY2FwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLnRleHQudHJhbnNsYXRlLlVuaWNvZGVVbmVzY2FwZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLnRleHQudHJhbnNsYXRlLlVuaWNvZGVVbnBhaXJlZFN1cnJvZ2F0ZVJlbW92ZXI7CisKKy8qKgorICogPHA+RXNjYXBlcyBhbmQgdW5lc2NhcGVzIHtAY29kZSBTdHJpbmd9cyBmb3IKKyAqIEphdmEsIEphdmEgU2NyaXB0LCBIVE1MIGFuZCBYTUwuPC9wPgorICoKKyAqIDxwPiNUaHJlYWRTYWZlIzwvcD4KKyAqCisgKgorICogPHA+CisgKiBUaGlzIGNvZGUgaGFzIGJlZW4gYWRhcHRlZCBmcm9tIEFwYWNoZSBDb21tb25zIExhbmcgMy41LgorICogPC9wPgorICovCitwdWJsaWMgY2xhc3MgU3RyaW5nRXNjYXBlVXRpbHMgeworCisgICAgLyogRVNDQVBFIFRSQU5TTEFUT1JTICovCisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgZXNjYXBpbmcgSmF2YS4gCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI2VzY2FwZUphdmEoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMgCisgICAgICogb2JqZWN0IGFsbG93cyB0aGUgSmF2YSBlc2NhcGluZyBmdW5jdGlvbmFsaXR5IHRvIGJlIHVzZWQgCisgICAgICogYXMgdGhlIGZvdW5kYXRpb24gZm9yIGEgY3VzdG9tIHRyYW5zbGF0b3IuIAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBFU0NBUEVfSkFWQSA9CisgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiXCIiLCAiXFxcIiJ9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiXFwiLCAiXFxcXCJ9LAorICAgICAgICAgICAgICAgICAgICB9KS53aXRoKAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuSkFWQV9DVFJMX0NIQVJTX0VTQ0FQRSgpKQorICAgICAgICAgICAgKS53aXRoKAorICAgICAgICAgICAgICAgICAgICBKYXZhVW5pY29kZUVzY2FwZXIub3V0c2lkZU9mKDMyLCAweDdmKQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciBlc2NhcGluZyBFY21hU2NyaXB0L0phdmFTY3JpcHQuIAorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICNlc2NhcGVFY21hU2NyaXB0KFN0cmluZyl9IGlzIHRoZSBleHBlY3RlZCBtZXRob2Qgb2YgdXNlLCB0aGlzIAorICAgICAqIG9iamVjdCBhbGxvd3MgdGhlIEVjbWFTY3JpcHQgZXNjYXBpbmcgZnVuY3Rpb25hbGl0eSB0byBiZSB1c2VkIAorICAgICAqIGFzIHRoZSBmb3VuZGF0aW9uIGZvciBhIGN1c3RvbSB0cmFuc2xhdG9yLiAKKyAgICAgKgorICAgICAqIEBzaW5jZSAzLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgRVNDQVBFX0VDTUFTQ1JJUFQgPQorICAgICAgICAgICAgbmV3IEFnZ3JlZ2F0ZVRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBMb29rdXBUcmFuc2xhdG9yKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXVtdIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiJyIsICJcXCcifSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiXCIiLCAiXFxcIiJ9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyJcXCIsICJcXFxcIn0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ii8iLCAiXFwvIn0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkpBVkFfQ1RSTF9DSEFSU19FU0NBUEUoKSksCisgICAgICAgICAgICAgICAgICAgIEphdmFVbmljb2RlRXNjYXBlci5vdXRzaWRlT2YoMzIsIDB4N2YpCisgICAgICAgICAgICApOworCisgICAgLyoqCisgICAgICogVHJhbnNsYXRvciBvYmplY3QgZm9yIGVzY2FwaW5nIEpzb24uCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI2VzY2FwZUpzb24oU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBKc29uIGVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZAorICAgICAqIGFzIHRoZSBmb3VuZGF0aW9uIGZvciBhIGN1c3RvbSB0cmFuc2xhdG9yLgorICAgICAqCisgICAgICogQHNpbmNlIDMuMgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBFU0NBUEVfSlNPTiA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyJcIiIsICJcXFwiIn0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IlxcIiwgIlxcXFwifSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiLyIsICJcXC8ifQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuSkFWQV9DVFJMX0NIQVJTX0VTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgSmF2YVVuaWNvZGVFc2NhcGVyLm91dHNpZGVPZigzMiwgMHg3ZikKKyAgICAgICAgICAgICk7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgZXNjYXBpbmcgWE1MLgorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICNlc2NhcGVYbWwoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMgCisgICAgICogb2JqZWN0IGFsbG93cyB0aGUgWE1MIGVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayAjRVNDQVBFX1hNTDEwfSBvciB7QGxpbmsgI0VTQ0FQRV9YTUwxMX0gaW5zdGVhZC4KKyAgICAgKi8KKyAgICBARGVwcmVjYXRlZAorICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBFU0NBUEVfWE1MID0KKyAgICAgICAgICAgIG5ldyBBZ2dyZWdhdGVUcmFuc2xhdG9yKAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuQkFTSUNfRVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuQVBPU19FU0NBUEUoKSkKKyAgICAgICAgICAgICk7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgZXNjYXBpbmcgWE1MIDEuMC4KKyAgICAgKgorICAgICAqIFdoaWxlIHtAbGluayAjZXNjYXBlWG1sMTAoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBYTUwgZXNjYXBpbmcgZnVuY3Rpb25hbGl0eSB0byBiZSB1c2VkCisgICAgICogYXMgdGhlIGZvdW5kYXRpb24gZm9yIGEgY3VzdG9tIHRyYW5zbGF0b3IuCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4zCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIEVTQ0FQRV9YTUwxMCA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkJBU0lDX0VTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkFQT1NfRVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW11bXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMDAiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDAxIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAwMiIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMDMiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDA0IiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAwNSIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMDYiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDA3IiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAwOCIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMGIiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDBjIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAwZSIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMGYiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDEwIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAxMSIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMTIiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDEzIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAxNCIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMTUiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDE2IiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAxNyIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMTgiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDE5IiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAxYSIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMWIiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDFjIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1MDAxZCIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMWUiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDFmIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1ZmZmZSIsIFN0cmluZ1V0aWxzLkVNUFRZIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdWZmZmYiLCBTdHJpbmdVdGlscy5FTVBUWSB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksCisgICAgICAgICAgICAgICAgICAgIE51bWVyaWNFbnRpdHlFc2NhcGVyLmJldHdlZW4oMHg3ZiwgMHg4NCksCisgICAgICAgICAgICAgICAgICAgIE51bWVyaWNFbnRpdHlFc2NhcGVyLmJldHdlZW4oMHg4NiwgMHg5ZiksCisgICAgICAgICAgICAgICAgICAgIG5ldyBVbmljb2RlVW5wYWlyZWRTdXJyb2dhdGVSZW1vdmVyKCkKKyAgICAgICAgICAgICk7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgZXNjYXBpbmcgWE1MIDEuMS4KKyAgICAgKgorICAgICAqIFdoaWxlIHtAbGluayAjZXNjYXBlWG1sMTEoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBYTUwgZXNjYXBpbmcgZnVuY3Rpb25hbGl0eSB0byBiZSB1c2VkCisgICAgICogYXMgdGhlIGZvdW5kYXRpb24gZm9yIGEgY3VzdG9tIHRyYW5zbGF0b3IuCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4zCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIEVTQ0FQRV9YTUwxMSA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkJBU0lDX0VTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkFQT1NfRVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW11bXSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICJcdTAwMDAiLCBTdHJpbmdVdGlscy5FTVBUWSB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDBiIiwgIiYjMTE7IiB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHUwMDBjIiwgIiYjMTI7IiB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAiXHVmZmZlIiwgU3RyaW5nVXRpbHMuRU1QVFkgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgIlx1ZmZmZiIsIFN0cmluZ1V0aWxzLkVNUFRZIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSwKKyAgICAgICAgICAgICAgICAgICAgTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweDEsIDB4OCksCisgICAgICAgICAgICAgICAgICAgIE51bWVyaWNFbnRpdHlFc2NhcGVyLmJldHdlZW4oMHhlLCAweDFmKSwKKyAgICAgICAgICAgICAgICAgICAgTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweDdmLCAweDg0KSwKKyAgICAgICAgICAgICAgICAgICAgTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweDg2LCAweDlmKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFVuaWNvZGVVbnBhaXJlZFN1cnJvZ2F0ZVJlbW92ZXIoKQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciBlc2NhcGluZyBIVE1MIHZlcnNpb24gMy4wLgorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICNlc2NhcGVIdG1sMyhTdHJpbmcpfSBpcyB0aGUgZXhwZWN0ZWQgbWV0aG9kIG9mIHVzZSwgdGhpcyAKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBIVE1MIGVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIEVTQ0FQRV9IVE1MMyA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkJBU0lDX0VTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLklTTzg4NTlfMV9FU0NBUEUoKSkKKyAgICAgICAgICAgICk7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgZXNjYXBpbmcgSFRNTCB2ZXJzaW9uIDQuMC4KKyAgICAgKgorICAgICAqIFdoaWxlIHtAbGluayAjZXNjYXBlSHRtbDQoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMgCisgICAgICogb2JqZWN0IGFsbG93cyB0aGUgSFRNTCBlc2NhcGluZyBmdW5jdGlvbmFsaXR5IHRvIGJlIHVzZWQgCisgICAgICogYXMgdGhlIGZvdW5kYXRpb24gZm9yIGEgY3VzdG9tIHRyYW5zbGF0b3IuIAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBFU0NBUEVfSFRNTDQgPQorICAgICAgICAgICAgbmV3IEFnZ3JlZ2F0ZVRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBMb29rdXBUcmFuc2xhdG9yKEVudGl0eUFycmF5cy5CQVNJQ19FU0NBUEUoKSksCisgICAgICAgICAgICAgICAgICAgIG5ldyBMb29rdXBUcmFuc2xhdG9yKEVudGl0eUFycmF5cy5JU084ODU5XzFfRVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuSFRNTDQwX0VYVEVOREVEX0VTQ0FQRSgpKQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciBlc2NhcGluZyBpbmRpdmlkdWFsIENvbW1hIFNlcGFyYXRlZCBWYWx1ZXMuIAorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICNlc2NhcGVDc3YoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMgCisgICAgICogb2JqZWN0IGFsbG93cyB0aGUgQ1NWIGVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIEVTQ0FQRV9DU1YgPSBuZXcgQ3N2RXNjYXBlcigpOworCisgICAgLy8gVE9ETzogQ3JlYXRlIGEgcGFyZW50IGNsYXNzIC0gJ1NpbmdsZVBhc3NUcmFuc2xhdG9yJyA/CisgICAgLy8gICAgICAgSXQgd291bGQgaGFuZGxlIHRoZSBpbmRleCBjaGVja2luZyArIGxlbmd0aCByZXR1cm5pbmcsIAorICAgIC8vICAgICAgIGFuZCBjb3VsZCBhbHNvIGhhdmUgYW4gb3B0aW1pemF0aW9uIGNoZWNrIG1ldGhvZC4KKyAgICBzdGF0aWMgY2xhc3MgQ3N2RXNjYXBlciBleHRlbmRzIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgeworCisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgQ1NWX0RFTElNSVRFUiA9ICcsJzsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBDU1ZfUVVPVEUgPSAnIic7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDU1ZfUVVPVEVfU1RSID0gU3RyaW5nLnZhbHVlT2YoQ1NWX1FVT1RFKTsKKyAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIENTVl9TRUFSQ0hfQ0hBUlMgPQorICAgICAgICAgICAgICAgIG5ldyBjaGFyW10ge0NTVl9ERUxJTUlURVIsIENTVl9RVU9URSwgQ2hhclV0aWxzLkNSLCBDaGFyVXRpbHMuTEZ9OworCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgaW50IHRyYW5zbGF0ZShmaW5hbCBDaGFyU2VxdWVuY2UgaW5wdXQsIGZpbmFsIGludCBpbmRleCwgZmluYWwgV3JpdGVyIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKworICAgICAgICAgICAgaWYoaW5kZXggIT0gMCkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNzdkVzY2FwZXIgc2hvdWxkIG5ldmVyIHJlYWNoIHRoZSBbMV0gaW5kZXgiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKFN0cmluZ1V0aWxzLmNvbnRhaW5zTm9uZShpbnB1dC50b1N0cmluZygpLCBDU1ZfU0VBUkNIX0NIQVJTKSkgeworICAgICAgICAgICAgICAgIG91dC53cml0ZShpbnB1dC50b1N0cmluZygpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKENTVl9RVU9URSk7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKFN0cmluZ1V0aWxzLnJlcGxhY2UoaW5wdXQudG9TdHJpbmcoKSwgQ1NWX1FVT1RFX1NUUiwgQ1NWX1FVT1RFX1NUUiArIENTVl9RVU9URV9TVFIpKTsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoQ1NWX1FVT1RFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBDaGFyYWN0ZXIuY29kZVBvaW50Q291bnQoaW5wdXQsIDAsIGlucHV0Lmxlbmd0aCgpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIFVORVNDQVBFIFRSQU5TTEFUT1JTICovCisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgdW5lc2NhcGluZyBlc2NhcGVkIEphdmEuIAorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICN1bmVzY2FwZUphdmEoU3RyaW5nKX0gaXMgdGhlIGV4cGVjdGVkIG1ldGhvZCBvZiB1c2UsIHRoaXMgCisgICAgICogb2JqZWN0IGFsbG93cyB0aGUgSmF2YSB1bmVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgLy8gVE9ETzogdGhyb3cgImlsbGVnYWwgY2hhcmFjdGVyOiBcOTIiIGFzIGFuIEV4Y2VwdGlvbiBpZiBhIFwgb24gdGhlIGVuZCBvZiB0aGUgSmF2YSAoYXMgcGVyIHRoZSBjb21waWxlcik/CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIFVORVNDQVBFX0pBVkEgPQorICAgICAgICAgICAgbmV3IEFnZ3JlZ2F0ZVRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBPY3RhbFVuZXNjYXBlcigpLCAgICAgLy8gLmJldHdlZW4oJ1wxJywgJ1wzNzcnKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IFVuaWNvZGVVbmVzY2FwZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkpBVkFfQ1RSTF9DSEFSU19VTkVTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdW10geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyJcXFxcIiwgIlxcIn0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IlxcXCIiLCAiXCIifSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiXFwnIiwgIicifSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsiXFwiLCAiIn0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciB1bmVzY2FwaW5nIGVzY2FwZWQgRWNtYVNjcmlwdC4gCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI3VuZXNjYXBlRWNtYVNjcmlwdChTdHJpbmcpfSBpcyB0aGUgZXhwZWN0ZWQgbWV0aG9kIG9mIHVzZSwgdGhpcyAKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBFY21hU2NyaXB0IHVuZXNjYXBpbmcgZnVuY3Rpb25hbGl0eSB0byBiZSB1c2VkIAorICAgICAqIGFzIHRoZSBmb3VuZGF0aW9uIGZvciBhIGN1c3RvbSB0cmFuc2xhdG9yLiAKKyAgICAgKgorICAgICAqIEBzaW5jZSAzLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgVU5FU0NBUEVfRUNNQVNDUklQVCA9IFVORVNDQVBFX0pBVkE7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgdW5lc2NhcGluZyBlc2NhcGVkIEpzb24uCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI3VuZXNjYXBlSnNvbihTdHJpbmcpfSBpcyB0aGUgZXhwZWN0ZWQgbWV0aG9kIG9mIHVzZSwgdGhpcworICAgICAqIG9iamVjdCBhbGxvd3MgdGhlIEpzb24gdW5lc2NhcGluZyBmdW5jdGlvbmFsaXR5IHRvIGJlIHVzZWQKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4KKyAgICAgKgorICAgICAqIEBzaW5jZSAzLjIKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgVU5FU0NBUEVfSlNPTiA9IFVORVNDQVBFX0pBVkE7CisKKyAgICAvKioKKyAgICAgKiBUcmFuc2xhdG9yIG9iamVjdCBmb3IgdW5lc2NhcGluZyBlc2NhcGVkIEhUTUwgMy4wLiAKKyAgICAgKgorICAgICAqIFdoaWxlIHtAbGluayAjdW5lc2NhcGVIdG1sMyhTdHJpbmcpfSBpcyB0aGUgZXhwZWN0ZWQgbWV0aG9kIG9mIHVzZSwgdGhpcyAKKyAgICAgKiBvYmplY3QgYWxsb3dzIHRoZSBIVE1MIHVuZXNjYXBpbmcgZnVuY3Rpb25hbGl0eSB0byBiZSB1c2VkIAorICAgICAqIGFzIHRoZSBmb3VuZGF0aW9uIGZvciBhIGN1c3RvbSB0cmFuc2xhdG9yLiAKKyAgICAgKgorICAgICAqIEBzaW5jZSAzLjAKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgVU5FU0NBUEVfSFRNTDMgPQorICAgICAgICAgICAgbmV3IEFnZ3JlZ2F0ZVRyYW5zbGF0b3IoCisgICAgICAgICAgICAgICAgICAgIG5ldyBMb29rdXBUcmFuc2xhdG9yKEVudGl0eUFycmF5cy5CQVNJQ19VTkVTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLklTTzg4NTlfMV9VTkVTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IE51bWVyaWNFbnRpdHlVbmVzY2FwZXIoKQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciB1bmVzY2FwaW5nIGVzY2FwZWQgSFRNTCA0LjAuIAorICAgICAqCisgICAgICogV2hpbGUge0BsaW5rICN1bmVzY2FwZUh0bWw0KFN0cmluZyl9IGlzIHRoZSBleHBlY3RlZCBtZXRob2Qgb2YgdXNlLCB0aGlzIAorICAgICAqIG9iamVjdCBhbGxvd3MgdGhlIEhUTUwgdW5lc2NhcGluZyBmdW5jdGlvbmFsaXR5IHRvIGJlIHVzZWQgCisgICAgICogYXMgdGhlIGZvdW5kYXRpb24gZm9yIGEgY3VzdG9tIHRyYW5zbGF0b3IuIAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBVTkVTQ0FQRV9IVE1MNCA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkJBU0lDX1VORVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuSVNPODg1OV8xX1VORVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuSFRNTDQwX0VYVEVOREVEX1VORVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTnVtZXJpY0VudGl0eVVuZXNjYXBlcigpCisgICAgICAgICAgICApOworCisgICAgLyoqCisgICAgICogVHJhbnNsYXRvciBvYmplY3QgZm9yIHVuZXNjYXBpbmcgZXNjYXBlZCBYTUwuCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI3VuZXNjYXBlWG1sKFN0cmluZyl9IGlzIHRoZSBleHBlY3RlZCBtZXRob2Qgb2YgdXNlLCB0aGlzIAorICAgICAqIG9iamVjdCBhbGxvd3MgdGhlIFhNTCB1bmVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIFVORVNDQVBFX1hNTCA9CisgICAgICAgICAgICBuZXcgQWdncmVnYXRlVHJhbnNsYXRvcigKKyAgICAgICAgICAgICAgICAgICAgbmV3IExvb2t1cFRyYW5zbGF0b3IoRW50aXR5QXJyYXlzLkJBU0lDX1VORVNDQVBFKCkpLAorICAgICAgICAgICAgICAgICAgICBuZXcgTG9va3VwVHJhbnNsYXRvcihFbnRpdHlBcnJheXMuQVBPU19VTkVTQ0FQRSgpKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3IE51bWVyaWNFbnRpdHlVbmVzY2FwZXIoKQorICAgICAgICAgICAgKTsKKworICAgIC8qKgorICAgICAqIFRyYW5zbGF0b3Igb2JqZWN0IGZvciB1bmVzY2FwaW5nIGVzY2FwZWQgQ29tbWEgU2VwYXJhdGVkIFZhbHVlIGVudHJpZXMuCisgICAgICoKKyAgICAgKiBXaGlsZSB7QGxpbmsgI3VuZXNjYXBlQ3N2KFN0cmluZyl9IGlzIHRoZSBleHBlY3RlZCBtZXRob2Qgb2YgdXNlLCB0aGlzIAorICAgICAqIG9iamVjdCBhbGxvd3MgdGhlIENTViB1bmVzY2FwaW5nIGZ1bmN0aW9uYWxpdHkgdG8gYmUgdXNlZCAKKyAgICAgKiBhcyB0aGUgZm91bmRhdGlvbiBmb3IgYSBjdXN0b20gdHJhbnNsYXRvci4gCisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIFVORVNDQVBFX0NTViA9IG5ldyBDc3ZVbmVzY2FwZXIoKTsKKworICAgIHN0YXRpYyBjbGFzcyBDc3ZVbmVzY2FwZXIgZXh0ZW5kcyBDaGFyU2VxdWVuY2VUcmFuc2xhdG9yIHsKKworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIENTVl9ERUxJTUlURVIgPSAnLCc7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgQ1NWX1FVT1RFID0gJyInOworICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1NWX1FVT1RFX1NUUiA9IFN0cmluZy52YWx1ZU9mKENTVl9RVU9URSk7CisgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBDU1ZfU0VBUkNIX0NIQVJTID0KKyAgICAgICAgICAgICAgICBuZXcgY2hhcltdIHtDU1ZfREVMSU1JVEVSLCBDU1ZfUVVPVEUsIENoYXJVdGlscy5DUiwgQ2hhclV0aWxzLkxGfTsKKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIGludCB0cmFuc2xhdGUoZmluYWwgQ2hhclNlcXVlbmNlIGlucHV0LCBmaW5hbCBpbnQgaW5kZXgsIGZpbmFsIFdyaXRlciBvdXQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisKKyAgICAgICAgICAgIGlmKGluZGV4ICE9IDApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDc3ZVbmVzY2FwZXIgc2hvdWxkIG5ldmVyIHJlYWNoIHRoZSBbMV0gaW5kZXgiKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCBpbnB1dC5jaGFyQXQoMCkgIT0gQ1NWX1FVT1RFIHx8IGlucHV0LmNoYXJBdChpbnB1dC5sZW5ndGgoKSAtIDEpICE9IENTVl9RVU9URSApIHsKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoaW5wdXQudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudChpbnB1dCwgMCwgaW5wdXQubGVuZ3RoKCkpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBzdHJpcCBxdW90ZXMKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxdW90ZWxlc3MgPSBpbnB1dC5zdWJTZXF1ZW5jZSgxLCBpbnB1dC5sZW5ndGgoKSAtIDEpLnRvU3RyaW5nKCk7CisKKyAgICAgICAgICAgIGlmICggU3RyaW5nVXRpbHMuY29udGFpbnNBbnkocXVvdGVsZXNzLCBDU1ZfU0VBUkNIX0NIQVJTKSApIHsKKyAgICAgICAgICAgICAgICAvLyBkZWFsIHdpdGggZXNjYXBlZCBxdW90ZXM7IGllKSAiIgorICAgICAgICAgICAgICAgIG91dC53cml0ZShTdHJpbmdVdGlscy5yZXBsYWNlKHF1b3RlbGVzcywgQ1NWX1FVT1RFX1NUUiArIENTVl9RVU9URV9TVFIsIENTVl9RVU9URV9TVFIpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgb3V0LndyaXRlKGlucHV0LnRvU3RyaW5nKCkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5jb2RlUG9pbnRDb3VudChpbnB1dCwgMCwgaW5wdXQubGVuZ3RoKCkpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogSGVscGVyIGZ1bmN0aW9ucyAqLworCisgICAgLyoqCisgICAgICogPHA+e0Bjb2RlIFN0cmluZ0VzY2FwZVV0aWxzfSBpbnN0YW5jZXMgc2hvdWxkIE5PVCBiZSBjb25zdHJ1Y3RlZCBpbgorICAgICAqIHN0YW5kYXJkIHByb2dyYW1taW5nLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkluc3RlYWQsIHRoZSBjbGFzcyBzaG91bGQgYmUgdXNlZCBhczo8L3A+CisgICAgICogPHByZT5TdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVKYXZhKCJmb28iKTs8L3ByZT4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgY29uc3RydWN0b3IgaXMgcHVibGljIHRvIHBlcm1pdCB0b29scyB0aGF0IHJlcXVpcmUgYSBKYXZhQmVhbgorICAgICAqIGluc3RhbmNlIHRvIG9wZXJhdGUuPC9wPgorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmdFc2NhcGVVdGlscygpIHsKKyAgICAgICAgc3VwZXIoKTsKKyAgICB9CisKKyAgICAvLyBKYXZhIGFuZCBKYXZhU2NyaXB0CisgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8qKgorICAgICAqIDxwPkVzY2FwZXMgdGhlIGNoYXJhY3RlcnMgaW4gYSB7QGNvZGUgU3RyaW5nfSB1c2luZyBKYXZhIFN0cmluZyBydWxlcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5EZWFscyBjb3JyZWN0bHkgd2l0aCBxdW90ZXMgYW5kIGNvbnRyb2wtY2hhcnMgKHRhYiwgYmFja3NsYXNoLCBjciwgZmYsIGV0Yy4pIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlNvIGEgdGFiIGJlY29tZXMgdGhlIGNoYXJhY3RlcnMge0Bjb2RlICdcXCd9IGFuZAorICAgICAqIHtAY29kZSAndCd9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiBKYXZhIHN0cmluZ3MgYW5kIEphdmFTY3JpcHQgc3RyaW5ncworICAgICAqIGlzIHRoYXQgaW4gSmF2YVNjcmlwdCwgYSBzaW5nbGUgcXVvdGUgYW5kIGZvcndhcmQtc2xhc2ggKC8pIGFyZSBlc2NhcGVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkV4YW1wbGU6PC9wPgorICAgICAqIDxwcmU+CisgICAgICogaW5wdXQgc3RyaW5nOiBIZSBkaWRuJ3Qgc2F5LCAiU3RvcCEiCisgICAgICogb3V0cHV0IHN0cmluZzogSGUgZGlkbid0IHNheSwgXCJTdG9wIVwiCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIFN0cmluZyB0byBlc2NhcGUgdmFsdWVzIGluLCBtYXkgYmUgbnVsbAorICAgICAqIEByZXR1cm4gU3RyaW5nIHdpdGggZXNjYXBlZCB2YWx1ZXMsIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGVzY2FwZUphdmEoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBFU0NBUEVfSkFWQS50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkVzY2FwZXMgdGhlIGNoYXJhY3RlcnMgaW4gYSB7QGNvZGUgU3RyaW5nfSB1c2luZyBFY21hU2NyaXB0IFN0cmluZyBydWxlcy48L3A+CisgICAgICogPHA+RXNjYXBlcyBhbnkgdmFsdWVzIGl0IGZpbmRzIGludG8gdGhlaXIgRWNtYVNjcmlwdCBTdHJpbmcgZm9ybS4KKyAgICAgKiBEZWFscyBjb3JyZWN0bHkgd2l0aCBxdW90ZXMgYW5kIGNvbnRyb2wtY2hhcnMgKHRhYiwgYmFja3NsYXNoLCBjciwgZmYsIGV0Yy4pIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlNvIGEgdGFiIGJlY29tZXMgdGhlIGNoYXJhY3RlcnMge0Bjb2RlICdcXCd9IGFuZAorICAgICAqIHtAY29kZSAndCd9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiBKYXZhIHN0cmluZ3MgYW5kIEVjbWFTY3JpcHQgc3RyaW5ncworICAgICAqIGlzIHRoYXQgaW4gRWNtYVNjcmlwdCwgYSBzaW5nbGUgcXVvdGUgYW5kIGZvcndhcmQtc2xhc2ggKC8pIGFyZSBlc2NhcGVkLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCBFY21hU2NyaXB0IGlzIGJlc3Qga25vd24gYnkgdGhlIEphdmFTY3JpcHQgYW5kIEFjdGlvblNjcmlwdCBkaWFsZWN0cy4gPC9wPgorICAgICAqCisgICAgICogPHA+RXhhbXBsZTo8L3A+CisgICAgICogPHByZT4KKyAgICAgKiBpbnB1dCBzdHJpbmc6IEhlIGRpZG4ndCBzYXksICJTdG9wISIKKyAgICAgKiBvdXRwdXQgc3RyaW5nOiBIZSBkaWRuXCd0IHNheSwgXCJTdG9wIVwiCisgICAgICogPC9wcmU+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIFN0cmluZyB0byBlc2NhcGUgdmFsdWVzIGluLCBtYXkgYmUgbnVsbAorICAgICAqIEByZXR1cm4gU3RyaW5nIHdpdGggZXNjYXBlZCB2YWx1ZXMsIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGVzY2FwZUVjbWFTY3JpcHQoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBFU0NBUEVfRUNNQVNDUklQVC50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkVzY2FwZXMgdGhlIGNoYXJhY3RlcnMgaW4gYSB7QGNvZGUgU3RyaW5nfSB1c2luZyBKc29uIFN0cmluZyBydWxlcy48L3A+CisgICAgICogPHA+RXNjYXBlcyBhbnkgdmFsdWVzIGl0IGZpbmRzIGludG8gdGhlaXIgSnNvbiBTdHJpbmcgZm9ybS4KKyAgICAgKiBEZWFscyBjb3JyZWN0bHkgd2l0aCBxdW90ZXMgYW5kIGNvbnRyb2wtY2hhcnMgKHRhYiwgYmFja3NsYXNoLCBjciwgZmYsIGV0Yy4pIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlNvIGEgdGFiIGJlY29tZXMgdGhlIGNoYXJhY3RlcnMge0Bjb2RlICdcXCd9IGFuZAorICAgICAqIHtAY29kZSAndCd9LjwvcD4KKyAgICAgKgorICAgICAqIDxwPlRoZSBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiBKYXZhIHN0cmluZ3MgYW5kIEpzb24gc3RyaW5ncworICAgICAqIGlzIHRoYXQgaW4gSnNvbiwgZm9yd2FyZC1zbGFzaCAoLykgaXMgZXNjYXBlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5TZWUgaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjNDYyNy50eHQgZm9yIGZ1cnRoZXIgZGV0YWlscy4gPC9wPgorICAgICAqCisgICAgICogPHA+RXhhbXBsZTo8L3A+CisgICAgICogPHByZT4KKyAgICAgKiBpbnB1dCBzdHJpbmc6IEhlIGRpZG4ndCBzYXksICJTdG9wISIKKyAgICAgKiBvdXRwdXQgc3RyaW5nOiBIZSBkaWRuJ3Qgc2F5LCBcIlN0b3AhXCIKKyAgICAgKiA8L3ByZT4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCAgU3RyaW5nIHRvIGVzY2FwZSB2YWx1ZXMgaW4sIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiBTdHJpbmcgd2l0aCBlc2NhcGVkIHZhbHVlcywge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICoKKyAgICAgKiBAc2luY2UgMy4yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZXNjYXBlSnNvbihmaW5hbCBTdHJpbmcgaW5wdXQpIHsKKyAgICAgICAgcmV0dXJuIEVTQ0FQRV9KU09OLnRyYW5zbGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+VW5lc2NhcGVzIGFueSBKYXZhIGxpdGVyYWxzIGZvdW5kIGluIHRoZSB7QGNvZGUgU3RyaW5nfS4KKyAgICAgKiBGb3IgZXhhbXBsZSwgaXQgd2lsbCB0dXJuIGEgc2VxdWVuY2Ugb2Yge0Bjb2RlICdcJ30gYW5kCisgICAgICoge0Bjb2RlICduJ30gaW50byBhIG5ld2xpbmUgY2hhcmFjdGVyLCB1bmxlc3MgdGhlIHtAY29kZSAnXCd9CisgICAgICogaXMgcHJlY2VkZWQgYnkgYW5vdGhlciB7QGNvZGUgJ1wnfS48L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byB1bmVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIGEgbmV3IHVuZXNjYXBlZCB7QGNvZGUgU3RyaW5nfSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdW5lc2NhcGVKYXZhKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gVU5FU0NBUEVfSkFWQS50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlVuZXNjYXBlcyBhbnkgRWNtYVNjcmlwdCBsaXRlcmFscyBmb3VuZCBpbiB0aGUge0Bjb2RlIFN0cmluZ30uPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIGl0IHdpbGwgdHVybiBhIHNlcXVlbmNlIG9mIHtAY29kZSAnXCd9IGFuZCB7QGNvZGUgJ24nfQorICAgICAqIGludG8gYSBuZXdsaW5lIGNoYXJhY3RlciwgdW5sZXNzIHRoZSB7QGNvZGUgJ1wnfSBpcyBwcmVjZWRlZCBieSBhbm90aGVyCisgICAgICoge0Bjb2RlICdcJ30uPC9wPgorICAgICAqCisgICAgICogQHNlZSAjdW5lc2NhcGVKYXZhKFN0cmluZykKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byB1bmVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIEEgbmV3IHVuZXNjYXBlZCB7QGNvZGUgU3RyaW5nfSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdW5lc2NhcGVFY21hU2NyaXB0KGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gVU5FU0NBUEVfRUNNQVNDUklQVC50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlVuZXNjYXBlcyBhbnkgSnNvbiBsaXRlcmFscyBmb3VuZCBpbiB0aGUge0Bjb2RlIFN0cmluZ30uPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGUsIGl0IHdpbGwgdHVybiBhIHNlcXVlbmNlIG9mIHtAY29kZSAnXCd9IGFuZCB7QGNvZGUgJ24nfQorICAgICAqIGludG8gYSBuZXdsaW5lIGNoYXJhY3RlciwgdW5sZXNzIHRoZSB7QGNvZGUgJ1wnfSBpcyBwcmVjZWRlZCBieSBhbm90aGVyCisgICAgICoge0Bjb2RlICdcJ30uPC9wPgorICAgICAqCisgICAgICogQHNlZSAjdW5lc2NhcGVKYXZhKFN0cmluZykKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byB1bmVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIEEgbmV3IHVuZXNjYXBlZCB7QGNvZGUgU3RyaW5nfSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICoKKyAgICAgKiBAc2luY2UgMy4yCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdW5lc2NhcGVKc29uKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gVU5FU0NBUEVfSlNPTi50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8vIEhUTUwgYW5kIFhNTAorICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvKioKKyAgICAgKiA8cD5Fc2NhcGVzIHRoZSBjaGFyYWN0ZXJzIGluIGEge0Bjb2RlIFN0cmluZ30gdXNpbmcgSFRNTCBlbnRpdGllcy48L3A+CisgICAgICoKKyAgICAgKiA8cD4KKyAgICAgKiBGb3IgZXhhbXBsZToKKyAgICAgKiA8L3A+IAorICAgICAqIDxwPjxjb2RlPiJicmVhZCIgJmFtcDsgImJ1dHRlciI8L2NvZGU+PC9wPgorICAgICAqIGJlY29tZXM6CisgICAgICogPHA+CisgICAgICogPGNvZGU+JmFtcDtxdW90O2JyZWFkJmFtcDtxdW90OyAmYW1wO2FtcDsgJmFtcDtxdW90O2J1dHRlciZhbXA7cXVvdDs8L2NvZGU+LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlN1cHBvcnRzIGFsbCBrbm93biBIVE1MIDQuMCBlbnRpdGllcywgaW5jbHVkaW5nIGZ1bmt5IGFjY2VudHMuCisgICAgICogTm90ZSB0aGF0IHRoZSBjb21tb25seSB1c2VkIGFwb3N0cm9waGUgZXNjYXBlIGNoYXJhY3RlciAoJmFtcDthcG9zOykKKyAgICAgKiBpcyBub3QgYSBsZWdhbCBlbnRpdHkgYW5kIHNvIGlzIG5vdCBzdXBwb3J0ZWQpLiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byBlc2NhcGUsIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiBhIG5ldyBlc2NhcGVkIHtAY29kZSBTdHJpbmd9LCB7QGNvZGUgbnVsbH0gaWYgbnVsbCBzdHJpbmcgaW5wdXQKKyAgICAgKgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2hvdHdpcmVkLmx5Y29zLmNvbS93ZWJtb25rZXkvcmVmZXJlbmNlL3NwZWNpYWxfY2hhcmFjdGVycy8iPklTTyBFbnRpdGllczwvYT4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sMzIjbGF0aW4xIj5IVE1MIDMuMiBDaGFyYWN0ZXIgRW50aXRpZXMgZm9yIElTTyBMYXRpbi0xPC9hPgorICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9zZ21sL2VudGl0aWVzLmh0bWwiPkhUTUwgNC4wIENoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlczwvYT4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0MDEvY2hhcnNldC5odG1sI2gtNS4zIj5IVE1MIDQuMDEgQ2hhcmFjdGVyIFJlZmVyZW5jZXM8L2E+CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNDAxL2NoYXJzZXQuaHRtbCNjb2RlLXBvc2l0aW9uIj5IVE1MIDQuMDEgQ29kZSBwb3NpdGlvbnM8L2E+CisgICAgICoKKyAgICAgKiBAc2luY2UgMy4wCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZXNjYXBlSHRtbDQoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBFU0NBUEVfSFRNTDQudHJhbnNsYXRlKGlucHV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5Fc2NhcGVzIHRoZSBjaGFyYWN0ZXJzIGluIGEge0Bjb2RlIFN0cmluZ30gdXNpbmcgSFRNTCBlbnRpdGllcy48L3A+CisgICAgICogPHA+U3VwcG9ydHMgb25seSB0aGUgSFRNTCAzLjAgZW50aXRpZXMuIDwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCAgdGhlIHtAY29kZSBTdHJpbmd9IHRvIGVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGVzY2FwZWQge0Bjb2RlIFN0cmluZ30sIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGVzY2FwZUh0bWwzKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gRVNDQVBFX0hUTUwzLnRyYW5zbGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIC8qKgorICAgICAqIDxwPlVuZXNjYXBlcyBhIHN0cmluZyBjb250YWluaW5nIGVudGl0eSBlc2NhcGVzIHRvIGEgc3RyaW5nCisgICAgICogY29udGFpbmluZyB0aGUgYWN0dWFsIFVuaWNvZGUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIGVzY2FwZXMuIFN1cHBvcnRzIEhUTUwgNC4wIGVudGl0aWVzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlLCB0aGUgc3RyaW5nIHtAY29kZSAiJmx0O0ZyYW4mY2NlZGlsO2FpcyZndDsifQorICAgICAqIHdpbGwgYmVjb21lIHtAY29kZSAiPEZyYW7nYWlzPiJ9PC9wPgorICAgICAqCisgICAgICogPHA+SWYgYW4gZW50aXR5IGlzIHVucmVjb2duaXplZCwgaXQgaXMgbGVmdCBhbG9uZSwgYW5kIGluc2VydGVkCisgICAgICogdmVyYmF0aW0gaW50byB0aGUgcmVzdWx0IHN0cmluZy4gZS5nLiB7QGNvZGUgIiZndDsmenp6ejt4In0gd2lsbAorICAgICAqIGJlY29tZSB7QGNvZGUgIj4menp6ejt4In0uPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0ICB0aGUge0Bjb2RlIFN0cmluZ30gdG8gdW5lc2NhcGUsIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiBhIG5ldyB1bmVzY2FwZWQge0Bjb2RlIFN0cmluZ30sIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHVuZXNjYXBlSHRtbDQoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBVTkVTQ0FQRV9IVE1MNC50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPlVuZXNjYXBlcyBhIHN0cmluZyBjb250YWluaW5nIGVudGl0eSBlc2NhcGVzIHRvIGEgc3RyaW5nCisgICAgICogY29udGFpbmluZyB0aGUgYWN0dWFsIFVuaWNvZGUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIGVzY2FwZXMuIFN1cHBvcnRzIG9ubHkgSFRNTCAzLjAgZW50aXRpZXMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0ICB0aGUge0Bjb2RlIFN0cmluZ30gdG8gdW5lc2NhcGUsIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiBhIG5ldyB1bmVzY2FwZWQge0Bjb2RlIFN0cmluZ30sIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqCisgICAgICogQHNpbmNlIDMuMAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHVuZXNjYXBlSHRtbDMoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBVTkVTQ0FQRV9IVE1MMy50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAvKioKKyAgICAgKiA8cD5Fc2NhcGVzIHRoZSBjaGFyYWN0ZXJzIGluIGEge0Bjb2RlIFN0cmluZ30gdXNpbmcgWE1MIGVudGl0aWVzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPkZvciBleGFtcGxlOiB7QGNvZGUgImJyZWFkIiAmICJidXR0ZXIifSA9Jmd0OworICAgICAqIHtAY29kZSAmcXVvdDticmVhZCZxdW90OyAmYW1wOyAmcXVvdDtidXR0ZXImcXVvdDt9LgorICAgICAqIDwvcD4KKyAgICAgKgorICAgICAqIDxwPlN1cHBvcnRzIG9ubHkgdGhlIGZpdmUgYmFzaWMgWE1MIGVudGl0aWVzIChndCwgbHQsIHF1b3QsIGFtcCwgYXBvcykuCisgICAgICogRG9lcyBub3Qgc3VwcG9ydCBEVERzIG9yIGV4dGVybmFsIGVudGl0aWVzLjwvcD4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhhdCBVbmljb2RlIGNoYXJhY3RlcnMgZ3JlYXRlciB0aGFuIDB4N2YgYXJlIGFzIG9mIDMuMCwgbm8gbG9uZ2VyIAorICAgICAqICAgIGVzY2FwZWQuIElmIHlvdSBzdGlsbCB3aXNoIHRoaXMgZnVuY3Rpb25hbGl0eSwgeW91IGNhbiBhY2hpZXZlIGl0IAorICAgICAqICAgIHZpYSB0aGUgZm9sbG93aW5nOiAKKyAgICAgKiB7QGNvZGUgU3RyaW5nRXNjYXBlVXRpbHMuRVNDQVBFX1hNTC53aXRoKCBOdW1lcmljRW50aXR5RXNjYXBlci5iZXR3ZWVuKDB4N2YsIEludGVnZXIuTUFYX1ZBTFVFKSApO308L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byBlc2NhcGUsIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiBhIG5ldyBlc2NhcGVkIHtAY29kZSBTdHJpbmd9LCB7QGNvZGUgbnVsbH0gaWYgbnVsbCBzdHJpbmcgaW5wdXQKKyAgICAgKiBAc2VlICN1bmVzY2FwZVhtbChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2VzY2FwZVhtbDEwKGphdmEubGFuZy5TdHJpbmcpfSBvciB7QGxpbmsgI2VzY2FwZVhtbDExKGphdmEubGFuZy5TdHJpbmcpfSBpbnN0ZWFkLgorICAgICAqLworICAgIEBEZXByZWNhdGVkCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgZXNjYXBlWG1sKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gRVNDQVBFX1hNTC50cmFuc2xhdGUoaW5wdXQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIDxwPkVzY2FwZXMgdGhlIGNoYXJhY3RlcnMgaW4gYSB7QGNvZGUgU3RyaW5nfSB1c2luZyBYTUwgZW50aXRpZXMuPC9wPgorICAgICAqCisgICAgICogPHA+Rm9yIGV4YW1wbGU6IHtAY29kZSAiYnJlYWQiICYgImJ1dHRlciJ9ID0mZ3Q7CisgICAgICoge0Bjb2RlICZxdW90O2JyZWFkJnF1b3Q7ICZhbXA7ICZxdW90O2J1dHRlciZxdW90O30uCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IFhNTCAxLjAgaXMgYSB0ZXh0LW9ubHkgZm9ybWF0OiBpdCBjYW5ub3QgcmVwcmVzZW50IGNvbnRyb2wKKyAgICAgKiBjaGFyYWN0ZXJzIG9yIHVucGFpcmVkIFVuaWNvZGUgc3Vycm9nYXRlIGNvZGVwb2ludHMsIGV2ZW4gYWZ0ZXIgZXNjYXBpbmcuCisgICAgICoge0Bjb2RlIGVzY2FwZVhtbDEwfSB3aWxsIHJlbW92ZSBjaGFyYWN0ZXJzIHRoYXQgZG8gbm90IGZpdCBpbiB0aGUKKyAgICAgKiBmb2xsb3dpbmcgcmFuZ2VzOjwvcD4KKyAgICAgKgorICAgICAqIDxwPntAY29kZSAjeDkgfCAjeEEgfCAjeEQgfCBbI3gyMC0jeEQ3RkZdIHwgWyN4RTAwMC0jeEZGRkRdIHwgWyN4MTAwMDAtI3gxMEZGRkZdfTwvcD4KKyAgICAgKgorICAgICAqIDxwPlRob3VnaCBub3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCB7QGNvZGUgZXNjYXBlWG1sMTB9IHdpbGwgZXNjYXBlCisgICAgICogY2hhcmFjdGVycyBpbiB0aGUgZm9sbG93aW5nIHJhbmdlczo8L3A+CisgICAgICoKKyAgICAgKiA8cD57QGNvZGUgWyN4N0YtI3g4NF0gfCBbI3g4Ni0jeDlGXX08L3A+CisgICAgICoKKyAgICAgKiA8cD5UaGUgcmV0dXJuZWQgc3RyaW5nIGNhbiBiZSBpbnNlcnRlZCBpbnRvIGEgdmFsaWQgWE1MIDEuMCBvciBYTUwgMS4xCisgICAgICogZG9jdW1lbnQuIElmIHlvdSB3YW50IHRvIGFsbG93IG1vcmUgbm9uLXRleHQgY2hhcmFjdGVycyBpbiBhbiBYTUwgMS4xCisgICAgICogZG9jdW1lbnQsIHVzZSB7QGxpbmsgI2VzY2FwZVhtbDExKFN0cmluZyl9LjwvcD4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCAgdGhlIHtAY29kZSBTdHJpbmd9IHRvIGVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIGEgbmV3IGVzY2FwZWQge0Bjb2RlIFN0cmluZ30sIHtAY29kZSBudWxsfSBpZiBudWxsIHN0cmluZyBpbnB1dAorICAgICAqIEBzZWUgI3VuZXNjYXBlWG1sKGphdmEubGFuZy5TdHJpbmcpCisgICAgICogQHNpbmNlIDMuMworICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVzY2FwZVhtbDEwKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gRVNDQVBFX1hNTDEwLnRyYW5zbGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogPHA+RXNjYXBlcyB0aGUgY2hhcmFjdGVycyBpbiBhIHtAY29kZSBTdHJpbmd9IHVzaW5nIFhNTCBlbnRpdGllcy48L3A+CisgICAgICoKKyAgICAgKiA8cD5Gb3IgZXhhbXBsZToge0Bjb2RlICJicmVhZCIgJiAiYnV0dGVyIn0gPSZndDsKKyAgICAgKiB7QGNvZGUgJnF1b3Q7YnJlYWQmcXVvdDsgJmFtcDsgJnF1b3Q7YnV0dGVyJnF1b3Q7fS4KKyAgICAgKiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5YTUwgMS4xIGNhbiByZXByZXNlbnQgY2VydGFpbiBjb250cm9sIGNoYXJhY3RlcnMsIGJ1dCBpdCBjYW5ub3QgcmVwcmVzZW50CisgICAgICogdGhlIG51bGwgYnl0ZSBvciB1bnBhaXJlZCBVbmljb2RlIHN1cnJvZ2F0ZSBjb2RlcG9pbnRzLCBldmVuIGFmdGVyIGVzY2FwaW5nLgorICAgICAqIHtAY29kZSBlc2NhcGVYbWwxMX0gd2lsbCByZW1vdmUgY2hhcmFjdGVycyB0aGF0IGRvIG5vdCBmaXQgaW4gdGhlIGZvbGxvd2luZworICAgICAqIHJhbmdlczo8L3A+CisgICAgICoKKyAgICAgKiA8cD57QGNvZGUgWyN4MS0jeEQ3RkZdIHwgWyN4RTAwMC0jeEZGRkRdIHwgWyN4MTAwMDAtI3gxMEZGRkZdfTwvcD4KKyAgICAgKgorICAgICAqIDxwPntAY29kZSBlc2NhcGVYbWwxMX0gd2lsbCBlc2NhcGUgY2hhcmFjdGVycyBpbiB0aGUgZm9sbG93aW5nIHJhbmdlczo8L3A+CisgICAgICoKKyAgICAgKiA8cD57QGNvZGUgWyN4MS0jeDhdIHwgWyN4Qi0jeENdIHwgWyN4RS0jeDFGXSB8IFsjeDdGLSN4ODRdIHwgWyN4ODYtI3g5Rl19PC9wPgorICAgICAqCisgICAgICogPHA+VGhlIHJldHVybmVkIHN0cmluZyBjYW4gYmUgaW5zZXJ0ZWQgaW50byBhIHZhbGlkIFhNTCAxLjEgZG9jdW1lbnQuIERvIG5vdAorICAgICAqIHVzZSBpdCBmb3IgWE1MIDEuMCBkb2N1bWVudHMuPC9wPgorICAgICAqCisgICAgICogQHBhcmFtIGlucHV0ICB0aGUge0Bjb2RlIFN0cmluZ30gdG8gZXNjYXBlLCBtYXkgYmUgbnVsbAorICAgICAqIEByZXR1cm4gYSBuZXcgZXNjYXBlZCB7QGNvZGUgU3RyaW5nfSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICogQHNlZSAjdW5lc2NhcGVYbWwoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKiBAc2luY2UgMy4zCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZXNjYXBlWG1sMTEoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBFU0NBUEVfWE1MMTEudHJhbnNsYXRlKGlucHV0KTsKKyAgICB9CisKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgLyoqCisgICAgICogPHA+VW5lc2NhcGVzIGEgc3RyaW5nIGNvbnRhaW5pbmcgWE1MIGVudGl0eSBlc2NhcGVzIHRvIGEgc3RyaW5nCisgICAgICogY29udGFpbmluZyB0aGUgYWN0dWFsIFVuaWNvZGUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAgICAqIGVzY2FwZXMuPC9wPgorICAgICAqCisgICAgICogPHA+U3VwcG9ydHMgb25seSB0aGUgZml2ZSBiYXNpYyBYTUwgZW50aXRpZXMgKGd0LCBsdCwgcXVvdCwgYW1wLCBhcG9zKS4KKyAgICAgKiBEb2VzIG5vdCBzdXBwb3J0IERURHMgb3IgZXh0ZXJuYWwgZW50aXRpZXMuPC9wPgorICAgICAqCisgICAgICogPHA+Tm90ZSB0aGF0IG51bWVyaWNhbCBcXHUgVW5pY29kZSBjb2RlcyBhcmUgdW5lc2NhcGVkIHRvIHRoZWlyIHJlc3BlY3RpdmUgCisgICAgICogICAgVW5pY29kZSBjaGFyYWN0ZXJzLiBUaGlzIG1heSBjaGFuZ2UgaW4gZnV0dXJlIHJlbGVhc2VzLiA8L3A+CisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgIHRoZSB7QGNvZGUgU3RyaW5nfSB0byB1bmVzY2FwZSwgbWF5IGJlIG51bGwKKyAgICAgKiBAcmV0dXJuIGEgbmV3IHVuZXNjYXBlZCB7QGNvZGUgU3RyaW5nfSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICogQHNlZSAjZXNjYXBlWG1sKFN0cmluZykKKyAgICAgKiBAc2VlICNlc2NhcGVYbWwxMChTdHJpbmcpCisgICAgICogQHNlZSAjZXNjYXBlWG1sMTEoU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIHVuZXNjYXBlWG1sKGZpbmFsIFN0cmluZyBpbnB1dCkgeworICAgICAgICByZXR1cm4gVU5FU0NBUEVfWE1MLnRyYW5zbGF0ZShpbnB1dCk7CisgICAgfQorCisgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLyoqCisgICAgICogPHA+UmV0dXJucyBhIHtAY29kZSBTdHJpbmd9IHZhbHVlIGZvciBhIENTViBjb2x1bW4gZW5jbG9zZWQgaW4gZG91YmxlIHF1b3RlcywKKyAgICAgKiBpZiByZXF1aXJlZC48L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgdmFsdWUgY29udGFpbnMgYSBjb21tYSwgbmV3bGluZSBvciBkb3VibGUgcXVvdGUsIHRoZW4gdGhlCisgICAgICogICAgU3RyaW5nIHZhbHVlIGlzIHJldHVybmVkIGVuY2xvc2VkIGluIGRvdWJsZSBxdW90ZXMuPC9wPgorICAgICAqCisgICAgICogPHA+QW55IGRvdWJsZSBxdW90ZSBjaGFyYWN0ZXJzIGluIHRoZSB2YWx1ZSBhcmUgZXNjYXBlZCB3aXRoIGFub3RoZXIgZG91YmxlIHF1b3RlLjwvcD4KKyAgICAgKgorICAgICAqIDxwPklmIHRoZSB2YWx1ZSBkb2VzIG5vdCBjb250YWluIGEgY29tbWEsIG5ld2xpbmUgb3IgZG91YmxlIHF1b3RlLCB0aGVuIHRoZQorICAgICAqICAgIFN0cmluZyB2YWx1ZSBpcyByZXR1cm5lZCB1bmNoYW5nZWQuPC9wPgorICAgICAqCisgICAgICogc2VlIDxhIGhyZWY9Imh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29tbWEtc2VwYXJhdGVkX3ZhbHVlcyI+V2lraXBlZGlhPC9hPiBhbmQKKyAgICAgKiA8YSBocmVmPSJodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0MTgwIj5SRkMgNDE4MDwvYT4uCisgICAgICoKKyAgICAgKiBAcGFyYW0gaW5wdXQgdGhlIGlucHV0IENTViBjb2x1bW4gU3RyaW5nLCBtYXkgYmUgbnVsbAorICAgICAqIEByZXR1cm4gdGhlIGlucHV0IFN0cmluZywgZW5jbG9zZWQgaW4gZG91YmxlIHF1b3RlcyBpZiB0aGUgdmFsdWUgY29udGFpbnMgYSBjb21tYSwKKyAgICAgKiBuZXdsaW5lIG9yIGRvdWJsZSBxdW90ZSwge0Bjb2RlIG51bGx9IGlmIG51bGwgc3RyaW5nIGlucHV0CisgICAgICogQHNpbmNlIDIuNAorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGVzY2FwZUNzdihmaW5hbCBTdHJpbmcgaW5wdXQpIHsKKyAgICAgICAgcmV0dXJuIEVTQ0FQRV9DU1YudHJhbnNsYXRlKGlucHV0KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiA8cD5SZXR1cm5zIGEge0Bjb2RlIFN0cmluZ30gdmFsdWUgZm9yIGFuIHVuZXNjYXBlZCBDU1YgY29sdW1uLiA8L3A+CisgICAgICoKKyAgICAgKiA8cD5JZiB0aGUgdmFsdWUgaXMgZW5jbG9zZWQgaW4gZG91YmxlIHF1b3RlcywgYW5kIGNvbnRhaW5zIGEgY29tbWEsIG5ld2xpbmUgCisgICAgICogICAgb3IgZG91YmxlIHF1b3RlLCB0aGVuIHF1b3RlcyBhcmUgcmVtb3ZlZC4gCisgICAgICogPC9wPgorICAgICAqCisgICAgICogPHA+QW55IGRvdWJsZSBxdW90ZSBlc2NhcGVkIGNoYXJhY3RlcnMgKGEgcGFpciBvZiBkb3VibGUgcXVvdGVzKSBhcmUgdW5lc2NhcGVkIAorICAgICAqICAgIHRvIGp1c3Qgb25lIGRvdWJsZSBxdW90ZS4gPC9wPgorICAgICAqCisgICAgICogPHA+SWYgdGhlIHZhbHVlIGlzIG5vdCBlbmNsb3NlZCBpbiBkb3VibGUgcXVvdGVzLCBvciBpcyBhbmQgZG9lcyBub3QgY29udGFpbiBhIAorICAgICAqICAgIGNvbW1hLCBuZXdsaW5lIG9yIGRvdWJsZSBxdW90ZSwgdGhlbiB0aGUgU3RyaW5nIHZhbHVlIGlzIHJldHVybmVkIHVuY2hhbmdlZC48L3A+CisgICAgICoKKyAgICAgKiBzZWUgPGEgaHJlZj0iaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21tYS1zZXBhcmF0ZWRfdmFsdWVzIj5XaWtpcGVkaWE8L2E+IGFuZAorICAgICAqIDxhIGhyZWY9Imh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQxODAiPlJGQyA0MTgwPC9hPi4KKyAgICAgKgorICAgICAqIEBwYXJhbSBpbnB1dCB0aGUgaW5wdXQgQ1NWIGNvbHVtbiBTdHJpbmcsIG1heSBiZSBudWxsCisgICAgICogQHJldHVybiB0aGUgaW5wdXQgU3RyaW5nLCB3aXRoIGVuY2xvc2luZyBkb3VibGUgcXVvdGVzIHJlbW92ZWQgYW5kIGVtYmVkZGVkIGRvdWJsZSAKKyAgICAgKiBxdW90ZXMgdW5lc2NhcGVkLCB7QGNvZGUgbnVsbH0gaWYgbnVsbCBzdHJpbmcgaW5wdXQKKyAgICAgKiBAc2luY2UgMi40CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgdW5lc2NhcGVDc3YoZmluYWwgU3RyaW5nIGlucHV0KSB7CisgICAgICAgIHJldHVybiBVTkVTQ0FQRV9DU1YudHJhbnNsYXRlKGlucHV0KTsKKyAgICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvY29tbW9ucy90ZXh0L1N0cmluZ0VzY2FwZVV0aWxzVGVzdC5qYXZhIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvdGV4dC9TdHJpbmdFc2NhcGVVdGlsc1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODZmNzY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2NvbW1vbnMvdGV4dC9TdHJpbmdFc2NhcGVVdGlsc1Rlc3QuamF2YQpAQCAtMCwwICsxLDYyMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQorICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoCisgKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCisgKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMAorICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgKKyAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKiAKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKiAKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy50ZXh0OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Db25zdHJ1Y3RvcjsKK2ltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMuaW8uSU9VdGlsczsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMudGV4dC50cmFuc2xhdGUuQ2hhclNlcXVlbmNlVHJhbnNsYXRvcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMudGV4dC50cmFuc2xhdGUuTnVtZXJpY0VudGl0eUVzY2FwZXI7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CisKKy8qKgorICogVW5pdCB0ZXN0cyBmb3Ige0BsaW5rIFN0cmluZ0VzY2FwZVV0aWxzfS4KKyAqCisgKiA8cD4KKyAqIFRoaXMgY29kZSBoYXMgYmVlbiBhZGFwdGVkIGZyb20gQXBhY2hlIENvbW1vbnMgTGFuZyAzLjUuCisgKiA8L3A+CisgKgorICovCitwdWJsaWMgY2xhc3MgU3RyaW5nRXNjYXBlVXRpbHNUZXN0IHsKKyAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgRk9PID0gImZvbyI7CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RDb25zdHJ1Y3RvcigpIHsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbChuZXcgU3RyaW5nRXNjYXBlVXRpbHMoKSk7CisgICAgICAgIGZpbmFsIENvbnN0cnVjdG9yPD8+W10gY29ucyA9IFN0cmluZ0VzY2FwZVV0aWxzLmNsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3JzKCk7CisgICAgICAgIGFzc2VydEVxdWFscygxLCBjb25zLmxlbmd0aCk7CisgICAgICAgIGFzc2VydFRydWUoTW9kaWZpZXIuaXNQdWJsaWMoY29uc1swXS5nZXRNb2RpZmllcnMoKSkpOworICAgICAgICBhc3NlcnRUcnVlKE1vZGlmaWVyLmlzUHVibGljKFN0cmluZ0VzY2FwZVV0aWxzLmNsYXNzLmdldE1vZGlmaWVycygpKSk7CisgICAgICAgIGFzc2VydEZhbHNlKE1vZGlmaWVyLmlzRmluYWwoU3RyaW5nRXNjYXBlVXRpbHMuY2xhc3MuZ2V0TW9kaWZpZXJzKCkpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVKYXZhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKG51bGwsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUphdmEobnVsbCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuRVNDQVBFX0pBVkEudHJhbnNsYXRlKG51bGwsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfQorICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuRVNDQVBFX0pBVkEudHJhbnNsYXRlKCIiLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgIH0KKworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKCJlbXB0eSBzdHJpbmciLCAiIiwgIiIpOworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKEZPTywgRk9PKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlSmF2YSgidGFiIiwgIlxcdCIsICJcdCIpOworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKCJiYWNrc2xhc2giLCAiXFxcXCIsICJcXCIpOworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKCJzaW5nbGUgcXVvdGUgc2hvdWxkIG5vdCBiZSBlc2NhcGVkIiwgIiciLCAiJyIpOworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKCJcXFxcXFxiXFx0XFxyIiwgIlxcXGJcdFxyIik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIlxcdTEyMzQiLCAiXHUxMjM0Iik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIlxcdTAyMzQiLCAiXHUwMjM0Iik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIlxcdTAwRUYiLCAiXHUwMGVmIik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIlxcdTAwMDEiLCAiXHUwMDAxIik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIlNob3VsZCB1c2UgY2FwaXRhbGl6ZWQgVW5pY29kZSBoZXgiLCAiXFx1QUJDRCIsICJcdWFiY2QiKTsKKworICAgICAgICBhc3NlcnRFc2NhcGVKYXZhKCJIZSBkaWRuJ3Qgc2F5LCBcXFwic3RvcCFcXFwiIiwKKyAgICAgICAgICAgICAgICAiSGUgZGlkbid0IHNheSwgXCJzdG9wIVwiIik7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEoIm5vbi1icmVha2luZyBzcGFjZSIsICJUaGlzIHNwYWNlIGlzIG5vbi1icmVha2luZzoiICsgIlxcdTAwQTAiLAorICAgICAgICAgICAgICAgICJUaGlzIHNwYWNlIGlzIG5vbi1icmVha2luZzpcdTAwYTAiKTsKKyAgICAgICAgYXNzZXJ0RXNjYXBlSmF2YSgiXFx1QUJDRFxcdTEyMzRcXHUwMTJDIiwKKyAgICAgICAgICAgICAgICAiXHVBQkNEXHUxMjM0XHUwMTJDIik7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9MQU5HLTQyMQorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwZUphdmFXaXRoU2xhc2goKSB7CisgICAgICAgIGZpbmFsIFN0cmluZyBpbnB1dCA9ICJTdHJpbmcgd2l0aCBhIHNsYXNoICgvKSBpbiBpdCI7CisKKyAgICAgICAgZmluYWwgU3RyaW5nIGV4cGVjdGVkID0gaW5wdXQ7CisgICAgICAgIGZpbmFsIFN0cmluZyBhY3R1YWwgPSBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVKYXZhKGlucHV0KTsKKworICAgICAgICAvKioKKyAgICAgICAgICogSW4gMi40IFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUphdmEoU3RyaW5nKSBlc2NhcGVzICcvJyBjaGFyYWN0ZXJzLCB3aGljaCBhcmUgbm90IGEgdmFsaWQgY2hhcmFjdGVyIHRvIGVzY2FwZQorICAgICAgICAgKiBpbiBhIEphdmEgc3RyaW5nLgorICAgICAgICAgKi8KKyAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBhY3R1YWwpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFc2NhcGVKYXZhKGZpbmFsIFN0cmluZyBlc2NhcGVkLCBmaW5hbCBTdHJpbmcgb3JpZ2luYWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVzY2FwZUphdmEobnVsbCwgZXNjYXBlZCwgb3JpZ2luYWwpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRFc2NhcGVKYXZhKFN0cmluZyBtZXNzYWdlLCBmaW5hbCBTdHJpbmcgZXhwZWN0ZWQsIGZpbmFsIFN0cmluZyBvcmlnaW5hbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGNvbnZlcnRlZCA9IFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUphdmEob3JpZ2luYWwpOworICAgICAgICBtZXNzYWdlID0gImVzY2FwZUphdmEoU3RyaW5nKSBmYWlsZWQiICsgKG1lc3NhZ2UgPT0gbnVsbCA/ICIiIDogKCI6ICIgKyBtZXNzYWdlKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBleHBlY3RlZCwgY29udmVydGVkKTsKKworICAgICAgICBmaW5hbCBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5FU0NBUEVfSkFWQS50cmFuc2xhdGUob3JpZ2luYWwsIHdyaXRlcik7CisgICAgICAgIGFzc2VydEVxdWFscyhleHBlY3RlZCwgd3JpdGVyLnRvU3RyaW5nKCkpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuZXNjYXBlSmF2YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUphdmEobnVsbCkpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuVU5FU0NBUEVfSkFWQS50cmFuc2xhdGUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5VTkVTQ0FQRV9KQVZBLnRyYW5zbGF0ZSgiIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUphdmEoIlxcdTAyLTMiKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgUnVudGltZUV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0VW5lc2NhcGVKYXZhKCIiLCAiIik7CisgICAgICAgIGFzc2VydFVuZXNjYXBlSmF2YSgidGVzdCIsICJ0ZXN0Iik7CisgICAgICAgIGFzc2VydFVuZXNjYXBlSmF2YSgiXG50ZXN0XGIiLCAiXFxudGVzdFxcYiIpOworICAgICAgICBhc3NlcnRVbmVzY2FwZUphdmEoIlx1MTIzNDI1Zm9vXG50ZXN0XGIiLCAiXFx1MTIzNDI1Zm9vXFxudGVzdFxcYiIpOworICAgICAgICBhc3NlcnRVbmVzY2FwZUphdmEoIidcZm9vXHRlc3RlXHIiLCAiXFwnXFxmb29cXHRlc3RlXFxyIik7CisgICAgICAgIGFzc2VydFVuZXNjYXBlSmF2YSgiIiwgIlxcIik7CisgICAgICAgIC8vZm9vCisgICAgICAgIGFzc2VydFVuZXNjYXBlSmF2YSgibG93ZXJjYXNlIFVuaWNvZGUiLCAiXHVBQkNEeCIsICJcXHVhYmNkeCIpOworICAgICAgICBhc3NlcnRVbmVzY2FwZUphdmEoInVwcGVyY2FzZSBVbmljb2RlIiwgIlx1QUJDRHgiLCAiXFx1QUJDRHgiKTsKKyAgICAgICAgYXNzZXJ0VW5lc2NhcGVKYXZhKCJVbmljb2RlIGFzIGZpbmFsIGNoYXJhY3RlciIsICJcdUFCQ0QiLCAiXFx1YWJjZCIpOworICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBhc3NlcnRVbmVzY2FwZUphdmEoZmluYWwgU3RyaW5nIHVuZXNjYXBlZCwgZmluYWwgU3RyaW5nIG9yaWdpbmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBhc3NlcnRVbmVzY2FwZUphdmEobnVsbCwgdW5lc2NhcGVkLCBvcmlnaW5hbCk7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGFzc2VydFVuZXNjYXBlSmF2YShmaW5hbCBTdHJpbmcgbWVzc2FnZSwgZmluYWwgU3RyaW5nIHVuZXNjYXBlZCwgZmluYWwgU3RyaW5nIG9yaWdpbmFsKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgZXhwZWN0ZWQgPSB1bmVzY2FwZWQ7CisgICAgICAgIGZpbmFsIFN0cmluZyBhY3R1YWwgPSBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUphdmEob3JpZ2luYWwpOworCisgICAgICAgIGFzc2VydEVxdWFscygidW5lc2NhcGUoU3RyaW5nKSBmYWlsZWQiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlID09IG51bGwgPyAiIiA6ICgiOiAiICsgbWVzc2FnZSkpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICI6IGV4cGVjdGVkICciICsgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlSmF2YShleHBlY3RlZCkgKworICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgZXNjYXBlIHRoaXMgc28gd2UgY2FuIHNlZSBpdCBpbiB0aGUgZXJyb3IgbWVzc2FnZQorICAgICAgICAgICAgICAgICAgICAgICAgIicgYWN0dWFsICciICsgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlSmF2YShhY3R1YWwpICsgIiciLAorICAgICAgICAgICAgICAgIGV4cGVjdGVkLCBhY3R1YWwpOworCisgICAgICAgIGZpbmFsIFN0cmluZ1dyaXRlciB3cml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLlVORVNDQVBFX0pBVkEudHJhbnNsYXRlKG9yaWdpbmFsLCB3cml0ZXIpOworICAgICAgICBhc3NlcnRFcXVhbHModW5lc2NhcGVkLCB3cml0ZXIudG9TdHJpbmcoKSk7CisKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVFY21hU2NyaXB0KCkgeworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlRWNtYVNjcmlwdChudWxsKSk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5FU0NBUEVfRUNNQVNDUklQVC50cmFuc2xhdGUobnVsbCwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5FU0NBUEVfRUNNQVNDUklQVC50cmFuc2xhdGUoIiIsIG51bGwpOworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBleCkgeworICAgICAgICAgICAgZmFpbCgpOworICAgICAgICB9IGNhdGNoIChmaW5hbCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgfQorCisgICAgICAgIGFzc2VydEVxdWFscygiSGUgZGlkblxcJ3Qgc2F5LCBcXFwic3RvcCFcXFwiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlRWNtYVNjcmlwdCgiSGUgZGlkbid0IHNheSwgXCJzdG9wIVwiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxcXCJ0ZXN0XFxcIikudmFsdWUgPSBcXCc8c2NyaXB0PmFsZXJ0KFxcJ2FhYVxcJyk7PFxcL3NjcmlwdD5cXCc7IiwKKyAgICAgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVFY21hU2NyaXB0KCJkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInRlc3RcIikudmFsdWUgPSAnPHNjcmlwdD5hbGVydCgnYWFhJyk7PC9zY3JpcHQ+JzsiKSk7CisgICAgfQorCisKKyAgICAvLyBIVE1MIGFuZCBYTUwKKyAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXVtdIEhUTUxfRVNDQVBFUyA9IHsKKyAgICAgICAgICAgIHsibm8gZXNjYXBpbmciLCAicGxhaW4gdGV4dCIsICJwbGFpbiB0ZXh0In0sCisgICAgICAgICAgICB7Im5vIGVzY2FwaW5nIiwgInBsYWluIHRleHQiLCAicGxhaW4gdGV4dCJ9LAorICAgICAgICAgICAgeyJlbXB0eSBzdHJpbmciLCAiIiwgIiJ9LAorICAgICAgICAgICAgeyJudWxsIiwgbnVsbCwgbnVsbH0sCisgICAgICAgICAgICB7ImFtcGVyc2FuZCIsICJicmVhZCAmYW1wOyBidXR0ZXIiLCAiYnJlYWQgJiBidXR0ZXIifSwKKyAgICAgICAgICAgIHsicXVvdGVzIiwgIiZxdW90O2JyZWFkJnF1b3Q7ICZhbXA7IGJ1dHRlciIsICJcImJyZWFkXCIgJiBidXR0ZXIifSwKKyAgICAgICAgICAgIHsiZmluYWwgY2hhcmFjdGVyIG9ubHkiLCAiZ3JlYXRlciB0aGFuICZndDsiLCAiZ3JlYXRlciB0aGFuID4ifSwKKyAgICAgICAgICAgIHsiZmlyc3QgY2hhcmFjdGVyIG9ubHkiLCAiJmx0OyBsZXNzIHRoYW4iLCAiPCBsZXNzIHRoYW4ifSwKKyAgICAgICAgICAgIHsiYXBvc3Ryb3BoZSIsICJIdW50aW5ndG9uJ3MgY2hvcmVhIiwgIkh1bnRpbmd0b24ncyBjaG9yZWEifSwKKyAgICAgICAgICAgIHsibGFuZ3VhZ2VzIiwgIkVuZ2xpc2gsRnJhbiZjY2VkaWw7YWlzLFx1NjVFNVx1NjcyQ1x1OEE5RSAobmlob25nbykiLCAiRW5nbGlzaCxGcmFuXHUwMEU3YWlzLFx1NjVFNVx1NjcyQ1x1OEE5RSAobmlob25nbykifSwKKyAgICAgICAgICAgIHsiOC1iaXQgYXNjaWkgc2hvdWxkbid0IG51bWJlci1lc2NhcGUiLCAiXHUwMDgwXHUwMDlGIiwgIlx1MDA4MFx1MDA5RiJ9LAorICAgIH07CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVIdG1sKCkgeworICAgICAgICBmb3IgKGZpbmFsIFN0cmluZ1tdIGVsZW1lbnQgOiBIVE1MX0VTQ0FQRVMpIHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtZXNzYWdlID0gZWxlbWVudFswXTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZCA9IGVsZW1lbnRbMV07CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgb3JpZ2luYWwgPSBlbGVtZW50WzJdOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIGV4cGVjdGVkLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVIdG1sNChvcmlnaW5hbCkpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5FU0NBUEVfSFRNTDQudHJhbnNsYXRlKG9yaWdpbmFsLCBzdyk7CisgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgYWN0dWFsID0gb3JpZ2luYWwgPT0gbnVsbCA/IG51bGwgOiBzdy50b1N0cmluZygpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpOworICAgICAgICB9CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0VW5lc2NhcGVIdG1sNCgpIHsKKyAgICAgICAgZm9yIChmaW5hbCBTdHJpbmdbXSBlbGVtZW50IDogSFRNTF9FU0NBUEVTKSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbWVzc2FnZSA9IGVsZW1lbnRbMF07CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZXhwZWN0ZWQgPSBlbGVtZW50WzJdOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG9yaWdpbmFsID0gZWxlbWVudFsxXTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBleHBlY3RlZCwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVIdG1sNChvcmlnaW5hbCkpOworCisgICAgICAgICAgICBmaW5hbCBTdHJpbmdXcml0ZXIgc3cgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLlVORVNDQVBFX0hUTUw0LnRyYW5zbGF0ZShvcmlnaW5hbCwgc3cpOworICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFjdHVhbCA9IG9yaWdpbmFsID09IG51bGwgPyBudWxsIDogc3cudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKTsKKyAgICAgICAgfQorICAgICAgICAvLyBcdTAwRTcgaXMgYSBjZWRpbGxhIChjIHdpdGggd2lnZ2xlIHVuZGVyKQorICAgICAgICAvLyBub3RlIHRoYXQgdGhlIHRlc3Qgc3RyaW5nIG11c3QgYmUgNy1iaXQtY2xlYW4gKFVuaWNvZGUgZXNjYXBlZCkgb3IgZWxzZSBpdCB3aWxsIGNvbXBpbGUgaW5jb3JyZWN0bHkKKyAgICAgICAgLy8gb24gc29tZSBsb2NhbGVzICAgICAgICAKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmdW5ueSBjaGFycyBwYXNzIHRocm91Z2ggT0siLCAiRnJhblx1MDBFN2FpcyIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIkZyYW5cdTAwRTdhaXMiKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyY7V29ybGQiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCJIZWxsbyY7V29ybGQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8mIztXb3JsZCIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIkhlbGxvJiM7V29ybGQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8mIyA7V29ybGQiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCJIZWxsbyYjIDtXb3JsZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZWxsbyYjIztXb3JsZCIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIkhlbGxvJiMjO1dvcmxkIikpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuZXNjYXBlSGV4Q2hhcnNIdG1sKCkgeworICAgICAgICAvLyBTaW1wbGUgZWFzeSB0byBncm9rIHRlc3QgCisgICAgICAgIGFzc2VydEVxdWFscygiaGV4IG51bWJlciB1bmVzY2FwZSIsICJcdTAwODBcdTAwOUYiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCImI3g4MDsmI3g5RjsiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiaGV4IG51bWJlciB1bmVzY2FwZSIsICJcdTAwODBcdTAwOUYiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCImI1g4MDsmI1g5RjsiKSk7CisgICAgICAgIC8vIFRlc3QgYWxsIENoYXJhY3RlciB2YWx1ZXM6CisgICAgICAgIGZvciAoY2hhciBpID0gQ2hhcmFjdGVyLk1JTl9WQUxVRTsgaSA8IENoYXJhY3Rlci5NQVhfVkFMVUU7IGkrKykgeworICAgICAgICAgICAgZmluYWwgQ2hhcmFjdGVyIGMxID0gbmV3IENoYXJhY3RlcihpKTsKKyAgICAgICAgICAgIGZpbmFsIENoYXJhY3RlciBjMiA9IG5ldyBDaGFyYWN0ZXIoKGNoYXIpKGkrMSkpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIGV4cGVjdGVkID0gYzEudG9TdHJpbmcoKSArIGMyLnRvU3RyaW5nKCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZXNjYXBlZEMxID0gIiYjeCIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKChjMS5jaGFyVmFsdWUoKSkpICsgIjsiOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIGVzY2FwZWRDMiA9ICImI3giICsgSW50ZWdlci50b0hleFN0cmluZygoYzIuY2hhclZhbHVlKCkpKSArICI7IjsKKyAgICAgICAgICAgIGFzc2VydEVxdWFscygiaGV4IG51bWJlciB1bmVzY2FwZSBpbmRleCAiICsgKGludClpLCBleHBlY3RlZCwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVIdG1sNChlc2NhcGVkQzEgKyBlc2NhcGVkQzIpKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuZXNjYXBlVW5rbm93bkVudGl0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoIiZ6enp6OyIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIiZ6enp6OyIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVIdG1sVmVyc2lvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCImQmV0YTsiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVIdG1sNCgiXHUwMzkyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx1MDM5MiIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIiZCZXRhOyIpKTsKKworICAgICAgICAvLyBUT0RPOiByZWZpbmUgQVBJIGZvciBlc2NhcGluZy91bmVzY2FwaW5nIHNwZWNpZmljIEhUTUwgdmVyc2lvbnMKKyAgICB9CisKKyAgICBAVGVzdAorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCAiZGVwcmVjYXRpb24iICkgLy8gRVNDQVBFX1hNTCBoYXMgYmVlbiByZXBsYWNlZCBieSBFU0NBUEVfWE1MMTAgYW5kIEVTQ0FQRV9YTUwxMSBpbiAzLjMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlWG1sKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiJmx0O2FiYyZndDsiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwoIjxhYmM+IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIjxhYmM+IiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoIiZsdDthYmMmZ3Q7IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIHNob3VsZCBub3QgZXNjYXBlID4weDdmIHZhbHVlcyIsCisgICAgICAgICAgICAgICAgIlx1MDBBMSIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbCgiXHUwMEExIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCBzaG91bGQgYmUgYWJsZSB0byB1bmVzY2FwZSA+MHg3ZiB2YWx1ZXMiLAorICAgICAgICAgICAgICAgICJcdTAwQTAiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZVhtbCgiJiMxNjA7IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCBzaG91bGQgYmUgYWJsZSB0byB1bmVzY2FwZSA+MHg3ZiB2YWx1ZXMgd2l0aCBvbmUgbGVhZGluZyAwIiwKKyAgICAgICAgICAgICAgICAiXHUwMEEwIiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoIiYjMDE2MDsiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIHNob3VsZCBiZSBhYmxlIHRvIHVuZXNjYXBlID4weDdmIHZhbHVlcyB3aXRoIHR3byBsZWFkaW5nIDBzIiwKKyAgICAgICAgICAgICAgICAiXHUwMEEwIiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoIiYjMDAxNjA7IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCBzaG91bGQgYmUgYWJsZSB0byB1bmVzY2FwZSA+MHg3ZiB2YWx1ZXMgd2l0aCB0aHJlZSBsZWFkaW5nIDBzIiwKKyAgICAgICAgICAgICAgICAiXHUwMEEwIiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoIiYjMDAwMTYwOyIpKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoImFpbid0IiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoImFpbiZhcG9zO3QiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiYWluJmFwb3M7dCIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbCgiYWluJ3QiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sKCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwobnVsbCkpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwobnVsbCkpOworCisgICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLkVTQ0FQRV9YTUwudHJhbnNsYXRlKCI8YWJjPiIsIHN3KTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICB9CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIHdhcyBlc2NhcGVkIGluY29ycmVjdGx5IiwgIiZsdDthYmMmZ3Q7Iiwgc3cudG9TdHJpbmcoKSApOworCisgICAgICAgIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuVU5FU0NBUEVfWE1MLnRyYW5zbGF0ZSgiJmx0O2FiYyZndDsiLCBzdyk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCB3YXMgdW5lc2NhcGVkIGluY29ycmVjdGx5IiwgIjxhYmM+Iiwgc3cudG9TdHJpbmcoKSApOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwZVhtbDEwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiYSZsdDtiJmd0O2MmcXVvdDtkJmFwb3M7ZSZhbXA7ZiIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbDEwKCJhPGI+Y1wiZCdlJmYiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIDEuMCBzaG91bGQgbm90IGVzY2FwZSBcdCBcbiBcciIsCisgICAgICAgICAgICAgICAgImFcdGJccmNcbmQiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwxMCgiYVx0YlxyY1xuZCIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYTUwgMS4wIHNob3VsZCBvbWl0IG1vc3QgI3gwLXg4IHwgI3hiIHwgI3hjIHwgI3hlLSN4MTkiLAorICAgICAgICAgICAgICAgICJhYiIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbDEwKCJhXHUwMDAwXHUwMDAxXHUwMDA4XHUwMDBiXHUwMDBjXHUwMDBlXHUwMDFmYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYTUwgMS4wIHNob3VsZCBvbWl0ICN4ZDgwMC0jeGRmZmYiLAorICAgICAgICAgICAgICAgICJhXHVkN2ZmICBcdWUwMDBiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sMTAoImFcdWQ3ZmZcdWQ4MDAgXHVkZmZmIFx1ZTAwMGIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIDEuMCBzaG91bGQgb21pdCAjeGZmZmUgfCAjeGZmZmYiLAorICAgICAgICAgICAgICAgICJhXHVmZmZkYiIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbDEwKCJhXHVmZmZkXHVmZmZlXHVmZmZmYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYTUwgMS4wIHNob3VsZCBlc2NhcGUgI3g3Zi0jeDg0IHwgI3g4NiAtICN4OWYsIGZvciBYTUwgMS4xIGNvbXBhdGliaWxpdHkiLAorICAgICAgICAgICAgICAgICJhXHUwMDdlJiMxMjc7JiMxMzI7XHUwMDg1JiMxMzQ7JiMxNTk7XHUwMGEwYiIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbDEwKCJhXHUwMDdlXHUwMDdmXHUwMDg0XHUwMDg1XHUwMDg2XHUwMDlmXHUwMGEwYiIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVYbWwxMSgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHMoImEmbHQ7YiZndDtjJnF1b3Q7ZCZhcG9zO2UmYW1wO2YiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwxMSgiYTxiPmNcImQnZSZmIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCAxLjEgc2hvdWxkIG5vdCBlc2NhcGUgXHQgXG4gXHIiLAorICAgICAgICAgICAgICAgICJhXHRiXHJjXG5kIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sMTEoImFcdGJccmNcbmQiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIDEuMSBzaG91bGQgb21pdCAjeDAiLAorICAgICAgICAgICAgICAgICJhYiIsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZVhtbDExKCJhXHUwMDAwYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYTUwgMS4xIHNob3VsZCBlc2NhcGUgI3gxLXg4IHwgI3hiIHwgI3hjIHwgI3hlLSN4MTkiLAorICAgICAgICAgICAgICAgICJhJiMxOyYjODsmIzExOyYjMTI7JiMxNDsmIzMxO2IiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwxMSgiYVx1MDAwMVx1MDAwOFx1MDAwYlx1MDAwY1x1MDAwZVx1MDAxZmIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiWE1MIDEuMSBzaG91bGQgZXNjYXBlICN4N0YtI3g4NCB8ICN4ODYtI3g5RiIsCisgICAgICAgICAgICAgICAgImFcdTAwN2UmIzEyNzsmIzEzMjtcdTAwODUmIzEzNDsmIzE1OTtcdTAwYTBiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sMTEoImFcdTAwN2VcdTAwN2ZcdTAwODRcdTAwODVcdTAwODZcdTAwOWZcdTAwYTBiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlhNTCAxLjEgc2hvdWxkIG9taXQgI3hkODAwLSN4ZGZmZiIsCisgICAgICAgICAgICAgICAgImFcdWQ3ZmYgIFx1ZTAwMGIiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVYbWwxMSgiYVx1ZDdmZlx1ZDgwMCBcdWRmZmYgXHVlMDAwYiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJYTUwgMS4xIHNob3VsZCBvbWl0ICN4ZmZmZSB8ICN4ZmZmZiIsCisgICAgICAgICAgICAgICAgImFcdWZmZmRiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sMTEoImFcdWZmZmRcdWZmZmVcdWZmZmZiIikpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIFN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4gCisgICAgICogPHA+CisgICAgICogRnJvbSBodHRwOi8vd3d3LnczLm9yZy9JbnRlcm5hdGlvbmFsL3F1ZXN0aW9ucy9xYS1lc2NhcGVzCisgICAgICogPC9wPgorICAgICAqIDxibG9ja3F1b3RlPgorICAgICAqIFN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyBhcmUgdGhvc2UgVW5pY29kZSBjaGFyYWN0ZXJzIHRoYXQgaGF2ZSBjb2RlIHBvaW50cyBoaWdoZXIgdGhhbiB0aGUgY2hhcmFjdGVycyBpbgorICAgICAqIHRoZSBCYXNpYyBNdWx0aWxpbmd1YWwgUGxhbmUgKEJNUCkuIEluIFVURi0xNiBhIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIGVuY29kZWQgdXNpbmcgdHdvIDE2LWJpdCBzdXJyb2dhdGUgY29kZSBwb2ludHMgZnJvbSB0aGUKKyAgICAgKiBCTVAuIEJlY2F1c2Ugb2YgdGhpcywgc29tZSBwZW9wbGUgdGhpbmsgdGhhdCBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgbmVlZCB0byBiZSByZXByZXNlbnRlZCB1c2luZyB0d28gZXNjYXBlcywgYnV0IHRoaXMgaXMgaW5jb3JyZWN0CisgICAgICogLSB5b3UgbXVzdCB1c2UgdGhlIHNpbmdsZSwgY29kZSBwb2ludCB2YWx1ZSBmb3IgdGhhdCBjaGFyYWN0ZXIuIEZvciBleGFtcGxlLCB1c2UgJmFtcDsmIzM1O3gyMzNCNCYjNTk7IHJhdGhlciB0aGFuCisgICAgICogJmFtcDsmIzM1O3hEODRDJiM1OTsmYW1wOyYjMzU7eERGQjQmIzU5Oy4KKyAgICAgKiA8L2Jsb2NrcXVvdGU+CisgICAgICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9JbnRlcm5hdGlvbmFsL3F1ZXN0aW9ucy9xYS1lc2NhcGVzIj5Vc2luZyBjaGFyYWN0ZXIgZXNjYXBlcyBpbiBtYXJrdXAgYW5kIENTUzwvYT4KKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvTEFORy03MjgiPkxBTkctNzI4PC9hPgorICAgICAqLworICAgIEBUZXN0CisgICAgQFN1cHByZXNzV2FybmluZ3MoICJkZXByZWNhdGlvbiIgKSAvLyBFU0NBUEVfWE1MIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IEVTQ0FQRV9YTUwxMCBhbmQgRVNDQVBFX1hNTDExIGluIDMuMworICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVYbWxTdXBwbGVtZW50YXJ5Q2hhcmFjdGVycygpIHsKKyAgICAgICAgZmluYWwgQ2hhclNlcXVlbmNlVHJhbnNsYXRvciBlc2NhcGVYbWwgPQorICAgICAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLkVTQ0FQRV9YTUwud2l0aCggTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweDdmLCBJbnRlZ2VyLk1BWF9WQUxVRSkgKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIG11c3QgYmUgcmVwcmVzZW50ZWQgdXNpbmcgYSBzaW5nbGUgZXNjYXBlIiwgIiYjMTQ0MzA4OyIsCisgICAgICAgICAgICAgICAgZXNjYXBlWG1sLnRyYW5zbGF0ZSgiXHVEODRDXHVERkI0IikpOworCisgICAgICAgIGFzc2VydEVxdWFscygiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIG1peGVkIHdpdGggYmFzaWMgY2hhcmFjdGVycyBzaG91bGQgYmUgZW5jb2RlZCBjb3JyZWN0bHkiLCAiYSBiIGMgJiMxNDQzMDg7IiwKKyAgICAgICAgICAgICAgICBlc2NhcGVYbWwudHJhbnNsYXRlKCJhIGIgYyBcdUQ4NENcdURGQjQiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBAU3VwcHJlc3NXYXJuaW5ncyggImRlcHJlY2F0aW9uIiApIC8vIEVTQ0FQRV9YTUwgaGFzIGJlZW4gcmVwbGFjZWQgYnkgRVNDQVBFX1hNTDEwIGFuZCBFU0NBUEVfWE1MMTEgaW4gMy4zCisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwZVhtbEFsbENoYXJhY3RlcnMoKSB7CisgICAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3htbC8jY2hhcnNldHMgc2F5czoKKyAgICAgICAgLy8gQ2hhciA6Oj0gI3g5IHwgI3hBIHwgI3hEIHwgWyN4MjAtI3hEN0ZGXSB8IFsjeEUwMDAtI3hGRkZEXSB8IFsjeDEwMDAwLSN4MTBGRkZGXSAvKiBhbnkgVW5pY29kZSBjaGFyYWN0ZXIsCisgICAgICAgIC8vIGV4Y2x1ZGluZyB0aGUgc3Vycm9nYXRlIGJsb2NrcywgRkZGRSwgYW5kIEZGRkYuICovCisgICAgICAgIGZpbmFsIENoYXJTZXF1ZW5jZVRyYW5zbGF0b3IgZXNjYXBlWG1sID0gU3RyaW5nRXNjYXBlVXRpbHMuRVNDQVBFX1hNTAorICAgICAgICAgICAgICAgIC53aXRoKE51bWVyaWNFbnRpdHlFc2NhcGVyLmJlbG93KDkpLCBOdW1lcmljRW50aXR5RXNjYXBlci5iZXR3ZWVuKDB4QiwgMHhDKSwgTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweEUsIDB4MTkpLAorICAgICAgICAgICAgICAgICAgICAgICAgTnVtZXJpY0VudGl0eUVzY2FwZXIuYmV0d2VlbigweEQ4MDAsIDB4REZGRiksIE51bWVyaWNFbnRpdHlFc2NhcGVyLmJldHdlZW4oMHhGRkZFLCAweEZGRkYpLCBOdW1lcmljRW50aXR5RXNjYXBlci5hYm92ZSgweDExMDAwMCkpOworCisgICAgICAgIGFzc2VydEVxdWFscygiJiMwOyYjMTsmIzI7JiMzOyYjNDsmIzU7JiM2OyYjNzsmIzg7IiwgZXNjYXBlWG1sLnRyYW5zbGF0ZSgiXHUwMDAwXHUwMDAxXHUwMDAyXHUwMDAzXHUwMDA0XHUwMDA1XHUwMDA2XHUwMDA3XHUwMDA4IikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlx0IiwgZXNjYXBlWG1sLnRyYW5zbGF0ZSgiXHQiKSk7IC8vIDB4OQorICAgICAgICBhc3NlcnRFcXVhbHMoIlxuIiwgZXNjYXBlWG1sLnRyYW5zbGF0ZSgiXG4iKSk7IC8vIDB4QQorICAgICAgICBhc3NlcnRFcXVhbHMoIiYjMTE7JiMxMjsiLCBlc2NhcGVYbWwudHJhbnNsYXRlKCJcdTAwMEJcdTAwMEMiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXHIiLCBlc2NhcGVYbWwudHJhbnNsYXRlKCJcciIpKTsgLy8gMHhECisgICAgICAgIGFzc2VydEVxdWFscygiSGVsbG8gV29ybGQhIEFpbiZhcG9zO3QgdGhpcyBncmVhdD8iLCBlc2NhcGVYbWwudHJhbnNsYXRlKCJIZWxsbyBXb3JsZCEgQWluJ3QgdGhpcyBncmVhdD8iKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiJiMxNDsmIzE1OyYjMjQ7JiMyNTsiLCBlc2NhcGVYbWwudHJhbnNsYXRlKCJcdTAwMEVcdTAwMEZcdTAwMThcdTAwMTkiKSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV2ZXJzZSBvZiB0aGUgYWJvdmUuCisgICAgICoKKyAgICAgKiBAc2VlIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvTEFORy03MjkiPkxBTkctNzI5PC9hPgorICAgICAqLworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuZXNjYXBlWG1sU3VwcGxlbWVudGFyeUNoYXJhY3RlcnMoKSB7CisgICAgICAgIGFzc2VydEVxdWFscygiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgbXVzdCBiZSByZXByZXNlbnRlZCB1c2luZyBhIHNpbmdsZSBlc2NhcGUiLCAiXHVEODRDXHVERkI0IiwKKyAgICAgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZVhtbCgiJiMxNDQzMDg7IikgKTsKKworICAgICAgICBhc3NlcnRFcXVhbHMoIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyBtaXhlZCB3aXRoIGJhc2ljIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGRlY29kZWQgY29ycmVjdGx5IiwgImEgYiBjIFx1RDg0Q1x1REZCNCIsCisgICAgICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVYbWwoImEgYiBjICYjMTQ0MzA4OyIpICk7CisgICAgfQorCisgICAgLy8gVGVzdHMgaXNzdWUgIzM4NTY5CisgICAgLy8gaHR0cDovL2lzc3Vlcy5hcGFjaGUub3JnL2J1Z3ppbGxhL3Nob3dfYnVnLmNnaT9pZD0zODU2OQorICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFN0YW5kYWxvbmVBbXBoZXJzYW5kKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIjxQJk8+IiwgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVIdG1sNCgiJmx0O1AmTyZndDsiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygidGVzdCAmIDwiLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCJ0ZXN0ICYgJmx0OyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCI8UCZPPiIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlWG1sKCImbHQ7UCZPJmd0OyIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJ0ZXN0ICYgPCIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlWG1sKCJ0ZXN0ICYgJmx0OyIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMYW5nMzEzKCkgeworICAgICAgICBhc3NlcnRFcXVhbHMoIiYgJiIsIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlSHRtbDQoIiYgJmFtcDsiKSk7CisgICAgfQorCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlQ3N2U3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vLmJhciIsICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlQ3N2KCJmb28uYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlwiZm9vLGJhclwiIiwgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUNzdigiZm9vLGJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcImZvb1xuYmFyXCIiLCAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVDc3YoImZvb1xuYmFyIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoIlwiZm9vXHJiYXJcIiIsICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUNzdigiZm9vXHJiYXIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiXCJmb29cIlwiYmFyXCIiLCAgICAgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlQ3N2KCJmb29cImJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb29cdUQ4NENcdURGQjRiYXIiLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVDc3YoImZvb1x1RDg0Q1x1REZCNGJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCAgIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUNzdigiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlQ3N2KG51bGwpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVDc3ZXcml0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgY2hlY2tDc3ZFc2NhcGVXcml0ZXIoImZvby5iYXIiLCAgICAgICAgICAgICJmb28uYmFyIik7CisgICAgICAgIGNoZWNrQ3N2RXNjYXBlV3JpdGVyKCJcImZvbyxiYXJcIiIsICAgICAgICAiZm9vLGJhciIpOworICAgICAgICBjaGVja0NzdkVzY2FwZVdyaXRlcigiXCJmb29cbmJhclwiIiwgICAgICAgImZvb1xuYmFyIik7CisgICAgICAgIGNoZWNrQ3N2RXNjYXBlV3JpdGVyKCJcImZvb1xyYmFyXCIiLCAgICAgICAiZm9vXHJiYXIiKTsKKyAgICAgICAgY2hlY2tDc3ZFc2NhcGVXcml0ZXIoIlwiZm9vXCJcImJhclwiIiwgICAgICJmb29cImJhciIpOworICAgICAgICBjaGVja0NzdkVzY2FwZVdyaXRlcigiZm9vXHVEODRDXHVERkI0YmFyIiwgImZvb1x1RDg0Q1x1REZCNGJhciIpOworICAgICAgICBjaGVja0NzdkVzY2FwZVdyaXRlcigiIiwgbnVsbCk7CisgICAgICAgIGNoZWNrQ3N2RXNjYXBlV3JpdGVyKCIiLCAiIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ3N2RXNjYXBlV3JpdGVyKGZpbmFsIFN0cmluZyBleHBlY3RlZCwgZmluYWwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmdXcml0ZXIgd3JpdGVyID0gbmV3IFN0cmluZ1dyaXRlcigpOworICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMuRVNDQVBFX0NTVi50cmFuc2xhdGUodmFsdWUsIHdyaXRlcik7CisgICAgICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIHdyaXRlci50b1N0cmluZygpKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgZmFpbCgiVGhyZXc6ICIgKyBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdFVuZXNjYXBlQ3N2U3RyaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vLmJhciIsICAgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUNzdigiZm9vLmJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb28sYmFyIiwgICAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlQ3N2KCJcImZvbyxiYXJcIiIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJmb29cbmJhciIsICAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlQ3N2KCJcImZvb1xuYmFyXCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscygiZm9vXHJiYXIiLCAgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUNzdigiXCJmb29ccmJhclwiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvb1wiYmFyIiwgICAgICAgICAgICAgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVDc3YoIlwiZm9vXCJcImJhclwiIikpOworICAgICAgICBhc3NlcnRFcXVhbHMoImZvb1x1RDg0Q1x1REZCNGJhciIsICAgU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVDc3YoImZvb1x1RDg0Q1x1REZCNGJhciIpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCIiLCAgIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlQ3N2KCIiKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUNzdihudWxsKSk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJcImZvby5iYXJcIiIsICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLnVuZXNjYXBlQ3N2KCJcImZvby5iYXJcIiIpKTsKKyAgICB9CisKKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RVbmVzY2FwZUNzdldyaXRlcigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBjaGVja0NzdlVuZXNjYXBlV3JpdGVyKCJmb28uYmFyIiwgICAgICAgICAgICAiZm9vLmJhciIpOworICAgICAgICBjaGVja0NzdlVuZXNjYXBlV3JpdGVyKCJmb28sYmFyIiwgICAgICAgICAgICAiXCJmb28sYmFyXCIiKTsKKyAgICAgICAgY2hlY2tDc3ZVbmVzY2FwZVdyaXRlcigiZm9vXG5iYXIiLCAgICAgICAgICAgIlwiZm9vXG5iYXJcIiIpOworICAgICAgICBjaGVja0NzdlVuZXNjYXBlV3JpdGVyKCJmb29ccmJhciIsICAgICAgICAgICAiXCJmb29ccmJhclwiIik7CisgICAgICAgIGNoZWNrQ3N2VW5lc2NhcGVXcml0ZXIoImZvb1wiYmFyIiwgICAgICAgICAgICJcImZvb1wiXCJiYXJcIiIpOworICAgICAgICBjaGVja0NzdlVuZXNjYXBlV3JpdGVyKCJmb29cdUQ4NENcdURGQjRiYXIiLCAiZm9vXHVEODRDXHVERkI0YmFyIik7CisgICAgICAgIGNoZWNrQ3N2VW5lc2NhcGVXcml0ZXIoIiIsIG51bGwpOworICAgICAgICBjaGVja0NzdlVuZXNjYXBlV3JpdGVyKCIiLCAiIik7CisKKyAgICAgICAgY2hlY2tDc3ZVbmVzY2FwZVdyaXRlcigiXCJmb28uYmFyXCIiLCAgICAgICAgIlwiZm9vLmJhclwiIik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ3N2VW5lc2NhcGVXcml0ZXIoZmluYWwgU3RyaW5nIGV4cGVjdGVkLCBmaW5hbCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZ1dyaXRlciB3cml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CisgICAgICAgICAgICBTdHJpbmdFc2NhcGVVdGlscy5VTkVTQ0FQRV9DU1YudHJhbnNsYXRlKHZhbHVlLCB3cml0ZXIpOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCB3cml0ZXIudG9TdHJpbmcoKSk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGZhaWwoIlRocmV3OiAiICsgZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyAvLyBodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0xBTkctNDgwCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0RXNjYXBlSHRtbEhpZ2hVbmljb2RlKCkgeworICAgICAgICAvLyB0aGlzIGlzIHRoZSB1dGY4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjaGFyYWN0ZXI6CisgICAgICAgIC8vIENPVU5USU5HIFJPRCBVTklUIERJR0lUIFRIUkVFCisgICAgICAgIC8vIGluIFVuaWNvZGUKKyAgICAgICAgLy8gY29kZXBvaW50OiBVKzFEMzYyCisgICAgICAgIGZpbmFsIGJ5dGVbXSBkYXRhID0gbmV3IGJ5dGVbXSB7IChieXRlKTB4RjAsIChieXRlKTB4OUQsIChieXRlKTB4OEQsIChieXRlKTB4QTIgfTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgb3JpZ2luYWwgPSBuZXcgU3RyaW5nKGRhdGEsIENoYXJzZXQuZm9yTmFtZSgiVVRGOCIpKTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgZXNjYXBlZCA9IFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUh0bWw0KCBvcmlnaW5hbCApOworICAgICAgICBhc3NlcnRFcXVhbHMoICJIaWdoIFVuaWNvZGUgc2hvdWxkIG5vdCBoYXZlIGJlZW4gZXNjYXBlZCIsIG9yaWdpbmFsLCBlc2NhcGVkKTsKKworICAgICAgICBmaW5hbCBTdHJpbmcgdW5lc2NhcGVkID0gU3RyaW5nRXNjYXBlVXRpbHMudW5lc2NhcGVIdG1sNCggZXNjYXBlZCApOworICAgICAgICBhc3NlcnRFcXVhbHMoICJIaWdoIFVuaWNvZGUgc2hvdWxkIGhhdmUgYmVlbiB1bmNoYW5nZWQiLCBvcmlnaW5hbCwgdW5lc2NhcGVkKTsKKworICAgICAgICAvLyBUT0RPOiBJIHRoaW5rIHRoaXMgc2hvdWxkIGhvbGQsIG5lZWRzIGZ1cnRoZXIgaW52ZXN0aWdhdGlvbgorICAgICAgICAvLyAgICAgICAgU3RyaW5nIHVuZXNjYXBlZEZyb21FbnRpdHkgPSBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCAiJiMxMTk2NTA7IiApOworICAgICAgICAvLyAgICAgICAgYXNzZXJ0RXF1YWxzKCAiSGlnaCBVbmljb2RlIHNob3VsZCBoYXZlIGJlZW4gdW5lc2NhcGVkIiwgb3JpZ2luYWwsIHVuZXNjYXBlZEZyb21FbnRpdHkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvTEFORy0zMzkKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RFc2NhcGVIaXJhZ2FuYSgpIHsKKyAgICAgICAgLy8gU29tZSByYW5kb20gSmFwYW5lc2UgVW5pY29kZSBjaGFyYWN0ZXJzCisgICAgICAgIGZpbmFsIFN0cmluZyBvcmlnaW5hbCA9ICJcdTMwNEJcdTMwNENcdTMwNjgiOworICAgICAgICBmaW5hbCBTdHJpbmcgZXNjYXBlZCA9IFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUh0bWw0KG9yaWdpbmFsKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAiSGlyYWdhbmEgY2hhcmFjdGVyIFVuaWNvZGUgYmVoYXZpb3VyIHNob3VsZCBub3QgYmUgYmVpbmcgZXNjYXBlZCBieSBlc2NhcGVIdG1sNCIsCisgICAgICAgICAgICAgICAgb3JpZ2luYWwsIGVzY2FwZWQpOworCisgICAgICAgIGZpbmFsIFN0cmluZyB1bmVzY2FwZWQgPSBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUh0bWw0KCBlc2NhcGVkICk7CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAiSGlyYWdhbmEgY2hhcmFjdGVyIFVuaWNvZGUgYmVoYXZpb3VyIGhhcyBjaGFuZ2VkIC0gZXhwZWN0ZWQgbm8gdW5lc2NhcGluZyIsIGVzY2FwZWQsIHVuZXNjYXBlZCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGVzdHMgaHR0cHM6Ly9pc3N1ZXMuYXBhY2hlLm9yZy9qaXJhL2Jyb3dzZS9MQU5HLTcwOAorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqICAgICAgICAgICAgIGlmIGFuIEkvTyBlcnJvciBvY2N1cnMKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIHB1YmxpYyB2b2lkIHRlc3RMYW5nNzA4KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgRmlsZUlucHV0U3RyZWFtIGZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oInNyYy90ZXN0L3Jlc291cmNlcy9sYW5nLTcwOC1pbnB1dC50eHQiKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIGlucHV0ID0gSU9VdGlscy50b1N0cmluZyhmaXMsICJVVEYtOCIpOworICAgICAgICBmaW5hbCBTdHJpbmcgZXNjYXBlZCA9IFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUVjbWFTY3JpcHQoaW5wdXQpOworICAgICAgICAvLyBqdXN0IHRoZSBlbmQ6CisgICAgICAgIGFzc2VydFRydWUoZXNjYXBlZCwgZXNjYXBlZC5lbmRzV2l0aCgifV0iKSk7CisgICAgICAgIC8vIGEgbGl0dGxlIG1vcmU6CisgICAgICAgIGFzc2VydFRydWUoZXNjYXBlZCwgZXNjYXBlZC5lbmRzV2l0aCgiXCJ2YWx1ZUNvZGVcXFwiOlxcXCJcXFwifV0iKSk7CisgICAgICAgIGZpcy5jbG9zZSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlc3RzIGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvTEFORy03MjAKKyAgICAgKi8KKyAgICBAVGVzdAorICAgIEBTdXBwcmVzc1dhcm5pbmdzKCAiZGVwcmVjYXRpb24iICkgLy8gZXNjYXBlWG1sKFN0cmluZykgaGFzIGJlZW4gcmVwbGFjZWQgYnkgZXNjYXBlWG1sMTAoU3RyaW5nKSBhbmQgZXNjYXBlWG1sMTEoU3RyaW5nKSBpbiAzLjMKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGFuZzcyMCgpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGlucHV0ID0gIlx1ZDg0Mlx1ZGZiNyIgKyAiQSI7CisgICAgICAgIGZpbmFsIFN0cmluZyBlc2NhcGVkID0gU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlWG1sKGlucHV0KTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGlucHV0LCBlc2NhcGVkKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUZXN0cyBodHRwczovL2lzc3Vlcy5hcGFjaGUub3JnL2ppcmEvYnJvd3NlL0xBTkctOTExCisgICAgICovCisgICAgQFRlc3QKKyAgICBwdWJsaWMgdm9pZCB0ZXN0TGFuZzkxMSgpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGJlbGxzVGVzdCA9ICJcdWQ4M2RcdWRjODBcdWQ4M2RcdWRkMTQiOworICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWUgPSBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVKYXZhKGJlbGxzVGVzdCk7CisgICAgICAgIGZpbmFsIFN0cmluZyB2YWx1ZVRlc3QgPSBTdHJpbmdFc2NhcGVVdGlscy51bmVzY2FwZUphdmEodmFsdWUpOworICAgICAgICBhc3NlcnRFcXVhbHMoYmVsbHNUZXN0LCB2YWx1ZVRlc3QpOworICAgIH0KKworICAgIEBUZXN0CisgICAgcHVibGljIHZvaWQgdGVzdEVzY2FwZUpzb24oKSB7CisgICAgICAgIGFzc2VydEVxdWFscyhudWxsLCBTdHJpbmdFc2NhcGVVdGlscy5lc2NhcGVKc29uKG51bGwpKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLkVTQ0FQRV9KU09OLnRyYW5zbGF0ZShudWxsLCBudWxsKTsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgfSBjYXRjaCAoZmluYWwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIFN0cmluZ0VzY2FwZVV0aWxzLkVTQ0FQRV9KU09OLnRyYW5zbGF0ZSgiIiwgbnVsbCk7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgIH0gY2F0Y2ggKGZpbmFsIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBleCkgeworICAgICAgICB9CisKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCJIZSBkaWRuJ3Qgc2F5LCBcXFwic3RvcCFcXFwiIiwgU3RyaW5nRXNjYXBlVXRpbHMuZXNjYXBlSnNvbigiSGUgZGlkbid0IHNheSwgXCJzdG9wIVwiIikpOworCisgICAgICAgIGZpbmFsIFN0cmluZyBleHBlY3RlZCA9ICJcXFwiZm9vXFxcIiBpc24ndCBcXFwiYmFyXFxcIi4gc3BlY2lhbHM6IFxcYlxcclxcblxcZlxcdFxcXFxcXC8iOworICAgICAgICBmaW5hbCBTdHJpbmcgaW5wdXQgPSJcImZvb1wiIGlzbid0IFwiYmFyXCIuIHNwZWNpYWxzOiBcYlxyXG5cZlx0XFwvIjsKKworICAgICAgICBhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIFN0cmluZ0VzY2FwZVV0aWxzLmVzY2FwZUpzb24oaW5wdXQpKTsKKyAgICB9CisKK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCg==