LyoKICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQogKgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cyAKICogcmVzZXJ2ZWQuCiAqCiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKICogYXJlIG1ldDoKICoKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLiAKICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCiAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKICogICAgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDogIAogKiAgICAgICAiVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSB0aGUKICogICAgICAgIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChodHRwOi8vd3d3LmFwYWNoZS5vcmcvKS4iCiAqICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZGdtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwKICogICAgaWYgYW5kIHdoZXJldmVyIHN1Y2ggdGhpcmQtcGFydHkgYWNrbm93bGVkZ21lbnRzIG5vcm1hbGx5IGFwcGVhci4KICoKICogNC4gVGhlIG5hbWVzICJYYWxhbiIgYW5kICJBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiIgbXVzdAogKiAgICBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMKICogICAgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuIAogKiAgICBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdCBhcGFjaGVAYXBhY2hlLm9yZy4KICoKICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIsCiAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWUsIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgogKiAgICBwZXJtaXNzaW9uIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTRUQgT1IgSU1QTElFRAogKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwogKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQogKiBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFQQUNIRSBTT0ZUV0FSRSBGT1VOREFUSU9OIE9SCiAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GCiAqIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksCiAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAogKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIFRoaXMgc29mdHdhcmUgY29uc2lzdHMgb2Ygdm9sdW50YXJ5IGNvbnRyaWJ1dGlvbnMgbWFkZSBieSBtYW55CiAqIGluZGl2aWR1YWxzIG9uIGJlaGFsZiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gYW5kIHdhcwogKiBvcmlnaW5hbGx5IGJhc2VkIG9uIHNvZnR3YXJlIGNvcHlyaWdodCAoYykgMTk5OSwgTG90dXMKICogRGV2ZWxvcG1lbnQgQ29ycG9yYXRpb24uLCBodHRwOi8vd3d3LmxvdHVzLmNvbS4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCiAqLwpwYWNrYWdlIG9yZy5hcGFjaGUueGFsYW4uc2VyaWFsaXplOwoKaW1wb3J0IGphdmEuaW8uV3JpdGVyOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKCi8qKgogKiBQcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCBlbmNvZGluZ3MuIERlcGVuZHMgb24gdGhlIEphdmEgcnVudGltZQogKiB0byBwcm92aWRlcyB3cml0ZXJzIGZvciB0aGUgZGlmZmVyZW50IGVuY29kaW5ncywgYnV0IGNhbiBiZSB1c2VkCiAqIHRvIG92ZXJyaWRlIGVuY29kaW5nIG5hbWVzIGFuZCBwcm92aWRlIHRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIKICogZm9yIGVhY2ggZW5jb2RpbmcuCiAqCiAqIEB2ZXJzaW9uICRSZXZpc2lvbiQgJERhdGUkCiAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFya2luQGludGFsaW8uY29tIj5Bc3NhZiBBcmtpbjwvYT4KICovCnB1YmxpYyBjbGFzcyBFbmNvZGluZ3MgZXh0ZW5kcyBPYmplY3QKewoKICAvKioKICAgKiBUaGUgbGFzdCBwcmludGFibGUgY2hhcmFjdGVyIGZvciB1bmtub3duIGVuY29kaW5ncy4KICAgKi8KICBzdGF0aWMgZmluYWwgaW50IG1fZGVmYXVsdExhc3RQcmludGFibGUgPSAweDdGOwoKICAvKioKICAgKiBSZXR1cm5zIGEgd3JpdGVyIGZvciB0aGUgc3BlY2lmaWVkIGVuY29kaW5nIGJhc2VkIG9uCiAgICogYW4gb3V0cHV0IHN0cmVhbS4KICAgKgogICAqIEBwYXJhbSBvdXRwdXQgVGhlIG91dHB1dCBzdHJlYW0KICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGVuY29kaW5nCiAgICogQHJldHVybiBBIHN1aXRhYmxlIHdyaXRlcgogICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBUaGVyZSBpcyBubyBjb252ZXJ0b3IKICAgKiAgdG8gc3VwcG9ydCB0aGlzIGVuY29kaW5nCiAgICovCiAgcHVibGljIHN0YXRpYyBXcml0ZXIgZ2V0V3JpdGVyKE91dHB1dFN0cmVhbSBvdXRwdXQsIFN0cmluZyBlbmNvZGluZykKICAgICAgICAgIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uCiAgewoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX2VuY29kaW5ncy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgaWYgKF9lbmNvZGluZ3NbaV0ubmFtZS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKSkKICAgICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgIHJldHVybiBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dHB1dCwgX2VuY29kaW5nc1tpXS5qYXZhTmFtZSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgLy8gamF2YSAxLjEuOAogICAgICAgIHsKICAgICAgICAgIC8vIGtlZXAgdHJ5aW5nCiAgICAgICAgfQogICAgICAgIGNhdGNoIChVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uIHVzZWUpCiAgICAgICAgewoKICAgICAgICAgIC8vIGtlZXAgdHJ5aW5nCiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgdHJ5CiAgICB7CiAgICAgIHJldHVybiBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG91dHB1dCwgZW5jb2RpbmcpOwogICAgfQogICAgY2F0Y2goIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSAvLyBqYXZhIDEuMS44CiAgICB7CiAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uKGVuY29kaW5nKTsKICAgIH0KICB9CiAgCiAgLyoqCiAgICogUmV0dXJucyBhbiBvcGFxdWUgQ2hhclRvQnl0ZSBjb252ZXJ0ZXIgZm9yIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmcuCiAgICoKICAgKiBAcGFyYW0gZW5jb2RpbmcgVGhlIGVuY29kaW5nCiAgICogQHJldHVybiBBbiBvYmplY3Qgd2hpY2ggc2hvdWxkIGJlIGEgc3VuLmlvLkNoYXJUb0J5dGVDb252ZXJ0ZXIsIG9yIG51bGwuCiAgICovCiAgcHVibGljIHN0YXRpYyBPYmplY3QgZ2V0Q2hhclRvQnl0ZUNvbnZlcnRlcihTdHJpbmcgZW5jb2RpbmcpCiAgewoKICAgIENsYXNzIGNoYXJUb0J5dGVDb252ZXJ0ZXJDbGFzcyA9IG51bGw7CiAgICBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZ2V0Q29udmVydGVyTWV0aG9kID0gbnVsbDsKICAgIAogICAgdHJ5CiAgICB7CiAgICAgIGNoYXJUb0J5dGVDb252ZXJ0ZXJDbGFzcyA9IENsYXNzLmZvck5hbWUoInN1bi5pby5DaGFyVG9CeXRlQ29udmVydGVyIik7CiAgICAgIENsYXNzIGFyZ1R5cGVzW10gPSBuZXcgQ2xhc3NbMV07CiAgICAgIGFyZ1R5cGVzWzBdID0gU3RyaW5nLmNsYXNzOwogICAgICBnZXRDb252ZXJ0ZXJNZXRob2QgCiAgICAgICAgPSBjaGFyVG9CeXRlQ29udmVydGVyQ2xhc3MuZ2V0TWV0aG9kKCJnZXRDb252ZXJ0ZXIiLCBhcmdUeXBlcyk7CiAgICB9CiAgICBjYXRjaChFeGNlcHRpb24gZSkKICAgIHsKICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJXYXJuaW5nOiBDb3VsZCBub3QgZ2V0IGNoYXJUb0J5dGVDb252ZXJ0ZXJDbGFzcyEiKTsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBPYmplY3QgYXJnc1tdID0gbmV3IE9iamVjdFsxXTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX2VuY29kaW5ncy5sZW5ndGg7ICsraSkKICAgIHsKICAgICAgaWYgKF9lbmNvZGluZ3NbaV0ubmFtZS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKSkKICAgICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgIGFyZ3NbMF0gPSBfZW5jb2RpbmdzW2ldLmphdmFOYW1lOwogICAgICAgICAgT2JqZWN0IGNvbnZlcnRlciA9IGdldENvbnZlcnRlck1ldGhvZC5pbnZva2UobnVsbCwgYXJncyk7CiAgICAgICAgICBpZihudWxsICE9IGNvbnZlcnRlcikKICAgICAgICAgICAgcmV0dXJuIGNvbnZlcnRlcjsKICAgICAgICB9CiAgICAgICAgY2F0Y2goIEV4Y2VwdGlvbiBpYWUpCiAgICAgICAgewogICAgICAgICAgLy8ga2VlcCB0cnlpbmcKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gbnVsbDsKICB9CgogIC8qKgogICAqIFJldHVybnMgdGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3RlciBmb3IgdGhlIHNwZWNpZmllZAogICAqIGVuY29kaW5nLgogICAqCiAgICogQHBhcmFtIGVuY29kaW5nIFRoZSBlbmNvZGluZwogICAqIEByZXR1cm4gVGhlIGxhc3QgcHJpbnRhYmxlIGNoYXJhY3RlcgogICAqLwogIHB1YmxpYyBzdGF0aWMgaW50IGdldExhc3RQcmludGFibGUoU3RyaW5nIGVuY29kaW5nKQogIHsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IF9lbmNvZGluZ3MubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIGlmIChfZW5jb2RpbmdzW2ldLm5hbWUuZXF1YWxzSWdub3JlQ2FzZShlbmNvZGluZykKICAgICAgICAgICAgICB8fCBfZW5jb2RpbmdzW2ldLmphdmFOYW1lLmVxdWFsc0lnbm9yZUNhc2UoZW5jb2RpbmcpKQogICAgICAgIHJldHVybiBfZW5jb2RpbmdzW2ldLmxhc3RQcmludGFibGU7CiAgICB9CgogICAgcmV0dXJuIG1fZGVmYXVsdExhc3RQcmludGFibGU7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBsYXN0IHByaW50YWJsZSBjaGFyYWN0ZXIgZm9yIGFuIHVuc3BlY2lmaWVkCiAgICogZW5jb2RpbmcuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBkZWZhdWx0IHNpemUKICAgKi8KICBwdWJsaWMgc3RhdGljIGludCBnZXRMYXN0UHJpbnRhYmxlKCkKICB7CiAgICByZXR1cm4gbV9kZWZhdWx0TGFzdFByaW50YWJsZTsKICB9CgogIC8qKiBUaGUgZGVmYXVsdCBlbmNvZGluZywgSVNPIHN0eWxlLCBJU08gc3R5bGUuICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX01JTUVfRU5DT0RJTkcgPSAiVVRGLTgiOwoKICAvKioKICAgKiBHZXQgdGhlIHByb3BlciBtaW1lIGVuY29kaW5nLiAgRnJvbSB0aGUgWFNMVCByZWNvbW1lbmRhdGlvbjogIlRoZSBlbmNvZGluZwogICAqIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIHByZWZlcnJlZCBlbmNvZGluZyB0byB1c2UgZm9yIG91dHB1dHRpbmcgdGhlIHJlc3VsdAogICAqIHRyZWUuIFhTTFQgcHJvY2Vzc29ycyBhcmUgcmVxdWlyZWQgdG8gcmVzcGVjdCB2YWx1ZXMgb2YgVVRGLTggYW5kIFVURi0xNi4KICAgKiBGb3Igb3RoZXIgdmFsdWVzLCBpZiB0aGUgWFNMVCBwcm9jZXNzb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUgc3BlY2lmaWVkCiAgICogZW5jb2RpbmcgaXQgbWF5IHNpZ25hbCBhbiBlcnJvcjsgaWYgaXQgZG9lcyBub3Qgc2lnbmFsIGFuIGVycm9yIGl0IHNob3VsZAogICAqIHVzZSBVVEYtOCBvciBVVEYtMTYgaW5zdGVhZC4gVGhlIFhTTFQgcHJvY2Vzc29yIG11c3Qgbm90IHVzZSBhbiBlbmNvZGluZwogICAqIHdob3NlIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIEVuY05hbWUgcHJvZHVjdGlvbiBvZiB0aGUgWE1MIFJlY29tbWVuZGF0aW9uCiAgICogW1hNTF0uIElmIG5vIGVuY29kaW5nIGF0dHJpYnV0ZSBpcyBzcGVjaWZpZWQsIHRoZW4gdGhlIFhTTFQgcHJvY2Vzc29yIHNob3VsZAogICAqIHVzZSBlaXRoZXIgVVRGLTggb3IgVVRGLTE2LiIKICAgKgogICAqIEBwYXJhbSBlbmNvZGluZyBSZWZlcmVuY2UgdG8gamF2YS1zdHlsZSBlbmNvZGluZyBzdHJpbmcsIHdoaWNoIG1heSBiZSBudWxsLCAKICAgKiBpbiB3aGljaCBjYXNlIGEgZGVmYXVsdCB3aWxsIGJlIGZvdW5kLgogICAqCiAgICogQHJldHVybiBUaGUgSVNPLXN0eWxlIGVuY29kaW5nIHN0cmluZywgb3IgbnVsbCBpZiBmYWlsdXJlLgogICAqLwogIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldE1pbWVFbmNvZGluZyhTdHJpbmcgZW5jb2RpbmcpCiAgewoKICAgIGlmIChudWxsID09IGVuY29kaW5nKQogICAgewogICAgICB0cnkKICAgICAgewoKICAgICAgICAvLyBHZXQgdGhlIGRlZmF1bHQgc3lzdGVtIGNoYXJhY3RlciBlbmNvZGluZy4gIFRoaXMgbWF5IGJlIAogICAgICAgIC8vIGluY29ycmVjdCBpZiB0aGV5IHBhc3NlZCBpbiBhIHdyaXRlciwgYnV0IHJpZ2h0IG5vdyB0aGVyZSAKICAgICAgICAvLyBzZWVtcyB0byBiZSBubyB3YXkgdG8gZ2V0IHRoZSBlbmNvZGluZyBmcm9tIGEgd3JpdGVyLgogICAgICAgIGVuY29kaW5nID0gU3lzdGVtLmdldFByb3BlcnR5KCJmaWxlLmVuY29kaW5nIiwgIlVURjgiKTsKCiAgICAgICAgaWYgKG51bGwgIT0gZW5jb2RpbmcpCiAgICAgICAgewoKICAgICAgICAgIC8qCiAgICAgICAgICAqIFNlZSBpZiB0aGUgbWltZSB0eXBlIGlzIGVxdWFsIHRvIFVURjguICBJZiB5b3UgZG9uJ3QKICAgICAgICAgICogZG8gdGhhdCwgdGhlbiAgY29udmVydEphdmEyTWltZUVuY29kaW5nIHdpbGwgY29udmVydAogICAgICAgICAgKiA4ODU5XzEgdG8gIklTTy04ODU5LTEiLCB3aGljaCBpcyBub3Qgd2hhdCB3ZSB3YW50LAogICAgICAgICAgKiBJIHRoaW5rLCBhbmQgSSBkb24ndCB0aGluayBJIHdhbnQgdG8gYWx0ZXIgdGhlIHRhYmxlcwogICAgICAgICAgKiB0byBjb252ZXJ0IGV2ZXJ5dGhpbmcgdG8gVVRGLTguCiAgICAgICAgICAqLwogICAgICAgICAgU3RyaW5nIGplbmNvZGluZyA9CiAgICAgICAgICAgIChlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKCJDcDEyNTIiKSB8fCBlbmNvZGluZy5lcXVhbHNJZ25vcmVDYXNlKAogICAgICAgICAgICAiSVNPODg1OV8xIikgfHwgZW5jb2RpbmcuZXF1YWxzSWdub3JlQ2FzZSgiODg1OV8xIikgCiAgICAgICAgICAgIHx8IGVuY29kaW5nLmVxdWFsc0lnbm9yZUNhc2UoIlVURjgiKSkgPyBERUZBVUxUX01JTUVfRU5DT0RJTkcKICAgICAgICAgICAgICA6IGNvbnZlcnRKYXZhMk1pbWVFbmNvZGluZygKICAgICAgICAgICAgICBlbmNvZGluZyk7CgogICAgICAgICAgZW5jb2RpbmcgPSAobnVsbCAhPSBqZW5jb2RpbmcpID8gamVuY29kaW5nIDogREVGQVVMVF9NSU1FX0VOQ09ESU5HOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgZW5jb2RpbmcgPSBERUZBVUxUX01JTUVfRU5DT0RJTkc7CiAgICAgICAgfQogICAgICB9CiAgICAgIGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkKICAgICAgewogICAgICAgIGVuY29kaW5nID0gREVGQVVMVF9NSU1FX0VOQ09ESU5HOwogICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGVuY29kaW5nID0gY29udmVydEphdmEyTWltZUVuY29kaW5nKGVuY29kaW5nKTsKICAgIH0KCiAgICByZXR1cm4gZW5jb2Rpbmc7CiAgfQoKICAvKioKICAgKiBUcnkgdGhlIGJlc3Qgd2UgY2FuIHRvIGNvbnZlcnQgYSBKYXZhIGVuY29kaW5nIHRvIGEgWE1MLXN0eWxlIGVuY29kaW5nLgogICAqCiAgICogQHBhcmFtIGVuY29kaW5nIG5vbi1udWxsIHJlZmVyZW5jZSB0byBlbmNvZGluZyBzdHJpbmcsIGphdmEgc3R5bGUuCiAgICoKICAgKiBAcmV0dXJuIElTTy1zdHlsZSBlbmNvZGluZyBzdHJpbmcuCiAgICovCiAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29udmVydEphdmEyTWltZUVuY29kaW5nKFN0cmluZyBlbmNvZGluZykKICB7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfZW5jb2RpbmdzLmxlbmd0aDsgKytpKQogICAgewogICAgICBpZiAoX2VuY29kaW5nc1tpXS5qYXZhTmFtZS5lcXVhbHNJZ25vcmVDYXNlKGVuY29kaW5nKSkKICAgICAgewogICAgICAgIHJldHVybiBfZW5jb2RpbmdzW2ldLm5hbWU7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZW5jb2Rpbmc7CiAgfQogIAogIC8qKgogICAqIFRyeSB0aGUgYmVzdCB3ZSBjYW4gdG8gY29udmVydCBhIEphdmEgZW5jb2RpbmcgdG8gYSBYTUwtc3R5bGUgZW5jb2RpbmcuCiAgICoKICAgKiBAcGFyYW0gZW5jb2Rpbmcgbm9uLW51bGwgcmVmZXJlbmNlIHRvIGVuY29kaW5nIHN0cmluZywgamF2YSBzdHlsZS4KICAgKgogICAqIEByZXR1cm4gSVNPLXN0eWxlIGVuY29kaW5nIHN0cmluZy4KICAgKi8KICBwdWJsaWMgc3RhdGljIFN0cmluZyBjb252ZXJ0TWltZTJKYXZhRW5jb2RpbmcoU3RyaW5nIGVuY29kaW5nKQogIHsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IF9lbmNvZGluZ3MubGVuZ3RoOyArK2kpCiAgICB7CiAgICAgIGlmIChfZW5jb2RpbmdzW2ldLm5hbWUuZXF1YWxzSWdub3JlQ2FzZShlbmNvZGluZykpCiAgICAgIHsKICAgICAgICByZXR1cm4gX2VuY29kaW5nc1tpXS5qYXZhTmFtZTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBlbmNvZGluZzsKICB9CgoKICAvKioKICAgKiBDb25zdHJ1Y3RzIGEgbGlzdCBvZiBhbGwgdGhlIHN1cHBvcnRlZCBlbmNvZGluZ3MuCiAgICovCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW5jb2RpbmdJbmZvW10gX2VuY29kaW5ncyA9IG5ldyBFbmNvZGluZ0luZm9bXQogIHsKCiAgICAvLyAgICA8cHJlZmVycmVkIE1JTUUgbmFtZT4sIDxKYXZhIGVuY29kaW5nIG5hbWU+CiAgICAvLyBuZXcgRW5jb2RpbmdJbmZvKCAiSVNPIDg4NTktMSIsICJDUDEyNTIiKTsgLy8gQ2xvc2UgZW5vdWdoLCBJIGd1ZXNzCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJXSU5ET1dTLTEyNTAiLCAiQ3AxMjUwIiwgMHgwMEZGKSwgIC8vIFBldGVyIFNtb2xpawogICAgLy8gUGF0Y2ggYXR0cmlidXRlZCB0byBoYXZhcmR3QHVuZGVyZHVza2VuLm5vIChI5XZhcmQgV2lndGlsKQogICAgbmV3IEVuY29kaW5nSW5mbygiV0lORE9XUy0xMjUyIiwgIkNwMTI1MiIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJVVEYtOCIsICJVVEY4IiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIlVTLUFTQ0lJIiwgIklTTzg4NTlfMSIsIDB4N0YpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMSIsICJJU084ODU5XzEiLCAweDAwRkYpLAogICAgLy8gUGF0Y2ggYXR0cmlidXRlZCB0byBoYXZhcmR3QHVuZGVyZHVza2VuLm5vIChI5XZhcmQgV2lndGlsKQogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMSIsICJJU084ODU5LTEiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMiIsICJJU084ODU5XzIiLCAweDAwRkYpLAogICAgLy8gSSdtIGdvaW5nIHRvIGFwcGx5ICJJU084ODU5LVgiIHZhcmlhbnQgdG8gYWxsIHRoZXNlLCB0byBiZSBzYWZlLgogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMiIsICJJU084ODU5LTIiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMyIsICJJU084ODU5XzMiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktMyIsICJJU084ODU5LTMiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNCIsICJJU084ODU5XzQiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNCIsICJJU084ODU5LTQiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNSIsICJJU084ODU5XzUiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNSIsICJJU084ODU5LTUiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNiIsICJJU084ODU5XzYiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNiIsICJJU084ODU5LTYiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNyIsICJJU084ODU5XzciLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktNyIsICJJU084ODU5LTciLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOCIsICJJU084ODU5XzgiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOCIsICJJU084ODU5LTgiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOSIsICJJU084ODU5XzkiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTg4NTktOSIsICJJU084ODU5LTkiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiVVMtQVNDSUkiLCAiODg1OV8xIiwgMHgwMEZGKSwgIC8vID8KICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTEiLCAiODg1OV8xIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTIiLCAiODg1OV8yIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTMiLCAiODg1OV8zIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTQiLCAiODg1OV80IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTUiLCAiODg1OV81IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTYiLCAiODg1OV82IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTciLCAiODg1OV83IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTgiLCAiODg1OV84IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTkiLCAiODg1OV85IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTEiLCAiODg1OS0xIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTIiLCAiODg1OS0yIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTMiLCAiODg1OS0zIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTQiLCAiODg1OS00IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTUiLCAiODg1OS01IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTYiLCAiODg1OS02IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTciLCAiODg1OS03IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTgiLCAiODg1OS04IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy04ODU5LTkiLCAiODg1OS05IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIklTTy0yMDIyLUpQIiwgIkpJUyIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJTSElGVF9KSVMiLCAiU0pJUyIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtSlAiLCAiRVVDX0pQIiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVVQy1LUiIsICJFVUNfS1IiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRVVDLUNOIiwgIkVVQ19DTiIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtVFciLCAiRVVDX1RXIiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkdCMjMxMiIsICJFVUNfQ04iLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRVVDLUpQIiwgIkVVQy1KUCIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFVUMtS1IiLCAiRVVDLUtSIiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVVQy1DTiIsICJFVUMtQ04iLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRVVDLVRXIiwgIkVVQy1UVyIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJHQjIzMTIiLCAiRVVDLUNOIiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkdCMjMxMiIsICJHQjIzMTIiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiQklHNSIsICJCaWc1IiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVVQy1KUCIsICJFVUNKSVMiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRVVDLUtSIiwgIktTQzU2MDEiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiSVNPLTIwMjItS1IiLCAiSVNPMjAyMktSIiwgMHhGRkZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIktPSTgtUiIsICJLT0k4X1IiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLVVTIiwgIkNwMDM3IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1DQSIsICJDcDAzNyIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtTkwiLCAiQ3AwMzciLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLURLIiwgIkNwMjc3IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1OTyIsICJDcDI3NyIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtRkkiLCAiQ3AyNzgiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLVNFIiwgIkNwMjc4IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1JVCIsICJDcDI4MCIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtRVMiLCAiQ3AyODQiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUdCIiwgIkNwMjg1IiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1GUiIsICJDcDI5NyIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtQVIxIiwgIkNwNDIwIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1IRSIsICJDcDQyNCIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtQ0giLCAiQ3A1MDAiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLVJPRUNFIiwgIkNwODcwIiwgMHgwMEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkVCQ0RJQy1DUC1ZVSIsICJDcDg3MCIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJFQkNESUMtQ1AtSVMiLCAiQ3A4NzEiLCAweDAwRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiRUJDRElDLUNQLUFSMiIsICJDcDkxOCIsIDB4MDBGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJNYWNSb21hbiIsICJNYWNURUMiLCAweEZGKSwKICAgIG5ldyBFbmNvZGluZ0luZm8oIkFTQ0lJIiwgIkFTQ0lJIiwgMHg3RiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJJU08tTGF0aW4tMSIsICJBU0NJSSIsIDB4RkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiVVRGLTgiLCAiVVRGOCIsIDB4RkZGRiksCiAgICBuZXcgRW5jb2RpbmdJbmZvKCJVTklDT0RFIiwgIlVuaWNvZGUiLCAweEZGRkYpLAogICAgbmV3IEVuY29kaW5nSW5mbygiVVRGLTE2IiwgIlVuaWNvZGUiLCAweEZGRkYpCiAgfTsKfQo=