LyoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMiwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICRTb3VyY2U6IC94c3JsL05zdm4vaWN1L2ljdTRqL3NyYy9jb20vaWJtL2ljdS90ZXh0L1J1bGVCYXNlZENvbGxhdG9yLmphdmEsdiAkIAoqICREYXRlOiAyMDAyLzEyLzEzIDIwOjIwOjAxICQgCiogJFJldmlzaW9uOiAxLjI5ICQKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCnBhY2thZ2UgY29tLmlibS5pY3UudGV4dDsKCmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5CdWZmZXJlZElucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS50ZXh0LkNoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgamF2YS50ZXh0LlN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgY29tLmlibS5pY3UubGFuZy5VQ2hhcmFjdGVyOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5JbnRUcmllOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5UcmllOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5JQ1VMb2NhbGVEYXRhOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5CT0NVOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5VdGlsaXR5OwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5JQ1VEZWJ1ZzsKCi8qKgogKiA8cD5SdWxlQmFzZWRDb2xsYXRvciBpcyBhIGNvbmNyZXRlIHN1YmNsYXNzIG9mIENvbGxhdG9yLiBJdCBhbGxvd3MKICogY3VzdG9taXphdGlvbiBvZiB0aGUgQ29sbGF0b3IgdmlhIHVzZXItc3BlY2lmaWVkIHJ1bGUgc2V0cy4KICogUnVsZUJhc2VkQ29sbGF0b3IgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGxpYW50IHRvIHRoZSA8YQogKiBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjEwLyI+IFVuaWNvZGUKICogQ29sbGF0aW9uIEFsZ29yaXRobSAoVUNBKTwvYT4gYW5kIGNvbmZvcm1zIHRvIElTTyAxNDY1MS48L3A+CiAqCiAqIDxwPlVzZXJzIGFyZSBzdHJvbmdseSBlbmNvdXJhZ2VkIHRvIHJlYWQgPGEKICogaHJlZj0iaHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9JbnRyby5odG1sIj4KICogdGhlIHVzZXJzIGd1aWRlPC9hPiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29sbGF0aW9uCiAqIHNlcnZpY2UgYmVmb3JlIHVzaW5nIHRoaXMgY2xhc3MuPC9wPgogKgogKiA8cD5DcmVhdGUgYSBSdWxlQmFzZWRDb2xsYXRvciBmcm9tIGEgbG9jYWxlIGJ5IGNhbGxpbmcgdGhlCiAqIGdldEluc3RhbmNlKExvY2FsZSkgZmFjdG9yeSBtZXRob2QgaW4gdGhlIGJhc2UgY2xhc3MgQ29sbGF0b3IuCiAqIENvbGxhdG9yLmdldEluc3RhbmNlKExvY2FsZSkgY3JlYXRlcyBhIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdAogKiBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgYnkgdGhlIGFyZ3VtZW50IGxvY2FsZS4gIElmIGEKICogY3VzdG9taXplZCBjb2xsYXRpb24gb3JkZXJpbmcgYXIgYXR0cmlidXRlcyBpcyByZXF1aXJlZCwgdXNlIHRoZQogKiBSdWxlQmFzZWRDb2xsYXRvcihTdHJpbmcpIGNvbnN0cnVjdG9yIHdpdGggdGhlIGFwcHJvcHJpYXRlCiAqIHJ1bGVzLiBUaGUgY3VzdG9taXplZCBSdWxlQmFzZWRDb2xsYXRvciB3aWxsIGJhc2UgaXRzIG9yZGVyaW5nIG9uCiAqIFVDQSwgd2hpbGUgcmUtYWRqdXN0aW5nIHRoZSBhdHRyaWJ1dGVzIGFuZCBvcmRlcnMgb2YgdGhlIGNoYXJhY3RlcnMKICogaW4gdGhlIHNwZWNpZmllZCBydWxlIGFjY29yZGluZ2x5LjwvcD4KICoKICogPHA+UnVsZUJhc2VkQ29sbGF0b3IgcHJvdmlkZXMgY29ycmVjdCBjb2xsYXRpb24gb3JkZXJzIGZvciBtb3N0CiAqIGxvY2FsZXMgc3VwcG9ydGVkIGluIElDVS4gSWYgc3BlY2lmaWMgZGF0YSBmb3IgYSBsb2NhbGUgaXMgbm90CiAqIGF2YWlsYWJsZSwgdGhlIG9yZGVycyBldmVudHVhbGx5IGZhbGxzIGJhY2sgdG8gdGhlIDxhCiAqIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTAvIj5VQ0EgY29sbGF0aW9uCiAqIG9yZGVyIDwvYT4uPC9wPgogKgogKiA8cD5Gb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheCBhbmQgZGV0YWlscwogKiBhYm91dCBjdXN0b21pemF0aW9uLCBwbGVhc2UgcmVmZXIgdG8gdGhlCiAqIDxhIGhyZWY9Imh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9pY3UvdXNlcmd1aWRlL0NvbGxhdGVfQ3VzdG9taXphdGlvbi5odG1sIj4KICogQ29sbGF0aW9uIGN1c3RvbWl6YXRpb248L2E+IHNlY3Rpb24gb2YgdGhlIHVzZXIncyBndWlkZS48L3A+CiAqCiAqIDxwPjxzdHJvbmc+Tm90ZTwvc3Ryb25nPiB0aGF0IHRoZXJlIGFyZSBzb21lIGRpZmZlcmVuY2VzIGJldHdlZW4KICogdGhlIENvbGxhdGlvbiBydWxlIHN5bnRheCB1c2VkIGluIEphdmEgYW5kIElDVTRKOgogKgogKiA8dWw+CiAqIDxsaT5BY2NvcmRpbmcgdG8gdGhlIEpESyBkb2N1bWVudGF0aW9uOgogKiA8aT4KICogPHA+CiAqIE1vZGlmaWVyICchJyA6IFR1cm5zIG9uIFRoYWkvTGFvIHZvd2VsLWNvbnNvbmFudCBzd2FwcGluZy4gSWYgdGhpcyBydWxlIAogKiBpcyBpbiBmb3JjZSB3aGVuIGEgVGhhaSB2b3dlbCBvZiB0aGUgcmFuZ2UgJiM5MjtVMEU0MC0mIzkyO1UwRTQ0IHByZWNlZGVzIGEgCiAqIFRoYWkgY29uc29uYW50IG9mIHRoZSByYW5nZSAmIzkyO1UwRTAxLSYjOTI7VTBFMkUgT1IgYSBMYW8gdm93ZWwgb2YgdGhlIAogKiByYW5nZSAmIzkyO1UwRUMwLSYjOTI7VTBFQzQgcHJlY2VkZXMgYSBMYW8gY29uc29uYW50IG9mIHRoZSByYW5nZSAKICogJiM5MjtVMEU4MS0mIzkyO1UwRUFFIHRoZW4gdGhlIAogKiB2b3dlbCBpcyBwbGFjZWQgYWZ0ZXIgdGhlIGNvbnNvbmFudCBmb3IgY29sbGF0aW9uIHB1cnBvc2VzLiAKICogPC9wPgogKiA8cD4KICogSWYgYSBydWxlIGlzIHdpdGhvdXQgdGhlIG1vZGlmaWVyICchJywgdGhlIFRoYWkvTGFvIHZvd2VsLWNvbnNvbmFudCAKICogc3dhcHBpbmcgaXMgbm90IHR1cm5lZCBvbi4KICogPC9wPgogKiA8L2k+CiAqIDxwPgogKiBJQ1U0SidzIFJ1bGVCYXNlZENvbGxhdG9yIGRvZXMgbm90IHN1cHBvcnQgdHVybmluZyBvZmYgdGhlIFRoYWkvTGFvIAogKiB2b3dlbC1jb25zb25hbnQgc3dhcHBpbmcsIHNpbmNlIHRoZSBVQ0EgY2xlYXJseSBzdGF0ZXMgdGhhdCBpdCBoYXMgdG8gYmUgCiAqIHN1cHBvcnRlZCB0byBlbnN1cmUgYSBjb3JyZWN0IHNvcnRpbmcgb3JkZXIuIElmIGEgJyEnIGlzIGVuY291bnRlcmVkLCBpdCBpcwogKiBpZ25vcmVkLgogKiA8L3A+CiAqIDxsaT5BcyBtZW50aW9uZWQgaW4gdGhlIGRvY3VtZW50YXRpb24gb2YgdGhlIGJhc2UgY2xhc3MgQ29sbGF0b3IsIAogKiAgICAgY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uIG1vZGUgaXMgbm90IHN1cHBvcnRlZC4KICogPC91bD4KICogPHA+CiAqIDxzdHJvbmc+RXhhbXBsZXM8L3N0cm9uZz4KICogPC9wPgogKiA8cD4KICogQ3JlYXRpbmcgQ3VzdG9taXplZCBSdWxlQmFzZWRDb2xsYXRvcnM6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiBTdHJpbmcgc2ltcGxlID0gIiZhbXA7IGEgJmx0OyBiICZsdDsgYyAmbHQ7IGQiOwogKiBSdWxlQmFzZWRDb2xsYXRvciBzaW1wbGVDb2xsYXRvciA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihzaW1wbGUpOwogKiAKICogU3RyaW5nIG5vcndlZ2lhbiA9ICImYW1wOyBhICwgQSAmbHQ7IGIgLCBCICZsdDsgYyAsIEMgJmx0OyBkICwgRCAmbHQ7IGUgLCBFICIKICogICAgICAgICAgICAgICAgICAgICsgIiZsdDsgZiAsIEYgJmx0OyBnICwgRyAmbHQ7IGggLCBIICZsdDsgaSAsIEkgJmx0OyBqICwgIgogKiAgICAgICAgICAgICAgICAgICAgKyAiSiAmbHQ7IGsgLCBLICZsdDsgbCAsIEwgJmx0OyBtICwgTSAmbHQ7IG4gLCBOICZsdDsgIgogKiAgICAgICAgICAgICAgICAgICAgKyAibyAsIE8gJmx0OyBwICwgUCAmbHQ7IHEgLCBRICZsdCByICwgUiAmbHQgcyAsIFMgJmx0OyAiCiAqICAgICAgICAgICAgICAgICAgICArICJ0ICwgVCAmbHQ7IHUgLCBVICZsdDsgdiAsIFYgJmx0OyB3ICwgVyAmbHQ7IHggLCBYICIKICogICAgICAgICAgICAgICAgICAgICsgIiZsdDsgeSAsIFkgJmx0OyB6ICwgWiAmbHQ7ICYjOTI7dTAwRTUgPSBhJiM5Mjt1MDMwQSAiCiAqICAgICAgICAgICAgICAgICAgICArICIsICYjOTI7dTAwQzUgPSBBJiM5Mjt1MDMwQSA7IGFhICwgQUEgJmx0OyAmIzkyO3UwMEU2ICIKICogICAgICAgICAgICAgICAgICAgICsgIiwgJiM5Mjt1MDBDNiAmbHQ7ICYjOTI7dTAwRjggLCAmIzkyO3UwMEQ4IjsKICogUnVsZUJhc2VkQ29sbGF0b3Igbm9yd2VnaWFuQ29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iobm9yd2VnaWFuKTsKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICoKICogQ29uY2F0ZW5hdGluZyBydWxlcyB0byBjb21iaW5lIDxjb2RlPkNvbGxhdG9yPC9jb2RlPnM6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqIFJ1bGVCYXNlZENvbGxhdG9yIGVuX1VTQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IpCiAqICAgICBDb2xsYXRvci5nZXRJbnN0YW5jZShuZXcgTG9jYWxlKCJlbiIsICJVUyIsICIiKSk7CiAqIC8vIENyZWF0ZSBhIGRhX0RLIENvbGxhdG9yIG9iamVjdAogKiBSdWxlQmFzZWRDb2xsYXRvciBkYV9ES0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKQogKiAgICAgQ29sbGF0b3IuZ2V0SW5zdGFuY2UobmV3IExvY2FsZSgiZGEiLCAiREsiLCAiIikpOwogKiAvLyBDb21iaW5lIHRoZSB0d28KICogLy8gRmlyc3QsIGdldCB0aGUgY29sbGF0aW9uIHJ1bGVzIGZyb20gZW5fVVNDb2xsYXRvcgogKiBTdHJpbmcgZW5fVVNSdWxlcyA9IGVuX1VTQ29sbGF0b3IuZ2V0UnVsZXMoKTsKICogLy8gU2Vjb25kLCBnZXQgdGhlIGNvbGxhdGlvbiBydWxlcyBmcm9tIGRhX0RLQ29sbGF0b3IKICogU3RyaW5nIGRhX0RLUnVsZXMgPSBkYV9ES0NvbGxhdG9yLmdldFJ1bGVzKCk7CiAqIFJ1bGVCYXNlZENvbGxhdG9yIG5ld0NvbGxhdG9yID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbl9VU1J1bGVzICsgZGFfREtSdWxlcyk7CiAqIC8vIG5ld0NvbGxhdG9yIGhhcyB0aGUgY29tYmluZWQgcnVsZXMKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICoKICogTWFraW5nIGNoYW5nZXMgdG8gYW4gZXhpc3RpbmcgUnVsZUJhc2VkQ29sbGF0b3IgdG8gY3JlYXRlIGEgbmV3IAogKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gb2JqZWN0LCBieSBhcHBlbmRpbmcgY2hhbmdlcyB0byB0aGUgZXhpc3RpbmcgcnVsZToKICogPGJsb2NrcXVvdGU+CiAqIDxwcmU+CiAqIC8vIENyZWF0ZSBhIG5ldyBDb2xsYXRvciBvYmplY3Qgd2l0aCBhZGRpdGlvbmFsIHJ1bGVzCiAqIFN0cmluZyBhZGRSdWxlcyA9ICImYW1wOyBDICZsdDsgY2gsIGNILCBDaCwgQ0giOwogKiBSdWxlQmFzZWRDb2xsYXRvciBteUNvbGxhdG9yID0KICogICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihlbl9VU0NvbGxhdG9yICsgYWRkUnVsZXMpOwogKiAvLyBteUNvbGxhdG9yIGNvbnRhaW5zIHRoZSBuZXcgcnVsZXMKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICoKICogSG93IHRvIGNoYW5nZSB0aGUgb3JkZXIgb2Ygbm9uLXNwYWNpbmcgYWNjZW50czoKICogPGJsb2NrcXVvdGU+CiAqIDxwcmU+CiAqIC8vIG9sZCBydWxlIHdpdGggbWFpbiBhY2NlbnRzCiAqIFN0cmluZyBvbGRSdWxlcyA9ICI9ICYjOTI7dTAzMDEgOyAmIzkyO3UwMzAwIDsgJiM5Mjt1MDMwMiA7ICYjOTI7dTAzMDggIiAgICAKICogICAgICAgICAgICAgICAgICsgIjsgJiM5Mjt1MDMyNyA7ICYjOTI7dTAzMDMgOyAmIzkyO3UwMzA0IDsgJiM5Mjt1MDMwNSAiCiAqICAgICAgICAgICAgICAgICArICI7ICYjOTI7dTAzMDYgOyAmIzkyO3UwMzA3IDsgJiM5Mjt1MDMwOSA7ICYjOTI7dTAzMEEgIiAKICogICAgICAgICAgICAgICAgICsgIjsgJiM5Mjt1MDMwQiA7ICYjOTI7dTAzMEMgOyAmIzkyO3UwMzBEIDsgJiM5Mjt1MDMwRSAiCiAqICAgICAgICAgICAgICAgICArICI7ICYjOTI7dTAzMEYgOyAmIzkyO3UwMzEwIDsgJiM5Mjt1MDMxMSA7ICYjOTI7dTAzMTIgIgogKiAgICAgICAgICAgICAgICAgKyAiJmx0OyBhICwgQSA7IGFlLCBBRSA7ICYjOTI7dTAwZTYgLCAmIzkyO3UwMGM2ICIKICogICAgICAgICAgICAgICAgICsgIiZsdDsgYiAsIEIgJmx0OyBjLCBDICZsdDsgZSwgRSAmYW1wOyBDICZsdDsgZCAsIEQiOwogKiAvLyBjaGFuZ2UgdGhlIG9yZGVyIG9mIGFjY2VudCBjaGFyYWN0ZXJzCiAqIFN0cmluZyBhZGRPbiA9ICImYW1wOyAmIzkyO3UwMzAwIDsgJiM5Mjt1MDMwOCA7ICYjOTI7dTAzMDIiOwogKiBSdWxlQmFzZWRDb2xsYXRvciBteUNvbGxhdG9yID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKG9sZFJ1bGVzICsgYWRkT24pOwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKgogKiBQdXR0aW5nIGluIGEgbmV3IHByaW1hcnkgb3JkZXJpbmcgYmVmb3JlIHRoZSBkZWZhdWx0IHNldHRpbmcsIAogKiBlLmcuIHNvcnQgRW5nbGlzaCBjaGFyYWN0ZXJzIGJlZm9yZSBvciBhZnRlciBKYXBhbmVzZSBjaGFyYWN0ZXJzIGluIHRoZSBKYXBhbmVzZSAKICogPGNvZGU+Q29sbGF0b3I8L2NvZGU+OgogKiA8YmxvY2txdW90ZT4KICogPHByZT4KICogLy8gZ2V0IGVuX1VTIENvbGxhdG9yIHJ1bGVzCiAqIFJ1bGVCYXNlZENvbGxhdG9yIGVuX1VTQ29sbGF0b3IgCiAqICAgICAgICAgICAgICAgICAgICAgICAgPSAoUnVsZUJhc2VkQ29sbGF0b3IpQ29sbGF0b3IuZ2V0SW5zdGFuY2UoTG9jYWxlLlVTKTsKICogLy8gYWRkIGEgZmV3IEphcGFuZXNlIGNoYXJhY3RlcnMgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqIC8vIHN1cHBvc2UgdGhlIGxhc3QgY2hhcmFjdGVyIGJlZm9yZSB0aGUgZmlyc3QgYmFzZSBsZXR0ZXIgJ2EnIGluCiAqIC8vIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlIGlzICYjOTI7dTIyMTIKICogU3RyaW5nIGphU3RyaW5nID0gIiYgJiM5Mjt1MjIxMiAmbHQgJiM5Mjt1MzA0MSwgJiM5Mjt1MzA0MiAmbHQgJiM5Mjt1MzA0MywgIgogKiAgICAgICAgICAgICAgICAgICArICImIzkyO3UzMDQ0IjsKICogUnVsZUJhc2VkQ29sbGF0b3IgbXlKYXBhbmVzZUNvbGxhdG9yIAogKiAgICAgICAgICAgICAgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoZW5fVVNDb2xsYXRvci5nZXRSdWxlcygpICsgamFTdHJpbmcpOwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKiA8L3A+CiAqIDxwPgogKiBUaGlzIGNsYXNzIGlzIG5vdCBzdWJjbGFzc2FibGUKICogPC9wPgogKiBAYXV0aG9yIFN5biBXZWUgUXVlawogKiBAZHJhZnQgSUNVIDIuMgogKi8KcHVibGljIGZpbmFsIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yIGV4dGVuZHMgQ29sbGF0b3IgCnsgICAKCS8vIHB1YmxpYyBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8vIHB1YmxpYyBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgogICAgICogPHA+CiAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIHRoZSBhcmd1bWVudCBydWxlcyBmb3IgCiAgICAgKiBjdXN0b21pemF0aW9uLiBUaGUgY29sbGF0b3Igd2lsbCBiZSBiYXNlZCBvbiBVQ0EsIAogICAgICogd2l0aCB0aGUgYXR0cmlidXRlcyBhbmQgcmUtb3JkZXJpbmcgb2YgdGhlIGNoYXJhY3RlcnMgc3BlY2lmaWVkIGluIHRoZSAKICAgICAqIGFyZ3VtZW50IHJ1bGVzLgogICAgICogPC9wPgogICAgICogPHA+U2VlIHRoZSB1c2VyIGd1aWRlJ3Mgc2VjdGlvbiBvbiAKICAgICAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9DdXN0b21pemF0aW9uLmh0bWw+CiAgICAgKiBDb2xsYXRpb24gQ3VzdG9taXphdGlvbjwvYT4gZm9yIGRldGFpbHMgb24gdGhlIHJ1bGUgc3ludGF4LgogICAgICogPC9wPgogICAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAgICogQGV4Y2VwdGlvbiBQYXJzZUV4Y2VwdGlvbiBhbmQgSU9FeGNlcHRpb24gdGhyb3duLiBQYXJzZUV4Y2VwdGlvbiB0aHJvd24gCiAgICAgKiAgICAgICAgICAgIHdoZW4gYXJndW1lbnQgcnVsZXMgaGF2ZSBhbiBpbnZhbGlkIHN5bnRheC4gSU9FeGNlcHRpb24gCiAgICAgKiAgICAgICAgICAgIHRocm93biB3aGVuIGFuIGVycm9yIG9jY3VyZWQgd2hpbGUgcmVhZGluZyBpbnRlcm5hbCBkYXRhLgogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIFJ1bGVCYXNlZENvbGxhdG9yKFN0cmluZyBydWxlcykgdGhyb3dzIEV4Y2VwdGlvbgogICAgewogICAgICAgIGlmIChydWxlcyA9PSBudWxsIHx8IHJ1bGVzLmxlbmd0aCgpID09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29sbGF0aW9uIHJ1bGVzIGNhbiBub3QgYmUgbnVsbCIpOwogICAgICAgIH0KICAgIAlzZXRXaXRoVUNBRGF0YSgpOwogICAgICAgIENvbGxhdGlvblBhcnNlZFJ1bGVCdWlsZGVyIGJ1aWxkZXIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gbmV3IENvbGxhdGlvblBhcnNlZFJ1bGVCdWlsZGVyKHJ1bGVzKTsKCSAgICAKCQlidWlsZGVyLnNldFJ1bGVzKHRoaXMpOwogICAgICAgIG1fcnVsZXNfID0gcnVsZXM7CiAgICAgICAgaW5pdCgpOwogICAgICAgIGluaXRVdGlsaXR5KCk7CiAgICB9CiAgICAKICAgIC8vIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgICogQ2xvbmVzIHRoZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHJldHVybiBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdAogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIE9iamVjdCBjbG9uZSgpIHRocm93cyBDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbgogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIHJlc3VsdCA9IChSdWxlQmFzZWRDb2xsYXRvcilzdXBlci5jbG9uZSgpOwogICAgICAgIC8vIHNpbmNlIGFsbCBjb2xsYXRpb24gZGF0YSBpbiB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgZG8gbm90IGNoYW5nZQogICAgICAgIC8vIHdlIGNhbiBzYWZlbHkgYXNzaWduIHRoZSByZXN1bHQuZmllbGRzIHRvIHRoaXMgY29sbGF0b3IKICAgICAgICByZXN1bHQuaW5pdFV0aWxpdHkoKTsgLy8gbGV0IHRoZSBuZXcgY2xvbmUgaGF2ZSB0aGVpciBvd24gdXRpbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdGVyYXRvcnMKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBmb3IgdGhlIGdpdmVuIFN0cmluZy4KICAgICAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihTdHJpbmcgc291cmNlKSAKICAgIHsKICAgICAgICByZXR1cm4gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGZvciB0aGUgZ2l2ZW4gQ2hhcmFjdGVySXRlcmF0b3IuCiAgICAgKiBUaGUgc291cmNlIGl0ZXJhdG9yJ3MgaW50ZWdyaXR5IHdpbGwgYmUgcHJlc2VydmVkIHNpbmNlIGEgbmV3IGNvcHkgCiAgICAgKiB3aWxsIGJlIGNyZWF0ZWQgZm9yIHVzZS4KICAgICAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGdldENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhcmFjdGVySXRlcmF0b3Igc291cmNlKSAKICAgIHsJCiAgICAgCUNoYXJhY3Rlckl0ZXJhdG9yIG5ld3NvdXJjZSA9IChDaGFyYWN0ZXJJdGVyYXRvcilzb3VyY2UuY2xvbmUoKTsgICAKICAgICAgICByZXR1cm4gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihuZXdzb3VyY2UsIHRoaXMpOwogICAgfQogICAgCiAgICAvLyBwdWJsaWMgc2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIEhpcmFnYW5hIFF1YXRlcm5hcnkgbW9kZSB0byBiZSBvbiBvciBvZmYuCiAgICAgKiBXaGVuIHRoZSBIaXJhZ2FuYSBRdWF0ZXJuYXJ5IG1vZGUgaXMgdHVybmVkIG9uLCB0aGUgY29sbGF0b3IgCiAgICAgKiBwb3NpdGlvbnMgSGlyYWdhbmEgY2hhcmFjdGVycyBiZWZvcmUgYWxsIG5vbi1pZ25vcmFibGUgY2hhcmFjdGVycyBpbiAKICAgICAqIFFVQVRFUk5BUlkgc3RyZW5ndGguIFRoaXMgaXMgdG8gcHJvZHVjZSBhIGNvcnJlY3QgSklTIGNvbGxhdGlvbiBvcmRlciwKICAgICAqIGRpc3Rpbmd1aXNoaW5nIGJldHdlZW4gS2F0YWthbmEgIGFuZCBIaXJhZ2FuYSBjaGFyYWN0ZXJzLiAKICAgICAqIEBwYXJhbSBmbGFnIHRydWUgaWYgSGlyYWdhbmEgUXVhdGVybmFyeSBtb2RlIGlzIHRvIGJlIG9uLCBmYWxzZSAKICAgICAqICAgICAgICBvdGhlcndpc2UKICAgICAqIEBzZWUgI3NldEhpcmFnYW5hUXVhdGVybmFyeURlZmF1bHQKICAgICAqIEBzZWUgI2lzSGlyYWdhbmFRdWF0ZXJuYXJ5CiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRIaXJhZ2FuYVF1YXRlcm5hcnkoYm9vbGVhbiBmbGFnKQogICAgewoJbV9pc0hpcmFnYW5hNF8gPSBmbGFnOwkKICAgIH0KCQogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBIaXJhZ2FuYSBRdWF0ZXJuYXJ5IG1vZGUgdG8gdGhlIGluaXRpYWwgbW9kZSBzZXQgZHVyaW5nIAogICAgICogY29uc3RydWN0aW9uIG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvci4KICAgICAqIFNlZSBzZXRIaXJhZ2FuYVF1YXRlcm5hcnkoYm9vbGVhbikgZm9yIG1vcmUgZGV0YWlscy4KICAgICAqIEBzZWUgI3NldEhpcmFnYW5hUXVhdGVybmFyeShib29sZWFuKQogICAgICogQHNlZSAjaXNIaXJhZ2FuYVF1YXRlcm5hcnkKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldEhpcmFnYW5hUXVhdGVybmFyeURlZmF1bHQoKQogICAgewoJbV9pc0hpcmFnYW5hNF8gPSBtX2RlZmF1bHRJc0hpcmFnYW5hNF87CQogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgd2hldGhlciB1cHBlcmNhc2UgY2hhcmFjdGVycyBzb3J0IGJlZm9yZSBsb3dlcmNhc2UKICAgICAqIGNoYXJhY3RlcnMgb3IgdmljZSB2ZXJzYSwgaW4gc3RyZW5ndGggVEVSVElBUlkuIFRoZSBkZWZhdWx0IAogICAgICogbW9kZSBpcyBmYWxzZSwgYW5kIHNvIGxvd2VyY2FzZSBjaGFyYWN0ZXJzIHNvcnQgYmVmb3JlIHVwcGVyY2FzZQogICAgICogY2hhcmFjdGVycy4gCiAgICAgKiBJZiB0cnVlLCBzb3J0IHVwcGVyIGNhc2UgY2hhcmFjdGVycyBmaXJzdC4KICAgICAqIEBwYXJhbSB1cHBlcmZpcnN0IHRydWUgdG8gc29ydCB1cHBlcmNhc2UgY2hhcmFjdGVycyBiZWZvcmUgCiAgICAgKiAgICAgICAgICAgICAgICAgICBsb3dlcmNhc2UgY2hhcmFjdGVycywgZmFsc2UgdG8gc29ydCBsb3dlcmNhc2UgCiAgICAgKiAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzIGJlZm9yZSB1cHBlcmNhc2UgY2hhcmFjdGVycyAKICAgICAqIEBzZWUgI2lzTG93ZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI2lzVXBwZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI3NldExvd2VyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNzZXRDYXNlRmlyc3REZWZhdWx0CiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRVcHBlckNhc2VGaXJzdChib29sZWFuIHVwcGVyZmlyc3QpCiAgICB7CiAgICAgICAgaWYgKHVwcGVyZmlyc3QpIHsKICAgICAgICAgICAgaWYobV9jYXNlRmlyc3RfICE9IEF0dHJpYnV0ZVZhbHVlLlVQUEVSX0ZJUlNUXykgewogICAgICAgICAgICAgICAgbGF0aW5PbmVSZWdlblRhYmxlXyA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbV9jYXNlRmlyc3RfID0gQXR0cmlidXRlVmFsdWUuVVBQRVJfRklSU1RfOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaWYobV9jYXNlRmlyc3RfICE9IEF0dHJpYnV0ZVZhbHVlLk9GRl8pIHsKICAgICAgICAgICAgICAgIGxhdGluT25lUmVnZW5UYWJsZV8gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1fY2FzZUZpcnN0XyA9IEF0dHJpYnV0ZVZhbHVlLk9GRl87CiAgICAgICAgfQogICAgICAgIHVwZGF0ZUludGVybmFsU3RhdGUoKTsKICAgIH0KCQogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBvcmRlcnMgb2YgbG93ZXIgY2FzZWQgY2hhcmFjdGVycyB0byBzb3J0IGJlZm9yZSB1cHBlciBjYXNlZCAKICAgICAqIGNoYXJhY3RlcnMsIGluIHN0cmVuZ3RoIFRFUlRJQVJZLiBUaGUgZGVmYXVsdCAKICAgICAqIG1vZGUgaXMgZmFsc2UuCiAgICAgKiBJZiB0cnVlIGlzIHNldCwgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHdpbGwgc29ydCBsb3dlciBjYXNlZCBjaGFyYWN0ZXJzIAogICAgICogYmVmb3JlIHRoZSB1cHBlciBjYXNlZCBvbmVzLgogICAgICogT3RoZXJ3aXNlLCBpZiBmYWxzZSBpcyBzZXQsIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB3aWxsIGlnbm9yZSBjYXNlIAogICAgICogcHJlZmVyZW5jZXMuCiAgICAgKiBAcGFyYW0gbG93ZXJmaXJzdCB0cnVlIGZvciBzb3J0aW5nIGxvd2VyIGNhc2VkIGNoYXJhY3RlcnMgYmVmb3JlIAogICAgICogICAgICAgICAgICAgICAgICAgdXBwZXIgY2FzZWQgY2hhcmFjdGVycywgZmFsc2UgdG8gaWdub3JlIGNhc2UgCiAgICAgKiAgICAgICAgICAgICAgICAgICBwcmVmZXJlbmNlcy4gCiAgICAgKiBAc2VlICNpc0xvd2VyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNpc1VwcGVyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNzZXRVcHBlckNhc2VGaXJzdAogICAgICogQHNlZSAjc2V0Q2FzZUZpcnN0RGVmYXVsdAogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0TG93ZXJDYXNlRmlyc3QoYm9vbGVhbiBsb3dlcmZpcnN0KQogICAgewogIAlpZiAobG93ZXJmaXJzdCkgewogICAgICAgICAgICBpZihtX2Nhc2VGaXJzdF8gIT0gQXR0cmlidXRlVmFsdWUuTE9XRVJfRklSU1RfKSB7CiAgICAgICAgICAgICAgICBsYXRpbk9uZVJlZ2VuVGFibGVfID0gdHJ1ZTsKICAgICAgICAgICAgfSAgICAgICAgICAgIAogICAJCQltX2Nhc2VGaXJzdF8gPSBBdHRyaWJ1dGVWYWx1ZS5MT1dFUl9GSVJTVF87CiAgIAl9CiAgIAllbHNlIHsKICAgICAgICAgICAgaWYobV9jYXNlRmlyc3RfICE9IEF0dHJpYnV0ZVZhbHVlLk9GRl8pIHsKICAgICAgICAgICAgICAgIGxhdGluT25lUmVnZW5UYWJsZV8gPSB0cnVlOwogICAgICAgICAgICB9ICAgICAgICAgICAgCiAgIAkgICAgbV9jYXNlRmlyc3RfID0gQXR0cmlidXRlVmFsdWUuT0ZGXzsKICAgIAl9CiAgIAl1cGRhdGVJbnRlcm5hbFN0YXRlKCk7CiAgICB9CiAgIAkKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2FzZSBmaXJzdCBtb2RlIHRvIHRoZSBpbml0aWFsIG1vZGUgc2V0IGR1cmluZyAKICAgICAqIGNvbnN0cnVjdGlvbiBvZiB0aGUgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBTZWUgc2V0VXBwZXJDYXNlRmlyc3QoYm9vbGVhbikgYW5kIHNldExvd2VyQ2FzZUZpcnN0KGJvb2xlYW4pIGZvciBtb3JlIAogICAgICogZGV0YWlscy4KICAgICAqIEBzZWUgI2lzTG93ZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI2lzVXBwZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI3NldExvd2VyQ2FzZUZpcnN0KGJvb2xlYW4pCiAgICAgKiBAc2VlICNzZXRVcHBlckNhc2VGaXJzdChib29sZWFuKQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIGZpbmFsIHZvaWQgc2V0Q2FzZUZpcnN0RGVmYXVsdCgpCiAgICB7CiAgICAgICAgaWYobV9jYXNlRmlyc3RfICE9IG1fZGVmYXVsdENhc2VGaXJzdF8pIHsKICAgICAgICAgICAgbGF0aW5PbmVSZWdlblRhYmxlXyA9IHRydWU7CiAgICAgICAgfSAgICAgICAgICAgIAoJbV9jYXNlRmlyc3RfID0gbV9kZWZhdWx0Q2FzZUZpcnN0XzsKCXVwZGF0ZUludGVybmFsU3RhdGUoKTsKICAgIH0KICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGFsdGVybmF0ZSBoYW5kbGluZyBtb2RlIHRvIHRoZSBpbml0aWFsIG1vZGUgc2V0IGR1cmluZyAKICAgICAqIGNvbnN0cnVjdGlvbiBvZiB0aGUgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBTZWUgc2V0QWx0ZXJuYXRlSGFuZGxpbmcoYm9vbGVhbikgZm9yIG1vcmUgZGV0YWlscy4KICAgICAqIEBzZWUgI3NldEFsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZChib29sZWFuKQogICAgICogQHNlZSAjaXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWQoKQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0QWx0ZXJuYXRlSGFuZGxpbmdEZWZhdWx0KCkKICAgIHsKICAgIAltX2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXyA9IG1fZGVmYXVsdElzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXzsKICAgIAl1cGRhdGVJbnRlcm5hbFN0YXRlKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY2FzZSBsZXZlbCBtb2RlIHRvIHRoZSBpbml0aWFsIG1vZGUgc2V0IGR1cmluZyAKICAgICAqIGNvbnN0cnVjdGlvbiBvZiB0aGUgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBTZWUgc2V0Q2FzZUxldmVsKGJvb2xlYW4pIGZvciBtb3JlIGRldGFpbHMuCiAgICAgKiBAc2VlICNzZXRDYXNlTGV2ZWwoYm9vbGVhbikKICAgICAqIEBzZWUgI2lzQ2FzZUxldmVsCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRDYXNlTGV2ZWxEZWZhdWx0KCkKICAgIHsKICAgIAltX2lzQ2FzZUxldmVsXyA9IG1fZGVmYXVsdElzQ2FzZUxldmVsXzsKICAgIAl1cGRhdGVJbnRlcm5hbFN0YXRlKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIHRvIHRoZSBpbml0aWFsIG1vZGUgc2V0IGR1cmluZyBjb25zdHJ1Y3Rpb24KICAgICAqIG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvci4KICAgICAqIFNlZSBzZXREZWNvbXBvc2l0aW9uKGludCkgZm9yIG1vcmUgZGV0YWlscy4KICAgICAqIEBzZWUgI2dldERlY29tcG9zaXRpb24KICAgICAqIEBzZWUgI3NldERlY29tcG9zaXRpb24oaW50KQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0RGVjb21wb3NpdGlvbkRlZmF1bHQoKQogICAgewogICAgCXNldERlY29tcG9zaXRpb24obV9kZWZhdWx0RGVjb21wb3NpdGlvbl8pOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIEZyZW5jaCBjb2xsYXRpb24gbW9kZSB0byB0aGUgaW5pdGlhbCBtb2RlIHNldCBkdXJpbmcgCiAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yLgogICAgICogU2VlIHNldEZyZW5jaENvbGxhdGlvbihib29sZWFuKSBmb3IgbW9yZSBkZXRhaWxzLgogICAgICogQHNlZSAjaXNGcmVuY2hDb2xsYXRpb24KICAgICAqIEBzZWUgI3NldEZyZW5jaENvbGxhdGlvbihib29sZWFuKQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0RnJlbmNoQ29sbGF0aW9uRGVmYXVsdCgpCiAgICB7CiAgICAgICAgaWYobV9pc0ZyZW5jaENvbGxhdGlvbl8gIT0gbV9kZWZhdWx0SXNGcmVuY2hDb2xsYXRpb25fKSB7CiAgICAgICAgICAgIGxhdGluT25lUmVnZW5UYWJsZV8gPSB0cnVlOwogICAgICAgIH0KICAgIAltX2lzRnJlbmNoQ29sbGF0aW9uXyA9IG1fZGVmYXVsdElzRnJlbmNoQ29sbGF0aW9uXzsKICAgIAl1cGRhdGVJbnRlcm5hbFN0YXRlKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoIHRvIHRoZSBpbml0aWFsIG1vZGUgc2V0IGR1cmluZyB0aGUgCiAgICAgKiBjb25zdHJ1Y3Rpb24gb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yLgogICAgICogU2VlIHNldFN0cmVuZ3RoKGludCkgZm9yIG1vcmUgZGV0YWlscy4KICAgICAqIEBzZWUgI3NldFN0cmVuZ3RoKGludCkKICAgICAqIEBzZWUgI2dldFN0cmVuZ3RoCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRTdHJlbmd0aERlZmF1bHQoKQogICAgewogICAgCXNldFN0cmVuZ3RoKG1fZGVmYXVsdFN0cmVuZ3RoXyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgbW9kZSBmb3IgdGhlIGRpcmVjdGlvbiBvZiBTRUNPTkRBUlkgd2VpZ2h0cyB0byBiZSB1c2VkIGluIAogICAgICogRnJlbmNoIGNvbGxhdGlvbi4KICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGZhbHNlLCB3aGljaCB0cmVhdHMgU0VDT05EQVJZIHdlaWdodHMgaW4gdGhlIG9yZGVyIAogICAgICogdGhleSBhcHBlYXIuCiAgICAgKiBJZiBzZXQgdG8gdHJ1ZSwgdGhlIFNFQ09OREFSWSB3ZWlnaHRzIHdpbGwgYmUgc29ydGVkIGJhY2t3YXJkcy4KICAgICAqIFNlZSB0aGUgc2VjdGlvbiBvbiAKICAgICAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9TZXJ2aWNlQXJjaGl0ZWN0dXJlLmh0bWw+CiAgICAgKiBGcmVuY2ggY29sbGF0aW9uPC9hPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgICAqIEBwYXJhbSBmbGFnIHRydWUgdG8gc2V0IHRoZSBGcmVuY2ggY29sbGF0aW9uIG9uLCBmYWxzZSB0byBzZXQgaXQgb2ZmCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICogQHNlZSAjaXNGcmVuY2hDb2xsYXRpb24KICAgICAqIEBzZWUgI3NldEZyZW5jaENvbGxhdGlvbkRlZmF1bHQKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0RnJlbmNoQ29sbGF0aW9uKGJvb2xlYW4gZmxhZykgCiAgICB7CiAgICAgICAgaWYobV9pc0ZyZW5jaENvbGxhdGlvbl8gIT0gZmxhZykgewogICAgICAgICAgICBsYXRpbk9uZVJlZ2VuVGFibGVfID0gdHJ1ZTsKICAgICAgICB9CiAgICAJbV9pc0ZyZW5jaENvbGxhdGlvbl8gPSBmbGFnOwogICAgCXVwZGF0ZUludGVybmFsU3RhdGUoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBhbHRlcm5hdGUgaGFuZGxpbmcgZm9yIFFVQVRFUk5BUlkgc3RyZW5ndGggdG8gYmUgZWl0aGVyIAogICAgICogc2hpZnRlZCBvciBub24taWdub3JhYmxlLiAKICAgICAqIFNlZSB0aGUgVUNBIGRlZmluaXRpb24gb24gCiAgICAgKiA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjEwLyOnMy4yLjIgVmFyaWFibGUgQ29sbGF0aW9uIEVsZW1lbnRzIj4KICAgICAqIEFsdGVybmF0ZSBXZWlnaHRpbmc8L2E+LgogICAgICogVGhpcyBhdHRyaWJ1dGUgd2lsbCBvbmx5IGJlIGVmZmVjdGl2ZSB3aGVuIFFVQVRFUk5BUlkgc3RyZW5ndGggaXMgc2V0LgogICAgICogVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoaXMgbW9kZSBpcyBmYWxzZSwgY29ycmVzcG9uZGluZyB0byB0aGUgCiAgICAgKiBOT05fSUdOT1JBQkxFIG1vZGUgaW4gVUNBLiBJbiB0aGUgTk9OLUlHTk9SQUJMRSBtb2RlLCB0aGUgCiAgICAgKiBSdWxlQmFzZWRDb2xsYXRvciB3aWxsIHRyZWF0cyBhbGwgdGhlIGNvZGVwb2ludHMgd2l0aCBub24taWdub3JhYmxlIAogICAgICogcHJpbWFyeSB3ZWlnaHRzIGluIHRoZSBzYW1lIHdheS4gCiAgICAgKiBJZiB0aGUgbW9kZSBpcyBzZXQgdG8gdHJ1ZSwgdGhlIGJlaGF2aW91ciBjb3JyZXNwb25kcyB0byBTSElGVEVEIGRlZmluZWQKICAgICAqIGluIFVDQSwgdGhpcyBjYXVzZXMgY29kZXBvaW50cyB3aXRoIFBSSU1BUlkgb3JkZXJzIHRoYXQgYXJlIGVxdWFsIG9yIAogICAgICogYmVsb3cgdGhlIHZhcmlhYmxlIHRvcCB2YWx1ZSB0byBiZSBpZ25vcmVkIGluIFBSSU1BUlkgb3JkZXIgYW5kIAogICAgICogbW92ZWQgdG8gdGhlIFFVQVRFUk5BUlkgb3JkZXIuCiAgICAgKiBAcGFyYW0gc2hpZnRlZCB0cnVlIGlmIFNISUZURUQgYmVoYXZpb3VyIGZvciBhbHRlcm5hdGUgaGFuZGxpbmcgaXMgCiAgICAgKiAgICAgICAgZGVzaXJlZCwgZmFsc2UgZm9yIHRoZSBOT05fSUdOT1JBQkxFIGJlaGF2aW91ci4KICAgICAqIEBzZWUgI2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkCiAgICAgKiBAc2VlICNzZXRBbHRlcm5hdGVIYW5kbGluZ0RlZmF1bHQKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldEFsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZChib29sZWFuIHNoaWZ0ZWQpCiAgICB7CiAgICAJbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF8gPSBzaGlmdGVkOwogICAgCXVwZGF0ZUludGVybmFsU3RhdGUoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIFdoZW4gY2FzZSBsZXZlbCBpcyBzZXQgdG8gdHJ1ZSwgYW4gYWRkaXRpb25hbCB3ZWlnaHQgaXMgZm9ybWVkIAogICAgICogYmV0d2VlbiB0aGUgU0VDT05EQVJZIGFuZCBURVJUSUFSWSB3ZWlnaHQsIGtub3duIGFzIHRoZSBjYXNlIGxldmVsLiAKICAgICAqIFRoZSBjYXNlIGxldmVsIGlzIHVzZWQgdG8gZGlzdGluZ3Vpc2ggbGFyZ2UgYW5kIHNtYWxsIEphcGFuZXNlIEthbmEgCiAgICAgKiBjaGFyYWN0ZXJzLiBDYXNlIGxldmVsIGNvdWxkIGFsc28gYmUgdXNlZCBpbiBvdGhlciBzaXR1YXRpb25zLiAKICAgICAqIEZvciBleGFtcGxlIHRvIGRpc3Rpbmd1aXNoIGNlcnRhaW4gUGlueWluIGNoYXJhY3RlcnMuIAogICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgZmFsc2UsIHdoaWNoIG1lYW5zIHRoZSBjYXNlIGxldmVsIGlzIG5vdCBnZW5lcmF0ZWQuCiAgICAgKiBUaGUgY29udGVudHMgb2YgdGhlIGNhc2UgbGV2ZWwgYXJlIGFmZmVjdGVkIGJ5IHRoZSBjYXNlIGZpcnN0CiAgICAgKiBtb2RlLiBBIHNpbXBsZSB3YXkgdG8gaWdub3JlIGFjY2VudCBkaWZmZXJlbmNlcyBpbiBhIHN0cmluZyBpcyB0byBzZXQgCiAgICAgKiB0aGUgc3RyZW5ndGggdG8gUFJJTUFSWSBhbmQgZW5hYmxlIGNhc2UgbGV2ZWwuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFNlZSB0aGUgc2VjdGlvbiBvbiAKICAgICAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9TZXJ2aWNlQXJjaGl0ZWN0dXJlLmh0bWw+CiAgICAgKiBjYXNlIGxldmVsPC9hPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgICAqIDwvcD4KICAgICAqIEBwYXJhbSBmbGFnIHRydWUgaWYgY2FzZSBsZXZlbCBzb3J0aW5nIGlzIHJlcXVpcmVkLCBmYWxzZSBvdGhlcndpc2UKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKiBAc2VlICNzZXRDYXNlTGV2ZWxEZWZhdWx0CiAgICAgKiBAc2VlICNpc0Nhc2VMZXZlbAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRDYXNlTGV2ZWwoYm9vbGVhbiBmbGFnKSAKICAgIHsKICAgIAltX2lzQ2FzZUxldmVsXyA9IGZsYWc7CiAgICAJdXBkYXRlSW50ZXJuYWxTdGF0ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBTZXRzIHRoaXMgQ29sbGF0b3IncyBzdHJlbmd0aCBwcm9wZXJ0eS4gVGhlIHN0cmVuZ3RoIHByb3BlcnR5IAogICAgICogZGV0ZXJtaW5lcyB0aGUgbWluaW11bSBsZXZlbCBvZiBkaWZmZXJlbmNlIGNvbnNpZGVyZWQgc2lnbmlmaWNhbnQgCiAgICAgKiBkdXJpbmcgY29tcGFyaXNvbi4KICAgICAqIDwvcD4KICAgICAqIDxwPlNlZSB0aGUgQ29sbGF0b3IgY2xhc3MgZGVzY3JpcHRpb24gZm9yIGFuIGV4YW1wbGUgb2YgdXNlLjwvcD4KICAgICAqIEBwYXJhbSB0aGUgbmV3IHN0cmVuZ3RoIHZhbHVlLgogICAgICogQHNlZSAjZ2V0U3RyZW5ndGgKICAgICAqIEBzZWUgI3NldFN0cmVuZ3RoRGVmYXVsdAogICAgICogQHNlZSAjUFJJTUFSWQogICAgICogQHNlZSAjU0VDT05EQVJZCiAgICAgKiBAc2VlICNURVJUSUFSWQogICAgICogQHNlZSAjUVVBVEVSTkFSWQogICAgICogQHNlZSAjSURFTlRJQ0FMCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgbmV3IHN0cmVuZ3RoIHZhbHVlIGlzIG5vdCBvbmUgCiAgICAgKiAJCQkJb2YgUFJJTUFSWSwgU0VDT05EQVJZLCBURVJUSUFSWSwgUVVBVEVSTkFSWSBvciBJREVOVElDQUwuCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRTdHJlbmd0aChpbnQgbmV3U3RyZW5ndGgpIAogICAgewogICAgICAgIHN1cGVyLnNldFN0cmVuZ3RoKG5ld1N0cmVuZ3RoKTsKICAgICAgICB1cGRhdGVJbnRlcm5hbFN0YXRlKCk7CiAgICB9CgogICAgLy8gcHVibGljIGdldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb2xsYXRpb24gcnVsZXMgZm9yIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IuICAgICAKICAgICAqIEByZXR1cm4gcmV0dXJucyB0aGUgY29sbGF0aW9uIHJ1bGVzCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGdldFJ1bGVzKCkKICAgIHsKICAgIAlyZXR1cm4gbV9ydWxlc187CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYW4gVW5pY29kZVNldCB0aGF0IGNvbnRhaW5zIGFsbCB0aGUgY2hhcmFjdGVycyBhbmQgc2VxdWVuY2VzIAogICAgICogdGFpbG9yZWQgaW4gdGhpcyBjb2xsYXRvci4KICAgICAqIEByZXR1cm4gYSBwb2ludGVyIHRvIGEgVW5pY29kZVNldCBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIAogICAgICogICAgICAgICBjb2RlIHBvaW50cyBhbmQgc2VxdWVuY2VzIHRoYXQgbWF5IHNvcnQgZGlmZmVyZW50bHkgdGhhbgogICAgICogICAgICAgICBpbiB0aGUgVUNBLiAKICAgICAqIEBleGNlcHRpb24gUGFyc2VFeGNlcHRpb24gdGhyb3duIHdoZW4gYXJndW1lbnQgcnVsZXMgaGF2ZSBhbiAKICAgICAqICAgICAgICAgICAgaW52YWxpZCBzeW50YXguIElPRXhjZXB0aW9uIAogICAgICogQGRyYWZ0IElDVSAyLjQKICAgICAqLwogICAgcHVibGljIFVuaWNvZGVTZXQgZ2V0VGFpbG9yZWRTZXQoKQogICAgewogICAgICAgIHRyeSB7CgkgICAgICAgQ29sbGF0aW9uUnVsZVBhcnNlciBzcmMgPSBuZXcgQ29sbGF0aW9uUnVsZVBhcnNlcihnZXRSdWxlcygpKTsKCSAgICAgICByZXR1cm4gc3JjLmdldFRhaWxvcmVkU2V0KCk7CiAgICAgICAgfSBjYXRjaChFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigiQSB0YWlsb3JpbmcgcnVsZSBzaG91bGQgbm90IGhhdmUgZXJyb3JzLiBTb21ldGhpbmcgaXMgcXVpdGUgd3JvbmchIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBHZXQgYSBDb2xsYXRpb24ga2V5IGZvciB0aGUgYXJndW1lbnQgU3RyaW5nIHNvdXJjZSBmcm9tIHRoaXMgCiAgICAgKiBSdWxlQmFzZWRDb2xsYXRvci4gCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIEdlbmVyYWwgcmVjb21tZW5kYXRpb246IDxicj4KICAgICAqIElmIGNvbXBhcmlzb24gYXJlIHRvIGJlIGRvbmUgdG8gdGhlIHNhbWUgU3RyaW5nIG11bHRpcGxlIHRpbWVzLCBpdCB3b3VsZAogICAgICogYmUgbW9yZSBlZmZpY2llbnQgdG8gZ2VuZXJhdGUgQ29sbGF0aW9uS2V5cyBmb3IgdGhlIFN0cmluZ3MgYW5kIHVzZSAKICAgICAqIENvbGxhdGlvbktleS5jb21wYXJlVG8oQ29sbGF0aW9uS2V5KSBmb3IgdGhlIGNvbXBhcmlzb25zLgogICAgICogSWYgdGhlIGVhY2ggU3RyaW5ncyBhcmUgY29tcGFyZWQgdG8gb25seSBvbmNlLCB1c2luZyB0aGUgbWV0aG9kCiAgICAgKiBSdWxlQmFzZWRDb2xsYXRvci5jb21wYXJlKFN0cmluZywgU3RyaW5nKSB3aWxsIGhhdmUgYSBiZXR0ZXIgcGVyZm9ybWFuY2UuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFNlZSB0aGUgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgYW4gZXhwbGFuYXRpb24gYWJvdXQgQ29sbGF0aW9uS2V5cy4KICAgICAqIDwvcD4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHRleHQgU3RyaW5nIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYSBjb2xsYXRpb24ga2V5LgogICAgICogQHJldHVybiB0aGUgQ29sbGF0aW9uS2V5IGZvciB0aGUgZ2l2ZW4gU3RyaW5nIGJhc2VkIG9uIHRoaXMgCiAgICAgKiAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yJ3MgY29sbGF0aW9uIHJ1bGVzLiBJZiB0aGUgc291cmNlIFN0cmluZyBpcyAKICAgICAqICAgICAgICAgbnVsbCwgYSBudWxsIENvbGxhdGlvbktleSBpcyByZXR1cm5lZC4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgICAgKiBAc2VlICNjb21wYXJlKFN0cmluZywgU3RyaW5nKQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIENvbGxhdGlvbktleSBnZXRDb2xsYXRpb25LZXkoU3RyaW5nIHNvdXJjZSkKICAgIHsKICAgIAlpZiAoc291cmNlID09IG51bGwpIHsKICAgIAkJcmV0dXJuIG51bGw7CiAgICAJfQogICAgCWludCBzdHJlbmd0aCA9IGdldFN0cmVuZ3RoKCk7CiAgICAJbV91dGlsQ29tcGFyZTBfID0gbV9pc0Nhc2VMZXZlbF87CiAgICAgICAgbV91dGlsQ29tcGFyZTFfID0gdHJ1ZTsKICAgIAltX3V0aWxDb21wYXJlMl8gPSBzdHJlbmd0aCA+PSBTRUNPTkRBUlk7CiAgICAJbV91dGlsQ29tcGFyZTNfID0gc3RyZW5ndGggPj0gVEVSVElBUlk7CiAgICAJbV91dGlsQ29tcGFyZTRfID0gc3RyZW5ndGggPj0gUVVBVEVSTkFSWTsKCQltX3V0aWxDb21wYXJlNV8gPSBzdHJlbmd0aCA9PSBJREVOVElDQUw7CgoJCW1fdXRpbEJ5dGVzQ291bnQwXyA9IDA7CiAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfID0gMDsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50Ml8gPSAwOwogICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyA9IDA7CiAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfID0gMDsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50NV8gPSAwOwogICAgCW1fdXRpbENvdW50MF8gPSAwOwogICAgICAgIG1fdXRpbENvdW50MV8gPSAwOwogICAgICAgIG1fdXRpbENvdW50Ml8gPSAwOwogICAgICAgIG1fdXRpbENvdW50M18gPSAwOwogICAgICAgIG1fdXRpbENvdW50NF8gPSAwOwogICAgICAgIG1fdXRpbENvdW50NV8gPSAwOwogICAgCWJvb2xlYW4gZG9GcmVuY2ggPSBtX2lzRnJlbmNoQ29sbGF0aW9uXyAmJiBtX3V0aWxDb21wYXJlMl87CiAgICAJLy8gVE9ETzogVUNPTF9DT01NT05fQk9UNCBzaG91bGQgYmUgYSBmdW5jdGlvbiBvZiBxU2hpZnRlZC4gCgkgICAgLy8gSWYgd2UgaGF2ZSBubyBxU2hpZnRlZCwgd2UgZG9uJ3QgbmVlZCB0byBzZXQgVUNPTF9DT01NT05fQk9UNCBzbyAKCSAgICAvLyBoaWdoLgogICAJCWludCBjb21tb25Cb3R0b200ID0gKChtX3ZhcmlhYmxlVG9wVmFsdWVfID4+PiA4KSArIDEpICYgTEFTVF9CWVRFX01BU0tfOwogICAgCWJ5dGUgaGlyYWdhbmE0ID0gMDsKICAgIAlpZiAobV9pc0hpcmFnYW5hNF8gJiYgbV91dGlsQ29tcGFyZTRfKSB7CiAgICAJCS8vIGFsbG9jYXRlIG9uZSBtb3JlIHNwYWNlIGZvciBoaXJhZ2FuYSwgdmFsdWUgZm9yIGhpcmFnYW5hCiAgICAgIAkJaGlyYWdhbmE0ID0gKGJ5dGUpY29tbW9uQm90dG9tNDsKICAgICAgCQljb21tb25Cb3R0b200ICsrOwogICAgCX0KICAgIAkKICAgIAlpbnQgYm90dG9tQ291bnQ0ID0gMHhGRiAtIGNvbW1vbkJvdHRvbTQ7CiAgICAJLy8gSWYgd2UgbmVlZCB0byBub3JtYWxpemUsIHdlJ2xsIGRvIGl0IGFsbCBhdCBvbmNlIGF0IHRoZSBiZWdpbm5pbmchCiAgICAJaWYgKG1fdXRpbENvbXBhcmU1XyAmJiBOb3JtYWxpemVyLnF1aWNrQ2hlY2soc291cmNlLCBOb3JtYWxpemVyLk5GRCkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhPSBOb3JtYWxpemVyLllFUykgewogICAgICAgICAgICAvLyBpZiBpdCBpcyBpZGVudGljYWwgc3RyZW5ndGgsIHdlIGhhdmUgdG8gbm9ybWFsaXplIHRoZSBzdHJpbmcgdG8KICAgICAgICAgICAgLy8gTkZEIHNvIHRoYXQgaXQgd2lsbCBiZSBhcHBlbmRlZCBjb3JyZWN0bHkgdG8gdGhlIGVuZCBvZiB0aGUgc29ydAogICAgICAgICAgICAvLyBrZXkKICAgICAgICAgICAgc291cmNlID0gTm9ybWFsaXplci5kZWNvbXBvc2Uoc291cmNlLCBmYWxzZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGdldERlY29tcG9zaXRpb24oKSAhPSBOT19ERUNPTVBPU0lUSU9OCiAgICAJCSYmIE5vcm1hbGl6ZXIucXVpY2tDaGVjayhzb3VyY2UsIE5vcm1hbGl6ZXIuRkNEKSAKICAgIAkJCQkJCQkJCQkJCSE9IE5vcm1hbGl6ZXIuWUVTKSB7CiAgICAgICAgICAgIC8vIGZvciB0aGUgcmVzdCBvZiB0aGUgc3RyZW5ndGgsIGlmIGRlY29tcG9zaXRpb24gaXMgb24sIEZDRCBpcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIGVub3VnaCBmb3IgdXMgdG8gd29yayBvbi4KICAgICAgICAJc291cmNlID0gTm9ybWFsaXplci5ub3JtYWxpemUoc291cmNlLE5vcm1hbGl6ZXIuRkNEKTsKICAgIAl9CgkJZ2V0U29ydEtleUJ5dGVzKHNvdXJjZSwgZG9GcmVuY2gsIGhpcmFnYW5hNCwgY29tbW9uQm90dG9tNCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbUNvdW50NCk7CgkJYnl0ZSBzb3J0a2V5W10gPSBnZXRTb3J0S2V5KHNvdXJjZSwgZG9GcmVuY2gsIGNvbW1vbkJvdHRvbTQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3R0b21Db3VudDQpOwoJCXJldHVybiBuZXcgQ29sbGF0aW9uS2V5KHNvdXJjZSwgc29ydGtleSk7CiAgICB9CiAgICAJCSAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgYW4gdXBwZXJjYXNlIGNoYXJhY3RlciBpcyBzb3J0ZWQgYmVmb3JlIHRoZSBjb3JyZXNwb25kaW5nIGxvd2VyY2FzZSBjaGFyYWN0ZXIuCiAgICAgKiBTZWUgc2V0Q2FzZUZpcnN0KGJvb2xlYW4pIGZvciBkZXRhaWxzLgogICAgICogQHNlZSAjc2V0VXBwZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI3NldExvd2VyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNpc0xvd2VyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNzZXRDYXNlRmlyc3REZWZhdWx0CiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdXBwZXIgY2FzZWQgY2hhcmFjdGVycyBhcmUgc29ydGVkIGJlZm9yZSBsb3dlciBjYXNlZCAKICAgICAqICAgICAgICAgY2hhcmFjdGVycywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICAgcHVibGljIGJvb2xlYW4gaXNVcHBlckNhc2VGaXJzdCgpCiAgICAgewogICAgICAgIHJldHVybiAobV9jYXNlRmlyc3RfID09IEF0dHJpYnV0ZVZhbHVlLlVQUEVSX0ZJUlNUXyk7CiAgICAgfQoJCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIGEgbG93ZXJjYXNlIGNoYXJhY3RlciBpcyBzb3J0ZWQgYmVmb3JlIHRoZSBjb3JyZXNwb25kaW5nIHVwcGVyY2FzZSBjaGFyYWN0ZXIuCiAgICAgKiBTZWUgc2V0Q2FzZUZpcnN0KGJvb2xlYW4pIGZvciBkZXRhaWxzLgogICAgICogQHNlZSAjc2V0VXBwZXJDYXNlRmlyc3QKICAgICAqIEBzZWUgI3NldExvd2VyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNpc1VwcGVyQ2FzZUZpcnN0CiAgICAgKiBAc2VlICNzZXRDYXNlRmlyc3REZWZhdWx0CiAgICAgKiBAcmV0dXJuIHRydWUgbG93ZXIgY2FzZWQgY2hhcmFjdGVycyBhcmUgc29ydGVkIGJlZm9yZSB1cHBlciBjYXNlZCAKICAgICAqICAgICAgICAgY2hhcmFjdGVycywgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0xvd2VyQ2FzZUZpcnN0KCkKICAgIHsKICAgICAgICByZXR1cm4gKG1fY2FzZUZpcnN0XyA9PSBBdHRyaWJ1dGVWYWx1ZS5MT1dFUl9GSVJTVF8pOwkKICAgIH0KCQogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdGhlIGFsdGVybmF0ZSBoYW5kbGluZyBiZWhhdmlvdXIgaXMgdGhlIFVDQSBkZWZpbmVkIFNISUZURUQgb3IgCiAgICAgKiBOT05fSUdOT1JBQkxFLgogICAgICogSWYgcmV0dXJuIHZhbHVlIGlzIHRydWUsIHRoZW4gdGhlIGFsdGVybmF0ZSBoYW5kbGluZyBhdHRyaWJ1dGUgZm9yIHRoZSAKICAgICAqIENvbGxhdG9yIGlzIFNISUZURUQuIE90aGVyd2lzZSBpZiByZXR1cm4gdmFsdWUgaXMgZmFsc2UsIHRoZW4gdGhlIAogICAgICogYWx0ZXJuYXRlIGhhbmRsaW5nIGF0dHJpYnV0ZSBmb3IgdGhlIENvbGxhdG9yIGlzIE5PTl9JR05PUkFCTEUKICAgICAqIFNlZSBzZXRBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWQoYm9vbGVhbikgZm9yIG1vcmUgZGV0YWlscy4KICAgICAqIEByZXR1cm4gdHJ1ZSBvciBmYWxzZSAKICAgICAqIEBzZWUgI3NldEFsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZChib29sZWFuKQogICAgICogQHNlZSAjc2V0QWx0ZXJuYXRlSGFuZGxpbmdEZWZhdWx0CiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZCgpCiAgICB7CglyZXR1cm4gbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF87CiAgICB9CgkKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIGNhc2UgbGV2ZWwgaXMgc2V0IHRvIHRydWUuCiAgICAgKiBTZWUgc2V0Q2FzZUxldmVsKGJvb2xlYW4pIGZvciBkZXRhaWxzLgogICAgICogQHJldHVybiB0aGUgY2FzZSBsZXZlbCBtb2RlCiAgICAgKiBAc2VlICNzZXRDYXNlTGV2ZWxEZWZhdWx0CiAgICAgKiBAc2VlICNpc0Nhc2VMZXZlbAogICAgICogQHNlZSAjc2V0Q2FzZUxldmVsKGJvb2xlYW4pCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Nhc2VMZXZlbCgpCiAgICB7CiAgICAgICAgcmV0dXJuIG1faXNDYXNlTGV2ZWxfOwkKICAgIH0KCQogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgRnJlbmNoIENvbGxhdGlvbiBpcyBzZXQgdG8gdHJ1ZS4KICAgICAqIFNlZSBzZXRGcmVuY2hDb2xsYXRpb24oYm9vbGVhbikgZm9yIGRldGFpbHMuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgRnJlbmNoIENvbGxhdGlvbiBpcyBzZXQgdG8gdHJ1ZSwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAc2VlICNzZXRGcmVuY2hDb2xsYXRpb24oYm9vbGVhbikKICAgICAqIEBzZWUgI3NldEZyZW5jaENvbGxhdGlvbkRlZmF1bHQKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgICBwdWJsaWMgYm9vbGVhbiBpc0ZyZW5jaENvbGxhdGlvbigpCiAgICAgewogICAgICAgICByZXR1cm4gbV9pc0ZyZW5jaENvbGxhdGlvbl87CiAgICAgfQoJCgkvKioKCSAqIENoZWNrcyBpZiB0aGUgSGlyYWdhbmEgUXVhdGVybmFyeSBtb2RlIGlzIHNldCBvbi4KCSAqIFNlZSBzZXRIaXJhZ2FuYVF1YXRlcm5hcnkoYm9vbGVhbikgZm9yIG1vcmUgZGV0YWlscy4KCSAqIEByZXR1cm4gZmxhZyB0cnVlIGlmIEhpcmFnYW5hIFF1YXRlcm5hcnkgbW9kZSBpcyBvbiwgZmFsc2Ugb3RoZXJ3aXNlCgkgKiBAc2VlICNzZXRIaXJhZ2FuYVF1YXRlcm5hcnlEZWZhdWx0CgkgKiBAc2VlICNzZXRIaXJhZ2FuYVF1YXRlcm5hcnkoYm9vbGVhbikKCSAqIEBkcmFmdCBJQ1UgMi4yCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzSGlyYWdhbmFRdWF0ZXJuYXJ5KCkKCXsKCQlyZXR1cm4gbV9pc0hpcmFnYW5hNF87Cgl9CgkJCgkvLyBwdWJsaWMgb3RoZXIgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBDb21wYXJlcyB0aGUgZXF1YWxpdHkgb2YgdHdvIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdHMuCiAgICAgKiBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3RzIGFyZSBlcXVhbCBpZiB0aGV5IGhhdmUgdGhlIHNhbWUgY29sbGF0aW9uCiAgICAgKiBydWxlcyBhbmQgdGhlIHNhbWUgYXR0cmlidXRlcy4KICAgICAqIEBwYXJhbSBvYmogdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHRvIGJlIGNvbXBhcmVkIHRvLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IgaGFzIGV4YWN0bHkgdGhlIHNhbWUgCiAgICAgKiAgICAgICAgIGNvbGxhdGlvbiBiZWhhdmlvdXIgYXMgb2JqLCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgCiAgICB7CiAgICAgICAgaWYgKG9iaiA9PSBudWxsKSB7CiAgICAgICAgCXJldHVybiBmYWxzZTsgIC8vIHN1cGVyIGRvZXMgY2xhc3MgY2hlY2sKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMgPT0gb2JqKSB7CiAgICAgICAgCXJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkgewogICAgICAgIAlyZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIG90aGVyID0gKFJ1bGVCYXNlZENvbGxhdG9yKW9iajsKICAgICAgICAvLyBhbGwgb3RoZXIgbm9uLXRyYW5zaWVudCBpbmZvcm1hdGlvbiBpcyBhbHNvIGNvbnRhaW5lZCBpbiBydWxlcy4KICAgICAgICBpZiAoZ2V0U3RyZW5ndGgoKSAhPSBvdGhlci5nZXRTdHJlbmd0aCgpIAogICAgICAgICAgICAgICB8fCBnZXREZWNvbXBvc2l0aW9uKCkgIT0gb3RoZXIuZ2V0RGVjb21wb3NpdGlvbigpIAogICAgICAgICAgICAgICB8fCBvdGhlci5tX2Nhc2VGaXJzdF8gIT0gbV9jYXNlRmlyc3RfCiAgICAgICAgICAgICAgIHx8IG90aGVyLm1fY2FzZVN3aXRjaF8gIT0gbV9jYXNlU3dpdGNoXwogICAgICAgICAgICAgICB8fCBvdGhlci5tX2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF8KICAgICAgICAgICAgICAgfHwgb3RoZXIubV9pc0Nhc2VMZXZlbF8gIT0gbV9pc0Nhc2VMZXZlbF8KICAgICAgICAgICAgICAgfHwgb3RoZXIubV9pc0ZyZW5jaENvbGxhdGlvbl8gIT0gbV9pc0ZyZW5jaENvbGxhdGlvbl8KICAgICAgICAgICAgICAgfHwgb3RoZXIubV9pc0hpcmFnYW5hNF8gIT0gbV9pc0hpcmFnYW5hNF8pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBib29sZWFuIHJ1bGVzID0gbV9ydWxlc18gPT0gb3RoZXIubV9ydWxlc187CiAgICAgICAgaWYgKCFydWxlcyAmJiAobV9ydWxlc18gIT0gbnVsbCAmJiBvdGhlci5tX3J1bGVzXyAhPSBudWxsKSkgewogICAgICAgICAgICBydWxlcyA9IG1fcnVsZXNfLmVxdWFscyhvdGhlci5tX3J1bGVzXyk7CiAgICAgICAgfQogICAgICAgIGlmICghcnVsZXMgfHwgIUlDVURlYnVnLmVuYWJsZWQoImNvbGxhdGlvbiIpKSB7CiAgICAgICAgICAgIHJldHVybiBydWxlczsKICAgICAgICB9CiAgICAgICAgaWYgKG1fYWRkaXRpb24zXyAhPSBvdGhlci5tX2FkZGl0aW9uM18gCiAgICAgICAgICAgICAgICAgIHx8IG1fYm90dG9tM18gIT0gb3RoZXIubV9ib3R0b20zXyAKICAgICAgICAgICAgICAgICAgfHwgbV9ib3R0b21Db3VudDNfICE9IG90aGVyLm1fYm90dG9tQ291bnQzXyAKICAgICAgICAgICAgICAgICAgfHwgbV9jb21tb24zXyAhPSBvdGhlci5tX2NvbW1vbjNfIAogICAgICAgICAgICAgICAgICB8fCBtX2lzU2ltcGxlM18gIT0gb3RoZXIubV9pc1NpbXBsZTNfCiAgICAgICAgICAgICAgICAgIHx8IG1fbWFzazNfICE9IG90aGVyLm1fbWFzazNfCiAgICAgICAgICAgICAgICAgIHx8IG1fbWluQ29udHJhY3Rpb25FbmRfICE9IG90aGVyLm1fbWluQ29udHJhY3Rpb25FbmRfCiAgICAgICAgICAgICAgICAgIHx8IG1fbWluVW5zYWZlXyAhPSBvdGhlci5tX21pblVuc2FmZV8KICAgICAgICAgICAgICAgICAgfHwgbV90b3AzXyAhPSBvdGhlci5tX3RvcDNfCiAgICAgICAgICAgICAgICAgIHx8IG1fdG9wQ291bnQzXyAhPSBvdGhlci5tX3RvcENvdW50M18KICAgICAgICAgICAgICAgICAgfHwgIUFycmF5cy5lcXVhbHMobV91bnNhZmVfLCBvdGhlci5tX3Vuc2FmZV8pKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtX3RyaWVfLmVxdWFscyhvdGhlci5tX3RyaWVfKSkgewogICAgICAgICAgICAvLyB3ZSBzaG91bGQgdXNlIHRoZSB0cmllIGl0ZXJhdG9yIGhlcmUsIGJ1dCB0aGVuIHRoaXMgcGFydCBpcyAKICAgICAgICAgICAgLy8gb25seSB1c2VkIGluIHRoZSB0ZXN0LgogICAgICAgICAgICBmb3IgKGludCBpID0gVUNoYXJhY3Rlci5NQVhfVkFMVUU7IGkgPj0gVUNoYXJhY3Rlci5NSU5fVkFMVUU7IGkgLS0pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCB2ID0gbV90cmllXy5nZXRDb2RlUG9pbnRWYWx1ZShpKTsKICAgICAgICAgICAgICAgIGludCBvdGhlcnYgPSBvdGhlci5tX3RyaWVfLmdldENvZGVQb2ludFZhbHVlKGkpOwogICAgICAgICAgICAgICAgaWYgKHYgIT0gb3RoZXJ2KSB7CiAgICAgICAgICAgICAgICAgICAgaW50IG1hc2sgPSB2ICYgKENFX1RBR19NQVNLXyB8IENFX1NQRUNJQUxfRkxBR18pOwogICAgICAgICAgICAgICAgICAgIGlmIChtYXNrID09IChvdGhlcnYgJiAweGZmMDAwMDAwKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2ICY9IDB4ZmZmZmZmOyAKICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJ2ICY9IDB4ZmZmZmZmOyAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hc2sgPT0gMHhmMTAwMDAwMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdiAtPSAobV9leHBhbnNpb25PZmZzZXRfIDw8IDQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJ2IC09IChvdGhlci5tX2V4cGFuc2lvbk9mZnNldF8gPDwgNCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFzayA9PSAweGYyMDAwMDAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2IC09IG1fY29udHJhY3Rpb25PZmZzZXRfOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJ2IC09IG90aGVyLm1fY29udHJhY3Rpb25PZmZzZXRfOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID09IG90aGVydikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChBcnJheXMuZXF1YWxzKG1fY29udHJhY3Rpb25DRV8sIG90aGVyLm1fY29udHJhY3Rpb25DRV8pCiAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobV9jb250cmFjdGlvbkVuZF8sIG90aGVyLm1fY29udHJhY3Rpb25FbmRfKQogICAgICAgICAgICAmJiBBcnJheXMuZXF1YWxzKG1fY29udHJhY3Rpb25JbmRleF8sIG90aGVyLm1fY29udHJhY3Rpb25JbmRleF8pCiAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobV9leHBhbnNpb25fLCBvdGhlci5tX2V4cGFuc2lvbl8pCiAgICAgICAgICAgICYmIEFycmF5cy5lcXVhbHMobV9leHBhbnNpb25FbmRDRV8sIG90aGVyLm1fZXhwYW5zaW9uRW5kQ0VfKSkgewogICAgICAgICAgICAvLyBub3QgY29tcGFyaW5nIHBhZGRpbmdzCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbV9leHBhbnNpb25FbmRDRV8ubGVuZ3RoOyBpICsrKSB7CiAgICAgICAgICAgICAgICAgaWYgKG1fZXhwYW5zaW9uRW5kQ0VNYXhTaXplX1tpXSAKICAgICAgICAgICAgICAgICAgICAgIT0gb3RoZXIubV9leHBhbnNpb25FbmRDRU1heFNpemVfW2ldKSB7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgCgkvKioKICAgICAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBoYXNoIGNvZGUgZm9yIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBAcmV0dXJuIHRoZSB1bmlxdWUgaGFzaCBjb2RlIGZvciB0aGlzIENvbGxhdG9yCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgCiAgICB7CiAgICAgICAgU3RyaW5nIHJ1bGVzID0gZ2V0UnVsZXMoKTsKICAgICAgICBpZiAocnVsZXMgPT0gbnVsbCkgewogICAgICAgICAgICBydWxlcyA9ICIiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcnVsZXMuaGFzaENvZGUoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb21wYXJlcyB0aGUgc291cmNlIHRleHQgU3RyaW5nIHRvIHRoZSB0YXJnZXQgdGV4dCBTdHJpbmcgYWNjb3JkaW5nIHRvIAogICAgICogdGhlIGNvbGxhdGlvbiBydWxlcywgc3RyZW5ndGggYW5kIGRlY29tcG9zaXRpb24gbW9kZSBmb3IgdGhpcyAKICAgICAqIFJ1bGVCYXNlZENvbGxhdG9yLiAKICAgICAqIFJldHVybnMgYW4gaW50ZWdlciBsZXNzIHRoYW4sIAogICAgICogZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHplcm8gZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIHNvdXJjZSBTdHJpbmcgaXMgCiAgICAgKiBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgdGFyZ2V0IFN0cmluZy4gU2VlIHRoZSBDb2xsYXRvcgogICAgICogY2xhc3MgZGVzY3JpcHRpb24gZm9yIGFuIGV4YW1wbGUgb2YgdXNlLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBHZW5lcmFsIHJlY29tbWVuZGF0aW9uOiA8YnI+CiAgICAgKiBJZiBjb21wYXJpc29uIGFyZSB0byBiZSBkb25lIHRvIHRoZSBzYW1lIFN0cmluZyBtdWx0aXBsZSB0aW1lcywgaXQgd291bGQKICAgICAqIGJlIG1vcmUgZWZmaWNpZW50IHRvIGdlbmVyYXRlIENvbGxhdGlvbktleXMgZm9yIHRoZSBTdHJpbmdzIGFuZCB1c2UgCiAgICAgKiBDb2xsYXRpb25LZXkuY29tcGFyZVRvKENvbGxhdGlvbktleSkgZm9yIHRoZSBjb21wYXJpc29ucy4KICAgICAqIElmIHRoZSBlYWNoIFN0cmluZ3MgYXJlIGNvbXBhcmVkIHRvIG9ubHkgb25jZSwgdXNpbmcgdGhlIG1ldGhvZAogICAgICogUnVsZUJhc2VkQ29sbGF0b3IuY29tcGFyZShTdHJpbmcsIFN0cmluZykgd2lsbCBoYXZlIGEgYmV0dGVyIHBlcmZvcm1hbmNlLgogICAgICogPC9wPgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHRleHQgU3RyaW5nLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHRleHQgU3RyaW5nLgogICAgICogQHJldHVybiBSZXR1cm5zIGFuIGludGVnZXIgdmFsdWUuIFZhbHVlIGlzIGxlc3MgdGhhbiB6ZXJvIGlmIHNvdXJjZSBpcyAKICAgICAqICAgICAgICAgbGVzcyB0aGFuIHRhcmdldCwgdmFsdWUgaXMgemVybyBpZiBzb3VyY2UgYW5kIHRhcmdldCBhcmUgZXF1YWwsIAogICAgICogICAgICAgICB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gemVybyBpZiBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldC4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgICAgKiBAc2VlICNnZXRDb2xsYXRpb25LZXkKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgY29tcGFyZShTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0KQogICAgewogICAgCWlmIChzb3VyY2UgPT0gdGFyZ2V0KSB7CgkgICAgICAgIHJldHVybiAwOwoJICAgIH0KCQoJCS8vIEZpbmQgdGhlIGxlbmd0aCBvZiBhbnkgbGVhZGluZyBwb3J0aW9uIHRoYXQgaXMgZXF1YWwKCQlpbnQgb2Zmc2V0ID0gZ2V0Rmlyc3RVbm1hdGNoZWRPZmZzZXQoc291cmNlLCB0YXJnZXQpOwoJCWlmIChvZmZzZXQgPT0gc291cmNlLmxlbmd0aCgpKSB7CgkJCWlmIChvZmZzZXQgPT0gdGFyZ2V0Lmxlbmd0aCgpIHx8IGNoZWNrSWdub3JhYmxlKHRhcmdldCwgb2Zmc2V0KSkgewoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJcmV0dXJuIC0xOwoJICAgIH0KCSAgICBlbHNlIGlmICh0YXJnZXQubGVuZ3RoKCkgPT0gb2Zmc2V0KSB7CgkgICAgCWlmIChjaGVja0lnbm9yYWJsZShzb3VyY2UsIG9mZnNldCkpIHsKCSAgICAJCXJldHVybiAwOwoJICAgIAl9CgkgICAgCXJldHVybiAxOwoJICAgIH0KICAgICAgICAKICAgICAgICAvL3JldHVybiBjb21wYXJlUmVndWxhcihzb3VyY2UsIHRhcmdldCwgb2Zmc2V0KTsKICAgICAgICBpZihsYXRpbk9uZVVzZV8pIHsKICAgICAgICAgIGlmIChzb3VyY2UuY2hhckF0KG9mZnNldCkgPiBFTkRPRkxBVElOT05FUkFOR0VfIHx8IHRhcmdldC5jaGFyQXQob2Zmc2V0KSA+IEVORE9GTEFUSU5PTkVSQU5HRV8pIHsgLy8gc291cmNlIG9yIHRhcmdldCBzdGFydCB3aXRoIG5vbi1sYXRpbi0xCiAgICAgICAgICAgIHJldHVybiBjb21wYXJlUmVndWxhcihzb3VyY2UsIHRhcmdldCwgb2Zmc2V0KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBjb21wYXJlVXNlTGF0aW4xKHNvdXJjZSwgdGFyZ2V0LCBvZmZzZXQpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY29tcGFyZVJlZ3VsYXIoc291cmNlLCB0YXJnZXQsIG9mZnNldCk7CiAgICAgICAgfSAgICAgICAgCiAgICB9CgogICAgLy8gcGFja2FnZSBwcml2YXRlIGlubmVyIGludGVyZmFjZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCgkgKiBBdHRyaWJ1dGUgdmFsdWVzIHRvIGJlIHVzZWQgd2hlbiBzZXR0aW5nIHRoZSBDb2xsYXRvciBvcHRpb25zCgkgKi8KCXN0YXRpYyBpbnRlcmZhY2UgQXR0cmlidXRlVmFsdWUKCXsKCQkvKioKCQkgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBhdHRyaWJ1dGUgdmFsdWUgd2lsbCBiZSB1c2VkLiAKCQkgKiBTZWUgaW5kaXZpZHVhbCBhdHRyaWJ1dGUgZm9yIGRldGFpbHMgb24gaXRzIGRlZmF1bHQgdmFsdWUuIAoJCSAqLwoJCXN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF8gPSAtMTsKCQkvKiogCgkJICogUHJpbWFyeSBjb2xsYXRpb24gc3RyZW5ndGggCgkJICovCgkJc3RhdGljIGZpbmFsIGludCBQUklNQVJZXyA9IENvbGxhdG9yLlBSSU1BUlk7CgkJLyoqIAoJCSAqIFNlY29uZGFyeSBjb2xsYXRpb24gc3RyZW5ndGggCgkJICovCgkJc3RhdGljIGZpbmFsIGludCBTRUNPTkRBUllfID0gQ29sbGF0b3IuU0VDT05EQVJZOwoJCS8qKiAKCQkgKiBUZXJ0aWFyeSBjb2xsYXRpb24gc3RyZW5ndGggCgkJICovCgkJc3RhdGljIGZpbmFsIGludCBURVJUSUFSWV8gPSBDb2xsYXRvci5URVJUSUFSWTsKCQkvKiogCgkJICogRGVmYXVsdCBjb2xsYXRpb24gc3RyZW5ndGggCgkJICovCgkJc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NUUkVOR1RIXyA9IENvbGxhdG9yLlRFUlRJQVJZOwoJCS8qKgoJCSAqIEludGVybmFsIHVzZSBmb3Igc3RyZW5ndGggY2hlY2tzIGluIENvbGxhdGlvbiBlbGVtZW50cwoJCSAqLwoJCXN0YXRpYyBmaW5hbCBpbnQgQ0VfU1RSRU5HVEhfTElNSVRfID0gQ29sbGF0b3IuVEVSVElBUlkgKyAxOwoJCS8qKiAKCQkgKiBRdWF0ZXJuYXJ5IGNvbGxhdGlvbiBzdHJlbmd0aCAKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IFFVQVRFUk5BUllfID0gMzsKCQkvKiogCgkJICogSWRlbnRpY2FsIGNvbGxhdGlvbiBzdHJlbmd0aCAKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IElERU5USUNBTF8gPSBDb2xsYXRvci5JREVOVElDQUw7CgkJLyoqCgkJICogSW50ZXJuYWwgdXNlIGZvciBzdHJlbmd0aCBjaGVja3MKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IFNUUkVOR1RIX0xJTUlUXyA9IENvbGxhdG9yLklERU5USUNBTCArIDE7CgkJLyoqIAoJCSAqIFR1cm4gdGhlIGZlYXR1cmUgb2ZmIC0gd29ya3MgZm9yIEZSRU5DSF9DT0xMQVRJT04sIENBU0VfTEVWRUwsIAoJCSAqIEhJUkFHQU5BX1FVQVRFUk5BUllfTU9ERSBhbmQgREVDT01QT1NJVElPTl9NT0RFCgkJICovCgkJc3RhdGljIGZpbmFsIGludCBPRkZfID0gMTY7CgkJLyoqIAoJCSAqIFR1cm4gdGhlIGZlYXR1cmUgb24gLSB3b3JrcyBmb3IgRlJFTkNIX0NPTExBVElPTiwgQ0FTRV9MRVZFTCwgCgkJICogSElSQUdBTkFfUVVBVEVSTkFSWV9NT0RFIGFuZCBERUNPTVBPU0lUSU9OX01PREUKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IE9OXyA9IDE3OwoJCS8qKiAKCQkgKiBWYWxpZCBmb3IgQUxURVJOQVRFX0hBTkRMSU5HLiBBbHRlcm5hdGUgaGFuZGxpbmcgd2lsbCBiZSBzaGlmdGVkIAoJCSAqLwoJCXN0YXRpYyBmaW5hbCBpbnQgU0hJRlRFRF8gPSAyMDsKCQkvKiogCgkJICogVmFsaWQgZm9yIEFMVEVSTkFURV9IQU5ETElORy4gQWx0ZXJuYXRlIGhhbmRsaW5nIHdpbGwgYmUgbm9uIAoJCSAqIGlnbm9yYWJsZSAKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IE5PTl9JR05PUkFCTEVfID0gMjE7CgkJLyoqIAoJCSAqIFZhbGlkIGZvciBDQVNFX0ZJUlNUIC0gbG93ZXIgY2FzZSBzb3J0cyBiZWZvcmUgdXBwZXIgY2FzZSAKCQkgKi8KCQlzdGF0aWMgZmluYWwgaW50IExPV0VSX0ZJUlNUXyA9IDI0OwoJCS8qKiAKCQkgKiBVcHBlciBjYXNlIHNvcnRzIGJlZm9yZSBsb3dlciBjYXNlIAoJCSAqLwoJCXN0YXRpYyBmaW5hbCBpbnQgVVBQRVJfRklSU1RfID0gMjU7CgkgICAgLyoqCgkJICogTnVtYmVyIG9mIGF0dHJpYnV0ZSB2YWx1ZXMKCQkgKi8KCSAgICBzdGF0aWMgZmluYWwgaW50IExJTUlUXyA9IDI5OwoJfTsKCSAgICAKCS8qKiAKCSAqIEF0dHJpYnV0ZXMgdGhhdCBjb2xsYXRpb24gc2VydmljZSB1bmRlcnN0YW5kcy4gQWxsIHRoZSBhdHRyaWJ1dGVzIGNhbiAKCSAqIHRha2UgREVGQVVMVCB2YWx1ZSwgYXMgd2VsbCBhcyB0aGUgdmFsdWVzIHNwZWNpZmljIHRvIGVhY2ggb25lLiAKCSAqLwoJc3RhdGljIGludGVyZmFjZSBBdHRyaWJ1dGUgCgl7CgkgICAgLyoqIAoJICAgICAqIEF0dHJpYnV0ZSBmb3IgZGlyZWN0aW9uIG9mIHNlY29uZGFyeSB3ZWlnaHRzIC0gdXNlZCBpbiBGcmVuY2guCgkgICAgICogQWNjZXB0YWJsZSB2YWx1ZXMgYXJlIE9OLCB3aGljaCByZXN1bHRzIGluIHNlY29uZGFyeSB3ZWlnaHRzIGJlaW5nIAoJICAgICAqIGNvbnNpZGVyZWQgYmFja3dhcmRzIGFuZCBPRkYgd2hpY2ggdHJlYXRzIHNlY29uZGFyeSB3ZWlnaHRzIGluIHRoZSAKCSAgICAgKiBvcmRlciB0aGV5IGFwcGVhci4KCSAgICAgKi8KICAgIAlzdGF0aWMgZmluYWwgaW50IEZSRU5DSF9DT0xMQVRJT05fID0gMDsgCgkgICAgLyoqIAoJICAgICAqIEF0dHJpYnV0ZSBmb3IgaGFuZGxpbmcgdmFyaWFibGUgZWxlbWVudHMuIEFjY2VwdGFibGUgdmFsdWVzIGFyZSAKCSAgICAgKiBOT05fSUdOT1JBQkxFIChkZWZhdWx0KSB3aGljaCB0cmVhdHMgYWxsIHRoZSBjb2RlcG9pbnRzIHdpdGggCgkgICAgICogbm9uLWlnbm9yYWJsZSBwcmltYXJ5IHdlaWdodHMgaW4gdGhlIHNhbWUgd2F5LCBhbmQgU0hJRlRFRCB3aGljaCAKCSAgICAgKiBjYXVzZXMgY29kZXBvaW50cyB3aXRoIHByaW1hcnkgd2VpZ2h0cyB0aGF0IGFyZSBlcXVhbCBvciBiZWxvdyB0aGUgCgkgICAgICogdmFyaWFibGUgdG9wIHZhbHVlIHRvIGJlIGlnbm9yZWQgb24gcHJpbWFyeSBsZXZlbCBhbmQgbW92ZWQgdG8gdGhlIAoJICAgICAqIHF1YXRlcm5hcnkgbGV2ZWwuCgkgICAgICovCgkgICAgc3RhdGljIGZpbmFsIGludCBBTFRFUk5BVEVfSEFORExJTkdfID0gMTsKCSAgICAvKiogCgkgICAgICogQ29udHJvbHMgdGhlIG9yZGVyaW5nIG9mIHVwcGVyIGFuZCBsb3dlciBjYXNlIGxldHRlcnMuIEFjY2VwdGFibGUgCgkgICAgICogdmFsdWVzIGFyZSBPRkYgKGRlZmF1bHQpLCB3aGljaCBvcmRlcnMgdXBwZXIgYW5kIGxvd2VyIGNhc2UgbGV0dGVycyAKCSAgICAgKiBpbiBhY2NvcmRhbmNlIHRvIHRoZWlyIHRlcnRpYXJ5IHdlaWdodHMsIFVQUEVSX0ZJUlNUIHdoaWNoIGZvcmNlcyAKCSAgICAgKiB1cHBlciBjYXNlIGxldHRlcnMgdG8gc29ydCBiZWZvcmUgbG93ZXIgY2FzZSBsZXR0ZXJzLCBhbmQgCgkgICAgICogTE9XRVJfRklSU1Qgd2hpY2ggZG9lcyB0aGUgb3Bwb3NpdGUuIAoJICAgICAqLwoJICAgIHN0YXRpYyBmaW5hbCBpbnQgQ0FTRV9GSVJTVF8gPSAyOwoJICAgIC8qKiAKCSAgICAgKiBDb250cm9scyB3aGV0aGVyIGFuIGV4dHJhIGNhc2UgbGV2ZWwgKHBvc2l0aW9uZWQgYmVmb3JlIHRoZSB0aGlyZCAKCSAgICAgKiBsZXZlbCkgaXMgZ2VuZXJhdGVkIG9yIG5vdC4gQWNjZXB0YWJsZSB2YWx1ZXMgYXJlIE9GRiAoZGVmYXVsdCksCgkgICAgICogd2hlbiBjYXNlIGxldmVsIGlzIG5vdCBnZW5lcmF0ZWQsIGFuZCBPTiB3aGljaCBjYXVzZXMgdGhlIGNhc2UKCSAgICAgKiBsZXZlbCB0byBiZSBnZW5lcmF0ZWQuIENvbnRlbnRzIG9mIHRoZSBjYXNlIGxldmVsIGFyZSBhZmZlY3RlZCBieQoJICAgICAqIHRoZSB2YWx1ZSBvZiBDQVNFX0ZJUlNUIGF0dHJpYnV0ZS4gQSBzaW1wbGUgd2F5IHRvIGlnbm9yZSBhY2NlbnQgCgkgICAgICogZGlmZmVyZW5jZXMgaW4gYSBzdHJpbmcgaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCB0byBQUklNQVJZIGFuZCAKCSAgICAgKiBlbmFibGUgY2FzZSBsZXZlbC4gCgkgICAgICovCgkgICAgc3RhdGljIGZpbmFsIGludCBDQVNFX0xFVkVMXyA9IDM7CgkgICAgLyoqIAoJICAgICAqIENvbnRyb2xzIHdoZXRoZXIgdGhlIG5vcm1hbGl6YXRpb24gY2hlY2sgYW5kIG5lY2Vzc2FyeSAKCSAgICAgKiBub3JtYWxpemF0aW9ucyBhcmUgcGVyZm9ybWVkLiBXaGVuIHNldCB0byBPRkYgKGRlZmF1bHQpIG5vIAoJICAgICAqIG5vcm1hbGl6YXRpb24gY2hlY2sgaXMgcGVyZm9ybWVkLiBUaGUgY29ycmVjdG5lc3Mgb2YgdGhlIHJlc3VsdCBpcyAKCSAgICAgKiBndWFyYW50ZWVkIG9ubHkgaWYgdGhlIGlucHV0IGRhdGEgaXMgaW4gc28tY2FsbGVkIEZDRCBmb3JtIChzZWUgCgkgICAgICogdXNlcnMgbWFudWFsIGZvciBtb3JlIGluZm8pLiBXaGVuIHNldCB0byBPTiwgYW4gaW5jcmVtZW50YWwgY2hlY2sgCgkgICAgICogaXMgcGVyZm9ybWVkIHRvIHNlZSB3aGV0aGVyIHRoZSBpbnB1dCBkYXRhIGlzIGluIHRoZSBGQ0QgZm9ybS4gSWYgCgkgICAgICogdGhlIGRhdGEgaXMgbm90IGluIHRoZSBGQ0QgZm9ybSwgaW5jcmVtZW50YWwgTkZEIG5vcm1hbGl6YXRpb24gaXMgCgkgICAgICogcGVyZm9ybWVkLiAKCSAgICAgKi8KCSAgICBzdGF0aWMgZmluYWwgaW50IE5PUk1BTElaQVRJT05fTU9ERV8gPSA0OyAKCSAgICAvKiogCgkgICAgICogVGhlIHN0cmVuZ3RoIGF0dHJpYnV0ZS4gQ2FuIGJlIGVpdGhlciBQUklNQVJZLCBTRUNPTkRBUlksIFRFUlRJQVJZLCAKCSAgICAgKiBRVUFURVJOQVJZIG9yIElERU5USUNBTC4gVGhlIHVzdWFsIHN0cmVuZ3RoIGZvciBtb3N0IGxvY2FsZXMgCgkgICAgICogKGV4Y2VwdCBKYXBhbmVzZSkgaXMgdGVydGlhcnkuIFF1YXRlcm5hcnkgc3RyZW5ndGggaXMgdXNlZnVsIHdoZW4gCgkgICAgICogY29tYmluZWQgd2l0aCBzaGlmdGVkIHNldHRpbmcgZm9yIGFsdGVybmF0ZSBoYW5kbGluZyBhdHRyaWJ1dGUgYW5kIAoJICAgICAqIGZvciBKSVMgeCA0MDYxIGNvbGxhdGlvbiwgd2hlbiBpdCBpcyB1c2VkIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gCgkgICAgICogS2F0YWthbmEgIGFuZCBIaXJhZ2FuYSAodGhpcyBpcyBhY2hpZXZlZCBieSBzZXR0aW5nIHRoZSAKCSAgICAgKiBISVJBR0FOQV9RVUFURVJOQVJZIG1vZGUgdG8gb24uIE90aGVyd2lzZSwgcXVhdGVybmFyeSBsZXZlbCBpcyAKICAgICAgICAgKiBhZmZlY3RlZCBvbmx5IGJ5IHRoZSBudW1iZXIgb2Ygbm9uIGlnbm9yYWJsZSBjb2RlIHBvaW50cyBpbiB0aGUgCgkgICAgICogc3RyaW5nLiBJZGVudGljYWwgc3RyZW5ndGggaXMgcmFyZWx5IHVzZWZ1bCwgYXMgaXQgYW1vdW50cyB0byAKCSAgICAgKiBjb2RlcG9pbnRzIG9mIHRoZSBORkQgZm9ybSBvZiB0aGUgc3RyaW5nLiAKCSAgICAgKi8KCSAgICBzdGF0aWMgZmluYWwgaW50IFNUUkVOR1RIXyA9IDU7CgkgICAgLyoqIAoJICAgICAqIFdoZW4gdHVybmVkIG9uLCB0aGlzIGF0dHJpYnV0ZSBwb3NpdGlvbnMgSGlyYWdhbmEgYmVmb3JlIGFsbCAgCgkgICAgICogbm9uLWlnbm9yYWJsZXMgb24gcXVhdGVybmFyeSBsZXZlbC4gVGhpcyBpcyBhIHNuZWFreSB3YXkgdG8gcHJvZHVjZSAKCSAgICAgKiBKSVMgc29ydCBvcmRlci4gCgkgICAgICovICAgICAKCSAgICBzdGF0aWMgZmluYWwgaW50IEhJUkFHQU5BX1FVQVRFUk5BUllfTU9ERV8gPSA2OwogICAgICAgIC8qKgoJICAgICAqIEF0dHJpYnV0ZSBjb3VudAoJICAgICAqLwoJICAgIHN0YXRpYyBmaW5hbCBpbnQgTElNSVRfID0gNzsKCX07CgkKCS8qKgogICAgICogRGF0YU1hbmlwdWxhdGUgc2luZ2xldG9uCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBEYXRhTWFuaXB1bGF0ZSBpbXBsZW1lbnRzIFRyaWUuRGF0YU1hbmlwdWxhdGUKICAgIHsKICAgIAkvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAJCiAgICAJLyoqCgkgICAgICogSW50ZXJuYWwgbWV0aG9kIGNhbGxlZCB0byBwYXJzZSBhIGxlYWQgc3Vycm9nYXRlJ3MgY2UgZm9yIHRoZSBvZmZzZXQKCSAgICAgKiB0byB0aGUgbmV4dCB0cmFpbCBzdXJyb2dhdGUgZGF0YS4KCSAgICAgKiBAcGFyYW0gY2UgY29sbGF0aW9uIGVsZW1lbnQgb2YgdGhlIGxlYWQgc3Vycm9nYXRlCgkgICAgICogQHJldHVybiBkYXRhIG9mZnNldCBvciAwIGZvciB0aGUgbmV4dCB0cmFpbCBzdXJyb2dhdGUKCSAgICAgKiBAZHJhZnQgMi4yCgkgICAgICovCgkgICAgcHVibGljIGZpbmFsIGludCBnZXRGb2xkaW5nT2Zmc2V0KGludCBjZSkKCSAgICB7CgkgICAgCWlmIChpc1NwZWNpYWwoY2UpICYmIGdldFRhZyhjZSkgPT0gQ0VfU1VSUk9HQVRFX1RBR18pIHsKCSAgICAJCXJldHVybiAoY2UgJiAweEZGRkZGRik7CgkgICAgCX0KCSAgICAJcmV0dXJuIDA7CgkgICAgfSAKCSAgICAKCSAgICAvKioKCSAgICAgKiBHZXQgc2luZ2xldG9uIG9iamVjdAoJICAgICAqLwoJICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgRGF0YU1hbmlwdWxhdGUgZ2V0SW5zdGFuY2UoKQoJICAgIHsKCSAgICAJaWYgKG1faW5zdGFuY2VfID09IG51bGwpIHsKCSAgICAJCW1faW5zdGFuY2VfID0gIG5ldyBEYXRhTWFuaXB1bGF0ZSgpOwoJICAgIAl9CgkgICAgCXJldHVybiBtX2luc3RhbmNlXzsKCSAgICB9CgkgICAgCgkgICAgLy8gcHJpdmF0ZSBkYXRhIG1lbWJlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkgICAgCgkgICAgLyoqCgkgICAgICogU2luZ2xldG9uIGluc3RhbmNlCgkgICAgICovCgkgICAgcHJpdmF0ZSBzdGF0aWMgRGF0YU1hbmlwdWxhdGUgbV9pbnN0YW5jZV87CgkgICAgCgkgICAgLy8gcHJpdmF0ZSBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkgICAgCgkgICAgLyoqCgkgICAgICogcHJpdmF0ZSB0byBwcmV2ZW50IGluaXRpYWxpemF0aW9uCgkgICAgICovCgkgICAgcHJpdmF0ZSBEYXRhTWFuaXB1bGF0ZSgpCgkgICAgewoJICAgIH0KICAgIH07CiAgICAKICAgIC8qKgogICAgICogVUNBQ29uc3RhbnRzCiAgICAgKi8KICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBVQ0FDb25zdGFudHMKICAgIHsKICAgICAgICAgaW50IEZJUlNUX1RFUlRJQVJZX0lHTk9SQUJMRV9bXSA9IG5ldyBpbnRbMl07ICAgICAgIC8vIDB4MDAwMDAwMDAgCiAgICAgICAgIGludCBMQVNUX1RFUlRJQVJZX0lHTk9SQUJMRV9bXSA9IG5ldyBpbnRbMl07ICAgICAgICAvLyAweDAwMDAwMDAwIAogICAgICAgICBpbnQgRklSU1RfUFJJTUFSWV9JR05PUkFCTEVfW10gPSBuZXcgaW50WzJdOyAgICAgICAgLy8gMHgwMDAwODcwNSAKICAgICAgICAgaW50IEZJUlNUX1NFQ09OREFSWV9JR05PUkFCTEVfW10gPSBuZXcgaW50WzJdOyAgICAgIC8vIDB4MDAwMDAwMDAgCiAgICAgICAgIGludCBMQVNUX1NFQ09OREFSWV9JR05PUkFCTEVfW10gPSBuZXcgaW50WzJdOyAgICAgICAvLyAweDAwMDAwNTAwIAogICAgICAgICBpbnQgTEFTVF9QUklNQVJZX0lHTk9SQUJMRV9bXSA9IG5ldyBpbnRbMl07ICAgICAgICAgLy8gMHgwMDAwREQwNSAKICAgICAgICAgaW50IEZJUlNUX1ZBUklBQkxFX1tdID0gbmV3IGludFsyXTsgICAgICAgICAgICAgICAgIC8vIDB4MDUwNzA1MDUgCiAgICAgICAgIGludCBMQVNUX1ZBUklBQkxFX1tdID0gbmV3IGludFsyXTsgICAgICAgICAgICAgICAgICAvLyAweDEzQ0YwNTA1IAogICAgICAgICBpbnQgRklSU1RfTk9OX1ZBUklBQkxFX1tdID0gbmV3IGludFsyXTsgICAgICAgICAgICAgLy8gMHgxNjIwMDUwNSAKICAgICAgICAgaW50IExBU1RfTk9OX1ZBUklBQkxFX1tdID0gbmV3IGludFsyXTsgICAgICAgICAgICAgIC8vIDB4NzY3QzA1MDUgCiAgICAgICAgIGludCBSRVNFVF9UT1BfVkFMVUVfW10gPSBuZXcgaW50WzJdOyAgICAgICAgICAgICAgICAvLyAweDlGMDAwMzAzIAogICAgICAgICBpbnQgRklSU1RfSU1QTElDSVRfW10gPSBuZXcgaW50WzJdOyAKICAgICAgICAgaW50IExBU1RfSU1QTElDSVRfW10gPSBuZXcgaW50WzJdOyAgCiAgICAgICAgIGludCBGSVJTVF9UUkFJTElOR19bXSA9IG5ldyBpbnRbMl07IAogICAgICAgICBpbnQgTEFTVF9UUkFJTElOR19bXSA9IG5ldyBpbnRbMl07ICAKICAgICAgICAgaW50IFBSSU1BUllfVE9QX01JTl87IAogICAgICAgICBpbnQgUFJJTUFSWV9JTVBMSUNJVF9NSU5fOyAvLyAweEU4MDAwMDAwIAogICAgICAgICBpbnQgUFJJTUFSWV9JTVBMSUNJVF9NQVhfOyAvLyAweEYwMDAwMDAwIAogICAgICAgICBpbnQgUFJJTUFSWV9UUkFJTElOR19NSU5fOyAvLyAweEU4MDAwMDAwIAogICAgICAgICBpbnQgUFJJTUFSWV9UUkFJTElOR19NQVhfOyAvLyAweEYwMDAwMDAwIAogICAgICAgICBpbnQgUFJJTUFSWV9TUEVDSUFMX01JTl87IC8vIDB4RTgwMDAwMDAgCiAgICAgICAgIGludCBQUklNQVJZX1NQRUNJQUxfTUFYXzsgLy8gMHhGMDAwMDAwMCAKICAgIH0KICAgIAogICAgLy8gcGFja2FnZSBwcml2YXRlIGRhdGEgbWVtYmVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9GSVJTVF9UQUlMT1JFRF8gPSAoYnl0ZSkweDA0OwogICAgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9DT01NT05fID0gKGJ5dGUpMHgwNTsKICAgIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX1RPUF8yXyA9IDB4ODY7IC8vIGludCBmb3IgdW5zaWduZXNzCiAgICBzdGF0aWMgZmluYWwgaW50IENPTU1PTl9CT1RUT01fMl8gPSBCWVRFX0NPTU1PTl87CiAgICAvKioKCSAqIENhc2Ugc3RyZW5ndGggbWFzawoJICovCglzdGF0aWMgZmluYWwgaW50IENFX0NBU0VfQklUX01BU0tfID0gMHhDMDsKCXN0YXRpYyBmaW5hbCBpbnQgQ0VfVEFHX1NISUZUXyA9IDI0OwoJc3RhdGljIGZpbmFsIGludCBDRV9UQUdfTUFTS18gPSAweDBGMDAwMDAwOwoJCglzdGF0aWMgZmluYWwgaW50IENFX1NQRUNJQUxfRkxBR18gPSAweEYwMDAwMDAwOwogICAgLyoqIAogICAgICogTGVhZCBzdXJyb2dhdGUgdGhhdCBpcyB0YWlsb3JlZCBhbmQgZG9lc24ndCBzdGFydCBhIGNvbnRyYWN0aW9uIAogICAgICovCiAgICBzdGF0aWMgZmluYWwgaW50IENFX1NVUlJPR0FURV9UQUdfID0gNTsgIAoJLyoqCiAgCSAqIE1hc2sgdG8gZ2V0IHRoZSBwcmltYXJ5IHN0cmVuZ3RoIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudAogIAkgKi8KICAJc3RhdGljIGZpbmFsIGludCBDRV9QUklNQVJZX01BU0tfID0gMHhGRkZGMDAwMDsKICAJLyoqCiAgCSAqIE1hc2sgdG8gZ2V0IHRoZSBzZWNvbmRhcnkgc3RyZW5ndGggb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50CiAgCSAqLwogICAJc3RhdGljIGZpbmFsIGludCBDRV9TRUNPTkRBUllfTUFTS18gPSAweEZGMDA7CiAgIAkvKioKICAJICogTWFzayB0byBnZXQgdGhlIHRlcnRpYXJ5IHN0cmVuZ3RoIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudAogIAkgKi8KICAgCXN0YXRpYyBmaW5hbCBpbnQgQ0VfVEVSVElBUllfTUFTS18gPSAweEZGOwogICAJLyoqCiAgIAkgKiBQcmltYXJ5IHN0cmVuZ3RoIHNoaWZ0IAogICAJICovCglzdGF0aWMgZmluYWwgaW50IENFX1BSSU1BUllfU0hJRlRfID0gMTY7CgkvKiogCgkgKiBTZWNvbmRhcnkgc3RyZW5ndGggc2hpZnQgCgkgKi8KCXN0YXRpYyBmaW5hbCBpbnQgQ0VfU0VDT05EQVJZX1NISUZUXyA9IDg7CiAgIAkvKioKICAgCSAqIENvbnRpbnVhdGlvbiBtYXJrZXIKICAgCSAqLwogICAJc3RhdGljIGZpbmFsIGludCBDRV9DT05USU5VQVRJT05fTUFSS0VSXyA9IDB4QzA7CiAgIAkKICAgCS8qKgoJICogU2l6ZSBvZiBjb2xsYXRvciByYXcgZGF0YSBoZWFkZXJzIGFuZCBvcHRpb25zIGJlZm9yZSB0aGUgZXhwYW5zaW9uCgkgKiBkYXRhLiBUaGlzIGlzIHVzZWQgd2hlbiBleHBhbnNpb24gY2VzIGFyZSB0byBiZSByZXRyaWV2ZWQuIElDVTRDIHVzZXMKCSAqIHRoZSBleHBhbnNpb24gb2Zmc2V0IHN0YXJ0aW5nIGZyb20gVUNvbGxhdG9yLlVDb2xIZWFkZXIsIGhlbmNlIElDVTRKCgkgKiB3aWxsIGhhdmUgdG8gbWludXMgdGhhdCBvZmYgdG8gZ2V0IHRoZSByaWdodCBleHBhbnNpb24gY2Ugb2Zmc2V0LiBJbgoJICogbnVtYmVyIG9mIGludHMuCgkgKi8KCWludCBtX2V4cGFuc2lvbk9mZnNldF87CgkvKioKCSAqIFNpemUgb2YgY29sbGF0b3IgcmF3IGRhdGEgaGVhZGVycywgb3B0aW9ucyBhbmQgZXhwYW5zaW9ucyBiZWZvcmUKCSAqIGNvbnRyYWN0aW9uIGRhdGEuIFRoaXMgaXMgdXNlZCB3aGVuIGNvbnRyYWN0aW9uIGNlcyBhcmUgdG8gYmUgcmV0cmlldmVkLiAKCSAqIElDVTRDIHVzZXMgY29udHJhY3Rpb24gb2Zmc2V0IHN0YXJ0aW5nIGZyb20gVUNvbGxhdG9yLlVDb2xIZWFkZXIsIGhlbmNlCgkgKiBJQ1U0SiB3aWxsIGhhdmUgdG8gbWludXMgdGhhdCBvZmYgdG8gZ2V0IHRoZSByaWdodCBjb250cmFjdGlvbiBjZSAKCSAqIG9mZnNldC4gSW4gbnVtYmVyIG9mIGNoYXJzLgoJICovCglpbnQgbV9jb250cmFjdGlvbk9mZnNldF87CiAgICAvKioKICAgICAqIEZsYWcgaW5kaWNhdG9yIGlmIEphbW8gaXMgc3BlY2lhbAogICAgICovCiAgICBib29sZWFuIG1faXNKYW1vU3BlY2lhbF87CiAKIAkvLyBDb2xsYXRvciBvcHRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIAogCWludCBtX2RlZmF1bHRWYXJpYWJsZVRvcFZhbHVlXzsKCWJvb2xlYW4gbV9kZWZhdWx0SXNGcmVuY2hDb2xsYXRpb25fOwoJYm9vbGVhbiBtX2RlZmF1bHRJc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF87IAogICAgaW50IG1fZGVmYXVsdENhc2VGaXJzdF87CiAgICBib29sZWFuIG1fZGVmYXVsdElzQ2FzZUxldmVsXzsKICAgIGludCBtX2RlZmF1bHREZWNvbXBvc2l0aW9uXzsKICAgIGludCBtX2RlZmF1bHRTdHJlbmd0aF87CiAgICBib29sZWFuIG1fZGVmYXVsdElzSGlyYWdhbmE0XzsKIAkvKioKIAkgKiBWYWx1ZSBvZiB0aGUgdmFyaWFibGUgdG9wCiAJICovCiAgICBpbnQgbV92YXJpYWJsZVRvcFZhbHVlXzsKICAgIC8qKiAKICAgICAqIEF0dHJpYnV0ZSBmb3Igc3BlY2lhbCBIaXJhZ2FuYSAKICAgICAqLwogICAgYm9vbGVhbiBtX2lzSGlyYWdhbmE0XzsgICAgICAgICAKCS8qKgogICAgICogQ2FzZSBzb3J0aW5nIGN1c3RvbWl6YXRpb24KICAgICAqLwogICAgaW50IG1fY2FzZUZpcnN0XzsKICAgIAogICAgLy8gZW5kIENvbGxhdG9yIG9wdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgIAogICAgLyoqCiAgICAgKiBFeHBhbnNpb24gdGFibGUKICAgICAqLwogICAgaW50IG1fZXhwYW5zaW9uX1tdOwogICAgLyoqCiAgICAgKiBDb250cmFjdGlvbiBpbmRleCB0YWJsZQogICAgICovCiAgICBjaGFyIG1fY29udHJhY3Rpb25JbmRleF9bXTsKICAgIC8qKgogICAgICogQ29udHJhY3Rpb24gQ0UgdGFibGUKICAgICAqLwogICAgaW50IG1fY29udHJhY3Rpb25DRV9bXTsKICAgIC8qKgogICAgICogRGF0YSB0cmllCiAgICAgKi8KICAgIEludFRyaWUgbV90cmllXzsKICAgIC8qKgogICAgICogVGFibGUgdG8gc3RvcmUgYWxsIGNvbGxhdGlvbiBlbGVtZW50cyB0aGF0IGFyZSB0aGUgbGFzdCBlbGVtZW50IG9mIGFuCiAgICAgKiBleHBhbnNpb24uIFRoaXMgaXMgZm9yIHVzZSBpbiBTdHJpbmdTZWFyY2guCiAgICAgKi8KICAgIGludCBtX2V4cGFuc2lvbkVuZENFX1tdOwogICAgLyoqCiAgICAgKiBUYWJsZSB0byBzdG9yZSB0aGUgbWF4aW11bSBzaXplIG9mIGFueSBleHBhbnNpb25zIHRoYXQgZW5kIHdpdGggdGhlIAogICAgICogY29ycmVzcG9uZGluZyBjb2xsYXRpb24gZWxlbWVudCBpbiBtX2V4cGFuc2lvbkVuZENFXy4gRm9yIHVzZSBpbgogICAgICogU3RyaW5nU2VhcmNoIHRvbwogICAgICovCiAgICBieXRlIG1fZXhwYW5zaW9uRW5kQ0VNYXhTaXplX1tdOwogICAgLyoqCiAgICAgKiBIZXVyaXN0aWMgdGFibGUgdG8gc3RvcmUgaW5mb3JtYXRpb24gb24gd2hldGhlciBhIGNoYXIgY2hhcmFjdGVyIGlzIAogICAgICogY29uc2lkZXJlZCAidW5zYWZlIi4gIlVuc2FmZSIgY2hhcmFjdGVyIGFyZSBjb21iaW5pbmcgbWFya3Mgb3IgdGhvc2UgCiAgICAgKiBiZWxvbmdpbmcgdG8gc29tZSBjb250cmFjdGlvbiBzZXF1ZW5jZSBmcm9tIHRoZSBvZmZzZXQgMSBvbndhcmRzLiAKICAgICAqIEUuZy4gaWYgIkFCQyIgaXMgdGhlIG9ubHkgY29udHJhY3Rpb24sIHRoZW4gJ0InIGFuZCAnQycgYXJlIGNvbnNpZGVyZWQgCiAgICAgKiB1bnNhZmUuIElmIHdlIGhhdmUgYW5vdGhlciBjb250cmFjdGlvbiAiWkEiIHdpdGggdGhlIG9uZSBhYm92ZSwgdGhlbiAKICAgICAqICdBJywgJ0InLCAnQycgYXJlICJ1bnNhZmUiIGJ1dCAnWicgaXMgbm90LiAKICAgICAqLwogICAgYnl0ZSBtX3Vuc2FmZV9bXTsKICAgIC8qKgogICAgICogVGFibGUgdG8gc3RvcmUgaW5mb3JtYXRpb24gb24gd2hldGhlciBhIGNvZGVwb2ludCBjYW4gb2NjdXIgYXMgdGhlIGxhc3QKICAgICAqIGNoYXJhY3RlciBpbiBhIGNvbnRyYWN0aW9uCiAgICAgKi8KICAgIGJ5dGUgbV9jb250cmFjdGlvbkVuZF9bXTsKICAgIC8qKgoJICogT3JpZ2luYWwgY29sbGF0aW9uIHJ1bGVzCgkgKi8KCVN0cmluZyBtX3J1bGVzXzsKCS8qKgogICAgICogVGhlIHNtYWxsZXN0ICJ1bnNhZmUiIGNvZGVwb2ludAogICAgICovCiAgICBjaGFyIG1fbWluVW5zYWZlXzsKICAgIC8qKgoJICogVGhlIHNtYWxsZXN0IGNvZGVwb2ludCB0aGF0IGNvdWxkIGJlIHRoZSBlbmQgb2YgYSBjb250cmFjdGlvbgoJICovCgljaGFyIG1fbWluQ29udHJhY3Rpb25FbmRfOwoJCgkvKioKICAgICAqIFVuaWNvZGVEYXRhLnR4dCBwcm9wZXJ0eSBvYmplY3QKICAgICAqLwogICAgc3RhdGljIGZpbmFsIFJ1bGVCYXNlZENvbGxhdG9yIFVDQV87ICAKICAgIC8qKgogICAgICogVUNBIENvbnN0YW50cwogICAgICovCiAgICBzdGF0aWMgZmluYWwgVUNBQ29uc3RhbnRzIFVDQV9DT05TVEFOVFNfOwogICAgLyoqCiAgICAgKiBUYWJsZSBmb3IgVUNBIGFuZCBidWlsZGVyIHVzZQogICAgICovCiAgICBzdGF0aWMgZmluYWwgY2hhciBVQ0FfQ09OVFJBQ1RJT05TX1tdOwogICAgLyoqCiAgICAgKiBJbXBsaWNpdCBjb25zdGFudHMKICAgICAqLwogICAgc3RhdGljIGZpbmFsIGludCBJTVBMSUNJVF9CQVNFX0JZVEVfOwogICAgc3RhdGljIGZpbmFsIGludCBJTVBMSUNJVF9MSU1JVF9CWVRFXzsKICAgIHN0YXRpYyBmaW5hbCBpbnQgSU1QTElDSVRfNEJZVEVfQk9VTkRBUllfOwogICAgc3RhdGljIGZpbmFsIGludCBMQVNUX01VTFRJUExJRVJfOwogICAgc3RhdGljIGZpbmFsIGludCBMQVNUMl9NVUxUSVBMSUVSXzsKICAgIHN0YXRpYyBmaW5hbCBpbnQgSU1QTElDSVRfQkFTRV8zQllURV87CiAgICBzdGF0aWMgZmluYWwgaW50IElNUExJQ0lUX0JBU0VfNEJZVEVfOwogICAgc3RhdGljIGZpbmFsIGludCBCWVRFU19UT19BVk9JRF8gPSAzOwogICAgc3RhdGljIGZpbmFsIGludCBPVEhFUl9DT1VOVF8gPSAyNTYgLSBCWVRFU19UT19BVk9JRF87CiAgICBzdGF0aWMgZmluYWwgaW50IExBU1RfQ09VTlRfID0gT1RIRVJfQ09VTlRfIC8gMjsKICAgIC8qKgogICAgICogUm9vbSBmb3IgaW50ZXJ2ZW5pbmcsIHdpdGhvdXQgZXhwYW5kaW5nIHRvIDUgYnl0ZXMKICAgICAqLwogICAgc3RhdGljIGZpbmFsIGludCBMQVNUX0NPVU5UMl8gPSBPVEhFUl9DT1VOVF8gLyAyMTsgCiAgICBzdGF0aWMgZmluYWwgaW50IElNUExJQ0lUXzNCWVRFX0NPVU5UXyA9IDE7CiAgICAKICAgIC8vIGJsb2NrIHRvIGluaXRpYWxpc2UgY2hhcmFjdGVyIHByb3BlcnR5IGRhdGFiYXNlCiAgICBzdGF0aWMKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgCVVDQV8gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKTsKICAgICAgICAgICAgVUNBX0NPTlNUQU5UU18gPSBuZXcgVUNBQ29uc3RhbnRzKCk7CiAgICAgICAgCUlucHV0U3RyZWFtIGkgPSBVQ0FfLmdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIvY29tL2libS9pY3UvaW1wbC9kYXRhL3VjYWRhdGEuaWN1Iik7CiAgICAgICAgCQogICAgICAgCQlCdWZmZXJlZElucHV0U3RyZWFtIGIgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShpLCA5MDAwMCk7CiAgICAgICAgCUNvbGxhdG9yUmVhZGVyIHJlYWRlciA9IG5ldyBDb2xsYXRvclJlYWRlcihiKTsKICAgICAgICAJVUNBX0NPTlRSQUNUSU9OU18gPSByZWFkZXIucmVhZChVQ0FfLCBVQ0FfQ09OU1RBTlRTXyk7CiAgICAgICAgICAgIGIuY2xvc2UoKTsKICAgICAgICAJaS5jbG9zZSgpOwogICAgICAgICAgICAvLyBjYWxsZWQgYmVmb3JlIGRvaW5nIGNhbm9uaWNhbCBjbG9zdXJlIGZvciB0aGUgVUNBLgogICAgICAgICAgICBJTVBMSUNJVF9CQVNFX0JZVEVfID0gVUNBX0NPTlNUQU5UU18uUFJJTUFSWV9JTVBMSUNJVF9NSU5fOwogICAgICAgICAgICAvLyBsZWF2ZSByb29tIGZvciAxIDMtYnl0ZSBhbmQgMiA0LWJ5dGUgZm9ybXMKICAgICAgICAgICAgSU1QTElDSVRfTElNSVRfQllURV8gPSBJTVBMSUNJVF9CQVNFX0JZVEVfICsgNDsgCiAgICAgICAgICAgIElNUExJQ0lUXzRCWVRFX0JPVU5EQVJZXyA9IElNUExJQ0lUXzNCWVRFX0NPVU5UXyAqIE9USEVSX0NPVU5UXyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBMQVNUX0NPVU5UXzsKICAgICAgICAgICAgTEFTVF9NVUxUSVBMSUVSXyA9IE9USEVSX0NPVU5UXyAvIExBU1RfQ09VTlRfOwogICAgICAgICAgICBMQVNUMl9NVUxUSVBMSUVSXyA9IE9USEVSX0NPVU5UXyAvIExBU1RfQ09VTlQyXzsKICAgICAgICAgICAgSU1QTElDSVRfQkFTRV8zQllURV8gPSAoSU1QTElDSVRfQkFTRV9CWVRFXyA8PCAyNCkgKyAweDAzMDMwMDsKICAgICAgICAgICAgSU1QTElDSVRfQkFTRV80QllURV8gPSAoKElNUExJQ0lUX0JBU0VfQllURV8gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNUExJQ0lUXzNCWVRFX0NPVU5UXykgPDwgMjQpICsgMHgwMzAzMDM7CiAgICAgICAgCVVDQV8ubV9ydWxlc18gPSBudWxsOwogICAgICAgIAlVQ0FfLmluaXQoKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQogICAgICAgIHsKICAgICAgICAJZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgIH0gCiAgICAKICAgIC8vIHBhY2thZ2UgcHJpdmF0ZSBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgKiA8cD5Qcml2YXRlIGNvbnRydWN0b3IgZm9yIHVzZSBieSBzdWJjbGFzc2VzLiAKICAgICogUHVibGljIGFjY2VzcyB0byBjcmVhdGluZyBDb2xsYXRvcnMgaXMgaGFuZGxlZCBieSB0aGUgQVBJIAogICAgKiBDb2xsYXRvci5nZXRJbnN0YW5jZSgpIG9yIFJ1bGVCYXNlZENvbGxhdG9yKFN0cmluZyBydWxlcykuCiAgICAqIDwvcD4KICAgICogPHA+CiAgICAqIFRoaXMgY29uc3RydWN0b3IgY29uc3RydWN0cyB0aGUgVUNBIGNvbGxhdG9yIGludGVybmFsbHkKICAgICogPC9wPgogICAgKi8KICAgIFJ1bGVCYXNlZENvbGxhdG9yKCkgCiAgICB7CiAgICAgICAgaW5pdFV0aWxpdHkoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvcnMgYSBSdWxlQmFzZWRDb2xsYXRvciBmcm9tIHRoZSBhcmd1bWVudCBsb2NhbGUuCiAgICAgKiBJZiBubyByZXNvdXJjZSBidW5kbGUgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2NhbGUsIFVDQSBpcyB1c2VkIAogICAgICogaW5zdGVhZC4KICAgICAqIEBwYXJhbSBsb2NhbGUKICAgICAqLwogICAgUnVsZUJhc2VkQ29sbGF0b3IoTG9jYWxlIGxvY2FsZSkKICAgIHsKICAgICAgICBSZXNvdXJjZUJ1bmRsZSByYiA9IElDVUxvY2FsZURhdGEuZ2V0TG9jYWxlRWxlbWVudHMobG9jYWxlKTsKICAgICAgICBpbml0VXRpbGl0eSgpOwogICAgICAgIGlmIChyYiAhPSBudWxsKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBPYmplY3QgZWxlbWVudHMgPSByYi5nZXRPYmplY3QoIkNvbGxhdGlvbkVsZW1lbnRzIik7CiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIE9iamVjdFtdW10gcnVsZXMgPSAoT2JqZWN0W11bXSllbGVtZW50czsKICAgICAgICAgICAgICAgICAgICBtX3J1bGVzXyA9IChTdHJpbmcpcnVsZXNbMV1bMV07CiAgICAgICAgICAgICAgICAgICAgLy8gJSVDb2xsYXRpb25CaW4KICAgICAgICAgICAgICAgICAgICBieXRlIG1hcFtdID0gKGJ5dGUgW10pcnVsZXNbMF1bMV07CiAgICAgICAgICAgICAgICAgICAgQnVmZmVyZWRJbnB1dFN0cmVhbSBpbnB1dCA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG1hcCkpOwogICAgICAgICAgICAgICAgICAgIENvbGxhdG9yUmVhZGVyIHJlYWRlciA9IG5ldyBDb2xsYXRvclJlYWRlcihpbnB1dCwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChtYXAubGVuZ3RoID4gTUlOX0JJTkFSWV9EQVRBX1NJWkVfKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkKHRoaXMsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkSGVhZGVyKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucmVhZE9wdGlvbnModGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1cGxpY2F0aW5nIFVDQV8ncyBkYXRhCiAgICAgICAgICAgICAgICAgICAgICAgIHNldFdpdGhVQ0FUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICAgICAgLy8gaWYgZmFpbGVkIHVzZSBVQ0EuCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0V2l0aFVDQURhdGEoKTsKICAgIH0gCiAgICAKICAgIC8vIHBhY2thZ2UgcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGlzIGNvbGxhdG9yIHRvIHVzZSB0aGUgdGFibGVzIGluIFVDQS4gTm90ZSBvcHRpb25zIG5vdCB0YWtlbgogICAgICogY2FyZSBvZiBoZXJlLgogICAgICovCiAgICBmaW5hbCB2b2lkIHNldFdpdGhVQ0FUYWJsZXMoKQogICAgewogICAgICAgIG1fY29udHJhY3Rpb25PZmZzZXRfID0gVUNBXy5tX2NvbnRyYWN0aW9uT2Zmc2V0XzsKICAgICAgICBtX2V4cGFuc2lvbk9mZnNldF8gPSBVQ0FfLm1fZXhwYW5zaW9uT2Zmc2V0XzsKICAgICAgICBtX2V4cGFuc2lvbl8gPSBVQ0FfLm1fZXhwYW5zaW9uXzsKICAgICAgICBtX2NvbnRyYWN0aW9uSW5kZXhfID0gVUNBXy5tX2NvbnRyYWN0aW9uSW5kZXhfOwogICAgICAgIG1fY29udHJhY3Rpb25DRV8gPSBVQ0FfLm1fY29udHJhY3Rpb25DRV87CiAgICAgICAgbV90cmllXyA9IFVDQV8ubV90cmllXzsKICAgICAgICBtX2V4cGFuc2lvbkVuZENFXyA9IFVDQV8ubV9leHBhbnNpb25FbmRDRV87CgkgICAgbV9leHBhbnNpb25FbmRDRU1heFNpemVfID0gVUNBXy5tX2V4cGFuc2lvbkVuZENFTWF4U2l6ZV87CgkgICAgbV91bnNhZmVfID0gVUNBXy5tX3Vuc2FmZV87CgkgICAgbV9jb250cmFjdGlvbkVuZF8gPSBVQ0FfLm1fY29udHJhY3Rpb25FbmRfOwoJICAgIG1fbWluVW5zYWZlXyA9IFVDQV8ubV9taW5VbnNhZmVfOyAKICAgICAgICBtX21pbkNvbnRyYWN0aW9uRW5kXyA9IFVDQV8ubV9taW5Db250cmFjdGlvbkVuZF87CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGlzIGNvbGxhdG9yIHRvIHVzZSB0aGUgYWxsIG9wdGlvbnMgYW5kIHRhYmxlcyBpbiBVQ0EuIAogICAgICovCiAgICBmaW5hbCB2b2lkIHNldFdpdGhVQ0FEYXRhKCkKICAgIHsKICAgICAgICBsYXRpbk9uZUZhaWxlZF8gPSB0cnVlOwogICAgICAgIAogICAgCW1fYWRkaXRpb24zXyA9IFVDQV8ubV9hZGRpdGlvbjNfOwogICAgCW1fYm90dG9tM18gPSBVQ0FfLm1fYm90dG9tM187CiAgICAJbV9ib3R0b21Db3VudDNfID0gVUNBXy5tX2JvdHRvbUNvdW50M187CiAgICAJbV9jYXNlRmlyc3RfID0gVUNBXy5tX2Nhc2VGaXJzdF87CiAgICAJbV9jYXNlU3dpdGNoXyA9IFVDQV8ubV9jYXNlU3dpdGNoXzsKICAgIAltX2NvbW1vbjNfID0gVUNBXy5tX2NvbW1vbjNfOwogICAgCW1fY29udHJhY3Rpb25PZmZzZXRfID0gVUNBXy5tX2NvbnRyYWN0aW9uT2Zmc2V0XzsKICAgIAlzZXREZWNvbXBvc2l0aW9uKFVDQV8uZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIAltX2RlZmF1bHRDYXNlRmlyc3RfID0gVUNBXy5tX2RlZmF1bHRDYXNlRmlyc3RfOwogICAgCW1fZGVmYXVsdERlY29tcG9zaXRpb25fID0gVUNBXy5tX2RlZmF1bHREZWNvbXBvc2l0aW9uXzsKICAgIAltX2RlZmF1bHRJc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF8gCiAgICAJICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBVQ0FfLm1fZGVmYXVsdElzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXzsKICAgIAltX2RlZmF1bHRJc0Nhc2VMZXZlbF8gPSBVQ0FfLm1fZGVmYXVsdElzQ2FzZUxldmVsXzsKICAgIAltX2RlZmF1bHRJc0ZyZW5jaENvbGxhdGlvbl8gPSBVQ0FfLm1fZGVmYXVsdElzRnJlbmNoQ29sbGF0aW9uXzsKICAgIAltX2RlZmF1bHRJc0hpcmFnYW5hNF8gPSBVQ0FfLm1fZGVmYXVsdElzSGlyYWdhbmE0XzsKICAgIAltX2RlZmF1bHRTdHJlbmd0aF8gPSBVQ0FfLm1fZGVmYXVsdFN0cmVuZ3RoXzsKICAgIAltX2RlZmF1bHRWYXJpYWJsZVRvcFZhbHVlXyA9IFVDQV8ubV9kZWZhdWx0VmFyaWFibGVUb3BWYWx1ZV87CiAgICAJbV9leHBhbnNpb25PZmZzZXRfID0gVUNBXy5tX2V4cGFuc2lvbk9mZnNldF87CiAgICAJbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF8gPSBVQ0FfLm1faXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWRfOwogICAgCW1faXNDYXNlTGV2ZWxfID0gVUNBXy5tX2lzQ2FzZUxldmVsXzsKICAgIAltX2lzRnJlbmNoQ29sbGF0aW9uXyA9IFVDQV8ubV9pc0ZyZW5jaENvbGxhdGlvbl87CiAgICAJbV9pc0hpcmFnYW5hNF8gPSBVQ0FfLm1faXNIaXJhZ2FuYTRfOwogICAgCW1faXNKYW1vU3BlY2lhbF8gPSBVQ0FfLm1faXNKYW1vU3BlY2lhbF87CiAgICAJbV9pc1NpbXBsZTNfID0gVUNBXy5tX2lzU2ltcGxlM187CiAgICAJbV9tYXNrM18gPSBVQ0FfLm1fbWFzazNfOwogICAgCW1fbWluQ29udHJhY3Rpb25FbmRfID0gVUNBXy5tX21pbkNvbnRyYWN0aW9uRW5kXzsKICAgIAltX21pblVuc2FmZV8gPSBVQ0FfLm1fbWluVW5zYWZlXzsKICAgIAltX3J1bGVzXyA9IFVDQV8ubV9ydWxlc187CiAgICAJc2V0U3RyZW5ndGgoVUNBXy5nZXRTdHJlbmd0aCgpKTsKICAgIAltX3RvcDNfID0gVUNBXy5tX3RvcDNfOwogICAgCW1fdG9wQ291bnQzXyA9IFVDQV8ubV90b3BDb3VudDNfOwogICAgCW1fdmFyaWFibGVUb3BWYWx1ZV8gPSBVQ0FfLm1fdmFyaWFibGVUb3BWYWx1ZV87CiAgICAJc2V0V2l0aFVDQVRhYmxlcygpOwogICAgICAgIGxhdGluT25lRmFpbGVkXyA9IGZhbHNlOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFRlc3Qgd2hldGhlciBhIGNoYXIgY2hhcmFjdGVyIGlzIHBvdGVudGlhbGx5ICJ1bnNhZmUiIGZvciB1c2UgYXMgYSAKICAgICAqIGNvbGxhdGlvbiBzdGFydGluZyBwb2ludC4gIlVuc2FmZSIgY2hhcmFjdGVycyBhcmUgY29tYmluaW5nIG1hcmtzIG9yIAogICAgICogdGhvc2UgYmVsb25naW5nIHRvIHNvbWUgY29udHJhY3Rpb24gc2VxdWVuY2UgZnJvbSB0aGUgb2Zmc2V0IDEgb253YXJkcy4KICAgICAqIEUuZy4gaWYgIkFCQyIgaXMgdGhlIG9ubHkgY29udHJhY3Rpb24sIHRoZW4gJ0InIGFuZCAKICAgICAqICdDJyBhcmUgY29uc2lkZXJlZCB1bnNhZmUuIElmIHdlIGhhdmUgYW5vdGhlciBjb250cmFjdGlvbiAiWkEiIHdpdGggCiAgICAgKiB0aGUgb25lIGFib3ZlLCB0aGVuICdBJywgJ0InLCAnQycgYXJlICJ1bnNhZmUiIGJ1dCAnWicgaXMgbm90LiAKICAgICAqIEBwYXJhbSBjaCBjaGFyYWN0ZXIgdG8gZGV0ZXJtaW4KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjaCBpcyB1bnNhZmUsIGZhbHNlIG90aGVyd2lzZQogICAgICovCglmaW5hbCBib29sZWFuIGlzVW5zYWZlKGNoYXIgY2gpIAoJewogICAgCWlmIChjaCA8IG1fbWluVW5zYWZlXykgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgaWYgKGNoID49IChIRVVSSVNUSUNfU0laRV8gPDwgSEVVUklTVElDX1NISUZUXykpIHsKCSAgICAgIAlpZiAoVVRGMTYuaXNMZWFkU3Vycm9nYXRlKGNoKSB8fCBVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICAgICAgLy8gIFRyYWlsIHN1cnJvZ2F0ZSBhcmUgYWx3YXlzIGNvbnNpZGVyZWQgdW5zYWZlLgoJICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgIH0KCSAgICAgICAgY2ggJj0gSEVVUklTVElDX09WRVJGTE9XX01BU0tfOwoJICAgICAgICBjaCArPSBIRVVSSVNUSUNfT1ZFUkZMT1dfT0ZGU0VUXzsKCSAgICB9CgkgICAgaW50IHZhbHVlID0gbV91bnNhZmVfW2NoID4+IEhFVVJJU1RJQ19TSElGVF9dOwoJICAgIHJldHVybiAoKHZhbHVlID4+IChjaCAmIEhFVVJJU1RJQ19NQVNLXykpICYgMSkgIT0gMDsKCX0KCQoJLyoqCgkgKiBBcHByb3hpbWF0ZSBkZXRlcm1pbmF0aW9uIGlmIGEgY2hhciBjaGFyYWN0ZXIgaXMgYXQgYSBjb250cmFjdGlvbiBlbmQuCgkgKiBHdWFyYW50ZWVkIHRvIGJlIHRydWUgaWYgYSBjaGFyYWN0ZXIgaXMgYXQgdGhlIGVuZCBvZiBhIGNvbnRyYWN0aW9uLAoJICogb3RoZXJ3aXNlIGl0IGlzIG5vdCBkZXRlcm1pbmlzdGljLgoJICogQHBhcmFtIGNoIGNoYXJhY3RlciB0byBiZSBkZXRlcm1pbmVkCgkgKi8KCWZpbmFsIGJvb2xlYW4gaXNDb250cmFjdGlvbkVuZChjaGFyIGNoKSAKCXsKCQlpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgCQlyZXR1cm4gdHJ1ZTsKCQl9CgogICAgCWlmIChjaCA8IG1fbWluQ29udHJhY3Rpb25FbmRfKSB7CiAgICAgICAgCXJldHVybiBmYWxzZTsKICAgIAl9CgogICAJCWlmIChjaCA+PSAoSEVVUklTVElDX1NJWkVfIDw8IEhFVVJJU1RJQ19TSElGVF8pKSB7CiAgICAgICAgCWNoICY9IEhFVVJJU1RJQ19PVkVSRkxPV19NQVNLXzsKICAgICAgICAJY2ggKz0gSEVVUklTVElDX09WRVJGTE9XX09GRlNFVF87CiAgICAJfQogICAgCWludCB2YWx1ZSA9IG1fY29udHJhY3Rpb25FbmRfW2NoID4+IEhFVVJJU1RJQ19TSElGVF9dOwoJICAgIHJldHVybiAoKHZhbHVlID4+IChjaCAmIEhFVVJJU1RJQ19NQVNLXykpICYgMSkgIT0gMDsKCX0KCQoJLyoqCgkgKiBSZXRyaWV2ZSB0aGUgdGFnIG9mIGEgc3BlY2lhbCBjZQoJICogQHBhcmFtIGNlIGNlIHRvIHRlc3QKCSAqIEByZXR1cm4gdGFnIG9mIGNlCgkgKi8KCXN0YXRpYyBpbnQgZ2V0VGFnKGludCBjZSkgCgl7CgkJcmV0dXJuIChjZSAmIENFX1RBR19NQVNLXykgPj4gQ0VfVEFHX1NISUZUXzsKCX0KICAgIAogICAgLyoqIAoJICogQ2hlY2tpbmcgaWYgY2UgaXMgc3BlY2lhbAoJICogQHBhcmFtIGNlIHRvIGNoZWNrCgkgKiBAcmV0dXJuIHRydWUgaWYgY2UgaXMgc3BlY2lhbAoJICovCglzdGF0aWMgYm9vbGVhbiBpc1NwZWNpYWwoaW50IGNlKQoJewoJCXJldHVybiAoY2UgJiBDRV9TUEVDSUFMX0ZMQUdfKSA9PSBDRV9TUEVDSUFMX0ZMQUdfOyAKCX0KCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGUgYXJndW1lbnQgY2UgaXMgYSBjb250aW51YXRpb24KICAgICAqIEBwYXJhbSBjZSBjb2xsYXRpb24gZWxlbWVudCB0byB0ZXN0CiAgICAgKiBAcmV0dXJuIHRydWUgaWYgY2UgaXMgYSBjb250aW51YXRpb24KICAgICAqLwogICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNDb250aW51YXRpb24oaW50IGNlKSAKICAgIHsKICAgICAgICByZXR1cm4gY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2UgJiBDRV9DT05USU5VQVRJT05fVEFHXykgPT0gQ0VfQ09OVElOVUFUSU9OX1RBR187CiAgICB9CiAgICAKICAgIC8vIHByaXZhdGUgaW5uZXIgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLy8gcHJpdmF0ZSB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFRoZSBzbWFsbGVzdCBuYXR1cmFsIHVuc2FmZSBvciBjb250cmFjdGlvbiBlbmQgY2hhciBjaGFyYWN0ZXIgYmVmb3JlIAogICAgICogdGFpbG9yaW5nLgogICAgICogVGhpcyBpcyBhIGNvbWJpbmluZyBtYXJrLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9NSU5fSEVVUklTVElDXyA9IDB4MzAwOwogICAgLyoqIAogICAgICogSGV1cmlzdGljIHRhYmxlIHRhYmxlIHNpemUuIFNpemUgaXMgMzIgYnl0ZXMsIDEgYml0IGZvciBlYWNoIAogICAgICogbGF0aW4gMSBjaGFyLCBhbmQgc29tZSBwb3dlciBvZiB0d28gZm9yIGhhc2hpbmcgdGhlIHJlc3Qgb2YgdGhlIGNoYXJzLiAgIAogICAgICogU2l6ZSBpbiBieXRlcy4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgSEVVUklTVElDX1NJWkVfID0gMTA1NjsKICAgIC8qKiAKICAgICAqIE1hc2sgdmFsdWUgZG93biB0byAic29tZSBwb3dlciBvZiB0d28iIC0gMSwKICAgICAqIG51bWJlciBvZiBiaXRzLCBub3QgbnVtIG9mIGJ5dGVzLgogICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIEhFVVJJU1RJQ19PVkVSRkxPV19NQVNLXyA9IDB4MWZmZjsKCS8qKgoJICogVW5zYWZlIGNoYXJhY3RlciBzaGlmdAoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSEVVUklTVElDX1NISUZUXyA9IDM7CgkvKioKCSAqIFVuc2FmZSBjaGFyYWN0ZXIgYWRkaXRpb24gZm9yIGNoYXJhY3RlciB0b28gbGFyZ2UsIGl0IGhhcyB0byBiZSBmb2xkZWQKCSAqIHRoZW4gaW5jcmVtZW50ZWQuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgSEVVUklTVElDX09WRVJGTE9XX09GRlNFVF8gPSAyNTY7CgkvKiogCiAgICAgKiBNYXNrIHZhbHVlIHRvIGdldCBvZmZzZXQgaW4gaGV1cmlzdGljIHRhYmxlLgogICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIEhFVVJJU1RJQ19NQVNLXyA9IDc7CgkKCXByaXZhdGUgaW50IG1fY2FzZVN3aXRjaF87IAogICAgcHJpdmF0ZSBpbnQgbV9jb21tb24zXzsKICAgIHByaXZhdGUgaW50IG1fbWFzazNfOyAKICAgIC8qKiAKICAgICAqIFdoZW4gc3dpdGNoaW5nIGNhc2UsIHdlIG5lZWQgdG8gYWRkIG9yIHN1YnRyYWN0IGRpZmZlcmVudCB2YWx1ZXMuCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG1fYWRkaXRpb24zXzsgCiAgICAvKiogCiAgICAgKiBVcHBlciByYW5nZSB3aGVuIGNvbXByZXNzaW5nIAogICAgICovCiAgICBwcml2YXRlIGludCBtX3RvcDNfOwogICAgLyoqIAogICAgICogVXBwZXIgcmFuZ2Ugd2hlbiBjb21wcmVzc2luZyAKICAgICAqLyAKICAgIHByaXZhdGUgaW50IG1fYm90dG9tM187IAogICAgcHJpdmF0ZSBpbnQgbV90b3BDb3VudDNfOwogICAgcHJpdmF0ZSBpbnQgbV9ib3R0b21Db3VudDNfOwkKCS8qKgoJICogQ2FzZSBmaXJzdCBjb25zdGFudHMKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBU0VfU1dJVENIXyA9IDB4QzA7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTk9fQ0FTRV9TV0lUQ0hfID0gMDsKCS8qKgoJICogQ2FzZSBsZXZlbCBjb25zdGFudHMKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENFX1JFTU9WRV9DQVNFXyA9IDB4M0Y7IAoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENFX0tFRVBfQ0FTRV8gPSAweEZGOwoJLyoqCgkgKiBDYXNlIHN0cmVuZ3RoIG1hc2sKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENFX0NBU0VfTUFTS18zXyA9IDB4RkY7CgkvKiogCgkgKiBTb3J0a2V5IHNpemUgZmFjdG9yLiBWYWx1ZXMgY2FuIGJlIGNoYW5nZWQuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBQUk9QT1JUSU9OXzJfID0gMC41OwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgZG91YmxlIFBST1BPUlRJT05fM18gPSAwLjY2NzsKCgkvLyBUaGVzZSB2YWx1ZXMgY29tZSBmcm9tIHRoZSBVQ0EgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKiogCgkgKiBUaGlzIGlzIGFuIGVudW0gdGhhdCBsaXN0cyBtYWdpYyBzcGVjaWFsIGJ5dGUgdmFsdWVzIGZyb20gdGhlIAoJICogZnJhY3Rpb25hbCBVQ0EgCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9aRVJPXyA9IDB4MDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9MRVZFTF9TRVBBUkFUT1JfID0gKGJ5dGUpMHgwMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9TT1JUS0VZX0dMVUVfID0gKGJ5dGUpMHgwMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9TSElGVF9QUkVGSVhfID0gKGJ5dGUpMHgwMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9VTlNISUZURURfTUlOXyA9IEJZVEVfU0hJRlRfUFJFRklYXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGUgQllURV9GSVJTVF9VQ0FfID0gQllURV9DT01NT05fOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBCWVRFX0xBU1RfTEFUSU5fUFJJTUFSWV8gPSAoYnl0ZSkweDRDOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBCWVRFX0ZJUlNUX05PTl9MQVRJTl9QUklNQVJZXyA9IChieXRlKTB4NEQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIEJZVEVfVU5TSElGVEVEX01BWF8gPSAoYnl0ZSkweEZGOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRPVEFMXzJfID0gQ09NTU9OX1RPUF8yXyAtIENPTU1PTl9CT1RUT01fMl8gLSAxOyAKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGTEFHX0JJVF9NQVNLX0NBU0VfU1dJVENIX09GRl8gPSAweDgwOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZMQUdfQklUX01BU0tfQ0FTRV9TV0lUQ0hfT05fID0gMHg0MDsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT01NT05fVE9QX0NBU0VfU1dJVENIX09GRl8zXyA9IDB4ODU7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX1RPUF9DQVNFX1NXSVRDSF9MT1dFUl8zXyA9IDB4NDU7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX1RPUF9DQVNFX1NXSVRDSF9VUFBFUl8zXyA9IDB4QzU7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX0JPVFRPTV8zXyA9IDB4MDU7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX0JPVFRPTV9DQVNFX1NXSVRDSF9VUFBFUl8zXyA9IDB4ODY7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX0JPVFRPTV9DQVNFX1NXSVRDSF9MT1dFUl8zXyA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTU1PTl9CT1RUT01fM187Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVE9QX0NPVU5UXzJfID0gKGludCkoUFJPUE9SVElPTl8yXyAqIFRPVEFMXzJfKTsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCT1RUT01fQ09VTlRfMl8gPSBUT1RBTF8yXyAtIFRPUF9DT1VOVF8yXzsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT01NT05fMl8gPSBDT01NT05fQk9UVE9NXzJfOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPTU1PTl9VUFBFUl9GSVJTVF8zXyA9IDB4QzU7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OX05PUk1BTF8zXyA9IENPTU1PTl9CT1RUT01fM187Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09NTU9OXzRfID0gKGJ5dGUpMHhGRjsKICAgIAogICAgCgkKCS8qKgoJICogTWluaW11bSBzaXplIHJlcXVpcmVkIGZvciB0aGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIGluIGJ5dGVzLgoJICogU2l6ZSBvZiBVQ0EgaGVhZGVyICsgc2l6ZSBvZiBvcHRpb25zIHRvIDQgYnl0ZXMKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1JTl9CSU5BUllfREFUQV9TSVpFXyA9ICg0MiArIDI0KSA8PCAyOyAgICAgCgkKCS8qKgoJICogSWYgdGhpcyBjb2xsYXRvciBpcyB0byBnZW5lcmF0ZSBvbmx5IHNpbXBsZSB0ZXJ0aWFyaWVzIGZvciBmYXN0IHBhdGgKCSAqLwoJcHJpdmF0ZSBib29sZWFuIG1faXNTaW1wbGUzXzsKCQoJLyoqCiAgICAgKiBGcmVuY2ggY29sbGF0aW9uIHNvcnRpbmcgZmxhZwogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gbV9pc0ZyZW5jaENvbGxhdGlvbl87IAogICAgLyoqCiAgICAgKiBGbGFnIGluZGljYXRpbmcgaWYgc2hpZnRlZCBpcyByZXF1ZXN0ZWQgZm9yIFF1YXRlcm5hcnkgYWx0ZXJuYXRlCiAgICAgKiBoYW5kbGluZy4gSWYgdGhpcyBpcyBub3QgdHJ1ZSwgdGhlIGRlZmF1bHQgZm9yIGFsdGVybmF0ZSBoYW5kbGluZyB3aWxsCiAgICAgKiBiZSBub24taWdub3JhYmxlLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF87IAogICAgLyoqIAogICAgICogRXh0cmEgY2FzZSBsZXZlbCBmb3Igc29ydGluZwogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gbV9pc0Nhc2VMZXZlbF87CgkKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTT1JUX0JVRkZFUl9JTklUX1NJWkVfID0gMTI4OwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPUlRfQlVGRkVSX0lOSVRfU0laRV8xXyA9IAoJCQkJCQkJCQkJCQkJU09SVF9CVUZGRVJfSU5JVF9TSVpFXyA8PCAzOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPUlRfQlVGRkVSX0lOSVRfU0laRV8yXyA9IFNPUlRfQlVGRkVSX0lOSVRfU0laRV87Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU09SVF9CVUZGRVJfSU5JVF9TSVpFXzNfID0gU09SVF9CVUZGRVJfSU5JVF9TSVpFXzsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTT1JUX0JVRkZFUl9JTklUX1NJWkVfQ0FTRV8gPSAKCQkJCQkJCQkJCQkJU09SVF9CVUZGRVJfSU5JVF9TSVpFXyA+PiAyOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNPUlRfQlVGRkVSX0lOSVRfU0laRV80XyA9IFNPUlRfQlVGRkVSX0lOSVRfU0laRV87CiAgICAKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRV9DT05USU5VQVRJT05fVEFHXyA9IDB4QzA7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0VfUkVNT1ZFX0NPTlRJTlVBVElPTl9NQVNLXyA9IDB4RkZGRkZGM0Y7IAoKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMQVNUX0JZVEVfTUFTS18gPSAweEZGOwoJCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0VfUkVTRVRfVE9QX1ZBTFVFXyA9IDB4OUYwMDAzMDM7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ0VfTkVYVF9UT1BfVkFMVUVfID0gMHhFODk2MDMwMzsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFNPUlRfQ0FTRV9CWVRFX1NUQVJUXyA9IChieXRlKTB4ODA7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFNPUlRfQ0FTRV9TSElGVF9TVEFSVF8gPSAoYnl0ZSk3OwoJCglwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIFNPUlRfTEVWRUxfVEVSTUlOQVRPUl8gPSAxOwoJCgkvKioKCSAqIENFIGJ1ZmZlciBzaXplCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDRV9CVUZGRVJfU0laRV8gPSA1MTI7CiAgICAgICAKICAgIC8vIHZhcmlhYmxlcyBmb3IgTGF0aW4tMSBwcm9jZXNzaW5nCiAgICBib29sZWFuIGxhdGluT25lVXNlXyAgICAgICAgPSBmYWxzZTsKICAgIGJvb2xlYW4gbGF0aW5PbmVSZWdlblRhYmxlXyA9IGZhbHNlOwogICAgYm9vbGVhbiBsYXRpbk9uZUZhaWxlZF8gICAgID0gZmFsc2U7CgogICAgaW50IGxhdGluT25lVGFibGVMZW5fID0gMDsgICAgICAgCiAgICBpbnQgbGF0aW5PbmVDRXNfW10gPSBudWxsOwogICAgLyoqCiAgICAgKiBCdW5jaCBvZiB1dGlsaXR5IGl0ZXJhdG9ycwogICAgICovCiAgICBwcml2YXRlIFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yIG1fc3JjVXRpbEl0ZXJfOwogICAgcHJpdmF0ZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgbV9zcmNVdGlsQ29sRUl0ZXJfOyAgIAogICAgcHJpdmF0ZSBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvciBtX3RndFV0aWxJdGVyXzsKICAgIHByaXZhdGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG1fdGd0VXRpbENvbEVJdGVyXzsKICAgIC8qKgogICAgICogVXRpbGl0eSBjb21wYXJpc29uIGZsYWdzCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBtX3V0aWxDb21wYXJlMF87CiAgICBwcml2YXRlIGJvb2xlYW4gbV91dGlsQ29tcGFyZTFfOwogICAgcHJpdmF0ZSBib29sZWFuIG1fdXRpbENvbXBhcmUyXzsKICAgIHByaXZhdGUgYm9vbGVhbiBtX3V0aWxDb21wYXJlM187CiAgICBwcml2YXRlIGJvb2xlYW4gbV91dGlsQ29tcGFyZTRfOwogICAgcHJpdmF0ZSBib29sZWFuIG1fdXRpbENvbXBhcmU1XzsgCiAgICAvKioKICAgICAqIFV0aWxpdHkgYnl0ZSBidWZmZXIKICAgICAqLwogICAgcHJpdmF0ZSBieXRlIG1fdXRpbEJ5dGVzMF9bXTsKICAgIHByaXZhdGUgYnl0ZSBtX3V0aWxCeXRlczFfW107CiAgICBwcml2YXRlIGJ5dGUgbV91dGlsQnl0ZXMyX1tdOwogICAgcHJpdmF0ZSBieXRlIG1fdXRpbEJ5dGVzM19bXTsKICAgIHByaXZhdGUgYnl0ZSBtX3V0aWxCeXRlczRfW107CiAgICBwcml2YXRlIGJ5dGUgbV91dGlsQnl0ZXM1X1tdOwogICAgCiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50MF87CiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50MV87CiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50Ml87CiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50M187CiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50NF87CiAgICBwcml2YXRlIGludCBtX3V0aWxCeXRlc0NvdW50NV87CiAgICBwcml2YXRlIGludCBtX3V0aWxDb3VudDBfOwogICAgcHJpdmF0ZSBpbnQgbV91dGlsQ291bnQxXzsKICAgIHByaXZhdGUgaW50IG1fdXRpbENvdW50Ml87CiAgICBwcml2YXRlIGludCBtX3V0aWxDb3VudDNfOwogICAgcHJpdmF0ZSBpbnQgbV91dGlsQ291bnQ0XzsKICAgIHByaXZhdGUgaW50IG1fdXRpbENvdW50NV87CiAgICAKICAgIHByaXZhdGUgaW50IG1fdXRpbEZyZW5jaFN0YXJ0XzsgCiAgICBwcml2YXRlIGludCBtX3V0aWxGcmVuY2hFbmRfOwogICAgCiAgICAvKiogCiAgICAgKiBQcmVwYXJpbmcgdGhlIENFIGJ1ZmZlcnMuIHdpbGwgYmUgZmlsbGVkIGR1cmluZyB0aGUgcHJpbWFyeSBwaGFzZQogICAgICovCiAgICBwcml2YXRlIGludCBtX3NyY1V0aWxDRUJ1ZmZlcl9bXTsgCiAgICBwcml2YXRlIGludCBtX3RndFV0aWxDRUJ1ZmZlcl9bXTsKICAgIHByaXZhdGUgaW50IG1fc3JjVXRpbENFQnVmZmVyU2l6ZV87CiAgICBwcml2YXRlIGludCBtX3RndFV0aWxDRUJ1ZmZlclNpemVfOwogICAgCiAgICBwcml2YXRlIGludCBtX3NyY1V0aWxDb250T2Zmc2V0XzsKICAgIHByaXZhdGUgaW50IG1fdGd0VXRpbENvbnRPZmZzZXRfOwogICAgCiAgICBwcml2YXRlIGludCBtX3NyY1V0aWxPZmZzZXRfOwogICAgcHJpdmF0ZSBpbnQgbV90Z3RVdGlsT2Zmc2V0XzsKICAgIAogICAgLy8gcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgcHJpdmF0ZSBmaW5hbCBpbnQgY29tcGFyZVJlZ3VsYXIoU3RyaW5nIHNvdXJjZSwgU3RyaW5nIHRhcmdldCwgaW50IG9mZnNldCkgewogICAgICAgIGludCBzdHJlbmd0aCA9IGdldFN0cmVuZ3RoKCk7CiAgICAgICAgLy8gc2V0dGluZyB1cCB0aGUgY29sbGF0b3IgcGFyYW1ldGVycyAgIAogICAgICAgIG1fdXRpbENvbXBhcmUwXyA9IG1faXNDYXNlTGV2ZWxfOwogICAgICAgIG1fdXRpbENvbXBhcmUxXyA9IHRydWU7CiAgICAgICAgbV91dGlsQ29tcGFyZTJfID0gc3RyZW5ndGggPj0gU0VDT05EQVJZOwogICAgICAgIG1fdXRpbENvbXBhcmUzXyA9IHN0cmVuZ3RoID49IFRFUlRJQVJZOwogICAgICAgIG1fdXRpbENvbXBhcmU0XyA9IHN0cmVuZ3RoID49IFFVQVRFUk5BUlk7CiAgICAgICAgbV91dGlsQ29tcGFyZTVfID0gc3RyZW5ndGggPT0gSURFTlRJQ0FMOwogICAgICAgIGJvb2xlYW4gZG9GcmVuY2ggPSBtX2lzRnJlbmNoQ29sbGF0aW9uXyAmJiBtX3V0aWxDb21wYXJlMl87CiAgICAgICAgYm9vbGVhbiBkb1NoaWZ0NCA9IG1faXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWRfICYmIG1fdXRpbENvbXBhcmU0XzsKICAgICAgICBib29sZWFuIGRvSGlyYWdhbmE0ID0gbV9pc0hpcmFnYW5hNF8gJiYgbV91dGlsQ29tcGFyZTRfOwogICAgCiAgICAgICAgaWYgKGRvSGlyYWdhbmE0ICYmIGRvU2hpZnQ0KSB7CiAgICAgICAgICAgIFN0cmluZyBzb3VyY2VzdWIgPSBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldCk7CiAgICAgICAgICAgIFN0cmluZyB0YXJnZXRzdWIgPSB0YXJnZXQuc3Vic3RyaW5nKG9mZnNldCk7CiAgICAgICAgICAgIHJldHVybiBjb21wYXJlQnlTb3J0S2V5cyhzb3VyY2VzdWIsIHRhcmdldHN1Yik7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIFRoaXMgaXMgdGhlIGxvd2VzdCBwcmltYXJ5IHZhbHVlIHRoYXQgd2lsbCBub3QgYmUgaWdub3JlZCBpZiBzaGlmdGVkCiAgICAgICAgaW50IGxvd2VzdHB2YWx1ZSA9IG1faXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWRfIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbV92YXJpYWJsZVRvcFZhbHVlXyA8PCAxNiA6IDA7CiAgICAgICAgbV9zcmNVdGlsQ0VCdWZmZXJTaXplXyA9IDA7CiAgICAgICAgbV90Z3RVdGlsQ0VCdWZmZXJTaXplXyA9IDA7CiAgICAgICAgaW50IHJlc3VsdCA9IGRvUHJpbWFyeUNvbXBhcmUoZG9IaXJhZ2FuYTQsIGxvd2VzdHB2YWx1ZSwgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsIG9mZnNldCk7CiAgICAgICAgaWYgKG1fc3JjVXRpbENFQnVmZmVyU2l6ZV8gPT0gLTEgCiAgICAgICAgICAgICYmIG1fdGd0VXRpbENFQnVmZmVyU2l6ZV8gPT0gLTEpIHsKICAgICAgICAgICAgLy8gc2luY2UgdGhlIGNlYnVmZmVyIGlzIGNsZWFyZWQgd2hlbiB3ZSBoYXZlIGRldGVybWluZWQgdGhhdAogICAgICAgICAgICAvLyBlaXRoZXIgc291cmNlIGlzIGdyZWF0ZXIgdGhhbiB0YXJnZXQgb3IgdmljZSB2ZXJzYSwgdGhlIHJldHVybgogICAgICAgICAgICAvLyByZXN1bHQgaXMgdGhlIGNvbXBhcmlzb24gcmVzdWx0IGFuZCBub3QgdGhlIGhpcmFnYW5hIHJlc3VsdAogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0gCiAgICAgICAgCiAgICAgICAgaW50IGhpcmFnYW5hcmVzdWx0ID0gcmVzdWx0OwogICAgICAgIAogICAgICAgIGlmIChtX3V0aWxDb21wYXJlMl8pIHsKICAgICAgICAgICAgcmVzdWx0ID0gZG9TZWNvbmRhcnlDb21wYXJlKGRvRnJlbmNoKTsKICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIGRvaW5nIHRoZSBjYXNlIGJpdAogICAgICAgIGlmIChtX3V0aWxDb21wYXJlMF8pIHsKICAgICAgICAgICAgcmVzdWx0ID0gZG9DYXNlQ29tcGFyZSgpOwogICAgICAgICAgICBpZiAocmVzdWx0ICE9IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0gICAKICAgICAgICB9CiAgICAgICAgLy8gVGVydGlhcnkgbGV2ZWwKICAgICAgICBpZiAobV91dGlsQ29tcGFyZTNfKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IGRvVGVydGlhcnlDb21wYXJlKCk7CiAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIAogICAgICAgIGlmIChkb1NoaWZ0NCkgeyAgLy8gY2hlY2tRdWFkCiAgICAgICAgICAgIHJlc3VsdCA9IGRvUXVhdGVybmFyeUNvbXBhcmUobG93ZXN0cHZhbHVlKTsKICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgfSAKICAgICAgICBlbHNlIGlmIChkb0hpcmFnYW5hNCAmJiBoaXJhZ2FuYXJlc3VsdCAhPSAwKSB7CiAgICAgICAgICAgIC8vIElmIHdlJ3JlIGZpbmUgb24gcXVhdGVybmFyaWVzLCB3ZSBtaWdodCBiZSBkaWZmZXJlbnQKICAgICAgICAgICAgLy8gb24gSGlyYWdhbmEuIFRoaXMsIGhvd2V2ZXIsIG1pZ2h0IGZhaWwgdXMgaW4gc2hpZnRlZC4KICAgICAgICAgICAgcmV0dXJuIGhpcmFnYW5hcmVzdWx0OwogICAgICAgIH0KICAgIAogICAgICAgIC8vIEZvciBJREVOVElDQUwgY29tcGFyaXNvbnMsIHdlIHVzZSBhIGJpdHdpc2UgY2hhcmFjdGVyIGNvbXBhcmlzb24gCiAgICAgICAgLy8gYXMgYSB0aWVicmVha2VyIGlmIGFsbCBlbHNlIGlzIGVxdWFsLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgLy8gR2V0dGluZyBoZXJlICBzaG91bGQgYmUgcXVpdGUgcmFyZSAtIHN0cmluZ3MgYXJlIG5vdCBpZGVudGljYWwgLSAgICAgCiAgICAgICAgLy8gdGhhdCBpcyBjaGVja2VkIGZpcnN0LCBidXQgY29tcGFyZWQgPT0gdGhyb3VnaCBhbGwgb3RoZXIgY2hlY2tzLiAgCiAgICAgICAgaWYgKG1fdXRpbENvbXBhcmU1XykgewogICAgICAgICAgICByZXR1cm4gZG9JZGVudGljYWxDb21wYXJlKHNvdXJjZSwgdGFyZ2V0LCBvZmZzZXQsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBHZXRzIHRoZSAyIGJ5dGVzIG9mIHByaW1hcnkgb3JkZXIgYW5kIGFkZHMgaXQgdG8gdGhlIHByaW1hcnkgYnl0ZSBhcnJheQogICAgICogQHBhcmFtIGNlIGN1cnJlbnQgY2UKICAgICAqIEBwYXJhbSBub3RJc0NvbnRpbnVhdGlvbiBmbGFnIGluZGljYXRpbmcgaWYgdGhlIGN1cnJlbnQgYnl0ZXMgYmVsb25nIHRvIAogICAgICogCQkJYSBjb250aW51YXRpb24gY2UKICAgICAqIEBwYXJhbSBkb1NoaWZ0IGZsYWcgaW5kaWNhdGluZyBpZiBjZSBpcyB0byBiZSBzaGlmdGVkCiAgICAgKiBAcGFyYW0gbGVhZFByaW1hcnkgbGVhZCBwcmltYXJ5IHVzZWQgZm9yIGNvbXByZXNzaW9uCiAgICAgKiBAcGFyYW0gY29tbW9uQm90dG9tNCBjb21tb24gYnl0ZSB2YWx1ZSBmb3IgUXVhdGVybmFyeQogICAgICogQHBhcmFtIGJvdHRvbUNvdW50NCBzbWFsbGVzdCBieXRlIHZhbHVlIGZvciBRdWF0ZXJuYXJ5CiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgbGVhZCBwcmltYXJ5IGZvciBjb21wcmVzc2lvbgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIGludCBkb1ByaW1hcnlCeXRlcyhpbnQgY2UsIGJvb2xlYW4gbm90SXNDb250aW51YXRpb24sIAogICAgCQkJCQkJICAgICAgYm9vbGVhbiBkb1NoaWZ0LCBpbnQgbGVhZFByaW1hcnksCiAgICAJCQkJCQkgICAgICBpbnQgY29tbW9uQm90dG9tNCwgaW50IGJvdHRvbUNvdW50NCkKICAgIHsKICAgIAkKICAgIAlpbnQgcDIgPSAoY2UgPj49IDE2KSAmIExBU1RfQllURV9NQVNLXzsgLy8gaW4gaW50cyBmb3IgdW5zaWduZWQgCiAgICAgICAgaW50IHAxID0gY2UgPj4+IDg7ICAvLyBjb21wYXJpc29uCiAgICAJaWYgKGRvU2hpZnQpIHsKICAgIAkJaWYgKG1fdXRpbENvdW50NF8gPiAwKSB7CiAgICAgICAgICAgIAl3aGlsZSAobV91dGlsQ291bnQ0XyA+IGJvdHRvbUNvdW50NCkgewogICAgICAgICAgICAJCW1fdXRpbEJ5dGVzNF8gPSBhcHBlbmQobV91dGlsQnl0ZXM0XywgbV91dGlsQnl0ZXNDb3VudDRfLAogICAgICAgICAgICAJCQkJICAgICAgICAgICAgIChieXRlKShjb21tb25Cb3R0b200ICsgYm90dG9tQ291bnQ0KSk7CiAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfICsrOwogICAgICAgICAgIAkJCW1fdXRpbENvdW50NF8gLT0gYm90dG9tQ291bnQ0OwogICAgICAgICAgIAkJfQogICAgICAgICAgIAkJbV91dGlsQnl0ZXM0XyA9IGFwcGVuZChtX3V0aWxCeXRlczRfLCBtX3V0aWxCeXRlc0NvdW50NF8sCgkJCQkJCQkgICAgICAgICAgIChieXRlKShjb21tb25Cb3R0b200IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAobV91dGlsQ291bnQ0XyAtIDEpKSk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50NF8gKys7CiAgICAgICAgICAgCQltX3V0aWxDb3VudDRfID0gMDsKICAgICAgICAJfQogICAgICAgIAkvLyBkZWFsaW5nIHdpdGggYSB2YXJpYWJsZSBhbmQgd2UncmUgdHJlYXRpbmcgdGhlbSBhcyBzaGlmdGVkCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBzaGlmdGVkIGlnbm9yYWJsZQogICAgICAgICAgICBpZiAocDEgIT0gMCkgeyAKICAgICAgICAgICAgIAkvLyB3ZSBuZWVkIHRvIGNoZWNrIHRoaXMgc2luY2Ugd2UgY291bGQgYmUgaW4gY29udGludWF0aW9uCiAgICAgICAgICAgICAJbV91dGlsQnl0ZXM0XyA9IGFwcGVuZChtX3V0aWxCeXRlczRfLCBtX3V0aWxCeXRlc0NvdW50NF8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSlwMSk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50NF8gKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHAyICE9IDApIHsKICAgICAgICAgICAgCW1fdXRpbEJ5dGVzNF8gPSBhcHBlbmQobV91dGlsQnl0ZXM0XywgbV91dGlsQnl0ZXNDb3VudDRfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpcDIpOwogICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfICsrOwogICAgICAgICAgICB9CiAgICAgICAgfSAKICAgICAgICBlbHNlIHsKICAgICAgICAJLy8gTm90ZTogVGhpcyBjb2RlIGFzc3VtZXMgdGhhdCB0aGUgdGFibGUgaXMgd2VsbCBidWlsdCAKICAgICAgICAJLy8gaS5lLiBub3QgaGF2aW5nIDAgYnl0ZXMgd2hlcmUgdGhleSBhcmUgbm90IHN1cHBvc2VkIHRvIGJlLgogICAgICAgCQkvLyBVc3VhbGx5LCB3ZSdsbCBoYXZlIG5vbi16ZXJvIHByaW1hcnkxICYgcHJpbWFyeTIsIGV4Y2VwdCAKICAgICAgCQkvLyBpbiBjYXNlcyBvZiBMYXRpbk9uZSBhbmQgZnJpZW5kcywgd2hlbiBwcmltYXJ5MiB3aWxsIGJlCiAgICAgICAJCS8vIHJlZ3VsYXIgYW5kIHNpbXBsZSBzb3J0a2V5IGNhbGMgCiAgICAgICAJCWlmIChwMSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CiAgICAgICAgICAgCQlpZiAobm90SXNDb250aW51YXRpb24pIHsKICAgICAgICAgICAJCQlpZiAobGVhZFByaW1hcnkgPT0gcDEpIHsKICAgICAgICAgICAgICAgCQkJbV91dGlsQnl0ZXMxXyA9IGFwcGVuZChtX3V0aWxCeXRlczFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8sIChieXRlKXAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICsrOwogICAgICAgICAgIAkJCX0gCiAgICAgICAgICAgICAgICAgIAllbHNlIHsKICAgICAgICAgICAgICAgICAgICAJaWYgKGxlYWRQcmltYXJ5ICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAJCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgCQkJCShieXRlKSgocDEgPiBsZWFkUHJpbWFyeSkgCiAgICAgICAgICAgICAgICAgICAgCQkJCQkJPyBCWVRFX1VOU0hJRlRFRF9NQVhfIAogICAgICAgICAgICAgICAgICAgICAgCQkJCQkJOiBCWVRFX1VOU0hJRlRFRF9NSU5fKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgICAJaWYgKHAyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKICAgICAgICAgICAgICAgICAgICAJCS8vIG9uZSBieXRlciwgbm90IGNvbXByZXNzZWQKICAgICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKXAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICAgICAgICAgICAgICAgICAgCWxlYWRQcmltYXJ5ID0gMDsKICAgICAgICAgICAgICAgICAgICAJfSAKICAgICAgICAgICAgICAgICAgICAJZWxzZSBpZiAocDEgPCBCWVRFX0ZJUlNUX05PTl9MQVRJTl9QUklNQVJZXwogICAgICAgICAgICAgICAgICAgIAkJICB8fCAocDEgCiAgICAgICAgICAgICAgICAgICAgPiAoUnVsZUJhc2VkQ29sbGF0b3IuVUNBX0NPTlNUQU5UU18uTEFTVF9OT05fVkFSSUFCTEVfWzBdIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4+PiAyNCkKICAgICAgICAgICAgICAgICAgICAJCQkmJiBwMSAKICAgICAgICAgICAgICAgICAgICA8IChSdWxlQmFzZWRDb2xsYXRvci5VQ0FfQ09OU1RBTlRTXy5GSVJTVF9JTVBMSUNJVF9bMF0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPj4+IDI0KSkpIHsKICAgICAgICAgICAgICAgICAgICAJCQkvLyBub3QgY29tcHJlc3NpYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIAkJbGVhZFByaW1hcnkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAJCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpcDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICAgICAgICAgICAgICAgICAgCQltX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKXAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgICAgICAgICAgICAgCX0gCiAgICAgICAgICAgICAgICAgICAgCWVsc2UgeyAvLyBjb21wcmVzcwogICAgICAgICAgICAgICAgICAgIAkJbGVhZFByaW1hcnkgPSBwMTsKICAgICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKXAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfLCAoYnl0ZSlwMik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICBlbHNlIHsgCiAgICAgICAgICAgICAgICAJLy8gY29udGludWF0aW9uLCBhZGQgcHJpbWFyeSB0byB0aGUga2V5LCBubyBjb21wcmVzc2lvbgogICAgICAgICAgICAgICAgICAJbV91dGlsQnl0ZXMxXyA9IGFwcGVuZChtX3V0aWxCeXRlczFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXywgKGJ5dGUpcDEpOwogICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICAgICAgICAgICAgCWlmIChwMiAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CiAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8sIChieXRlKXAyKTsgCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZCBwYXJ0CiAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgCX0KICAgICAgIAlyZXR1cm4gbGVhZFByaW1hcnk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogR2V0cyB0aGUgc2Vjb25kYXJ5IGJ5dGUgYW5kIGFkZHMgaXQgdG8gdGhlIHNlY29uZGFyeSBieXRlIGFycmF5CiAgICAgKiBAcGFyYW0gY2UgY3VycmVudCBjZQogICAgICogQHBhcmFtIG5vdElzQ29udGludWF0aW9uIGZsYWcgaW5kaWNhdGluZyBpZiB0aGUgY3VycmVudCBieXRlcyBiZWxvbmcgdG8gCiAgICAgKiAJCQlhIGNvbnRpbnVhdGlvbiBjZQogICAgICogQHBhcmFtIGRvRnJlbmNoIGZsYWcgaW5kaWNhdG9yIGlmIGZyZW5jaCBzb3J0IGlzIHRvIGJlIHBlcmZvcm1lZAogICAgICovCiAgICBwcml2YXRlIGZpbmFsIHZvaWQgZG9TZWNvbmRhcnlCeXRlcyhpbnQgY2UsIGJvb2xlYW4gbm90SXNDb250aW51YXRpb24sCiAgICAJCQkJCQkgCQkgICAgYm9vbGVhbiBkb0ZyZW5jaCkKICAgIHsKICAgIAlpbnQgcyA9IChjZSA+Pj0gOCkgJiBMQVNUX0JZVEVfTUFTS187IC8vIGludCBmb3IgY29tcGFyaXNvbgogICAgCWlmIChzICE9IDApIHsKICAgIAkJaWYgKCFkb0ZyZW5jaCkgewogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBjb21wcmVzc2lvbiBjb2RlLgogICAgICAgICAgICAgICAgaWYgKHMgPT0gQ09NTU9OXzJfICYmIG5vdElzQ29udGludWF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICBtX3V0aWxDb3VudDJfICsrOwogICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAJaWYgKG1fdXRpbENvdW50Ml8gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgCWlmIChzID4gQ09NTU9OXzJfKSB7IC8vIG5vdCBuZWNlc3NhcnkgZm9yIDR0aCBsZXZlbC4KICAgICAgICAgICAgICAgICAgICAJCXdoaWxlIChtX3V0aWxDb3VudDJfID4gVE9QX0NPVU5UXzJfKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsQnl0ZXMyXyA9IGFwcGVuZChtX3V0aWxCeXRlczJfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDJfLAogICAgICAgICAgICAgICAgICAgICAgICAJCQkJKGJ5dGUpKENPTU1PTl9UT1BfMl8gLSBUT1BfQ09VTlRfMl8pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50Ml8gKys7CiAgICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsQ291bnQyXyAtPSBUT1BfQ09VTlRfMl87CiAgICAgICAgICAgICAgICAgICAgICAJCX0KICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsQnl0ZXMyXyA9IGFwcGVuZChtX3V0aWxCeXRlczJfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50Ml8sCiAgICAgICAgICAgICAgICAgICAgICAJCQkJICAgICAgICAgICAgICAgKGJ5dGUpKENPTU1PTl9UT1BfMl8gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIChtX3V0aWxDb3VudDJfIC0gMSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQyXyArKzsKICAgICAgICAgICAgICAgICAgICAJfSAKICAgICAgICAgICAgICAgICAgICAJZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgCQl3aGlsZSAobV91dGlsQ291bnQyXyA+IEJPVFRPTV9DT1VOVF8yXykgewogICAgICAgICAgICAgICAgICAgICAgICAJCW1fdXRpbEJ5dGVzMl8gPSBhcHBlbmQobV91dGlsQnl0ZXMyXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQyXywKICAgICAgICAgICAgICAgICAgICAgICAgCQkJKGJ5dGUpKENPTU1PTl9CT1RUT01fMl8gKyBCT1RUT01fQ09VTlRfMl8pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50Ml8gKys7CiAgICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsQ291bnQyXyAtPSBCT1RUT01fQ09VTlRfMl87CiAgICAgICAgICAgICAgICAgICAgICAJCX0KICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsQnl0ZXMyXyA9IGFwcGVuZChtX3V0aWxCeXRlczJfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50Ml8sCiAgICAgICAgICAgICAgICAgICAgICAJCQkJICAgICAgICAgICAgICAgKGJ5dGUpKENPTU1PTl9CT1RUT01fMl8gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChtX3V0aWxDb3VudDJfIC0gMSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQyXyArKzsKICAgICAgICAgICAgICAgICAgICAJfQogICAgICAgICAgICAgICAgICAgIAltX3V0aWxDb3VudDJfID0gMDsKICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzMl8gPSBhcHBlbmQobV91dGlsQnl0ZXMyXywgbV91dGlsQnl0ZXNDb3VudDJfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKXMpOwogICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQyXyArKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzMl8gPSBhcHBlbmQobV91dGlsQnl0ZXMyXywgbV91dGlsQnl0ZXNDb3VudDJfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSlzKTsKICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDJfICsrOwogICAgICAgICAgICAgICAgICAvLyBEbyB0aGUgc3BlY2lhbCBoYW5kbGluZyBmb3IgRnJlbmNoIHNlY29uZGFyaWVzCiAgICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZ2V0IGNvbnRpbnVhdGlvbiBlbGVtZW50cyBhbmQgZG8gaW50ZXJtZWRpYXRlIAogICAgICAgICAgICAgICAgICAvLyByZXN0b3JlIAogICAgICAgICAgICAgICAgICAvLyBhYmMxYzJjM2RlIHdpdGggZnJlbmNoIHNlY29uZGFyaWVzIG5lZWQgdG8gYmUgZWRjMWMyYzNiYSAKICAgICAgICAgICAgICAgICAgLy8gTk9UIGVkYzNjMmMxYmEKICAgICAgICAgICAgICAgICAgaWYgKG5vdElzQ29udGludWF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgCWlmIChtX3V0aWxGcmVuY2hTdGFydF8gIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgCS8vIHJldmVyc2Ugc2Vjb25kYXJpZXMgZnJvbSBmcmVuY2hTdGFydFB0ciB1cCB0byAKICAgICAgICAgICAgICAgICAgICAgICAgCS8vIGZyZW5jaEVuZFB0cgogICAgICAgICAgICAgICAgICAgICAgCQlyZXZlcnNlQnVmZmVyKG1fdXRpbEJ5dGVzMl8pOwogICAgICAgICAgICAgICAgICAgICAgCQltX3V0aWxGcmVuY2hTdGFydF8gPSAtMTsgCiAgICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgCWlmIChtX3V0aWxGcmVuY2hTdGFydF8gPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgIAkJbV91dGlsRnJlbmNoU3RhcnRfICA9IG1fdXRpbEJ5dGVzQ291bnQyXyAtIDI7CiAgICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgICAJbV91dGlsRnJlbmNoRW5kXyA9IG1fdXRpbEJ5dGVzQ291bnQyXyAtIDE7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAJfQogICAgCX0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXZlcnNlIHRoZSBhcmd1bWVudCBidWZmZXIgCiAgICAgKiBAcGFyYW0gYnVmZmVyIHRvIHJldmVyc2UKICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHJldmVyc2VCdWZmZXIoYnl0ZSBidWZmZXJbXSkgCiAgICB7IAogICAgCWludCBzdGFydCA9IG1fdXRpbEZyZW5jaFN0YXJ0XzsKICAgIAlpbnQgZW5kID0gbV91dGlsRnJlbmNoRW5kXzsKICAgIAl3aGlsZSAoc3RhcnQgPCBlbmQpIHsgCiAgICAJCWJ5dGUgYiA9IGJ1ZmZlcltzdGFydF07IAogICAgCQlidWZmZXJbc3RhcnQgKytdID0gYnVmZmVyW2VuZF07IAogICAgCQlidWZmZXJbZW5kIC0tXSA9IGI7IAogICAgCX0KCX0KCgkvKioKCSAqIEluc2VydCB0aGUgY2FzZSBzaGlmdGluZyBieXRlIGlmIHJlcXVpcmVkCgkgKiBAcGFyYW0gY2FzZXNoaWZ0IHZhbHVlCgkgKiBAcmV0dXJuIG5ldyBjYXNlc2hpZnQgdmFsdWUKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZG9DYXNlU2hpZnQoaW50IGNhc2VzaGlmdCkgCgl7CiAgCQlpZiAoY2FzZXNoaWZ0ICA9PSAwKSB7CiAgICAJCW1fdXRpbEJ5dGVzMF8gPSBhcHBlbmQobV91dGlsQnl0ZXMwXywgbV91dGlsQnl0ZXNDb3VudDBfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTT1JUX0NBU0VfQllURV9TVEFSVF8pOwogICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MF8gKys7CiAgICAJCWNhc2VzaGlmdCA9IFNPUlRfQ0FTRV9TSElGVF9TVEFSVF87CiAgCQl9CiAgCQlyZXR1cm4gY2FzZXNoaWZ0OwoJfQoKCS8qKgoJICogUGVyZm9ybXMgdGhlIGNhc2luZyBzb3J0CgkgKiBAcGFyYW0gdGVydGlhcnkgYnl0ZSBpbiBpbnRzIGZvciBlYXN5IGNvbXBhcmlzb24KCSAqIEBwYXJhbSBub3RJc0NvbnRpbnVhdGlvbiBmbGFnIGluZGljYXRpbmcgaWYgdGhlIGN1cnJlbnQgYnl0ZXMgYmVsb25nIHRvIAogICAgICogCQkJYSBjb250aW51YXRpb24gY2UKCSAqIEBwYXJhbSBjYXNlc2hpZnQKCSAqIEByZXR1cm4gdGhlIG5ldyB2YWx1ZSBvZiBjYXNlIHNoaWZ0CgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGRvQ2FzZUJ5dGVzKGludCB0ZXJ0aWFyeSwgYm9vbGVhbiBub3RJc0NvbnRpbnVhdGlvbiwgCgkJCQkJCQkgICAgICBpbnQgY2FzZXNoaWZ0KQoJewoJCWNhc2VzaGlmdCA9IGRvQ2FzZVNoaWZ0KGNhc2VzaGlmdCk7CiAgICAgICAgICAgICAgCQkKICAgICAgICBpZiAobm90SXNDb250aW51YXRpb24gJiYgdGVydGlhcnkgIT0gMCkgewogICAgICAgIAlieXRlIGNhc2ViaXRzID0gKGJ5dGUpKHRlcnRpYXJ5ICYgMHhDMCk7CiAgICAgICAgICAgIGlmIChtX2Nhc2VGaXJzdF8gPT0gQXR0cmlidXRlVmFsdWUuVVBQRVJfRklSU1RfKSB7CiAgICAgICAgICAgICAgICBpZiAoY2FzZWJpdHMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzMF9bbV91dGlsQnl0ZXNDb3VudDBfIC0gMV0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHw9ICgxIDw8ICgtLSBjYXNlc2hpZnQpKTsKICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kIGJpdAogICAgICAgICAgICAgICAgICAgICBjYXNlc2hpZnQgPSBkb0Nhc2VTaGlmdChjYXNlc2hpZnQgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXMwX1ttX3V0aWxCeXRlc0NvdW50MF8gLSAxXSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfD0gKChjYXNlYml0cyA+PiA2KSAmIDEpIDw8ICgtLSBjYXNlc2hpZnQpOwogICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChjYXNlYml0cyAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXMwX1ttX3V0aWxCeXRlc0NvdW50MF8gLSAxXSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8PSAxIDw8ICgtLSBjYXNlc2hpZnQpOwogICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZCBiaXQKICAgICAgICAgICAgICAgICAgICBjYXNlc2hpZnQgPSBkb0Nhc2VTaGlmdChjYXNlc2hpZnQpOwogICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzMF9bbV91dGlsQnl0ZXNDb3VudDBfIC0gMV0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8PSAoKGNhc2ViaXRzID4+IDcpICYgMSkgPDwgKC0tIGNhc2VzaGlmdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjYXNlc2hpZnQgLS07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgICAKCQlyZXR1cm4gY2FzZXNoaWZ0OwoJfQoJCgkvKioKCSAqIEdldHMgdGhlIHRlcnRpYXJ5IGJ5dGUgYW5kIGFkZHMgaXQgdG8gdGhlIHRlcnRpYXJ5IGJ5dGUgYXJyYXkKICAgICAqIEBwYXJhbSB0ZXJ0aWFyeSBieXRlIGluIGludCBmb3IgZWFzeSBjb21wYXJpc29uCiAgICAgKiBAcGFyYW0gbm90SXNDb250aW51YXRpb24gZmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBjdXJyZW50IGJ5dGVzIGJlbG9uZyB0byAKICAgICAqIAkJCWEgY29udGludWF0aW9uIGNlCgkgKi8KCXByaXZhdGUgZmluYWwgdm9pZCBkb1RlcnRpYXJ5Qnl0ZXMoaW50IHRlcnRpYXJ5LCBib29sZWFuIG5vdElzQ29udGludWF0aW9uKQoJewoJCWlmICh0ZXJ0aWFyeSAhPSAwKSB7CgkJCS8vIFRoaXMgaXMgY29tcHJlc3Npb24gY29kZS4KICAgICAgICAgICAgLy8gc2VxdWVuY2Ugc2l6ZSBjaGVjayBpcyBpbmNsdWRlZCBpbiB0aGUgaWYgY2xhdXNlCiAgICAgICAgICAgIGlmICh0ZXJ0aWFyeSA9PSBtX2NvbW1vbjNfICYmIG5vdElzQ29udGludWF0aW9uKSB7CiAgICAgICAgICAgICAgICAgbV91dGlsQ291bnQzXyArKzsKICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIAlpbnQgY29tbW9uMyA9IG1fY29tbW9uM18gJiBMQVNUX0JZVEVfTUFTS187CiAgICAgICAgICAgICAgICBpZiAodGVydGlhcnkgPiBjb21tb24zICYmIG1fY29tbW9uM18gPT0gQ09NTU9OX05PUk1BTF8zXykgewogICAgICAgICAgICAgICAgICAgIHRlcnRpYXJ5ICs9IG1fYWRkaXRpb24zXzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRlcnRpYXJ5IDw9IGNvbW1vbjMgCiAgICAgICAgICAgICAgICAgICAgICAgICAmJiBtX2NvbW1vbjNfID09IENPTU1PTl9VUFBFUl9GSVJTVF8zXykgewogICAgICAgICAgICAgICAgICAgIHRlcnRpYXJ5IC09IG1fYWRkaXRpb24zXzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChtX3V0aWxDb3VudDNfID4gMCkgewogICAgICAgICAgICAgICAgCWlmICh0ZXJ0aWFyeSA+IGNvbW1vbjMpIHsKICAgICAgICAgICAgICAgIAkJd2hpbGUgKG1fdXRpbENvdW50M18gPiBtX3RvcENvdW50M18pIHsKICAgICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzM18gPSBhcHBlbmQobV91dGlsQnl0ZXMzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXywKICAgICAgICAgICAgICAgICAgICAgICAgCQkJCQkoYnl0ZSkobV90b3AzXyAtIG1fdG9wQ291bnQzXykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfICsrOwogICAgICAgICAgICAgICAgICAgICAgICAJbV91dGlsQ291bnQzXyAtPSBtX3RvcENvdW50M187CiAgICAgICAgICAgICAgICAgICAgICAJfQogICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbEJ5dGVzM18gPSBhcHBlbmQobV91dGlsQnl0ZXMzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfLAogICAgICAgICAgICAgICAgICAgICAgICAJCSAgICAgICAgICAgICAgIChieXRlKShtX3RvcDNfIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIChtX3V0aWxDb3VudDNfIC0gMSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfICsrOwogICAgICAgICAgICAgICAgIAl9IAogICAgICAgICAgICAgICAgIAllbHNlIHsKICAgICAgICAgICAgICAgICAJCXdoaWxlIChtX3V0aWxDb3VudDNfID4gbV9ib3R0b21Db3VudDNfKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIAltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50M18sCiAgICAgICAgICAgICAgICAgICAgICAgCQkgICAgICAgICAgICAgKGJ5dGUpKG1fYm90dG9tM18gKyBtX2JvdHRvbUNvdW50M18pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyArKzsKICAgICAgICAgICAgICAgICAgICAgICAgCW1fdXRpbENvdW50M18gLT0gbV9ib3R0b21Db3VudDNfOwogICAgICAgICAgICAgICAgICAgICAgCX0KICAgICAgICAgICAgICAgICAgICAgIAltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXywKICAgICAgICAgICAgICAgICAgICAgICAgCQkgICAgICAgICAgICAgICAoYnl0ZSkobV9ib3R0b20zXyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAobV91dGlsQ291bnQzXyAtIDEpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyArKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbV91dGlsQ291bnQzXyA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIG1fdXRpbEJ5dGVzQ291bnQzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKXRlcnRpYXJ5KTsKICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyArKzsKICAgICAgICAgICAgfQogICAgICAgIH0KCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBRdWF0ZXJuYXJ5IGJ5dGUgYW5kIGFkZHMgaXQgdG8gdGhlIFF1YXRlcm5hcnkgYnl0ZSBhcnJheQogICAgICogQHBhcmFtIGlzQ29kZVBvaW50SGlyYWdhbmEgZmxhZyBpbmRpY2F0b3IgaWYgdGhlIHByZXZpb3VzIGNvZGVwb2ludCAKICAgICAqIAkJCXdlIGRlYWx0IHdpdGggd2FzIEhpcmFnYW5hCiAgICAgKiBAcGFyYW0gY29tbW9uQm90dG9tNCBzbWFsbGVzdCBjb21tb24gUXVhdGVybmFyeSBieXRlIAogICAgICogQHBhcmFtIGJvdHRvbUNvdW50NCBzbWFsbGVzdCBRdWF0ZXJuYXJ5IGJ5dGUgCiAgICAgKiBAcGFyYW0gaGlyYWdhbmE0IGhpcmFnYW5hIFF1YXRlcm5hcnkgYnl0ZQoJICovCglwcml2YXRlIGZpbmFsIHZvaWQgZG9RdWF0ZXJuYXJ5Qnl0ZXMoYm9vbGVhbiBpc0NvZGVQb2ludEhpcmFnYW5hLAoJCQkJCQkJCQkgIGludCBjb21tb25Cb3R0b200LCBpbnQgYm90dG9tQ291bnQ0LAoJCQkJCQkJCQkgIGJ5dGUgaGlyYWdhbmE0KQoJewoJCWlmIChpc0NvZGVQb2ludEhpcmFnYW5hKSB7IC8vIFRoaXMgd2FzIEhpcmFnYW5hLCBuZWVkIHRvIG5vdGUgaXQKCQkJaWYgKG1fdXRpbENvdW50NF8gPiAwKSB7IC8vIENsb3NlIHRoaXMgcGFydAogICAgICAgICAgICAJd2hpbGUgKG1fdXRpbENvdW50NF8gPiBib3R0b21Db3VudDQpIHsKICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlczRfID0gYXBwZW5kKG1fdXRpbEJ5dGVzNF8sIG1fdXRpbEJ5dGVzQ291bnQ0XywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoY29tbW9uQm90dG9tNCAKICAgICAgICAgICAgICAgICAgICAJCQkJCQkJCQkrIGJvdHRvbUNvdW50NCkpOwogICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQ0XyArKzsKICAgICAgICAgICAgICAgICAgICBtX3V0aWxDb3VudDRfIC09IGJvdHRvbUNvdW50NDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzNF8gPSBhcHBlbmQobV91dGlsQnl0ZXM0XywgbV91dGlsQnl0ZXNDb3VudDRfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoY29tbW9uQm90dG9tNCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAobV91dGlsQ291bnQ0XyAtIDEpKSk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50NF8gKys7CiAgICAgICAgICAgICAgICBtX3V0aWxDb3VudDRfID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBtX3V0aWxCeXRlczRfID0gYXBwZW5kKG1fdXRpbEJ5dGVzNF8sIG1fdXRpbEJ5dGVzQ291bnQ0XywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlyYWdhbmE0KTsgLy8gQWRkIHRoZSBIaXJhZ2FuYQogICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50NF8gKys7CiAgICAgICAgfSAKICAgICAgICBlbHNlIHsgLy8gVGhpcyB3YXNuJ3QgSGlyYWdhbmEsIHNvIHdlIGNhbiBjb250aW51ZSBhZGRpbmcgc3R1ZmYKICAgICAgICAgICAgbV91dGlsQ291bnQ0XyArKzsKICAgICAgICB9Cgl9CgkKCS8qKgoJICogSXRlcmF0ZXMgdGhyb3VnaCB0aGUgYXJndW1lbnQgc3RyaW5nIGZvciBhbGwgY2VzLgoJICogU3BsaXQgdGhlIGNlcyBpbnRvIHRoZWlyIHJlbGV2YW50IHByaW1hcmllcywgc2Vjb25kYXJpZXMgZXRjLgoJICogQHBhcmFtIHNvdXJjZSBub3JtYWxpemVkIHN0cmluZwoJICogQHBhcmFtIGRvRnJlbmNoIGZsYWcgaW5kaWNhdG9yIGlmIHNwZWNpYWwgaGFuZGxpbmcgb2YgRnJlbmNoIGhhcyB0byBiZQoJICogCQkJCQlkb25lCgkgKiBAcGFyYW0gaGlyYWdhbmE0IG9mZnNldCBmb3IgSGlyYWdhbmEgcXVhdGVybmFyeQoJICogQHBhcmFtIGNvbW1vbkJvdHRvbTQgc21hbGxlc3QgY29tbW9uIHF1YXRlcm5hcnkgYnl0ZQoJICogQHBhcmFtIGJvdHRvbUNvdW50NCBzbWFsbGVzdCBxdWF0ZXJuYXJ5IGJ5dGUKCSAqLwoJcHJpdmF0ZSBmaW5hbCB2b2lkIGdldFNvcnRLZXlCeXRlcyhTdHJpbmcgc291cmNlLCBib29sZWFuIGRvRnJlbmNoLAoJCQkJCQkJCQkgICBieXRlIGhpcmFnYW5hNCwgaW50IGNvbW1vbkJvdHRvbTQsIAoJCQkJCQkJCQkgICBpbnQgYm90dG9tQ291bnQ0KQoJCQkJCQkJCQkgICAKCXsKCQlpbnQgYmFja3VwRGVjb21wb3NpdGlvbiA9IGdldERlY29tcG9zaXRpb24oKTsKCQlzZXREZWNvbXBvc2l0aW9uKE5PX0RFQ09NUE9TSVRJT04pOyAvLyBoYXZlIHRvIHJldmVydCB0byBiYWNrdXAgbGF0ZXIKICAgIAltX3NyY1V0aWxJdGVyXy5zZXRUZXh0KHNvdXJjZSk7CiAgICAgICAgbV9zcmNVdGlsQ29sRUl0ZXJfLnNldFRleHQobV9zcmNVdGlsSXRlcl8pOwogICAgCW1fdXRpbEZyZW5jaFN0YXJ0XyA9IC0xOyAKICAgICAgICBtX3V0aWxGcmVuY2hFbmRfID0gLTE7CiAgICAJCiAgICAJLy8gc2NyaXB0b3JkZXIgbm90IGltcGxlbWVudGVkIHlldCAKICAgIAkvLyBjb25zdCB1aW50OF90ICpzY3JpcHRPcmRlciA9IGNvbGwtPnNjcmlwdE9yZGVyOwoKCQlib29sZWFuIGRvU2hpZnQgPSBmYWxzZTsKICAgIAlib29sZWFuIG5vdElzQ29udGludWF0aW9uID0gZmFsc2U7CgogICAgCWludCBsZWFkUHJpbWFyeSA9IDA7IC8vIGludCBmb3IgZWFzaWVyIGNvbXBhcmlzb24KICAgIAlpbnQgY2FzZVNoaWZ0ID0gMDsKCSAgICAKICAgIAl3aGlsZSAodHJ1ZSkgewogICAgICAgIAlpbnQgY2UgPSBtX3NyY1V0aWxDb2xFSXRlcl8ubmV4dCgpOwogICAgICAgICAgICBpZiAoY2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewogICAgICAgICAgICAJYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CiAgICAgICAgICAgIAljb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbm90SXNDb250aW51YXRpb24gPSAhaXNDb250aW51YXRpb24oY2UpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgKG5vdElzQ29udGludWF0aW9uKSB7CiAgICAgICAgICAgIAkJaWYgKHNjcmlwdE9yZGVyICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIAkJcHJpbWFyeTEgPSBzY3JpcHRPcmRlcltwcmltYXJ5MV07CiAgICAgICAgICAgICAgCQl9CiAgICAgICAgICAgIAl9Ki8KICAgICAgICAgICAgYm9vbGVhbiBpc1ByaW1hcnlCeXRlSWdub3JhYmxlID0gKGNlICYgQ0VfUFJJTUFSWV9NQVNLXykgPT0gMDsKICAgICAgICAgICAgLy8gYWN0dWFsbHkgd2UgY2FuIGp1c3QgY2hlY2sgdGhhdCB0aGUgZmlyc3QgYnl0ZSBpcyAwCiAgICAgICAgICAgIC8vIGdlbmVyYXRpb24gc3R1ZmZzIHRoZSBvcmRlciBsZWZ0IGZpcnN0CiAgICAgICAgICAgIGJvb2xlYW4gaXNTbWFsbGVyVGhhblZhcmlhYmxlVG9wID0gKGNlID4+PiBDRV9QUklNQVJZX1NISUZUXykgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD0gbV92YXJpYWJsZVRvcFZhbHVlXzsKICAgICAgICAgICAgZG9TaGlmdCA9IChtX2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXyAKICAgICAgICAgICAgCQkJJiYgKChub3RJc0NvbnRpbnVhdGlvbiAmJiBpc1NtYWxsZXJUaGFuVmFyaWFibGVUb3AgCiAgICAJCQkJCQkmJiAhaXNQcmltYXJ5Qnl0ZUlnbm9yYWJsZSkgLy8gcHJpbWFyeSBieXRlIG5vdCAwCiAgICAJCQkJCXx8ICghbm90SXNDb250aW51YXRpb24gJiYgZG9TaGlmdCkpIAogICAgCQkJCQl8fCAoZG9TaGlmdCAmJiBpc1ByaW1hcnlCeXRlSWdub3JhYmxlKSk7CiAgICAgICAgICAgIGlmIChkb1NoaWZ0ICYmIGlzUHJpbWFyeUJ5dGVJZ25vcmFibGUpIHsKICAgIAkJCS8vIGFtZW5kbWVudCB0byB0aGUgVUNBIHNheXMgdGhhdCBwcmltYXJ5IGlnbm9yYWJsZXMgYW5kIG90aGVyIAogICAgCQkJLy8gaWdub3JhYmxlcyBzaG91bGQgYmUgcmVtb3ZlZCBpZiBmb2xsb3dpbmcgYSBzaGlmdGVkIGNvZGUgCiAgICAJCQkvLyBwb2ludAogICAgICAgICAgICAgICAgLy8gaWYgd2Ugd2VyZSBzaGlmdGVkIGFuZCB3ZSBnb3QgYW4gaWdub3JhYmxlIGNvZGUgcG9pbnQKICAgICAgICAgICAgICAgIC8vIHdlIHNob3VsZCBqdXN0IGNvbXBsZXRlbHkgaWdub3JlIGl0CiAgICAgICAgICAgICAgICBjb250aW51ZTsgCiAgICAgICAgICAgIH0gCgkJCWxlYWRQcmltYXJ5ID0gZG9QcmltYXJ5Qnl0ZXMoY2UsIG5vdElzQ29udGludWF0aW9uLCBkb1NoaWZ0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWFkUHJpbWFyeSwgY29tbW9uQm90dG9tNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm90dG9tQ291bnQ0KTsKICAgICAgICAgICAgaWYgKGRvU2hpZnQpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgkJCWlmIChtX3V0aWxDb21wYXJlMl8pIHsKICAgICAgICAJCWRvU2Vjb25kYXJ5Qnl0ZXMoY2UsIG5vdElzQ29udGludWF0aW9uLAlkb0ZyZW5jaCk7CgkJCX0KCgkJCWludCB0ID0gY2UgJiBMQVNUX0JZVEVfTUFTS187CgkJCWlmICghbm90SXNDb250aW51YXRpb24pIHsKICAgICAgICAgICAgICAJdCA9IGNlICYgQ0VfUkVNT1ZFX0NPTlRJTlVBVElPTl9NQVNLXzsKICAgICAgICAgICAgfQogICAgICAgICAgICAJCiAgICAgICAgICAgIGlmIChtX3V0aWxDb21wYXJlMF8pIHsKICAgICAgICAgICAgICAJY2FzZVNoaWZ0ID0gZG9DYXNlQnl0ZXModCwgbm90SXNDb250aW51YXRpb24sIGNhc2VTaGlmdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAobm90SXNDb250aW51YXRpb24pIHsKICAgICAgICAgICAgICAgICB0IF49IG1fY2FzZVN3aXRjaF87CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHQgJj0gbV9tYXNrM187CiAgICAgICAgICAgICAgCQogICAgICAgICAgICBpZiAobV91dGlsQ29tcGFyZTNfKSB7CiAgICAgICAgICAgIAlkb1RlcnRpYXJ5Qnl0ZXModCwgbm90SXNDb250aW51YXRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgaWYgKG1fdXRpbENvbXBhcmU0XyAmJiBub3RJc0NvbnRpbnVhdGlvbikgeyAvLyBjb21wYXJlIHF1YWQKICAgICAgICAgICAgICAgIGRvUXVhdGVybmFyeUJ5dGVzKG1fc3JjVXRpbENvbEVJdGVyXy5tX2lzQ29kZVBvaW50SGlyYWdhbmFfLCAKICAgICAgICAgICAgICAgIAkJCSAJICBjb21tb25Cb3R0b200LCBib3R0b21Db3VudDQsIGhpcmFnYW5hNCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2V0RGVjb21wb3NpdGlvbihiYWNrdXBEZWNvbXBvc2l0aW9uKTsgLy8gcmV2ZXJ0cyB0byBvcmlnaW5hbAkKICAgICAgICBpZiAobV91dGlsRnJlbmNoU3RhcnRfICE9IC0xKSB7CiAgICAgICAgCS8vIG9uZSBsYXN0IHJvdW5kIG9mIGNoZWNrcwogICAgCQlyZXZlcnNlQnVmZmVyKG1fdXRpbEJ5dGVzMl8pOwogIAkJfQoJfQoJCgkvKioKCSAqIEZyb20gdGhlIGluZGl2aWR1YWwgc3RyZW5ndGggYnl0ZSByZXN1bHRzIHRoZSBmaW5hbCBjb21wYWN0IHNvcnRrZXkgCgkgKiB3aWxsIGJlIGNhbGN1bGF0ZWQuCgkgKiBAcGFyYW0gc291cmNlIHRleHQgc3RyaW5nCgkgKiBAcGFyYW0gZG9GcmVuY2ggZmxhZyBpbmRpY2F0aW5nIHRoYXQgc3BlY2lhbCBoYW5kbGluZyBvZiBGcmVuY2ggaGFzIHRvIAoJICogCQkJCQliZSBkb25lCgkgKiBAcGFyYW0gY29tbW9uQm90dG9tNCBzbWFsbGVzdCBjb21tb24gcXVhdGVybmFyeSBieXRlCgkgKiBAcGFyYW0gYm90dG9tQ291bnQ0IHNtYWxsZXN0IHF1YXRlcm5hcnkgYnl0ZQoJICogQHJldHVybiB0aGUgY29tcGFjdCBzb3J0a2V5CgkgKi8KCXByaXZhdGUgZmluYWwgYnl0ZVtdIGdldFNvcnRLZXkoU3RyaW5nIHNvdXJjZSwgYm9vbGVhbiBkb0ZyZW5jaCwgCgkJCQkJCQkJCWludCBjb21tb25Cb3R0b200LCBpbnQgYm90dG9tQ291bnQ0KQoJewoJCS8vIHdlIGhhdmUgZG9uZSBhbGwgdGhlIENFJ3MsIG5vdyBsZXQncyBwdXQgdGhlbSB0b2dldGhlciB0byBmb3JtIAogICAgICAJLy8gYSBrZXkgCiAgICAgIAlpZiAobV91dGlsQ29tcGFyZTJfKSB7CiAgICAgICAgCWRvU2Vjb25kYXJ5KGRvRnJlbmNoKTsKICAgICAgCQlpZiAobV91dGlsQ29tcGFyZTBfKSB7CgkJCQlkb0Nhc2UoKTsgICAgICAgIAogICAgICAJCX0KICAgICAgCQlpZiAobV91dGlsQ29tcGFyZTNfKSB7CiAgICAgIAkJCWRvVGVydGlhcnkoKTsKICAgICAgCQkJaWYgKG1fdXRpbENvbXBhcmU0XykgewogICAgICAJCQkJZG9RdWF0ZXJuYXJ5KGNvbW1vbkJvdHRvbTQsIGJvdHRvbUNvdW50NCk7CiAgICAgICAgCQkJaWYgKG1fdXRpbENvbXBhcmU1XykgewogICAgICAgICAgCQkJCWRvSWRlbnRpY2FsKHNvdXJjZSk7CiAgICAgICAgCQkJfQoKICAgICAgCQkJfQogICAgICAJCX0KICAgICAgCX0KICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAoYnl0ZSkwKTsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgYnl0ZSByZXN1bHRbXSA9IChieXRlIFtdKW1fdXRpbEJ5dGVzMV8uY2xvbmUoKTsKICAgIAlyZXR1cm4gcmVzdWx0OwoJfQoJCgkvKioKCSAqIFBhY2tzIHRoZSBGcmVuY2ggYnl0ZXMKCSAqIEBwYXJhbSBjb3VudCBhcnJheSBvZiBjb21wcmVzc2lvbiBjb3VudHMKCSAqLwoJcHJpdmF0ZSBmaW5hbCB2b2lkIGRvRnJlbmNoKCkgCgl7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBtX3V0aWxCeXRlc0NvdW50Ml87IGkgKyspIHsKCQkJYnl0ZSBzID0gbV91dGlsQnl0ZXMyX1ttX3V0aWxCeXRlc0NvdW50Ml8gLSBpIC0gMV07CgkJICAgIC8vIFRoaXMgaXMgY29tcHJlc3Npb24gY29kZS4KCQkgICAgaWYgKHMgPT0gQ09NTU9OXzJfKSB7CgkJICAgICAgICArKyBtX3V0aWxDb3VudDJfOwoJCSAgICB9IAoJCSAgICBlbHNlIHsKCQkgICAgICAJaWYgKG1fdXRpbENvdW50Ml8gPiAwKSB7CgkJICAgICAgCQkvLyBnZXR0aW5nIHRoZSB1bnNpZ25lZCB2YWx1ZQoJCSAgICAgICAgCWlmICgocyAmIExBU1RfQllURV9NQVNLXykgPiBDT01NT05fMl8pIHsgCgkJICAgICAgICAJCS8vIG5vdCBuZWNlc3NhcnkgZm9yIDR0aCBsZXZlbC4KCQkgICAgICAgICAgCQl3aGlsZSAobV91dGlsQ291bnQyXyA+IFRPUF9DT1VOVF8yXykgewoJCSAgICAgICAgICAgIAkJbV91dGlsQnl0ZXMxXyA9IGFwcGVuZChtX3V0aWxCeXRlczFfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8sIAoJCSAgICAgICAgICAgIAkJCQkJKGJ5dGUpKENPTU1PTl9UT1BfMl8gLSBUT1BfQ09VTlRfMl8pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKCQkgICAgICAgICAgICAJCW1fdXRpbENvdW50Ml8gLT0gVE9QX0NPVU5UXzJfOwoJCSAgICAgICAgICAJCX0KCQkgICAgICAgICAgCQltX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoQ09NTU9OX1RPUF8yXyAKCQkgICAgICAgICAgCQkJCQkJCQkJICAtIChtX3V0aWxDb3VudDJfIC0gMSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICsrOwoJCSAgICAgICAgCX0gCgkJICAgICAgICAJZWxzZSB7CgkJICAgICAgICAgIAkJd2hpbGUgKG1fdXRpbENvdW50Ml8gPiBCT1RUT01fQ09VTlRfMl8pIHsKCQkgICAgICAgICAgICAJCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfLCAKCQkgICAgICAgICAgICAJCQkoYnl0ZSkoQ09NTU9OX0JPVFRPTV8yXyArIEJPVFRPTV9DT1VOVF8yXykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICsrOwoJCSAgICAgICAgICAgIAkJbV91dGlsQ291bnQyXyAtPSBCT1RUT01fQ09VTlRfMl87CgkJICAgICAgICAgIAkJfQoJCSAgICAgICAgICAJCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8sICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoQ09NTU9OX0JPVFRPTV8yXyAKCQkgICAgICAgICAgCQkJCQkJCQkJICArIChtX3V0aWxDb3VudDJfIC0gMSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICsrOwoJCSAgICAgICAgCX0KCQkgICAgICAgIAltX3V0aWxDb3VudDJfID0gMDsKCQkgICAgICAJfQoJCSAgICAgIAltX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sIG1fdXRpbEJ5dGVzQ291bnQxXywgcyk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CgkJICAgIH0KCQl9CgkJaWYgKG1fdXRpbENvdW50Ml8gPiAwKSB7CgkJICAgIHdoaWxlIChtX3V0aWxDb3VudDJfID4gQk9UVE9NX0NPVU5UXzJfKSB7CgkJICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGUpKENPTU1PTl9CT1RUT01fMl8gCgkJICAgICAgCQkJCQkJCQkJCSsgQk9UVE9NX0NPVU5UXzJfKSk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CgkJICAgICAgCW1fdXRpbENvdW50Ml8gLT0gQk9UVE9NX0NPVU5UXzJfOwoJCSAgICB9CgkJICAgIG1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoQ09NTU9OX0JPVFRPTV8yXyAKCQkgICAgCQkJCQkJCQkJCSsgKG1fdXRpbENvdW50Ml8gLSAxKSkpOwogICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CgkJfQoJfQoKCS8qKgoJICogQ29tcGFjdHMgdGhlIHNlY29uZGFyeSBieXRlcyBhbmQgc3RvcmVzIHRoZW0gaW50byB0aGUgcHJpbWFyeSBhcnJheQoJICogQHBhcmFtIGRvRnJlbmNoIGZsYWcgaW5kaWNhdG9yIHRoYXQgRnJlbmNoIGhhcyB0byBiZSBoYW5kbGVkIHNwZWNpYWxseQoJICovCglwcml2YXRlIGZpbmFsIHZvaWQgZG9TZWNvbmRhcnkoYm9vbGVhbiBkb0ZyZW5jaCkKCXsKCQlpZiAobV91dGlsQ291bnQyXyA+IDApIHsKICAgICAgICAgIAl3aGlsZSAobV91dGlsQ291bnQyXyA+IEJPVFRPTV9DT1VOVF8yXykgewogICAgICAgICAgICAJbV91dGlsQnl0ZXMyXyA9IGFwcGVuZChtX3V0aWxCeXRlczJfLCBtX3V0aWxCeXRlc0NvdW50Ml8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShDT01NT05fQk9UVE9NXzJfIAogICAgICAgICAgICAJCQkJCSAJCQkJCQkrIEJPVFRPTV9DT1VOVF8yXykpOwogICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDJfICsrOwogICAgICAgICAgICAJbV91dGlsQ291bnQyXyAtPSBCT1RUT01fQ09VTlRfMl87CiAgICAgICAgICAJfQogICAgICAgICAgCW1fdXRpbEJ5dGVzMl8gPSBhcHBlbmQobV91dGlsQnl0ZXMyXywgbV91dGlsQnl0ZXNDb3VudDJfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShDT01NT05fQk9UVE9NXzJfICsgCiAgICAgICAgICAJCQkJCQkJCQkJCShtX3V0aWxDb3VudDJfIC0gMSkpKTsKICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDJfICsrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBtX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTT1JUX0xFVkVMX1RFUk1JTkFUT1JfKTsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgCiAgICAgICAgaWYgKGRvRnJlbmNoKSB7IC8vIGRvIHRoZSByZXZlcnNlIGNvcHkKICAgICAgICAgICAJZG9GcmVuY2goKTsKICAgICAgICB9IAogICAgICAgIGVsc2UgewogICAgICAgIAlpZiAobV91dGlsQnl0ZXMxXy5sZW5ndGggPD0gbV91dGlsQnl0ZXNDb3VudDFfCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1fdXRpbEJ5dGVzQ291bnQyXykgewogICAgICAgIAkJbV91dGlsQnl0ZXMxXyA9IGluY3JlYXNlKG1fdXRpbEJ5dGVzMV8sIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDJfKTsKICAgICAgICAJfQogICAgICAgICAgIAlTeXN0ZW0uYXJyYXljb3B5KG1fdXRpbEJ5dGVzMl8sIDAsIG1fdXRpbEJ5dGVzMV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXywgbV91dGlsQnl0ZXNDb3VudDJfKTsKICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICs9IG1fdXRpbEJ5dGVzQ291bnQyXzsKICAgICAgICB9IAoJfQoJCgkvKioKCSAqIEluY3JlYXNlIGJ1ZmZlciBzaXplCgkgKiBAcGFyYW0gYXJyYXkgYXJyYXkgb2YgYnl0ZXMKCSAqIEBwYXJhbSBzaXplIG9mIHRoZSBieXRlIGFycmF5CgkgKiBAcGFyYW0gaW5jcmVtZW50c2l6ZSBzaXplIHRvIGluY3JlYXNlCgkgKiBAcmV0dXJuIHRoZSBuZXcgYnVmZmVyCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBpbmNyZWFzZShieXRlIGJ1ZmZlcltdLCBpbnQgc2l6ZSwgCgkJCQkJCQkJCQkgaW50IGluY3JlbWVudHNpemUpCgl7CgkJYnl0ZSByZXN1bHRbXSA9IG5ldyBieXRlW2J1ZmZlci5sZW5ndGggKyBpbmNyZW1lbnRzaXplXTsKCQlTeXN0ZW0uYXJyYXljb3B5KGJ1ZmZlciwgMCwgcmVzdWx0LCAwLCBzaXplKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJCgkvKioKCSAqIEluY3JlYXNlIGJ1ZmZlciBzaXplCgkgKiBAcGFyYW0gYXJyYXkgYXJyYXkgb2YgYnl0ZXMKCSAqIEBwYXJhbSBzaXplIG9mIHRoZSBieXRlIGFycmF5CgkgKiBAcGFyYW0gaW5jcmVtZW50c2l6ZSBzaXplIHRvIGluY3JlYXNlCgkgKiBAcmV0dXJuIHRoZSBuZXcgYnVmZmVyCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludFtdIGluY3JlYXNlKGludCBidWZmZXJbXSwgaW50IHNpemUsIAoJCQkJCQkJCQkJaW50IGluY3JlbWVudHNpemUpCgl7CgkJaW50IHJlc3VsdFtdID0gbmV3IGludFtidWZmZXIubGVuZ3RoICsgaW5jcmVtZW50c2l6ZV07CgkJU3lzdGVtLmFycmF5Y29weShidWZmZXIsIDAsIHJlc3VsdCwgMCwgc2l6ZSk7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBDb21wYWN0cyB0aGUgY2FzZSBieXRlcyBhbmQgc3RvcmVzIHRoZW0gaW50byB0aGUgcHJpbWFyeSBhcnJheQoJICovCglwcml2YXRlIGZpbmFsIHZvaWQgZG9DYXNlKCkKCXsKCQltX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTT1JUX0xFVkVMX1RFUk1JTkFUT1JfKTsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CgkJaWYgKG1fdXRpbEJ5dGVzMV8ubGVuZ3RoIDw9IG1fdXRpbEJ5dGVzQ291bnQxXyArIG1fdXRpbEJ5dGVzQ291bnQwXykgewoJCQltX3V0aWxCeXRlczFfID0gaW5jcmVhc2UobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQwXyk7CgkJfQoJCVN5c3RlbS5hcnJheWNvcHkobV91dGlsQnl0ZXMwXywgMCwgbV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQwXyk7CiAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICs9IG1fdXRpbEJ5dGVzQ291bnQwXzsKCX0KCQoJLyoqCgkgKiBDb21wYWN0cyB0aGUgdGVydGlhcnkgYnl0ZXMgYW5kIHN0b3JlcyB0aGVtIGludG8gdGhlIHByaW1hcnkgYXJyYXkKCSAqLwoJcHJpdmF0ZSBmaW5hbCB2b2lkIGRvVGVydGlhcnkoKQoJewoJCWlmIChtX3V0aWxDb3VudDNfID4gMCkgewogICAgICAgICAgCWlmIChtX2NvbW1vbjNfICE9IENPTU1PTl9CT1RUT01fM18pIHsKICAgICAgICAgIAkJd2hpbGUgKG1fdXRpbENvdW50M18gPj0gbV90b3BDb3VudDNfKSB7CiAgICAgICAgICAgICAgCQltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIG1fdXRpbEJ5dGVzQ291bnQzXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShtX3RvcDNfIC0gbV90b3BDb3VudDNfKSk7CiAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfICsrOwogICAgICAgICAgICAgIAkJbV91dGlsQ291bnQzXyAtPSBtX3RvcENvdW50M187CiAgICAgICAgICAgIAl9CiAgICAgICAgICAgIAltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIG1fdXRpbEJ5dGVzQ291bnQzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShtX3RvcDNfIC0gbV91dGlsQ291bnQzXykpOwogICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfICsrOwogICAgICAgICAgCX0gCiAgICAgICAgICAJZWxzZSB7CiAgICAgICAgICAJCXdoaWxlIChtX3V0aWxDb3VudDNfID4gbV9ib3R0b21Db3VudDNfKSB7CiAgICAgICAgICAgICAgCQltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIG1fdXRpbEJ5dGVzQ291bnQzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkobV9ib3R0b20zXyAKICAgICAgICAgICAgICAJCQkJCQkJCQkJCSsgbV9ib3R0b21Db3VudDNfKSk7CiAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDNfICsrOwogICAgICAgICAgICAgIAkJbV91dGlsQ291bnQzXyAtPSBtX2JvdHRvbUNvdW50M187CiAgICAgICAgICAgIAl9CiAgICAgICAgICAgIAltX3V0aWxCeXRlczNfID0gYXBwZW5kKG1fdXRpbEJ5dGVzM18sIG1fdXRpbEJ5dGVzQ291bnQzXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShtX2JvdHRvbTNfIAogICAgICAgICAgICAJCQkJCQkJCSAgKyAobV91dGlsQ291bnQzXyAtIDEpKSk7CiAgICAgICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50M18gKys7CiAgICAgICAgICAJfQogICAgICAgIH0KICAgICAgICBtX3V0aWxCeXRlczFfID0gYXBwZW5kKG1fdXRpbEJ5dGVzMV8sIG1fdXRpbEJ5dGVzQ291bnQxXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTT1JUX0xFVkVMX1RFUk1JTkFUT1JfKTsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKys7CiAgICAgICAgaWYgKG1fdXRpbEJ5dGVzMV8ubGVuZ3RoIDw9IG1fdXRpbEJ5dGVzQ291bnQxXyArIG1fdXRpbEJ5dGVzQ291bnQzXykgewogICAgICAgIAltX3V0aWxCeXRlczFfID0gaW5jcmVhc2UobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyk7CiAgICAgICAgfQogICAgICAgIFN5c3RlbS5hcnJheWNvcHkobV91dGlsQnl0ZXMzXywgMCwgbV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQzXyk7CiAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICs9IG1fdXRpbEJ5dGVzQ291bnQzXzsKCX0KCQoJLyoqCgkgKiBDb21wYWN0cyB0aGUgcXVhdGVybmFyeSBieXRlcyBhbmQgc3RvcmVzIHRoZW0gaW50byB0aGUgcHJpbWFyeSBhcnJheQoJICovCglwcml2YXRlIGZpbmFsIHZvaWQgZG9RdWF0ZXJuYXJ5KGludCBjb21tb25ib3R0b200LCBpbnQgYm90dG9tY291bnQ0KQoJewoJCWlmIChtX3V0aWxDb3VudDRfID4gMCkgewogICAgICAgICAgICB3aGlsZSAobV91dGlsQ291bnQ0XyA+IGJvdHRvbWNvdW50NCkgewogICAgICAgICAgICAgICAgbV91dGlsQnl0ZXM0XyA9IGFwcGVuZChtX3V0aWxCeXRlczRfLCBtX3V0aWxCeXRlc0NvdW50NF8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZSkoY29tbW9uYm90dG9tNCArIGJvdHRvbWNvdW50NCkpOwogICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfICsrOwogICAgICAgICAgICAgICAgbV91dGlsQ291bnQ0XyAtPSBib3R0b21jb3VudDQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbV91dGlsQnl0ZXM0XyA9IGFwcGVuZChtX3V0aWxCeXRlczRfLCBtX3V0aWxCeXRlc0NvdW50NF8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlKShjb21tb25ib3R0b200CiAgICAgICAgICAgIAkJCQkJCQkJCSsgKG1fdXRpbENvdW50NF8gLSAxKSkpOwogICAgICAgICAgICBtX3V0aWxCeXRlc0NvdW50NF8gKys7CiAgICAgICAgfQogICAgICAgIG1fdXRpbEJ5dGVzMV8gPSBhcHBlbmQobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNPUlRfTEVWRUxfVEVSTUlOQVRPUl8pOwogICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyArKzsKICAgICAgICBpZiAobV91dGlsQnl0ZXMxXy5sZW5ndGggPD0gbV91dGlsQnl0ZXNDb3VudDFfICsgbV91dGlsQnl0ZXNDb3VudDRfKSB7CiAgICAgICAgCW1fdXRpbEJ5dGVzMV8gPSBpbmNyZWFzZShtX3V0aWxCeXRlczFfLCBtX3V0aWxCeXRlc0NvdW50MV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfKTsKICAgICAgICB9CiAgICAgICAgU3lzdGVtLmFycmF5Y29weShtX3V0aWxCeXRlczRfLCAwLCBtX3V0aWxCeXRlczFfLCBtX3V0aWxCeXRlc0NvdW50MV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgbV91dGlsQnl0ZXNDb3VudDRfKTsKICAgICAgICBtX3V0aWxCeXRlc0NvdW50MV8gKz0gbV91dGlsQnl0ZXNDb3VudDRfOwoJfQoJCgkvKioKCSAqIERlYWxzIHdpdGggdGhlIGlkZW50aWNhbCBzb3J0LgoJICogQXBwZW5kcyB0aGUgQk9DU1UgdmVyc2lvbiBvZiB0aGUgc291cmNlIHN0cmluZyB0byB0aGUgZW5kcyBvZiB0aGUKCSAqIGJ5dGUgYnVmZmVyLgoJICogQHBhcmFtIHNvdXJjZSB0ZXh0IHN0cmluZwoJICovCglwcml2YXRlIGZpbmFsIHZvaWQgZG9JZGVudGljYWwoU3RyaW5nIHNvdXJjZSkKCXsKCQlpbnQgaXNpemUgPSBCT0NVLmdldENvbXByZXNzaW9uTGVuZ3RoKHNvdXJjZSk7CgkJbV91dGlsQnl0ZXMxXyA9IGFwcGVuZChtX3V0aWxCeXRlczFfLCBtX3V0aWxCeXRlc0NvdW50MV8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU09SVF9MRVZFTF9URVJNSU5BVE9SXyk7CiAgICAgICAgbV91dGlsQnl0ZXNDb3VudDFfICsrOwoJCWlmIChtX3V0aWxCeXRlczFfLmxlbmd0aCA8PSBtX3V0aWxCeXRlc0NvdW50MV8gKyBpc2l6ZSkgewogICAgICAgIAltX3V0aWxCeXRlczFfID0gaW5jcmVhc2UobV91dGlsQnl0ZXMxXywgbV91dGlsQnl0ZXNDb3VudDFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyBpc2l6ZSk7CiAgICAgICAgfQogICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyA9IEJPQ1UuY29tcHJlc3Moc291cmNlLCBtX3V0aWxCeXRlczFfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdXRpbEJ5dGVzQ291bnQxXyk7IAoJfQoJCgkvKioKCSAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgZmlyc3QgdW5tYXRjaGVkIGNoYXJhY3RlcnMgaW4gc291cmNlIGFuZCB0YXJnZXQuCgkgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBvZmZzZXQgb2YgdGhlIHN0YXJ0IG9mIGEgY29udHJhY3Rpb24gb3IgYSAKCSAqIGNvbWJpbmluZyBzZXF1ZW5jZSwgaWYgdGhlIGZpcnN0IGRpZmZlcmVuY2UgaXMgaW4gdGhlIG1pZGRsZSBvZiBzdWNoIGEgCgkgKiBzZXF1ZW5jZS4KCSAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nCgkgKiBAcGFyYW0gdGFyZ2V0IHN0cmluZwoJICogQHJldHVybiBvZmZzZXQgb2YgdGhlIGZpcnN0IHVubWF0Y2hlZCBjaGFyYWN0ZXJzIGluIHNvdXJjZSBhbmQgdGFyZ2V0LgoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXRGaXJzdFVubWF0Y2hlZE9mZnNldChTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0KQoJewoJCWludCByZXN1bHQgPSAwOwoJCWludCBzbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwoJCWludCB0bGVuZ3RoID0gdGFyZ2V0Lmxlbmd0aCgpOwoJCWludCBtaW5sZW5ndGggPSBzbGVuZ3RoOwoJCWlmIChtaW5sZW5ndGggPiB0bGVuZ3RoKSB7CgkJCW1pbmxlbmd0aCA9IHRsZW5ndGg7CgkJfQoJCXdoaWxlIChyZXN1bHQgPCBtaW5sZW5ndGggCgkJCQkmJiBzb3VyY2UuY2hhckF0KHJlc3VsdCkgPT0gdGFyZ2V0LmNoYXJBdChyZXN1bHQpKSB7CgkJCXJlc3VsdCArKzsKCSAgICB9CgkgICAgaWYgKHJlc3VsdCA+IDApIHsKCSAgICAgICAgLy8gVGhlcmUgaXMgYW4gaWRlbnRpY2FsIHBvcnRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdHdvIAoJICAgICAgICAvLyBzdHJpbmdzLiBJZiB0aGUgaWRlbnRpY2FsIHBvcnRpb24gZW5kcyB3aXRoaW4gYSBjb250cmFjdGlvbiBvciBhIAoJICAgICAgICAvLyBjb21iaW5pbmcgY2hhcmFjdGVyIHNlcXVlbmNlLCBiYWNrIHVwIHRvIHRoZSBzdGFydCBvZiB0aGF0IAoJICAgICAgICAvLyBzZXF1ZW5jZS4KCSAgICAgICAgY2hhciBzY2hhciA9IDA7CgkgICAgICAgIGNoYXIgdGNoYXIgPSAwOwoJICAgICAgICBpZiAocmVzdWx0IDwgbWlubGVuZ3RoKSB7ICAgICAgICAgICAgICAKCSAgICAgICAgCXNjaGFyID0gc291cmNlLmNoYXJBdChyZXN1bHQpOyAvLyBmaXJzdCBkaWZmZXJpbmcgY2hhcnMgICAKCSAgICAgICAgCXRjaGFyID0gdGFyZ2V0LmNoYXJBdChyZXN1bHQpOwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc2NoYXIgPSBzb3VyY2UuY2hhckF0KG1pbmxlbmd0aCAtIDEpOyAKICAgICAgICAgICAgICAgIGlmIChpc1Vuc2FmZShzY2hhcikpIHsKICAgICAgICAgICAgICAgICAgICB0Y2hhciA9IHNjaGFyOwogICAgICAgICAgICAgICAgfQogICAgCSAgICAgICAgZWxzZSBpZiAoc2xlbmd0aCA9PSB0bGVuZ3RoKSB7CiAgICAJICAgICAgICAJCXJldHVybiByZXN1bHQ7CiAgICAJICAgICAgICB9CiAgICAJICAgICAgICBlbHNlIGlmIChzbGVuZ3RoIDwgdGxlbmd0aCkgewogICAgCSAgICAgICAgCXRjaGFyID0gdGFyZ2V0LmNoYXJBdChyZXN1bHQpOwogICAgCSAgICAgICAgfQogICAgCSAgICAgICAgZWxzZSB7CiAgICAJICAgICAgICAJc2NoYXIgPSBzb3VyY2UuY2hhckF0KHJlc3VsdCk7CiAgICAJICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgaWYgKGlzVW5zYWZlKHNjaGFyKSB8fCBpc1Vuc2FmZSh0Y2hhcikpCgkgICAgICAgIHsKCSAgICAgICAgICAgIC8vIFdlIGFyZSBzdG9wcGVkIGluIHRoZSBtaWRkbGUgb2YgYSBjb250cmFjdGlvbiBvciBjb21iaW5pbmcKCSAgICAgICAgICAgIC8vIHNlcXVlbmNlLgoJICAgICAgICAgICAgLy8gTG9vayBiYWNrd2FyZHMgZm9yIHRoZSBwYXJ0IG9mIHRoZSBzdHJpbmcgZm9yIHRoZSBzdGFydCBvZiAKCSAgICAgICAgICAgIC8vIHRoZSBzZXF1ZW5jZQoJICAgICAgICAgICAgLy8gSXQgZG9lc24ndCBtYXR0ZXIgd2hpY2ggc3RyaW5nIHdlIHNjYW4sIHNpbmNlIHRoZXkgYXJlIHRoZSAKCSAgICAgICAgICAgIC8vIHNhbWUgaW4gdGhpcyByZWdpb24uCgkgICAgICAgICAgICBkbyB7CgkgICAgICAgICAgICAgICAgcmVzdWx0IC0tOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgd2hpbGUgKHJlc3VsdCA+IDAgJiYgaXNVbnNhZmUoc291cmNlLmNoYXJBdChyZXN1bHQpKSk7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBBcHBlbmRpbmcgYW4gYnl0ZSB0byBhbiBhcnJheSBvZiBieXRlcyBhbmQgaW5jcmVhc2VzIGl0IGlmIHdlIHJ1biBvdXQgb2YgCgkgKiBzcGFjZQoJICogQHBhcmFtIGFycmF5IG9mIGJ5dGUgYXJyYXlzCgkgKiBAcGFyYW0gYXBwZW5kaW5kZXggaW5kZXggaW4gdGhlIGJ5dGUgYXJyYXkgdG8gYXBwZW5kCgkgKiBAcGFyYW0gdmFsdWUgdG8gYXBwZW5kCiAgICAgKiBAcmV0dXJuIGFycmF5IGlmIGFycmF5IHNpemUgY2FuIGFjY29tb2RhdGUgdGhlIG5ldyB2YWx1ZSwgb3RoZXJ3aXNlCiAgICAgKiAgICAgICAgIGEgYmlnZ2VyIGFycmF5IHdpbGwgYmUgY3JlYXRlZCBhbmQgcmV0dXJuZWQKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIGFwcGVuZChieXRlIGFycmF5W10sIGludCBhcHBlbmRpbmRleCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGUgdmFsdWUpCgl7CgkJaWYgKGFwcGVuZGluZGV4ICsgMSA+PSBhcnJheS5sZW5ndGgpIHsKCQkJYXJyYXkgPSBpbmNyZWFzZShhcnJheSwJYXBwZW5kaW5kZXgsIFNPUlRfQlVGRkVSX0lOSVRfU0laRV8pOwoJCX0JCQkKCQlhcnJheVthcHBlbmRpbmRleF0gPSB2YWx1ZTsKICAgICAgICByZXR1cm4gYXJyYXk7Cgl9CgkKCS8qKiAKCSAqIFRoaXMgaXMgYSB0cmljayBzdHJpbmcgY29tcGFyZSBmdW5jdGlvbiB0aGF0IGdvZXMgaW4gYW5kIHVzZXMgc29ydGtleXMgCgkgKiB0byBjb21wYXJlLiBJdCBpcyB1c2VkIHdoZW4gY29tcGFyZSBnZXRzIGluIHRyb3VibGUgYW5kIG5lZWRzIHRvIGJhaWwgCgkgKiBvdXQuCgkgKiBAcGFyYW0gc291cmNlIHRleHQgc3RyaW5nCgkgKiBAcGFyYW0gdGFyZ2V0IHRleHQgc3RyaW5nCgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGNvbXBhcmVCeVNvcnRLZXlzKFN0cmluZyBzb3VyY2UsIFN0cmluZyB0YXJnZXQpCgkJCQkJCQkJCQkJCQkJCgl7CgkgICAgQ29sbGF0aW9uS2V5IHNvdXJjZWtleSA9IGdldENvbGxhdGlvbktleShzb3VyY2UpOwoJICAgIENvbGxhdGlvbktleSB0YXJnZXRrZXkgPSBnZXRDb2xsYXRpb25LZXkodGFyZ2V0KTsJCgkgICAgcmV0dXJuIHNvdXJjZWtleS5jb21wYXJlVG8odGFyZ2V0a2V5KTsKCX0KCQoJLyoqCgkgKiBQZXJmb3JtcyB0aGUgcHJpbWFyeSBjb21wYXJpc29ucywgYW5kIGZpbGxzIHVwIHRoZSBDRSBidWZmZXIgYXQgdGhlCgkgKiBzYW1lIHRpbWUuIAoJICogVGhlIHJldHVybiB2YWx1ZSB0b2dnbGVzIGJldHdlZW4gdGhlIGNvbXBhcmlzb24gcmVzdWx0IGFuZCB0aGUgaGlyYWdhbmEKCSAqIHJlc3VsdC4gSWYgZWl0aGVyIHRoZSBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldCBvciB2aWNlIHZlcnNhLCB0aGUgCgkgKiByZXR1cm4gcmVzdWx0IGlzIHRoZSBjb21wYXJpc29uIHJlc3VsdCwgaWUgMSBvciAtMSwgZnVydGhlcm1vcmUgdGhlCgkgKiBjZWJ1ZmZlcnMgd2lsbCBiZSBjbGVhcmVkIHdoZW4gdGhhdCBoYXBwZW5zLiBJZiB0aGUgcHJpbWFyeSBjb21wYXJpc29ucwoJICogYXJlIGVxdWFsLCB3ZSdsbCBoYXZlIHRvIGNvbnRpbnVlIHdpdGggc2Vjb25kYXJ5IGNvbXBhcmlzb24uIEluIHRoaXMgY2FzZQoJICogdGhlIGNlYnVmZmVyIHdpbGwgbm90IGJlIGNsZWFyZWQgYW5kIHRoZSByZXR1cm4gcmVzdWx0IHdpbGwgYmUgdGhlIAoJICogaGlyYWdhbmEgcmVzdWx0LgoJICogQHBhcmFtIGRvSGlyYWdhbmE0IGZsYWcgaW5kaWNhdG9yIHRoYXQgSGlyYWdhbmEgUXVhdGVybmFyeSBoYXMgdG8gYmUgCgkgKiAJCQkJCW9ic2VydmVkCgkgKiBAcGFyYW0gbG93ZXN0cHZhbHVlIHRoZSBsb3dlc3QgcHJpbWFyeSB2YWx1ZSB0aGF0IHdpbGwgbm90IGJlIGlnbm9yZWQgaWYgCgkgKiAJCQkJCQlhbHRlcm5hdGUgaGFuZGxpbmcgaXMgc2hpZnRlZAoJICogQHBhcmFtIHNvdXJjZSB0ZXh0IHN0cmluZwoJICogQHBhcmFtIHRhcmdldCB0ZXh0IHN0cmluZwoJICogQHBhcmFtIHRleHRvZmZzZXQgb2Zmc2V0IGluIHRleHQgdG8gc3RhcnQgdGhlIGNvbXBhcmlzb24KCSAqIEByZXR1cm4gY29tcGFyaW9uIHJlc3VsdCBpZiBhIHByaW1hcnkgZGlmZmVyZW5jZSBpcyBmb3VuZCwgb3RoZXJ3aXNlCgkgKiAJCQkJCQloaXJhZ2FuYSByZXN1bHQKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZG9QcmltYXJ5Q29tcGFyZShib29sZWFuIGRvSGlyYWdhbmE0LCBpbnQgbG93ZXN0cHZhbHVlLAoJCQkJCQkJCQkJU3RyaW5nIHNvdXJjZSwgU3RyaW5nIHRhcmdldCwgCgkJCQkJCQkJCQlpbnQgdGV4dG9mZnNldCkKCQkJCQkJCQkJICAgCQoJewoJCS8vIFByZXBhcmluZyB0aGUgY29udGV4dCBvYmplY3RzIGZvciBpdGVyYXRpbmcgb3ZlciBzdHJpbmdzCiAgICAgICAgbV9zcmNVdGlsSXRlcl8uc2V0VGV4dChzb3VyY2UpOwogICAgICAgIG1fc3JjVXRpbENvbEVJdGVyXy5zZXRUZXh0KG1fc3JjVXRpbEl0ZXJfLCB0ZXh0b2Zmc2V0KTsKICAgICAgICBtX3RndFV0aWxJdGVyXy5zZXRUZXh0KHRhcmdldCk7CiAgICAgICAgbV90Z3RVdGlsQ29sRUl0ZXJfLnNldFRleHQobV90Z3RVdGlsSXRlcl8sIHRleHRvZmZzZXQpOwoJCQoJCS8vIE5vbiBzaGlmdGVkIHByaW1hcnkgcHJvY2Vzc2luZyBpcyBxdWl0ZSBzaW1wbGUKCSAgICBpZiAoIW1faXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWRfKSB7CgkgICAgCWludCBoaXJhZ2FuYXJlc3VsdCA9IDA7ICAgIAkJCQkJCQkJCQkJCQkJCgkgICAgICAJd2hpbGUgKHRydWUpIHsKCSAgICAgIAkJaW50IHNvcmRlciA9IDA7CgkJCQkvLyBXZSBmZXRjaCBDRXMgdW50aWwgd2UgaGl0IGEgbm9uIGlnbm9yYWJsZSBwcmltYXJ5IG9yIGVuZC4KCSAgICAgICAgCWRvIHsKCSAgICAgICAgICAJCXNvcmRlciA9IG1fc3JjVXRpbENvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgCQltX3NyY1V0aWxDRUJ1ZmZlcl8gPSBhcHBlbmQobV9zcmNVdGlsQ0VCdWZmZXJfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9zcmNVdGlsQ0VCdWZmZXJTaXplXywgc29yZGVyKTsKICAgICAgICAgICAgICAgICAgICBtX3NyY1V0aWxDRUJ1ZmZlclNpemVfICsrOwoJICAgICAgICAgIAkJc29yZGVyICY9IENFX1BSSU1BUllfTUFTS187CgkgICAgICAgIAl9IHdoaWxlIChzb3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSk7CgkKCQkJCWludCB0b3JkZXIgPSAwOwoJICAgICAgICAJZG8gewoJICAgICAgICAgIAkJdG9yZGVyID0gbV90Z3RVdGlsQ29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAJCW1fdGd0VXRpbENFQnVmZmVyXyA9IGFwcGVuZChtX3RndFV0aWxDRUJ1ZmZlcl8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3RndFV0aWxDRUJ1ZmZlclNpemVfLCB0b3JkZXIpOwogICAgICAgICAgICAgICAgICAgIG1fdGd0VXRpbENFQnVmZmVyU2l6ZV8gKys7CgkgICAgICAgICAgCQl0b3JkZXIgJj0gQ0VfUFJJTUFSWV9NQVNLXzsKCSAgICAgICAgCX0gd2hpbGUgKHRvcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKTsKCQoJICAgICAgICAJLy8gaWYgYm90aCBwcmltYXJpZXMgYXJlIHRoZSBzYW1lCgkgICAgICAgIAlpZiAoc29yZGVyID09IHRvcmRlcikgewoJICAgICAgICAgICAgCS8vIGFuZCB0aGVyZSBhcmUgbm8gbW9yZSBDRXMsIHdlIGFkdmFuY2UgdG8gdGhlIG5leHQgbGV2ZWwKCSAgICAgICAgICAgIAlpZiAobV9zcmNVdGlsQ0VCdWZmZXJfW21fc3JjVXRpbENFQnVmZmVyU2l6ZV8gLSAxXSAKCSAgICAgICAgICAgIAkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAJCWJyZWFrOwoJICAgICAgICAgICAgCX0KCSAgICAgICAgICAgIAlpZiAoZG9IaXJhZ2FuYTQgJiYgaGlyYWdhbmFyZXN1bHQgPT0gMCAKCSAgICAgICAgICAgIAkJJiYgbV9zcmNVdGlsQ29sRUl0ZXJfLm1faXNDb2RlUG9pbnRIaXJhZ2FuYV8gIT0KCSAgICAgICAgICAgICAgCQkJCQkJbV90Z3RVdGlsQ29sRUl0ZXJfLm1faXNDb2RlUG9pbnRIaXJhZ2FuYV8pIHsKCSAgICAgICAgICAgICAgCQlpZiAobV9zcmNVdGlsQ29sRUl0ZXJfLm1faXNDb2RlUG9pbnRIaXJhZ2FuYV8pIHsKCSAgICAgICAgICAgICAgICAJCWhpcmFnYW5hcmVzdWx0ID0gLTE7CgkgICAgICAgICAgICAgIAkJfQoJICAgICAgICAgICAgICAJCWVsc2UgewoJICAgICAgICAgICAgICAJCQloaXJhZ2FuYXJlc3VsdCA9IDE7CgkgICAgICAgICAgICAgIAkJfQoJICAgICAgICAgICAgCX0KCSAgICAgICAgCX0gCgkgICAgICAgIAllbHNlIHsKCSAgICAgICAgICAgIAkvLyBpZiB0d28gcHJpbWFyaWVzIGFyZSBkaWZmZXJlbnQsIHdlIGFyZSBkb25lCgkgICAgICAgICAgICAJcmV0dXJuIGVuZFByaW1hcnlDb21wYXJlKHNvcmRlciwgdG9yZGVyKTsKCSAgICAgICAgCX0KCSAgICAgIAl9IAoJICAgICAgCS8vIG5vIHByaW1hcnkgZGlmZmVyZW5jZS4uLiBkbyB0aGUgcmVzdCBmcm9tIHRoZSBidWZmZXJzCgkgICAgICAJcmV0dXJuIGhpcmFnYW5hcmVzdWx0OwoJICAgIH0gCgkgICAgZWxzZSB7IC8vIHNoaWZ0ZWQgLSBkbyBhIHNsaWdodGx5IG1vcmUgY29tcGxpY2F0ZWQgcHJvY2Vzc2luZyA6KQoJICAgICAgCXdoaWxlICh0cnVlKSB7CgkgICAgICAgIAlpbnQgc29yZGVyID0gZ2V0UHJpbWFyeVNoaWZ0ZWRDb21wYXJlQ0UobV9zcmNVdGlsQ29sRUl0ZXJfLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RwdmFsdWUsIHRydWUpOwoJCQkJaW50IHRvcmRlciA9IGdldFByaW1hcnlTaGlmdGVkQ29tcGFyZUNFKG1fdGd0VXRpbENvbEVJdGVyXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXN0cHZhbHVlLCBmYWxzZSk7CgkgICAgICAgIAlpZiAoc29yZGVyID09IHRvcmRlcikgewoJICAgICAgICAgICAgCWlmIChtX3NyY1V0aWxDRUJ1ZmZlcl9bbV9zcmNVdGlsQ0VCdWZmZXJTaXplXyAtIDFdIAoJICAgICAgICAgICAgCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAJCWJyZWFrOwoJICAgICAgICAgICAgCX0gCgkgICAgICAgICAgICAJZWxzZSB7CgkgICAgICAgICAgICAgIAkJY29udGludWU7CgkgICAgICAgICAgICAJfQoJICAgICAgICAJfSAKCSAgICAgICAgCWVsc2UgewoJICAgIAkJCXJldHVybiBlbmRQcmltYXJ5Q29tcGFyZShzb3JkZXIsIHRvcmRlcik7CgkgICAgICAgIAl9CgkgICAgICAJfSAvLyBubyBwcmltYXJ5IGRpZmZlcmVuY2UuLi4gZG8gdGhlIHJlc3QgZnJvbSB0aGUgYnVmZmVycwoJICAgIH0KCQlyZXR1cm4gMDsKCX0KCQoJLyoqCgkgKiBUaGlzIGlzIHVzZWQgb25seSBmb3IgcHJpbWFyeSBzdHJlbmd0aCB3aGVuIHdlIGtub3cgdGhhdCBzb3JkZXIgaXMgCgkgKiBhbHJlYWR5IGRpZmZlcmVudCBmcm9tIHRvcmRlci4KCSAqIENvbXBhcmVzIHNvcmRlciBhbmQgdG9yZGVyLCByZXR1cm5zIC0xIGlmIHNvcmRlciBpcyBsZXNzIHRoYW4gdG9yZGVyLgoJICogQ2xlYXJzIHRoZSBjZWJ1ZmZlciBhdCB0aGUgc2FtZSB0aW1lLgoJICogQHBhcmFtIHNvcmRlciBzb3VyY2Ugc3RyZW5ndGggb3JkZXIKCSAqIEBwYXJhbSB0b3JkZXIgdGFyZ2V0IHN0cmVuZ3RoIG9yZGVyCgkgKiBAcmV0dXJuIHRoZSBjb21wYXJpc29uIHJlc3VsdCBvZiBzb3JkZXIgYW5kIHRvcmRlcgoJICovCglwcml2YXRlIGZpbmFsIGludCBlbmRQcmltYXJ5Q29tcGFyZShpbnQgc29yZGVyLCBpbnQgdG9yZGVyKQoJewoJCS8vIGlmIHdlIHJlYWNoIGhlcmUsIHRoZSBjZSBvZmZzZXQgYWNjZXNzZWQgaXMgdGhlIGxhc3QgY2UKCQkvLyBhcHBlbmRlZCB0byB0aGUgYnVmZmVyCgkJYm9vbGVhbiBpc1NvdXJjZU51bGxPcmRlciA9IChtX3NyY1V0aWxDRUJ1ZmZlcl9bCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3NyY1V0aWxDRUJ1ZmZlclNpemVfIC0gMV0gCgkJCSAJCQkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUik7CgkJYm9vbGVhbiBpc1RhcmdldE51bGxPcmRlciA9IChtX3RndFV0aWxDRUJ1ZmZlcl9bCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX3RndFV0aWxDRUJ1ZmZlclNpemVfIC0gMV0gCgkJCSAJCQkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUik7CSAJCQkJCQoJCW1fc3JjVXRpbENFQnVmZmVyU2l6ZV8gPSAtMTsKCSAgICBtX3RndFV0aWxDRUJ1ZmZlclNpemVfID0gLTE7CgkgICAgaWYgKGlzU291cmNlTnVsbE9yZGVyKSB7CgkgICAgCXJldHVybiAtMTsKCSAgICB9CgkgICAgaWYgKGlzVGFyZ2V0TnVsbE9yZGVyKSB7CgkgICAgCXJldHVybiAxOwoJICAgIH0KCSAgICAvLyBnZXR0aW5nIHJpZCBvZiB0aGUgc2lnbgoJICAgIHNvcmRlciA+Pj49IENFX1BSSU1BUllfU0hJRlRfOwoJICAgIHRvcmRlciA+Pj49IENFX1BSSU1BUllfU0hJRlRfOwoJICAgIGlmIChzb3JkZXIgPCB0b3JkZXIpIHsKCSAgICAJcmV0dXJuIC0xOwoJICAgIH0KCSAgICByZXR1cm4gMTsKCX0KCQoJLyoqCgkgKiBDYWxjdWxhdGVzIHRoZSBuZXh0IHByaW1hcnkgc2hpZnRlZCB2YWx1ZSBhbmQgZmlsbHMgdXAgY2VidWZmZXIgd2l0aCB0aGUgCgkgKiBuZXh0IG5vbi1pZ25vcmFibGUgY2UuCgkgKiBAcGFyYW0gY29sZWl0ZXIgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IKCSAqIEBwYXJhbSBkb0hpcmFnYW5hNCBmbGFnIGluZGljYXRvciBpZiBoaXJhZ2FuYSBxdWF0ZXJuYXJ5IGlzIHRvIGJlIAoJICogCQkJCQkJaGFuZGxlZAoJICogQHBhcmFtIGxvd2VzdHB2YWx1ZSBsb3dlc3QgcHJpbWFyeSBzaGlmdGVkIHZhbHVlIHRoYXQgd2lsbCBub3QgYmUgCgkgKiAJCQkJCQlpZ25vcmVkCgkgKiBAcmV0dXJuIHJlc3VsdCBuZXh0IG1vZGlmaWVkIGNlIAoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXRQcmltYXJ5U2hpZnRlZENvbXBhcmVDRSgKCQkJCQkJCQkJCUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb2xlaXRlciwKCQkJCQkJCQkJCWludCBsb3dlc3RwdmFsdWUsIGJvb2xlYW4gaXNTcmMpCgkJCQkJCQkJCQkKCXsKCQlib29sZWFuIHNoaWZ0ZWQgPSBmYWxzZTsKCQlpbnQgcmVzdWx0ID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKICAgICAgICBpbnQgY2VidWZmZXJbXSA9IG1fc3JjVXRpbENFQnVmZmVyXzsKICAgICAgICBpbnQgY2VidWZmZXJzaXplID0gbV9zcmNVdGlsQ0VCdWZmZXJTaXplXzsKICAgICAgICBpZiAoIWlzU3JjKSB7CiAgICAgICAgICAgIGNlYnVmZmVyID0gbV90Z3RVdGlsQ0VCdWZmZXJfOwogICAgICAgICAgICBjZWJ1ZmZlcnNpemUgPSBtX3RndFV0aWxDRUJ1ZmZlclNpemVfOwogICAgICAgIH0KCSAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICByZXN1bHQgPSBjb2xlaXRlci5uZXh0KCk7CgkgICAgICAgIGlmIChyZXN1bHQgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgY2VidWZmZXIgPSBhcHBlbmQoY2VidWZmZXIsIGNlYnVmZmVyc2l6ZSwgcmVzdWx0KTsKICAgICAgICAgICAgICAgIGNlYnVmZmVyc2l6ZSArKzsKCSAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICB9IAoJICAgICAgICBlbHNlIGlmIChyZXN1bHQgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRQoJICAgICAgICAgICAgICAgICB8fCAoc2hpZnRlZCAKCSAgICAgICAgICAgICAgICAgICAgICYmIChyZXN1bHQgJiBDRV9QUklNQVJZX01BU0tfKSAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSkgeyAKICAgICAgICAgICAgICAgIC8vIFVDQSBhbWVuZG1lbnQgLSBpZ25vcmUgaWdub3JhYmxlcyB0aGF0IGZvbGxvdyBzaGlmdGVkIGNvZGUgCiAgICAgICAgICAgICAgICAvLyBwb2ludHMKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9IAoJICAgICAgICBlbHNlIGlmIChpc0NvbnRpbnVhdGlvbihyZXN1bHQpKSB7CgkgICAgICAgIAlpZiAoKHJlc3VsdCAmIENFX1BSSU1BUllfTUFTS18pIAoJICAgICAgICAgICAgCQkJCQkhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7IAoJICAgICAgICAgICAgCS8vIFRoZXJlIGlzIHByaW1hcnkgdmFsdWUKCSAgICAgICAgICAgICAgCWlmIChzaGlmdGVkKSB7CgkgICAgICAgICAgICAgICAgCXJlc3VsdCA9IChyZXN1bHQgJiBDRV9QUklNQVJZX01BU0tfKSAKCSAgICAgICAgICAgICAgICAJCQkJCQl8IENFX0NPTlRJTlVBVElPTl9NQVJLRVJfOyAKCSAgICAgICAgICAgICAgICAJLy8gcHJlc2VydmUgaW50ZXJlc3RpbmcgY29udGludWF0aW9uCgkgICAgICAgICAgICAgICAgCWNlYnVmZmVyID0gYXBwZW5kKGNlYnVmZmVyLCBjZWJ1ZmZlcnNpemUsIHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlYnVmZmVyc2l6ZSArKzsKCSAgICAgICAgICAgCQkJY29udGludWU7CgkgICAgICAgIAkJfSAKCSAgICAgICAgCQllbHNlIHsKCSAgICAgICAgICAgCQkJY2VidWZmZXIgPSBhcHBlbmQoY2VidWZmZXIsIGNlYnVmZmVyc2l6ZSwgcmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VidWZmZXJzaXplICsrOwoJICAgICAgICAgICAgICAgIAlicmVhazsKCSAgICAgICAgICAgICAgCX0KCSAgICAgICAgICAgIH0gCgkgICAgICAgICAgICBlbHNlIHsgLy8gSnVzdCBsb3dlciBsZXZlbCB2YWx1ZXMKCSAgICAgICAgICAgIAlpZiAoIXNoaWZ0ZWQpIHsKCSAgICAgICAgICAgIAkJY2VidWZmZXIgPSBhcHBlbmQoY2VidWZmZXIsIGNlYnVmZmVyc2l6ZSwgcmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgY2VidWZmZXJzaXplICsrOwoJICAgICAgICAgICAgICAJfQoJICAgICAgICAgICAgfQoJICAgICAgICB9IAoJICAgICAgICBlbHNlIHsgLy8gcmVndWxhcgogICAgICAgICAgICAgICAgaWYgKFV0aWxpdHkuY29tcGFyZVVuc2lnbmVkKHJlc3VsdCAmIENFX1BSSU1BUllfTUFTS18sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VzdHB2YWx1ZSkgPiAwKSB7CgkgICAgICAgICAgICAgCWNlYnVmZmVyID0gYXBwZW5kKGNlYnVmZmVyLCBjZWJ1ZmZlcnNpemUsIHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgY2VidWZmZXJzaXplICsrOwoJICAgICAgICAgICAgIAlicmVhazsKCSAgICAgICAgICAgIH0gCgkgICAgICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIAlpZiAoKHJlc3VsdCAmIENFX1BSSU1BUllfTUFTS18pICE9IDApIHsKCSAgICAgICAgICAgICAgICAJc2hpZnRlZCA9IHRydWU7CgkgICAgICAgICAgICAgICAgCXJlc3VsdCAmPSBDRV9QUklNQVJZX01BU0tfOwoJICAgICAgICAgICAgICAgIAljZWJ1ZmZlciA9IGFwcGVuZChjZWJ1ZmZlciwgY2VidWZmZXJzaXplLCByZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWJ1ZmZlcnNpemUgKys7CgkgICAgICAgICAgICAgICAgCWNvbnRpbnVlOwoJICAgICAgICAgICAgICAJfSAKCSAgICAgICAgICAgICAgCWVsc2UgewoJICAgICAgICAgICAgICAgIAljZWJ1ZmZlciA9IGFwcGVuZChjZWJ1ZmZlciwgY2VidWZmZXJzaXplLCByZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBjZWJ1ZmZlcnNpemUgKys7CgkgICAgICAgICAgICAgICAgCXNoaWZ0ZWQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICAJY29udGludWU7CgkgICAgICAgICAgICAgIAl9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CiAgICAgICAgaWYgKGlzU3JjKSB7CiAgICAgICAgICAgIG1fc3JjVXRpbENFQnVmZmVyXyA9IGNlYnVmZmVyOwogICAgICAgICAgICBtX3NyY1V0aWxDRUJ1ZmZlclNpemVfID0gY2VidWZmZXJzaXplOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgbV90Z3RVdGlsQ0VCdWZmZXJfID0gY2VidWZmZXI7CiAgICAgICAgICAgIG1fdGd0VXRpbENFQnVmZmVyU2l6ZV8gPSBjZWJ1ZmZlcnNpemU7CiAgICAgICAgfQoJICAgIHJlc3VsdCAmPSBDRV9QUklNQVJZX01BU0tfOwoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgkJCQkJCQkKCS8qKgoJICogQXBwZW5kaW5nIGFuIGludCB0byBhbiBhcnJheSBvZiBpbnRzIGFuZCBpbmNyZWFzZXMgaXQgaWYgd2UgcnVuIG91dCBvZiAKCSAqIHNwYWNlCgkgKiBAcGFyYW0gYXJyYXkgb2YgaW50IGFycmF5cwoJICogQHBhcmFtIGFwcGVuZGluZGV4IGluZGV4IGF0IHdoaWNoIHZhbHVlIHdpbGwgYmUgYXBwZW5kZWQKCSAqIEBwYXJhbSB2YWx1ZSB0byBhcHBlbmQKICAgICAqIEByZXR1cm4gYXJyYXkgaWYgc2l6ZSBpcyBub3QgaW5jcmVhc2VkLCBvdGhlcndpc2UgYSBuZXcgYXJyYXkgd2lsbCBiZSAKICAgICAqICAgICAgICAgcmV0dXJuZWQKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gYXBwZW5kKGludCBhcnJheVtdLCBpbnQgYXBwZW5kaW5kZXgsIGludCB2YWx1ZSkKCXsKCQlpZiAoYXBwZW5kaW5kZXggKyAxID49IGFycmF5Lmxlbmd0aCkgewoJCQlhcnJheSA9IGluY3JlYXNlKGFycmF5LCBhcHBlbmRpbmRleCwgQ0VfQlVGRkVSX1NJWkVfKTsKCQl9CQkJCgkJYXJyYXlbYXBwZW5kaW5kZXhdID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIGFycmF5OwoJfQoJCgkvKioKCSAqIERvZXMgc2Vjb25kYXJ5IHN0cmVuZ3RoIGNvbXBhcmlzb24gYmFzZWQgb24gdGhlIGNvbGxlY3RlZCBjZXMuCgkgKiBAcGFyYW0gZG9GcmVuY2ggZmxhZyBpbmRpY2F0ZXMgaWYgRnJlbmNoIG9yZGVyaW5nIGlzIHRvIGJlIGRvbmUKCSAqIEByZXR1cm4gdGhlIHNlY29uZGFyeSBzdHJlbmd0aCBjb21wYXJpc29uIHJlc3VsdAoJICovCglwcml2YXRlIGZpbmFsIGludCBkb1NlY29uZGFyeUNvbXBhcmUoYm9vbGVhbiBkb0ZyZW5jaCkKCXsKCQkvLyBub3csIHdlJ3JlIGdvbm5hIHJlZXhhbWluZSBjb2xsZWN0ZWQgQ0VzCgkgICAgaWYgKCFkb0ZyZW5jaCkgeyAvLyBub3JtYWwKCSAgICAJaW50IHNvZmZzZXQgPSAwOwoJICAgIAlpbnQgdG9mZnNldCA9IDA7CgkgICAgICAgIHdoaWxlICh0cnVlKSB7CgkgICAgICAgIAlpbnQgc29yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAgICAgICAJd2hpbGUgKHNvcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAJc29yZGVyID0gbV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgKytdIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgQ0VfU0VDT05EQVJZX01BU0tfOwoJICAgICAgICAgIAl9CgkJCQlpbnQgdG9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAgICAgICAJd2hpbGUgKHRvcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgCQl0b3JkZXIgPSBtX3RndFV0aWxDRUJ1ZmZlcl9bdG9mZnNldCArK10gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiBDRV9TRUNPTkRBUllfTUFTS187CgkgICAgICAgICAgCX0KCQoJICAgICAgICAgIAlpZiAoc29yZGVyID09IHRvcmRlcikgewoJICAgICAgICAgICAgCWlmIChtX3NyY1V0aWxDRUJ1ZmZlcl9bc29mZnNldCAtIDFdICAKCSAgICAgICAgICAgIAkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAJCWJyZWFrOwoJICAgICAgICAgICAgCX0KCSAgICAgICAgICAJfSAKCSAgICAgICAgICAJZWxzZSB7CgkgICAgICAgICAgCQlpZiAobV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgLSAxXSA9PSAKCSAgICAgICAgICAJCQkJQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgIAkJCXJldHVybiAtMTsKCSAgICAgICAgICAJCX0KCSAgICAgICAgICAJCWlmIChtX3RndFV0aWxDRUJ1ZmZlcl9bdG9mZnNldCAtIDFdID09IAoJICAgICAgICAgIAkJCQlDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgCQkJcmV0dXJuIDE7CgkgICAgICAgICAgCQl9CgkgICAgICAgICAgICAgICAJcmV0dXJuIChzb3JkZXIgPCB0b3JkZXIpID8gLTEgOiAxOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0KCSAgICB9IAoJICAgIGVsc2UgeyAvLyBkbyB0aGUgRnJlbmNoIAoJICAgIAltX3NyY1V0aWxDb250T2Zmc2V0XyA9IDA7CiAgICAgICAgICAgIG1fdGd0VXRpbENvbnRPZmZzZXRfID0gMDsKICAgICAgICAgICAgbV9zcmNVdGlsT2Zmc2V0XyA9IG1fc3JjVXRpbENFQnVmZmVyU2l6ZV8gLSAyOyAKICAgICAgICAgICAgbV90Z3RVdGlsT2Zmc2V0XyA9IG1fdGd0VXRpbENFQnVmZmVyU2l6ZV8gLSAyOyAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgCWludCBzb3JkZXIgPSBnZXRTZWNvbmRhcnlGcmVuY2hDRSh0cnVlKTsKCSAgICAgICAgCWludCB0b3JkZXIgPSBnZXRTZWNvbmRhcnlGcmVuY2hDRShmYWxzZSk7CgkgICAgICAgICAgCWlmIChzb3JkZXIgPT0gdG9yZGVyKSB7CgkgICAgICAgICAgICAJaWYgKChtX3NyY1V0aWxPZmZzZXRfIDwgMCAmJiBtX3RndFV0aWxPZmZzZXRfIDwgMCkgCgkgICAgICAgICAgICAJCXx8IG1fc3JjVXRpbENFQnVmZmVyX1ttX3NyY1V0aWxPZmZzZXRfXSAKCSAgICAgICAgICAgIAkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAJCWJyZWFrOwoJICAgICAgICAgICAgCX0gCgkgICAgICAgICAgCX0gCgkgICAgICAgICAgCWVsc2UgewoJICAgICAgICAgICAgICAJcmV0dXJuIChzb3JkZXIgPCB0b3JkZXIpID8gLTEgOiAxOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIDA7Cgl9CgkKCS8qKgoJICogQ2FsY3VsYXRlcyB0aGUgbmV4dCBzZWNvbmRhcnkgZnJlbmNoIENFLgoJICogQHBhcmFtIGlzU3JjIGZsYWcgaW5kaWNhdG9yIGlmIHdlIGFyZSBjYWxjdWxhdGluZyB0aGUgc3JjIGNlcwoJICogQHJldHVybiByZXN1bHQgbmV4dCBtb2RpZmllZCBjZQoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXRTZWNvbmRhcnlGcmVuY2hDRShib29sZWFuIGlzU3JjKQoJewoJCWludCByZXN1bHQgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwogICAgICAgIGludCBvZmZzZXQgPSBtX3NyY1V0aWxPZmZzZXRfOwogICAgICAgIGludCBjb250aW51YXRpb25vZmZzZXQgPSBtX3NyY1V0aWxDb250T2Zmc2V0XzsKICAgICAgICBpbnQgY2VidWZmZXJbXSA9IG1fc3JjVXRpbENFQnVmZmVyXzsKICAgICAgICBpZiAoIWlzU3JjKSB7CiAgICAgICAgICAgIG9mZnNldCA9IG1fdGd0VXRpbE9mZnNldF87CiAgICAgICAgICAgIGNvbnRpbnVhdGlvbm9mZnNldCA9IG1fdGd0VXRpbENvbnRPZmZzZXRfOwogICAgICAgICAgICBjZWJ1ZmZlciA9IG1fdGd0VXRpbENFQnVmZmVyXzsKICAgICAgICB9CiAgICAgICAgCgkgICAgd2hpbGUgKHJlc3VsdCA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFIAoJICAgIAkJJiYgb2Zmc2V0ID49IDApIHsKCSAgICAgICAgaWYgKGNvbnRpbnVhdGlvbm9mZnNldCA9PSAwKSB7CgkgICAgICAgIAlyZXN1bHQgPSBjZWJ1ZmZlcltvZmZzZXRdOwoJCSAgICAgICAgd2hpbGUgKGlzQ29udGludWF0aW9uKGNlYnVmZmVyW29mZnNldCAtLV0pKTsKCQkgICAgICAgIC8vIGFmdGVyIHRoaXMsIHNvcmRlciBpcyBhdCB0aGUgc3RhcnQgb2YgY29udGludWF0aW9uLCAKCQkgICAgICAgIC8vIGFuZCBvZmZzZXQgcG9pbnRzIGJlZm9yZSB0aGF0IAoJCSAgICAgICAgaWYgKGlzQ29udGludWF0aW9uKGNlYnVmZmVyW29mZnNldCArIDFdKSkgewoJCSAgICAgICAgCS8vIHNhdmUgb2Zmc2V0IGZvciBsYXRlcgoJCSAgICAgICAgCWNvbnRpbnVhdGlvbm9mZnNldCA9IG9mZnNldDsgCgkJICAgICAgICAJb2Zmc2V0ICs9IDI7ICAKCQkgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgCXJlc3VsdCA9IGNlYnVmZmVyW29mZnNldCArK107CgkgICAgICAgIAlpZiAoIWlzQ29udGludWF0aW9uKHJlc3VsdCkpIHsgCgkgICAgICAgIAkJLy8gd2UgaGF2ZSBmaW5pc2hlZCB3aXRoIHRoaXMgY29udGludWF0aW9uCgkgICAgICAgICAgIAkJb2Zmc2V0ID0gY29udGludWF0aW9ub2Zmc2V0OwoJICAgICAgICAgICAJCS8vIHJlc2V0IHRoZSBwb2ludGVyIHRvIGJlZm9yZSBjb250aW51YXRpb24gCgkgICAgICAgICAgIAkJY29udGludWF0aW9ub2Zmc2V0ID0gMDsKCSAgICAgICAgICAgCQljb250aW51ZTsKCSAgICAgICAgCX0KCSAgICAgICAgfQoJICAgICAgICByZXN1bHQgJj0gQ0VfU0VDT05EQVJZX01BU0tfOyAvLyByZW1vdmUgY29udGludWF0aW9uIGJpdCAgICAgICAgCgkgICAgfSAgCiAgICAgICAgaWYgKGlzU3JjKSB7CiAgICAgICAgICAgIG1fc3JjVXRpbE9mZnNldF8gPSBvZmZzZXQ7CiAgICAgICAgICAgIG1fc3JjVXRpbENvbnRPZmZzZXRfID0gY29udGludWF0aW9ub2Zmc2V0OwogICAgICAgIH0gIAogICAgICAgIGVsc2UgewogICAgICAgICAgICBtX3RndFV0aWxPZmZzZXRfID0gb2Zmc2V0OwogICAgICAgICAgICBtX3RndFV0aWxDb250T2Zmc2V0XyA9IGNvbnRpbnVhdGlvbm9mZnNldDsKICAgICAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBEb2VzIGNhc2Ugc3RyZW5ndGggY29tcGFyaXNvbiBiYXNlZCBvbiB0aGUgY29sbGVjdGVkIGNlcy4KCSAqIEByZXR1cm4gdGhlIGNhc2Ugc3RyZW5ndGggY29tcGFyaXNvbiByZXN1bHQKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZG9DYXNlQ29tcGFyZSgpCgl7CgkJaW50IHNvZmZzZXQgPSAwOwoJCWludCB0b2Zmc2V0ID0gMDsKCSAgICB3aGlsZSAodHJ1ZSkgewoJICAgIAlpbnQgc29yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAgICAgaW50IHRvcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIHdoaWxlICgoc29yZGVyICYgQ0VfUkVNT1ZFX0NBU0VfKSAKCSAgICAgICAgCQkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAJc29yZGVyID0gbV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgKytdOwoJICAgICAgICAgIAlpZiAoIWlzQ29udGludWF0aW9uKHNvcmRlcikpIHsKCSAgICAgICAgICAgIAlzb3JkZXIgJj0gQ0VfQ0FTRV9NQVNLXzNfOwoJICAgICAgICAgICAgCXNvcmRlciBePSBtX2Nhc2VTd2l0Y2hfOwoJICAgICAgICAgIAl9IAoJICAgICAgICAgIAllbHNlIHsKCSAgICAgICAgICAgIAlzb3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0KCQoJICAgICAgICB3aGlsZSAoKHRvcmRlciAmIENFX1JFTU9WRV9DQVNFXykgCgkgICAgICAgIAkJCQkJCT09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgCXRvcmRlciA9IG1fdGd0VXRpbENFQnVmZmVyX1t0b2Zmc2V0ICsrXTsKCSAgICAgICAgICAJaWYgKCFpc0NvbnRpbnVhdGlvbih0b3JkZXIpKSB7CgkgICAgICAgICAgICAJdG9yZGVyICY9IENFX0NBU0VfTUFTS18zXzsKCSAgICAgICAgICAgIAl0b3JkZXIgXj0gbV9jYXNlU3dpdGNoXzsKCSAgICAgICAgICAJfSAKCSAgICAgICAgICAJZWxzZSB7CgkgICAgICAgICAgICAJdG9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAgICAgICAJfQoJICAgICAgICB9CgkKICAgICAgICAgICAgc29yZGVyICY9IENFX0NBU0VfQklUX01BU0tfOwogICAgICAgICAgICB0b3JkZXIgJj0gQ0VfQ0FTRV9CSVRfTUFTS187CgkJCWlmIChzb3JkZXIgPT0gdG9yZGVyKSB7CgkJCQlpZiAobV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgLSAxXSAKCQkJCQkJCQkJCT09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAJCWJyZWFrOwoJICAgICAgICAJfSAKCQkJfQoJCQllbHNlIHsKCSAgICAgICAgCWlmIChtX3NyY1V0aWxDRUJ1ZmZlcl9bc29mZnNldCAtIDFdIAoJICAgICAgICAJCQkJCQk9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgCQlyZXR1cm4gLTE7CgkgICAgICAgIAl9CiAgICAgICAgICAgICAgICBpZiAobV90Z3RVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgLSAxXSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQoJICAgICAgICAJcmV0dXJuIChzb3JkZXIgPCB0b3JkZXIpID8gLTEgOiAxOwoJCQl9CgkgICAgfQoJICAgIHJldHVybiAwOwoJfQoJCgkvKioKCSAqIERvZXMgdGVydGlhcnkgc3RyZW5ndGggY29tcGFyaXNvbiBiYXNlZCBvbiB0aGUgY29sbGVjdGVkIGNlcy4KCSAqIEByZXR1cm4gdGhlIHRlcnRpYXJ5IHN0cmVuZ3RoIGNvbXBhcmlzb24gcmVzdWx0CgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGRvVGVydGlhcnlDb21wYXJlKCkKCXsKCQlpbnQgc29mZnNldCA9IDA7CgkgICAgaW50IHRvZmZzZXQgPSAwOwoJICAgIHdoaWxlICh0cnVlKSB7CgkgICAgCWludCBzb3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgIAlpbnQgdG9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAgICAgd2hpbGUgKChzb3JkZXIgJiBDRV9SRU1PVkVfQ0FTRV8pIAoJICAgICAgICAJCQkJCT09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAJc29yZGVyID0gbV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgKytdICYgbV9tYXNrM187CgkgICAgICAgICAgCWlmICghaXNDb250aW51YXRpb24oc29yZGVyKSkgewoJICAgICAgICAgICAgCXNvcmRlciBePSBtX2Nhc2VTd2l0Y2hfOwoJICAgICAgICAgIAl9IAoJICAgICAgICAgIAllbHNlIHsKCSAgICAgICAgICAgIAlzb3JkZXIgJj0gQ0VfUkVNT1ZFX0NBU0VfOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0KCQoJCQl3aGlsZSAoKHRvcmRlciAmIENFX1JFTU9WRV9DQVNFXykgCgkgICAgICAgIAkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgIAl0b3JkZXIgPSBtX3RndFV0aWxDRUJ1ZmZlcl9bdG9mZnNldCArK10gJiBtX21hc2szXzsKCSAgICAgICAgICAJaWYgKCFpc0NvbnRpbnVhdGlvbih0b3JkZXIpKSB7CgkgICAgICAgICAgICAJdG9yZGVyIF49IG1fY2FzZVN3aXRjaF87CgkgICAgICAgICAgCX0gCgkgICAgICAgICAgCWVsc2UgewoJICAgICAgICAgICAgCXRvcmRlciAmPSBDRV9SRU1PVkVfQ0FTRV87CgkgICAgICAgICAgCX0KCSAgICAgICAgfSAgICAgICAgCgkKCSAgICAgICAgaWYgKHNvcmRlciA9PSB0b3JkZXIpIHsKCSAgICAgICAgICAJaWYgKG1fc3JjVXRpbENFQnVmZmVyX1tzb2Zmc2V0IC0gMV0gCgkgICAgICAgICAgCQkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgCWJyZWFrOwoJICAgICAgICAgIAl9IAoJICAgICAgICB9IAoJICAgICAgICBlbHNlIHsKCSAgICAgICAgCWlmIChtX3NyY1V0aWxDRUJ1ZmZlcl9bc29mZnNldCAtIDFdID09IAoJICAgICAgICAgIAkJCQkJCQlDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgCQlyZXR1cm4gLTE7CgkgICAgICAgICAgCX0KCSAgICAgICAgICAJaWYgKG1fdGd0VXRpbENFQnVmZmVyX1t0b2Zmc2V0IC0gMV0gPT0gCgkgICAgICAgICAgCQkJCUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAJCXJldHVybiAxOwoJICAgICAgICAgIAl9CgkgICAgICAgICAgICByZXR1cm4gKHNvcmRlciA8IHRvcmRlcikgPyAtMSA6IDE7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIDA7Cgl9CgkKCS8qKgoJICogRG9lcyBxdWF0ZXJuYXJ5IHN0cmVuZ3RoIGNvbXBhcmlzb24gYmFzZWQgb24gdGhlIGNvbGxlY3RlZCBjZXMuCgkgKiBAcGFyYW0gbG93ZXN0cHZhbHVlIHRoZSBsb3dlc3QgcHJpbWFyeSB2YWx1ZSB0aGF0IHdpbGwgbm90IGJlIGlnbm9yZWQgaWYgCgkgKiAJCQkJCQlhbHRlcm5hdGUgaGFuZGxpbmcgaXMgc2hpZnRlZAoJICogQHJldHVybiB0aGUgcXVhdGVybmFyeSBzdHJlbmd0aCBjb21wYXJpc29uIHJlc3VsdAoJICovCglwcml2YXRlIGZpbmFsIGludCBkb1F1YXRlcm5hcnlDb21wYXJlKGludCBsb3dlc3RwdmFsdWUpCgl7CgkJYm9vbGVhbiBzU2hpZnRlZCA9IHRydWU7CgkgICAgYm9vbGVhbiB0U2hpZnRlZCA9IHRydWU7CgkgICAgaW50IHNvZmZzZXQgPSAwOwoJICAgIGludCB0b2Zmc2V0ID0gMDsKCSAgICB3aGlsZSAodHJ1ZSkgewoJICAgIAlpbnQgc29yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAJaW50IHRvcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIHdoaWxlIChzb3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRQoJICAgICAgICAJCXx8IChpc0NvbnRpbnVhdGlvbihzb3JkZXIpICYmICFzU2hpZnRlZCkpIHsKCSAgICAgICAgICAJc29yZGVyID0gbV9zcmNVdGlsQ0VCdWZmZXJfW3NvZmZzZXQgKytdOwoJICAgICAgICAgIAlpZiAoaXNDb250aW51YXRpb24oc29yZGVyKSkgewoJICAgICAgICAgICAgCWlmICghc1NoaWZ0ZWQpIHsKCSAgICAgICAgICAgICAgCQljb250aW51ZTsKCSAgICAgICAgICAgIAl9CgkgICAgICAgICAgCX0gCgkgICAgICAgICAgCWVsc2UgaWYgKFV0aWxpdHkuY29tcGFyZVVuc2lnbmVkKHNvcmRlciwgbG93ZXN0cHZhbHVlKSA+IDAgCgkgICAgICAgICAgCQkJCXx8IChzb3JkZXIgJiBDRV9QUklNQVJZX01BU0tfKSAKCSAgICAgICAgICAJCQkJCQk9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7IAoJICAgICAgICAgIAkJLy8gbm9uIGNvbnRpbnVhdGlvbgoJICAgICAgICAgICAgCXNvcmRlciA9IENFX1BSSU1BUllfTUFTS187CgkgICAgICAgICAgICAJc1NoaWZ0ZWQgPSBmYWxzZTsKCSAgICAgICAgICAJfSAKCSAgICAgICAgICAJZWxzZSB7CgkgICAgICAgICAgICAJc1NoaWZ0ZWQgPSB0cnVlOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0KCSAgICAgICAgc29yZGVyID4+Pj0gQ0VfUFJJTUFSWV9TSElGVF87CgkJCXdoaWxlICh0b3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAKCSAgICAgICAgCQl8fCAoaXNDb250aW51YXRpb24odG9yZGVyKSAmJiAhdFNoaWZ0ZWQpKSB7CgkgICAgICAgICAgCXRvcmRlciA9IG1fdGd0VXRpbENFQnVmZmVyX1t0b2Zmc2V0ICsrXTsKCSAgICAgICAgICAJaWYgKGlzQ29udGludWF0aW9uKHRvcmRlcikpIHsKCSAgICAgICAgICAgIAlpZiAoIXRTaGlmdGVkKSB7CgkgICAgICAgICAgICAgIAkJY29udGludWU7CgkgICAgICAgICAgICAJfQoJICAgICAgICAgIAl9IAoJICAgICAgICAgIAllbHNlIGlmIChVdGlsaXR5LmNvbXBhcmVVbnNpZ25lZCh0b3JkZXIsIGxvd2VzdHB2YWx1ZSkgPiAwIAoJICAgICAgICAgIAkJCQl8fCAodG9yZGVyICYgQ0VfUFJJTUFSWV9NQVNLXykgCgkgICAgICAgICAgCQkJCQkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgeyAKCSAgICAgICAgICAJCS8vIG5vbiBjb250aW51YXRpb24KCSAgICAgICAgICAgIAl0b3JkZXIgPSBDRV9QUklNQVJZX01BU0tfOwoJICAgICAgICAgICAgCXRTaGlmdGVkID0gZmFsc2U7CgkgICAgICAgICAgCX0gCgkgICAgICAgICAgCWVsc2UgewoJICAgICAgICAgICAgCXRTaGlmdGVkID0gdHJ1ZTsKCSAgICAgICAgICAJfQoJICAgICAgICB9CgkgICAgICAgIHRvcmRlciA+Pj49IENFX1BSSU1BUllfU0hJRlRfOwoJCgkgICAgICAgIGlmIChzb3JkZXIgPT0gdG9yZGVyKSB7CgkgICAgICAgICAgCWlmIChtX3NyY1V0aWxDRUJ1ZmZlcl9bc29mZnNldCAtIDFdIAoJICAgICAgICAgIAkJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgCWJyZWFrOwoJICAgICAgICAgIAl9CgkgICAgICAgIH0gCgkgICAgICAgIGVsc2UgewoJICAgICAgICAJaWYgKG1fc3JjVXRpbENFQnVmZmVyX1tzb2Zmc2V0IC0gMV0gPT0gCgkgICAgICAgICAgCQlDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgCQlyZXR1cm4gLTE7CgkgICAgICAgICAgCX0KCSAgICAgICAgICAJaWYgKG1fdGd0VXRpbENFQnVmZmVyX1t0b2Zmc2V0IC0gMV0gPT0gCgkgICAgICAgICAgCQlDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgCQlyZXR1cm4gMTsKCSAgICAgICAgICAJfQoJICAgICAgICAgICAgcmV0dXJuIChzb3JkZXIgPCB0b3JkZXIpID8gLTEgOiAxOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiAwOwoJfQoJCgkvKiogIAoJICogSW50ZXJuYWwgZnVuY3Rpb24uIERvZXMgYnl0ZSBsZXZlbCBzdHJpbmcgY29tcGFyZS4gVXNlZCBieSBzdHJjb2xsIGlmIAoJICogc3RyZW5ndGggPT0gaWRlbnRpY2FsIGFuZCBzdHJpbmdzIGFyZSBvdGhlcndpc2UgZXF1YWwuIFRoaXMgaXMgYSByYXJlIAoJICogY2FzZS4gQ29tcGFyaXNvbiBtdXN0IGJlIGRvbmUgb24gTkZEIG5vcm1hbGl6ZWQgc3RyaW5ncy4gRkNEIGlzIG5vdCBnb29kIAoJICogZW5vdWdoLgoJICogQHBhcmFtIHNvdXJjZSB0ZXh0CgkgKiBAcGFyYW0gdGFyZ2V0IHRleHQKCSAqIEBwYXJhbSBvZmZzZXQgb2YgdGhlIGZpcnN0IGRpZmZlcmVuY2UgaW4gdGhlIHRleHQgc3RyaW5ncwoJICogQHBhcmFtIG5vcm1hbGl6ZSBmbGFnIGluZGljYXRpbmcgaWYgd2UgYXJlIHRvIG5vcm1hbGl6ZSB0aGUgdGV4dCBiZWZvcmUKCSAqIAkJCQljb21wYXJpc29uCgkgKiBAcmV0dXJuIDEgaWYgc291cmNlIGlzIGdyZWF0ZXIgdGhhbiB0YXJnZXQsIC0xIGxlc3MgdGhhbiBhbmQgMCBpZiBlcXVhbHMKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IGRvSWRlbnRpY2FsQ29tcGFyZShTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0LCAKCQkJCQkJCQkJCQkJaW50IG9mZnNldCwgYm9vbGVhbiBub3JtYWxpemUpCgkJCQkJCQkJCQkJCQoJewoJICAgIGlmIChub3JtYWxpemUpIHsKCSAgICAgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhzb3VyY2UsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCSE9IE5vcm1hbGl6ZXIuWUVTKSB7CgkgICAgICAgICAgICBzb3VyY2UgPSBOb3JtYWxpemVyLmRlY29tcG9zZShzb3VyY2UsIGZhbHNlKTsKCSAgICAgICAgfQoJCgkgICAgICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2sodGFyZ2V0LCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQkJIT0gTm9ybWFsaXplci5ZRVMpIHsKCSAgICAgICAgICAgIHRhcmdldCA9IE5vcm1hbGl6ZXIuZGVjb21wb3NlKHRhcmdldCwgZmFsc2UpOwoJICAgICAgICB9CgkgICAgICAgIG9mZnNldCA9IDA7CgkgICAgfQoJCgkgICAgcmV0dXJuIGRvU3RyaW5nQ29tcGFyZShzb3VyY2UsIHRhcmdldCwgb2Zmc2V0KTsKCX0KCQoJLyoqCgkgKiBDb21wYXJlcyBzdHJpbmcgZm9yIHRoZWlyIGNvZGVwb2ludCBvcmRlci4KCSAqIFRoaXMgY29tcGFyaXNvbiBoYW5kbGVzIHN1cnJvZ2F0ZSBjaGFyYWN0ZXJzIGFuZCBwbGFjZSB0aGVtIGFmdGVyIHRoZSAKCSAqIGFsbCBub24gc3Vycm9nYXRlIGNoYXJhY3RlcnMuCgkgKiBAcGFyYW0gc291cmNlIHRleHQKCSAqIEBwYXJhbSB0YXJnZXQgdGV4dAoJICogQHBhcmFtIG9mZnNldCBzdGFydCBvZmZzZXQgZm9yIGNvbXBhcmlzb24KCSAqIEByZXR1cm4gMSBpZiBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldCwgLTEgbGVzcyB0aGFuIGFuZCAwIGlmIGVxdWFscwoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgZG9TdHJpbmdDb21wYXJlKFN0cmluZyBzb3VyY2UsIAoJCQkJCQkJCQkJCSBTdHJpbmcgdGFyZ2V0LAoJCQkJCQkJCQkJCSBpbnQgb2Zmc2V0KSAKCXsKICAgIAkvLyBjb21wYXJlIGlkZW50aWNhbCBwcmVmaXhlcyAtIHRoZXkgZG8gbm90IG5lZWQgdG8gYmUgZml4ZWQgdXAKICAgIAljaGFyIHNjaGFyID0gMDsKICAgIAljaGFyIHRjaGFyID0gMDsKICAgIAlpbnQgc2xlbmd0aCA9IHNvdXJjZS5sZW5ndGgoKTsKICAgIAlpbnQgdGxlbmd0aCA9IHRhcmdldC5sZW5ndGgoKTsKICAgIAlpbnQgbWlubGVuZ3RoID0gTWF0aC5taW4oc2xlbmd0aCwgdGxlbmd0aCk7CiAgICAJd2hpbGUgKG9mZnNldCA8IG1pbmxlbmd0aCkgewogICAgICAgIAlzY2hhciA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0KTsKICAgICAgICAJdGNoYXIgPSB0YXJnZXQuY2hhckF0KG9mZnNldCArKyk7CiAgICAgICAgCWlmIChzY2hhciAhPSB0Y2hhcikgewogICAgICAgICAgICAJYnJlYWs7CiAgICAgICAgCX0KICAgIAl9CiAgICAJCiAgICAJaWYgKHNjaGFyID09IHRjaGFyICYmIG9mZnNldCA9PSBtaW5sZW5ndGgpIHsKICAgIAkJaWYgKHNsZW5ndGggPiBtaW5sZW5ndGgpIHsKICAgIAkJCXJldHVybiAxOwogICAgCQl9CiAgICAJCWlmICh0bGVuZ3RoID4gbWlubGVuZ3RoKSB7CiAgICAJCQlyZXR1cm4gLTE7CiAgICAJCX0KICAgIAkJcmV0dXJuIDA7CiAgICAJfQoKICAgCQkvLyAgaWYgYm90aCB2YWx1ZXMgYXJlIGluIG9yIGFib3ZlIHRoZSBzdXJyb2dhdGUgcmFuZ2UsIEZpeCB0aGVtIHVwLgogICAJCWlmIChzY2hhciA+PSBVVEYxNi5MRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUgCiAgIAkJCSYmIHRjaGFyID49IFVURjE2LkxFQURfU1VSUk9HQVRFX01JTl9WQUxVRSkgewogICAgICAgIAlzY2hhciA9IGZpeHVwVVRGMTYoc2NoYXIpOwogICAgICAgIAl0Y2hhciA9IGZpeHVwVVRGMTYodGNoYXIpOwogICAgCX0KCiAgICAJLy8gbm93IGMxIGFuZCBjMiBhcmUgaW4gVVRGLTMyLWNvbXBhdGlibGUgb3JkZXIKICAgIAlyZXR1cm4gKHNjaGFyIDwgdGNoYXIpID8gLTEgOiAxOyAvLyBzY2hhciBhbmQgdGNoYXIgaGFzIHRvIGJlIGRpZmZlcmVudAoJfQoJCgkvKiogCgkgKiBSb3RhdGUgc3Vycm9nYXRlcyB0byB0aGUgdG9wIHRvIGdldCBjb2RlIHBvaW50IG9yZGVyCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgZml4dXBVVEYxNihjaGFyIGNoKSAKCXsgICAgICAgICAgICAgICAgICAKICAgIAlpZiAoY2ggPj0gMHhlMDAwKSB7ICAgICAgICAgICAgICAgICAKICAgICAgICAJY2ggLT0gMHg4MDA7ICAgICAgICAgICAgICAgICAgICAKICAgIAl9IAogICAgCWVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgCWNoICs9IDB4MjAwMDsgICAgICAgICAgICAgICAgIAogICAgCX0gICAgIAogICAgCXJldHVybiBjaDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJfQoJCgkvKioKCSAqIENoZWNrcyB0aGF0IHRoZSBzb3VyY2UgYWZ0ZXIgb2Zmc2V0IGlzIGlnbm9yYWJsZQoJICogQHBhcmFtIHNvdXJjZSB0ZXh0IHN0cmluZyB0byBjaGVjawoJICogQHBhcmFtIG9mZnNldCAKCSAqIEByZXR1cm4gdHJ1ZSBpZiBzb3VyY2UgYWZ0ZXIgb2Zmc2V0IGlzIGlnbm9yYWJsZS4gZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja0lnbm9yYWJsZShTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0KQoJCQkJCQkJCQkJCQkJCgl7CiAgICAgICAgbV9zcmNVdGlsSXRlcl8uc2V0VGV4dChzb3VyY2UpOwogICAgICAgIG1fc3JjVXRpbENvbEVJdGVyXy5zZXRUZXh0KG1fc3JjVXRpbEl0ZXJfLCBvZmZzZXQpOwoJICAgIGludCBjZSA9IG1fc3JjVXRpbENvbEVJdGVyXy5uZXh0KCk7CgkgICAgd2hpbGUgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAJaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAJCXJldHVybiBmYWxzZTsKCSAgICAJfQoJICAgIAljZSA9IG1fc3JjVXRpbENvbEVJdGVyXy5uZXh0KCk7CgkgICAgfQoJICAgIHJldHVybiB0cnVlOyAKCX0KCQoJLyoqCgkgKiBSZXNldHMgdGhlIGludGVybmFsIGNhc2UgZGF0YSBtZW1iZXJzIGFuZCBjb21wcmVzc2lvbiB2YWx1ZXMuCgkgKi8KCXByaXZhdGUgdm9pZCB1cGRhdGVJbnRlcm5hbFN0YXRlKCkgCgl7CiAgICAgIAlpZiAobV9jYXNlRmlyc3RfID09IEF0dHJpYnV0ZVZhbHVlLlVQUEVSX0ZJUlNUXykgewogICAgICAgIAltX2Nhc2VTd2l0Y2hfID0gQ0FTRV9TV0lUQ0hfOwogICAgICAJfSAKICAgICAgCWVsc2UgewogICAgICAgIAltX2Nhc2VTd2l0Y2hfID0gTk9fQ0FTRV9TV0lUQ0hfOwogICAgICAJfQoKICAgICAgCWlmIChtX2lzQ2FzZUxldmVsXyB8fCBtX2Nhc2VGaXJzdF8gPT0gQXR0cmlidXRlVmFsdWUuT0ZGXykgewogICAgICAgIAltX21hc2szXyA9IENFX1JFTU9WRV9DQVNFXzsKICAgICAgICAJbV9jb21tb24zXyA9IENPTU1PTl9OT1JNQUxfM187CiAgICAgICAgCW1fYWRkaXRpb24zXyA9IEZMQUdfQklUX01BU0tfQ0FTRV9TV0lUQ0hfT0ZGXzsKICAgICAgICAJbV90b3AzXyA9IENPTU1PTl9UT1BfQ0FTRV9TV0lUQ0hfT0ZGXzNfOwogICAgICAgIAltX2JvdHRvbTNfID0gQ09NTU9OX0JPVFRPTV8zXzsKICAgICAgCX0gCiAgICAgIAllbHNlIHsKICAgICAgICAJbV9tYXNrM18gPSBDRV9LRUVQX0NBU0VfOwogICAgICAgIAltX2FkZGl0aW9uM18gPSBGTEFHX0JJVF9NQVNLX0NBU0VfU1dJVENIX09OXzsKICAgICAgICAJaWYgKG1fY2FzZUZpcnN0XyA9PSBBdHRyaWJ1dGVWYWx1ZS5VUFBFUl9GSVJTVF8pIHsKICAgICAgICAgIAkJbV9jb21tb24zXyA9IENPTU1PTl9VUFBFUl9GSVJTVF8zXzsKICAgICAgICAgIAkJbV90b3AzXyA9IENPTU1PTl9UT1BfQ0FTRV9TV0lUQ0hfVVBQRVJfM187CiAgICAgICAgICAJCW1fYm90dG9tM18gPSBDT01NT05fQk9UVE9NX0NBU0VfU1dJVENIX1VQUEVSXzNfOwogICAgICAgIAl9IGVsc2UgewogICAgICAgICAgCQltX2NvbW1vbjNfID0gQ09NTU9OX05PUk1BTF8zXzsKICAgICAgICAgIAkJbV90b3AzXyA9IENPTU1PTl9UT1BfQ0FTRV9TV0lUQ0hfTE9XRVJfM187CiAgICAgICAgICAJCW1fYm90dG9tM18gPSBDT01NT05fQk9UVE9NX0NBU0VfU1dJVENIX0xPV0VSXzNfOwogICAgICAgIAl9CiAgICAgIAl9CgogICAgICAJLy8gU2V0IHRoZSBjb21wcmVzc2lvbiB2YWx1ZXMKICAgICAgCWludCB0b3RhbDMgPSBtX3RvcDNfIC0gQ09NTU9OX0JPVFRPTV8zXyAtIDE7CiAgICAgIAkvLyB3ZSBtdWx0aWxwbHkgZG91YmxlIHdpdGggaW50LCBidXQgbmVlZCBvbmx5IGludAogICAgICAJbV90b3BDb3VudDNfID0gKGludCkoUFJPUE9SVElPTl8zXyAqIHRvdGFsMyk7IAogICAgICAJbV9ib3R0b21Db3VudDNfID0gdG90YWwzIC0gbV90b3BDb3VudDNfOwoKICAgICAgCWlmICghbV9pc0Nhc2VMZXZlbF8gJiYgZ2V0U3RyZW5ndGgoKSA9PSBBdHRyaWJ1dGVWYWx1ZS5URVJUSUFSWV8gCiAgICAgICAgICAJJiYgIW1faXNGcmVuY2hDb2xsYXRpb25fICYmICFtX2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXykgewogICAgICAgIAltX2lzU2ltcGxlM18gPSB0cnVlOwogICAgICAJfSAKICAgICAgCWVsc2UgewogICAgICAgIAltX2lzU2ltcGxlM18gPSBmYWxzZTsKICAgICAgCX0KICAgICAgICBpZighbV9pc0Nhc2VMZXZlbF8gJiYgZ2V0U3RyZW5ndGgoKSA8PSBBdHRyaWJ1dGVWYWx1ZS5URVJUSUFSWV8gCiAgICAgICAgICAmJiAhbV9pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZF8gJiYgIWxhdGluT25lRmFpbGVkXykgewogICAgICAgICAgaWYobGF0aW5PbmVDRXNfID09IG51bGwgfHwgbGF0aW5PbmVSZWdlblRhYmxlXykgewogICAgICAgICAgICBpZihzZXRVcExhdGluT25lKCkpIHsgLy8gaWYgd2Ugc3VjY2VlZCBpbiBidWlsZGluZyBsYXRpbjEgdGFibGUsIHdlJ2xsIHVzZSBpdAogICAgICAgICAgICAgIGxhdGluT25lVXNlXyA9IHRydWU7IAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGxhdGluT25lVXNlXyA9IGZhbHNlOwogICAgICAgICAgICAgIGxhdGluT25lRmFpbGVkXyA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGF0aW5PbmVSZWdlblRhYmxlXyA9IGZhbHNlOwogICAgICAgICAgfSBlbHNlIHsgLy8gbGF0aW4xVGFibGUgZXhpc3RzIGFuZCBpdCBkb2Vzbid0IG5lZWQgdG8gYmUgcmVnZW5lcmF0ZWQsIGp1c3QgdXNlIGl0CiAgICAgICAgICAgIGxhdGluT25lVXNlXyA9IHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxhdGluT25lVXNlXyA9IGZhbHNlOwogICAgICAgIH0gICAgIAogICAgICAgIAoJfQoJCgkvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIHZvaWQgaW5pdCgpCiAgICB7CiAgICAJZm9yIChtX21pblVuc2FmZV8gPSAwOyBtX21pblVuc2FmZV8gPCBERUZBVUxUX01JTl9IRVVSSVNUSUNfOyAKICAgIAkgICAgIG1fbWluVW5zYWZlXyArKykgeyAgCiAgICAJCS8vIEZpbmQgdGhlIHNtYWxsZXN0IHVuc2FmZSBjaGFyLgogICAgICAgIAlpZiAoaXNVbnNhZmUobV9taW5VbnNhZmVfKSkgewogICAgICAgIAkJYnJlYWs7CiAgICAgICAgCX0KICAgIAl9CiAgICAJCiAgICAJZm9yIChtX21pbkNvbnRyYWN0aW9uRW5kXyA9IDA7IAogICAgCSAgICAgbV9taW5Db250cmFjdGlvbkVuZF8gPCBERUZBVUxUX01JTl9IRVVSSVNUSUNfOyAKICAgIAkgICAgIG1fbWluQ29udHJhY3Rpb25FbmRfICsrKSB7ICAKICAgIAkgICAgLy8gRmluZCB0aGUgc21hbGxlc3QgY29udHJhY3Rpb24tZW5kaW5nIGNoYXIuCiAgICAgICAgCWlmIChpc0NvbnRyYWN0aW9uRW5kKG1fbWluQ29udHJhY3Rpb25FbmRfKSkgewogICAgICAgIAkJYnJlYWs7CiAgICAgICAgCX0KICAgIAl9CiAgICAgICAgbGF0aW5PbmVGYWlsZWRfID0gdHJ1ZTsKICAgIAlzZXRTdHJlbmd0aChtX2RlZmF1bHRTdHJlbmd0aF8pOwogICAgCXNldERlY29tcG9zaXRpb24obV9kZWZhdWx0RGVjb21wb3NpdGlvbl8pOwogICAgICAgIG1fdmFyaWFibGVUb3BWYWx1ZV8gPSBtX2RlZmF1bHRWYXJpYWJsZVRvcFZhbHVlXzsKICAgIAltX2lzRnJlbmNoQ29sbGF0aW9uXyA9IG1fZGVmYXVsdElzRnJlbmNoQ29sbGF0aW9uXzsKICAgIAltX2lzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXyA9IG1fZGVmYXVsdElzQWx0ZXJuYXRlSGFuZGxpbmdTaGlmdGVkXzsKICAgIAltX2lzQ2FzZUxldmVsXyA9IG1fZGVmYXVsdElzQ2FzZUxldmVsXzsKICAgIAltX2Nhc2VGaXJzdF8gPSBtX2RlZmF1bHRDYXNlRmlyc3RfOwogICAgCW1faXNIaXJhZ2FuYTRfID0gbV9kZWZhdWx0SXNIaXJhZ2FuYTRfOwogICAgICAgIGxhdGluT25lRmFpbGVkXyA9IGZhbHNlOwogICAgCXVwZGF0ZUludGVybmFsU3RhdGUoKTsKICAgIH0KICAgIAogICAgLyoqIAogICAgICogIEluaXRpYWxpemVzIHV0aWxpdHkgaXRlcmF0b3JzIGFuZCBieXRlIGJ1ZmZlciB1c2VkIGJ5IGNvbXBhcmUKICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGluaXRVdGlsaXR5KCkgewogICAgICAgbV9zcmNVdGlsSXRlcl8gPSBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IobmV3IFN0cmluZygiIikpOwogICAgICAgbV9zcmNVdGlsQ29sRUl0ZXJfID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihtX3NyY1V0aWxJdGVyXywgdGhpcyk7CiAgICAgICBtX3RndFV0aWxJdGVyXyA9IG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcihuZXcgU3RyaW5nKCIiKSk7CiAgICAgICBtX3RndFV0aWxDb2xFSXRlcl8gPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKG1fdGd0VXRpbEl0ZXJfLCB0aGlzKTsKICAgICAgIG1fdXRpbEJ5dGVzMF8gPSBuZXcgYnl0ZVtTT1JUX0JVRkZFUl9JTklUX1NJWkVfQ0FTRV9dOyAvLyBjYXNlCiAgICAgICBtX3V0aWxCeXRlczFfID0gbmV3IGJ5dGVbU09SVF9CVUZGRVJfSU5JVF9TSVpFXzFfXTsgLy8gcHJpbWFyeSAKICAgICAgIG1fdXRpbEJ5dGVzMl8gPSBuZXcgYnl0ZVtTT1JUX0JVRkZFUl9JTklUX1NJWkVfMl9dOyAvLyBzZWNvbmRhcnkKICAgICAgIG1fdXRpbEJ5dGVzM18gPSBuZXcgYnl0ZVtTT1JUX0JVRkZFUl9JTklUX1NJWkVfM19dOyAvLyB0ZXJ0aWFyeSAKICAgICAgIG1fdXRpbEJ5dGVzNF8gPSBuZXcgYnl0ZVtTT1JUX0JVRkZFUl9JTklUX1NJWkVfNF9dOyAgLy8gUXVhdGVybmFyeQogICAgICAgbV9zcmNVdGlsQ0VCdWZmZXJfID0gbmV3IGludFtDRV9CVUZGRVJfU0laRV9dOwogICAgICAgbV90Z3RVdGlsQ0VCdWZmZXJfID0gbmV3IGludFtDRV9CVUZGRVJfU0laRV9dOwogICAgfQogICAgCiAgICAKICAgIAogICAgLy8gQ29uc3RzIGZvciBMYXRpbi0xIHNwZWNpYWwgcHJvY2Vzc2luZwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVORE9GTEFUSU5PTkVSQU5HRV8gPSAweEZGOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExBVElOT05FVEFCTEVMRU5fICAgPSAoRU5ET0ZMQVRJTk9ORVJBTkdFXys1MCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQkFJTF9PVVRfQ0VfICAgICAgICA9IDB4RkYwMDAwMDA7CiAgICAKICAgICAvKiogCiAgICAgKiBHZW5lcmF0ZSBsYXRpbi0xIHRhYmxlcwogICAgICovCiAgICAKICAgIHByaXZhdGUgY2xhc3Mgc2hpZnRWYWx1ZXMgewogICAgICAgIGludCBwcmltU2hpZnQgPSAyNDsKICAgICAgICBpbnQgc2VjU2hpZnQgPSAyNDsKICAgICAgICBpbnQgdGVyU2hpZnQgPSAyNDsKICAgIH07CiAgICAKICAgIHByaXZhdGUgZmluYWwgdm9pZCAKICAgIGFkZExhdGluT25lRW50cnkoY2hhciBjaCwgaW50IENFLCBzaGlmdFZhbHVlcyBzaCkgewogICAgICBpbnQgcHJpbWFyeTEgPSAwLCBwcmltYXJ5MiA9IDAsIHNlY29uZGFyeSA9IDAsIHRlcnRpYXJ5ID0gMDsKICAgICAgYm9vbGVhbiByZXZlcnNlU2Vjb25kYXJ5ID0gZmFsc2U7CiAgICAgIGlmKCFpc0NvbnRpbnVhdGlvbihDRSkpIHsKICAgICAgICB0ZXJ0aWFyeSA9ICgoQ0UgJiBtX21hc2szXykpOwogICAgICAgIHRlcnRpYXJ5IF49IG1fY2FzZVN3aXRjaF87CiAgICAgICAgcmV2ZXJzZVNlY29uZGFyeSA9IHRydWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGVydGlhcnkgPSAoYnl0ZSkoKENFICYgQ0VfUkVNT1ZFX0NPTlRJTlVBVElPTl9NQVNLXykpOwogICAgICAgIHRlcnRpYXJ5ICY9IENFX1JFTU9WRV9DQVNFXzsKICAgICAgICByZXZlcnNlU2Vjb25kYXJ5ID0gZmFsc2U7CiAgICAgIH0KICAgIAogICAgICBzZWNvbmRhcnkgPSAoKENFID4+Pj0gOCkgJiBMQVNUX0JZVEVfTUFTS18pOwogICAgICBwcmltYXJ5MiA9ICAoKENFID4+Pj0gOCkgJiBMQVNUX0JZVEVfTUFTS18pOwogICAgICBwcmltYXJ5MSA9ICAoQ0UgPj4+IDgpOwogICAgCiAgICAgIGlmKHByaW1hcnkxICE9IDApIHsKICAgICAgICBsYXRpbk9uZUNFc19bY2hdIHw9IChwcmltYXJ5MSA8PCBzaC5wcmltU2hpZnQpOwogICAgICAgIHNoLnByaW1TaGlmdCAtPSA4OwogICAgICB9CiAgICAgIGlmKHByaW1hcnkyICE9IDApIHsKICAgICAgICBpZihzaC5wcmltU2hpZnQgPCAwKSB7CiAgICAgICAgICBsYXRpbk9uZUNFc19bY2hdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgbGF0aW5PbmVDRXNfW2xhdGluT25lVGFibGVMZW5fK2NoXSA9IEJBSUxfT1VUX0NFXzsKICAgICAgICAgIGxhdGluT25lQ0VzX1syKmxhdGluT25lVGFibGVMZW5fK2NoXSA9IEJBSUxfT1VUX0NFXzsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgbGF0aW5PbmVDRXNfW2NoXSB8PSAocHJpbWFyeTIgPDwgc2gucHJpbVNoaWZ0KTsKICAgICAgICBzaC5wcmltU2hpZnQgLT0gODsKICAgICAgfQogICAgICBpZihzZWNvbmRhcnkgIT0gMCkgewogICAgICAgIGlmKHJldmVyc2VTZWNvbmRhcnkgJiYgbV9pc0ZyZW5jaENvbGxhdGlvbl8pIHsgLy8gcmV2ZXJzZSBzZWNvbmRhcnkKICAgICAgICAgIGxhdGluT25lQ0VzX1tsYXRpbk9uZVRhYmxlTGVuXytjaF0gPj4+PSA4OyAvLyBtYWtlIHNwYWNlIGZvciBzZWNvbmRhcnkKICAgICAgICAgIGxhdGluT25lQ0VzX1tsYXRpbk9uZVRhYmxlTGVuXytjaF0gfD0gKHNlY29uZGFyeSA8PCAyNCk7CiAgICAgICAgfSBlbHNlIHsgLy8gbm9ybWFsIGNhc2UgCiAgICAgICAgICBsYXRpbk9uZUNFc19bbGF0aW5PbmVUYWJsZUxlbl8rY2hdIHw9IChzZWNvbmRhcnkgPDwgc2guc2VjU2hpZnQpOwogICAgICAgIH0KICAgICAgICBzaC5zZWNTaGlmdCAtPSA4OwogICAgICB9CiAgICAgIGlmKHRlcnRpYXJ5ICE9IDApIHsKICAgICAgICBsYXRpbk9uZUNFc19bMipsYXRpbk9uZVRhYmxlTGVuXytjaF0gfD0gKHRlcnRpYXJ5IDw8IHNoLnRlclNoaWZ0KTsKICAgICAgICBzaC50ZXJTaGlmdCAtPSA4OwogICAgICB9CiAgICB9CiAgICAKICAgIHByaXZhdGUgZmluYWwgdm9pZAogICAgcmVzaXplTGF0aW5PbmVUYWJsZShpbnQgbmV3U2l6ZSkgewogICAgICAgIGludCBuZXdUYWJsZVtdID0gbmV3IGludFszKm5ld1NpemVdOwogICAgICAgIGludCBzaXplVG9Db3B5ID0gKChuZXdTaXplPGxhdGluT25lVGFibGVMZW5fKT9uZXdTaXplOmxhdGluT25lVGFibGVMZW5fKTsKICAgICAgICAvL3VwcnZfbWVtc2V0KG5ld1RhYmxlLCAwLCBuZXdTaXplKnNpemVvZih1aW50MzJfdCkqMyk7IC8vIGF1dG9tYXRpY2FsbHkgY2xlYXJlZC4KICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxhdGluT25lQ0VzXywgMCwgbmV3VGFibGUsIDAsIHNpemVUb0NvcHkpOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGF0aW5PbmVDRXNfLCBsYXRpbk9uZVRhYmxlTGVuXywgbmV3VGFibGUsIG5ld1NpemUsIHNpemVUb0NvcHkpOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGF0aW5PbmVDRXNfLCAyKmxhdGluT25lVGFibGVMZW5fLCBuZXdUYWJsZSwgMipuZXdTaXplLCBzaXplVG9Db3B5KTsKICAgICAgICBsYXRpbk9uZVRhYmxlTGVuXyA9IG5ld1NpemU7CiAgICAgICAgbGF0aW5PbmVDRXNfID0gbmV3VGFibGU7CiAgICB9CiAgICAKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzZXRVcExhdGluT25lKCkgewogICAgICBpZihsYXRpbk9uZUNFc18gPT0gbnVsbCkgewogICAgICAgIGxhdGluT25lQ0VzXyA9IG5ldyBpbnRbMypMQVRJTk9ORVRBQkxFTEVOX107IAogICAgICAgIGxhdGluT25lVGFibGVMZW5fID0gTEFUSU5PTkVUQUJMRUxFTl87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgQXJyYXlzLmZpbGwobGF0aW5PbmVDRXNfLCAwKTsKICAgICAgfQogICAgICBpZihtX0NvbnRJbmZvXyA9PSBudWxsKSB7CiAgICAgICAgbV9Db250SW5mb18gPSBuZXcgQ29udHJhY3Rpb25JbmZvKCk7CiAgICAgIH0KICAgICAgY2hhciBjaCA9IDA7CiAgICAgIC8vU3RyaW5nQnVmZmVyIHNDaCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgLy9Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXQgPSBnZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc0NoLnRvU3RyaW5nKCkpOwogICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXQgPSBnZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIiIpOwogICAgCiAgICAgIHNoaWZ0VmFsdWVzIHMgPSBuZXcgc2hpZnRWYWx1ZXMoKTsKICAgICAgaW50IENFID0gMDsKICAgICAgY2hhciBjb250cmFjdGlvbk9mZnNldCA9IEVORE9GTEFUSU5PTkVSQU5HRV8rMTsKICAgIAogICAgICBmb3IoY2ggPSAwOyBjaCA8PSBFTkRPRkxBVElOT05FUkFOR0VfOyBjaCsrKSB7CiAgICAgICAgcy5wcmltU2hpZnQgPSAyNDsgcy5zZWNTaGlmdCA9IDI0OyBzLnRlclNoaWZ0ID0gMjQ7CiAgICAgICAgaWYoY2ggPCAweDEwMCkgewogICAgICAgICAgQ0UgPSBtX3RyaWVfLmdldExhdGluMUxpbmVhclZhbHVlKGNoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgQ0UgPSBtX3RyaWVfLmdldExlYWRWYWx1ZShjaCk7CiAgICAgICAgICBpZihDRSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuQ0VfTk9UX0ZPVU5EXykgewogICAgICAgICAgICBDRSA9IFVDQV8ubV90cmllXy5nZXRMZWFkVmFsdWUoY2gpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZighaXNTcGVjaWFsKENFKSkgeyAKICAgICAgICAgIGFkZExhdGluT25lRW50cnkoY2gsIENFLCBzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3dpdGNoIChSdWxlQmFzZWRDb2xsYXRvci5nZXRUYWcoQ0UpKSB7CiAgICAgICAgICBjYXNlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5DRV9FWFBBTlNJT05fVEFHXzoKICAgICAgICAgICAgLy9zQ2guZGVsZXRlKDAsIHNDaC5sZW5ndGgoKSk7CiAgICAgICAgICAgIC8vc0NoLmFwcGVuZChjaCk7CiAgICAgICAgICAgIC8vaXQuc2V0VGV4dChzQ2gudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIGl0LnNldFRleHQoVUNoYXJhY3Rlci50b1N0cmluZyhjaCkpOwogICAgICAgICAgICB3aGlsZSgoQ0UgPSBpdC5uZXh0KCkpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKICAgICAgICAgICAgICBpZihzLnByaW1TaGlmdCA8IDAgfHwgcy5zZWNTaGlmdCA8IDAgfHwgcy50ZXJTaGlmdCA8IDApIHsKICAgICAgICAgICAgICAgIGxhdGluT25lQ0VzX1tjaF0gPSBCQUlMX09VVF9DRV87CiAgICAgICAgICAgICAgICBsYXRpbk9uZUNFc19bbGF0aW5PbmVUYWJsZUxlbl8rY2hdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgICAgICAgbGF0aW5PbmVDRXNfWzIqbGF0aW5PbmVUYWJsZUxlbl8rY2hdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGFkZExhdGluT25lRW50cnkoY2gsIENFLCBzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLkNFX0NPTlRSQUNUSU9OX1RBR186CiAgICAgICAgICAgIC8vIGhlcmUgaXMgdGhlIHRyaWNrCiAgICAgICAgICAgIC8vIEYyIGlzIGNvbnRyYWN0aW9uLiBXZSBkbyBzb21ldGhpbmcgdmVyeSBzaW1pbGFyIHRvIGNvbnRyYWN0aW9ucwogICAgICAgICAgICAvLyBidXQgaGF2ZSB0d28gaW5kaWNlcywgb25lIGluIHRoZSByZWFsIGNvbnRyYWN0aW9uIHRhYmxlIGFuZCB0aGUKICAgICAgICAgICAgLy8gb3RoZXIgdG8gd2hlcmUgd2Ugc3R1ZmZlZCB0aGluZ3MuIFRoaXMgaG9wZXMgdGhhdCB3ZSBkb24ndCBoYXZlCiAgICAgICAgICAgIC8vIG1hbnkgY29udHJhY3Rpb25zICh0aGlzIHNob3VsZCB3b3JrIGZvciBsYXRpbi0xIHRhYmxlcykuCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBpZigoQ0UgJiAweDAwRkZGMDAwKSAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgICAgaW50IFVDaGFyT2Zmc2V0ID0gKENFICYgMHhGRkZGRkYpIC0gbV9jb250cmFjdGlvbk9mZnNldF87IC8vZ2V0Q29udHJhY3Rpb25PZmZzZXQoQ0UpXQogICAgCiAgICAgICAgICAgICAgQ0UgfD0gKGNvbnRyYWN0aW9uT2Zmc2V0ICYgMHhGRkYpIDw8IDEyOyAvLyBpbnNlcnQgdGhlIG9mZnNldCBpbiBsYXRpbi0xIHRhYmxlCiAgICAgICAgCiAgICAgICAgICAgICAgbGF0aW5PbmVDRXNfW2NoXSA9IENFOwogICAgICAgICAgICAgIGxhdGluT25lQ0VzX1tsYXRpbk9uZVRhYmxlTGVuXytjaF0gPSBDRTsKICAgICAgICAgICAgICBsYXRpbk9uZUNFc19bMipsYXRpbk9uZVRhYmxlTGVuXytjaF0gPSBDRTsKICAgIAogICAgICAgICAgICAgIC8vIFdlJ3JlIGdvaW5nIHRvIGp1bXAgaW50byBjb250cmFjdGlvbiB0YWJsZSwgcGljayB0aGUgZWxlbWVudHMKICAgICAgICAgICAgICAvLyBhbmQgdXNlIHRoZW0KICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgIC8vQ0UgPSAqKGNvbnRyYWN0aW9uQ0VzICsgKFVDaGFyT2Zmc2V0IC0gY29udHJhY3Rpb25JbmRleCkpOwogICAgICAgICAgICAgICAgICBDRSA9IG1fY29udHJhY3Rpb25DRV9bVUNoYXJPZmZzZXRdOwogICAgICAgICAgICAgICAgICBpZihnZXRUYWcoQ0UpID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5DRV9FWFBBTlNJT05fVEFHXykgewogICAgICAgICAgICAgICAgICAgIGludCBpOyAgICAvKiBnZW5lcmFsIGNvdW50ZXIgKi8KICAgICAgICAgICAgICAgICAgICAvL3VpbnQzMl90ICpDRU9mZnNldCA9ICh1aW50MzJfdCAqKWltYWdlK2dldEV4cGFuc2lvbk9mZnNldChDRSk7IC8qIGZpbmQgdGhlIG9mZnNldCB0byBleHBhbnNpb24gdGFibGUgKi8KICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gKChDRSAmIDB4RkZGRkYwKSA+PiA0KSAtIG1fZXhwYW5zaW9uT2Zmc2V0XzsgLy9pdC5nZXRFeHBhbnNpb25PZmZzZXQodGhpcywgQ0UpOwogICAgICAgICAgICAgICAgICAgIGludCBzaXplID0gQ0UgJiAweEY7IC8vIGdldEV4cGFuc2lvbkNvdW50KENFKTsKICAgICAgICAgICAgICAgICAgICAvL0NFID0gKkNFT2Zmc2V0Kys7CiAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZSAhPSAwKSB7IC8qIGlmIHRoZXJlIGFyZSBsZXNzIHRoYW4gMTYgZWxlbWVudHMgaW4gZXhwYW5zaW9uLCB3ZSBkb24ndCB0ZXJtaW5hdGUgKi8KICAgICAgICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaTxzaXplOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYocy5wcmltU2hpZnQgPCAwIHx8IHMuc2VjU2hpZnQgPCAwIHx8IHMudGVyU2hpZnQgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aW5PbmVDRXNfW2NvbnRyYWN0aW9uT2Zmc2V0XSA9IEJBSUxfT1VUX0NFXzsKICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpbk9uZUNFc19bbGF0aW5PbmVUYWJsZUxlbl8rY29udHJhY3Rpb25PZmZzZXRdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGluT25lQ0VzX1syKmxhdGluT25lVGFibGVMZW5fK2NvbnRyYWN0aW9uT2Zmc2V0XSA9IEJBSUxfT1VUX0NFXzsKICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBhZGRMYXRpbk9uZUVudHJ5KGNvbnRyYWN0aW9uT2Zmc2V0LCBtX2V4cGFuc2lvbl9bb2Zmc2V0K2ldLCBzKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvKiBlbHNlLCB3ZSBkbyAqLwogICAgICAgICAgICAgICAgICAgICAgd2hpbGUobV9leHBhbnNpb25fW29mZnNldF0gIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZihzLnByaW1TaGlmdCA8IDAgfHwgcy5zZWNTaGlmdCA8IDAgfHwgcy50ZXJTaGlmdCA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpbk9uZUNFc19bY29udHJhY3Rpb25PZmZzZXRdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGluT25lQ0VzX1tsYXRpbk9uZVRhYmxlTGVuXytjb250cmFjdGlvbk9mZnNldF0gPSBCQUlMX09VVF9DRV87CiAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aW5PbmVDRXNfWzIqbGF0aW5PbmVUYWJsZUxlbl8rY29udHJhY3Rpb25PZmZzZXRdID0gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZExhdGluT25lRW50cnkoY29udHJhY3Rpb25PZmZzZXQsIG1fZXhwYW5zaW9uX1tvZmZzZXQrK10sIHMpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250cmFjdGlvbk9mZnNldCsrOwogICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIWlzU3BlY2lhbChDRSkpIHsKICAgICAgICAgICAgICAgICAgICBhZGRMYXRpbk9uZUVudHJ5KGNvbnRyYWN0aW9uT2Zmc2V0KyssIENFLCBzKTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgbGF0aW5PbmVDRXNfW2NvbnRyYWN0aW9uT2Zmc2V0XSA9IEJBSUxfT1VUX0NFXzsKICAgICAgICAgICAgICAgICAgICAgIGxhdGluT25lQ0VzX1tsYXRpbk9uZVRhYmxlTGVuXytjb250cmFjdGlvbk9mZnNldF0gPSBCQUlMX09VVF9DRV87CiAgICAgICAgICAgICAgICAgICAgICBsYXRpbk9uZUNFc19bMipsYXRpbk9uZVRhYmxlTGVuXytjb250cmFjdGlvbk9mZnNldF0gPSBCQUlMX09VVF9DRV87CiAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGlvbk9mZnNldCsrOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIFVDaGFyT2Zmc2V0Kys7CiAgICAgICAgICAgICAgICAgIHMucHJpbVNoaWZ0ID0gMjQ7IHMuc2VjU2hpZnQgPSAyNDsgcy50ZXJTaGlmdCA9IDI0OwogICAgICAgICAgICAgICAgICBpZihjb250cmFjdGlvbk9mZnNldCA9PSBsYXRpbk9uZVRhYmxlTGVuXykgeyAvLyB3ZSBuZWVkIHRvIHJlYWxsb2NhdGUKICAgICAgICAgICAgICAgICAgIHJlc2l6ZUxhdGluT25lVGFibGUoMipsYXRpbk9uZVRhYmxlTGVuXyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IHdoaWxlKG1fY29udHJhY3Rpb25JbmRleF9bVUNoYXJPZmZzZXRdICE9IDB4RkZGRik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBsYXRpbk9uZUZhaWxlZF8gPSB0cnVlOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGNvbXBhY3QgdGFibGUKICAgICAgaWYoY29udHJhY3Rpb25PZmZzZXQgPCBsYXRpbk9uZVRhYmxlTGVuXykgewogICAgICAgIHJlc2l6ZUxhdGluT25lVGFibGUoY29udHJhY3Rpb25PZmZzZXQpOwogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgY2xhc3MKICAgIENvbnRyYWN0aW9uSW5mbyB7CiAgICAgICAgaW50IGluZGV4OwogICAgfTsKICAgIAogICAgQ29udHJhY3Rpb25JbmZvIG1fQ29udEluZm9fOwoKICAgIHByaXZhdGUgaW50IAogICAgZ2V0TGF0aW5PbmVDb250cmFjdGlvbihpbnQgc3RyZW5ndGgsIGludCBDRSwgU3RyaW5nIHMpIHsKICAgIC8vaW50IHN0cmVuZ3RoLCBpbnQgQ0UsIFN0cmluZyBzLCBJbnRlZ2VyIGluZCkgewogICAgICBpbnQgbGVuID0gcy5sZW5ndGgoKTsgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAvL2NvbnN0IFVDaGFyICpVQ2hhck9mZnNldCA9IChVQ2hhciAqKWNvbGwtPmltYWdlK2dldENvbnRyYWN0T2Zmc2V0KENFJjB4RkZGKTsKICAgICAgaW50IFVDaGFyT2Zmc2V0ID0gKENFICYgMHhGRkYpIC0gbV9jb250cmFjdGlvbk9mZnNldF87CiAgICAgIGludCBvZmZzZXQgPSAxOwogICAgICBpbnQgbGF0aW5PbmVPZmZzZXQgPSAoQ0UgJiAweDAwRkZGMDAwKSA+Pj4gMTI7CiAgICAgIGNoYXIgc2NoYXIgPSAwLCB0Y2hhciA9IDA7CiAgICAKICAgICAgZm9yKDs7KSB7CiAgICAgICAgLyoKICAgICAgICBpZihsZW4gPT0gLTEpIHsKICAgICAgICAgIGlmKHNbKmluZGV4XSA9PSAwKSB7IC8vIGVuZCBvZiBzdHJpbmcKICAgICAgICAgICAgcmV0dXJuKGNvbGwtPmxhdGluT25lQ0VzW3N0cmVuZ3RoKmNvbGwtPmxhdGluT25lVGFibGVMZW4rbGF0aW5PbmVPZmZzZXRdKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNjaGFyID0gc1sqaW5kZXhdOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgKi8KICAgICAgICAgIGlmKG1fQ29udEluZm9fLmluZGV4ID09IGxlbikgewogICAgICAgICAgICByZXR1cm4obGF0aW5PbmVDRXNfW3N0cmVuZ3RoKmxhdGluT25lVGFibGVMZW5fK2xhdGluT25lT2Zmc2V0XSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzY2hhciA9IHMuY2hhckF0KG1fQ29udEluZm9fLmluZGV4KTsKICAgICAgICAgIH0KICAgICAgICAvL30KICAgIAogICAgICAgIHdoaWxlKHNjaGFyID4gKHRjaGFyID0gbV9jb250cmFjdGlvbkluZGV4X1tVQ2hhck9mZnNldCtvZmZzZXRdLyoqKFVDaGFyT2Zmc2V0K29mZnNldCkqLykpIHsgLyogc2luY2UgdGhlIGNvbnRyYWN0aW9uIGNvZGVwb2ludHMgc2hvdWxkIGJlIG9yZGVyZWQsIHdlIHNraXAgYWxsIHRoYXQgYXJlIHNtYWxsZXIgKi8KICAgICAgICAgIG9mZnNldCsrOwogICAgICAgIH0KICAgIAogICAgICAgIGlmIChzY2hhciA9PSB0Y2hhcikgewogICAgICAgICAgbV9Db250SW5mb18uaW5kZXgrKzsKICAgICAgICAgIHJldHVybihsYXRpbk9uZUNFc19bc3RyZW5ndGgqbGF0aW5PbmVUYWJsZUxlbl8rbGF0aW5PbmVPZmZzZXQrb2Zmc2V0XSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICBpZihzY2hhciAgPiBFTkRPRkxBVElOT05FUkFOR0VfIC8qJiAweEZGMDAqLykgewogICAgICAgICAgICByZXR1cm4gQkFJTF9PVVRfQ0VfOwogICAgICAgICAgfQogICAgICAgICAgLy8gc2tpcCBjb21wbGV0ZWx5IGlnbm9yYWJsZXMKICAgICAgICAgIGludCBpc1plcm9DRSA9IG1fdHJpZV8uZ2V0TGVhZFZhbHVlKHNjaGFyKTsgLy9VVFJJRV9HRVQzMl9GUk9NX0xFQUQoY29sbC0+bWFwcGluZywgc2NoYXIpOwogICAgICAgICAgaWYoaXNaZXJvQ0UgPT0gMCkgeyAvLyB3ZSBoYXZlIHRvIGlnbm9yZSBjb21wbGV0ZWx5IGlnbm9yYWJsZXMKICAgICAgICAgICAgbV9Db250SW5mb18uaW5kZXgrKzsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CiAgICAKICAgICAgICAgIHJldHVybihsYXRpbk9uZUNFc19bc3RyZW5ndGgqbGF0aW5PbmVUYWJsZUxlbl8rbGF0aW5PbmVPZmZzZXRdKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAKICAgIC8qKiAKICAgICAqIFRoaXMgaXMgYSBmYXN0IHN0cmNvbGwsIGdlYXJlZCB0b3dhcmRzIHRleHQgaW4gTGF0aW4tMS4gCiAgICAgKiBJdCBzdXBwb3J0cyBjb250cmFjdGlvbnMgb2Ygc2l6ZSB0d28sIEZyZW5jaCBzZWNvbmRhcmllcwogICAgICogYW5kIGNhc2Ugc3dpdGNoaW5nLiBZb3UgY2FuIHVzZSBpdCB3aXRoIHN0cmVuZ3RocyBwcmltYXJ5CiAgICAgKiB0byB0ZXJ0aWFyeS4gSXQgZG9lcyBub3Qgc3VwcG9ydCBzaGlmdGVkIGFuZCBjYXNlIGxldmVsLgogICAgICogSXQgcmVsaWVzIG9uIHRoZSB0YWJsZSBidWlsZCBieSBzZXR1cExhdGluMVRhYmxlLiBJZiBpdAogICAgICogZG9lc24ndCB1bmRlcnN0YW5kIHNvbWV0aGluZywgaXQgd2lsbCBnbyB0byB0aGUgcmVndWxhcgogICAgICogc3RyY29sbC4gCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgaW50IAogICAgY29tcGFyZVVzZUxhdGluMShTdHJpbmcgc291cmNlLCBTdHJpbmcgdGFyZ2V0LCBpbnQgc3RhcnRPZmZzZXQpCiAgICB7CiAgICAgICAgaW50IHNMZW4gPSBzb3VyY2UubGVuZ3RoKCk7CiAgICAgICAgaW50IHRMZW4gPSB0YXJnZXQubGVuZ3RoKCk7CiAgICAgICAgCiAgICAgICAgaW50IHN0cmVuZ3RoID0gZ2V0U3RyZW5ndGgoKTsKICAgIAogICAgICAgIGludCBzSW5kZXggPSBzdGFydE9mZnNldCwgdEluZGV4ID0gc3RhcnRPZmZzZXQ7CiAgICAgICAgY2hhciBzQ2hhciA9IDAsIHRDaGFyID0gMDsKICAgICAgICBpbnQgc09yZGVyPTAsIHRPcmRlcj0wOwogICAgCiAgICAgICAgYm9vbGVhbiBlbmRPZlNvdXJjZSA9IGZhbHNlOwogICAgCiAgICAgICAgLy91aW50MzJfdCAqZWxlbWVudHMgPSBjb2xsLT5sYXRpbk9uZUNFczsKICAgIAogICAgICAgIGJvb2xlYW4gaGF2ZUNvbnRyYWN0aW9ucyA9IGZhbHNlOyAvLyBpZiB3ZSBoYXZlIGNvbnRyYWN0aW9ucyBpbiBvdXIgc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBjYW5ub3QgZG8gRnJlbmNoIHNlY29uZGFyeQogICAgCiAgICAgICAgaW50IG9mZnNldCA9IGxhdGluT25lVGFibGVMZW5fOwogICAgICAgIAogICAgICAgIC8vIERvIHRoZSBwcmltYXJ5IGxldmVsCiAgICBwcmltTG9vcDoKICAgICAgICBmb3IoOzspIHsKICAgICAgICAgIHdoaWxlKHNPcmRlcj09MCkgeyAvLyB0aGlzIGxvb3Agc2tpcHMgcHJpbWFyeSBpZ25vcmFibGVzCiAgICAgICAgICAgIC8vIHNPcmRlcj1nZXROZXh0bGF0aW5PbmVDRShzb3VyY2UpOwogICAgICAgICAgICAgIGlmKHNJbmRleD09c0xlbikgewogICAgICAgICAgICAgICAgZW5kT2ZTb3VyY2UgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHNDaGFyPXNvdXJjZS5jaGFyQXQoc0luZGV4KyspOyAvL1tzSW5kZXgrK107ICAgICAgICAgICAgICAKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIGlmKHNDaGFyID4gRU5ET0ZMQVRJTk9ORVJBTkdFXykgeyAvLyBpZiB3ZSBlbmNvdW50ZXIgbm9uLWxhdGluLTEsIHdlIGJhaWwgb3V0IAogICAgICAgICAgICAgIC8vZnByaW50ZihzdGRlcnIsICJSIik7CiAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVSZWd1bGFyKHNvdXJjZSwgdGFyZ2V0LCBzdGFydE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc09yZGVyID0gbGF0aW5PbmVDRXNfW3NDaGFyXTsKICAgICAgICAgICAgaWYoaXNTcGVjaWFsKHNPcmRlcikpIHsgLy8gaWYgd2UgZ290IGEgc3BlY2lhbAogICAgICAgICAgICAgIC8vIHNwZWNpYWxzIGNhbiBiYXNpY2FsbHkgYmUgZWl0aGVyIGNvbnRyYWN0aW9ucyBvciBiYWlsLW91dCBzaWducy4gSWYgd2UgZ2V0IGFueXRoaW5nCiAgICAgICAgICAgICAgLy8gZWxzZSwgd2UnbGwgYmFpbCBvdXQgYW55d2FzeQogICAgICAgICAgICAgIGlmKGdldFRhZyhzT3JkZXIpID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5DRV9DT05UUkFDVElPTl9UQUdfKSB7CiAgICAgICAgICAgICAgICBtX0NvbnRJbmZvXy5pbmRleCA9IHNJbmRleDsKICAgICAgICAgICAgICAgIHNPcmRlciA9IGdldExhdGluT25lQ29udHJhY3Rpb24oMCwgc09yZGVyLCBzb3VyY2UpOwogICAgICAgICAgICAgICAgc0luZGV4ID0gbV9Db250SW5mb18uaW5kZXg7CiAgICAgICAgICAgICAgICBoYXZlQ29udHJhY3Rpb25zID0gdHJ1ZTsgLy8gaWYgdGhlcmUgYXJlIGNvbnRyYWN0aW9ucywgd2UgY2Fubm90IGRvIEZyZW5jaCBzZWNvbmRhcnkKICAgICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIGlmIHRoZXJlIGFyZSBjb250cmFjdGlvbnMgaW4gdGhlIHRhYmxlLCBidXQgd2UgYWx3YXlzIHVzZSBqdXN0IG9uZSBjaGFyLAogICAgICAgICAgICAgICAgLy8gd2UgbWlnaHQgYmUgYWJsZSB0byBkbyBGcmVuY2guIFRoaXMgc2hvdWxkIGJlIGNoZWNrZWQgb3V0LgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZihpc1NwZWNpYWwoc09yZGVyKSAvKj09IFVDT0xfQkFJTF9PVVRfQ0UqLykgewogICAgICAgICAgICAgICAgLy9mcHJpbnRmKHN0ZGVyciwgIlMiKTsKICAgICAgICAgICAgICAgIHJldHVybiBjb21wYXJlUmVndWxhcihzb3VyY2UsIHRhcmdldCwgc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgCiAgICAgICAgICB3aGlsZSh0T3JkZXI9PTApIHsgIC8vIHRoaXMgbG9vcCBza2lwcyBwcmltYXJ5IGlnbm9yYWJsZXMKICAgICAgICAgICAgLy8gdE9yZGVyPWdldE5leHRsYXRpbk9uZUNFKHRhcmdldCk7CiAgICAgICAgICAgIGlmKHRJbmRleD09dExlbikgewogICAgICAgICAgICAgIGlmKGVuZE9mU291cmNlKSB7CiAgICAgICAgICAgICAgICBicmVhayBwcmltTG9vcDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRDaGFyPXRhcmdldC5jaGFyQXQodEluZGV4KyspOyAvL1t0SW5kZXgrK107CiAgICAgICAgICAgIGlmKHRDaGFyID4gRU5ET0ZMQVRJTk9ORVJBTkdFXykgeyAvLyBpZiB3ZSBlbmNvdW50ZXIgbm9uLWxhdGluLTEsIHdlIGJhaWwgb3V0IAogICAgICAgICAgICAgIC8vZnByaW50ZihzdGRlcnIsICJSIik7CiAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVSZWd1bGFyKHNvdXJjZSwgdGFyZ2V0LCBzdGFydE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdE9yZGVyID0gbGF0aW5PbmVDRXNfW3RDaGFyXTsKICAgICAgICAgICAgaWYoaXNTcGVjaWFsKHRPcmRlcikpIHsKICAgICAgICAgICAgICAvLyBIYW5kbGluZyBzcGVjaWFscywgc2VlIHRoZSBjb21tZW50cyBmb3Igc291cmNlCiAgICAgICAgICAgICAgaWYoZ2V0VGFnKHRPcmRlcikgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLkNFX0NPTlRSQUNUSU9OX1RBR18pIHsKICAgICAgICAgICAgICAgIG1fQ29udEluZm9fLmluZGV4ID0gdEluZGV4OwogICAgICAgICAgICAgICAgdE9yZGVyID0gZ2V0TGF0aW5PbmVDb250cmFjdGlvbigwLCB0T3JkZXIsIHRhcmdldCk7CiAgICAgICAgICAgICAgICB0SW5kZXggPSBtX0NvbnRJbmZvXy5pbmRleDsKICAgICAgICAgICAgICAgIGhhdmVDb250cmFjdGlvbnMgPSB0cnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZihpc1NwZWNpYWwodE9yZGVyKS8qPT0gVUNPTF9CQUlMX09VVF9DRSovKSB7CiAgICAgICAgICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiUyIpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVSZWd1bGFyKHNvdXJjZSwgdGFyZ2V0LCBzdGFydE9mZnNldCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZihlbmRPZlNvdXJjZSkgeyAvLyBzb3VyY2UgaXMgZmluaXNoZWQsIGJ1dCB0YXJnZXQgaXMgbm90LCBzYXkgdGhlIHJlc3VsdC4KICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICB9CiAgICAKICAgICAgICAgIGlmKHNPcmRlciA9PSB0T3JkZXIpIHsgLy8gaWYgd2UgaGF2ZSBzYW1lIENFcywgd2UgY29udGludWUgdGhlIGxvb3AKICAgICAgICAgICAgc09yZGVyID0gMDsgdE9yZGVyID0gMDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBjb21wYXJlIGN1cnJlbnQgdG9wIGJ5dGVzCiAgICAgICAgICAgIGlmKCgoc09yZGVyXnRPcmRlcikmMHhGRjAwMDAwMCkhPTApIHsKICAgICAgICAgICAgICAvLyB0b3AgYnl0ZXMgZGlmZmVyLCByZXR1cm4gZGlmZmVyZW5jZQogICAgICAgICAgICAgIGlmKHNPcmRlciA+Pj4gOCA8IHRPcmRlciA+Pj4gOCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gaW5zdGVhZCBvZiByZXR1cm4gKGludDMyX3QpKHNPcmRlcj4+MjQpLShpbnQzMl90KSh0T3JkZXI+PjI0KTsKICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSBtdXN0IHJldHVybiBlbnVtIHZhbHVlCiAgICAgICAgICAgIH0KICAgIAogICAgICAgICAgICAvLyB0b3AgYnl0ZXMgbWF0Y2gsIGNvbnRpbnVlIHdpdGggZm9sbG93aW5nIGJ5dGVzCiAgICAgICAgICAgIHNPcmRlcjw8PTg7CiAgICAgICAgICAgIHRPcmRlcjw8PTg7CiAgICAgICAgICB9IAogICAgICAgIH0KICAgIAogICAgICAgIC8vIGFmdGVyIHByaW1hcnkgbG9vcCwgd2UgZGVmaW5pdGVseSBrbm93IHRoZSBzaXplcyBvZiBzdHJpbmdzLCAKICAgICAgICAvLyBzbyB3ZSBzZXQgaXQgYW5kIHVzZSBzaW1wbGVyIGxvb3AgZm9yIHNlY29uZGFyaWVzIGFuZCB0ZXJ0aWFyaWVzCiAgICAgICAgLy9zTGVuID0gc0luZGV4OyB0TGVuID0gdEluZGV4OwogICAgICAgIGlmKHN0cmVuZ3RoID49IFNFQ09OREFSWSkgewogICAgICAgICAgLy8gYWRqdXN0IHRoZSB0YWJsZSBiZWdnaW5pbmcKICAgICAgICAgIC8vbGF0aW5PbmVDRXNfICs9IGNvbGwtPmxhdGluT25lVGFibGVMZW47CiAgICAgICAgICBlbmRPZlNvdXJjZSA9IGZhbHNlOyAKICAgIAogICAgICAgICAgaWYoIW1faXNGcmVuY2hDb2xsYXRpb25fKSB7IC8vIG5vbiBGcmVuY2gKICAgICAgICAgICAgLy8gVGhpcyBsb29wIGlzIGEgc2ltcGxpZmllZCBjb3B5IG9mIHByaW1hcnkgbG9vcAogICAgICAgICAgICAvLyBhdCB0aGlzIHBvaW50IHdlIGtub3cgdGhhdCB3aG9sZSBzdHJpbmdzIGFyZSBsYXRpbi0xLCBzbyB3ZSBkb24ndCAKICAgICAgICAgICAgLy8gY2hlY2sgZm9yIHRoYXQuIFdlIGFsc28ga25vdyB0aGF0IHdlIG9ubHkgaGF2ZSBjb250cmFjdGlvbnMgYXMgCiAgICAgICAgICAgIC8vIHNwZWNpYWxzLgogICAgICAgICAgICAvL3NJbmRleCA9IDA7IHRJbmRleCA9IDA7CiAgICAgICAgICAgIHNJbmRleCA9IHN0YXJ0T2Zmc2V0OyB0SW5kZXggPSBzdGFydE9mZnNldDsKICAgIHNlY0xvb3A6CiAgICAgICAgICAgIGZvcig7OykgewogICAgICAgICAgICAgIHdoaWxlKHNPcmRlcj09MCkgewogICAgICAgICAgICAgICAgaWYoc0luZGV4PT1zTGVuKSB7CiAgICAgICAgICAgICAgICAgIGVuZE9mU291cmNlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzQ2hhcj1zb3VyY2UuY2hhckF0KHNJbmRleCsrKTsgLy9bc0luZGV4KytdOwogICAgICAgICAgICAgICAgc09yZGVyID0gbGF0aW5PbmVDRXNfW29mZnNldCtzQ2hhcl07CiAgICAgICAgICAgICAgICBpZihpc1NwZWNpYWwoc09yZGVyKSkgewogICAgICAgICAgICAgICAgICAgIG1fQ29udEluZm9fLmluZGV4ID0gc0luZGV4OwogICAgICAgICAgICAgICAgICAgIHNPcmRlciA9IGdldExhdGluT25lQ29udHJhY3Rpb24oMSwgc09yZGVyLCBzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgIHNJbmRleCA9IG1fQ29udEluZm9fLmluZGV4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgIAogICAgICAgICAgICAgIHdoaWxlKHRPcmRlcj09MCkgewogICAgICAgICAgICAgICAgaWYodEluZGV4PT10TGVuKSB7CiAgICAgICAgICAgICAgICAgIGlmKGVuZE9mU291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2VjTG9vcDsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdENoYXI9dGFyZ2V0LmNoYXJBdCh0SW5kZXgrKyk7IC8vW3RJbmRleCsrXTsKICAgICAgICAgICAgICAgIHRPcmRlciA9IGxhdGluT25lQ0VzX1tvZmZzZXQrdENoYXJdOwogICAgICAgICAgICAgICAgaWYoaXNTcGVjaWFsKHRPcmRlcikpIHsKICAgICAgICAgICAgICAgICAgICBtX0NvbnRJbmZvXy5pbmRleCA9IHRJbmRleDsKICAgICAgICAgICAgICAgICAgICB0T3JkZXIgPSBnZXRMYXRpbk9uZUNvbnRyYWN0aW9uKDEsIHRPcmRlciwgdGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICB0SW5kZXggPSBtX0NvbnRJbmZvXy5pbmRleDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYoZW5kT2ZTb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgIH0KICAgIAogICAgICAgICAgICAgIGlmKHNPcmRlciA9PSB0T3JkZXIpIHsKICAgICAgICAgICAgICAgIHNPcmRlciA9IDA7IHRPcmRlciA9IDA7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gc2VlIHByaW1hcnkgbG9vcCBmb3IgY29tbWVudHMgb24gdGhpcwogICAgICAgICAgICAgICAgaWYoKChzT3JkZXJedE9yZGVyKSYweEZGMDAwMDAwKSE9MCkgewogICAgICAgICAgICAgICAgICBpZihzT3JkZXIgPj4+IDggPCB0T3JkZXIgPj4+IDgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNPcmRlcjw8PTg7CiAgICAgICAgICAgICAgICB0T3JkZXI8PD04OwogICAgICAgICAgICAgIH0gCiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7IC8vIEZyZW5jaAogICAgICAgICAgICBpZihoYXZlQ29udHJhY3Rpb25zKSB7IC8vIGlmIHdlIGhhdmUgY29udHJhY3Rpb25zLCB3ZSBoYXZlIHRvIGJhaWwgb3V0CiAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgZG9uJ3QgcmVhbGx5IGtub3cgaG93IHRvIGhhbmRsZSB0aGVtIGhlcmUKICAgICAgICAgICAgICByZXR1cm4gY29tcGFyZVJlZ3VsYXIoc291cmNlLCB0YXJnZXQsIHN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBGb3IgRnJlbmNoLCB3ZSBnbyBiYWNrd2FyZHMKICAgICAgICAgICAgc0luZGV4ID0gc0xlbjsgdEluZGV4ID0gdExlbjsKICAgIHNlY0ZMb29wOgogICAgICAgICAgICBmb3IoOzspIHsKICAgICAgICAgICAgICB3aGlsZShzT3JkZXI9PTApIHsKICAgICAgICAgICAgICAgIGlmKHNJbmRleD09c3RhcnRPZmZzZXQpIHsKICAgICAgICAgICAgICAgICAgZW5kT2ZTb3VyY2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNDaGFyPXNvdXJjZS5jaGFyQXQoLS1zSW5kZXgpOyAvL1stLXNJbmRleF07CiAgICAgICAgICAgICAgICBzT3JkZXIgPSBsYXRpbk9uZUNFc19bb2Zmc2V0K3NDaGFyXTsKICAgICAgICAgICAgICAgIC8vIGRvbid0IGV2ZW4gbG9vayBmb3IgY29udHJhY3Rpb25zCiAgICAgICAgICAgICAgfQogICAgCiAgICAgICAgICAgICAgd2hpbGUodE9yZGVyPT0wKSB7CiAgICAgICAgICAgICAgICBpZih0SW5kZXg9PXN0YXJ0T2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgIGlmKGVuZE9mU291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgc2VjRkxvb3A7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRDaGFyPXRhcmdldC5jaGFyQXQoLS10SW5kZXgpOyAvL1stLXRJbmRleF07CiAgICAgICAgICAgICAgICB0T3JkZXIgPSBsYXRpbk9uZUNFc19bb2Zmc2V0K3RDaGFyXTsKICAgICAgICAgICAgICAgIC8vIGRvbid0IGV2ZW4gbG9vayBmb3IgY29udHJhY3Rpb25zCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmKGVuZE9mU291cmNlKSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICB9CiAgICAKICAgICAgICAgICAgICBpZihzT3JkZXIgPT0gdE9yZGVyKSB7CiAgICAgICAgICAgICAgICBzT3JkZXIgPSAwOyB0T3JkZXIgPSAwOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHNlZSB0aGUgcHJpbWFyeSBsb29wIGZvciBjb21tZW50cwogICAgICAgICAgICAgICAgaWYoKChzT3JkZXJedE9yZGVyKSYweEZGMDAwMDAwKSE9MCkgewogICAgICAgICAgICAgICAgICBpZihzT3JkZXIgPj4+IDggPCB0T3JkZXIgPj4+IDgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNPcmRlcjw8PTg7CiAgICAgICAgICAgICAgICB0T3JkZXI8PD04OwogICAgICAgICAgICAgIH0gICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9IAogICAgCiAgICAgICAgaWYoc3RyZW5ndGggPj0gVEVSVElBUlkpIHsKICAgICAgICAgIC8vIHRlcnRpYXJ5IGxvb3AgaXMgdGhlIHNhbWUgYXMgc2Vjb25kYXJ5IChleGNlcHQgbm8gRnJlbmNoKQogICAgICAgICAgb2Zmc2V0ICs9IGxhdGluT25lVGFibGVMZW5fOwogICAgICAgICAgLy9zSW5kZXggPSAwOyB0SW5kZXggPSAwOwogICAgICAgICAgc0luZGV4ID0gc3RhcnRPZmZzZXQ7IHRJbmRleCA9IHN0YXJ0T2Zmc2V0OwogICAgICAgICAgZW5kT2ZTb3VyY2UgPSBmYWxzZTsKICAgICAgICAgIGZvcig7OykgewogICAgICAgICAgICB3aGlsZShzT3JkZXI9PTApIHsKICAgICAgICAgICAgICBpZihzSW5kZXg9PXNMZW4pIHsKICAgICAgICAgICAgICAgIGVuZE9mU291cmNlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBzQ2hhcj1zb3VyY2UuY2hhckF0KHNJbmRleCsrKTsgLy9bc0luZGV4KytdOwogICAgICAgICAgICAgIHNPcmRlciA9IGxhdGluT25lQ0VzX1tvZmZzZXQrc0NoYXJdOwogICAgICAgICAgICAgIGlmKGlzU3BlY2lhbChzT3JkZXIpKSB7CiAgICAgICAgICAgICAgICBtX0NvbnRJbmZvXy5pbmRleCA9IHNJbmRleDsKICAgICAgICAgICAgICAgIHNPcmRlciA9IGdldExhdGluT25lQ29udHJhY3Rpb24oMiwgc09yZGVyLCBzb3VyY2UpOwogICAgICAgICAgICAgICAgc0luZGV4ID0gbV9Db250SW5mb18uaW5kZXg7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlKHRPcmRlcj09MCkgewogICAgICAgICAgICAgIGlmKHRJbmRleD09dExlbikgewogICAgICAgICAgICAgICAgaWYoZW5kT2ZTb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7IC8vIGlmIGJvdGggc3RyaW5ncyBhcmUgYXQgdGhlIGVuZCwgdGhleSBhcmUgZXF1YWwKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB0Q2hhcj10YXJnZXQuY2hhckF0KHRJbmRleCsrKTsgLy9bdEluZGV4KytdOwogICAgICAgICAgICAgIHRPcmRlciA9IGxhdGluT25lQ0VzX1tvZmZzZXQrdENoYXJdOwogICAgICAgICAgICAgIGlmKGlzU3BlY2lhbCh0T3JkZXIpKSB7CiAgICAgICAgICAgICAgICBtX0NvbnRJbmZvXy5pbmRleCA9IHRJbmRleDsKICAgICAgICAgICAgICAgIHRPcmRlciA9IGdldExhdGluT25lQ29udHJhY3Rpb24oMiwgdE9yZGVyLCB0YXJnZXQpOwogICAgICAgICAgICAgICAgdEluZGV4ID0gbV9Db250SW5mb18uaW5kZXg7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGVuZE9mU291cmNlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoc09yZGVyID09IHRPcmRlcikgewogICAgICAgICAgICAgIHNPcmRlciA9IDA7IHRPcmRlciA9IDA7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgaWYoKChzT3JkZXJedE9yZGVyKSYweGZmMDAwMDAwKSE9MCkgewogICAgICAgICAgICAgICAgaWYoc09yZGVyID4+PiA4IDwgdE9yZGVyID4+PiA4KSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBzT3JkZXI8PD04OwogICAgICAgICAgICAgIHRPcmRlcjw8PTg7CiAgICAgICAgICAgIH0gCiAgICAgICAgICB9CiAgICAgICAgfSAKICAgICAgICByZXR1cm4gMDsKICAgIH0gICAgCn0K